diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 6ab67cba3d..f64f4fdf1a 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -578,6 +578,7 @@ void Folder::slotWatchedPathChanged(const QString& path) // When no sync is running or it's in the prepare phase, we can // always schedule a new sync. if (! _engine->isSyncRunning() || _syncResult.status() == SyncResult::SyncPrepare) { + emit watchedFileChangedExternally(path); emit scheduleToSync(this); return; } @@ -601,6 +602,7 @@ void Folder::slotWatchedPathChanged(const QString& path) #endif if (! ownChange) { + emit watchedFileChangedExternally(path); emit scheduleToSync(this); } } diff --git a/src/gui/folder.h b/src/gui/folder.h index c0c3580c90..cf01581176 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -204,6 +204,12 @@ signals: void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered void syncPausedChanged(Folder*, bool paused); + /** + * Fires for each change inside this folder that wasn't caused + * by sync activity. + */ + void watchedFileChangedExternally(const QString& path); + public slots: /** diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 8c5168171a..a9021804d0 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -107,6 +107,8 @@ void FolderMan::unloadFolder( Folder *f ) this, SLOT(slotFolderSyncPaused(Folder*,bool))); disconnect(&f->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)), _socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus))); + disconnect(f, SIGNAL(watchedFileChangedExternally(QString)), + &f->syncEngine().syncFileStatusTracker(), SLOT(slotPathTouched(QString))); } int FolderMan::unloadAndDeleteAllFolders() @@ -145,6 +147,7 @@ void FolderMan::registerFolderMonitor( Folder *folder ) // to the signal mapper which maps to the folder alias. The changed path // is lost this way, but we do not need it for the current implementation. connect(fw, SIGNAL(pathChanged(QString)), folder, SLOT(slotWatchedPathChanged(QString))); + _folderWatchers.insert(folder->alias(), fw); } @@ -795,6 +798,8 @@ Folder* FolderMan::addFolderInternal(const FolderDefinition& folderDefinition, A connect(folder, SIGNAL(syncPausedChanged(Folder*,bool)), SLOT(slotFolderSyncPaused(Folder*,bool))); connect(&folder->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)), _socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus))); + connect(folder, SIGNAL(watchedFileChangedExternally(QString)), + &folder->syncEngine().syncFileStatusTracker(), SLOT(slotPathTouched(QString))); registerFolderMonitor(folder); return folder; diff --git a/src/libsync/syncfilestatustracker.cpp b/src/libsync/syncfilestatustracker.cpp index ffac9e45c5..7867b14080 100644 --- a/src/libsync/syncfilestatustracker.cpp +++ b/src/libsync/syncfilestatustracker.cpp @@ -81,6 +81,8 @@ SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine) this, SLOT(slotAboutToPropagate(SyncFileItemVector&))); connect(syncEngine, SIGNAL(itemCompleted(const SyncFileItem&, const PropagatorJob&)), this, SLOT(slotItemCompleted(const SyncFileItem&))); + connect(syncEngine, SIGNAL(started()), + SLOT(slotClearDirtyPaths())); } SyncFileStatus SyncFileStatusTracker::rootStatus() @@ -143,6 +145,9 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName) return SyncFileStatus(SyncFileStatus::StatusWarning); } + if ( _dirtyPaths.contains(fileName) ) + return SyncFileStatus::StatusSync; + SyncFileItem* item = _syncEngine->findSyncItem(fileName); if (item) { return fileStatus(*item); @@ -157,6 +162,17 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName) return SyncFileStatus(); } +void SyncFileStatusTracker::slotPathTouched(const QString& fileName) +{ + QString folderPath = _syncEngine->localPath(); + Q_ASSERT(fileName.startsWith(folderPath)); + + QString localPath = fileName.mid(folderPath.size()); + _dirtyPaths.insert(localPath); + + emit fileStatusChanged(fileName, SyncFileStatus::StatusSync); +} + void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items) { std::map oldProblems; @@ -208,6 +224,13 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item) emit fileStatusChanged(getSystemDestination(item), fileStatus(item)); } +void SyncFileStatusTracker::slotClearDirtyPaths() +{ + // We just assume that during a sync all dirty statuses will be resolved + // one way or the other. + _dirtyPaths.clear(); +} + SyncFileStatus SyncFileStatusTracker::fileStatus(const SyncFileItem& item) { // Hack to know if the item was taken from the sync engine (Sync), or from the database (UpToDate) diff --git a/src/libsync/syncfilestatustracker.h b/src/libsync/syncfilestatustracker.h index fe8b9b9f57..7aa4617999 100644 --- a/src/libsync/syncfilestatustracker.h +++ b/src/libsync/syncfilestatustracker.h @@ -19,6 +19,7 @@ #include "syncfileitem.h" #include "syncfilestatus.h" #include +#include namespace OCC { @@ -36,12 +37,16 @@ public: explicit SyncFileStatusTracker(SyncEngine* syncEngine); SyncFileStatus fileStatus(const QString& systemFileName); +public slots: + void slotPathTouched(const QString& fileName); + signals: void fileStatusChanged(const QString& systemFileName, SyncFileStatus fileStatus); private slots: void slotAboutToPropagate(SyncFileItemVector& items); void slotItemCompleted(const SyncFileItem& item); + void slotClearDirtyPaths(); private: SyncFileStatus fileStatus(const SyncFileItem& item); @@ -53,6 +58,7 @@ private: SyncEngine* _syncEngine; std::map _syncProblems; + QSet _dirtyPaths; }; }