diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index 2c1a86d1a2..892c7bf3fc 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -1,304 +1,304 @@ /**************************************************************************************** * Copyright (c) 2004-2013 Mark Kretschmann * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #define DEBUG_PREFIX "PluginManager" #include "PluginManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** Defines the used plugin version number. * * This must match the desktop files. */ const int Plugins::PluginManager::s_pluginFrameworkVersion = 72; Plugins::PluginManager* Plugins::PluginManager::s_instance = 0; Plugins::PluginManager* Plugins::PluginManager::instance() { return s_instance ? s_instance : new PluginManager(); } void Plugins::PluginManager::destroy() { if( s_instance ) { delete s_instance; s_instance = 0; } } Plugins::PluginManager::PluginManager( QObject *parent ) : QObject( parent ) { DEBUG_BLOCK setObjectName( "PluginManager" ); s_instance = this; PERF_LOG( "Initialising Plugin Manager" ) init(); PERF_LOG( "Initialised Plugin Manager" ) } Plugins::PluginManager::~PluginManager() { // tell the managers to get rid of their current factories QList emptyFactories; StatSyncing::Controller *controller = Amarok::Components::statSyncingController(); if( controller ) controller->setFactories( emptyFactories ); ServicePluginManager::instance()->setFactories( emptyFactories ); CollectionManager::instance()->setFactories( emptyFactories ); StorageManager::instance()->setFactories( emptyFactories ); } void Plugins::PluginManager::init() { checkPluginEnabledStates(); } KPluginInfo::List Plugins::PluginManager::plugins( Type type ) const { return m_pluginInfosByType.value( type ); } QList Plugins::PluginManager::factories( Type type ) const { return m_factoriesByType.value( type ); } void Plugins::PluginManager::checkPluginEnabledStates() { // re-create all the member infos. m_pluginInfos.clear(); m_pluginInfosByType.clear(); m_factoriesByType.clear(); m_pluginInfos = findPlugins(); // reload all the plugins plus their enabled state if( m_pluginInfos.isEmpty() ) // try it a second time with syscoca handleNoPluginsFound(); QList allFactories; // sort the plugin infos by type foreach( const KPluginInfo &pluginInfo, m_pluginInfos ) { Type type; if( pluginInfo.category() == QLatin1String("Storage") ) type = Storage; else if( pluginInfo.category() == QLatin1String("Collection") ) type = Collection; else if( pluginInfo.category() == QLatin1String("Service") ) type = Service; else if( pluginInfo.category() == QLatin1String("Importer") ) type = Importer; else { warning() << pluginInfo.pluginName() << " has unknown category"; continue; } m_pluginInfosByType[ type ] << pluginInfo; // create the factories and sort them by type PluginFactory *factory = createFactory( pluginInfo ); if( factory ) { m_factoriesByType[ type ] << factory; allFactories << factory; } } // the setFactories functions should: - // - filter out factories not usefull (e.g. services when setting collections) + // - filter out factories not useful (e.g. services when setting collections) // - handle the new list of factories, disabling old ones and enabling new ones. PERF_LOG( "Loading storage plugins" ) StorageManager::instance()->setFactories( m_factoriesByType.value( Storage ) ); PERF_LOG( "Loaded storage plugins" ) PERF_LOG( "Loading collection plugins" ) CollectionManager::instance()->setFactories( m_factoriesByType.value( Collection ) ); PERF_LOG( "Loaded collection plugins" ) PERF_LOG( "Loading service plugins" ) ServicePluginManager::instance()->setFactories( m_factoriesByType.value( Service ) ); PERF_LOG( "Loaded service plugins" ) PERF_LOG( "Loading importer plugins" ) StatSyncing::Controller *controller = Amarok::Components::statSyncingController(); if( controller ) controller->setFactories( m_factoriesByType.value( Importer ) ); PERF_LOG( "Loaded importer plugins" ) // init all new factories // do this after they were added to the sub-manager so that they // have a chance to connect to signals // // we need to init by type and the storages need to go first foreach( PluginFactory* factory, m_factoriesByType[ Storage ] ) factory->init(); foreach( PluginFactory* factory, m_factoriesByType[ Collection ] ) factory->init(); foreach( PluginFactory* factory, m_factoriesByType[ Service ] ) factory->init(); foreach( PluginFactory* factory, m_factoriesByType[ Importer ] ) factory->init(); } bool Plugins::PluginManager::isPluginEnabled( const KPluginInfo &pluginInfo ) const { // mysql storage and collection are vital. They need to be loaded always if( pluginInfo.property("X-KDE-Amarok-vital").toBool() ) { return true; } else { const QString pluginName = pluginInfo.pluginName(); const bool enabledByDefault = pluginInfo.isPluginEnabledByDefault(); return Amarok::config( "Plugins" ).readEntry( pluginName + "Enabled", enabledByDefault ); } } Plugins::PluginFactory* Plugins::PluginManager::createFactory( const KPluginInfo &pluginInfo ) { if( !isPluginEnabled( pluginInfo ) ) return 0; // check if we already created this factory // note: old factories are not deleted. // We can't very well just destroy a factory being // currently used. const QString name = pluginInfo.pluginName(); if( m_factoryCreated.contains(name) ) return m_factoryCreated.value(name); KService::Ptr service = pluginInfo.service(); KPluginLoader loader( *( service.constData() ) ); KPluginFactory *pluginFactory( loader.factory() ); if( !pluginFactory ) { warning() << QString( "Failed to get factory '%1' from KPluginLoader: %2" ) .arg( name, loader.errorString() ); return 0; } // create the factory with this object as owner PluginFactory *factory = 0; if( !(factory = pluginFactory->create( this )) ) { warning() << "Failed to create plugin" << name << loader.errorString(); return 0; } m_factoryCreated[ pluginInfo.pluginName() ] = factory; return factory; } KPluginInfo::List Plugins::PluginManager::findPlugins() { QString query = QString::fromLatin1( "[X-KDE-Amarok-framework-version] == %1" " and [X-KDE-Amarok-rank] > 0" ) .arg( s_pluginFrameworkVersion ); KConfigGroup pluginsConfig = Amarok::config(QLatin1String("Plugins")); KService::List services = KServiceTypeTrader::self()->query( "Amarok/Plugin", query ); KPluginInfo::List plugins = KPluginInfo::fromServices( services, pluginsConfig ); // load the plugins foreach( KPluginInfo info, plugins ) { info.load( pluginsConfig ); // load the enabled state of plugin debug() << "found plugin:" << info.pluginName() << "enabled:" << info.isPluginEnabled(); } debug() << plugins.count() << "plugins in total"; return plugins; } void Plugins::PluginManager::handleNoPluginsFound() { DEBUG_BLOCK debug() << "No Amarok plugins found, running kbuildsycoca4."; // Run kbuildsycoca4 in a blocking fashion KProcess::execute( KStandardDirs::findExe( "kbuildsycoca4" ), QStringList( "--noincremental" ) ); // Wait a bit (3 sec) until ksycoca has fully updated for( int i = 0; i < 30; i++ ) { QThread::currentThread()->wait( 100 ); QApplication::processEvents(); } debug() << "Second attempt at finding plugins"; m_pluginInfos = findPlugins(); if( m_pluginInfos.isEmpty() ) { if( QApplication::type() != QApplication::Tty ) { KMessageBox::error( 0, i18n( "Amarok could not find any plugins. This indicates an installation problem." ) ); } else { warning() << "Amarok could not find any plugins. Bailing out."; } // don't use QApplication::exit, as the eventloop may not have started yet std::exit( EXIT_SUCCESS ); } } int Plugins::PluginManager::pluginFrameworkVersion() { return s_pluginFrameworkVersion; } #include "PluginManager.moc" diff --git a/src/core-impl/collections/support/CollectionManager.cpp b/src/core-impl/collections/support/CollectionManager.cpp index c0a189dbd6..ceff45469f 100644 --- a/src/core-impl/collections/support/CollectionManager.cpp +++ b/src/core-impl/collections/support/CollectionManager.cpp @@ -1,426 +1,426 @@ /**************************************************************************************** * Copyright (c) 2007-2008 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #define DEBUG_PREFIX "CollectionManager" #include "CollectionManager.h" #include "core/capabilities/CollectionScanCapability.h" #include "core/collections/Collection.h" #include "core/collections/MetaQueryMaker.h" #include "core/support/Amarok.h" #include "core/support/Debug.h" #include "core/support/SmartPointerList.h" #include "core-impl/meta/file/FileTrackProvider.h" #include "core-impl/meta/stream/Stream.h" #include "core-impl/meta/timecode/TimecodeTrackProvider.h" #include #include #include #include #include #include #include typedef QPair CollectionPair; /** Private structure of the collection manager */ struct CollectionManager::Private { QList collections; QList factories; // factories belong to PluginManager QList trackProviders; TimecodeTrackProvider *timecodeTrackProvider; Collections::TrackProvider *fileTrackProvider; // special case Collections::Collection *primaryCollection; QReadWriteLock lock; ///< protects all other variables against threading issues }; CollectionManager *CollectionManager::s_instance = 0; CollectionManager * CollectionManager::instance() { if( !s_instance ) { s_instance = new CollectionManager(); s_instance->init(); } return s_instance; } void CollectionManager::destroy() { if( s_instance ) { delete s_instance; s_instance = 0; } } CollectionManager::CollectionManager() : QObject() , d( new Private ) { DEBUG_BLOCK // ensure this object is created in a main thread Q_ASSERT( thread() == QCoreApplication::instance()->thread() ); setObjectName( "CollectionManager" ); d->primaryCollection = 0; d->timecodeTrackProvider = 0; d->fileTrackProvider = 0; } CollectionManager::~CollectionManager() { DEBUG_BLOCK { QWriteLocker locker( &d->lock ); d->collections.clear(); d->trackProviders.clear(); delete d->timecodeTrackProvider; delete d->fileTrackProvider; // Hmm, qDeleteAll from Qt 4.8 crashes with our SmartPointerList, do it manually. Bug 285951 while (!d->factories.isEmpty() ) delete d->factories.takeFirst(); } delete d; } void CollectionManager::init() { // register the timecode track provider now, as it needs to get added before loading // the stored playlist... Since it can have playable urls that might also match other providers, it needs to get added first. d->timecodeTrackProvider = new TimecodeTrackProvider(); addTrackProvider( d->timecodeTrackProvider ); - // addint fileTrackProvider second since local tracks should be preferred even if the url matchs two tracks + // addint fileTrackProvider second since local tracks should be preferred even if the url matches two tracks d->fileTrackProvider = new FileTrackProvider(); addTrackProvider( d->fileTrackProvider ); } void CollectionManager::setFactories( const QList &factories ) { using Collections::CollectionFactory; QSet newFactories = factories.toSet(); QSet oldFactories; { QReadLocker locker( &d->lock ); oldFactories = d->factories.toSet(); } // remove old factories foreach( Plugins::PluginFactory* pFactory, oldFactories - newFactories ) { CollectionFactory *factory = qobject_cast( pFactory ); if( !factory ) continue; disconnect( factory, SIGNAL(newCollection(Collections::Collection*)), this, SLOT(slotNewCollection(Collections::Collection*)) ); { QWriteLocker locker( &d->lock ); d->factories.removeAll( factory ); } } // create new factories foreach( Plugins::PluginFactory* pFactory, newFactories - oldFactories ) { CollectionFactory *factory = qobject_cast( pFactory ); if( !factory ) continue; connect( factory, SIGNAL(newCollection(Collections::Collection*)), this, SLOT(slotNewCollection(Collections::Collection*)) ); { QWriteLocker locker( &d->lock ); d->factories.append( factory ); } } d->factories = factories; } void CollectionManager::startFullScan() { QReadLocker locker( &d->lock ); foreach( const CollectionPair &pair, d->collections ) { QScopedPointer csc( pair.first->create()); if( csc ) csc->startFullScan(); } } void CollectionManager::startIncrementalScan( const QString &directory ) { QReadLocker locker( &d->lock ); foreach( const CollectionPair &pair, d->collections ) { QScopedPointer csc( pair.first->create()); if( csc ) csc->startIncrementalScan( directory ); } } void CollectionManager::stopScan() { QReadLocker locker( &d->lock ); foreach( const CollectionPair &pair, d->collections ) { QScopedPointer csc( pair.first->create()); if( csc ) csc->stopScan(); } } void CollectionManager::checkCollectionChanges() { startIncrementalScan( QString() ); } Collections::QueryMaker* CollectionManager::queryMaker() const { QReadLocker locker( &d->lock ); QList colls; foreach( const CollectionPair &pair, d->collections ) { if( pair.second & CollectionQueryable ) { colls << pair.first; } } return new Collections::MetaQueryMaker( colls ); } void CollectionManager::slotNewCollection( Collections::Collection* newCollection ) { DEBUG_BLOCK if( !newCollection ) { error() << "newCollection in slotNewCollection is 0"; return; } { QWriteLocker locker( &d->lock ); foreach( const CollectionPair &p, d->collections ) { if( p.first == newCollection ) { error() << "newCollection " << newCollection->collectionId() << " is already being managed"; return; } } } const QMetaObject *mo = metaObject(); const QMetaEnum me = mo->enumerator( mo->indexOfEnumerator( "CollectionStatus" ) ); const QString &value = KGlobal::config()->group( "CollectionManager" ).readEntry( newCollection->collectionId() ); int enumValue = me.keyToValue( value.toLocal8Bit().constData() ); CollectionStatus status; enumValue == -1 ? status = CollectionEnabled : status = (CollectionStatus) enumValue; CollectionPair pair( newCollection, status ); { QWriteLocker locker( &d->lock ); if( newCollection->collectionId() == QLatin1String("localCollection") ) { d->primaryCollection = newCollection; d->collections.insert( 0, pair ); // the primary collection should be the first collection to be searched d->trackProviders.insert( 1, newCollection ); // the primary collection should be between the timecode track provider and the local file track provider } else { d->collections.append( pair ); d->trackProviders.append( newCollection ); } connect( newCollection, SIGNAL(remove()), SLOT(slotRemoveCollection()), Qt::QueuedConnection ); connect( newCollection, SIGNAL(updated()), SLOT(slotCollectionChanged()), Qt::QueuedConnection ); debug() << "new Collection " << newCollection->collectionId(); } if( status & CollectionViewable ) { emit collectionAdded( newCollection ); emit collectionAdded( newCollection, status ); } } void CollectionManager::slotRemoveCollection() { Collections::Collection* collection = qobject_cast( sender() ); if( collection ) { CollectionStatus status = collectionStatus( collection->collectionId() ); CollectionPair pair( collection, status ); { QWriteLocker locker( &d->lock ); d->collections.removeAll( pair ); d->trackProviders.removeAll( collection ); } emit collectionRemoved( collection->collectionId() ); QTimer::singleShot( 500, collection, SLOT(deleteLater()) ); // give the tree some time to update itself until we really delete the collection pointers. } } void CollectionManager::slotCollectionChanged() { Collections::Collection *collection = dynamic_cast( sender() ); if( collection ) { CollectionStatus status = collectionStatus( collection->collectionId() ); if( status & CollectionViewable ) { emit collectionDataChanged( collection ); } } } QList CollectionManager::viewableCollections() const { QReadLocker locker( &d->lock ); QList result; foreach( const CollectionPair &pair, d->collections ) { if( pair.second & CollectionViewable ) { result << pair.first; } } return result; } Collections::Collection* CollectionManager::primaryCollection() const { QReadLocker locker( &d->lock ); return d->primaryCollection; } Meta::TrackPtr CollectionManager::trackForUrl( const KUrl &url ) { QReadLocker locker( &d->lock ); // TODO: // might be a podcast, in that case we'll have additional meta information // might be a lastfm track, another stream if( !url.isValid() ) return Meta::TrackPtr( 0 ); foreach( Collections::TrackProvider *provider, d->trackProviders ) { if( provider->possiblyContainsTrack( url ) ) { Meta::TrackPtr track = provider->trackForUrl( url ); if( track ) return track; } } // TODO: create specific TrackProviders for these: static const QSet remoteProtocols = QSet() << "http" << "https" << "mms" << "smb"; // consider unifying with TrackLoader::tracksLoaded() if( remoteProtocols.contains( url.protocol() ) ) return Meta::TrackPtr( new MetaStream::Track( url ) ); return Meta::TrackPtr( 0 ); } CollectionManager::CollectionStatus CollectionManager::collectionStatus( const QString &collectionId ) const { QReadLocker locker( &d->lock ); foreach( const CollectionPair &pair, d->collections ) { if( pair.first->collectionId() == collectionId ) { return pair.second; } } return CollectionDisabled; } QHash CollectionManager::collections() const { QReadLocker locker( &d->lock ); QHash result; foreach( const CollectionPair &pair, d->collections ) { result.insert( pair.first, pair.second ); } return result; } void CollectionManager::addTrackProvider( Collections::TrackProvider *provider ) { { QWriteLocker locker( &d->lock ); d->trackProviders.append( provider ); } emit trackProviderAdded( provider ); } void CollectionManager::removeTrackProvider( Collections::TrackProvider *provider ) { QWriteLocker locker( &d->lock ); d->trackProviders.removeAll( provider ); } diff --git a/src/core-impl/collections/support/CollectionManager.h b/src/core-impl/collections/support/CollectionManager.h index 5f56394d8f..0a7e40009d 100644 --- a/src/core-impl/collections/support/CollectionManager.h +++ b/src/core-impl/collections/support/CollectionManager.h @@ -1,178 +1,178 @@ /**************************************************************************************** * Copyright (c) 2007-2008 Maximilian Kossick * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef AMAROK_COLLECTIONMANAGER_H #define AMAROK_COLLECTIONMANAGER_H #include "amarok_export.h" #include "core/meta/forward_declarations.h" #include #include #include class CollectionManagerSingleton; namespace Plugins { class PluginFactory; } namespace Collections { class Collection; class CollectionFactory; class TrackProvider; class QueryMaker; } /** Class managing the different collections. * * This singleton class is the main repository for all current collections. - * The most usefull functions are probably queryMaker and + * The most useful functions are probably queryMaker and * viewableCollections */ class AMAROK_EXPORT CollectionManager : public QObject { Q_OBJECT Q_ENUMS( CollectionStatus ) public: /** * defines the status of a collection in respect to global queries (i.e. queries that query all known collections) * or the collection browser. */ enum CollectionStatus { CollectionDisabled = 1, ///< Collection neither viewable nor queryable (but might produce tracks that can be played) CollectionViewable = 2, ///< Collection will not be queried by CollectionManager::queryMaker CollectionQueryable= 4, ///< Collection wil not show up in the browser, but is queryable by global queries CollectionEnabled = CollectionViewable | CollectionQueryable ///< Collection viewable in the browser and queryable }; static CollectionManager *instance(); /** Destroys the instance of the CollectionManager. */ static void destroy(); /** * Returns a query maker that queries all queryable the collections */ Collections::QueryMaker *queryMaker() const; /** * returns all viewable collections. */ QList viewableCollections() const; //TODO: Remove /** * Allows access to one of Amarok's collection. * * @deprecated DO NOT USE this method. This is legacy code from the early days of Amarok * when SqlCollection was the only working collection. If you are writing new code, make * sure that it is able to handle multiple collections, * e.g. multiple connected media devices. Using this method means you are lazy. An easy way * is to use CollectionManager::queryMaker(). Alternatively, access the available collections * using CollectionManager::queryableCollections() or CollectionManager::viewableCollections() * and do whatever you want to. * */ Collections::Collection* primaryCollection() const; /** This method will try to get a Track object for the given url. This method will return 0 if no Track object could be created for the url. */ Meta::TrackPtr trackForUrl( const KUrl &url ); CollectionStatus collectionStatus( const QString &collectionId ) const; QHash collections() const; /** * adds a TrackProvider to the list of TrackProviders, * which allows CollectionManager to create tracks in trackForUrl. * CollectionManager does not take ownership of the TrackProvider pointer * * Note: collections that CollectionManager knows about are automatically * added to the list of TrackProviders. * * @param provider the new TrackProvider */ void addTrackProvider( Collections::TrackProvider *provider ); /** * removes a TrackProvider. Does not do anything if * CollectionManager does not know the given TrackProvider. * * Note: collections will be automatically removed from * the list of available TrackProviders. * * @param provider the provider to be removed */ void removeTrackProvider( Collections::TrackProvider *provider ); /** * Set the list of current factories * * For every factory that is a CollectionFactory uses it to create new * collections and register with this manager. */ void setFactories( const QList &factories ); public slots: /** Starts the full scan for each collection with CollectionScanCapability */ void startFullScan(); /** Starts the incremetal scan for each collection with CollectionScanCapability */ void startIncrementalScan( const QString &directory = QString() ); void stopScan(); void checkCollectionChanges(); signals: //deprecated, use collectionAdded( Collections::Collection*, CollectionStatus ) instead void collectionAdded( Collections::Collection *newCollection ); void collectionAdded( Collections::Collection *newCollection, CollectionManager::CollectionStatus status ); void collectionRemoved( QString collectionId ); void trackProviderAdded( Collections::TrackProvider *provider ); //this signal will be emitted after major changes to the collection //e.g. new songs where added, or an album changed //from compilation to non-compilation (and vice versa) //it will not be emitted on minor changes (e.g. the tags of a song were changed) void collectionDataChanged( Collections::Collection *changedCollection ); private slots: /** Will be called whenever a registered collection factory creates a new collection */ void slotNewCollection( Collections::Collection *newCollection ); /** Will remove the collection that emitted the signal */ void slotRemoveCollection(); void slotCollectionChanged(); private: static CollectionManager* s_instance; CollectionManager(); ~CollectionManager(); void init(); Q_DISABLE_COPY( CollectionManager ) struct Private; Private * const d; }; #endif /* AMAROK_COLLECTIONMANAGER_H */ diff --git a/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h b/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h index 213ea7b8bd..87fd4314ca 100644 --- a/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h +++ b/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h @@ -1,94 +1,94 @@ /**************************************************************************************** * Copyright (c) 2008 Edward Toroshchin * * Copyright (c) 2009 Jeff Mitchell * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef AMAROK_STORAGE_MYSQLSTORAGE_H #define AMAROK_STORAGE_MYSQLSTORAGE_H #include "core/storage/SqlStorage.h" #include #include #ifdef Q_WS_WIN #include #endif struct st_mysql; typedef struct st_mysql MYSQL; /** * Implements a SqlStorage using a MySQL backend */ class MySqlStorage: public SqlStorage { public: MySqlStorage(); virtual ~MySqlStorage(); virtual QStringList query( const QString &query ); virtual int insert( const QString &statement, const QString &table = QString() ); virtual QString escape( const QString &text ) const; virtual QString randomFunc() const; virtual QString boolTrue() const; virtual QString boolFalse() const; virtual QString idType() const; virtual QString textColumnType( int length = 255 ) const; virtual QString exactTextColumnType( int length = 1000 ) const; //the below value may have to be decreased even more for different indexes; only time will tell virtual QString exactIndexableTextColumnType( int length = 324 ) const; virtual QString longTextColumnType() const; /** Returns a list of the last sql errors. The list might not include every one error if the number is beyond a sensible limit. */ QStringList getLastErrors() const; /** Clears the list of the last errors. */ void clearLastErrors(); protected: /** Adds an error message to the m_lastErrors. * - * Adds a message including the mysql error number and mesage + * Adds a message including the mysql error number and message * to the last error messages. * @param message Usually the query statement being executed. */ void reportError( const QString &message ); void initThreadInitializer(); /** Sends the first sql commands to setup the connection. * * Sets things like the used database and charset. * @returns false if something fatal was wrong. */ bool sharedInit( const QString &databaseName ); MYSQL* m_db; /** Mutex protecting the m_lastErrors list */ mutable QMutex m_mutex; QString m_debugIdent; QStringList m_lastErrors; }; #endif diff --git a/src/dialogs/LabelListModel.cpp b/src/dialogs/LabelListModel.cpp index 054bb3fa5b..26ab96b565 100644 --- a/src/dialogs/LabelListModel.cpp +++ b/src/dialogs/LabelListModel.cpp @@ -1,164 +1,164 @@ /**************************************************************************************** * Copyright (c) 2009 Daniel Dewald * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #include "dialogs/LabelListModel.h" LabelListModel::LabelListModel( const QStringList &labels, QObject *parent ) : QAbstractListModel( parent ) , m_labels( labels ) { } int LabelListModel::rowCount( const QModelIndex &parent ) const { Q_UNUSED( parent ); return m_labels.count(); } QVariant LabelListModel::data( const QModelIndex &index, int role ) const { if ( !index.isValid() ) return QVariant(); if ( index.row() >= m_labels.size() ) return QVariant(); if ( role == Qt::DisplayRole ) return m_labels.at( index.row() ); else return QVariant(); } QVariant LabelListModel::headerData( int section, Qt::Orientation orientation, int role ) const { Q_UNUSED( section ); Q_UNUSED( orientation ); Q_UNUSED( role ); return QVariant(); } Qt::ItemFlags LabelListModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemIsEnabled; return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; } bool LabelListModel::setData( const QModelIndex &index, const QVariant &value, int role ) { if ( index.isValid() && role == Qt::EditRole ) { m_labels.replace( index.row(), value.toString() ); emit dataChanged( index, index ); m_labels.sort(); return true; } return false; } //Adds a label to the list if not present void LabelListModel::addLabel( const QString label ) { if ( ( !label.isEmpty() ) && ( !isPresent( label ) ) ) { beginInsertRows( QModelIndex(), 0 , m_labels.length()+1 ); m_labels << label ; m_labels.sort(); endInsertRows(); } } -//Checks if a label is alread present +//Checks if a label is already present bool LabelListModel::isPresent( const QString label ) { if ( m_labels.indexOf( label ) > -1 ) { return true; } return false; } // Removes the label "label" from the list if present void LabelListModel::removeLabel( const QString label ) { int index = m_labels.indexOf( label ); if ( index >= 0 ) { beginRemoveRows( QModelIndex(), index, index ); m_labels.removeAt( index ); endRemoveRows(); } } //Wrapper function for remove label void LabelListModel::removeLabels( const QStringList labels ) { if ( !labels.isEmpty() ) { for (int x = 0; x < labels.size(); ++x) { removeLabel( labels.at( x ) ); } } } //Returns all labels in the list QStringList LabelListModel::labels() { return m_labels; } //Sets label list to "labels" void LabelListModel::setLabels( QStringList labels ) { beginInsertRows( QModelIndex(), 0, m_labels.length() ); m_labels = labels; endInsertRows(); } bool LabelListModel::insertRows( int position, int rows, const QModelIndex &parent ) { Q_UNUSED( parent ); beginInsertRows( QModelIndex(), position, position+rows-1 ); for ( int row = 0; row < rows; ++row ) { m_labels.insert( position, "" ); } endInsertRows(); return true; } bool LabelListModel::removeRows( int position, int rows, const QModelIndex &parent ) { Q_UNUSED( parent ); beginRemoveRows( QModelIndex(), position, position+rows-1 ); for ( int row = 0; row < rows; ++row ) { m_labels.removeAt( position ); } endRemoveRows(); return true; } diff --git a/src/dialogs/TrackOrganizer.h b/src/dialogs/TrackOrganizer.h index 76a8fc7640..6344a22523 100644 --- a/src/dialogs/TrackOrganizer.h +++ b/src/dialogs/TrackOrganizer.h @@ -1,126 +1,126 @@ /*************************************************************************** * Copyright (c) 2010 Casey Link * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef TRACKORGANIZER_H #define TRACKORGANIZER_H #include "amarok_export.h" #include "core/meta/forward_declarations.h" #include #include /** * Generates a list of paths formatted according to the specified * format string. * @author Casey Link */ class AMAROK_EXPORT TrackOrganizer : public QObject { Q_OBJECT public: TrackOrganizer( const Meta::TrackList &tracks, QObject* parent = 0 ); /** * Sets the format string. Required. * @param format the format, e.g., %artist - %title.%filetype */ void setFormatString( const QString &format ); /** * Sets the folder (i.e. collection prefix) * @param prefix the folder prefix, e.g., /home/user/Music/ */ void setFolderPrefix( const QString &prefix ); /** - * Sets whether to move the the in an artist name to the end of the name. + * Sets whether to move the "the" in an artist name to the end of the name. * Default value is false. * @param flag turns the option on */ void setPostfixThe( bool flag ); /** * Sets whether to restrict filenames to ASCII * Default value is false. * @param flag turns the option on */ void setAsciiOnly( bool flag ); /** * Sets whether to replaces spaces with underscores.auto * Default value is false. * @param flag turns the option on */ void setReplaceSpaces( bool flag ); /** * Sets whether to restrict filenames to VFAT safe names. * Default value is false. * @param flag turns the option on */ void setVfatSafe( bool flag); /** * Sets a regex and replacement string to perform custom replacement * @param regex the regex value * @param string the string substitute for the regex match */ void setReplace( const QString ®ex, const QString &string ); /** * Sets a new file extension for the target file names. * @param fileExtension the file extension */ void setTargetFileExtension( const QString &fileExtension ); /** * Get the list of processed destinations * Only call after setting all the appropriate options * @see setFormatString * @arg batchSize How many to return this run of the function. If 0 (default) will calculate the * complete list. This function can return a shorter list at the end of the results list. * Over consecutive runs of this function the same number of results as the length of the * tracklist passed in the constructor will be returned. */ QMap getDestinations( unsigned int batchSize = 0 ); /** Call this function if you want getDestinations to return results starting from the first track. */ void resetTrackOffset() { m_trackOffset = 0; } private: QString buildDestination( const QString &format, const Meta::TrackPtr &track ) const; QString cleanPath( const QString &path ) const; /** Returns the number of characters that are the same in both strings beginning. */ static int commonPrefixLength( const QString &a, const QString &b ); Meta::TrackList m_allTracks; /** The starting track that is to be processed. */ int m_trackOffset; //options QString m_format; QString m_folderPrefix; bool m_postfixThe; bool m_AsciiOnly; bool m_UnderscoresNotSpaces; bool m_vfatSafe; QString m_regexPattern; QString m_replaceString; QString m_targetFileExtension; }; #endif // TRACKORGANIZER_H diff --git a/src/playlist/layouts/LayoutEditDialog.cpp b/src/playlist/layouts/LayoutEditDialog.cpp index 8f23fd641e..116f44c9a1 100644 --- a/src/playlist/layouts/LayoutEditDialog.cpp +++ b/src/playlist/layouts/LayoutEditDialog.cpp @@ -1,299 +1,299 @@ /**************************************************************************************** * Copyright (c) 2009 Thomas Lübking . * ****************************************************************************************/ #include "LayoutEditDialog.h" #include "widgets/TokenWithLayout.h" #include "widgets/TokenDropTarget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class HintingLineEdit : public QLineEdit { public: HintingLineEdit( const QString &hint = QString(), QWidget *parent = 0 ) : QLineEdit( parent ), m_hint( hint ) { } void setHint( const QString &hint ) { m_hint = hint; } protected: void paintEvent ( QPaintEvent *pe ) { QLineEdit::paintEvent( pe ); if ( !hasFocus() && text().isEmpty() ) { QStyleOptionFrame opt; initStyleOption( &opt ); QPainter p(this); QColor fg = palette().color( foregroundRole() ); fg.setAlpha( fg.alpha() / 2 ); p.setPen( fg ); p.drawText( style()->subElementRect( QStyle::SE_LineEditContents, &opt, this ), alignment() | Qt::TextSingleLine | Qt::TextIncludeTrailingSpaces, m_hint ); p.end(); } } private: QString m_hint; }; LayoutEditDialog::LayoutEditDialog( QWidget *parent ) : QDialog( parent ) { setWindowTitle( i18n( "Configuration for" ) ); QFont boldFont = font(); boldFont.setBold( true ); QVBoxLayout *l1 = new QVBoxLayout( this ); QHBoxLayout *l2 = new QHBoxLayout; l2->addWidget( m_prefix = new HintingLineEdit( i18nc( "placeholder for a prefix", "[prefix]" ), this ) ); m_prefix->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); l2->addWidget( m_element = new QLabel( this ) ); m_element->setFont( boldFont ); l2->addWidget( m_suffix = new HintingLineEdit( i18nc( "placeholder for a suffix", "[suffix]" ), this ) ); l1->addLayout( l2 ); QFrame *line = new QFrame( this ); line->setFrameStyle( QFrame::Sunken | QFrame::HLine ); l1->addWidget( line ); QWidget *boxWidget = new QWidget( this ); QLabel *l; #define HAVE_WIDTH_MODES 0 QHBoxLayout *l4 = new QHBoxLayout; l = new QLabel( i18n( "Width: " ), this ); l->setFont( boldFont ); l4->addWidget( l ); l4->addWidget( m_fixedWidth = new QRadioButton( i18n( "Custom" ), this ) ); m_fixedWidth->setToolTip( i18n( "Either a fixed (absolute) value, or a relative value (e.g. 128px or 12%)." ) ); m_fixedWidth->setChecked( true ); #if HAVE_WIDTH_MODES l4->addWidget( m_fitContent = new QRadioButton( i18n( "Fit content" ), this ) ); m_fitContent->setToolTip( i18n( "Fit the element text" ) ); #endif l4->addWidget( m_automaticWidth = new QRadioButton( i18nc( "automatic width", "Automatic" ), this ) ); m_automaticWidth->setToolTip( i18n( "Take homogeneous part of the space available to all elements with automatic width" ) ); l4->addStretch(); boxWidget->connect( m_fixedWidth, SIGNAL(toggled(bool)), SLOT(setEnabled(bool)) ); connect( m_automaticWidth, SIGNAL(toggled(bool)), SLOT(setAutomaticWidth(bool)) ); l1->addLayout( l4 ); QHBoxLayout *l5 = new QHBoxLayout( boxWidget ); l5->addWidget( m_width = new QSlider( Qt::Horizontal, boxWidget ) ); m_width->setRange( 0, 100 ); l = new QLabel( boxWidget ); l5->addWidget( l ); // width->connect( sizeMode, SIGNAL(currentIndexChanged(int)), SLOT(setDisabled()) ) l->setNum( 0 ); l->connect( m_width, SIGNAL(valueChanged(int)), SLOT(setNum(int)) ); #define HAVE_METRICS 0 #if HAVE_METRICS QComboBox *metrics = new QComboBox( this ); metrics->setFrame( false ); metrics->addItem( "%" ); metrics->addItem( "px" ); metrics->addItem( "chars" ); l5->addWidget( metrics ); #else QLabel *metrics = new QLabel( "%", this ); l5->addWidget( metrics ); #endif l1->addWidget( boxWidget ); line = new QFrame( this ); line->setFrameStyle( QFrame::Sunken | QFrame::HLine ); l1->addWidget( line ); QHBoxLayout *l3 = new QHBoxLayout; l = new QLabel( i18n( "Alignment: " ), this ); l->setFont( boldFont ); l3->addWidget( l ); l3->addWidget( m_alignLeft = new QToolButton( this ) ); l3->addWidget( m_alignCenter = new QToolButton( this ) ); l3->addWidget( m_alignRight = new QToolButton( this ) ); l3->addSpacing( 12 ); l = new QLabel( i18n( "Font: " ), this ); l->setFont( boldFont ); l3->addWidget( l ); l3->addWidget( m_bold = new QToolButton( this ) ); l3->addWidget( m_italic = new QToolButton( this ) ); l3->addWidget( m_underline = new QToolButton( this ) ); l3->addStretch(); l1->addLayout( l3 ); QDialogButtonBox *box = new QDialogButtonBox(this); box->addButton( QDialogButtonBox::Cancel ); box->addButton( QDialogButtonBox::Ok ); connect( box, SIGNAL(rejected()), SLOT(close()) ); connect( box, SIGNAL(accepted()), SLOT(apply()) ); l1->addWidget( box ); l1->addStretch(); m_alignLeft->setIcon( KIcon( "format-justify-left" ) ); m_alignLeft->setCheckable( true ); m_alignCenter->setIcon( KIcon( "format-justify-center" ) ); m_alignCenter->setCheckable( true ); m_alignRight->setIcon( KIcon( "format-justify-right" ) ); m_alignRight->setCheckable( true ); QButtonGroup *align = new QButtonGroup( this ); align->setExclusive( true ); align->addButton( m_alignLeft ); align->addButton( m_alignCenter ); align->addButton( m_alignRight ); m_bold->setIcon( KIcon( "format-text-bold" ) ); m_bold->setCheckable( true ); m_italic->setIcon( KIcon( "format-text-italic" ) ); m_italic->setCheckable( true ); m_underline->setIcon( KIcon( "format-text-underline" ) ); m_underline->setCheckable( true ); } void LayoutEditDialog::apply() { if( !m_token ) return; m_token.data()->setPrefix( m_prefix->text() ); m_token.data()->setSuffix( m_suffix->text() ); m_token.data()->setWidth( m_width->value() ); if ( m_alignLeft->isChecked() ) m_token.data()->setAlignment( Qt::AlignLeft ); else if ( m_alignCenter->isChecked() ) m_token.data()->setAlignment( Qt::AlignHCenter ); else if ( m_alignRight->isChecked() ) m_token.data()->setAlignment( Qt::AlignRight ); m_token.data()->setBold( m_bold->isChecked() ); m_token.data()->setItalic( m_italic->isChecked() ); m_token.data()->setUnderline( m_underline->isChecked() ); // we do this here to avoid reliance on the connection order (i.e. prevent close before apply) if( sender() ) close(); } void LayoutEditDialog::close() { m_token.clear(); QDialog::close(); } void LayoutEditDialog::setAutomaticWidth( bool automatic ) { if( automatic ) { m_previousWidth = m_width->value(); - m_width->setMinimum( 0 ); // without setting the minumum we can't set the value.. + m_width->setMinimum( 0 ); // without setting the minimum we can't set the value.. m_width->setValue( 0 ); // automatic width is represented by width == 0 } else { m_width->setValue( m_previousWidth ); m_width->setMinimum( 1 ); // set minimum back to 1 since "0" means automatic } } void LayoutEditDialog::setToken( TokenWithLayout *t ) { setWindowTitle( i18n( "Configuration for '%1'", t->name() ) ); apply(); m_token = t; if ( m_token ) { m_element->setText( m_token.data()->name() ); m_prefix->setText( m_token.data()->prefix() ); m_suffix->setText( m_token.data()->suffix() ); // Compute the remaining space from the tokens on the same line. // this should still not be done here as it makes upward assumptions // solution(?) token->element->row->elements TokenDropTarget *editWidget = qobject_cast( m_token.data()->parentWidget() ); if( editWidget ) { qreal spareWidth = 100.0; int row = editWidget->row( m_token.data() ); if( row > -1 ) { QList tokens = editWidget->tokensAtRow( row ); foreach ( Token *token, tokens ) { if ( token == m_token.data() ) continue; if ( TokenWithLayout *twl = qobject_cast( token ) ) spareWidth -= twl->width() * 100.0; } } int max = qMax( spareWidth, qreal( 0.0 ) ); if( max >= m_token.data()->width() * 100.0 ) m_width->setMaximum( qMax( spareWidth, qreal( 0.0 ) ) ); else m_width->setMaximum( m_token.data()->width() * 100.0 ); } m_width->setValue( m_token.data()->width() * 100.0 ); m_previousWidth = m_width->value(); if ( m_token.data()->width() > 0.0 ) m_fixedWidth->setChecked( true ); else m_automaticWidth->setChecked( true ); if ( m_token.data()->alignment() & Qt::AlignLeft ) m_alignLeft->setChecked(true); else if ( m_token.data()->alignment() & Qt::AlignHCenter ) m_alignCenter->setChecked(true); else if ( m_token.data()->alignment() & Qt::AlignRight ) m_alignRight->setChecked(true); m_bold->setChecked( m_token.data()->bold() ); m_italic->setChecked( m_token.data()->italic() ); m_underline->setChecked( m_token.data()->underline() ); } } #include "LayoutEditDialog.moc" diff --git a/src/scripting/scriptengine/AmarokPlaylistScript.h b/src/scripting/scriptengine/AmarokPlaylistScript.h index 395cf25ac4..7506362a5c 100644 --- a/src/scripting/scriptengine/AmarokPlaylistScript.h +++ b/src/scripting/scriptengine/AmarokPlaylistScript.h @@ -1,178 +1,178 @@ /**************************************************************************************** * Copyright (c) 2008 Peter ZHOU * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef AMAROK_PLAYLIST_SCRIPT_H #define AMAROK_PLAYLIST_SCRIPT_H #include "core/meta/forward_declarations.h" #include #include #include class QModelIndex; class QUrl; namespace AmarokScript { class AmarokScriptEngine; // SCRIPTDOX: Amarok.Playlist class AmarokPlaylistScript : public QObject { Q_OBJECT public: AmarokPlaylistScript( AmarokScriptEngine *engine ); /** * Return the index of the currently playing track in the playlist. */ Q_INVOKABLE int activeIndex(); /** * Return the number of tracks in the playlist. */ Q_INVOKABLE int totalTrackCount(); /** * Save the current playlist in the default playlist path. */ Q_INVOKABLE QString saveCurrentPlaylist(); /** * Load the track represented by the url and append to playlist. */ Q_INVOKABLE void addMedia( const QUrl &url ); /** * Append @param track to playlist. */ Q_INVOKABLE void addTrack( Meta::TrackPtr track ); /** * Load the list of tracks represented by the urls and append to playlist. */ Q_INVOKABLE void addMediaList( const QList &urls ); /** * Append the list of tracks to playlist. */ Q_INVOKABLE void addTrackList( const Meta::TrackList &tracks ); /** * Clear the current playlist. */ Q_INVOKABLE void clearPlaylist(); /** * Play the track at the specified index in the playlist. */ Q_INVOKABLE void playByIndex( int index ); /** * Prepend the the track represented by the passed url and start playing it. */ Q_INVOKABLE void playMedia( const QUrl &url ); /** * Prepend @param track and start playing it. */ Q_INVOKABLE void playTrack( Meta::TrackPtr track ); /** - * Prepend the the tracks represented by the passed urls and start playing them. + * Prepend the tracks represented by the passed urls and start playing them. */ Q_INVOKABLE void playMediaList( const QList &urls ); /** * Prepend tracks in @param trackList and start playing them. */ Q_INVOKABLE void playTrackList( const Meta::TrackList &trackList ); /** * Remove the currently playing track from the playlist. */ Q_INVOKABLE void removeCurrentTrack(); /** * Remove the track at @param index from the playlist. */ Q_INVOKABLE void removeByIndex( int index ); /** * Save the current playlist at the absolute path @param path. */ Q_INVOKABLE void savePlaylist( const QString& path ); /** * Set whether to stop playing after the current track. */ Q_INVOKABLE void setStopAfterCurrent( bool on ); /* * Indicates whether will stop playing after the current track. */ Q_INVOKABLE bool stopAfterCurrent(); /** * Show/ Hide the playlist. */ Q_INVOKABLE void togglePlaylist(); /** * Return a list of urls representing all the tracks in the playlist. */ Q_INVOKABLE QStringList filenames(); /** * Return the track at the specified position in the playlist. */ Q_INVOKABLE Meta::TrackPtr trackAt( int row ); /** * Get an unsorted list of indices of the currently selected tracks in the playlist. */ Q_INVOKABLE QList selectedIndexes(); /** * Get an unsorted list of urls of the currently selected tracks in the playlist. */ Q_INVOKABLE QStringList selectedFilenames(); signals: /** * Emitted when tracks are added to the playlist. */ void trackInserted( int start, int end ); /** * Emitted when tracks are removed from the playlist. */ void trackRemoved( int start, int end ); private slots: void slotTrackInserted( const QModelIndex&, int start, int end ); void slotTrackRemoved( const QModelIndex&, int start, int end ); private: AmarokScriptEngine* m_scriptEngine; }; } Q_DECLARE_METATYPE( QList ) #endif diff --git a/src/scripting/scriptengine/exporters/CollectionTypeExporter.h b/src/scripting/scriptengine/exporters/CollectionTypeExporter.h index 43a04f89ce..fa885b93c3 100644 --- a/src/scripting/scriptengine/exporters/CollectionTypeExporter.h +++ b/src/scripting/scriptengine/exporters/CollectionTypeExporter.h @@ -1,240 +1,240 @@ /**************************************************************************************** * Copyright (c) 2013 Anmol Ahuja * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef COLLECTIONTYPE_EXPORTER_H #define COLLECTIONTYPE_EXPORTER_H #include "amarok_export.h" #include "core/meta/forward_declarations.h" #include "core/collections/Collection.h" #include "core/collections/CollectionLocation.h" #include #include #include #include #include namespace Collections { class Collection; class QueryMaker; } class QScriptEngine; class QScriptValue; namespace AmarokScript { // SCRIPTDOX PROTOTYPE Collections::Collection Collection #ifdef DEBUG class AMAROK_EXPORT #else class #endif CollectionPrototype : public QObject { Q_OBJECT /** * Indicates whether user can choose track file path within this collection. */ Q_PROPERTY( bool isOrganizable READ isOrganizable ) /** * Indicates whether this collection can be written to (tracks added, removed). */ Q_PROPERTY( bool isWritable READ isWritable ) /** * A unique identifier for this collection */ Q_PROPERTY( QString collectionId READ collectionId ) /** * A user visible name for this collection. */ Q_PROPERTY( QString prettyName READ toString ) /** * The used space on this collection. */ Q_PROPERTY( float usedCapacity READ usedCapacity ) /** * The total storage capacity the collection. */ Q_PROPERTY( float totalCapacity READ totalCapacity ) /** * Indicates whether this collection still exists. */ Q_PROPERTY( bool isValid READ isValid ) /** * An icon representing this collection. */ Q_PROPERTY( QIcon icon READ icon ) /** * Indicates whether this collection can be queried using a * QueryMaker object */ Q_PROPERTY( bool isQueryable READ isQueryable ) /** * Indicates whether the collection is viewable in the browser. */ Q_PROPERTY( bool isViewable READ isViewable ) /** * Indicated whether tracks may be transcoded when copying tracks to this collection. */ Q_PROPERTY( bool supportsTranscode READ supportsTranscode ) /** * A displayable string representation of the collection's location. use the return * value of this method to display the collection location to the user. * @return a string representation of the collection location */ Q_PROPERTY( QString prettyLocation READ prettyLocation ) /** * Returns a list of machine usable string*s representingthe collection location. * For example, a local collection would return a list of paths where tracks are * stored, while an Ampache collection would return a list with one string * containing the URL of an ampache server. Empty for collections like iPod collection and * MTP devices. */ Q_PROPERTY( QStringList actualLocation READ actualLocation ) public: static void init( QScriptEngine *engine ); CollectionPrototype( Collections::Collection *collection ); Collections::Collection* data() const { return m_collection.data(); } /** * Copy a list of tracks to the destination collection */ Q_INVOKABLE void copyTracks( const Meta::TrackList &tracks, Collections::Collection *targetCollection ); /** * Copy a single track to the destination collection */ Q_INVOKABLE void copyTracks( const Meta::TrackPtr track, Collections::Collection *targetCollection ); /** * Convenience method for copying tracks based on QueryMaker results, * takes ownership of the @param qm (The querymaker is rendered invalid * after copying). * @see copyTracks( Meta::TrackList, CollectionLocation* ) */ Q_INVOKABLE void queryAndCopyTracks( Collections::QueryMaker *queryMaker, Collections::Collection *targetCollection ); /** * Copy an array of tracks to the destination collection. */ Q_INVOKABLE void moveTracks( const Meta::TrackList &tracks, Collections::Collection *targetCollection ); /** * Move a single track to the destination collection. */ Q_INVOKABLE void moveTracks( const Meta::TrackPtr track, Collections::Collection *targetCollection ); /** * Convenience method for moving tracks based on QueryMaker results, * takes ownership of the @param qm (The querymaker is rendered invalid * after moving). * @see moveTracks( Meta::TrackList, CollectionLocation* ) */ Q_INVOKABLE void queryAndMoveTracks( Collections::QueryMaker *queryMaker, Collections::Collection *targetCollection ); /** * Remove an array of tracks from collection. */ Q_INVOKABLE void removeTracks( const Meta::TrackList &trackList ); /** * Remove single track from collection. */ Q_INVOKABLE void removeTracks( const Meta::TrackPtr track ); /** * Convenience method for removing tracks selected by QueryMaker, * takes ownership of the @param qm (The querymaker is rendered invalid * after the removal). * @see removeTracks( Meta::TrackList ) */ Q_INVOKABLE void queryAndRemoveTracks( Collections::QueryMaker *qm ); /** * A querymaker object for querying the collection. */ Q_INVOKABLE Collections::QueryMaker *queryMaker(); private: QWeakPointer m_collection; bool isOrganizable() const; bool isWritable() const; QString collectionId() const; QString toString() const; float usedCapacity() const; float totalCapacity() const; bool isValid() const; QIcon icon() const; bool isQueryable() const; bool isViewable() const ; bool supportsTranscode() const; QString prettyLocation() const; QStringList actualLocation() const; Meta::TrackList removeInvalidTracks( const Meta::TrackList &tracks ); signals: /** * This signal will be emitted after major changes to the collection * e.g. new songs where added, or an album changed * from compilation to non-compilation (and vice versa) * it will not be emitted on minor changes (e.g. the tags of a song were changed) * * This means that previously done searches can no longer * be considered valid. */ void updated(); /** - * Emited when this collection is removed. + * Emitted when this collection is removed. */ void removed(); /** * Emitted when a copy operation from/ to this collection has finished. */ void finishCopy(); /** * Emitted when a removal operation on this collection has finished. */ void finishRemove(); /** * Emitted when a copy/ move operation from/ to this collection was aborted. */ void aborted(); }; } #endif diff --git a/src/services/lastfm/meta/LastFmMeta.h b/src/services/lastfm/meta/LastFmMeta.h index 3d8e275286..5413f529f0 100644 --- a/src/services/lastfm/meta/LastFmMeta.h +++ b/src/services/lastfm/meta/LastFmMeta.h @@ -1,122 +1,122 @@ /**************************************************************************************** * Copyright (c) 2007 Maximilian Kossick * * Copyright (c) 2008 Shane King * * Copyright (c) 2008 Leo Franchi * * * * This program is free software; you can redistribute it and/or modify it under * * the terms of the GNU General Public License as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any later * * version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * ****************************************************************************************/ #ifndef AMAROK_LASTFMMETA_H #define AMAROK_LASTFMMETA_H #include "core/meta/Meta.h" #include "core/capabilities/Capability.h" #include "services/ServiceMetaBase.h" // for the SourceInfoProvider namespace lastfm { class Track; } namespace LastFm { class Track : public QObject, public Meta::Track, public SourceInfoProvider { Q_OBJECT public: class Private; Track( const QString &lastFmUri ); - Track( lastfm::Track track ); //Convienience Constructor to allow constructing a Meta::LastFmTrack from a LastFmTrack (confusing?) + Track( lastfm::Track track ); //Convenience Constructor to allow constructing a Meta::LastFmTrack from a LastFmTrack (confusing?) virtual ~Track(); // methods inherited from Meta::Base virtual QString name() const; virtual QString sortableName() const; // methods inherited from Meta::Track virtual KUrl playableUrl() const; virtual QString prettyUrl() const; virtual QString uidUrl() const; virtual QString notPlayableReason() const; virtual Meta::AlbumPtr album() const; virtual Meta::ArtistPtr artist() const; virtual Meta::GenrePtr genre() const; virtual Meta::ComposerPtr composer() const; virtual Meta::YearPtr year() const; virtual qreal bpm() const; virtual QString comment() const; virtual int trackNumber() const; virtual int discNumber() const; virtual qint64 length() const; virtual int filesize() const; virtual int sampleRate() const; virtual int bitrate() const; virtual QString type() const; virtual bool inCollection() const; virtual Collections::Collection *collection() const; virtual bool hasCapabilityInterface( Capabilities::Capability::Type type ) const; virtual Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ); virtual Meta::StatisticsPtr statistics(); // own methods: void setTrackInfo( const lastfm::Track &trackInfo ); virtual QString sourceName(); virtual QString sourceDescription(); virtual QPixmap emblem(); virtual QString scalableEmblem(); //LastFm specific methods, cast the object to LastFm::Track to use them //you can cast the Track when type() returns "stream/lastfm" (or use a dynamic cast:) KUrl internalUrl() const; // this returns the private temporary url to the .mp3, DO NOT USE, // if you are asking, it has already expired QString streamName() const; // A nice name for the stream.. public slots: void ban(); private slots: void slotResultReady(); void slotWsReply(); signals: void skipTrack(); // needed for communication with multiplayablecapability private: void init( int id = -1 ); //use a d-pointer because some code is going to work directly with LastFm::Track Private * const d; QList< QAction * > m_trackActions; }; class LastFmProviderCapability : public Capabilities::Capability { public: LastFmProviderCapability(); ~LastFmProviderCapability(); }; typedef KSharedPtr TrackPtr; } #endif