// 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;
}
#endif
if (! ownChange) {
+ emit watchedFileChangedExternally(path);
emit scheduleToSync(this);
}
}
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:
/**
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()
// 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);
}
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;
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()
return SyncFileStatus(SyncFileStatus::StatusWarning);
}
+ if ( _dirtyPaths.contains(fileName) )
+ return SyncFileStatus::StatusSync;
+
SyncFileItem* item = _syncEngine->findSyncItem(fileName);
if (item) {
return fileStatus(*item);
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<QString, SyncFileStatus::SyncFileStatusTag> oldProblems;
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)
#include "syncfileitem.h"
#include "syncfilestatus.h"
#include <map>
+#include <QSet>
namespace OCC {
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);
SyncEngine* _syncEngine;
std::map<QString, SyncFileStatus::SyncFileStatusTag> _syncProblems;
+ QSet<QString> _dirtyPaths;
};
}