diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 75a08412a..a137fa115 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,7 @@ SET( tomahawkSources ${tomahawkSources} scrobbler.cpp shortcuthandler.cpp + scanmanager.cpp tomahawkapp.cpp main.cpp ) @@ -81,6 +82,7 @@ SET( tomahawkHeaders ${tomahawkHeaders} musicscanner.h scriptresolver.h scrobbler.h + scanmanager.h shortcuthandler.h ) diff --git a/src/musicscanner.cpp b/src/musicscanner.cpp index 2fa64f5d6..e70aea0f8 100644 --- a/src/musicscanner.cpp +++ b/src/musicscanner.cpp @@ -8,14 +8,13 @@ using namespace Tomahawk; - MusicScanner::MusicScanner( const QString& dir, quint32 bs ) - : QThread() + : QObject() , m_dir( dir ) , m_batchsize( bs ) + , m_dirLister( 0 ) + , m_dirListerThreadController( 0 ) { - moveToThread( this ); - m_ext2mime.insert( "mp3", "audio/mpeg" ); #ifndef NO_OGG @@ -31,15 +30,6 @@ MusicScanner::MusicScanner( const QString& dir, quint32 bs ) // m_ext2mime.insert( "mp4", "audio/mp4" ); } - -void -MusicScanner::run() -{ - QTimer::singleShot( 0, this, SLOT( startScan() ) ); - exec(); -} - - void MusicScanner::startScan() { @@ -74,18 +64,21 @@ MusicScanner::scan() connect( this, SIGNAL( batchReady( QVariantList ) ), SLOT( commitBatch( QVariantList ) ), Qt::DirectConnection ); - DirLister* lister = new DirLister( QDir( m_dir, 0 ), m_dirmtimes ); + m_dirListerThreadController = new QThread( this ); + m_dirLister = new DirLister( QDir( m_dir, 0 ), m_dirmtimes ); + m_dirLister->moveToThread( m_dirListerThreadController ); - connect( lister, SIGNAL( fileToScan( QFileInfo ) ), + connect( m_dirLister, SIGNAL( fileToScan( QFileInfo ) ), SLOT( scanFile( QFileInfo ) ), Qt::QueuedConnection ); // queued, so will only fire after all dirs have been scanned: - connect( lister, SIGNAL( finished( const QMap& ) ), + connect( m_dirLister, SIGNAL( finished( const QMap& ) ), SLOT( listerFinished( const QMap& ) ), Qt::QueuedConnection ); - connect( lister, SIGNAL( finished() ), lister, SLOT( deleteLater() ) ); - - lister->start(); + connect( m_dirLister, SIGNAL( destroyed(QObject*) ), this, SLOT( listerDestroyed(QObject*) ) ); + + m_dirListerThreadController->start(); + QMetaObject::invokeMethod( m_dirLister, "go" ); } @@ -111,9 +104,20 @@ MusicScanner::listerFinished( const QMap& newmtimes ) qDebug() << "Skipped the following files (no tags / no valid audio):"; foreach( const QString& s, m_skippedFiles ) qDebug() << s; + + m_dirLister->deleteLater(); } +void +MusicScanner::listerDestroyed( QObject* dirLister ) +{ + qDebug() << Q_FUNC_INFO; + m_dirLister = 0; + m_dirListerThreadController->deleteLater(); + m_dirListerThreadController = 0; +} + void MusicScanner::commitBatch( const QVariantList& tracks ) { diff --git a/src/musicscanner.h b/src/musicscanner.h index 366c1fb5f..b97f80b54 100644 --- a/src/musicscanner.h +++ b/src/musicscanner.h @@ -5,69 +5,26 @@ #include #include -#include #include #include #include #include #include -class MusicScanner : public QThread -{ -Q_OBJECT - -public: - MusicScanner( const QString& dir, quint32 bs = 0 ); - -protected: - void run(); - -signals: - //void fileScanned( QVariantMap ); - void finished( int, int ); - void batchReady( const QVariantList& ); - -private: - QVariant readFile( const QFileInfo& fi ); - -private slots: - void listerFinished( const QMap& newmtimes ); - void scanFile( const QFileInfo& fi ); - void startScan(); - void scan(); - void setMtimes( const QMap& m ); - void commitBatch( const QVariantList& ); - -private: - QString m_dir; - QMap m_ext2mime; // eg: mp3 -> audio/mpeg - unsigned int m_scanned; - unsigned int m_skipped; - - QList m_skippedFiles; - - QMap m_dirmtimes; - QMap m_newdirmtimes; - - QList m_scannedfiles; - quint32 m_batchsize; -}; - #include // descend dir tree comparing dir mtimes to last known mtime // emit signal for any dir with new content, so we can scan it. // finally, emit the list of new mtimes we observed. -class DirLister : public QThread +class DirLister : public QObject { Q_OBJECT public: DirLister( QDir d, QMap& mtimes ) - : QThread(), m_dir( d ), m_dirmtimes( mtimes ) + : QObject(), m_dir( d ), m_dirmtimes( mtimes ) { qDebug() << Q_FUNC_INFO; - moveToThread(this); } ~DirLister() @@ -75,13 +32,6 @@ public: qDebug() << Q_FUNC_INFO; } -protected: - void run() - { - QTimer::singleShot(0,this,SLOT(go())); - exec(); - } - signals: void fileToScan( QFileInfo ); void finished( const QMap& ); @@ -130,4 +80,46 @@ private: QMap m_newdirmtimes; }; +class MusicScanner : public QObject +{ +Q_OBJECT + +public: + MusicScanner( const QString& dir, quint32 bs = 0 ); + +signals: + //void fileScanned( QVariantMap ); + void finished( int, int ); + void batchReady( const QVariantList& ); + +private: + QVariant readFile( const QFileInfo& fi ); + +private slots: + void listerFinished( const QMap& newmtimes ); + void listerDestroyed( QObject* dirLister ); + void scanFile( const QFileInfo& fi ); + void startScan(); + void scan(); + void setMtimes( const QMap& m ); + void commitBatch( const QVariantList& ); + +private: + QString m_dir; + QMap m_ext2mime; // eg: mp3 -> audio/mpeg + unsigned int m_scanned; + unsigned int m_skipped; + + QList m_skippedFiles; + + QMap m_dirmtimes; + QMap m_newdirmtimes; + + QList m_scannedfiles; + quint32 m_batchsize; + + DirLister* m_dirLister; + QThread* m_dirListerThreadController; +}; + #endif diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp new file mode 100644 index 000000000..368f0448a --- /dev/null +++ b/src/scanmanager.cpp @@ -0,0 +1,58 @@ +#include "scanmanager.h" +#include "musicscanner.h" + +#include +#include + +ScanManager* ScanManager::s_instance = 0; + + +ScanManager* +ScanManager::instance() +{ + return s_instance; +} + + +ScanManager::ScanManager( QObject* parent ) + : QObject( parent ) + , m_scanner( 0 ) + , m_musicScannerThreadController( 0 ) +{ + s_instance = this; +} + + +ScanManager::~ScanManager() +{ + s_instance = 0; + m_musicScannerThreadController->deleteLater(); + m_musicScannerThreadController = 0; + m_scanner->deleteLater(); + m_scanner = 0; +} + +void +ScanManager::runManualScan( const QString &path ) +{ + qDebug() << Q_FUNC_INFO; + if ( !m_musicScannerThreadController && !m_scanner ) //still running if these are not zero + { + m_musicScannerThreadController = new QThread( this ); + MusicScanner* m_scanner = new MusicScanner( path ); + m_scanner->moveToThread( m_musicScannerThreadController ); + connect( m_scanner, SIGNAL( finished() ), m_scanner, SLOT( deleteLater() ) ); + connect( m_scanner, SIGNAL( destroyed(QObject*) ), this, SLOT( scanDestroyed(QObject*) ) ); + m_musicScannerThreadController->start( QThread::IdlePriority ); + QMetaObject::invokeMethod( m_scanner, "startScan" ); + } +} + +void +ScanManager::scannerDestroyed( QObject* scanner ) +{ + qDebug() << Q_FUNC_INFO; + m_scanner = 0; + m_musicScannerThreadController->deleteLater(); + m_musicScannerThreadController = 0; +} \ No newline at end of file diff --git a/src/scanmanager.h b/src/scanmanager.h new file mode 100644 index 000000000..24247c0ff --- /dev/null +++ b/src/scanmanager.h @@ -0,0 +1,32 @@ +#ifndef SCANMANAGER_H +#define SCANMANAGER_H + +#include + +#include "dllmacro.h" + +class MusicScanner; +class QThread; + +class DLLEXPORT ScanManager : public QObject +{ + Q_OBJECT +public: + static ScanManager* instance(); + + explicit ScanManager( QObject* parent = 0 ); + virtual ~ScanManager(); + + void runManualScan( const QString &path ); + +private slots: + void scannerDestroyed( QObject *scanner ); + +private: + static ScanManager* s_instance; + + MusicScanner* m_scanner; + QThread* m_musicScannerThreadController; +}; + +#endif diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 3360ae586..fa6b58d17 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -22,6 +22,7 @@ #include "sip/SipHandler.h" #include "sip/twitter/tomahawkoauthtwitter.h" #include +#include "scanmanager.h" static QString md5( const QByteArray& src ) @@ -145,11 +146,7 @@ SettingsDialog::~SettingsDialog() s->setScriptResolvers( resolvers ); if( rescan ) - { - MusicScanner* scanner = new MusicScanner(s->scannerPath() ); - connect( scanner, SIGNAL( finished() ), scanner, SLOT( deleteLater() ) ); - scanner->start(); - } + ScanManager::instance()->runManualScan( s->scannerPath() ); if( rejabber ) { @@ -180,21 +177,6 @@ SettingsDialog::showPathSelector() } -void -SettingsDialog::doScan() -{ - // TODO this doesnt really belong here.. - QString path = ui->lineEditMusicPath->text(); - MusicScanner* scanner = new MusicScanner( path ); - connect( scanner, SIGNAL( finished() ), scanner, SLOT( deleteLater() ) ); - scanner->start(); - - QMessageBox::information( this, tr( "Scanning Started" ), - tr( "Scanning now, check console output. TODO." ), - QMessageBox::Ok ); -} - - void SettingsDialog::onRejected() { diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 7c0e6c0a8..95cd1b2e5 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -48,8 +48,7 @@ protected: private slots: void onRejected(); void showPathSelector(); - void doScan(); - + void toggleUpnp( bool preferStaticEnabled ); void showProxySettings(); diff --git a/src/sip/jabber/jabber_p.cpp b/src/sip/jabber/jabber_p.cpp index c845f3c0f..bdbade4e7 100644 --- a/src/sip/jabber/jabber_p.cpp +++ b/src/sip/jabber/jabber_p.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include using namespace gloox; diff --git a/src/sip/jabber/jabber_p.h b/src/sip/jabber/jabber_p.h index 57d2d63ed..14a7d5c3a 100644 --- a/src/sip/jabber/jabber_p.h +++ b/src/sip/jabber/jabber_p.h @@ -10,7 +10,6 @@ #include #include #include -#include #include diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 19fbadec9..432e59022 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -25,6 +25,7 @@ #include "scriptresolver.h" #include "sourcelist.h" #include "shortcuthandler.h" +#include "scanmanager.h" #include "tomahawksettings.h" #include "audio/audioengine.h" @@ -149,10 +150,11 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) new TomahawkSettings( this ); m_audioEngine = new AudioEngine; - + new ScanManager( this ); + new Pipeline( this ); new SourceList( this ); - + m_servent = new Servent( this ); connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) ); diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index 36e71f8e4..b1c012c24 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -32,13 +32,13 @@ #include "widgets/welcomewidget.h" #include "audiocontrols.h" -#include "musicscanner.h" #include "settingsdialog.h" #include "tomahawksettings.h" #include "sourcelist.h" #include "transferview.h" #include "tomahawktrayicon.h" #include "playlist/dynamic/GeneratorInterface.h" +#include "scanmanager.h" using namespace Tomahawk; @@ -249,23 +249,9 @@ TomahawkWindow::rescanCollectionManually() s->scannerPath(), &ok ); s->setValue( "scannerpath", path ); if ( ok && !path.isEmpty() ) - { - MusicScanner* scanner = new MusicScanner( path ); - connect( scanner, SIGNAL( finished() ), this, SLOT( scanFinished() ) ); - scanner->start(); - } + ScanManager::instance()->runManualScan( path ); } - -void -TomahawkWindow::scanFinished() -{ - qDebug() << Q_FUNC_INFO; - MusicScanner* scanner = (MusicScanner*) sender(); - scanner->deleteLater(); -} - - void TomahawkWindow::addPeerManually() { diff --git a/src/tomahawkwindow.h b/src/tomahawkwindow.h index 078868e6d..36dbb8f50 100644 --- a/src/tomahawkwindow.h +++ b/src/tomahawkwindow.h @@ -12,6 +12,7 @@ class QAction; +class MusicScanner; class AudioControls; class TomahawkTrayIcon; @@ -46,11 +47,9 @@ public slots: void createPlaylist(); void loadSpiff(); void showSettingsDialog(); + void rescanCollectionManually(); private slots: - void scanFinished(); - void rescanCollectionManually(); - void onSipConnected(); void onSipDisconnected(); void onSipError();