Remove subdirectory watches after a directory is removed from the library. Otherwise subdirectories that changed after the directory was removed would be re-scanned and re-added.
This commit is contained in:
parent
b4e1cef2c2
commit
facb366017
@ -26,6 +26,7 @@ class FileSystemWatcherInterface : public QObject {
|
||||
FileSystemWatcherInterface(QObject* parent = 0);
|
||||
virtual void Init() {}
|
||||
virtual void AddPath(const QString& path) = 0;
|
||||
virtual void RemovePath(const QString& path) = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
static FileSystemWatcherInterface* Create(QObject* parent = 0);
|
||||
|
@ -32,6 +32,7 @@ class MacFSListener : public FileSystemWatcherInterface {
|
||||
explicit MacFSListener(QObject* parent = 0);
|
||||
void Init();
|
||||
void AddPath(const QString& path);
|
||||
void RemovePath(const QString& path);
|
||||
void Clear();
|
||||
|
||||
signals:
|
||||
|
@ -59,6 +59,12 @@ void MacFSListener::AddPath(const QString& path) {
|
||||
UpdateStream();
|
||||
}
|
||||
|
||||
void MacFSListener::RemovePath(const QString& path) {
|
||||
Q_ASSERT(run_loop_);
|
||||
paths_.remove(path);
|
||||
UpdateStream();
|
||||
}
|
||||
|
||||
void MacFSListener::Clear() {
|
||||
paths_.clear();
|
||||
UpdateStream();
|
||||
|
@ -30,6 +30,10 @@ void QtFSListener::AddPath(const QString& path) {
|
||||
watcher_.addPath(path);
|
||||
}
|
||||
|
||||
void QtFSListener::RemovePath(const QString& path) {
|
||||
watcher_.removePath(path);
|
||||
}
|
||||
|
||||
void QtFSListener::Clear() {
|
||||
watcher_.removePaths(watcher_.directories());
|
||||
watcher_.removePaths(watcher_.files());
|
||||
|
@ -27,6 +27,7 @@ class QtFSListener : public FileSystemWatcherInterface {
|
||||
public:
|
||||
QtFSListener(QObject* parent);
|
||||
virtual void AddPath(const QString& path);
|
||||
virtual void RemovePath(const QString& path);
|
||||
virtual void Clear();
|
||||
|
||||
private:
|
||||
|
@ -27,13 +27,17 @@ class QSqlQuery;
|
||||
struct Directory {
|
||||
Directory() : id(-1) {}
|
||||
|
||||
bool operator ==(const Directory& other) const {
|
||||
return path == other.path && id == other.id;
|
||||
}
|
||||
|
||||
QString path;
|
||||
int id;
|
||||
};
|
||||
Q_DECLARE_METATYPE(Directory);
|
||||
Q_DECLARE_METATYPE(Directory)
|
||||
|
||||
typedef QList<Directory> DirectoryList;
|
||||
Q_DECLARE_METATYPE(DirectoryList);
|
||||
Q_DECLARE_METATYPE(DirectoryList)
|
||||
|
||||
|
||||
struct Subdirectory {
|
||||
@ -43,9 +47,9 @@ struct Subdirectory {
|
||||
QString path;
|
||||
uint mtime;
|
||||
};
|
||||
Q_DECLARE_METATYPE(Subdirectory);
|
||||
Q_DECLARE_METATYPE(Subdirectory)
|
||||
|
||||
typedef QList<Subdirectory> SubdirectoryList;
|
||||
Q_DECLARE_METATYPE(SubdirectoryList);
|
||||
Q_DECLARE_METATYPE(SubdirectoryList)
|
||||
|
||||
#endif // DIRECTORY_H
|
||||
|
@ -184,9 +184,7 @@ SubdirectoryList LibraryWatcher::ScanTransaction::GetAllSubdirs() {
|
||||
}
|
||||
|
||||
void LibraryWatcher::AddDirectory(const Directory& dir, const SubdirectoryList& subdirs) {
|
||||
DirData data;
|
||||
data.dir = dir;
|
||||
watched_dirs_[dir.id] = data;
|
||||
watched_dirs_[dir.id] = dir;
|
||||
|
||||
if (subdirs.isEmpty()) {
|
||||
// This is a new directory that we've never seen before.
|
||||
@ -208,7 +206,7 @@ void LibraryWatcher::AddDirectory(const Directory& dir, const SubdirectoryList&
|
||||
ScanSubdirectory(subdir.path, subdir, &transaction);
|
||||
|
||||
if (monitor_)
|
||||
AddWatch(data, subdir.path);
|
||||
AddWatch(dir, subdir.path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,8 +221,8 @@ void LibraryWatcher::ScanSubdirectory(
|
||||
// Do not scan symlinked dirs that are already in collection
|
||||
if (path_info.isSymLink()) {
|
||||
QString real_path = path_info.symLinkTarget();
|
||||
foreach (const DirData& dir_data, watched_dirs_) {
|
||||
if (real_path.startsWith(dir_data.dir.path)) {
|
||||
foreach (const Directory& dir, watched_dirs_) {
|
||||
if (real_path.startsWith(dir.path)) {
|
||||
t->AddToProgress(1);
|
||||
return;
|
||||
}
|
||||
@ -550,7 +548,7 @@ uint LibraryWatcher::GetMtimeForCue(const QString& cue_path) {
|
||||
: 0;
|
||||
}
|
||||
|
||||
void LibraryWatcher::AddWatch(const DirData& dir, const QString& path) {
|
||||
void LibraryWatcher::AddWatch(const Directory& dir, const QString& path) {
|
||||
if (!QFile::exists(path))
|
||||
return;
|
||||
|
||||
@ -563,6 +561,12 @@ void LibraryWatcher::AddWatch(const DirData& dir, const QString& path) {
|
||||
void LibraryWatcher::RemoveDirectory(const Directory& dir) {
|
||||
rescan_queue_.remove(dir.id);
|
||||
watched_dirs_.remove(dir.id);
|
||||
|
||||
// Stop watching the directory's subdirectories
|
||||
foreach (const QString& subdir_path, subdir_mapping_.keys(dir)) {
|
||||
fs_watcher_->RemovePath(subdir_path);
|
||||
subdir_mapping_.remove(subdir_path);
|
||||
}
|
||||
}
|
||||
|
||||
bool LibraryWatcher::FindSongByPath(const SongList& list, const QString& path, Song* out) {
|
||||
@ -578,11 +582,11 @@ bool LibraryWatcher::FindSongByPath(const SongList& list, const QString& path, S
|
||||
|
||||
void LibraryWatcher::DirectoryChanged(const QString &subdir) {
|
||||
// Find what dir it was in
|
||||
QHash<QString, DirData>::const_iterator it = subdir_mapping_.constFind(subdir);
|
||||
QHash<QString, Directory>::const_iterator it = subdir_mapping_.constFind(subdir);
|
||||
if (it == subdir_mapping_.constEnd()) {
|
||||
return;
|
||||
}
|
||||
Directory dir = it->dir;
|
||||
Directory dir = *it;
|
||||
|
||||
qLog(Debug) << "Subdir" << subdir << "changed under directory" << dir.path << "id" << dir.id;
|
||||
|
||||
@ -702,10 +706,10 @@ void LibraryWatcher::ReloadSettings() {
|
||||
fs_watcher_->Clear();
|
||||
} else if (monitor_ && !was_monitoring_before) {
|
||||
// Add all directories to all QFileSystemWatchers again
|
||||
foreach (const DirData& data, watched_dirs_.values()) {
|
||||
SubdirectoryList subdirs = backend_->SubdirsInDirectory(data.dir.id);
|
||||
foreach (const Directory& dir, watched_dirs_.values()) {
|
||||
SubdirectoryList subdirs = backend_->SubdirsInDirectory(dir.id);
|
||||
foreach (const Subdirectory& subdir, subdirs) {
|
||||
AddWatch(data, subdir.path);
|
||||
AddWatch(dir, subdir.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -739,8 +743,8 @@ void LibraryWatcher::FullScanNow() {
|
||||
}
|
||||
|
||||
void LibraryWatcher::PerformScan(bool incremental, bool ignore_mtimes) {
|
||||
foreach (const DirData& data, watched_dirs_.values()) {
|
||||
ScanTransaction transaction(this, data.dir.id,
|
||||
foreach (const Directory& dir, watched_dirs_.values()) {
|
||||
ScanTransaction transaction(this, dir.id,
|
||||
incremental, ignore_mtimes);
|
||||
SubdirectoryList subdirs(transaction.GetAllSubdirs());
|
||||
transaction.AddToProgressMax(subdirs.count());
|
||||
|
@ -140,18 +140,13 @@ class LibraryWatcher : public QObject {
|
||||
ScanTransaction* t, bool force_noincremental = false);
|
||||
|
||||
private:
|
||||
// One of these gets stored for each Directory we're watching
|
||||
struct DirData {
|
||||
Directory dir;
|
||||
};
|
||||
|
||||
static bool FindSongByPath(const SongList& list, const QString& path, Song* out);
|
||||
inline static QString NoExtensionPart( const QString &fileName );
|
||||
inline static QString ExtensionPart( const QString &fileName );
|
||||
inline static QString DirectoryPart( const QString &fileName );
|
||||
QString PickBestImage(const QStringList& images);
|
||||
QString ImageForSong(const QString& path, QMap<QString, QStringList>& album_art);
|
||||
void AddWatch(const DirData& dir, const QString& path);
|
||||
void AddWatch(const Directory& dir, const QString& path);
|
||||
uint GetMtimeForCue(const QString& cue_path);
|
||||
void PerformScan(bool incremental, bool ignore_mtimes);
|
||||
|
||||
@ -181,7 +176,7 @@ class LibraryWatcher : public QObject {
|
||||
QString device_name_;
|
||||
|
||||
FileSystemWatcherInterface* fs_watcher_;
|
||||
QHash<QString, DirData> subdir_mapping_;
|
||||
QHash<QString, Directory> subdir_mapping_;
|
||||
|
||||
/* A list of words use to try to identify the (likely) best image
|
||||
* found in an directory to use as cover artwork.
|
||||
@ -194,7 +189,7 @@ class LibraryWatcher : public QObject {
|
||||
bool scan_on_startup_;
|
||||
bool monitor_;
|
||||
|
||||
QMap<int, DirData> watched_dirs_;
|
||||
QMap<int, Directory> watched_dirs_;
|
||||
QTimer* rescan_timer_;
|
||||
QMap<int, QStringList> rescan_queue_; // dir id -> list of subdirs to be scanned
|
||||
bool rescan_paused_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user