changeset 541:0a16db274f2c fswatcher

Update the filesystem watcher with work directory / file state. Still doesn't track "clean" files properly unless "show all files" is enabled
author Chris Cannam
date Tue, 14 Feb 2012 16:17:23 +0000
parents fc2df97920e8
children 7829da6abe97
files src/filestates.cpp src/filestates.h src/fswatcher.cpp src/fswatcher.h src/mainwindow.cpp src/mainwindow.h
diffstat 6 files changed, 73 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/filestates.cpp	Mon Feb 13 17:29:06 2012 +0000
+++ b/src/filestates.cpp	Tue Feb 14 16:17:23 2012 +0000
@@ -142,6 +142,18 @@
     return (m_stateMap.contains(file));
 }
 
+QStringList FileStates::trackedFiles() const
+{
+    QStringList all;
+    all << filesInState(Modified);
+    all << filesInState(Added);
+    all << filesInState(Removed);
+    all << filesInState(InConflict);
+    all << filesInState(Missing);
+    all << filesInState(Clean);
+    return all;
+}
+
 FileStates::Activities FileStates::activitiesSupportedBy(State s)
 {
     Activities a;
--- a/src/filestates.h	Mon Feb 13 17:29:06 2012 +0000
+++ b/src/filestates.h	Tue Feb 14 16:17:23 2012 +0000
@@ -52,6 +52,8 @@
     State stateOf(QString file) const;
     bool isKnown(QString file) const;
 
+    QStringList trackedFiles() const;
+
     enum Activity {
 
         // These are in the order in which they want to be listed in
--- a/src/fswatcher.cpp	Mon Feb 13 17:29:06 2012 +0000
+++ b/src/fswatcher.cpp	Tue Feb 14 16:17:23 2012 +0000
@@ -65,6 +65,7 @@
 FsWatcher::setWorkDirPath(QString path)
 {
     QMutexLocker locker(&m_mutex);
+    if (m_workDirPath == path) return;
     m_watcher.removePaths(m_watcher.directories());
     m_watcher.removePaths(m_watcher.files());
     m_workDirPath = path;
@@ -76,10 +77,24 @@
 FsWatcher::setTrackedFilePaths(QStringList paths)
 {
     QMutexLocker locker(&m_mutex);
-    m_watcher.removePaths(m_watcher.files());
+
+    QSet<QString> alreadyWatched = 
+	QSet<QString>::fromList(m_watcher.files());
+
     foreach (QString path, paths) {
-	m_watcher.addPath(path);
+        if (!alreadyWatched.contains(path)) {
+            m_watcher.addPath(path);
+        } else {
+            alreadyWatched.remove(path);
+        }
     }
+
+    // Remove the remaining paths, those that were being watched
+    // before but that are not in the list we were given
+    foreach (QString path, alreadyWatched) {
+        m_watcher.removePath(path);
+    }
+
     debugPrint();
 }
 
@@ -171,8 +186,12 @@
             std::cerr << "FsWatcher: Directory " << path << " has changed, but not in a way that we are monitoring" << std::endl;
 #endif
             return;
+        } else {
+#ifdef DEBUG_FSWATCHER
+            std::cerr << "FsWatcher: Directory " << path << " has changed" << std::endl;
+#endif
+            m_dirContents[path] = files;
         }
-        else m_dirContents[path] = files;
 
         size_t counter = ++m_lastCounter;
         m_changes[path] = counter;
@@ -192,6 +211,8 @@
         // watching the file explicitly, i.e. the file is in the
         // tracked file paths list. So we never want to ignore them
 
+        std::cerr << "FsWatcher: Tracked file " << path << " has changed" << std::endl;
+
         size_t counter = ++m_lastCounter;
         m_changes[path] = counter;
     }
@@ -205,10 +226,16 @@
     QFileInfo fi(path);
     QString fn(fi.fileName());
     foreach (QString pfx, m_ignoredPrefixes) {
-        if (fn.startsWith(pfx)) return true;
+        if (fn.startsWith(pfx)) {
+            std::cerr << "(ignoring: " << path << ")" << std::endl;
+            return true;
+        }
     }
     foreach (QString sfx, m_ignoredSuffixes) {
-        if (fn.endsWith(sfx)) return true;
+        if (fn.endsWith(sfx)) {
+            std::cerr << "(ignoring: " << path << ")" << std::endl;
+            return true;
+        }
     }
     return false;
 }
@@ -227,6 +254,8 @@
             files.insert(entry);
         }
     }
+//    std::cerr << "scanDirectory:" << std::endl;
+//    foreach (QString f, files) std::cerr << f << std::endl;
     return files;
 }
 
--- a/src/fswatcher.h	Mon Feb 13 17:29:06 2012 +0000
+++ b/src/fswatcher.h	Tue Feb 14 16:17:23 2012 +0000
@@ -40,7 +40,8 @@
      * directory and all its subdirectories (recursively) will be
      * monitored for changes.
      *
-     * Calling this also clears the tracked file path set. Call
+     * If this path differs from the currently set work dir path, then
+     * the tracked file paths will also be cleared. Call
      * setTrackedFilePaths afterwards to ensure non-directory files
      * are monitored.
      */
--- a/src/mainwindow.cpp	Mon Feb 13 17:29:06 2012 +0000
+++ b/src/mainwindow.cpp	Tue Feb 14 16:17:23 2012 +0000
@@ -68,7 +68,7 @@
     m_fsWatcher = new FsWatcher();
     m_fsWatcherToken = m_fsWatcher->getNewToken();
     m_commandSequenceInProgress = false;
-    connect(m_fsWatcher, SIGNAL(changed()), this, SLOT(fsWatcherChanged()));
+    connect(m_fsWatcher, SIGNAL(changed()), this, SLOT(checkFilesystem()));
 
     m_commitsSincePush = 0;
     m_shouldHgStat = true;
@@ -122,6 +122,7 @@
     setUnifiedTitleAndToolBarOnMac(true);
     connectActions();
     clearState();
+    updateFsWatcher();
     enableDisableActions();
 
     if (m_firstStart) {
@@ -261,6 +262,10 @@
 
     m_lastStatOutput = "";
 
+    // We're about to do a stat, so we can silently bring ourselves
+    // up-to-date on any file changes to this point
+    (void)m_fsWatcher->getChangedPaths(m_fsWatcherToken);
+
     m_runner->requestAction(HgAction(ACT_STAT, m_workFolderPath, params));
 }
 
@@ -1424,6 +1429,7 @@
             if (result) {
                 enableDisableActions();
                 clearState();
+                updateFsWatcher();
                 hgQueryPaths();
                 done = true;
             }
@@ -1509,6 +1515,7 @@
     if (openLocal(local)) {
         enableDisableActions();
         clearState();
+        updateFsWatcher();
         hgQueryPaths();
     }
 }
@@ -1815,16 +1822,22 @@
     }
 }
 
+void MainWindow::updateFsWatcher()
+{
+    m_fsWatcher->setWorkDirPath(m_workFolderPath);
+    m_fsWatcher->setTrackedFilePaths(m_hgTabs->getFileStates().trackedFiles());
+}
+
 void MainWindow::checkFilesystem()
 {
     DEBUG << "MainWindow::checkFilesystem" << endl;
-    hgRefresh();
-}
-
-void MainWindow::fsWatcherChanged()
-{
-    DEBUG << "MainWindow::fsWatcherChanged" << endl;
-
+    if (!m_commandSequenceInProgress) {
+        if (!m_fsWatcher->getChangedPaths(m_fsWatcherToken).empty()) {
+            hgRefresh();
+            return;
+        }
+    }
+    updateFsWatcher();
 }
 
 QString MainWindow::format1(QString head)
@@ -2507,6 +2520,7 @@
         enableDisableActions();
         m_hgTabs->updateHistory();
         updateRecentMenu();
+        checkFilesystem();
     }
 }
 
--- a/src/mainwindow.h	Mon Feb 13 17:29:06 2012 +0000
+++ b/src/mainwindow.h	Tue Feb 14 16:17:23 2012 +0000
@@ -113,7 +113,7 @@
     void hgIgnoreFiles(QStringList);
     void hgUnIgnoreFiles(QStringList);
 
-    void fsWatcherChanged();
+    void updateFsWatcher();
     void checkFilesystem();
 
     void newerVersionAvailable(QString);