# HG changeset patch # User Chris Cannam # Date 1294092128 0 # Node ID f16fe0db11f35d6abaf62a4e52e158e4536c20ca # Parent 4adbd5c9c15d52143a4dc3d095353326a3366cee * 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 diff -r 4adbd5c9c15d -r f16fe0db11f3 filestates.cpp --- a/filestates.cpp Mon Jan 03 14:31:22 2011 +0000 +++ b/filestates.cpp Mon Jan 03 22:02:08 2011 +0000 @@ -27,12 +27,14 @@ void FileStates::clearBuckets() { + m_clean.clear(); m_modified.clear(); m_added.clear(); m_removed.clear(); m_missing.clear(); m_inConflict.clear(); m_unknown.clear(); + m_ignored.clear(); } FileStates::State FileStates::charToState(QChar c, bool *ok) @@ -53,6 +55,7 @@ if (c == 'U') return InConflict; if (c == '?') return Unknown; if (c == 'C') return Clean; + if (c == 'I') return Ignored; if (ok) *ok = false; return Unknown; } @@ -60,13 +63,14 @@ QStringList *FileStates::stateToBucket(State s) { switch (s) { - case Clean: default: return 0; // not implemented yet + case Clean: return &m_clean; // not implemented yet case Modified: return &m_modified; case Added: return &m_added; case Unknown: return &m_unknown; case Removed: return &m_removed; case Missing: return &m_missing; case InConflict: return &m_inConflict; + case Ignored: return &m_ignored; } } @@ -95,12 +99,12 @@ } foreach (QString file, m_stateMap.keys()) { - QStringList *bucket = stateToBucket(m_stateMap[file]); - bucket->push_back(file); + if (bucket) bucket->push_back(file); } - DEBUG << "FileStates: " << m_modified.size() << " modified, " << m_added.size() + DEBUG << "FileStates: " + << m_modified.size() << " modified, " << m_added.size() << " added, " << m_removed.size() << " removed, " << m_missing.size() << " missing, " << m_inConflict.size() << " in conflict, " << m_unknown.size() << " unknown" << endl; diff -r 4adbd5c9c15d -r f16fe0db11f3 filestates.h --- a/filestates.h Mon Jan 03 14:31:22 2011 +0000 +++ b/filestates.h Mon Jan 03 22:02:08 2011 +0000 @@ -39,9 +39,10 @@ Missing, Clean, Unknown, + Ignored, FirstState = Modified, - LastState = Unknown + LastState = Ignored }; void parseStates(QString text); @@ -56,6 +57,8 @@ QStringList removed() const { return m_removed; } QStringList missing() const { return m_missing; } QStringList inConflict() const { return m_inConflict; } + QStringList clean() const { return m_clean; } + QStringList ignored() const { return m_ignored; } State getStateOfFile(QString file) const; @@ -66,6 +69,8 @@ QStringList m_removed; QStringList m_missing; QStringList m_inConflict; + QStringList m_clean; + QStringList m_ignored; QMap m_stateMap; State charToState(QChar, bool * = 0); diff -r 4adbd5c9c15d -r f16fe0db11f3 filestatuswidget.cpp --- a/filestatuswidget.cpp Mon Jan 03 14:31:22 2011 +0000 +++ b/filestatuswidget.cpp Mon Jan 03 22:02:08 2011 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include FileStatusWidget::FileStatusWidget(QWidget *parent) : QWidget(parent), @@ -79,6 +80,7 @@ m_simpleLabels[FileStates::Missing] = tr("Missing:"); m_simpleLabels[FileStates::InConflict] = tr("In Conflict:"); m_simpleLabels[FileStates::Unknown] = tr("Untracked:"); + m_simpleLabels[FileStates::Ignored] = tr("Ignored:"); m_descriptions[FileStates::Clean] = tr("You have not changed these files."); m_descriptions[FileStates::Modified] = tr("You have changed these files since you last committed them."); @@ -92,6 +94,8 @@ m_descriptions[FileStates::Unknown] = tr("These files are in your working folder but are not under version control.
" // "Select a file and use Add to place it under version control or Ignore to remove it from this list."); "Select a file and use Add to place it under version control."); + m_descriptions[FileStates::Ignored] = tr("These files have names that match entries in the working folder's .hgignore file,
" + "and so will be ignored by the version control system."); m_highlightExplanation = tr("Files highlighted in red " "have appeared since your most recent commit or update."); @@ -124,6 +128,12 @@ layout->setRowStretch(++row, 20); + layout->addItem(new QSpacerItem(1, 1), ++row, 0); + + m_showAllFiles = new QCheckBox(tr("Show all files"), this); + layout->addWidget(m_showAllFiles, ++row, 0, 1, 3, Qt::AlignLeft); + connect(m_showAllFiles, SIGNAL(toggled(bool)), + this, SIGNAL(showAllChanged(bool))); } FileStatusWidget::~FileStatusWidget() diff -r 4adbd5c9c15d -r f16fe0db11f3 filestatuswidget.h --- a/filestatuswidget.h Mon Jan 03 14:31:22 2011 +0000 +++ b/filestatuswidget.h Mon Jan 03 22:02:08 2011 +0000 @@ -27,6 +27,7 @@ class QPushButton; class QFileInfo; class ClickableLabel; +class QCheckBox; class FileStatusWidget : public QWidget { @@ -70,6 +71,7 @@ signals: void selectionChanged(); + void showAllChanged(bool); public slots: void clearSelections(); @@ -90,6 +92,8 @@ QLabel *m_noModificationsLabel; + QCheckBox *m_showAllFiles; + FileStates m_fileStates; QMap m_simpleLabels; QMap m_descriptions; diff -r 4adbd5c9c15d -r f16fe0db11f3 hgtabwidget.cpp --- a/hgtabwidget.cpp Mon Jan 03 14:31:22 2011 +0000 +++ b/hgtabwidget.cpp Mon Jan 03 22:02:08 2011 +0000 @@ -37,6 +37,8 @@ m_fileStatusWidget->setRemoteURL(remoteRepo); connect(m_fileStatusWidget, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); + connect(m_fileStatusWidget, SIGNAL(showAllChanged(bool)), + this, SIGNAL(showAllChanged(bool))); addTab(m_fileStatusWidget, tr("My work")); // History graph page diff -r 4adbd5c9c15d -r f16fe0db11f3 hgtabwidget.h --- a/hgtabwidget.h Mon Jan 03 14:31:22 2011 +0000 +++ b/hgtabwidget.h Mon Jan 03 22:02:08 2011 +0000 @@ -81,6 +81,7 @@ signals: void selectionChanged(); + void showAllChanged(bool); void commit(); void revert(); diff -r 4adbd5c9c15d -r f16fe0db11f3 mainwindow.cpp --- a/mainwindow.cpp Mon Jan 03 14:31:22 2011 +0000 +++ b/mainwindow.cpp Mon Jan 03 22:02:08 2011 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include "mainwindow.h" #include "multichoicedialog.h" @@ -49,6 +50,8 @@ QString wndTitle; + showAllFiles = false; + fsWatcher = 0; commitsSincePush = 0; shouldHgStat = true; @@ -79,6 +82,8 @@ connect(hgTabs, SIGNAL(selectionChanged()), this, SLOT(enableDisableActions())); + connect(hgTabs, SIGNAL(showAllChanged(bool)), + this, SLOT(showAllChanged(bool))); setUnifiedTitleAndToolBarOnMac(true); connectActions(); @@ -170,6 +175,12 @@ hgTabs->clearSelections(); } +void MainWindow::showAllChanged(bool s) +{ + showAllFiles = s; + hgQueryPaths(); +} + void MainWindow::hgRefresh() { clearState(); @@ -186,7 +197,12 @@ void MainWindow::hgStat() { QStringList params; - params << "stat" << "-ardum"; + + if (showAllFiles) { + params << "stat" << "-A"; + } else { + params << "stat" << "-ardum"; + } lastStatOutput = ""; @@ -867,6 +883,10 @@ mergeCommitComment = ""; stateUnknown = true; needNewLog = true; + if (fsWatcher) { + delete fsWatcher; + fsWatcher = 0; + } } void MainWindow::hgServe() @@ -1283,29 +1303,51 @@ void MainWindow::updateFileSystemWatcher() { - delete fsWatcher; - fsWatcher = new QFileSystemWatcher(); + bool justCreated = false; + if (!fsWatcher) { + 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 alreadyWatched; + QStringList dl(fsWatcher->directories()); + foreach (QString d, dl) alreadyWatched.insert(d); + std::deque pending; pending.push_back(workFolderPath); + while (!pending.empty()) { + QString path = pending.front(); pending.pop_front(); - fsWatcher->addPath(path); - DEBUG << "Added to file system watcher: " << path << endl; + if (!alreadyWatched.contains(path)) { + 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); + d.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | + QDir::Readable | QDir::NoSymLinks); foreach (QString entry, d.entryList()) { - if (entry == ".hg") continue; + if (entry.startsWith('.')) continue; QString entryPath = d.absoluteFilePath(entry); pending.push_back(entryPath); } } } - connect(fsWatcher, SIGNAL(directoryChanged(QString)), - this, SLOT(fsDirectoryChanged(QString))); - connect(fsWatcher, SIGNAL(fileChanged(QString)), - this, SLOT(fsFileChanged(QString))); + + if (justCreated) { + connect(fsWatcher, SIGNAL(directoryChanged(QString)), + this, SLOT(fsDirectoryChanged(QString))); + connect(fsWatcher, SIGNAL(fileChanged(QString)), + this, SLOT(fsFileChanged(QString))); + } } void MainWindow::fsDirectoryChanged(QString d) @@ -1434,7 +1476,6 @@ void MainWindow::commandFailed(HgAction action, QString output) { DEBUG << "MainWindow::commandFailed" << endl; - if (fsWatcher) fsWatcher->blockSignals(false); // Some commands we just have to ignore bad return values from: @@ -1473,6 +1514,9 @@ reportNewRemoteHeads(output); return; } + case ACT_STAT: + if (fsWatcher) fsWatcher->blockSignals(false); + break; // go on and report default: break; } @@ -1500,7 +1544,6 @@ void MainWindow::commandCompleted(HgAction completedAction, QString output) { HGACTIONS action = completedAction.action; - if (fsWatcher) fsWatcher->blockSignals(false); if (action == ACT_NONE) return; @@ -1535,6 +1578,7 @@ case ACT_STAT: lastStatOutput = output; updateFileSystemWatcher(); + if (fsWatcher) fsWatcher->blockSignals(false); break; case ACT_RESOLVE_LIST: @@ -1549,7 +1593,7 @@ output = winnowed.join("\n"); } DEBUG << "lastStatOutput = " << lastStatOutput << endl; - DEBUG << "output = " << output << endl; + DEBUG << "resolve output = " << output << endl; hgTabs->updateWorkFolderFileList(lastStatOutput + output); break; @@ -1784,7 +1828,6 @@ connect(hgAnnotateAct, SIGNAL(triggered()), this, SLOT(hgAnnotate())); connect(hgServeAct, SIGNAL(triggered()), this, SLOT(hgServe())); - connect(clearSelectionsAct, SIGNAL(triggered()), this, SLOT(clearSelections())); } void MainWindow::connectTabsSignals() @@ -1973,7 +2016,7 @@ { //File actions openAct = new QAction(QIcon(":/images/fileopen.png"), tr("Open..."), this); - openAct -> setStatusTip(tr("Open a repository")); + openAct -> setStatusTip(tr("Open an existing repository or working folder")); changeRemoteRepoAct = new QAction(tr("Change Remote Location..."), this); changeRemoteRepoAct->setStatusTip(tr("Change the default remote repository for pull and push actions")); @@ -2037,8 +2080,9 @@ aboutAct = new QAction(tr("About EasyMercurial"), this); // Miscellaneous - clearSelectionsAct = new QAction(tr("Clear selections"), this); - clearSelectionsAct->setShortcut(Qt::Key_Escape); + QShortcut *clearSelectionsShortcut = new QShortcut(Qt::Key_Escape, this); + connect(clearSelectionsShortcut, SIGNAL(activated()), + this, SLOT(clearSelections())); } void MainWindow::createMenus() @@ -2057,6 +2101,7 @@ fileMenu -> addAction(exitAct); advancedMenu -> addAction(hgIgnoreAct); + advancedMenu -> addSeparator(); advancedMenu -> addAction(hgServeAct); helpMenu = menuBar()->addMenu(tr("Help")); diff -r 4adbd5c9c15d -r f16fe0db11f3 mainwindow.h --- a/mainwindow.h Mon Jan 03 14:31:22 2011 +0000 +++ b/mainwindow.h Mon Jan 03 22:02:08 2011 +0000 @@ -71,6 +71,7 @@ void changeRemoteRepo(); void startupDialog(); void clearSelections(); + void showAllChanged(bool); void hgTest(); void hgQueryPaths(); @@ -154,6 +155,8 @@ bool firstStart; + bool showAllFiles; + //Actions enabled flags bool remoteRepoActionsEnabled; bool localRepoActionsEnabled; @@ -192,9 +195,6 @@ //Help menu actions QAction *aboutAct; - // Other actions - QAction *clearSelectionsAct; - QToolBar *fileToolBar; QToolBar *repoToolBar; QToolBar *workFolderToolBar; diff -r 4adbd5c9c15d -r f16fe0db11f3 multichoicedialog.cpp --- a/multichoicedialog.cpp Mon Jan 03 14:31:22 2011 +0000 +++ b/multichoicedialog.cpp Mon Jan 03 22:02:08 2011 +0000 @@ -84,7 +84,7 @@ outer->addWidget(bbox, 5, 0, 1, 3); m_okButton = bbox->button(QDialogButtonBox::Ok); - m_okButton->setEnabled(false); + updateOkButton(); setMinimumWidth(480); } @@ -203,6 +203,18 @@ void MultiChoiceDialog::urlChanged(const QString &s) { + updateOkButton(); +} + +void +MultiChoiceDialog::fileChanged(const QString &s) +{ + updateOkButton(); +} + +void +MultiChoiceDialog::updateOkButton() +{ /* This doesn't work well if (m_argTypes[m_currentChoice] != UrlToDirectoryArg) { return; @@ -231,17 +243,6 @@ } void -MultiChoiceDialog::fileChanged(const QString &s) -{ - if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) { - m_okButton->setEnabled(getArgument() != "" && - getAdditionalArgument() != ""); - } else { - m_okButton->setEnabled(getArgument() != ""); - } -} - -void MultiChoiceDialog::choiceChanged() { DEBUG << "choiceChanged" << endl; @@ -323,6 +324,7 @@ break; } + updateOkButton(); adjustSize(); } diff -r 4adbd5c9c15d -r f16fe0db11f3 multichoicedialog.h --- a/multichoicedialog.h Mon Jan 03 14:31:22 2011 +0000 +++ b/multichoicedialog.h Mon Jan 03 22:02:08 2011 +0000 @@ -65,6 +65,8 @@ void browse(); private: + void updateOkButton(); + QMap m_texts; QMap m_descriptions; QMap m_argTypes;