# HG changeset patch # User Chris Cannam # Date 1290609712 0 # Node ID 44ed7766d55a1147167c28021735b02477cad915 # Parent dfb7a274b90ffa43a6ce624b08f52c39f9d994bf * Clear selections when Esc pressed; some refactoring diff -r dfb7a274b90f -r 44ed7766d55a filestates.cpp --- a/filestates.cpp Wed Nov 24 13:50:33 2010 +0000 +++ b/filestates.cpp Wed Nov 24 14:41:52 2010 +0000 @@ -4,56 +4,85 @@ #include -FileStates::FileStates(QString text) +FileStates::FileStates() +{ +} + +void FileStates::clearBuckets() +{ + m_modified.clear(); + m_added.clear(); + m_removed.clear(); + m_missing.clear(); + m_unknown.clear(); +} + +FileStates::State FileStates::charToState(QChar c, bool *ok) +{ + if (ok) *ok = true; + if (c == 'M') return Modified; + if (c == 'A') return Added; + if (c == 'R') return Removed; + if (c == '!') return Missing; + if (c == '?') return Unknown; + if (c == 'C') return Clean; + if (ok) *ok = false; + return Unknown; +} + +QStringList *FileStates::stateToBucket(State s) +{ + switch (s) { + case Clean: default: return 0; // 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; + } +} + +void FileStates::parseStates(QString text) { text.replace("\r\n", "\n"); - QMap buckets; - buckets['M'] = &modified; - buckets['A'] = &added; - buckets['R'] = &removed; - buckets['!'] = &missing; - buckets['?'] = &unknown; + clearBuckets(); QStringList lines = text.split("\n", QString::SkipEmptyParts); + foreach (QString line, lines) { + if (line.length() < 3 || line[1] != ' ') { continue; } - QChar tag = line[0]; + + QChar c = line[0]; + bool ok = false; + State s = charToState(c, &ok); + if (!ok) continue; + QString file = line.right(line.length() - 2); - if (buckets.contains(tag)) { - buckets[tag]->push_back(file); - } + QStringList *bucket = stateToBucket(s); + bucket->push_back(file); + m_stateMap[file] = s; } - DEBUG << "FileStates: " << modified.size() << " modified, " << added.size() - << " added, " << removed.size() << " removed, " << missing.size() - << " missing, " << unknown.size() << " unknown" << endl; + DEBUG << "FileStates: " << m_modified.size() << " modified, " << m_added.size() + << " added, " << m_removed.size() << " removed, " << m_missing.size() + << " missing, " << m_unknown.size() << " unknown" << endl; } -QStringList FileStates::getFilesInState(State s) +QStringList FileStates::getFilesInState(State s) const { - switch (s) { - - case Modified: return modified; - case Added: return added; - case Unknown: return unknown; - case Removed: return removed; - case Missing: return missing; - - case UpToDate: // not supported yet - default: - return QStringList(); - } + QStringList *sl = const_cast(this)->stateToBucket(s); + if (sl) return *sl; + else return QStringList(); } -FileStates::State FileStates::getStateOfFile(QString file) +FileStates::State FileStates::getStateOfFile(QString file) const { - // slow, but let's worry about that if it becomes a problem - for (int is = int(FirstState); is <= int(LastState); ++is) { - QStringList fl = getFilesInState(State(is)); - foreach (QString f, fl) if (f == file) return State(is); + if (m_stateMap.contains(file)) { + return m_stateMap[file]; } DEBUG << "FileStates: WARNING: getStateOfFile: file " << file << " is unknown to us: returning Unknown state, " diff -r dfb7a274b90f -r 44ed7766d55a filestates.h --- a/filestates.h Wed Nov 24 13:50:33 2010 +0000 +++ b/filestates.h Wed Nov 24 14:41:52 2010 +0000 @@ -19,34 +19,51 @@ #define FILESTATES_H #include +#include +#include class FileStates { public: - FileStates() { } - FileStates(QString text); + FileStates(); enum State { - UpToDate, + Clean, Modified, Added, Unknown, Removed, Missing, - FirstState = UpToDate, + FirstState = Clean, LastState = Missing }; - QStringList modified; - QStringList added; - QStringList unknown; - QStringList removed; - QStringList missing; + void parseStates(QString text); - QStringList getFilesInState(State); - State getStateOfFile(QString file); + void clearBuckets(); + + QStringList getFilesInState(State) const; + + QStringList modified() const { return m_modified; } + QStringList added() const { return m_added; } + QStringList unknown() const { return m_unknown; } + QStringList removed() const { return m_removed; } + QStringList missing() const { return m_missing; } + + State getStateOfFile(QString file) const; + +private: + QStringList m_modified; + QStringList m_added; + QStringList m_unknown; + QStringList m_removed; + QStringList m_missing; + QMap m_stateMap; + + State charToState(QChar, bool * = 0); + QStringList *stateToBucket(State); }; #endif // FILESTATES_H diff -r dfb7a274b90f -r 44ed7766d55a filestatuswidget.cpp --- a/filestatuswidget.cpp Wed Nov 24 13:50:33 2010 +0000 +++ b/filestatuswidget.cpp Wed Nov 24 14:41:52 2010 +0000 @@ -49,31 +49,29 @@ layout->setColumnStretch(1, 20); - QStringList labels; - labels << tr("Modified files:") - << tr("Added files:") - << tr("Removed files:") - << tr("New untracked files:") - << tr("Missing files:"); + QMap labels; + labels[FileStates::Clean] = tr("Unmodified files:"); + labels[FileStates::Modified] = tr("Modified files:"); + labels[FileStates::Added] = tr("Added files:"); + labels[FileStates::Removed] = tr("Removed files:"); + labels[FileStates::Missing] = tr("Missing files:"); + labels[FileStates::Unknown] = tr("Untracked files:"); - QList lists; - lists << &m_modifiedList - << &m_addedList - << &m_removedList - << &m_unknownList - << &m_missingList; + for (int i = int(FileStates::FirstState); + i <= int(FileStates::LastState); ++i) { - for (int i = 0; i < labels.size(); ++i) { + FileStates::State s = FileStates::State(i); QWidget *box = new QWidget; QGridLayout *boxlayout = new QGridLayout; box->setLayout(boxlayout); - boxlayout->addWidget(new QLabel(labels[i]), 0, 0); + boxlayout->addWidget(new QLabel(labels[s]), 0, 0); - *lists[i] = new QListWidget; - (*lists[i])->setSelectionMode(QListWidget::ExtendedSelection); - boxlayout->addWidget(*lists[i], 1, 0); + QListWidget *w = new QListWidget; + m_stateListMap[s] = w; + w->setSelectionMode(QListWidget::ExtendedSelection); + boxlayout->addWidget(w, 1, 0); layout->addWidget(box, ++row, 0, 1, 2); box->hide(); @@ -87,6 +85,13 @@ delete m_dateReference; } +void FileStatusWidget::clearSelections() +{ + foreach (QListWidget *w, m_stateListMap) { + w->clearSelection(); + } +} + void FileStatusWidget::setLocalPath(QString p) { @@ -132,18 +137,12 @@ void FileStatusWidget::updateWidgets() { - FileStates &sp = m_fileStates; - QMap listmap; - listmap[&sp.modified] = m_modifiedList; - listmap[&sp.added] = m_addedList; - listmap[&sp.removed] = m_removedList; - listmap[&sp.missing] = m_missingList; - listmap[&sp.unknown] = m_unknownList; - - foreach (QStringList *sl, listmap.keys()) { - listmap[sl]->clear(); - listmap[sl]->addItems(*sl); - listmap[sl]->parentWidget()->setVisible(!sl->empty()); + foreach (FileStates::State s, m_stateListMap.keys()) { + QListWidget *w = m_stateListMap[s]; + w->clear(); + QStringList sl = m_fileStates.getFilesInState(s); + w->addItems(sl); + w->parentWidget()->setVisible(!sl.empty()); } if (m_dateReference) { @@ -151,14 +150,15 @@ // last interaction with the repo QDateTime refTime = m_dateReference->lastModified(); DEBUG << "reference time: " << refTime << endl; - for (int i = 0; i < m_unknownList->count(); ++i) { - QString fn(m_localPath + "/" + m_unknownList->item(i)->text()); + QListWidget *ul = m_stateListMap[FileStates::Unknown]; + for (int i = 0; i < ul->count(); ++i) { + QString fn(m_localPath + "/" + ul->item(i)->text()); DEBUG << "comparing with " << fn << endl; QFileInfo fi(fn); if (fi.exists() && fi.lastModified() > refTime) { DEBUG << "file " << fn << " is newer (" << fi.lastModified() << ") than reference" << endl; - highlightFile(m_unknownList, i); + highlightFile(ul, i); } } } diff -r dfb7a274b90f -r 44ed7766d55a filestatuswidget.h --- a/filestatuswidget.h Wed Nov 24 13:50:33 2010 +0000 +++ b/filestatuswidget.h Wed Nov 24 14:41:52 2010 +0000 @@ -44,11 +44,18 @@ void setFileStates(FileStates sp); bool haveChangesToCommit() const { - return !m_fileStates.added.empty() || - !m_fileStates.removed.empty() || - !m_fileStates.modified.empty(); + return !m_fileStates.added().empty() || + !m_fileStates.removed().empty() || + !m_fileStates.modified().empty(); } + QStringList getSelectedCommittableFiles(); + QStringList getSelectedAddableFiles(); + QStringList getSelectedRemoveableFiles(); + +public slots: + void clearSelections(); + private: QString m_localPath; QLabel *m_localPathLabel; @@ -57,12 +64,7 @@ QLabel *m_remoteURLLabel; FileStates m_fileStates; - - QListWidget *m_modifiedList; - QListWidget *m_addedList; - QListWidget *m_unknownList; - QListWidget *m_removedList; - QListWidget *m_missingList; + QMap m_stateListMap; QFileInfo *m_dateReference; diff -r dfb7a274b90f -r 44ed7766d55a hgexpwidget.cpp --- a/hgexpwidget.cpp Wed Nov 24 13:50:33 2010 +0000 +++ b/hgexpwidget.cpp Wed Nov 24 14:41:52 2010 +0000 @@ -57,6 +57,11 @@ addTab(historyGraphPageWidget, tr("History")); } +void HgExpWidget::clearSelections() +{ + fileStatusWidget->clearSelections(); +} + bool HgExpWidget::canCommit() const { return fileStatusWidget->haveChangesToCommit(); @@ -64,7 +69,7 @@ void HgExpWidget::updateWorkFolderFileList(QString fileList) { - fileStates = FileStates(fileList); + fileStates.parseStates(fileList); fileStatusWidget->setFileStates(fileStates); } diff -r dfb7a274b90f -r 44ed7766d55a hgexpwidget.h --- a/hgexpwidget.h Wed Nov 24 13:50:33 2010 +0000 +++ b/hgexpwidget.h Wed Nov 24 14:41:52 2010 +0000 @@ -54,6 +54,9 @@ bool canRemove() const; bool canDoFolderDiff() const; +public slots: + void clearSelections(); + private: FileStatusWidget *fileStatusWidget; diff -r dfb7a274b90f -r 44ed7766d55a mainwindow.cpp --- a/mainwindow.cpp Wed Nov 24 13:50:33 2010 +0000 +++ b/mainwindow.cpp Wed Nov 24 14:41:52 2010 +0000 @@ -130,6 +130,10 @@ "-Windows standalone install uses InstallJammer setup tool (Thanks, great tool !)
")); } +void MainWindow::clearSelections() +{ + hgExp->clearSelections(); +} void MainWindow::hgStat() { @@ -349,6 +353,10 @@ void MainWindow::hgCommit() { + //!!! Now that hg actions can be fired asynchronously (e.g. from + // the filesystem modified callback) we _really_ need to be able to + // queue important actions rather than just ignore them if busy! + if (runningAction == ACT_NONE) { QStringList params; @@ -1498,6 +1506,7 @@ connect(hgResolveListAct, SIGNAL(triggered()), this, SLOT(hgResolveList())); connect(hgResolveMarkAct, SIGNAL(triggered()), this, SLOT(hgResolveMark())); connect(hgServeAct, SIGNAL(triggered()), this, SLOT(hgServe())); + connect(clearSelectionsAct, SIGNAL(triggered()), this, SLOT(clearSelections())); } void MainWindow::tabChanged(int currTab) @@ -1776,6 +1785,10 @@ aboutQtAct = new QAction(tr("About Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); + + // Miscellaneous + clearSelectionsAct = new QAction(tr("Clear selections"), this); + clearSelectionsAct->setShortcut(Qt::Key_Escape); } void MainWindow::createMenus() @@ -1783,6 +1796,7 @@ fileMenu = menuBar()->addMenu(tr("File")); fileMenu -> addAction(hgInitAct); fileMenu -> addAction(hgCloneFromRemoteAct); + fileMenu->addAction(clearSelectionsAct); //!!! can't live here! fileMenu -> addSeparator(); fileMenu -> addAction(openAct); fileMenu -> addAction(settingsAct); diff -r dfb7a274b90f -r 44ed7766d55a mainwindow.h --- a/mainwindow.h Wed Nov 24 13:50:33 2010 +0000 +++ b/mainwindow.h Wed Nov 24 14:41:52 2010 +0000 @@ -93,6 +93,7 @@ void settings(); void open(); void startupDialog(); + void clearSelections(); void hgRemove(); void hgAdd(); @@ -209,6 +210,9 @@ QAction *aboutAct; QAction *aboutQtAct; + // Other actions + QAction *clearSelectionsAct; + QToolBar *fileToolBar; QToolBar *repoToolBar; QToolBar *workFolderToolBar;