mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-04-14 13:01:53 +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:
parent
d818a7f697
commit
3bc496eaaf
@ -124,7 +124,7 @@ void
|
||||
ACLSystem::authorizePath( const QString& dbid, const QString& path, ACLSystem::ACL type )
|
||||
{
|
||||
TomahawkSettings *s = TomahawkSettings::instance();
|
||||
if( !s->scannerPath().contains( path ) )
|
||||
if( !s->scannerPaths().contains( path ) )
|
||||
{
|
||||
qDebug() << "path selected is not in our scanner path!";
|
||||
return;
|
||||
|
@ -32,6 +32,7 @@ Database::instance()
|
||||
|
||||
Database::Database( const QString& dbname, QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_ready( false )
|
||||
, m_impl( new DatabaseImpl( dbname, this ) )
|
||||
, 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( ready() ) );
|
||||
connect( m_impl, SIGNAL( indexReady() ), SLOT( setIsReadyTrue() ) );
|
||||
|
||||
m_workerRW->start();
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ public:
|
||||
const bool indexReady() const { return m_indexReady; }
|
||||
|
||||
void loadIndex();
|
||||
|
||||
bool isReady() const { return m_ready; }
|
||||
|
||||
signals:
|
||||
void indexReady(); // search index
|
||||
@ -63,7 +65,11 @@ signals:
|
||||
public slots:
|
||||
void enqueue( QSharedPointer<DatabaseCommand> lc );
|
||||
|
||||
private slots:
|
||||
void setIsReadyTrue() { m_ready = true; }
|
||||
|
||||
private:
|
||||
bool m_ready;
|
||||
DatabaseImpl* m_impl;
|
||||
DatabaseWorker* m_workerRW;
|
||||
QHash< QString, DatabaseWorker* > m_workers;
|
||||
|
@ -84,6 +84,8 @@ signals:
|
||||
public slots:
|
||||
|
||||
private:
|
||||
bool m_ready;
|
||||
|
||||
bool updateSchema( int currentver );
|
||||
|
||||
QSqlDatabase db;
|
||||
|
@ -66,29 +66,50 @@ TomahawkSettings::~TomahawkSettings()
|
||||
|
||||
|
||||
QStringList
|
||||
TomahawkSettings::scannerPath() const
|
||||
TomahawkSettings::scannerPaths()
|
||||
{
|
||||
//FIXME: After enough time, remove this hack (and make const)
|
||||
#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
|
||||
return value( "scannerpath", "" ).toStringList();
|
||||
if( value( "scannerpaths" ).isNull() )
|
||||
setValue( "scannerpaths", value( "scannerpath" ) );
|
||||
return value( "scannerpaths", "" ).toStringList();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkSettings::setScannerPath( const QStringList& path )
|
||||
TomahawkSettings::setScannerPaths( const QStringList& paths )
|
||||
{
|
||||
setValue( "scannerpath", path );
|
||||
setValue( "scannerpaths", paths );
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
TomahawkSettings::setAcceptedLegalWarning( bool accept )
|
||||
{
|
||||
|
@ -41,9 +41,12 @@ public:
|
||||
void applyChanges() { emit changed(); }
|
||||
|
||||
/// General settings
|
||||
QStringList scannerPath() const; /// QDesktopServices::MusicLocation by default
|
||||
void setScannerPath( const QStringList& path );
|
||||
bool hasScannerPath() const;
|
||||
QStringList scannerPaths(); /// QDesktopServices::MusicLocation by default
|
||||
void setScannerPaths( const QStringList& paths );
|
||||
bool hasScannerPaths() const;
|
||||
|
||||
bool watchForChanges() const;
|
||||
void setWatchForChanges( bool watch );
|
||||
|
||||
bool acceptedLegalWarning() const;
|
||||
void setAcceptedLegalWarning( bool accept );
|
||||
|
@ -31,14 +31,16 @@ using namespace Tomahawk;
|
||||
void
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DirLister::scanDir( QDir dir, int depth )
|
||||
DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode )
|
||||
{
|
||||
qDebug() << "DirLister::scanDir scanning: " << dir.absolutePath();
|
||||
QFileInfoList dirs;
|
||||
const uint mtime = QFileInfo( dir.absolutePath() ).lastModified().toUTC().toTime_t();
|
||||
m_newdirmtimes.insert( dir.absolutePath(), mtime );
|
||||
@ -65,14 +67,18 @@ DirLister::scanDir( QDir dir, int depth )
|
||||
|
||||
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()
|
||||
, m_dirs( dirs )
|
||||
, m_recursive( recursive )
|
||||
, m_batchsize( bs )
|
||||
, m_dirLister( 0 )
|
||||
, m_dirListerThreadController( 0 )
|
||||
@ -150,8 +156,7 @@ MusicScanner::scan()
|
||||
|
||||
m_dirListerThreadController = new QThread( this );
|
||||
|
||||
//FIXME: MULTIPLECOLLECTIONDIRS
|
||||
m_dirLister = new DirLister( QDir( m_dirs.first(), 0 ), m_dirmtimes );
|
||||
m_dirLister = new DirLister( m_dirs, m_dirmtimes, m_recursive );
|
||||
m_dirLister->moveToThread( m_dirListerThreadController );
|
||||
|
||||
connect( m_dirLister, SIGNAL( fileToScan( QFileInfo ) ),
|
||||
|
@ -39,8 +39,15 @@ class DirLister : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
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;
|
||||
}
|
||||
@ -56,11 +63,13 @@ signals:
|
||||
|
||||
private slots:
|
||||
void go();
|
||||
void scanDir( QDir dir, int depth );
|
||||
void scanDir( QDir dir, int depth, DirLister::Mode mode );
|
||||
|
||||
private:
|
||||
QDir m_dir;
|
||||
QStringList m_dirs;
|
||||
QMap<QString, unsigned int> m_dirmtimes;
|
||||
bool m_recursive;
|
||||
|
||||
QMap<QString, unsigned int> m_newdirmtimes;
|
||||
};
|
||||
|
||||
@ -69,7 +78,7 @@ class MusicScanner : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MusicScanner( const QStringList& dirs, quint32 bs = 0 );
|
||||
MusicScanner( const QStringList& dirs, bool recursive = true, quint32 bs = 0 );
|
||||
~MusicScanner();
|
||||
|
||||
signals:
|
||||
@ -105,6 +114,7 @@ private:
|
||||
QMap<QString, unsigned int> m_newdirmtimes;
|
||||
|
||||
QList<QVariant> m_scannedfiles;
|
||||
bool m_recursive;
|
||||
quint32 m_batchsize;
|
||||
|
||||
DirLister* m_dirLister;
|
||||
|
@ -45,20 +45,33 @@ ScanManager::ScanManager( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_scanner( 0 )
|
||||
, m_musicScannerThreadController( 0 )
|
||||
, m_currScannerPaths()
|
||||
, m_dirWatcher( 0 )
|
||||
, m_queuedScanTimer( 0 )
|
||||
, m_deferredScanTimer( 0 )
|
||||
, m_queuedChangedDirs()
|
||||
, m_deferredDirs()
|
||||
{
|
||||
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( m_queuedScanTimer, SIGNAL( timeout() ), SLOT( queuedScanTimeout() ) );
|
||||
connect( m_deferredScanTimer, SIGNAL( timeout() ), SLOT( deferredScanTimeout() ) );
|
||||
connect( m_dirWatcher, SIGNAL( directoryChanged( const QString & ) ), SLOT( handleChangedDir( const QString & ) ) );
|
||||
|
||||
if ( TomahawkSettings::instance()->hasScannerPath() )
|
||||
m_currScannerPath = TomahawkSettings::instance()->scannerPath();
|
||||
if ( TomahawkSettings::instance()->hasScannerPaths() )
|
||||
m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
|
||||
|
||||
qDebug() << "loading initial directories to watch";
|
||||
QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) );
|
||||
m_deferredScanTimer->start();
|
||||
}
|
||||
|
||||
|
||||
@ -91,14 +104,18 @@ ScanManager::~ScanManager()
|
||||
void
|
||||
ScanManager::onSettingsChanged()
|
||||
{
|
||||
if ( TomahawkSettings::instance()->hasScannerPath() &&
|
||||
m_currScannerPath != TomahawkSettings::instance()->scannerPath() )
|
||||
if ( TomahawkSettings::instance()->hasScannerPaths() &&
|
||||
m_currScannerPaths != TomahawkSettings::instance()->scannerPaths() )
|
||||
{
|
||||
m_currScannerPath = TomahawkSettings::instance()->scannerPath();
|
||||
m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
|
||||
m_dirWatcher->removePaths( m_dirWatcher->directories() );
|
||||
m_dirWatcher->addPaths( m_currScannerPath );
|
||||
runManualScan( m_currScannerPath );
|
||||
m_dirWatcher->addPaths( m_currScannerPaths );
|
||||
runManualScan( m_currScannerPaths );
|
||||
}
|
||||
|
||||
if( TomahawkSettings::instance()->watchForChanges() &&
|
||||
!m_queuedChangedDirs.isEmpty() )
|
||||
runManualScan( m_queuedChangedDirs, false );
|
||||
}
|
||||
|
||||
|
||||
@ -107,21 +124,21 @@ ScanManager::startupWatchPaths()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if( !Database::instance() )
|
||||
if( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) )
|
||||
{
|
||||
QTimer::singleShot( 1000, this, SLOT( startupWatchPaths() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( m_currScannerPath );
|
||||
connect( cmd, SIGNAL( done( QMap<QString, unsigned int> ) ),
|
||||
SLOT( setInitialPaths( QMap<QString, unsigned int> ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( m_currScannerPaths );
|
||||
connect( cmd, SIGNAL( done( QMap< QString, unsigned int > ) ),
|
||||
SLOT( setInitialPaths( QMap< QString, unsigned int > ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScanManager::setInitialPaths( QMap<QString, unsigned int> pathMap )
|
||||
ScanManager::setInitialPaths( QMap< QString, unsigned int > pathMap )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
foreach( QString path, pathMap.keys() )
|
||||
@ -129,27 +146,45 @@ ScanManager::setInitialPaths( QMap<QString, unsigned int> pathMap )
|
||||
qDebug() << "Adding " << path << " to watcher";
|
||||
m_dirWatcher->addPath( path );
|
||||
}
|
||||
runManualScan( TomahawkSettings::instance()->scannerPaths() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScanManager::runManualScan( const QStringList& path )
|
||||
ScanManager::runManualScan( const QStringList& paths, bool recursive )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( !m_musicScannerThreadController && !m_scanner ) //still running if these are not zero
|
||||
{
|
||||
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 );
|
||||
connect( m_scanner, SIGNAL( finished() ), SLOT( scannerFinished() ) );
|
||||
connect( m_scanner, SIGNAL( addWatchedDirs( const QStringList & ) ), SLOT( addWatchedDirs( const QStringList & ) ) );
|
||||
connect( m_scanner, SIGNAL( removeWatchedDir( const QString & ) ), SLOT( removeWatchedDir( const QString & ) ) );
|
||||
m_musicScannerThreadController->start( QThread::IdlePriority );
|
||||
QMetaObject::invokeMethod( m_scanner, "startScan" );
|
||||
m_deferredDirs[recursive].clear();
|
||||
}
|
||||
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
|
||||
@ -180,6 +215,34 @@ ScanManager::handleChangedDir( const QString& path )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
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
|
||||
#define SCANMANAGER_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
class MusicScanner;
|
||||
class QThread;
|
||||
class QFileSystemWatcher;
|
||||
class QTimer;
|
||||
|
||||
class ScanManager : public QObject
|
||||
{
|
||||
@ -38,17 +40,16 @@ public:
|
||||
|
||||
explicit ScanManager( QObject* parent = 0 );
|
||||
virtual ~ScanManager();
|
||||
|
||||
void runManualScan( const QStringList& path );
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
public slots:
|
||||
void runManualScan( const QStringList& paths, bool recursive = true );
|
||||
void handleChangedDir( const QString& path );
|
||||
void addWatchedDirs( const QStringList& paths );
|
||||
void removeWatchedDir( const QString& path );
|
||||
void setInitialPaths( QMap<QString, unsigned int> pathMap );
|
||||
void setInitialPaths( QMap< QString, unsigned int > pathMap );
|
||||
|
||||
private slots:
|
||||
void scannerQuit();
|
||||
@ -56,6 +57,8 @@ private slots:
|
||||
void scannerDestroyed( QObject* scanner );
|
||||
|
||||
void startupWatchPaths();
|
||||
void queuedScanTimeout();
|
||||
void deferredScanTimeout();
|
||||
|
||||
void onSettingsChanged();
|
||||
|
||||
@ -64,8 +67,13 @@ private:
|
||||
|
||||
MusicScanner* m_scanner;
|
||||
QThread* m_musicScannerThreadController;
|
||||
QStringList m_currScannerPath;
|
||||
QStringList m_currScannerPaths;
|
||||
QFileSystemWatcher* m_dirWatcher;
|
||||
|
||||
QTimer* m_queuedScanTimer;
|
||||
QTimer* m_deferredScanTimer;
|
||||
QStringList m_queuedChangedDirs;
|
||||
QHash< bool, QStringList > m_deferredDirs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -87,7 +87,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
|
||||
// MUSIC SCANNER
|
||||
//FIXME: MULTIPLECOLLECTIONDIRS
|
||||
ui->lineEditMusicPath->setText( s->scannerPath().first() );
|
||||
ui->lineEditMusicPath->setText( s->scannerPaths().first() );
|
||||
ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
|
||||
|
||||
// LAST FM
|
||||
ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() );
|
||||
@ -134,7 +135,8 @@ SettingsDialog::~SettingsDialog()
|
||||
s->setExternalHostname( ui->staticHostName->text() );
|
||||
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->setLastFmUsername( ui->lineEditLastfmUsername->text() );
|
||||
|
@ -66,7 +66,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>e.g. user@example.com</string>
|
||||
<string>e.g. user@example.com</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -454,6 +454,19 @@
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -285,7 +285,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
}
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !TomahawkSettings::instance()->hasScannerPath() )
|
||||
if ( !TomahawkSettings::instance()->hasScannerPaths() )
|
||||
{
|
||||
m_mainwindow->showSettingsDialog();
|
||||
}
|
||||
|
@ -319,8 +319,8 @@ TomahawkWindow::showSettingsDialog()
|
||||
void
|
||||
TomahawkWindow::updateCollectionManually()
|
||||
{
|
||||
if ( TomahawkSettings::instance()->hasScannerPath() )
|
||||
ScanManager::instance()->runManualScan( TomahawkSettings::instance()->scannerPath() );
|
||||
if ( TomahawkSettings::instance()->hasScannerPaths() )
|
||||
ScanManager::instance()->runManualScan( TomahawkSettings::instance()->scannerPaths() );
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user