Mercurial > hg > easyhg
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 } |