diff mainwindow.cpp @ 238:e2f2c6e3c01b

* Attempt a different way of handling filesystem updates, that's more forgiving of fs changes caused by hg itself
author Chris Cannam
date Mon, 10 Jan 2011 13:30:19 +0000
parents c9a7e4ec2f78
children 661f5808aa0a
line wrap: on
line diff
--- a/mainwindow.cpp	Mon Jan 10 12:44:03 2011 +0000
+++ b/mainwindow.cpp	Mon Jan 10 13:30:19 2011 +0000
@@ -32,6 +32,7 @@
 #include <QRegExp>
 #include <QShortcut>
 #include <QUrl>
+#include <QTimer>
 
 #include "mainwindow.h"
 #include "multichoicedialog.h"
@@ -46,7 +47,9 @@
 
 
 MainWindow::MainWindow(QString myDirPath) :
-    m_myDirPath(myDirPath)
+    m_myDirPath(myDirPath),
+    m_fsWatcherGeneralTimer(0),
+    m_fsWatcherRestoreTimer(0)
 {
     setWindowIcon(QIcon(":images/easyhg-icon.png"));
 
@@ -238,11 +241,6 @@
 
     lastStatOutput = "";
 
-    // annoyingly, hg stat actually modifies the working directory --
-    // it creates files called hg-checklink and hg-checkexec to test
-    // properties of the filesystem
-    if (fsWatcher) fsWatcher->blockSignals(true);
-
     runner->requestAction(HgAction(ACT_STAT, workFolderPath, params));
 }
 
@@ -1480,6 +1478,16 @@
         }
     }
 
+    // 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(fsWatcher, SIGNAL(directoryChanged(QString)),
                 this, SLOT(fsDirectoryChanged(QString)));
@@ -1488,6 +1496,47 @@
     }
 }
 
+void MainWindow::suspendFileSystemWatcher()
+{
+    DEBUG << "MainWindow::suspendFileSystemWatcher" << endl;
+    if (fsWatcher) {
+        m_fsWatcherRestoreTimer->stop();
+        m_fsWatcherGeneralTimer->stop();
+        fsWatcher->blockSignals(true);
+    }
+}
+
+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 (fsWatcher) fsWatcher->blockSignals(false);
+}
+
+void MainWindow::checkFilesystem()
+{
+    DEBUG << "MainWindow::checkFilesystem" << endl;
+    hgStat();
+}
+
 void MainWindow::fsDirectoryChanged(QString d)
 {
     DEBUG << "MainWindow::fsDirectoryChanged " << d << endl;
@@ -1611,9 +1660,21 @@
     }
 }
 
+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.
+
+    suspendFileSystemWatcher();
+}
+
 void MainWindow::commandFailed(HgAction action, QString output)
 {
     DEBUG << "MainWindow::commandFailed" << endl;
+    restoreFileSystemWatcher();
 
     QString setstr;
 #ifdef Q_OS_MAC
@@ -1671,7 +1732,6 @@
             return;
         }
     case ACT_STAT:
-        if (fsWatcher) fsWatcher->blockSignals(false);
         break; // go on and report
     default:
         break;
@@ -1699,6 +1759,7 @@
 
 void MainWindow::commandCompleted(HgAction completedAction, QString output)
 {
+    restoreFileSystemWatcher();
     HGACTIONS action = completedAction.action;
 
     if (action == ACT_NONE) return;
@@ -1739,7 +1800,6 @@
     case ACT_STAT:
         lastStatOutput = output;
         updateFileSystemWatcher();
-        if (fsWatcher) fsWatcher->blockSignals(false);
         break;
 
     case ACT_RESOLVE_LIST: