diff --git a/src/App.h b/src/App.h --- a/src/App.h +++ b/src/App.h @@ -93,7 +93,7 @@ QStringList s_delayedAmarokUrls; }; -#define pApp static_cast(QCoreApplication::instance()) +#define pApp App::instance() #endif // AMAROK_APP_H diff --git a/src/GlobalCollectionActions.h b/src/GlobalCollectionActions.h --- a/src/GlobalCollectionActions.h +++ b/src/GlobalCollectionActions.h @@ -19,7 +19,6 @@ #include "amarok_export.h" #include "core/meta/forward_declarations.h" -#include "core/support/SmartPointerList.h" #include @@ -157,12 +156,12 @@ QList actionsFor( Meta::YearPtr year ); QList actionsFor( Meta::ComposerPtr composer ); - SmartPointerList m_genreActions; - SmartPointerList m_artistActions; - SmartPointerList m_albumActions; - SmartPointerList m_trackActions; - SmartPointerList m_yearActions; - SmartPointerList m_composerActions; + QList m_genreActions; + QList m_artistActions; + QList m_albumActions; + QList m_trackActions; + QList m_yearActions; + QList m_composerActions; }; #endif diff --git a/src/GlobalCurrentTrackActions.h b/src/GlobalCurrentTrackActions.h --- a/src/GlobalCurrentTrackActions.h +++ b/src/GlobalCurrentTrackActions.h @@ -19,7 +19,9 @@ #include "amarok_export.h" #include "core/meta/forward_declarations.h" -#include "core/support/SmartPointerList.h" + +#include + class GlobalCurrentTrackActions; class QAction; @@ -33,7 +35,7 @@ @author Nikolaj Hald Nielsen */ -class AMAROK_EXPORT GlobalCurrentTrackActions +class AMAROK_EXPORT GlobalCurrentTrackActions : public QObject { friend GlobalCurrentTrackActions* The::globalCurrentTrackActions(); @@ -45,7 +47,7 @@ GlobalCurrentTrackActions(); ~GlobalCurrentTrackActions(); - SmartPointerList m_actions; + QList m_actions; }; #endif diff --git a/src/GlobalCurrentTrackActions.cpp b/src/GlobalCurrentTrackActions.cpp --- a/src/GlobalCurrentTrackActions.cpp +++ b/src/GlobalCurrentTrackActions.cpp @@ -36,25 +36,18 @@ GlobalCurrentTrackActions::GlobalCurrentTrackActions() {} - GlobalCurrentTrackActions::~GlobalCurrentTrackActions() {} void GlobalCurrentTrackActions::addAction( QAction * action ) { m_actions.append( action ); + QObject::connect( action, &QObject::destroyed, this, [this, action]() { m_actions.removeAll( action ); } ); } QList< QAction * > GlobalCurrentTrackActions::actions() { - // Here we filter out dangling pointers to already destroyed QActions - - QList validActions; - - foreach( QAction* action, m_actions ) - validActions.append( action ); - - return validActions; + return m_actions; } diff --git a/src/MainWindow.h b/src/MainWindow.h --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -66,8 +66,6 @@ */ class AMAROK_EXPORT MainWindow : public KMainWindow { - friend MainWindow* The::mainWindow(); - Q_OBJECT public: @@ -211,8 +209,6 @@ int m_lastBrowser; int m_searchField; - static QPointer s_instance; - bool m_waitingForCd; }; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -23,6 +23,7 @@ #include "MainWindow.h" +#include "App.h" #include "ActionClasses.h" #include "EngineController.h" //for actions in ctor #include "KNotificationBackend.h" @@ -112,10 +113,8 @@ extern OcsData ocsData; -QPointer MainWindow::s_instance; - namespace The { - MainWindow* mainWindow() { return MainWindow::s_instance.data(); } + MainWindow* mainWindow() { return pApp->mainWindow(); } } MainWindow::MainWindow() @@ -127,7 +126,6 @@ DEBUG_BLOCK setObjectName( "MainWindow" ); - s_instance = this; #ifdef Q_WS_MAC (void)new GrowlInterface( qApp->applicationName() ); diff --git a/src/PluginManager.h b/src/PluginManager.h --- a/src/PluginManager.h +++ b/src/PluginManager.h @@ -67,12 +67,9 @@ /** Returns enabled plugin factories for the given plugin type. * - * This function will only return enable factories. - * - * Owner of the PluginFactory pointers is the PluginManager - * and the pointers will only be valid while the PluginManager exists. + * This function will only return factories for enabled plugins. */ - QList factories( Type type ) const; + QList > factories( Type type ) const; KPluginInfo::List plugins( Type type ) const; @@ -98,14 +95,14 @@ */ bool isPluginEnabled( const KPluginMetaData &plugin ) const; - /** Creates a factories for an info */ - PluginFactory* createFactory( const KPluginMetaData &pluginInfo ); + /** Creates a factories for a plugin */ + QSharedPointer createFactory( const KPluginMetaData &pluginInfo ); /// contains the names of all KPluginInfos that have factories created QVector m_plugins; QHash > m_pluginsByType; - QHash > m_factoriesByType; - QHash m_factoryCreated; + QHash > > m_factoriesByType; + QHash> m_factoryCreated; static const int s_pluginFrameworkVersion; static PluginManager *s_instance; diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -74,7 +74,7 @@ Plugins::PluginManager::~PluginManager() { // tell the managers to get rid of their current factories - QList emptyFactories; + QList > emptyFactories; StatSyncing::Controller *controller = Amarok::Components::statSyncingController(); if( controller ) @@ -119,7 +119,7 @@ return enabledList; } -QList +QList > Plugins::PluginManager::factories( Type type ) const { return m_factoriesByType.value( type ); @@ -155,7 +155,7 @@ for( const auto &pluginInfo : m_plugins ) { // create the factories and sort them by type - PluginFactory *factory = createFactory( pluginInfo ); + auto factory = createFactory( pluginInfo ); if( factory ) { @@ -265,7 +265,7 @@ } -Plugins::PluginFactory* +QSharedPointer Plugins::PluginManager::createFactory( const KPluginMetaData &pluginInfo ) { debug() << "Creating factory for plugin:" << pluginInfo.pluginId(); @@ -280,13 +280,14 @@ return m_factoryCreated.value( name ); QPluginLoader loader( pluginInfo.fileName() ); - auto pluginFactory = qobject_cast( loader.instance() ); + auto pointer = qobject_cast( loader.instance() ); + auto pluginFactory = QSharedPointer( pointer ); if( !pluginFactory ) { warning() << QString( "Failed to get factory '%1' from QPluginLoader: %2" ) .arg( name, loader.errorString() ); - return Q_NULLPTR; + return QSharedPointer(); } m_factoryCreated[ name ] = pluginFactory; diff --git a/src/TrayIcon.h b/src/TrayIcon.h --- a/src/TrayIcon.h +++ b/src/TrayIcon.h @@ -22,10 +22,10 @@ #include // baseclass #include "core/meta/forward_declarations.h" -#include "core/support/SmartPointerList.h" #include + class QAction; namespace Amarok { @@ -54,7 +54,7 @@ private: Meta::TrackPtr m_track; - SmartPointerList m_extraActions; + QList m_extraActions; QPointer m_separator; }; diff --git a/src/TrayIcon.cpp b/src/TrayIcon.cpp --- a/src/TrayIcon.cpp +++ b/src/TrayIcon.cpp @@ -289,20 +289,28 @@ if( m_track ) { foreach( QAction *action, The::globalCurrentTrackActions()->actions() ) + { m_extraActions.append( action ); + connect( action, &QObject::destroyed, this, [this, action]() { m_extraActions.removeAll( action ); } ); + } QScopedPointer ac( m_track->create() ); if( ac ) { QList actions = ac->actions(); foreach( QAction *action, actions ) + { m_extraActions.append( action ); + connect( action, &QObject::destroyed, this, [this, action]() { m_extraActions.removeAll( action ); } ); + } } QScopedPointer btc( m_track->create() ); if( btc ) { - m_extraActions.append( btc->bookmarkAction() ); + QAction *action = btc->bookmarkAction(); + m_extraActions.append( action ); + connect( action, &QObject::destroyed, this, [this, action]() { m_extraActions.removeAll( action ); } ); } } diff --git a/src/browsers/BrowserMessageArea.h b/src/browsers/BrowserMessageArea.h --- a/src/browsers/BrowserMessageArea.h +++ b/src/browsers/BrowserMessageArea.h @@ -39,23 +39,21 @@ /* Amarok::Logger virtual methods */ virtual void shortMessage( const QString &text ); virtual void longMessage( const QString &text, MessageType type ); + virtual void newProgressOperationImpl( KJob * job, const QString & text, QObject *context, + const std::function &function, Qt::ConnectionType type ) override; - virtual void newProgressOperation( KJob *job, const QString &text, QObject *obj, - const char *slot, Qt::ConnectionType type ); + virtual void newProgressOperationImpl( QNetworkReply *reply, const QString &text, QObject *obj, + const std::function &function, Qt::ConnectionType type ) override; - virtual void newProgressOperation( QNetworkReply *reply, const QString &text, QObject *obj, - const char *slot, Qt::ConnectionType type ); - - virtual void newProgressOperation( QObject *sender, const QString &text, int maximum, - QObject *obj, const char *slot, Qt::ConnectionType type ); + virtual void newProgressOperationImpl( QObject *sender, const QMetaMethod &increment, const QMetaMethod &end, const QString &text, + int maximum, QObject *obj, const std::function &function, Qt::ConnectionType type ) override; Q_SIGNALS: void signalLongMessage( const QString & text, MessageType type ); private Q_SLOTS: void hideProgress(); void nextShortMessage(); - void hideLongMessage(); void slotLongMessage( const QString &text, MessageType type = Information ); private: diff --git a/src/browsers/BrowserMessageArea.cpp b/src/browsers/BrowserMessageArea.cpp --- a/src/browsers/BrowserMessageArea.cpp +++ b/src/browsers/BrowserMessageArea.cpp @@ -75,51 +75,56 @@ } void -BrowserMessageArea::newProgressOperation( KJob *job, const QString &text, QObject *obj, - const char *slot, Qt::ConnectionType type ) +BrowserMessageArea::newProgressOperationImpl( KJob *job, const QString &text, QObject *context, + const std::function &function, Qt::ConnectionType type ) { KJobProgressBar *newBar = new KJobProgressBar( 0, job ); newBar->setDescription( text ); connect( job, &KJob::destroyed, m_progressBar, &CompoundProgressBar::endProgressOperation ); - newBar->setAbortSlot( obj, slot, type ); + newBar->setAbortSlot( context, function, type ); m_progressBar->addProgressBar( newBar, job ); m_progressBar->show(); m_busy = true; } void -BrowserMessageArea::newProgressOperation( QNetworkReply *reply, const QString &text, QObject *obj, - const char *slot, Qt::ConnectionType type ) +BrowserMessageArea::newProgressOperationImpl( QNetworkReply *reply, const QString &text, QObject *obj, + const std::function &function, Qt::ConnectionType type ) { NetworkProgressBar *newBar = new NetworkProgressBar( 0, reply ); newBar->setDescription( text ); newBar->setAbortSlot( reply, &QNetworkReply::deleteLater ); connect( reply, &QNetworkReply::destroyed, m_progressBar, &CompoundProgressBar::endProgressOperation ); - newBar->setAbortSlot( obj, slot, type ); + newBar->setAbortSlot( obj, function, type ); m_progressBar->addProgressBar( newBar, reply ); m_progressBar->show(); m_busy = true; } void -BrowserMessageArea::newProgressOperation( QObject *sender, const QString &text, int maximum, - QObject *obj, const char *slot, Qt::ConnectionType type ) +BrowserMessageArea::newProgressOperationImpl( QObject *sender, const QMetaMethod &increment, const QMetaMethod &end, const QString &text, + int maximum, QObject *obj, const std::function &function, Qt::ConnectionType type ) { ProgressBar *newBar = new ProgressBar( 0 ); newBar->setDescription( text ); newBar->setMaximum( maximum ); connect( sender, &QObject::destroyed, m_progressBar, &CompoundProgressBar::endProgressOperation, Qt::QueuedConnection ); - connect( sender, SIGNAL(endProgressOperation(QObject*)), m_progressBar, - SLOT(endProgressOperation(QObject*)), Qt::QueuedConnection ); - connect( sender, SIGNAL(incrementProgress()), m_progressBar, - SLOT(slotIncrementProgress()), Qt::QueuedConnection ); - connect( sender, SIGNAL(totalSteps(int)), newBar, SLOT(slotTotalSteps(int)) ); - newBar->setAbortSlot( obj, slot, type ); + int endIndex = m_progressBar->staticMetaObject.indexOfMethod( SLOT(endProgressOperation(QObject*)) ); + auto endSlot = m_progressBar->staticMetaObject.method( endIndex ); + connect( sender, end, m_progressBar, + endSlot, Qt::QueuedConnection ); + int incrementIndex = m_progressBar->staticMetaObject.indexOfMethod( SLOT(slotIncrementProgress()) ); + auto incrementSlot = m_progressBar->staticMetaObject.method( incrementIndex ); + connect( sender, increment, m_progressBar, + incrementSlot, Qt::QueuedConnection ); + if( sender->staticMetaObject.indexOfSignal( SIGNAL(totalSteps(int)) ) != -1 ) + connect( sender, SIGNAL(totalSteps(int)), newBar, SLOT(slotTotalSteps(int)) ); + newBar->setAbortSlot( obj, function, type ); m_progressBar->addProgressBar( newBar, sender ); m_progressBar->show(); @@ -152,15 +157,11 @@ } } -void -BrowserMessageArea::hideLongMessage() -{ - sender()->deleteLater(); -} - void BrowserMessageArea::slotLongMessage( const QString &text, MessageType type ) { - LongMessageWidget *message = new LongMessageWidget( this, text, type ); - connect( message, &LongMessageWidget::closed, this, &BrowserMessageArea::hideLongMessage ); + Q_UNUSED(type) + + LongMessageWidget *message = new LongMessageWidget( text ); + connect( message, &LongMessageWidget::closed, message, &QObject::deleteLater ); } diff --git a/src/configdialog/dialogs/DatabaseConfig.cpp b/src/configdialog/dialogs/DatabaseConfig.cpp --- a/src/configdialog/dialogs/DatabaseConfig.cpp +++ b/src/configdialog/dialogs/DatabaseConfig.cpp @@ -40,10 +40,9 @@ // enable the test button if one of the plugin factories has a correct testSettings slot // get all storage factories - QList factories; - factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage ); + auto factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage ); bool testFunctionAvailable = false; - foreach( Plugins::PluginFactory* factory, factories ) + for( const auto &factory : factories ) { // check the meta object if there is a testSettings slot available if( factory->metaObject()-> @@ -79,16 +78,15 @@ DatabaseConfig::testDatabaseConnection() //SLOT { // get all storage factories - QList factories; - factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage ); + auto factories = Plugins::PluginManager::instance()->factories( Plugins::PluginManager::Storage ); // try if they have a testSettings slot that we can call - foreach( Plugins::PluginFactory* factory, factories ) + for( const auto &factory : factories ) { bool callSucceeded = false; QStringList connectionErrors; - callSucceeded = QMetaObject::invokeMethod( factory, + callSucceeded = QMetaObject::invokeMethod( factory.data(), "testSettings", Q_RETURN_ARG( QStringList, connectionErrors ), Q_ARG( QString, kcfg_Host->text() ), diff --git a/src/core-impl/collections/db/sql/SqlCollectionLocation.cpp b/src/core-impl/collections/db/sql/SqlCollectionLocation.cpp --- a/src/core-impl/collections/db/sql/SqlCollectionLocation.cpp +++ b/src/core-impl/collections/db/sql/SqlCollectionLocation.cpp @@ -478,7 +478,7 @@ QString statusBarTxt = operationInProgressText( configuration, sources.count() ); m_transferjob = new TransferJob( this, configuration ); Amarok::Components::logger()->newProgressOperation( m_transferjob, statusBarTxt, this, - SLOT(slotTransferJobAborted()) ); + &SqlCollectionLocation::slotTransferJobAborted ); connect( m_transferjob, &Collections::TransferJob::result, this, &SqlCollectionLocation::slotTransferJobFinished ); m_transferjob->start(); diff --git a/src/core-impl/collections/ipodcollection/IpodCollectionLocation.cpp b/src/core-impl/collections/ipodcollection/IpodCollectionLocation.cpp --- a/src/core-impl/collections/ipodcollection/IpodCollectionLocation.cpp +++ b/src/core-impl/collections/ipodcollection/IpodCollectionLocation.cpp @@ -73,7 +73,8 @@ IpodCopyTracksJob *job = new IpodCopyTracksJob( sources, m_coll, configuration, isGoingToRemoveSources() ); int trackCount = sources.size(); Amarok::Components::logger()->newProgressOperation( job, - operationInProgressText( configuration, trackCount ), trackCount, job, SLOT(abort()) ); + operationInProgressText( configuration, trackCount ), + trackCount, job, &IpodCopyTracksJob::abort ); qRegisterMetaType( "IpodCopyTracksJob::CopiedStatus" ); connect( job, &IpodCopyTracksJob::signalTrackProcessed, diff --git a/src/core-impl/collections/ipodcollection/jobs/IpodParseTracksJob.cpp b/src/core-impl/collections/ipodcollection/jobs/IpodParseTracksJob.cpp --- a/src/core-impl/collections/ipodcollection/jobs/IpodParseTracksJob.cpp +++ b/src/core-impl/collections/ipodcollection/jobs/IpodParseTracksJob.cpp @@ -56,7 +56,7 @@ guint32 trackNumber = itdb_tracks_number( itdb ); QString operationText = i18nc( "operation when iPod is connected", "Reading iPod tracks" ); Amarok::Components::logger()->newProgressOperation( this, operationText, trackNumber, - this, SLOT(abort()) ); + this, &IpodParseTracksJob::abort ); Meta::TrackList staleTracks; QSet knownPaths; diff --git a/src/core-impl/collections/support/CollectionManager.h b/src/core-impl/collections/support/CollectionManager.h --- a/src/core-impl/collections/support/CollectionManager.h +++ b/src/core-impl/collections/support/CollectionManager.h @@ -131,7 +131,7 @@ * For every factory that is a CollectionFactory uses it to create new * collections and register with this manager. */ - void setFactories( const QList &factories ); + void setFactories( const QList > &factories ); public Q_SLOTS: /** Starts the full scan for each collection with CollectionScanCapability */ diff --git a/src/core-impl/collections/support/CollectionManager.cpp b/src/core-impl/collections/support/CollectionManager.cpp --- a/src/core-impl/collections/support/CollectionManager.cpp +++ b/src/core-impl/collections/support/CollectionManager.cpp @@ -44,7 +44,7 @@ struct CollectionManager::Private { QList collections; - QList factories; // factories belong to PluginManager + QList > factories; // factories belong to PluginManager QList trackProviders; TimecodeTrackProvider *timecodeTrackProvider; @@ -104,10 +104,6 @@ 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; @@ -127,43 +123,43 @@ } void -CollectionManager::setFactories( const QList &factories ) +CollectionManager::setFactories( const QList > &factories ) { using Collections::CollectionFactory; - QSet newFactories = factories.toSet(); - QSet oldFactories; + QSet > newFactories = factories.toSet(); + QSet > oldFactories; { QReadLocker locker( &d->lock ); oldFactories = d->factories.toSet(); } // remove old factories - foreach( Plugins::PluginFactory* pFactory, oldFactories - newFactories ) + for( const auto &pFactory : oldFactories - newFactories ) { - CollectionFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; - disconnect( factory, &CollectionFactory::newCollection, + disconnect( factory.data(), &CollectionFactory::newCollection, this, &CollectionManager::slotNewCollection ); { QWriteLocker locker( &d->lock ); d->factories.removeAll( factory ); } } // create new factories - foreach( Plugins::PluginFactory* pFactory, newFactories - oldFactories ) + for( const auto &pFactory : newFactories - oldFactories ) { - CollectionFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; - connect( factory, &CollectionFactory::newCollection, + connect( factory.data(), &CollectionFactory::newCollection, this, &CollectionManager::slotNewCollection ); { QWriteLocker locker( &d->lock ); diff --git a/src/core-impl/collections/umscollection/UmsCollectionLocation.cpp b/src/core-impl/collections/umscollection/UmsCollectionLocation.cpp --- a/src/core-impl/collections/umscollection/UmsCollectionLocation.cpp +++ b/src/core-impl/collections/umscollection/UmsCollectionLocation.cpp @@ -108,7 +108,7 @@ QString loggerText = operationInProgressText( configuration, sources.count(), m_umsCollection->prettyName() ); Amarok::Components::logger()->newProgressOperation( transferJob, loggerText, transferJob, - SLOT(slotCancel()) ); + &UmsTransferJob::slotCancel ); transferJob->start(); } @@ -127,7 +127,7 @@ "Removing %1 tracks from %2", sourceUrls.count(), m_umsCollection->prettyName() ); KIO::DeleteJob *delJob = KIO::del( sourceUrls, KIO::HideProgressInfo ); - Amarok::Components::logger()->newProgressOperation( delJob, loggerText, delJob, SLOT(kill()) ); + Amarok::Components::logger()->newProgressOperation( delJob, loggerText, delJob, &KIO::DeleteJob::kill, Qt::AutoConnection, KIO::Job::Quietly ); connect( delJob, &KIO::DeleteJob::finished, this, &UmsCollectionLocation::slotRemoveOperationFinished ); } diff --git a/src/core-impl/logger/ProxyLogger.h b/src/core-impl/logger/ProxyLogger.h --- a/src/core-impl/logger/ProxyLogger.h +++ b/src/core-impl/logger/ProxyLogger.h @@ -28,19 +28,24 @@ #include +#include + + class QNetworkReply; typedef QPair LongMessage; struct ProgressData { QPointer sender; + QMetaMethod increment; + QMetaMethod end; QPointer job; QPointer reply; QString text; int maximum; QPointer cancelObject; - const char *slot; + std::function function; Qt::ConnectionType type; }; @@ -68,15 +73,14 @@ public Q_SLOTS: virtual void shortMessage( const QString &text ); virtual void longMessage( const QString &text, MessageType type ); - virtual void newProgressOperation( KJob *job, const QString &text, QObject *obj = 0, - const char *slot = 0, - Qt::ConnectionType type = Qt::AutoConnection ); - virtual void newProgressOperation( QNetworkReply *reply, const QString &text, QObject *obj = 0, - const char *slot = 0, - Qt::ConnectionType type = Qt::AutoConnection ); - virtual void newProgressOperation( QObject *sender, const QString &text, int maximum = 100, - QObject *obj = 0, const char *slot = 0, - Qt::ConnectionType type = Qt::AutoConnection ); + virtual void newProgressOperationImpl( KJob * job, const QString & text, QObject * context, + const std::function &function, Qt::ConnectionType type ) override; + virtual void newProgressOperationImpl( QNetworkReply *reply, const QString &text, QObject *obj, + const std::function &function, + Qt::ConnectionType type ) override; + virtual void newProgressOperationImpl( QObject *sender, const QMetaMethod &increment, const QMetaMethod &end, + const QString &text, int maximum, QObject *obj, + const std::function &function, Qt::ConnectionType type ) override; /** * Set the real logger. diff --git a/src/core-impl/logger/ProxyLogger.cpp b/src/core-impl/logger/ProxyLogger.cpp --- a/src/core-impl/logger/ProxyLogger.cpp +++ b/src/core-impl/logger/ProxyLogger.cpp @@ -80,48 +80,50 @@ emit startTimer(); } -void -ProxyLogger::newProgressOperation( KJob *job, const QString &text, QObject *obj, const char *slot, Qt::ConnectionType type ) +void ProxyLogger::newProgressOperationImpl( KJob* job, const QString& text, QObject* context, const std::function &function, Qt::ConnectionType type ) { QMutexLocker locker( &m_lock ); ProgressData data; data.job = job; data.text = text; - data.cancelObject = obj; - data.slot = slot; + data.cancelObject = context; + data.function = function; data.type = type; m_progressQueue.enqueue( data ); emit startTimer(); } void -ProxyLogger::newProgressOperation( QNetworkReply *reply, const QString &text, QObject *obj, const char *slot, Qt::ConnectionType type ) +ProxyLogger::newProgressOperationImpl( QNetworkReply *reply, const QString &text, QObject *obj, const std::function &function, Qt::ConnectionType type ) { QMutexLocker locker( &m_lock ); ProgressData data; data.reply = reply; data.text = text; data.cancelObject = obj; - data.slot = slot; + data.function = function; data.type = type; m_progressQueue.enqueue( data ); emit startTimer(); } void -ProxyLogger::newProgressOperation( QObject *sender, const QString &text, int maximum, QObject *obj, - const char *slot, Qt::ConnectionType type ) +ProxyLogger::newProgressOperationImpl( QObject *sender, const QMetaMethod &increment, const QMetaMethod &end, const QString &text, + int maximum, QObject *obj, const std::function &function, Qt::ConnectionType type ) { QMutexLocker locker( &m_lock ); ProgressData data; data.sender = sender; + data.increment = increment; + data.end = end; data.text = text; data.maximum = maximum; data.cancelObject = obj; - data.slot = slot; + data.function = function; data.type = type; m_progressQueue.enqueue( data ); - connect( sender, SIGNAL(totalSteps(int)), SLOT(slotTotalSteps(int)) ); + if( sender->staticMetaObject.indexOfSignal( SIGNAL(totalSteps(int)) ) != -1 ) + connect( sender, SIGNAL(totalSteps(int)), SLOT(slotTotalSteps(int)) ); emit startTimer(); } @@ -146,21 +148,21 @@ ProgressData d = m_progressQueue.dequeue(); if( d.job ) { - m_logger->newProgressOperation( d.job.data(), d.text, d.cancelObject.data(), - d.cancelObject.data() ? d.slot : 0 , d.type ); + m_logger->newProgressOperationImpl( d.job.data(), d.text, d.cancelObject.data(), + d.function, d.type ); } else if( d.reply ) { - m_logger->newProgressOperation( d.reply.data(), d.text, d.cancelObject.data(), - d.cancelObject.data() ? d.slot : 0 , d.type ); + m_logger->newProgressOperationImpl( d.reply.data(), d.text, d.cancelObject.data(), + d.function, d.type ); } else if( d.sender ) { // m_logger handles the signals from now on disconnect( d.sender.data(), 0, this, 0 ); - m_logger->newProgressOperation( d.sender.data(), d.text, d.maximum, - d.cancelObject.data(), - d.cancelObject.data() ? d.slot : 0 , d.type ); + m_logger->newProgressOperationImpl( d.sender.data(), d.increment, d.end, d.text, + d.maximum, d.cancelObject.data(), + d.function, d.type ); } } } diff --git a/src/core-impl/podcasts/sql/SqlPodcastProvider.cpp b/src/core-impl/podcasts/sql/SqlPodcastProvider.cpp --- a/src/core-impl/podcasts/sql/SqlPodcastProvider.cpp +++ b/src/core-impl/podcasts/sql/SqlPodcastProvider.cpp @@ -1097,7 +1097,7 @@ const QString &description, Podcasts::PodcastReader* reader ) { - Amarok::Components::logger()->newProgressOperation( job, description, reader, SLOT(slotAbort()) ); + Amarok::Components::logger()->newProgressOperation( job, description, reader, &Podcasts::PodcastReader::slotAbort ); } void @@ -1168,7 +1168,9 @@ : i18n( "Downloading Podcast \"%1\"" , sqlEpisode->title() ), transferJob, - SLOT(kill()) + &KIO::TransferJob::kill, + Qt::AutoConnection, + KJob::Quietly ); connect( transferJob, &KIO::TransferJob::data, diff --git a/src/core-impl/storage/StorageManager.h b/src/core-impl/storage/StorageManager.h --- a/src/core-impl/storage/StorageManager.h +++ b/src/core-impl/storage/StorageManager.h @@ -58,8 +58,7 @@ /** retrieve an interface which allows client-code to store/load data in a relational database. - Note: code using this method does NOT take ownership of the pointer, but may cache the pointer - Note2: You should never modify the database unless you really really know what you do. + Note: You should never modify the database unless you really really know what you do. Using the SqlMeta (e.g. SqlRegistry or SqlTrack) is much better. @return Returns a pointer to the amarok wide SqlStorage or to an internal dummy SqlStorage if that cannot be found. @@ -73,7 +72,7 @@ * For every factory that is a CollectionFactory uses it to create new * collections and register with this manager. */ - void setFactories( const QList &factories ); + void setFactories( const QList > &factories ); /** Returns a list of the last sql errors. The list might not include every one error if the number diff --git a/src/core-impl/storage/StorageManager.cpp b/src/core-impl/storage/StorageManager.cpp --- a/src/core-impl/storage/StorageManager.cpp +++ b/src/core-impl/storage/StorageManager.cpp @@ -136,17 +136,17 @@ } void -StorageManager::setFactories( const QList &factories ) +StorageManager::setFactories( const QList > &factories ) { - foreach( Plugins::PluginFactory* pFactory, factories ) + for( const auto &pFactory : factories ) { - StorageFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; - connect( factory, &StorageFactory::newStorage, + connect( factory.data(), &StorageFactory::newStorage, this, &StorageManager::slotNewStorage ); - connect( factory, &StorageFactory::newError, + connect( factory.data(), &StorageFactory::newError, this, &StorageManager::slotNewError ); } } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -62,7 +62,6 @@ support/Amarok.cpp support/Components.cpp support/SemaphoreReleaser.cpp - support/SmartPointerList.cpp support/PluginFactory.cpp support/Debug.cpp ) diff --git a/src/core/interfaces/Logger.h b/src/core/interfaces/Logger.h --- a/src/core/interfaces/Logger.h +++ b/src/core/interfaces/Logger.h @@ -19,9 +19,12 @@ #include "core/amarokcore_export.h" -#include +#include #include +#include + + class KJob; class QNetworkReply; @@ -43,8 +46,6 @@ Logger() {} virtual ~Logger() {} - public Q_SLOTS: - /** * Informs the user about the progress of a job, i.e. a download job. * At the very least, the user is notified about the start and end of the job. @@ -56,7 +57,15 @@ * The signal will be emitted from the GUI thread. The receiver may not make assumptions about the sender * @param type The Qt connection type to use for the connection to the receiving slot. Defaults to Qt::AutoConnection */ - virtual void newProgressOperation( KJob *job, const QString &text, QObject *obj = 0, const char *slot = 0, Qt::ConnectionType type = Qt::AutoConnection ) = 0; + template + void newProgressOperation( KJob *job, const QString &text, Object *obj = nullptr, Func slot = nullptr, Qt::ConnectionType type = Qt::AutoConnection, FuncArgs... args ) + { + std::function function = [obj, slot, args...] () + { + ( *obj.*slot )( args... ); + }; + newProgressOperationImpl( job, text, obj, obj ? function : nullptr, type ); + } /** * Informs the user about the progress of a network request. @@ -69,12 +78,20 @@ * The signal will be emitted from the GUI thread. The receiver may not make assumptions about the sender * @param type The Qt connection type to use for the connection to the receiving slot. Defaults to Qt::AutoConnection */ - virtual void newProgressOperation( QNetworkReply *reply, const QString &text, QObject *obj = 0, const char *slot = 0, Qt::ConnectionType type = Qt::AutoConnection ) = 0; + template + void newProgressOperation( QNetworkReply *reply, const QString &text, Object *obj = nullptr, Func slot = nullptr, Qt::ConnectionType type = Qt::AutoConnection, FuncArgs... args ) + { + std::function function = [obj, slot, args...] () + { + ( *obj.*slot )( args... ); + }; + newProgressOperationImpl( reply, text, obj, obj ? function : nullptr, type ); + } /** * Informs the user about the progress of a generic QObject * - * @param sender The object sending the required signals. This sender must emit singals + * @param sender The object sending the required signals. This sender must emit signals * incrementProgress() and endProgressOperation() and optionally totalSteps(). * @param text An additional text that will be part of the notification * @param maximum The maximum value of the progress operation @@ -87,9 +104,19 @@ * @param type The Qt connection type to use for the connection to the receiving slot. * Defaults to Qt::AutoConnection */ - virtual void newProgressOperation( QObject *sender, const QString &text, int maximum = 100, - QObject *obj = 0, const char *slot = 0, - Qt::ConnectionType type = Qt::AutoConnection ) = 0; + template + typename std::enable_if::value && !std::is_convertible::value && std::is_convertible::value>::type + newProgressOperation( Sender *sender, const QString &text, int maximum = 100, Object *obj = nullptr, Func slot = nullptr, Qt::ConnectionType type = Qt::AutoConnection, FuncArgs... args ) + { + auto increment = QMetaMethod::fromSignal( &Sender::incrementProgress ); + auto end = QMetaMethod::fromSignal( &Sender::endProgressOperation ); + + std::function function = [obj, slot, args...] () + { + ( *obj.*slot )( args... ); + }; + newProgressOperationImpl( sender, increment, end, text, maximum, obj, obj ? function : nullptr, type ); + } /** * Sends a notification to the user. @@ -106,6 +133,11 @@ * @param type The context of the notification */ virtual void longMessage( const QString &text, MessageType type = Information ) = 0; + + virtual void newProgressOperationImpl( KJob *job, const QString &text, QObject *context, const std::function &function, Qt::ConnectionType type ) = 0; + virtual void newProgressOperationImpl( QNetworkReply *reply, const QString &text, QObject *context, const std::function &function, Qt::ConnectionType type ) = 0; + virtual void newProgressOperationImpl( QObject *sender, const QMetaMethod &increment, const QMetaMethod &end, const QString &text, + int maximum, QObject *context, const std::function &function, Qt::ConnectionType type ) = 0; }; } diff --git a/src/core/support/Amarok.cpp b/src/core/support/Amarok.cpp --- a/src/core/support/Amarok.cpp +++ b/src/core/support/Amarok.cpp @@ -337,6 +337,9 @@ QString vfatPath( const QString &path, PathSeparatorBehaviour behaviour ) { + if( path.isEmpty() ) + return QString(); + QString s = path; QChar separator = ( behaviour == AutoBehaviour ) ? QDir::separator() : ( behaviour == UnixBehaviour ) ? '/' : '\\'; diff --git a/src/core/support/SmartPointerList.h b/src/core/support/SmartPointerList.h deleted file mode 100644 --- a/src/core/support/SmartPointerList.h +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************************** - * Copyright (c) 2009 Mark Kretschmann * - * Copyright (c) 2009 Ian Monroe * - * Copyright (c) 2009 Max Howell * - * * - * 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_SMART_POINTER_LIST_H -#define AMAROK_SMART_POINTER_LIST_H - -#include "core/amarokcore_export.h" - -#include //baseclass -#include //baseclass - -#ifdef Q_CC_MSVC -class SmartPointerListDaddy : public QObject -#else -class AMAROK_CORE_EXPORT SmartPointerListDaddy : public QObject -#endif -{ - Q_OBJECT - QList& m_list; - -public: -#ifdef Q_CC_MSVC - AMAROK_CORE_EXPORT explicit SmartPointerListDaddy( QList* list ) : m_list( *list ) -#else - explicit SmartPointerListDaddy( QList* list ) : m_list( *list ) -#endif - {} - -private Q_SLOTS: - void onDestroyed() - { - m_list.removeAll( sender() ); - } -}; - -/** QList has no virtual functions, so we inherit privately and define the - * interface exactly to ensure users can't write code that breaks the - * class's internal behaviour. - * - * I deliberately didn't define clear. I worried people would assume it - * deleted the pointers. Or assume it didn't. I didn't expose a few other - * functions for that reason. - * - * non-const iterator functions are not exposed as they access the QList - * baseclass, and then the Daddy wouldn't be watching newly inserted items. - * - * --mxcl - * Exposed clear. This class doesn't have a QPtrList autodelete functionality - * ever, so if people think that, they're really confused! -- Ian Monroe - * - */ -template class SmartPointerList : private QList -{ - class SmartPointerListDaddy* m_daddy; - -public: - SmartPointerList() : m_daddy( new SmartPointerListDaddy( (QList*)this ) ) - {} - - ~SmartPointerList() - { - delete m_daddy; - } - - SmartPointerList( const SmartPointerList& that ) - : QList() - , m_daddy( new SmartPointerListDaddy( (QList*)this ) ) - { - QListIterator i( that ); - while (i.hasNext()) - append( i.next() ); - } - - SmartPointerList& operator=( const SmartPointerList& that ) - { - QListIterator i( *this); - while (i.hasNext()) - QObject::disconnect( m_daddy, 0, i.next(), 0 ); - - QList::operator=( that ); - - if (this != &that) { - QListIterator i( that ); - while (i.hasNext()) - m_daddy->connect( i.next(), SIGNAL(destroyed()), SLOT(onDestroyed()) ); - } - - return *this; - } - - // keep same function names as Qt - void append( T* o ) - { - m_daddy->connect( o, SIGNAL(destroyed()), SLOT(onDestroyed()) ); - QList::append( o ); - } - - void prepend( T* o ) - { - m_daddy->connect( o, SIGNAL(destroyed()), SLOT(onDestroyed()) ); - QList::prepend( o ); - } - - SmartPointerList& operator+=( T* o ) - { - append( o ); - return *this; - } - - SmartPointerList& operator<<( T* o ) - { - return operator+=( o ); - } - - SmartPointerList operator+( const SmartPointerList that ) - { - SmartPointerList copy = *this; - QListIterator i( that ); - while (i.hasNext()) - copy.append( i.next() ); - return copy; - } - - SmartPointerList& operator+=( const SmartPointerList that ) - { - QListIterator i( that ); - while (i.hasNext()) - append( i.next() ); - return *this; - } - - void push_back( T* o ) - { - append( o ); - } - - void push_front( T* o ) - { - prepend( o ); - } - - void replace( int i, T* o ) - { - QList::replace( i, o ); - m_daddy->connect( o, SIGNAL(destroyed()), SLOT(onDestroyed()) ); - } - - /** this is a "safe" class. We always bounds check */ - inline T* operator[]( int index ) const { return QList::value( index ); } - inline T* at( int index ) const { return QList::value( index ); } - - // make public safe functions again - using QList::back; - using QList::constBegin; - using QList::constEnd; - using typename QList::const_iterator; - using QList::contains; - using QList::count; - using QList::empty; - using QList::erase; - using QList::first; - using QList::front; - using QList::indexOf; - using QList::insert; - using QList::isEmpty; - using QList::last; - using QList::lastIndexOf; - using QList::mid; - using QList::move; - using QList::pop_back; - using QList::pop_front; - using QList::size; - using QList::swap; - using QList::value; - using QList::operator!=; - using QList::operator==; - - // can't use using directive here since we only want the const versions - typename QList::const_iterator begin() const { return QList::constBegin(); } - typename QList::const_iterator end() const { return QList::constEnd(); } - - // it can lead to poor performance situations if we don't disconnect - // but I think it's not worth making this class more complicated for such - // an edge case - using QList::clear; - using QList::removeAll; - using QList::removeAt; - using QList::removeFirst; - using QList::removeLast; - using QList::removeOne; - using QList::takeAt; - using QList::takeFirst; - using QList::takeLast; -}; - -#endif //HEADER_GUARD diff --git a/src/core/support/SmartPointerList.cpp b/src/core/support/SmartPointerList.cpp deleted file mode 100644 --- a/src/core/support/SmartPointerList.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/**************************************************************************************** - * Copyright (c) 2009 Nikolaj Hald Nielsen * - * Copyright (c) 2009 Mark Kretschmann * - * Copyright (c) 2009 Ian Monroe * - * * - * 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 . * - ****************************************************************************************/ - -//A file to make automoc happy - -#include "core/support/SmartPointerList.h" - diff --git a/src/dynamic/BiasedPlaylist.cpp b/src/dynamic/BiasedPlaylist.cpp --- a/src/dynamic/BiasedPlaylist.cpp +++ b/src/dynamic/BiasedPlaylist.cpp @@ -122,7 +122,7 @@ Amarok::Components::logger()->newProgressOperation( m_solver, i18n( "Generating playlist..." ), 100, - this, SLOT(requestAbort()) ); + this, &BiasedPlaylist::requestAbort ); ThreadWeaver::Queue::instance()->enqueue( QSharedPointer(m_solver) ); diff --git a/src/playlistgenerator/Preset.cpp b/src/playlistgenerator/Preset.cpp --- a/src/playlistgenerator/Preset.cpp +++ b/src/playlistgenerator/Preset.cpp @@ -129,7 +129,7 @@ emit lock( true ); ConstraintSolver* s = static_cast( sender() ); - Amarok::Components::logger()->newProgressOperation( s, i18n("Generating a new playlist"), s->iterationCount(), s, SLOT(requestAbort()), Qt::QueuedConnection ); + Amarok::Components::logger()->newProgressOperation( s, i18n("Generating a new playlist"), s->iterationCount(), s, &ConstraintSolver::requestAbort, Qt::QueuedConnection ); connect( s, &APG::ConstraintSolver::done, this, &Preset::solverFinished, Qt::QueuedConnection ); m_constraintTreeRoot->addChild( ConstraintTypes::TrackSpreader::createNew( m_constraintTreeRoot ), 0 ); // private mandatory constraint diff --git a/src/scanner/AbstractScanResultProcessor.cpp b/src/scanner/AbstractScanResultProcessor.cpp --- a/src/scanner/AbstractScanResultProcessor.cpp +++ b/src/scanner/AbstractScanResultProcessor.cpp @@ -67,7 +67,7 @@ i18n( "Scanning music" ), 100, this, - SLOT(abort()) ); + &AbstractScanResultProcessor::abort ); } diff --git a/src/services/ServicePluginManager.h b/src/services/ServicePluginManager.h --- a/src/services/ServicePluginManager.h +++ b/src/services/ServicePluginManager.h @@ -45,7 +45,7 @@ * Load any services that are configured to be loaded. * Unload any services that have been switched off. */ - void setFactories( const QList &factories ); + void setFactories( const QList > &factories ); public Q_SLOTS: QStringList loadedServices() const; @@ -64,7 +64,7 @@ /** The list of currently set factories. * Note: the PluginManager owns the pointers. */ - QList m_factories; + QList > m_factories; private Q_SLOTS: void slotNewService( ServiceBase *newService); diff --git a/src/services/ServicePluginManager.cpp b/src/services/ServicePluginManager.cpp --- a/src/services/ServicePluginManager.cpp +++ b/src/services/ServicePluginManager.cpp @@ -68,15 +68,15 @@ void -ServicePluginManager::setFactories( const QList &factories ) +ServicePluginManager::setFactories( const QList > &factories ) { - QSet newFactories = factories.toSet(); - QSet oldFactories = m_factories.toSet(); + QSet > newFactories = factories.toSet(); + QSet > oldFactories = m_factories.toSet(); // remove old factories - foreach( Plugins::PluginFactory* pFactory, oldFactories - newFactories ) + for( const auto &pFactory : oldFactories - newFactories ) { - ServiceFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; @@ -86,14 +86,14 @@ } // create new factories - foreach( Plugins::PluginFactory* pFactory, newFactories - oldFactories ) + for( const auto &pFactory : newFactories - oldFactories ) { - ServiceFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; - connect( factory, &ServiceFactory::newService, this, &ServicePluginManager::slotNewService ); - connect( factory, &ServiceFactory::removeService, this, &ServicePluginManager::slotRemoveService ); + connect( factory.data(), &ServiceFactory::newService, this, &ServicePluginManager::slotNewService ); + connect( factory.data(), &ServiceFactory::removeService, this, &ServicePluginManager::slotRemoveService ); } m_factories = factories; @@ -119,9 +119,9 @@ ServicePluginManager::loadedServices() const { QStringList names; - foreach( Plugins::PluginFactory *pFactory, m_factories ) + for( const auto &pFactory : m_factories ) { - ServiceFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; diff --git a/src/services/magnatune/MagnatuneAlbumDownloader.cpp b/src/services/magnatune/MagnatuneAlbumDownloader.cpp --- a/src/services/magnatune/MagnatuneAlbumDownloader.cpp +++ b/src/services/magnatune/MagnatuneAlbumDownloader.cpp @@ -71,7 +71,7 @@ msgText = i18n( "Downloading album from Magnatune.com" ); } - Amarok::Components::logger()->newProgressOperation( m_albumDownloadJob, msgText, this, SLOT(albumDownloadAborted()) ); + Amarok::Components::logger()->newProgressOperation( m_albumDownloadJob, msgText, this, &MagnatuneAlbumDownloader::albumDownloadAborted ); } void @@ -130,7 +130,7 @@ connect( m_coverDownloadJob, &KJob::result, this, &MagnatuneAlbumDownloader::coverDownloadComplete ); - Amarok::Components::logger()->newProgressOperation( m_coverDownloadJob, i18n( "Adding album cover to collection" ), this, SLOT(coverAddAborted()) ); + Amarok::Components::logger()->newProgressOperation( m_coverDownloadJob, i18n( "Adding album cover to collection" ), this, &MagnatuneAlbumDownloader::coverAddAborted ); emit( downloadComplete( true ) ); } diff --git a/src/services/magnatune/MagnatuneStore.cpp b/src/services/magnatune/MagnatuneStore.cpp --- a/src/services/magnatune/MagnatuneStore.cpp +++ b/src/services/magnatune/MagnatuneStore.cpp @@ -323,7 +323,7 @@ m_tempFileName = tempFile.fileName(); m_listDownloadJob = KIO::file_copy( QUrl("http://magnatune.com/info/album_info_xml.bz2"), QUrl::fromLocalFile( m_tempFileName ), 0700 , KIO::HideProgressInfo | KIO::Overwrite ); - Amarok::Components::logger()->newProgressOperation( m_listDownloadJob, i18n( "Downloading Magnatune.com database..." ), this, SLOT(listDownloadCancelled()) ); + Amarok::Components::logger()->newProgressOperation( m_listDownloadJob, i18n( "Downloading Magnatune.com database..." ), this, &MagnatuneStore::listDownloadCancelled ); connect( m_listDownloadJob, &KJob::result, this, &MagnatuneStore::listDownloadComplete ); diff --git a/src/statsyncing/Controller.h b/src/statsyncing/Controller.h --- a/src/statsyncing/Controller.h +++ b/src/statsyncing/Controller.h @@ -76,7 +76,7 @@ * multiple provider instances. This method is called by Amarok's plugin * infrastructure. */ - void setFactories( const QList &factories ); + void setFactories( const QList > &factories ); /** * Returns true if any instantiable provider types are registered with the @@ -212,7 +212,7 @@ * Return true if important metadata of both tracks is equal. */ bool tracksVirtuallyEqual( const Meta::TrackPtr &first, const Meta::TrackPtr &second ); - QMap m_providerFactories; + QMap > m_providerFactories; // synchronization-related ProviderPtrList m_providers; diff --git a/src/statsyncing/Controller.cpp b/src/statsyncing/Controller.cpp --- a/src/statsyncing/Controller.cpp +++ b/src/statsyncing/Controller.cpp @@ -149,11 +149,11 @@ } void -Controller::setFactories( const QList &factories ) +Controller::setFactories( const QList > &factories ) { - foreach( Plugins::PluginFactory *pFactory, factories ) + for( const auto &pFactory : factories ) { - ProviderFactory *factory = qobject_cast( pFactory ); + auto factory = qobject_cast( pFactory ); if( !factory ) continue; @@ -200,7 +200,7 @@ Controller::providerCreationDialog() const { CreateProviderDialog *dialog = new CreateProviderDialog( The::mainWindow() ); - foreach( ProviderFactory * const factory, m_providerFactories ) + for( const auto &factory : m_providerFactories ) dialog->addProviderType( factory->type(), factory->prettyName(), factory->icon(), factory->createConfigWidget() ); diff --git a/src/statsyncing/Process.cpp b/src/statsyncing/Process.cpp --- a/src/statsyncing/Process.cpp +++ b/src/statsyncing/Process.cpp @@ -127,7 +127,7 @@ } else // background operation { - Amarok::Components::logger()->newProgressOperation( job, text, 100, job, SLOT(abort()) ); + Amarok::Components::logger()->newProgressOperation( job, text, 100, job, &MatchTracksJob::abort ); } connect( job, &StatSyncing::MatchTracksJob::done, this, &Process::slotTracksMatched ); @@ -228,7 +228,7 @@ SynchronizeTracksJob *job = new SynchronizeTracksJob( m_matchedTracksModel->matchedTuples(), m_tracksToScrobble, m_options ); QString text = i18n( "Synchronizing Track Statistics" ); - Amarok::Components::logger()->newProgressOperation( job, text, 100, job, SLOT(abort()) ); + Amarok::Components::logger()->newProgressOperation( job, text, 100, job, &SynchronizeTracksJob::abort ); connect( job, &StatSyncing::SynchronizeTracksJob::done, this, &Process::slotLogSynchronization ); connect( job, &StatSyncing::SynchronizeTracksJob::done, job, &StatSyncing::SynchronizeTracksJob::deleteLater ); ThreadWeaver::Queue::instance()->enqueue( QSharedPointer(job) ); diff --git a/src/statusbar/CompoundProgressBar.h b/src/statusbar/CompoundProgressBar.h --- a/src/statusbar/CompoundProgressBar.h +++ b/src/statusbar/CompoundProgressBar.h @@ -45,9 +45,6 @@ void setProgressStatus( const QObject *owner, const QString &text ); void setProgress( const QObject *owner, int steps ); - /* reimplemented from QWidget for correct positioning of progressDetailsWidget */ - virtual void setParent( QWidget *parent ); - /* reimplemented from QWidget to open/close the details widget */ virtual void mousePressEvent( QMouseEvent *event ); diff --git a/src/statusbar/CompoundProgressBar.cpp b/src/statusbar/CompoundProgressBar.cpp --- a/src/statusbar/CompoundProgressBar.cpp +++ b/src/statusbar/CompoundProgressBar.cpp @@ -28,7 +28,7 @@ : ProgressBar( parent ) , m_mutex( QMutex::Recursive ) { - m_progressDetailsWidget = new PopupWidget( parent ); + m_progressDetailsWidget = new PopupWidget(); m_progressDetailsWidget->hide(); connect( cancelButton(), &QAbstractButton::clicked, this, &CompoundProgressBar::cancelAll ); @@ -139,18 +139,6 @@ m_progressMap.value( owner )->setMaximum( value ); } -void CompoundProgressBar::setParent( QWidget *parent ) -{ - QMutexLocker locker( &m_mutex ); - - delete m_progressDetailsWidget; - m_progressDetailsWidget = new PopupWidget( parent ); - m_progressDetailsWidget->hide(); - - ProgressBar::setParent( parent ); -} - - void CompoundProgressBar::setProgressStatus( const QObject *owner, const QString &text ) { QMutexLocker locker( &m_mutex ); diff --git a/src/statusbar/LongMessageWidget.h b/src/statusbar/LongMessageWidget.h --- a/src/statusbar/LongMessageWidget.h +++ b/src/statusbar/LongMessageWidget.h @@ -39,7 +39,7 @@ { Q_OBJECT public: - LongMessageWidget( QWidget *anchor, const QString &message, Amarok::Logger::MessageType type ); + LongMessageWidget( const QString &message ); ~LongMessageWidget(); diff --git a/src/statusbar/LongMessageWidget.cpp b/src/statusbar/LongMessageWidget.cpp --- a/src/statusbar/LongMessageWidget.cpp +++ b/src/statusbar/LongMessageWidget.cpp @@ -27,14 +27,11 @@ #include -LongMessageWidget::LongMessageWidget( QWidget *anchor, const QString &message, - Amarok::Logger::MessageType type ) - : PopupWidget( anchor ) - , m_counter( 0 ) +LongMessageWidget::LongMessageWidget( const QString &message ) + : m_counter( 0 ) , m_timeout( 6000 ) { DEBUG_BLOCK - Q_UNUSED( type ) setFrameStyle( QFrame::StyledPanel | QFrame::Raised ); diff --git a/src/statusbar/PopupWidget.h b/src/statusbar/PopupWidget.h --- a/src/statusbar/PopupWidget.h +++ b/src/statusbar/PopupWidget.h @@ -22,7 +22,7 @@ class PopupWidget : public BoxWidget { public: - explicit PopupWidget( QWidget *anchor, const QString &name = QString() ); + explicit PopupWidget( const QString &name = QString() ); ~PopupWidget(); void reposition(); diff --git a/src/statusbar/PopupWidget.cpp b/src/statusbar/PopupWidget.cpp --- a/src/statusbar/PopupWidget.cpp +++ b/src/statusbar/PopupWidget.cpp @@ -23,11 +23,10 @@ #include -PopupWidget::PopupWidget( QWidget *anchor, const QString &name ) - : BoxWidget( true, The::mainWindow() ) +PopupWidget::PopupWidget( const QString &name ) + : BoxWidget( true ) { Q_UNUSED( name ); - Q_UNUSED( anchor ); setBackgroundRole( QPalette::Window ); setAutoFillBackground( true ); @@ -39,8 +38,6 @@ setContentsMargins( 4, 4, 4, 4 ); setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); - - reposition(); } PopupWidget::~PopupWidget() @@ -52,6 +49,9 @@ { adjustSize(); + if( !The::mainWindow() ) + return; + //HACK: put longmessage popup in the bottom right of the window. QPoint p; p.setX( The::mainWindow()->width() - width() ); diff --git a/src/statusbar/ProgressBar.h b/src/statusbar/ProgressBar.h --- a/src/statusbar/ProgressBar.h +++ b/src/statusbar/ProgressBar.h @@ -25,6 +25,8 @@ #include #include +#include + #define POST_COMPLETION_DELAY 2000 /** @@ -40,10 +42,8 @@ void setDescription( const QString &description ); - ProgressBar *setAbortSlot( QObject *receiver, const char *slot, - Qt::ConnectionType type = Qt::AutoConnection ); - template - ProgressBar *setAbortSlot( const typename QtPrivate::FunctionPointer::Object *receiver, Func slot, + template + ProgressBar *setAbortSlot( Receiver receiver, Func slot, Qt::ConnectionType type = Qt::AutoConnection ) { cancelButton()->setHidden( false ); diff --git a/src/statusbar/ProgressBar.cpp b/src/statusbar/ProgressBar.cpp --- a/src/statusbar/ProgressBar.cpp +++ b/src/statusbar/ProgressBar.cpp @@ -79,17 +79,6 @@ m_descriptionLabel->setText( description ); } -ProgressBar * -ProgressBar::setAbortSlot( QObject *receiver, const char *slot, Qt::ConnectionType type ) -{ - cancelButton()->setHidden( false ); - if( receiver ) - connect( this, SIGNAL(cancelled(ProgressBar*)), receiver, slot, type ); - connect( cancelButton(), &QAbstractButton::clicked, this, &ProgressBar::cancel ); - - return this; -} - void ProgressBar::cancel() { DEBUG_BLOCK diff --git a/src/widgets/MetaQueryWidget.h b/src/widgets/MetaQueryWidget.h --- a/src/widgets/MetaQueryWidget.h +++ b/src/widgets/MetaQueryWidget.h @@ -54,8 +54,8 @@ qint64 timeDistance() const; void setTimeDistance( qint64 value ); - template - void connectChanged( typename QtPrivate::FunctionPointer::Object *receiver, Func slot ) + template + void connectChanged( Receiver receiver, Func slot ) { connect( m_timeEdit, QOverload::of(&QSpinBox::valueChanged), receiver, slot ); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -111,19 +111,6 @@ target_link_libraries(testqstringx Qt5::Test) -#------------------------ Test SmartPointerList ----------------------------- - -set( testsmartpointerlist_SRCS - TestSmartPointerList.cpp - ${AMAROK_SOURCE_TREE}/core/support/SmartPointerList.cpp - ) - -add_executable( testsmartpointerlist ${testsmartpointerlist_SRCS} ) -add_test(NAME testsmartpointerlist COMMAND $) -ecm_mark_as_test(testsmartpointerlist) - -target_link_libraries(testsmartpointerlist Qt5::Test) - #------------------------ Test TagGuesser ----------------------------- set( testtagguesser_SRCS diff --git a/tests/TestSmartPointerList.h b/tests/TestSmartPointerList.h deleted file mode 100644 --- a/tests/TestSmartPointerList.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2009 Max Howell * - * * - * 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 TESTSMARTPOINTERLIST_H -#define TESTSMARTPOINTERLIST_H - -#include -#include - -class TestSmartPointerList : public QObject -{ -Q_OBJECT - -public: - TestSmartPointerList(); - -private Q_SLOTS: - void testCount(); - void testCopy(); - void testCopyAndThenDelete(); - void testRemove(); - void testRemoveAt(); - void testMultipleOrgasms(); - void testForeach(); - void testOperatorPlus(); - void testOperatorPlusEquals(); -}; - -#endif // TESTSMARTPOINTERLIST_H diff --git a/tests/TestSmartPointerList.cpp b/tests/TestSmartPointerList.cpp deleted file mode 100644 --- a/tests/TestSmartPointerList.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2009 Max Howell * - * * - * 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. * - ***************************************************************************/ - -#include "TestSmartPointerList.h" - -#include "core/support/SmartPointerList.h" - -#include -#include -#include - -QTEST_GUILESS_MAIN( TestSmartPointerList ) - -// use a macro, as we don't want to test copy ctor early -#define THREE_TIMERS( x ) SmartPointerList x; x << new QTimer << new QTimer << new QTimer - -TestSmartPointerList::TestSmartPointerList() -{ -} - -void TestSmartPointerList::testCount() -{ - THREE_TIMERS( objects ); - QCOMPARE( objects.count(), 3 ); -} - -void TestSmartPointerList::testCopy() -{ - THREE_TIMERS( objects1 ); - SmartPointerList objects2 = objects1; - - for (int x = 0; x < 3; ++x) - QVERIFY( objects1[x] == objects2[x] ); - - QCOMPARE( objects1.count(), 3 ); - QCOMPARE( objects2.count(), 3 ); - delete objects1.last(); - QCOMPARE( objects1.count(), 2 ); - QCOMPARE( objects2.count(), 2 ); -} - -void TestSmartPointerList::testCopyAndThenDelete() -{ - THREE_TIMERS( os1 ); - SmartPointerList* os2 = new SmartPointerList( os1 ); - SmartPointerList os3( *os2 ); - - delete os2; - - QCOMPARE( os1.count(), 3 ); - QCOMPARE( os3.count(), 3 ); - - delete os1[1]; - - QCOMPARE( os1.count(), 2 ); - QCOMPARE( os3.count(), 2 ); -} - -void TestSmartPointerList::testRemove() -{ - THREE_TIMERS( objects ); - delete objects.last(); - QCOMPARE( objects.count(), 2 ); -} - -void TestSmartPointerList::testRemoveAt() -{ - THREE_TIMERS( os ); - QTimer* t = os[1]; - os.removeAt( 1 ); - os << t; - QCOMPARE( os.count(), 3 ); - delete t; - QCOMPARE( os.count(), 2 ); -} - -void TestSmartPointerList::testMultipleOrgasms() -{ - THREE_TIMERS( os ); - for (int x = 0; x < 10; ++x) - os << os.last(); - QCOMPARE( os.count(), 13 ); - delete os.last(); - QCOMPARE( os.count(), 2 ); -} - -void TestSmartPointerList::testForeach() -{ - THREE_TIMERS( objects ); - int x = 0; - foreach (QTimer* o, objects) { - (void) o; - x++; - } - QCOMPARE( x, 3 ); -} - -void TestSmartPointerList::testOperatorPlus() -{ - THREE_TIMERS( os1 ); - SmartPointerList os2 = os1; - - QCOMPARE( (os1 + os2).count(), 6 ); - delete os1.last(); - QCOMPARE( (os1 + os2).count(), 4 ); -} - -void TestSmartPointerList::testOperatorPlusEquals() -{ - THREE_TIMERS( os ); - os += os; - os += os; - QCOMPARE( os.count(), 12 ); - QTimer* t = os.takeLast(); - QCOMPARE( os.count(), 11 ); - delete t; - QCOMPARE( os.count(), 8 ); -} - diff --git a/tests/core-impl/logger/TestProxyLogger.cpp b/tests/core-impl/logger/TestProxyLogger.cpp --- a/tests/core-impl/logger/TestProxyLogger.cpp +++ b/tests/core-impl/logger/TestProxyLogger.cpp @@ -75,7 +75,7 @@ Q_UNUSED(thread); KJob *job = new DummyJob(); QObject *obj = new QObject(); - s_logger->newProgressOperation( job, QString( "foo" ), obj, "foo()" ); + s_logger->newProgressOperation( job, QString( "foo" ), obj ); if( deleteJob ) delete job; if( deleteObject ) delete obj; @@ -116,7 +116,7 @@ s_logger = new ProxyLogger(); Amarok::MockLogger *mock = new Amarok::MockLogger(); - EXPECT_CALL( *mock, newProgressOperation( An(), _, _, _, _ ) ).Times( 0 ); + EXPECT_CALL( *mock, newProgressOperationImpl( An(), _, _, _, _ ) ).Times( 0 ); s_logger->setLogger( mock ); @@ -137,7 +137,7 @@ s_logger = new ProxyLogger(); Amarok::MockLogger *mock = new Amarok::MockLogger(); - EXPECT_CALL( *mock, newProgressOperation( An(), _, 0, 0, _ ) ).Times( 1 ).WillOnce( Return() ); + EXPECT_CALL( *mock, newProgressOperationImpl( An(), _, nullptr, _, _ ) ).Times( 1 ).WillOnce( Return() ); s_logger->setLogger( mock ); @@ -176,7 +176,7 @@ s_logger = new ProxyLogger(); Amarok::MockLogger *mock = new Amarok::MockLogger(); - EXPECT_CALL( *mock, newProgressOperation( An(), _, _, _, _ ) ).Times( 1 ).WillOnce( Return() ); + EXPECT_CALL( *mock, newProgressOperationImpl( An(), _, _, _, _ ) ).Times( 1 ).WillOnce( Return() ); s_logger->setLogger( mock ); diff --git a/tests/importers/ImporterMocks.cpp b/tests/importers/ImporterMocks.cpp --- a/tests/importers/ImporterMocks.cpp +++ b/tests/importers/ImporterMocks.cpp @@ -113,6 +113,7 @@ void ImporterMocks::cleanupTestCase() { + Amarok::config( "StatSyncing" ).deleteGroup(); Amarok::Components::setEngineController( 0 ); delete m_engineController; } diff --git a/tests/mocks/MockLogger.h b/tests/mocks/MockLogger.h --- a/tests/mocks/MockLogger.h +++ b/tests/mocks/MockLogger.h @@ -34,19 +34,19 @@ { ON_CALL( *this, shortMessage( _ ) ).WillByDefault( Return() ); ON_CALL( *this, longMessage( _, _ ) ).WillByDefault( Return() ); - ON_CALL( *this, newProgressOperation( An(), _, _, _, _ ) ).WillByDefault( Return() ); - ON_CALL( *this, newProgressOperation( An(), _, _, _, _ ) ).WillByDefault( Return() ); - ON_CALL( *this, newProgressOperation( An(), _, _, _, _, _ ) ).WillByDefault( Return() ); + ON_CALL( *this, newProgressOperationImpl( An(), _, _, _, _ ) ).WillByDefault( Return() ); + ON_CALL( *this, newProgressOperationImpl( An(), _, _, _, _ ) ).WillByDefault( Return() ); + ON_CALL( *this, newProgressOperationImpl( An(), _, _, _, _, _, _, _ ) ).WillByDefault( Return() ); } MOCK_METHOD1( shortMessage, void( const QString& ) ); MOCK_METHOD2( longMessage, void( const QString&, Amarok::Logger::MessageType ) ); - MOCK_METHOD5( newProgressOperation, void( KJob*, const QString&, QObject*, const char*, - Qt::ConnectionType ) ); - MOCK_METHOD5( newProgressOperation, void( QNetworkReply*, const QString&, QObject*, - const char*, Qt::ConnectionType ) ); - MOCK_METHOD6( newProgressOperation, void( QObject *, const QString&, int, QObject*, - const char*, Qt::ConnectionType ) ); + MOCK_METHOD5( newProgressOperationImpl, void( KJob*, const QString&, QObject*, const std::function&, + Qt::ConnectionType ) ); + MOCK_METHOD5( newProgressOperationImpl, void( QNetworkReply*, const QString&, QObject*, + const std::function&, Qt::ConnectionType ) ); + MOCK_METHOD8( newProgressOperationImpl, void( QObject *, const QMetaMethod &, const QMetaMethod &, const QString&, + int, QObject*, const std::function&, Qt::ConnectionType ) ); }; }