comparison 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
comparison
equal deleted inserted replaced
237:c9a7e4ec2f78 238:e2f2c6e3c01b
30 #include <QSettings> 30 #include <QSettings>
31 #include <QInputDialog> 31 #include <QInputDialog>
32 #include <QRegExp> 32 #include <QRegExp>
33 #include <QShortcut> 33 #include <QShortcut>
34 #include <QUrl> 34 #include <QUrl>
35 #include <QTimer>
35 36
36 #include "mainwindow.h" 37 #include "mainwindow.h"
37 #include "multichoicedialog.h" 38 #include "multichoicedialog.h"
38 #include "startupdialog.h" 39 #include "startupdialog.h"
39 #include "colourset.h" 40 #include "colourset.h"
44 #include "settingsdialog.h" 45 #include "settingsdialog.h"
45 #include "version.h" 46 #include "version.h"
46 47
47 48
48 MainWindow::MainWindow(QString myDirPath) : 49 MainWindow::MainWindow(QString myDirPath) :
49 m_myDirPath(myDirPath) 50 m_myDirPath(myDirPath),
51 m_fsWatcherGeneralTimer(0),
52 m_fsWatcherRestoreTimer(0)
50 { 53 {
51 setWindowIcon(QIcon(":images/easyhg-icon.png")); 54 setWindowIcon(QIcon(":images/easyhg-icon.png"));
52 55
53 QString wndTitle; 56 QString wndTitle;
54 57
236 params << "stat" << "-ardum"; 239 params << "stat" << "-ardum";
237 } 240 }
238 241
239 lastStatOutput = ""; 242 lastStatOutput = "";
240 243
241 // annoyingly, hg stat actually modifies the working directory --
242 // it creates files called hg-checklink and hg-checkexec to test
243 // properties of the filesystem
244 if (fsWatcher) fsWatcher->blockSignals(true);
245
246 runner->requestAction(HgAction(ACT_STAT, workFolderPath, params)); 244 runner->requestAction(HgAction(ACT_STAT, workFolderPath, params));
247 } 245 }
248 246
249 void MainWindow::hgQueryPaths() 247 void MainWindow::hgQueryPaths()
250 { 248 {
1478 pending.push_back(entryPath); 1476 pending.push_back(entryPath);
1479 } 1477 }
1480 } 1478 }
1481 } 1479 }
1482 1480
1481 // The general timer isn't really related to the fs watcher
1482 // object, it just does something similar -- every now and then we
1483 // do a refresh just to update the history dates etc
1484
1485 m_fsWatcherGeneralTimer = new QTimer(this);
1486 connect(m_fsWatcherGeneralTimer, SIGNAL(timeout()),
1487 this, SLOT(checkFilesystem()));
1488 m_fsWatcherGeneralTimer->setInterval(30 * 60 * 1000); // half an hour
1489 m_fsWatcherGeneralTimer->start();
1490
1483 if (justCreated) { 1491 if (justCreated) {
1484 connect(fsWatcher, SIGNAL(directoryChanged(QString)), 1492 connect(fsWatcher, SIGNAL(directoryChanged(QString)),
1485 this, SLOT(fsDirectoryChanged(QString))); 1493 this, SLOT(fsDirectoryChanged(QString)));
1486 connect(fsWatcher, SIGNAL(fileChanged(QString)), 1494 connect(fsWatcher, SIGNAL(fileChanged(QString)),
1487 this, SLOT(fsFileChanged(QString))); 1495 this, SLOT(fsFileChanged(QString)));
1488 } 1496 }
1497 }
1498
1499 void MainWindow::suspendFileSystemWatcher()
1500 {
1501 DEBUG << "MainWindow::suspendFileSystemWatcher" << endl;
1502 if (fsWatcher) {
1503 m_fsWatcherRestoreTimer->stop();
1504 m_fsWatcherGeneralTimer->stop();
1505 fsWatcher->blockSignals(true);
1506 }
1507 }
1508
1509 void MainWindow::restoreFileSystemWatcher()
1510 {
1511 DEBUG << "MainWindow::restoreFileSystemWatcher" << endl;
1512 if (m_fsWatcherRestoreTimer) delete m_fsWatcherRestoreTimer;
1513
1514 // The restore timer is used to leave a polite interval between
1515 // being asked to restore the watcher and actually doing so. It's
1516 // a single shot timer each time it's used, but we don't use
1517 // QTimer::singleShot because we want to stop the previous one if
1518 // it's running (via deleting it)
1519
1520 m_fsWatcherRestoreTimer = new QTimer(this);
1521 connect(m_fsWatcherRestoreTimer, SIGNAL(timeout()),
1522 this, SLOT(actuallyRestoreFileSystemWatcher()));
1523 m_fsWatcherRestoreTimer->setInterval(1000);
1524 m_fsWatcherRestoreTimer->setSingleShot(true);
1525 m_fsWatcherRestoreTimer->start();
1526 }
1527
1528 void MainWindow::actuallyRestoreFileSystemWatcher()
1529 {
1530 DEBUG << "MainWindow::actuallyRestoreFileSystemWatcher" << endl;
1531 if (fsWatcher) fsWatcher->blockSignals(false);
1532 }
1533
1534 void MainWindow::checkFilesystem()
1535 {
1536 DEBUG << "MainWindow::checkFilesystem" << endl;
1537 hgStat();
1489 } 1538 }
1490 1539
1491 void MainWindow::fsDirectoryChanged(QString d) 1540 void MainWindow::fsDirectoryChanged(QString d)
1492 { 1541 {
1493 DEBUG << "MainWindow::fsDirectoryChanged " << d << endl; 1542 DEBUG << "MainWindow::fsDirectoryChanged " << d << endl;
1609 tr("Your local repository could not be pushed to the remote repository.<br><br>The remote repository may have been changed by someone else since you last pushed. Try pulling and merging their changes into your local repository first.<br><br>The output of the push command was:"), 1658 tr("Your local repository could not be pushed to the remote repository.<br><br>The remote repository may have been changed by someone else since you last pushed. Try pulling and merging their changes into your local repository first.<br><br>The output of the push command was:"),
1610 output)); 1659 output));
1611 } 1660 }
1612 } 1661 }
1613 1662
1663 void MainWindow::commandStarting(HgAction action)
1664 {
1665 // Annoyingly, hg stat actually modifies the working directory --
1666 // it creates files called hg-checklink and hg-checkexec to test
1667 // properties of the filesystem. For safety's sake, suspend the
1668 // fs watcher while running commands, and restore it shortly after
1669 // a command has finished.
1670
1671 suspendFileSystemWatcher();
1672 }
1673
1614 void MainWindow::commandFailed(HgAction action, QString output) 1674 void MainWindow::commandFailed(HgAction action, QString output)
1615 { 1675 {
1616 DEBUG << "MainWindow::commandFailed" << endl; 1676 DEBUG << "MainWindow::commandFailed" << endl;
1677 restoreFileSystemWatcher();
1617 1678
1618 QString setstr; 1679 QString setstr;
1619 #ifdef Q_OS_MAC 1680 #ifdef Q_OS_MAC
1620 setstr = tr("Preferences"); 1681 setstr = tr("Preferences");
1621 #else 1682 #else
1669 if (output.contains("creates new remote heads")) { 1730 if (output.contains("creates new remote heads")) {
1670 reportNewRemoteHeads(output); 1731 reportNewRemoteHeads(output);
1671 return; 1732 return;
1672 } 1733 }
1673 case ACT_STAT: 1734 case ACT_STAT:
1674 if (fsWatcher) fsWatcher->blockSignals(false);
1675 break; // go on and report 1735 break; // go on and report
1676 default: 1736 default:
1677 break; 1737 break;
1678 } 1738 }
1679 1739
1697 QMessageBox::warning(this, tr("Command failed"), message); 1757 QMessageBox::warning(this, tr("Command failed"), message);
1698 } 1758 }
1699 1759
1700 void MainWindow::commandCompleted(HgAction completedAction, QString output) 1760 void MainWindow::commandCompleted(HgAction completedAction, QString output)
1701 { 1761 {
1762 restoreFileSystemWatcher();
1702 HGACTIONS action = completedAction.action; 1763 HGACTIONS action = completedAction.action;
1703 1764
1704 if (action == ACT_NONE) return; 1765 if (action == ACT_NONE) return;
1705 1766
1706 bool headsChanged = false; 1767 bool headsChanged = false;
1737 break; 1798 break;
1738 1799
1739 case ACT_STAT: 1800 case ACT_STAT:
1740 lastStatOutput = output; 1801 lastStatOutput = output;
1741 updateFileSystemWatcher(); 1802 updateFileSystemWatcher();
1742 if (fsWatcher) fsWatcher->blockSignals(false);
1743 break; 1803 break;
1744 1804
1745 case ACT_RESOLVE_LIST: 1805 case ACT_RESOLVE_LIST:
1746 if (output != "") { 1806 if (output != "") {
1747 // Remove lines beginning with R (they are resolved, 1807 // Remove lines beginning with R (they are resolved,