comparison mainwindow.cpp @ 199:f16fe0db11f3

* Add "Show All Files" toggle to show ignored and clean files * Clear selection when Esc is pressed * Don't delete and recreate the filesystem watcher on stat, just update it
author Chris Cannam
date Mon, 03 Jan 2011 22:02:08 +0000
parents 4adbd5c9c15d
children 8c8c04bdf0fa
comparison
equal deleted inserted replaced
198:4adbd5c9c15d 199:f16fe0db11f3
28 #include <QToolBar> 28 #include <QToolBar>
29 #include <QToolButton> 29 #include <QToolButton>
30 #include <QSettings> 30 #include <QSettings>
31 #include <QInputDialog> 31 #include <QInputDialog>
32 #include <QRegExp> 32 #include <QRegExp>
33 #include <QShortcut>
33 34
34 #include "mainwindow.h" 35 #include "mainwindow.h"
35 #include "multichoicedialog.h" 36 #include "multichoicedialog.h"
36 #include "startupdialog.h" 37 #include "startupdialog.h"
37 #include "colourset.h" 38 #include "colourset.h"
47 { 48 {
48 setWindowIcon(QIcon(":images/easyhg-icon.png")); 49 setWindowIcon(QIcon(":images/easyhg-icon.png"));
49 50
50 QString wndTitle; 51 QString wndTitle;
51 52
53 showAllFiles = false;
54
52 fsWatcher = 0; 55 fsWatcher = 0;
53 commitsSincePush = 0; 56 commitsSincePush = 0;
54 shouldHgStat = true; 57 shouldHgStat = true;
55 58
56 createActions(); 59 createActions();
77 connectTabsSignals(); 80 connectTabsSignals();
78 setCentralWidget(hgTabs); 81 setCentralWidget(hgTabs);
79 82
80 connect(hgTabs, SIGNAL(selectionChanged()), 83 connect(hgTabs, SIGNAL(selectionChanged()),
81 this, SLOT(enableDisableActions())); 84 this, SLOT(enableDisableActions()));
85 connect(hgTabs, SIGNAL(showAllChanged(bool)),
86 this, SLOT(showAllChanged(bool)));
82 87
83 setUnifiedTitleAndToolBarOnMac(true); 88 setUnifiedTitleAndToolBarOnMac(true);
84 connectActions(); 89 connectActions();
85 clearState(); 90 clearState();
86 enableDisableActions(); 91 enableDisableActions();
168 void MainWindow::clearSelections() 173 void MainWindow::clearSelections()
169 { 174 {
170 hgTabs->clearSelections(); 175 hgTabs->clearSelections();
171 } 176 }
172 177
178 void MainWindow::showAllChanged(bool s)
179 {
180 showAllFiles = s;
181 hgQueryPaths();
182 }
183
173 void MainWindow::hgRefresh() 184 void MainWindow::hgRefresh()
174 { 185 {
175 clearState(); 186 clearState();
176 hgQueryPaths(); 187 hgQueryPaths();
177 } 188 }
184 } 195 }
185 196
186 void MainWindow::hgStat() 197 void MainWindow::hgStat()
187 { 198 {
188 QStringList params; 199 QStringList params;
189 params << "stat" << "-ardum"; 200
201 if (showAllFiles) {
202 params << "stat" << "-A";
203 } else {
204 params << "stat" << "-ardum";
205 }
190 206
191 lastStatOutput = ""; 207 lastStatOutput = "";
192 208
193 // annoyingly, hg stat actually modifies the working directory -- 209 // annoyingly, hg stat actually modifies the working directory --
194 // it creates files called hg-checklink and hg-checkexec to test 210 // it creates files called hg-checklink and hg-checkexec to test
865 lastRevertedFiles.clear(); 881 lastRevertedFiles.clear();
866 mergeTargetRevision = ""; 882 mergeTargetRevision = "";
867 mergeCommitComment = ""; 883 mergeCommitComment = "";
868 stateUnknown = true; 884 stateUnknown = true;
869 needNewLog = true; 885 needNewLog = true;
886 if (fsWatcher) {
887 delete fsWatcher;
888 fsWatcher = 0;
889 }
870 } 890 }
871 891
872 void MainWindow::hgServe() 892 void MainWindow::hgServe()
873 { 893 {
874 QStringList params; 894 QStringList params;
1281 } 1301 }
1282 } 1302 }
1283 1303
1284 void MainWindow::updateFileSystemWatcher() 1304 void MainWindow::updateFileSystemWatcher()
1285 { 1305 {
1286 delete fsWatcher; 1306 bool justCreated = false;
1287 fsWatcher = new QFileSystemWatcher(); 1307 if (!fsWatcher) {
1308 fsWatcher = new QFileSystemWatcher();
1309 justCreated = true;
1310 }
1311
1312 // QFileSystemWatcher will refuse to add a file or directory to
1313 // its watch list that it is already watching -- fine, that's what
1314 // we want -- but it prints a warning when this happens, which is
1315 // annoying because it would be the normal case for us. So we'll
1316 // check for duplicates ourselves.
1317 QSet<QString> alreadyWatched;
1318 QStringList dl(fsWatcher->directories());
1319 foreach (QString d, dl) alreadyWatched.insert(d);
1320
1288 std::deque<QString> pending; 1321 std::deque<QString> pending;
1289 pending.push_back(workFolderPath); 1322 pending.push_back(workFolderPath);
1323
1290 while (!pending.empty()) { 1324 while (!pending.empty()) {
1325
1291 QString path = pending.front(); 1326 QString path = pending.front();
1292 pending.pop_front(); 1327 pending.pop_front();
1293 fsWatcher->addPath(path); 1328 if (!alreadyWatched.contains(path)) {
1294 DEBUG << "Added to file system watcher: " << path << endl; 1329 fsWatcher->addPath(path);
1330 DEBUG << "Added to file system watcher: " << path << endl;
1331 }
1332
1295 QDir d(path); 1333 QDir d(path);
1296 if (d.exists()) { 1334 if (d.exists()) {
1297 d.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable); 1335 d.setFilter(QDir::Dirs | QDir::NoDotAndDotDot |
1336 QDir::Readable | QDir::NoSymLinks);
1298 foreach (QString entry, d.entryList()) { 1337 foreach (QString entry, d.entryList()) {
1299 if (entry == ".hg") continue; 1338 if (entry.startsWith('.')) continue;
1300 QString entryPath = d.absoluteFilePath(entry); 1339 QString entryPath = d.absoluteFilePath(entry);
1301 pending.push_back(entryPath); 1340 pending.push_back(entryPath);
1302 } 1341 }
1303 } 1342 }
1304 } 1343 }
1305 connect(fsWatcher, SIGNAL(directoryChanged(QString)), 1344
1306 this, SLOT(fsDirectoryChanged(QString))); 1345 if (justCreated) {
1307 connect(fsWatcher, SIGNAL(fileChanged(QString)), 1346 connect(fsWatcher, SIGNAL(directoryChanged(QString)),
1308 this, SLOT(fsFileChanged(QString))); 1347 this, SLOT(fsDirectoryChanged(QString)));
1348 connect(fsWatcher, SIGNAL(fileChanged(QString)),
1349 this, SLOT(fsFileChanged(QString)));
1350 }
1309 } 1351 }
1310 1352
1311 void MainWindow::fsDirectoryChanged(QString d) 1353 void MainWindow::fsDirectoryChanged(QString d)
1312 { 1354 {
1313 DEBUG << "MainWindow::fsDirectoryChanged " << d << endl; 1355 DEBUG << "MainWindow::fsDirectoryChanged " << d << endl;
1432 } 1474 }
1433 1475
1434 void MainWindow::commandFailed(HgAction action, QString output) 1476 void MainWindow::commandFailed(HgAction action, QString output)
1435 { 1477 {
1436 DEBUG << "MainWindow::commandFailed" << endl; 1478 DEBUG << "MainWindow::commandFailed" << endl;
1437 if (fsWatcher) fsWatcher->blockSignals(false);
1438 1479
1439 // Some commands we just have to ignore bad return values from: 1480 // Some commands we just have to ignore bad return values from:
1440 1481
1441 switch(action.action) { 1482 switch(action.action) {
1442 case ACT_NONE: 1483 case ACT_NONE:
1471 case ACT_PUSH: 1512 case ACT_PUSH:
1472 if (output.contains("creates new remote heads")) { 1513 if (output.contains("creates new remote heads")) {
1473 reportNewRemoteHeads(output); 1514 reportNewRemoteHeads(output);
1474 return; 1515 return;
1475 } 1516 }
1517 case ACT_STAT:
1518 if (fsWatcher) fsWatcher->blockSignals(false);
1519 break; // go on and report
1476 default: 1520 default:
1477 break; 1521 break;
1478 } 1522 }
1479 1523
1480 QString command = action.executable; 1524 QString command = action.executable;
1498 } 1542 }
1499 1543
1500 void MainWindow::commandCompleted(HgAction completedAction, QString output) 1544 void MainWindow::commandCompleted(HgAction completedAction, QString output)
1501 { 1545 {
1502 HGACTIONS action = completedAction.action; 1546 HGACTIONS action = completedAction.action;
1503 if (fsWatcher) fsWatcher->blockSignals(false);
1504 1547
1505 if (action == ACT_NONE) return; 1548 if (action == ACT_NONE) return;
1506 1549
1507 bool headsChanged = false; 1550 bool headsChanged = false;
1508 QStringList oldHeadIds; 1551 QStringList oldHeadIds;
1533 break; 1576 break;
1534 1577
1535 case ACT_STAT: 1578 case ACT_STAT:
1536 lastStatOutput = output; 1579 lastStatOutput = output;
1537 updateFileSystemWatcher(); 1580 updateFileSystemWatcher();
1581 if (fsWatcher) fsWatcher->blockSignals(false);
1538 break; 1582 break;
1539 1583
1540 case ACT_RESOLVE_LIST: 1584 case ACT_RESOLVE_LIST:
1541 if (output != "") { 1585 if (output != "") {
1542 // Remove lines beginning with R (they are resolved, 1586 // Remove lines beginning with R (they are resolved,
1547 if (!line.startsWith("R ")) winnowed.push_back(line); 1591 if (!line.startsWith("R ")) winnowed.push_back(line);
1548 } 1592 }
1549 output = winnowed.join("\n"); 1593 output = winnowed.join("\n");
1550 } 1594 }
1551 DEBUG << "lastStatOutput = " << lastStatOutput << endl; 1595 DEBUG << "lastStatOutput = " << lastStatOutput << endl;
1552 DEBUG << "output = " << output << endl; 1596 DEBUG << "resolve output = " << output << endl;
1553 hgTabs->updateWorkFolderFileList(lastStatOutput + output); 1597 hgTabs->updateWorkFolderFileList(lastStatOutput + output);
1554 break; 1598 break;
1555 1599
1556 case ACT_RESOLVE_MARK: 1600 case ACT_RESOLVE_MARK:
1557 shouldHgStat = true; 1601 shouldHgStat = true;
1782 connect(hgPullAct, SIGNAL(triggered()), this, SLOT(hgPull())); 1826 connect(hgPullAct, SIGNAL(triggered()), this, SLOT(hgPull()));
1783 connect(hgPushAct, SIGNAL(triggered()), this, SLOT(hgPush())); 1827 connect(hgPushAct, SIGNAL(triggered()), this, SLOT(hgPush()));
1784 1828
1785 connect(hgAnnotateAct, SIGNAL(triggered()), this, SLOT(hgAnnotate())); 1829 connect(hgAnnotateAct, SIGNAL(triggered()), this, SLOT(hgAnnotate()));
1786 connect(hgServeAct, SIGNAL(triggered()), this, SLOT(hgServe())); 1830 connect(hgServeAct, SIGNAL(triggered()), this, SLOT(hgServe()));
1787 connect(clearSelectionsAct, SIGNAL(triggered()), this, SLOT(clearSelections()));
1788 } 1831 }
1789 1832
1790 void MainWindow::connectTabsSignals() 1833 void MainWindow::connectTabsSignals()
1791 { 1834 {
1792 connect(hgTabs, SIGNAL(commit()), 1835 connect(hgTabs, SIGNAL(commit()),
1971 2014
1972 void MainWindow::createActions() 2015 void MainWindow::createActions()
1973 { 2016 {
1974 //File actions 2017 //File actions
1975 openAct = new QAction(QIcon(":/images/fileopen.png"), tr("Open..."), this); 2018 openAct = new QAction(QIcon(":/images/fileopen.png"), tr("Open..."), this);
1976 openAct -> setStatusTip(tr("Open a repository")); 2019 openAct -> setStatusTip(tr("Open an existing repository or working folder"));
1977 2020
1978 changeRemoteRepoAct = new QAction(tr("Change Remote Location..."), this); 2021 changeRemoteRepoAct = new QAction(tr("Change Remote Location..."), this);
1979 changeRemoteRepoAct->setStatusTip(tr("Change the default remote repository for pull and push actions")); 2022 changeRemoteRepoAct->setStatusTip(tr("Change the default remote repository for pull and push actions"));
1980 2023
1981 settingsAct = new QAction(QIcon(":/images/settings.png"), tr("Settings..."), this); 2024 settingsAct = new QAction(QIcon(":/images/settings.png"), tr("Settings..."), this);
2035 2078
2036 //Help actions 2079 //Help actions
2037 aboutAct = new QAction(tr("About EasyMercurial"), this); 2080 aboutAct = new QAction(tr("About EasyMercurial"), this);
2038 2081
2039 // Miscellaneous 2082 // Miscellaneous
2040 clearSelectionsAct = new QAction(tr("Clear selections"), this); 2083 QShortcut *clearSelectionsShortcut = new QShortcut(Qt::Key_Escape, this);
2041 clearSelectionsAct->setShortcut(Qt::Key_Escape); 2084 connect(clearSelectionsShortcut, SIGNAL(activated()),
2085 this, SLOT(clearSelections()));
2042 } 2086 }
2043 2087
2044 void MainWindow::createMenus() 2088 void MainWindow::createMenus()
2045 { 2089 {
2046 fileMenu = menuBar()->addMenu(tr("File")); 2090 fileMenu = menuBar()->addMenu(tr("File"));
2055 2099
2056 fileMenu -> addSeparator(); 2100 fileMenu -> addSeparator();
2057 fileMenu -> addAction(exitAct); 2101 fileMenu -> addAction(exitAct);
2058 2102
2059 advancedMenu -> addAction(hgIgnoreAct); 2103 advancedMenu -> addAction(hgIgnoreAct);
2104 advancedMenu -> addSeparator();
2060 advancedMenu -> addAction(hgServeAct); 2105 advancedMenu -> addAction(hgServeAct);
2061 2106
2062 helpMenu = menuBar()->addMenu(tr("Help")); 2107 helpMenu = menuBar()->addMenu(tr("Help"));
2063 helpMenu->addAction(aboutAct); 2108 helpMenu->addAction(aboutAct);
2064 } 2109 }