diff src/mainwindow.cpp @ 540:fc2df97920e8 fswatcher

Introduce FsWatcher into main window (though it isn't fully rigged up yet)
author Chris Cannam
date Mon, 13 Feb 2012 17:29:06 +0000
parents a4e699d32a9a
children 0a16db274f2c
line wrap: on
line diff
--- a/src/mainwindow.cpp	Fri Feb 10 21:49:27 2012 +0000
+++ b/src/mainwindow.cpp	Mon Feb 13 17:29:06 2012 +0000
@@ -52,14 +52,12 @@
 #include "workstatuswidget.h"
 #include "hgignoredialog.h"
 #include "versiontester.h"
+#include "fswatcher.h"
 
 
 MainWindow::MainWindow(QString myDirPath) :
     m_myDirPath(myDirPath),
-    m_helpDialog(0),
-    m_fsWatcherGeneralTimer(0),
-    m_fsWatcherRestoreTimer(0),
-    m_fsWatcherSuspended(false)
+    m_helpDialog(0)
 {
     setWindowIcon(QIcon(":images/easyhg-icon.png"));
 
@@ -67,7 +65,11 @@
 
     m_showAllFiles = false;
 
-    m_fsWatcher = 0;
+    m_fsWatcher = new FsWatcher();
+    m_fsWatcherToken = m_fsWatcher->getNewToken();
+    m_commandSequenceInProgress = false;
+    connect(m_fsWatcher, SIGNAL(changed()), this, SLOT(fsWatcherChanged()));
+
     m_commitsSincePush = 0;
     m_shouldHgStat = true;
 
@@ -1301,14 +1303,6 @@
     m_mergeCommitComment = "";
     m_stateUnknown = true;
     m_needNewLog = true;
-    if (m_fsWatcher) {
-        delete m_fsWatcherGeneralTimer;
-        m_fsWatcherGeneralTimer = 0;
-        delete m_fsWatcherRestoreTimer;
-        m_fsWatcherRestoreTimer = 0;
-        delete m_fsWatcher;
-        m_fsWatcher = 0;
-    }
 }
 
 void MainWindow::hgServe()
@@ -1821,126 +1815,16 @@
     }
 }
 
-void MainWindow::updateFileSystemWatcher()
-{
-    bool justCreated = false;
-    if (!m_fsWatcher) {
-        m_fsWatcher = new QFileSystemWatcher();
-        justCreated = true;
-    }
-
-    // QFileSystemWatcher will refuse to add a file or directory to
-    // its watch list that it is already watching -- fine, that's what
-    // we want -- but it prints a warning when this happens, which is
-    // annoying because it would be the normal case for us.  So we'll
-    // check for duplicates ourselves.
-    QSet<QString> alreadyWatched;
-    QStringList dl(m_fsWatcher->directories());
-    foreach (QString d, dl) alreadyWatched.insert(d);
-    
-    std::deque<QString> pending;
-    pending.push_back(m_workFolderPath);
-
-    while (!pending.empty()) {
-
-        QString path = pending.front();
-        pending.pop_front();
-        if (!alreadyWatched.contains(path)) {
-            m_fsWatcher->addPath(path);
-            DEBUG << "Added to file system watcher: " << path << endl;
-        }
-
-        QDir d(path);
-        if (d.exists()) {
-            d.setFilter(QDir::Dirs | QDir::NoDotAndDotDot |
-                        QDir::Readable | QDir::NoSymLinks);
-            foreach (QString entry, d.entryList()) {
-                if (entry.startsWith('.')) continue;
-                QString entryPath = d.absoluteFilePath(entry);
-                pending.push_back(entryPath);
-            }
-        }
-    }
-
-    // The general timer isn't really related to the fs watcher
-    // object, it just does something similar -- every now and then we
-    // do a refresh just to update the history dates etc
-
-    m_fsWatcherGeneralTimer = new QTimer(this);
-    connect(m_fsWatcherGeneralTimer, SIGNAL(timeout()),
-            this, SLOT(checkFilesystem()));
-    m_fsWatcherGeneralTimer->setInterval(30 * 60 * 1000); // half an hour
-    m_fsWatcherGeneralTimer->start();
-
-    if (justCreated) {
-        connect(m_fsWatcher, SIGNAL(directoryChanged(QString)),
-                this, SLOT(fsDirectoryChanged(QString)));
-        connect(m_fsWatcher, SIGNAL(fileChanged(QString)),
-                this, SLOT(fsFileChanged(QString)));
-    }
-}
-
-void MainWindow::suspendFileSystemWatcher()
-{
-    DEBUG << "MainWindow::suspendFileSystemWatcher" << endl;
-    if (m_fsWatcher) {
-        m_fsWatcherSuspended = true;
-        if (m_fsWatcherRestoreTimer) {
-            delete m_fsWatcherRestoreTimer;
-            m_fsWatcherRestoreTimer = 0;
-        }
-        m_fsWatcherGeneralTimer->stop();
-    }
-}
-
-void MainWindow::restoreFileSystemWatcher()
-{
-    DEBUG << "MainWindow::restoreFileSystemWatcher" << endl;
-    if (m_fsWatcherRestoreTimer) delete m_fsWatcherRestoreTimer;
-        
-    // The restore timer is used to leave a polite interval between
-    // being asked to restore the watcher and actually doing so.  It's
-    // a single shot timer each time it's used, but we don't use
-    // QTimer::singleShot because we want to stop the previous one if
-    // it's running (via deleting it)
-
-    m_fsWatcherRestoreTimer = new QTimer(this);
-    connect(m_fsWatcherRestoreTimer, SIGNAL(timeout()),
-            this, SLOT(actuallyRestoreFileSystemWatcher()));
-    m_fsWatcherRestoreTimer->setInterval(1000);
-    m_fsWatcherRestoreTimer->setSingleShot(true);
-    m_fsWatcherRestoreTimer->start();
-}
-
-void MainWindow::actuallyRestoreFileSystemWatcher()
-{
-    DEBUG << "MainWindow::actuallyRestoreFileSystemWatcher" << endl;
-    if (m_fsWatcher) {
-        m_fsWatcherSuspended = false;
-        m_fsWatcherGeneralTimer->start();
-    }
-}
-
 void MainWindow::checkFilesystem()
 {
     DEBUG << "MainWindow::checkFilesystem" << endl;
     hgRefresh();
 }
 
-void MainWindow::fsDirectoryChanged(QString d)
+void MainWindow::fsWatcherChanged()
 {
-    DEBUG << "MainWindow::fsDirectoryChanged " << d << endl;
-    if (!m_fsWatcherSuspended) {
-        hgStat();
-    }
-}
-
-void MainWindow::fsFileChanged(QString f)
-{
-    DEBUG << "MainWindow::fsFileChanged " << f << endl;
-    if (!m_fsWatcherSuspended) {
-        hgStat();
-    }
+    DEBUG << "MainWindow::fsWatcherChanged" << endl;
+
 }
 
 QString MainWindow::format1(QString head)
@@ -2088,21 +1972,14 @@
 
 void MainWindow::commandStarting(HgAction action)
 {
-    // Annoyingly, hg stat actually modifies the working directory --
-    // it creates files called hg-checklink and hg-checkexec to test
-    // properties of the filesystem.  For safety's sake, suspend the
-    // fs watcher while running commands, and restore it shortly after
-    // a command has finished.
-
-    if (action.action == ACT_STAT) {
-        suspendFileSystemWatcher();
-    }
+    m_commandSequenceInProgress = true;
 }
 
 void MainWindow::commandFailed(HgAction action, QString stderr, QString stdout)
 {
     DEBUG << "MainWindow::commandFailed" << endl;
-    restoreFileSystemWatcher();
+
+    m_commandSequenceInProgress = false;
 
     QString setstr;
 #ifdef Q_OS_MAC
@@ -2183,6 +2060,7 @@
             return;
         } else if (stderr.contains("no changes found") || stdout.contains("no changes found")) {
             // success: hg 2.1 starts returning failure code for empty pull/push
+            m_commandSequenceInProgress = true; // there may be further commands
             commandCompleted(action, stdout);
             return;
         }
@@ -2199,6 +2077,7 @@
             return;
         } else if (stderr.contains("no changes found") || stdout.contains("no changes found")) {
             // success: hg 2.1 starts returning failure code for empty pull/push
+            m_commandSequenceInProgress = true; // there may be further commands
             commandCompleted(action, stdout);
             return;
         }
@@ -2209,6 +2088,7 @@
         // problem, something else will fail too).  Pretend it
         // succeeded, so that any further actions that are contingent
         // on the success of the heads query get carried out properly.
+        m_commandSequenceInProgress = true; // there may be further commands
         commandCompleted(action, "");
         return;
     case ACT_FOLDERDIFF:
@@ -2261,7 +2141,6 @@
 {
 //    std::cerr << "commandCompleted: " << completedAction.action << std::endl;
 
-    restoreFileSystemWatcher();
     HGACTIONS action = completedAction.action;
 
     if (action == ACT_NONE) return;
@@ -2320,7 +2199,6 @@
 
     case ACT_STAT:
         m_lastStatOutput = output;
-        updateFileSystemWatcher();
         break;
 
     case ACT_RESOLVE_LIST:
@@ -2624,6 +2502,7 @@
     }
 
     if (noMore) {
+        m_commandSequenceInProgress = false;
         m_stateUnknown = false;
         enableDisableActions();
         m_hgTabs->updateHistory();