mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-05 13:47:26 +02:00
Implement watched folders and scan-on-startup. Folders are scanned after 10 seconds without a change. Also handles deferring scans of directories if attempted during an ongoing scan, both for recursive and non-recursive scans.
Fixes TWK-30 / THK-30.
This commit is contained in:
@@ -124,7 +124,7 @@ void
|
|||||||
ACLSystem::authorizePath( const QString& dbid, const QString& path, ACLSystem::ACL type )
|
ACLSystem::authorizePath( const QString& dbid, const QString& path, ACLSystem::ACL type )
|
||||||
{
|
{
|
||||||
TomahawkSettings *s = TomahawkSettings::instance();
|
TomahawkSettings *s = TomahawkSettings::instance();
|
||||||
if( !s->scannerPath().contains( path ) )
|
if( !s->scannerPaths().contains( path ) )
|
||||||
{
|
{
|
||||||
qDebug() << "path selected is not in our scanner path!";
|
qDebug() << "path selected is not in our scanner path!";
|
||||||
return;
|
return;
|
||||||
|
@@ -32,6 +32,7 @@ Database::instance()
|
|||||||
|
|
||||||
Database::Database( const QString& dbname, QObject* parent )
|
Database::Database( const QString& dbname, QObject* parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
|
, m_ready( false )
|
||||||
, m_impl( new DatabaseImpl( dbname, this ) )
|
, m_impl( new DatabaseImpl( dbname, this ) )
|
||||||
, m_workerRW( new DatabaseWorker( m_impl, this, true ) )
|
, m_workerRW( new DatabaseWorker( m_impl, this, true ) )
|
||||||
{
|
{
|
||||||
@@ -39,6 +40,7 @@ Database::Database( const QString& dbname, QObject* parent )
|
|||||||
|
|
||||||
connect( m_impl, SIGNAL( indexReady() ), SIGNAL( indexReady() ) );
|
connect( m_impl, SIGNAL( indexReady() ), SIGNAL( indexReady() ) );
|
||||||
connect( m_impl, SIGNAL( indexReady() ), SIGNAL( ready() ) );
|
connect( m_impl, SIGNAL( indexReady() ), SIGNAL( ready() ) );
|
||||||
|
connect( m_impl, SIGNAL( indexReady() ), SLOT( setIsReadyTrue() ) );
|
||||||
|
|
||||||
m_workerRW->start();
|
m_workerRW->start();
|
||||||
}
|
}
|
||||||
|
@@ -53,6 +53,8 @@ public:
|
|||||||
|
|
||||||
void loadIndex();
|
void loadIndex();
|
||||||
|
|
||||||
|
bool isReady() const { return m_ready; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void indexReady(); // search index
|
void indexReady(); // search index
|
||||||
void ready();
|
void ready();
|
||||||
@@ -63,7 +65,11 @@ signals:
|
|||||||
public slots:
|
public slots:
|
||||||
void enqueue( QSharedPointer<DatabaseCommand> lc );
|
void enqueue( QSharedPointer<DatabaseCommand> lc );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void setIsReadyTrue() { m_ready = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_ready;
|
||||||
DatabaseImpl* m_impl;
|
DatabaseImpl* m_impl;
|
||||||
DatabaseWorker* m_workerRW;
|
DatabaseWorker* m_workerRW;
|
||||||
QHash< QString, DatabaseWorker* > m_workers;
|
QHash< QString, DatabaseWorker* > m_workers;
|
||||||
|
@@ -84,6 +84,8 @@ signals:
|
|||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_ready;
|
||||||
|
|
||||||
bool updateSchema( int currentver );
|
bool updateSchema( int currentver );
|
||||||
|
|
||||||
QSqlDatabase db;
|
QSqlDatabase db;
|
||||||
|
@@ -66,29 +66,50 @@ TomahawkSettings::~TomahawkSettings()
|
|||||||
|
|
||||||
|
|
||||||
QStringList
|
QStringList
|
||||||
TomahawkSettings::scannerPath() const
|
TomahawkSettings::scannerPaths()
|
||||||
{
|
{
|
||||||
|
//FIXME: After enough time, remove this hack (and make const)
|
||||||
#ifndef TOMAHAWK_HEADLESS
|
#ifndef TOMAHAWK_HEADLESS
|
||||||
return value( "scannerpath", QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) ).toStringList();
|
if( value( "scannerpaths" ).isNull() )
|
||||||
|
setValue( "scannerpaths", value( "scannerpath" ) );
|
||||||
|
return value( "scannerpaths", QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) ).toStringList();
|
||||||
#else
|
#else
|
||||||
return value( "scannerpath", "" ).toStringList();
|
if( value( "scannerpaths" ).isNull() )
|
||||||
|
setValue( "scannerpaths", value( "scannerpath" ) );
|
||||||
|
return value( "scannerpaths", "" ).toStringList();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TomahawkSettings::setScannerPath( const QStringList& path )
|
TomahawkSettings::setScannerPaths( const QStringList& paths )
|
||||||
{
|
{
|
||||||
setValue( "scannerpath", path );
|
setValue( "scannerpaths", paths );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TomahawkSettings::hasScannerPath() const
|
TomahawkSettings::hasScannerPaths() const
|
||||||
{
|
{
|
||||||
return contains( "scannerpath" );
|
//FIXME: After enough time, remove this hack
|
||||||
|
return contains( "scannerpaths" ) || contains( "scannerpath" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TomahawkSettings::watchForChanges() const
|
||||||
|
{
|
||||||
|
return value( "watchForChanges", true ).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkSettings::setWatchForChanges( bool watch )
|
||||||
|
{
|
||||||
|
setValue( "watchForChanges", watch );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TomahawkSettings::setAcceptedLegalWarning( bool accept )
|
TomahawkSettings::setAcceptedLegalWarning( bool accept )
|
||||||
{
|
{
|
||||||
|
@@ -41,9 +41,12 @@ public:
|
|||||||
void applyChanges() { emit changed(); }
|
void applyChanges() { emit changed(); }
|
||||||
|
|
||||||
/// General settings
|
/// General settings
|
||||||
QStringList scannerPath() const; /// QDesktopServices::MusicLocation by default
|
QStringList scannerPaths(); /// QDesktopServices::MusicLocation by default
|
||||||
void setScannerPath( const QStringList& path );
|
void setScannerPaths( const QStringList& paths );
|
||||||
bool hasScannerPath() const;
|
bool hasScannerPaths() const;
|
||||||
|
|
||||||
|
bool watchForChanges() const;
|
||||||
|
void setWatchForChanges( bool watch );
|
||||||
|
|
||||||
bool acceptedLegalWarning() const;
|
bool acceptedLegalWarning() const;
|
||||||
void setAcceptedLegalWarning( bool accept );
|
void setAcceptedLegalWarning( bool accept );
|
||||||
|
@@ -31,14 +31,16 @@ using namespace Tomahawk;
|
|||||||
void
|
void
|
||||||
DirLister::go()
|
DirLister::go()
|
||||||
{
|
{
|
||||||
scanDir( m_dir, 0 );
|
foreach( QString dir, m_dirs )
|
||||||
|
scanDir( QDir( dir, 0 ), 0, ( m_recursive ? DirLister::Recursive : DirLister::NonRecursive ) );
|
||||||
emit finished( m_newdirmtimes );
|
emit finished( m_newdirmtimes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DirLister::scanDir( QDir dir, int depth )
|
DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode )
|
||||||
{
|
{
|
||||||
|
qDebug() << "DirLister::scanDir scanning: " << dir.absolutePath();
|
||||||
QFileInfoList dirs;
|
QFileInfoList dirs;
|
||||||
const uint mtime = QFileInfo( dir.absolutePath() ).lastModified().toUTC().toTime_t();
|
const uint mtime = QFileInfo( dir.absolutePath() ).lastModified().toUTC().toTime_t();
|
||||||
m_newdirmtimes.insert( dir.absolutePath(), mtime );
|
m_newdirmtimes.insert( dir.absolutePath(), mtime );
|
||||||
@@ -65,14 +67,18 @@ DirLister::scanDir( QDir dir, int depth )
|
|||||||
|
|
||||||
foreach( const QFileInfo& di, dirs )
|
foreach( const QFileInfo& di, dirs )
|
||||||
{
|
{
|
||||||
scanDir( di.absoluteFilePath(), depth + 1 );
|
if( mode == DirLister::Recursive || !m_dirmtimes.contains( di.absolutePath() ) )
|
||||||
|
scanDir( di.absoluteFilePath(), depth + 1, DirLister::Recursive );
|
||||||
|
else //should be the non-recursive case since the second test above should only happen with a new dir
|
||||||
|
scanDir( di.absoluteFilePath(), depth + 1, DirLister::MTimeOnly );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MusicScanner::MusicScanner( const QStringList& dirs, quint32 bs )
|
MusicScanner::MusicScanner( const QStringList& dirs, bool recursive, quint32 bs )
|
||||||
: QObject()
|
: QObject()
|
||||||
, m_dirs( dirs )
|
, m_dirs( dirs )
|
||||||
|
, m_recursive( recursive )
|
||||||
, m_batchsize( bs )
|
, m_batchsize( bs )
|
||||||
, m_dirLister( 0 )
|
, m_dirLister( 0 )
|
||||||
, m_dirListerThreadController( 0 )
|
, m_dirListerThreadController( 0 )
|
||||||
@@ -150,8 +156,7 @@ MusicScanner::scan()
|
|||||||
|
|
||||||
m_dirListerThreadController = new QThread( this );
|
m_dirListerThreadController = new QThread( this );
|
||||||
|
|
||||||
//FIXME: MULTIPLECOLLECTIONDIRS
|
m_dirLister = new DirLister( m_dirs, m_dirmtimes, m_recursive );
|
||||||
m_dirLister = new DirLister( QDir( m_dirs.first(), 0 ), m_dirmtimes );
|
|
||||||
m_dirLister->moveToThread( m_dirListerThreadController );
|
m_dirLister->moveToThread( m_dirListerThreadController );
|
||||||
|
|
||||||
connect( m_dirLister, SIGNAL( fileToScan( QFileInfo ) ),
|
connect( m_dirLister, SIGNAL( fileToScan( QFileInfo ) ),
|
||||||
|
@@ -39,8 +39,15 @@ class DirLister : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirLister( QDir d, QMap<QString, unsigned int>& mtimes )
|
|
||||||
: QObject(), m_dir( d ), m_dirmtimes( mtimes )
|
enum Mode {
|
||||||
|
NonRecursive,
|
||||||
|
Recursive,
|
||||||
|
MTimeOnly
|
||||||
|
};
|
||||||
|
|
||||||
|
DirLister( QStringList dirs, QMap<QString, unsigned int>& mtimes, bool recursive )
|
||||||
|
: QObject(), m_dirs( dirs ), m_dirmtimes( mtimes ), m_recursive( recursive )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
@@ -56,11 +63,13 @@ signals:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void go();
|
void go();
|
||||||
void scanDir( QDir dir, int depth );
|
void scanDir( QDir dir, int depth, DirLister::Mode mode );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QDir m_dir;
|
QStringList m_dirs;
|
||||||
QMap<QString, unsigned int> m_dirmtimes;
|
QMap<QString, unsigned int> m_dirmtimes;
|
||||||
|
bool m_recursive;
|
||||||
|
|
||||||
QMap<QString, unsigned int> m_newdirmtimes;
|
QMap<QString, unsigned int> m_newdirmtimes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +78,7 @@ class MusicScanner : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MusicScanner( const QStringList& dirs, quint32 bs = 0 );
|
MusicScanner( const QStringList& dirs, bool recursive = true, quint32 bs = 0 );
|
||||||
~MusicScanner();
|
~MusicScanner();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -105,6 +114,7 @@ private:
|
|||||||
QMap<QString, unsigned int> m_newdirmtimes;
|
QMap<QString, unsigned int> m_newdirmtimes;
|
||||||
|
|
||||||
QList<QVariant> m_scannedfiles;
|
QList<QVariant> m_scannedfiles;
|
||||||
|
bool m_recursive;
|
||||||
quint32 m_batchsize;
|
quint32 m_batchsize;
|
||||||
|
|
||||||
DirLister* m_dirLister;
|
DirLister* m_dirLister;
|
||||||
|
@@ -45,20 +45,33 @@ ScanManager::ScanManager( QObject* parent )
|
|||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_scanner( 0 )
|
, m_scanner( 0 )
|
||||||
, m_musicScannerThreadController( 0 )
|
, m_musicScannerThreadController( 0 )
|
||||||
|
, m_currScannerPaths()
|
||||||
, m_dirWatcher( 0 )
|
, m_dirWatcher( 0 )
|
||||||
|
, m_queuedScanTimer( 0 )
|
||||||
|
, m_deferredScanTimer( 0 )
|
||||||
|
, m_queuedChangedDirs()
|
||||||
|
, m_deferredDirs()
|
||||||
{
|
{
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
|
|
||||||
m_dirWatcher = new QFileSystemWatcher( parent );
|
m_queuedScanTimer = new QTimer( this );
|
||||||
|
m_queuedScanTimer->setSingleShot( true );
|
||||||
|
m_deferredScanTimer = new QTimer( this );
|
||||||
|
m_deferredScanTimer->setSingleShot( false );
|
||||||
|
m_deferredScanTimer->setInterval( 1000 );
|
||||||
|
m_dirWatcher = new QFileSystemWatcher( this );
|
||||||
|
|
||||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
|
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
|
||||||
|
connect( m_queuedScanTimer, SIGNAL( timeout() ), SLOT( queuedScanTimeout() ) );
|
||||||
|
connect( m_deferredScanTimer, SIGNAL( timeout() ), SLOT( deferredScanTimeout() ) );
|
||||||
connect( m_dirWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( handleChangedDir( const QString & ) ) );
|
connect( m_dirWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( handleChangedDir( const QString & ) ) );
|
||||||
|
|
||||||
if ( TomahawkSettings::instance()->hasScannerPath() )
|
if ( TomahawkSettings::instance()->hasScannerPaths() )
|
||||||
m_currScannerPath = TomahawkSettings::instance()->scannerPath();
|
m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
|
||||||
|
|
||||||
qDebug() << "loading initial directories to watch";
|
qDebug() << "loading initial directories to watch";
|
||||||
QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) );
|
QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) );
|
||||||
|
m_deferredScanTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -91,14 +104,18 @@ ScanManager::~ScanManager()
|
|||||||
void
|
void
|
||||||
ScanManager::onSettingsChanged()
|
ScanManager::onSettingsChanged()
|
||||||
{
|
{
|
||||||
if ( TomahawkSettings::instance()->hasScannerPath() &&
|
if ( TomahawkSettings::instance()->hasScannerPaths() &&
|
||||||
m_currScannerPath != TomahawkSettings::instance()->scannerPath() )
|
m_currScannerPaths != TomahawkSettings::instance()->scannerPaths() )
|
||||||
{
|
{
|
||||||
m_currScannerPath = TomahawkSettings::instance()->scannerPath();
|
m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
|
||||||
m_dirWatcher->removePaths( m_dirWatcher->directories() );
|
m_dirWatcher->removePaths( m_dirWatcher->directories() );
|
||||||
m_dirWatcher->addPaths( m_currScannerPath );
|
m_dirWatcher->addPaths( m_currScannerPaths );
|
||||||
runManualScan( m_currScannerPath );
|
runManualScan( m_currScannerPaths );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( TomahawkSettings::instance()->watchForChanges() &&
|
||||||
|
!m_queuedChangedDirs.isEmpty() )
|
||||||
|
runManualScan( m_queuedChangedDirs, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,21 +124,21 @@ ScanManager::startupWatchPaths()
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
if( !Database::instance() )
|
if( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) )
|
||||||
{
|
{
|
||||||
QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) );
|
QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( m_currScannerPath );
|
DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( m_currScannerPaths );
|
||||||
connect( cmd, SIGNAL( done( QMap<QString, unsigned int> ) ),
|
connect( cmd, SIGNAL( done( QMap< QString, unsigned int > ) ),
|
||||||
SLOT( setInitialPaths( QMap<QString, unsigned int> ) ) );
|
SLOT( setInitialPaths( QMap< QString, unsigned int > ) ) );
|
||||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ScanManager::setInitialPaths( QMap<QString, unsigned int> pathMap )
|
ScanManager::setInitialPaths( QMap< QString, unsigned int > pathMap )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
foreach( QString path, pathMap.keys() )
|
foreach( QString path, pathMap.keys() )
|
||||||
@@ -129,27 +146,45 @@ ScanManager::setInitialPaths( QMap<QString, unsigned int> pathMap )
|
|||||||
qDebug() << "Adding " << path << " to watcher";
|
qDebug() << "Adding " << path << " to watcher";
|
||||||
m_dirWatcher->addPath( path );
|
m_dirWatcher->addPath( path );
|
||||||
}
|
}
|
||||||
|
runManualScan( TomahawkSettings::instance()->scannerPaths() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ScanManager::runManualScan( const QStringList& path )
|
ScanManager::runManualScan( const QStringList& paths, bool recursive )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
if ( !m_musicScannerThreadController && !m_scanner ) //still running if these are not zero
|
if ( !m_musicScannerThreadController && !m_scanner ) //still running if these are not zero
|
||||||
{
|
{
|
||||||
m_musicScannerThreadController = new QThread( this );
|
m_musicScannerThreadController = new QThread( this );
|
||||||
m_scanner = new MusicScanner( path );
|
QStringList allPaths = paths;
|
||||||
|
foreach( QString path, m_deferredDirs[recursive] )
|
||||||
|
{
|
||||||
|
if( !allPaths.contains( path ) )
|
||||||
|
allPaths << path;
|
||||||
|
}
|
||||||
|
m_scanner = new MusicScanner( paths, recursive );
|
||||||
m_scanner->moveToThread( m_musicScannerThreadController );
|
m_scanner->moveToThread( m_musicScannerThreadController );
|
||||||
connect( m_scanner, SIGNAL( finished() ), SLOT( scannerFinished() ) );
|
connect( m_scanner, SIGNAL( finished() ), SLOT( scannerFinished() ) );
|
||||||
connect( m_scanner, SIGNAL( addWatchedDirs( const QStringList & ) ), SLOT( addWatchedDirs( const QStringList & ) ) );
|
connect( m_scanner, SIGNAL( addWatchedDirs( const QStringList & ) ), SLOT( addWatchedDirs( const QStringList & ) ) );
|
||||||
connect( m_scanner, SIGNAL( removeWatchedDir( const QString & ) ), SLOT( removeWatchedDir( const QString & ) ) );
|
connect( m_scanner, SIGNAL( removeWatchedDir( const QString & ) ), SLOT( removeWatchedDir( const QString & ) ) );
|
||||||
m_musicScannerThreadController->start( QThread::IdlePriority );
|
m_musicScannerThreadController->start( QThread::IdlePriority );
|
||||||
QMetaObject::invokeMethod( m_scanner, "startScan" );
|
QMetaObject::invokeMethod( m_scanner, "startScan" );
|
||||||
|
m_deferredDirs[recursive].clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
qDebug() << "Could not run manual scan, old scan still running";
|
{
|
||||||
|
qDebug() << "Could not run manual scan, old scan still running; deferring paths";
|
||||||
|
foreach( QString path, paths )
|
||||||
|
{
|
||||||
|
if( !m_deferredDirs[recursive].contains( path ) )
|
||||||
|
{
|
||||||
|
qDebug() << "Deferring path " << path;
|
||||||
|
m_deferredDirs[recursive] << path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -180,6 +215,34 @@ ScanManager::handleChangedDir( const QString& path )
|
|||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
qDebug() << "Dir changed: " << path;
|
qDebug() << "Dir changed: " << path;
|
||||||
|
m_queuedChangedDirs << path;
|
||||||
|
if( TomahawkSettings::instance()->watchForChanges() )
|
||||||
|
m_queuedScanTimer->start( 10000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ScanManager::queuedScanTimeout()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
runManualScan( m_queuedChangedDirs, false );
|
||||||
|
m_queuedChangedDirs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ScanManager::deferredScanTimeout()
|
||||||
|
{
|
||||||
|
if( !m_deferredDirs[true].isEmpty() )
|
||||||
|
{
|
||||||
|
qDebug() << "Running scan for deferred recursive paths";
|
||||||
|
runManualScan( m_deferredDirs[true], true );
|
||||||
|
}
|
||||||
|
else if( !m_deferredDirs[false].isEmpty() )
|
||||||
|
{
|
||||||
|
qDebug() << "Running scan for deferred non-recursive paths";
|
||||||
|
runManualScan( m_deferredDirs[false], false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,15 +19,17 @@
|
|||||||
#ifndef SCANMANAGER_H
|
#ifndef SCANMANAGER_H
|
||||||
#define SCANMANAGER_H
|
#define SCANMANAGER_H
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QMap>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
#include "dllmacro.h"
|
#include "dllmacro.h"
|
||||||
|
|
||||||
class MusicScanner;
|
class MusicScanner;
|
||||||
class QThread;
|
class QThread;
|
||||||
class QFileSystemWatcher;
|
class QFileSystemWatcher;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
class ScanManager : public QObject
|
class ScanManager : public QObject
|
||||||
{
|
{
|
||||||
@@ -39,16 +41,15 @@ public:
|
|||||||
explicit ScanManager( QObject* parent = 0 );
|
explicit ScanManager( QObject* parent = 0 );
|
||||||
virtual ~ScanManager();
|
virtual ~ScanManager();
|
||||||
|
|
||||||
void runManualScan( const QStringList& path );
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void runManualScan( const QStringList& paths, bool recursive = true );
|
||||||
void handleChangedDir( const QString& path );
|
void handleChangedDir( const QString& path );
|
||||||
void addWatchedDirs( const QStringList& paths );
|
void addWatchedDirs( const QStringList& paths );
|
||||||
void removeWatchedDir( const QString& path );
|
void removeWatchedDir( const QString& path );
|
||||||
void setInitialPaths( QMap<QString, unsigned int> pathMap );
|
void setInitialPaths( QMap< QString, unsigned int > pathMap );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void scannerQuit();
|
void scannerQuit();
|
||||||
@@ -56,6 +57,8 @@ private slots:
|
|||||||
void scannerDestroyed( QObject* scanner );
|
void scannerDestroyed( QObject* scanner );
|
||||||
|
|
||||||
void startupWatchPaths();
|
void startupWatchPaths();
|
||||||
|
void queuedScanTimeout();
|
||||||
|
void deferredScanTimeout();
|
||||||
|
|
||||||
void onSettingsChanged();
|
void onSettingsChanged();
|
||||||
|
|
||||||
@@ -64,8 +67,13 @@ private:
|
|||||||
|
|
||||||
MusicScanner* m_scanner;
|
MusicScanner* m_scanner;
|
||||||
QThread* m_musicScannerThreadController;
|
QThread* m_musicScannerThreadController;
|
||||||
QStringList m_currScannerPath;
|
QStringList m_currScannerPaths;
|
||||||
QFileSystemWatcher* m_dirWatcher;
|
QFileSystemWatcher* m_dirWatcher;
|
||||||
|
|
||||||
|
QTimer* m_queuedScanTimer;
|
||||||
|
QTimer* m_deferredScanTimer;
|
||||||
|
QStringList m_queuedChangedDirs;
|
||||||
|
QHash< bool, QStringList > m_deferredDirs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -87,7 +87,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
|||||||
|
|
||||||
// MUSIC SCANNER
|
// MUSIC SCANNER
|
||||||
//FIXME: MULTIPLECOLLECTIONDIRS
|
//FIXME: MULTIPLECOLLECTIONDIRS
|
||||||
ui->lineEditMusicPath->setText( s->scannerPath().first() );
|
ui->lineEditMusicPath->setText( s->scannerPaths().first() );
|
||||||
|
ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
|
||||||
|
|
||||||
// LAST FM
|
// LAST FM
|
||||||
ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() );
|
ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() );
|
||||||
@@ -134,7 +135,8 @@ SettingsDialog::~SettingsDialog()
|
|||||||
s->setExternalHostname( ui->staticHostName->text() );
|
s->setExternalHostname( ui->staticHostName->text() );
|
||||||
s->setExternalPort( ui->staticPort->value() );
|
s->setExternalPort( ui->staticPort->value() );
|
||||||
|
|
||||||
s->setScannerPath( QStringList( ui->lineEditMusicPath->text() ) );
|
s->setScannerPaths( QStringList( ui->lineEditMusicPath->text() ) );
|
||||||
|
s->setWatchForChanges( ui->checkBoxWatchForChanges->isChecked() );
|
||||||
|
|
||||||
s->setScrobblingEnabled( ui->checkBoxEnableLastfm->isChecked() );
|
s->setScrobblingEnabled( ui->checkBoxEnableLastfm->isChecked() );
|
||||||
s->setLastFmUsername( ui->lineEditLastfmUsername->text() );
|
s->setLastFmUsername( ui->lineEditLastfmUsername->text() );
|
||||||
|
@@ -454,6 +454,19 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxWatchForChanges">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Watch for changes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@@ -285,7 +285,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TOMAHAWK_HEADLESS
|
#ifndef TOMAHAWK_HEADLESS
|
||||||
if ( !TomahawkSettings::instance()->hasScannerPath() )
|
if ( !TomahawkSettings::instance()->hasScannerPaths() )
|
||||||
{
|
{
|
||||||
m_mainwindow->showSettingsDialog();
|
m_mainwindow->showSettingsDialog();
|
||||||
}
|
}
|
||||||
|
@@ -319,8 +319,8 @@ TomahawkWindow::showSettingsDialog()
|
|||||||
void
|
void
|
||||||
TomahawkWindow::updateCollectionManually()
|
TomahawkWindow::updateCollectionManually()
|
||||||
{
|
{
|
||||||
if ( TomahawkSettings::instance()->hasScannerPath() )
|
if ( TomahawkSettings::instance()->hasScannerPaths() )
|
||||||
ScanManager::instance()->runManualScan( TomahawkSettings::instance()->scannerPath() );
|
ScanManager::instance()->runManualScan( TomahawkSettings::instance()->scannerPaths() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user