Mercurial > hg > easyhg
changeset 307:5b4aa1c24407 new-branches-with-status-outside-tabs
Merge branch status_outside_tabs into branch new-branches, and make a new branch
author | Chris Cannam |
---|---|
date | Mon, 28 Feb 2011 13:09:37 +0000 |
parents | f7cdd5b31aed (current diff) b280a2dc0512 (diff) |
children | 7f50c040e13d |
files | changesetitem.cpp changesetitem.h changesetscene.cpp changesetscene.h hgaction.h hgtabwidget.cpp hgtabwidget.h historywidget.cpp historywidget.h mainwindow.cpp mainwindow.h |
diffstat | 23 files changed, 1188 insertions(+), 690 deletions(-) [+] |
line wrap: on
line diff
--- a/changesetitem.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/changesetitem.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -16,6 +16,7 @@ */ #include "changesetitem.h" +#include "changesetscene.h" #include "changesetdetailitem.h" #include "changeset.h" #include "textabbrev.h" @@ -107,6 +108,7 @@ ChangesetItem::activateMenu() { m_parentDiffActions.clear(); + m_summaryActions.clear(); QMenu *menu = new QMenu; QLabel *label = new QLabel(tr("<qt><b> Revision: </b>%1</qt>") @@ -119,25 +121,59 @@ QAction *copyId = menu->addAction(tr("Copy identifier to clipboard")); connect(copyId, SIGNAL(triggered()), this, SLOT(copyIdActivated())); + QAction *stat = menu->addAction(tr("Summarise changes")); + connect(stat, SIGNAL(triggered()), this, SLOT(showSummaryActivated())); + menu->addSeparator(); - if (m_changeset->parents().size() > 1) { + QStringList parents = m_changeset->parents(); - foreach (QString parentId, m_changeset->parents()) { - QAction *diffParent = - menu->addAction(tr("Diff to parent %1") - .arg(Changeset::hashOf(parentId))); - connect(diffParent, SIGNAL(triggered()), - this, SLOT(diffToParentActivated())); - m_parentDiffActions[diffParent] = parentId; + QString leftId, rightId; + bool havePositions = false; + + if (parents.size() > 1) { + ChangesetScene *cs = dynamic_cast<ChangesetScene *>(scene()); + if (cs && parents.size() == 2) { + ChangesetItem *i0 = cs->getItemById(parents[0]); + ChangesetItem *i1 = cs->getItemById(parents[1]); + if (i0 && i1) { + if (i0->x() < i1->x()) { + leftId = parents[0]; + rightId = parents[1]; + } else { + leftId = parents[1]; + rightId = parents[0]; + } + havePositions = true; + } + } + } + + if (parents.size() > 1) { + if (havePositions) { + + QAction *diff = menu->addAction(tr("Diff to left parent")); + connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated())); + m_parentDiffActions[diff] = leftId; + + diff = menu->addAction(tr("Diff to right parent")); + connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated())); + m_parentDiffActions[diff] = rightId; + + } else { + + foreach (QString parentId, parents) { + QString text = tr("Diff to parent %1").arg(Changeset::hashOf(parentId)); + QAction *diff = menu->addAction(text); + connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated())); + m_parentDiffActions[diff] = parentId; + } } } else { - QAction *diffParent = - menu->addAction(tr("Diff to parent")); - connect(diffParent, SIGNAL(triggered()), - this, SLOT(diffToParentActivated())); + QAction *diff = menu->addAction(tr("Diff to parent")); + connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated())); } QAction *diffCurrent = menu->addAction(tr("Diff to current working folder")); @@ -190,6 +226,11 @@ emit diffToParent(getId(), parentId); } +void ChangesetItem::showSummaryActivated() +{ + emit showSummary(m_changeset); +} + void ChangesetItem::updateActivated() { emit updateTo(getId()); } void ChangesetItem::diffToCurrentActivated() { emit diffToCurrent(getId()); } void ChangesetItem::mergeActivated() { emit mergeFrom(getId()); } @@ -197,8 +238,7 @@ void ChangesetItem::newBranchActivated() { emit newBranch(getId()); } void -ChangesetItem::paint(QPainter *paint, const QStyleOptionGraphicsItem *option, - QWidget *w) +ChangesetItem::paint(QPainter *paint, const QStyleOptionGraphicsItem *, QWidget *) { paint->save();
--- a/changesetitem.h Wed Feb 09 12:03:15 2011 +0000 +++ b/changesetitem.h Mon Feb 28 13:09:37 2011 +0000 @@ -63,6 +63,7 @@ void updateTo(QString); void diffToCurrent(QString); void diffToParent(QString child, QString parent); + void showSummary(Changeset *); void mergeFrom(QString); void newBranch(QString); void tag(QString); @@ -75,6 +76,7 @@ void copyIdActivated(); void updateActivated(); void diffToParentActivated(); + void showSummaryActivated(); void diffToCurrentActivated(); void mergeActivated(); void tagActivated(); @@ -97,6 +99,7 @@ bool m_new; QMap<QAction *, QString> m_parentDiffActions; + QMap<QAction *, QString> m_summaryActions; }; #endif // CHANGESETITEM_H
--- a/changesetscene.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/changesetscene.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -45,6 +45,9 @@ connect(item, SIGNAL(diffToParent(QString, QString)), this, SIGNAL(diffToParent(QString, QString))); + connect(item, SIGNAL(showSummary(Changeset *)), + this, SIGNAL(showSummary(Changeset *))); + connect(item, SIGNAL(mergeFrom(QString)), this, SIGNAL(mergeFrom(QString))); @@ -111,3 +114,14 @@ } } +ChangesetItem * +ChangesetScene::getItemById(QString id) +{ + foreach (QGraphicsItem *it, items()) { + ChangesetItem *csit = dynamic_cast<ChangesetItem *>(it); + if (csit && csit->getId() == id) return csit; + } + return 0; +} + +
--- a/changesetscene.h Wed Feb 09 12:03:15 2011 +0000 +++ b/changesetscene.h Mon Feb 28 13:09:37 2011 +0000 @@ -21,6 +21,7 @@ #include <QGraphicsScene> class ChangesetItem; +class Changeset; class UncommittedItem; class DateItem; @@ -35,6 +36,8 @@ void addUncommittedItem(UncommittedItem *item); void addDateItem(DateItem *item); + ChangesetItem *getItemById(QString id); // Slow: traversal required + signals: void commit(); void revert(); @@ -44,6 +47,7 @@ void updateTo(QString id); void diffToParent(QString id, QString parent); + void showSummary(Changeset *); void diffToCurrent(QString id); void mergeFrom(QString id); void newBranch(QString id);
--- a/confirmcommentdialog.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/confirmcommentdialog.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -51,8 +51,10 @@ QDialogButtonBox::Cancel); layout->addWidget(bbox, 2, 0); m_ok = bbox->button(QDialogButtonBox::Ok); + m_ok->setDefault(true); m_ok->setEnabled(initialComment != ""); m_ok->setText(okButtonText); + bbox->button(QDialogButtonBox::Cancel)->setAutoDefault(false); connect(bbox, SIGNAL(accepted()), this, SLOT(accept())); connect(bbox, SIGNAL(rejected()), this, SLOT(reject())); @@ -71,45 +73,57 @@ QString ConfirmCommentDialog::buildFilesText(QString intro, QStringList files) { QString text; - text = "<qt>" + intro; - text += "<p><code>"; + + if (intro == "") text = "<qt>"; + else text = "<qt>" + intro + "<p>"; + + text += "<code>"; foreach (QString file, files) { text += " " + xmlEncode(file) + "<br>"; } text += "</code></qt>"; + return text; } bool ConfirmCommentDialog::confirm(QWidget *parent, QString title, + QString head, QString text, QString okButtonText) { QMessageBox box(QMessageBox::Question, title, - text, + head, QMessageBox::Cancel, parent); + box.setInformativeText(text); + QPushButton *ok = box.addButton(QMessageBox::Ok); ok->setText(okButtonText); + box.setDefaultButton(QMessageBox::Ok); if (box.exec() == -1) return false; return box.standardButton(box.clickedButton()) == QMessageBox::Ok; } bool ConfirmCommentDialog::confirmDangerous(QWidget *parent, QString title, + QString head, QString text, QString okButtonText) { QMessageBox box(QMessageBox::Warning, title, - text, + head, QMessageBox::Cancel, parent); + box.setInformativeText(text); + QPushButton *ok = box.addButton(QMessageBox::Ok); ok->setText(okButtonText); + box.setDefaultButton(QMessageBox::Cancel); if (box.exec() == -1) return false; return box.standardButton(box.clickedButton()) == QMessageBox::Ok; } @@ -127,7 +141,7 @@ } else { text = "<qt>" + introTextWithCount + "</qt>"; } - return confirm(parent, title, text, okButtonText); + return confirm(parent, title, text, "", okButtonText); } bool ConfirmCommentDialog::confirmDangerousFilesAction(QWidget *parent, @@ -143,7 +157,7 @@ } else { text = "<qt>" + introTextWithCount + "</qt>"; } - return confirmDangerous(parent, title, text, okButtonText); + return confirmDangerous(parent, title, text, "", okButtonText); } bool ConfirmCommentDialog::confirmAndGetShortComment(QWidget *parent,
--- a/confirmcommentdialog.h Wed Feb 09 12:03:15 2011 +0000 +++ b/confirmcommentdialog.h Mon Feb 28 13:09:37 2011 +0000 @@ -32,11 +32,13 @@ public: static bool confirm(QWidget *parent, QString title, + QString head, QString text, QString okButtonText); static bool confirmDangerous(QWidget *parent, QString title, + QString head, QString text, QString okButtonText);
--- a/easyhg-extdiff.sh Wed Feb 09 12:03:15 2011 +0000 +++ b/easyhg-extdiff.sh Mon Feb 28 13:09:37 2011 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -x p=`dirname $0` if [ $# -lt 2 ]; then echo Insufficient arguments: $@ @@ -13,11 +13,18 @@ found=true "$p/$d" "$1" "$2" break + elif [ -x "$(type -path $d)" ]; then + found=true + "$d" "$1" "$2" + break; fi done if [ -z "$found" ]; then od=/usr/bin/opendiff if [ -x "$od" ]; then + found=true "$od" "$1" "$2" | cat fi fi +[ -n "$found" ] +
--- a/easyhg-merge.sh Wed Feb 09 12:03:15 2011 +0000 +++ b/easyhg-merge.sh Mon Feb 28 13:09:37 2011 +0000 @@ -18,11 +18,17 @@ found=true "$p/$d" "$ancestor" "$left" "$right" -o "$out" break + elif [ -x "$(type -path $d)" ]; then + found=true + "$d" "$ancestor" "$left" "$right" -o "$out" + break; fi done if [ -z "$found" ]; then fm=/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge if [ -x "$fm" ]; then + found=true "$fm" -left "$left" -merge "$out" -ancestor "$ancestor" -right "$right" fi fi +[ -n "$found" ]
--- a/easyhg.pro Wed Feb 09 12:03:15 2011 +0000 +++ b/easyhg.pro Mon Feb 28 13:09:37 2011 +0000 @@ -49,7 +49,9 @@ incomingdialog.h \ uncommitteditem.h \ settingsdialog.h \ - clickablelabel.h + clickablelabel.h \ + workstatuswidget.h \ + moreinformationdialog.h SOURCES = main.cpp \ mainwindow.cpp \ hgtabwidget.cpp \ @@ -79,7 +81,9 @@ changesetscene.cpp \ incomingdialog.cpp \ uncommitteditem.cpp \ - settingsdialog.cpp + settingsdialog.cpp \ + workstatuswidget.cpp \ + moreinformationdialog.cpp macx-* { SOURCES += common_osx.mm
--- a/filestatuswidget.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/filestatuswidget.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -18,7 +18,6 @@ #include "filestatuswidget.h" #include "debug.h" #include "multichoicedialog.h" -#include "clickablelabel.h" #include <QLabel> #include <QListWidget> @@ -43,40 +42,9 @@ int row = 0; -#ifndef Q_OS_MAC - layout->addItem(new QSpacerItem(1, 1), row, 0); - ++row; -#endif - - layout->addWidget(new QLabel(tr("Local:")), row, 0); - - m_openButton = new ClickableLabel; - QFont f(m_openButton->font()); - f.setBold(true); - m_openButton->setFont(f); - m_openButton->setMouseUnderline(true); - connect(m_openButton, SIGNAL(clicked()), this, SLOT(openButtonClicked())); - layout->addWidget(m_openButton, row, 1, 1, 2, Qt::AlignLeft); - - ++row; - layout->addWidget(new QLabel(tr("Remote:")), row, 0); - m_remoteURLLabel = new QLabel; - layout->addWidget(m_remoteURLLabel, row, 1, 1, 2); - - ++row; - layout->addWidget(new QLabel(tr("State:")), row, 0); - m_stateLabel = new QLabel; - layout->addWidget(m_stateLabel, row, 1, 1, 2); - - layout->setColumnStretch(1, 20); - - layout->addWidget(new QLabel("<qt><hr></qt>"), ++row, 0, 1, 3); - - ++row; - m_noModificationsLabel = new QLabel; setNoModificationsLabelText(); - layout->addWidget(m_noModificationsLabel, row, 1, 1, 2); + layout->addWidget(m_noModificationsLabel, row, 0); m_noModificationsLabel->hide(); m_simpleLabels[FileStates::Clean] = tr("Unmodified:"); @@ -107,7 +75,7 @@ "have appeared since your most recent commit or update."); m_boxesParent = new QWidget(this); - layout->addWidget(m_boxesParent, ++row, 0, 1, 3); + layout->addWidget(m_boxesParent, ++row, 0); QGridLayout *boxesLayout = new QGridLayout; boxesLayout->setMargin(0); @@ -152,7 +120,7 @@ layout->addItem(new QSpacerItem(8, 8), ++row, 0); m_showAllFiles = new QCheckBox(tr("Show all files"), this); - layout->addWidget(m_showAllFiles, ++row, 0, 1, 3, Qt::AlignLeft); + layout->addWidget(m_showAllFiles, ++row, 0, Qt::AlignLeft); connect(m_showAllFiles, SIGNAL(toggled(bool)), this, SIGNAL(showAllChanged(bool))); } @@ -162,32 +130,6 @@ delete m_dateReference; } -void FileStatusWidget::openButtonClicked() -{ - QDir d(m_localPath); - if (d.exists()) { - QStringList args; - QString path = d.canonicalPath(); -#if defined Q_OS_WIN32 - // Although the Win32 API is quite happy to have - // forward slashes as directory separators, Windows - // Explorer is not - path = path.replace('/', '\\'); - args << path; - QProcess::execute("c:/windows/explorer.exe", args); -#else - args << path; - QProcess::execute( -#if defined Q_OS_MAC - "/usr/bin/open", -#else - "/usr/bin/xdg-open", -#endif - args); -#endif - } -} - QString FileStatusWidget::labelFor(FileStates::State s, bool addHighlightExplanation) { QSettings settings; @@ -412,11 +354,16 @@ return files; } +QString +FileStatusWidget::localPath() const +{ + return m_localPath; +} + void FileStatusWidget::setLocalPath(QString p) { m_localPath = p; - m_openButton->setText(p); delete m_dateReference; m_dateReference = new QFileInfo(p + "/.hg/dirstate"); if (!m_dateReference->exists() || @@ -429,14 +376,6 @@ delete m_dateReference; m_dateReference = 0; } - m_openButton->setEnabled(QDir(m_localPath).exists()); -} - -void -FileStatusWidget::setRemoteURL(QString r) -{ - m_remoteURL = r; - m_remoteURLLabel->setText(r); } void @@ -447,13 +386,6 @@ } void -FileStatusWidget::setState(QString b) -{ - m_state = b; - updateStateLabel(); -} - -void FileStatusWidget::updateWidgets() { QDateTime lastInteractionTime; @@ -530,7 +462,6 @@ layoutBoxesLinearly(); } - updateStateLabel(); setNoModificationsLabelText(); } @@ -594,7 +525,3 @@ if (!ql.empty()) ql[0]->setText(text); } -void FileStatusWidget::updateStateLabel() -{ - m_stateLabel->setText(m_state); -}
--- a/filestatuswidget.h Wed Feb 09 12:03:15 2011 +0000 +++ b/filestatuswidget.h Mon Feb 28 13:09:37 2011 +0000 @@ -27,7 +27,6 @@ class QListWidget; class QPushButton; class QFileInfo; -class ClickableLabel; class QCheckBox; class FileStatusWidget : public QWidget @@ -38,16 +37,10 @@ FileStatusWidget(QWidget *parent = 0); ~FileStatusWidget(); - QString localPath() const { return m_localPath; } + QString localPath() const; void setLocalPath(QString p); - QString remoteURL() const { return m_remoteURL; } - void setRemoteURL(QString u); - - QString state() const { return m_state; } - void setState(QString b); - - FileStates fileStates() const { return m_fileStates; } + FileStates fileStates() const; void setFileStates(FileStates sp); bool haveChangesToCommit() const; @@ -80,18 +73,9 @@ private slots: void itemSelectionChanged(); - void openButtonClicked(); private: QString m_localPath; - ClickableLabel *m_openButton; - - QString m_remoteURL; - QLabel *m_remoteURLLabel; - - QString m_state; - QLabel *m_stateLabel; - QLabel *m_noModificationsLabel; QCheckBox *m_showAllFiles; @@ -112,7 +96,6 @@ void layoutBoxesGridly(int count); void layoutBoxesLinearly(); - void updateStateLabel(); void setNoModificationsLabelText(); QString labelFor(FileStates::State, bool addHighlightExplanation = false); void setLabelFor(QWidget *w, FileStates::State, bool addHighlightExplanation);
--- a/hgaction.h Wed Feb 09 12:03:15 2011 +0000 +++ b/hgaction.h Mon Feb 28 13:09:37 2011 +0000 @@ -43,6 +43,7 @@ ACT_INIT, ACT_COMMIT, ACT_ANNOTATE, + ACT_UNCOMMITTED_SUMMARY, ACT_DIFF_SUMMARY, ACT_FOLDERDIFF, ACT_CHGSETDIFF, @@ -63,15 +64,20 @@ QString workingDir; QStringList params; QString executable; // empty for normal Hg, but gets filled in by hgrunner + void *extraData; HgAction() : action(ACT_NONE) { } HgAction(HGACTIONS _action, QString _wd, QStringList _params) : - action(_action), workingDir(_wd), params(_params) { } + action(_action), workingDir(_wd), params(_params), extraData(0) { } + + HgAction(HGACTIONS _action, QString _wd, QStringList _params, void *_d) : + action(_action), workingDir(_wd), params(_params), extraData(_d) { } bool operator==(const HgAction &a) { return (a.action == action && a.workingDir == workingDir && - a.params == params && a.executable == executable); + a.params == params && a.executable == executable && + a.extraData == extraData); } bool shouldBeFast() const {
--- a/hgtabwidget.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/hgtabwidget.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -27,14 +27,12 @@ #include <iostream> HgTabWidget::HgTabWidget(QWidget *parent, - QString remoteRepo, QString workFolderPath) : QTabWidget(parent) { // Work page m_fileStatusWidget = new FileStatusWidget; m_fileStatusWidget->setLocalPath(workFolderPath); - m_fileStatusWidget->setRemoteURL(remoteRepo); connect(m_fileStatusWidget, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); connect(m_fileStatusWidget, SIGNAL(showAllChanged(bool)), @@ -69,6 +67,9 @@ connect(m_historyWidget, SIGNAL(diffToParent(QString, QString)), this, SIGNAL(diffToParent(QString, QString))); + connect(m_historyWidget, SIGNAL(showSummary(Changeset *)), + this, SIGNAL(showSummary(Changeset *))); + connect(m_historyWidget, SIGNAL(mergeFrom(QString)), this, SIGNAL(mergeFrom(QString))); @@ -243,15 +244,9 @@ } } -void HgTabWidget::setWorkFolderAndRepoNames(QString workFolderPath, QString remoteRepoPath) +void HgTabWidget::setLocalPath(QString workFolderPath) { m_fileStatusWidget->setLocalPath(workFolderPath); - m_fileStatusWidget->setRemoteURL(remoteRepoPath); -} - -void HgTabWidget::setState(QString state) -{ - m_fileStatusWidget->setState(state); } void HgTabWidget::showWorkTab()
--- a/hgtabwidget.h Wed Feb 09 12:03:15 2011 +0000 +++ b/hgtabwidget.h Mon Feb 28 13:09:37 2011 +0000 @@ -38,15 +38,14 @@ Q_OBJECT public: - HgTabWidget(QWidget *parent, QString remoteRepo, QString workFolderPath); + HgTabWidget(QWidget *parent, QString workFolderPath); void updateWorkFolderFileList(QString fileList); void setNewLog(QString hgLogList); void addIncrementalLog(QString hgLogList); - void setWorkFolderAndRepoNames(QString workFolderPath, QString remoteRepoPath); - void setState(QString state); + void setLocalPath(QString workFolderPath); void setCurrent(QStringList ids, QString branch); @@ -91,6 +90,7 @@ void updateTo(QString id); void diffToParent(QString id, QString parent); + void showSummary(Changeset *); void diffToCurrent(QString id); void mergeFrom(QString id); void newBranch(QString id);
--- a/historywidget.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/historywidget.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -141,7 +141,8 @@ m_newIds.insert(cs->id()); } - DEBUG << "addChangesets: " << csets.size() << " new changesets" << endl; + DEBUG << "addChangesets: " << csets.size() << " new changesets have (" + << m_changesets.size() << " already)" << endl; csets << m_changesets; m_changesets = csets; @@ -277,6 +278,9 @@ connect(scene, SIGNAL(diffToParent(QString, QString)), this, SIGNAL(diffToParent(QString, QString))); + connect(scene, SIGNAL(showSummary(Changeset *)), + this, SIGNAL(showSummary(Changeset *))); + connect(scene, SIGNAL(mergeFrom(QString)), this, SIGNAL(mergeFrom(QString)));
--- a/historywidget.h Wed Feb 09 12:03:15 2011 +0000 +++ b/historywidget.h Mon Feb 28 13:09:37 2011 +0000 @@ -54,6 +54,7 @@ void updateTo(QString id); void diffToParent(QString id, QString parent); + void showSummary(Changeset *); void diffToCurrent(QString id); void mergeFrom(QString id); void newBranch(QString id);
--- a/incomingdialog.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/incomingdialog.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -40,7 +40,9 @@ body = QString("<p>%1</p><code>%2</code>") .arg(tr("The command output was:")) .arg(xmlEncode(text).replace("\n", "<br>")); - } + } else { + body = tr("<qt>Your local repository already contains all changes found in the remote repository.</qt>"); + } scroll = false; } else { head = tr("There are %n change(s) ready to pull", "", csets.size()); @@ -59,12 +61,13 @@ int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this); info->setPixmap(style->standardIcon(QStyle::SP_MessageBoxInformation, 0, this) .pixmap(iconSize, iconSize)); - layout->addWidget(info, 0, 0); + layout->addWidget(info, 0, 0, 2, 1); QLabel *headLabel = new QLabel(QString("<qt><h3>%1</h3></qt>").arg(head)); layout->addWidget(headLabel, 0, 1); QLabel *textLabel = new QLabel(body); + if (csets.empty()) textLabel->setWordWrap(true); if (scroll) { QScrollArea *sa = new QScrollArea; @@ -78,6 +81,9 @@ QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok); connect(bb, SIGNAL(accepted()), this, SLOT(accept())); layout->addWidget(bb, 2, 0, 1, 2); + + layout->setColumnStretch(1, 20); + setMinimumWidth(400); }
--- a/mainwindow.cpp Wed Feb 09 12:03:15 2011 +0000 +++ b/mainwindow.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -43,7 +43,9 @@ #include "confirmcommentdialog.h" #include "incomingdialog.h" #include "settingsdialog.h" +#include "moreinformationdialog.h" #include "version.h" +#include "workstatuswidget.h" MainWindow::MainWindow(QString myDirPath) : @@ -56,55 +58,56 @@ QString wndTitle; - showAllFiles = false; - - fsWatcher = 0; - commitsSincePush = 0; - shouldHgStat = true; + m_showAllFiles = false; + + m_fsWatcher = 0; + m_commitsSincePush = 0; + m_shouldHgStat = true; createActions(); createMenus(); createToolBars(); createStatusBar(); - runner = new HgRunner(myDirPath, this); - connect(runner, SIGNAL(commandStarting(HgAction)), + m_runner = new HgRunner(m_myDirPath, this); + connect(m_runner, SIGNAL(commandStarting(HgAction)), this, SLOT(commandStarting(HgAction))); - connect(runner, SIGNAL(commandCompleted(HgAction, QString)), + connect(m_runner, SIGNAL(commandCompleted(HgAction, QString)), this, SLOT(commandCompleted(HgAction, QString))); - connect(runner, SIGNAL(commandFailed(HgAction, QString)), + connect(m_runner, SIGNAL(commandFailed(HgAction, QString)), this, SLOT(commandFailed(HgAction, QString))); - statusBar()->addPermanentWidget(runner); + statusBar()->addPermanentWidget(m_runner); setWindowTitle(tr("EasyMercurial")); - remoteRepoPath = ""; - workFolderPath = ""; + m_remoteRepoPath = ""; + m_workFolderPath = ""; readSettings(); - justMerged = false; + m_justMerged = false; QWidget *central = new QWidget(this); setCentralWidget(central); - hgTabs = new HgTabWidget(central, remoteRepoPath, workFolderPath); - connectTabsSignals(); - - // Instead of setting the tab widget as our central widget - // directly, put it in a layout, so that we can have some space - // around it on the Mac where it looks very strange without - QGridLayout *cl = new QGridLayout(central); - cl->addWidget(hgTabs, 0, 0); + int row = 0; #ifndef Q_OS_MAC cl->setMargin(0); #endif - connect(hgTabs, SIGNAL(selectionChanged()), + m_workStatus = new WorkStatusWidget(this); + cl->addWidget(m_workStatus, row++, 0); + + m_hgTabs = new HgTabWidget(central, m_workFolderPath); + connectTabsSignals(); + + cl->addWidget(m_hgTabs, row++, 0); + + connect(m_hgTabs, SIGNAL(selectionChanged()), this, SLOT(enableDisableActions())); - connect(hgTabs, SIGNAL(showAllChanged(bool)), + connect(m_hgTabs, SIGNAL(showAllChanged(bool)), this, SLOT(showAllChanged(bool))); setUnifiedTitleAndToolBarOnMac(true); @@ -112,7 +115,7 @@ clearState(); enableDisableActions(); - if (firstStart) { + if (m_firstStart) { startupDialog(); } @@ -131,7 +134,7 @@ void MainWindow::closeEvent(QCloseEvent *) { writeSettings(); - delete fsWatcher; + delete m_fsWatcher; } @@ -195,12 +198,12 @@ void MainWindow::clearSelections() { - hgTabs->clearSelections(); + m_hgTabs->clearSelections(); } void MainWindow::showAllChanged(bool s) { - showAllFiles = s; + m_showAllFiles = s; hgQueryPaths(); } @@ -216,36 +219,36 @@ //!!! should we test version output? Really we want at least 1.7.x //!!! for options such as merge --tool params << "--version"; - runner->requestAction(HgAction(ACT_TEST_HG, m_myDirPath, params)); + m_runner->requestAction(HgAction(ACT_TEST_HG, m_myDirPath, params)); } void MainWindow::hgTestExtension() { QStringList params; params << "--version"; - runner->requestAction(HgAction(ACT_TEST_HG_EXT, m_myDirPath, params)); + m_runner->requestAction(HgAction(ACT_TEST_HG_EXT, m_myDirPath, params)); } void MainWindow::hgStat() { QStringList params; - if (showAllFiles) { + if (m_showAllFiles) { params << "stat" << "-A"; } else { params << "stat" << "-ardum"; } - lastStatOutput = ""; - - runner->requestAction(HgAction(ACT_STAT, workFolderPath, params)); + m_lastStatOutput = ""; + + m_runner->requestAction(HgAction(ACT_STAT, m_workFolderPath, params)); } void MainWindow::hgQueryPaths() { // Quickest is to just read the file - QFileInfo hgrc(workFolderPath + "/.hg/hgrc"); + QFileInfo hgrc(m_workFolderPath + "/.hg/hgrc"); QString path; @@ -255,12 +258,12 @@ path = s.value("default").toString(); } - remoteRepoPath = path; + m_remoteRepoPath = path; // We have to do this here, because commandCompleted won't be called - MultiChoiceDialog::addRecentArgument("local", workFolderPath); - MultiChoiceDialog::addRecentArgument("remote", remoteRepoPath); - hgTabs->setWorkFolderAndRepoNames(workFolderPath, remoteRepoPath); + MultiChoiceDialog::addRecentArgument("local", m_workFolderPath); + MultiChoiceDialog::addRecentArgument("remote", m_remoteRepoPath); + updateWorkFolderAndRepoNames(); hgQueryBranch(); return; @@ -269,7 +272,7 @@ QStringList params; params << "paths"; - runner->requestAction(HgAction(ACT_QUERY_PATHS, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_QUERY_PATHS, m_workFolderPath, params)); */ } @@ -277,7 +280,7 @@ { // Quickest is to just read the file - QFile hgbr(workFolderPath + "/.hg/branch"); + QFile hgbr(m_workFolderPath + "/.hg/branch"); QString br = "default"; @@ -286,7 +289,7 @@ br = QString::fromUtf8(ba).trimmed(); } - currentBranch = br; + m_currentBranch = br; // We have to do this here, because commandCompleted won't be called hgStat(); @@ -296,7 +299,7 @@ QStringList params; params << "branch"; - runner->requestAction(HgAction(ACT_QUERY_BRANCH, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_QUERY_BRANCH, m_workFolderPath, params)); */ } @@ -309,7 +312,7 @@ // incremental log will end up with spurious stuff in it because // we won't be pruning at the ends of closed branches params << "heads" << "--closed"; - runner->requestAction(HgAction(ACT_QUERY_HEADS, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_QUERY_HEADS, m_workFolderPath, params)); } void MainWindow::hgLog() @@ -319,11 +322,21 @@ params << "--template"; params << Changeset::getLogTemplate(); - runner->requestAction(HgAction(ACT_LOG, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_LOG, m_workFolderPath, params)); } void MainWindow::hgLogIncremental(QStringList prune) { + // Sometimes we can be called with prune empty -- it represents + // the current heads, but if we have none already and for some + // reason are being prompted for an incremental update, we may run + // into trouble. In that case, make this a full log instead + + if (prune.empty()) { + hgLog(); + return; + } + QStringList params; params << "log"; @@ -334,26 +347,26 @@ params << "--template"; params << Changeset::getLogTemplate(); - runner->requestAction(HgAction(ACT_LOG_INCREMENTAL, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_LOG_INCREMENTAL, m_workFolderPath, params)); } void MainWindow::hgQueryParents() { QStringList params; params << "parents"; - runner->requestAction(HgAction(ACT_QUERY_PARENTS, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_QUERY_PARENTS, m_workFolderPath, params)); } void MainWindow::hgAnnotate() { QStringList params; - QString currentFile;//!!! = hgTabs -> getCurrentFileListLine(); + QString currentFile;//!!! = m_hgTabs -> getCurrentFileListLine(); if (!currentFile.isEmpty()) { params << "annotate" << "--" << currentFile.mid(2); //Jump over status marker characters (e.g "M ") - runner->requestAction(HgAction(ACT_ANNOTATE, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_ANNOTATE, m_workFolderPath, params)); } } @@ -362,7 +375,7 @@ QStringList params; params << "resolve" << "--list"; - runner->requestAction(HgAction(ACT_RESOLVE_LIST, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_RESOLVE_LIST, m_workFolderPath, params)); } void MainWindow::hgAdd() @@ -372,11 +385,11 @@ // hgExplorer permitted adding "all" files -- I'm not sure // that one is a good idea, let's require the user to select - QStringList files = hgTabs->getSelectedAddableFiles(); + QStringList files = m_hgTabs->getSelectedAddableFiles(); if (!files.empty()) { params << "add" << "--" << files; - runner->requestAction(HgAction(ACT_ADD, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_ADD, m_workFolderPath, params)); } } @@ -385,11 +398,11 @@ { QStringList params; - QStringList files = hgTabs->getSelectedRemovableFiles(); + QStringList files = m_hgTabs->getSelectedRemovableFiles(); if (!files.empty()) { params << "remove" << "--after" << "--force" << "--" << files; - runner->requestAction(HgAction(ACT_REMOVE, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_REMOVE, m_workFolderPath, params)); } } @@ -398,12 +411,12 @@ QStringList params; QString comment; - if (justMerged) { - comment = mergeCommitComment; + if (m_justMerged) { + comment = m_mergeCommitComment; } - QStringList files = hgTabs->getSelectedCommittableFiles(); - QStringList allFiles = hgTabs->getAllCommittableFiles(); + QStringList files = m_hgTabs->getSelectedCommittableFiles(); + QStringList allFiles = m_hgTabs->getAllCommittableFiles(); QStringList reportFiles = files; if (reportFiles.empty()) { reportFiles = allFiles; @@ -429,7 +442,7 @@ comment, tr("Commit"))) { - if (!justMerged && !files.empty()) { + if (!m_justMerged && !files.empty()) { // User wants to commit selected file(s) (and this is not // merge commit, which would fail if we selected files) params << "commit" << "--message" << comment @@ -440,8 +453,8 @@ << "--user" << getUserInfo(); } - runner->requestAction(HgAction(ACT_COMMIT, workFolderPath, params)); - mergeCommitComment = ""; + m_runner->requestAction(HgAction(ACT_COMMIT, m_workFolderPath, params)); + m_mergeCommitComment = ""; } } @@ -473,7 +486,7 @@ if (!branch.isEmpty()) {//!!! do something better if it is empty params << "branch" << filterTag(branch); - runner->requestAction(HgAction(ACT_NEW_BRANCH, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_NEW_BRANCH, m_workFolderPath, params)); } } } @@ -495,7 +508,7 @@ params << "tag" << "--user" << getUserInfo(); params << "--rev" << Changeset::hashOf(id) << filterTag(tag); - runner->requestAction(HgAction(ACT_TAG, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_TAG, m_workFolderPath, params)); } } } @@ -506,10 +519,10 @@ QString hgIgnorePath; QStringList params; - hgIgnorePath = workFolderPath; + hgIgnorePath = m_workFolderPath; hgIgnorePath += "/.hgignore"; - if (!QDir(workFolderPath).exists()) return; + if (!QDir(m_workFolderPath).exists()) return; QFile f(hgIgnorePath); if (!f.exists()) { f.open(QFile::WriteOnly); @@ -529,10 +542,10 @@ return; } - HgAction action(ACT_HG_IGNORE, workFolderPath, params); + HgAction action(ACT_HG_IGNORE, m_workFolderPath, params); action.executable = editor; - runner->requestAction(action); + m_runner->requestAction(action); } QString MainWindow::getDiffBinaryName() @@ -562,7 +575,7 @@ params << "diff" << "--stat"; - runner->requestAction(HgAction(ACT_DIFF_SUMMARY, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_UNCOMMITTED_SUMMARY, m_workFolderPath, params)); } void MainWindow::hgFolderDiff() @@ -577,9 +590,9 @@ params << "--config" << "extensions.extdiff=" << "extdiff"; params << "--program" << diff; - params << hgTabs->getSelectedCommittableFiles(); // may be none: whole dir - - runner->requestAction(HgAction(ACT_FOLDERDIFF, workFolderPath, params)); + params << m_hgTabs->getSelectedCommittableFiles(); // may be none: whole dir + + m_runner->requestAction(HgAction(ACT_FOLDERDIFF, m_workFolderPath, params)); } @@ -596,7 +609,7 @@ params << "--program" << diff; params << "--rev" << Changeset::hashOf(id); - runner->requestAction(HgAction(ACT_FOLDERDIFF, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_FOLDERDIFF, m_workFolderPath, params)); } @@ -607,14 +620,28 @@ QStringList params; - // Diff given revision against working folder + // Diff given revision against parent revision params << "--config" << "extensions.extdiff=" << "extdiff"; params << "--program" << diff; params << "--rev" << Changeset::hashOf(parent) << "--rev" << Changeset::hashOf(child); - runner->requestAction(HgAction(ACT_CHGSETDIFF, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_CHGSETDIFF, m_workFolderPath, params)); +} + + +void MainWindow::hgShowSummaryFor(Changeset *cs) +{ + QStringList params; + + // This will pick a default parent if there is more than one + // (whereas with diff we need to supply one). But it does need a + // bit more parsing + params << "log" << "--stat" << "--rev" << Changeset::hashOf(cs->id()); + + m_runner->requestAction(HgAction(ACT_DIFF_SUMMARY, m_workFolderPath, + params, cs)); } @@ -624,7 +651,7 @@ params << "update"; - runner->requestAction(HgAction(ACT_UPDATE, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_UPDATE, m_workFolderPath, params)); } @@ -634,7 +661,7 @@ params << "update" << "--rev" << Changeset::hashOf(id) << "--check"; - runner->requestAction(HgAction(ACT_UPDATE, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_UPDATE, m_workFolderPath, params)); } @@ -644,8 +671,8 @@ QString comment; bool all = false; - QStringList files = hgTabs->getSelectedRevertableFiles(); - QStringList allFiles = hgTabs->getAllRevertableFiles(); + QStringList files = m_hgTabs->getSelectedRevertableFiles(); + QStringList allFiles = m_hgTabs->getAllRevertableFiles(); if (files.empty() || files == allFiles) { files = allFiles; all = true; @@ -661,9 +688,9 @@ // Set up params before asking for confirmation, because there is // a failure case here that we would need to report on early - DEBUG << "hgRevert: justMerged = " << justMerged << ", mergeTargetRevision = " << mergeTargetRevision << endl; - - if (justMerged) { + DEBUG << "hgRevert: m_justMerged = " << m_justMerged << ", m_mergeTargetRevision = " << m_mergeTargetRevision << endl; + + if (m_justMerged) { // This is a little fiddly. The proper way to "revert" the // whole of an uncommitted merge is with "hg update --clean ." @@ -677,9 +704,9 @@ if (all) { params << "update" << "--clean" << "."; } else { - if (mergeTargetRevision != "") { + if (m_mergeTargetRevision != "") { params << "revert" << "--rev" - << Changeset::hashOf(mergeTargetRevision) + << Changeset::hashOf(m_mergeTargetRevision) << "--" << files; } else { QMessageBox::information @@ -704,9 +731,9 @@ files, tr("Revert"))) { - lastRevertedFiles = files; + m_lastRevertedFiles = files; - runner->requestAction(HgAction(ACT_REVERT, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_REVERT, m_workFolderPath, params)); } } @@ -723,7 +750,7 @@ params << "--" << files; } - runner->requestAction(HgAction(ACT_RESOLVE_MARK, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_RESOLVE_MARK, m_workFolderPath, params)); } @@ -738,26 +765,26 @@ params << "--tool" << merge; } - QStringList files = hgTabs->getSelectedUnresolvedFiles(); + QStringList files = m_hgTabs->getSelectedUnresolvedFiles(); if (files.empty()) { params << "--all"; } else { params << "--" << files; } - if (currentParents.size() == 1) { - mergeTargetRevision = currentParents[0]->id(); + if (m_currentParents.size() == 1) { + m_mergeTargetRevision = m_currentParents[0]->id(); } - runner->requestAction(HgAction(ACT_RETRY_MERGE, workFolderPath, params)); - - mergeCommitComment = tr("Merge"); + m_runner->requestAction(HgAction(ACT_RETRY_MERGE, m_workFolderPath, params)); + + m_mergeCommitComment = tr("Merge"); } void MainWindow::hgMerge() { - if (hgTabs->canResolve()) { + if (m_hgTabs->canResolve()) { hgRetryMerge(); return; } @@ -771,13 +798,13 @@ params << "--tool" << merge; } - if (currentParents.size() == 1) { - mergeTargetRevision = currentParents[0]->id(); + if (m_currentParents.size() == 1) { + m_mergeTargetRevision = m_currentParents[0]->id(); } - runner->requestAction(HgAction(ACT_MERGE, workFolderPath, params)); - - mergeCommitComment = tr("Merge"); + m_runner->requestAction(HgAction(ACT_MERGE, m_workFolderPath, params)); + + m_mergeCommitComment = tr("Merge"); } @@ -793,26 +820,26 @@ params << "--tool" << merge; } - if (currentParents.size() == 1) { - mergeTargetRevision = currentParents[0]->id(); + if (m_currentParents.size() == 1) { + m_mergeTargetRevision = m_currentParents[0]->id(); } - runner->requestAction(HgAction(ACT_MERGE, workFolderPath, params)); - - mergeCommitComment = ""; - - foreach (Changeset *cs, currentHeads) { - if (cs->id() == id && !cs->isOnBranch(currentBranch)) { + m_runner->requestAction(HgAction(ACT_MERGE, m_workFolderPath, params)); + + m_mergeCommitComment = ""; + + foreach (Changeset *cs, m_currentHeads) { + if (cs->id() == id && !cs->isOnBranch(m_currentBranch)) { if (cs->branch() == "" || cs->branch() == "default") { - mergeCommitComment = tr("Merge from the default branch"); + m_mergeCommitComment = tr("Merge from the default branch"); } else { - mergeCommitComment = tr("Merge from branch \"%1\"").arg(cs->branch()); + m_mergeCommitComment = tr("Merge from branch \"%1\"").arg(cs->branch()); } } } - if (mergeCommitComment == "") { - mergeCommitComment = tr("Merge from %1").arg(id); + if (m_mergeCommitComment == "") { + m_mergeCommitComment = tr("Merge from %1").arg(id); } } @@ -821,21 +848,21 @@ { QStringList params; - if (!QDir(workFolderPath).exists()) { - if (!QDir().mkpath(workFolderPath)) { + if (!QDir(m_workFolderPath).exists()) { + if (!QDir().mkpath(m_workFolderPath)) { DEBUG << "hgCloneFromRemote: Failed to create target path " - << workFolderPath << endl; + << m_workFolderPath << endl; //!!! report error return; } } - params << "clone" << remoteRepoPath << workFolderPath; + params << "clone" << m_remoteRepoPath << m_workFolderPath; - hgTabs->setWorkFolderAndRepoNames(workFolderPath, remoteRepoPath); - hgTabs->updateWorkFolderFileList(""); - - runner->requestAction(HgAction(ACT_CLONEFROMREMOTE, workFolderPath, params)); + updateWorkFolderAndRepoNames(); + m_hgTabs->updateWorkFolderFileList(""); + + m_runner->requestAction(HgAction(ACT_CLONEFROMREMOTE, m_workFolderPath, params)); } void MainWindow::hgInit() @@ -843,33 +870,32 @@ QStringList params; params << "init"; - params << workFolderPath; - - runner->requestAction(HgAction(ACT_INIT, workFolderPath, params)); + params << m_workFolderPath; + + m_runner->requestAction(HgAction(ACT_INIT, m_workFolderPath, params)); } void MainWindow::hgIncoming() { QStringList params; - params << "incoming" << "--newest-first" << remoteRepoPath; + params << "incoming" << "--newest-first" << m_remoteRepoPath; params << "--template" << Changeset::getLogTemplate(); - runner->requestAction(HgAction(ACT_INCOMING, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_INCOMING, m_workFolderPath, params)); } void MainWindow::hgPull() { if (ConfirmCommentDialog::confirm (this, tr("Confirm pull"), - format3(tr("Confirm pull from remote repository"), - tr("You are about to pull changes from the following remote repository:"), - remoteRepoPath), + tr("<qt><h3>Pull from remote repository?</h3></qt>"), + tr("<qt><p>You are about to pull changes from the remote repository at <code>%1</code>.</p></qt>").arg(xmlEncode(m_remoteRepoPath)), tr("Pull"))) { QStringList params; - params << "pull" << remoteRepoPath; - runner->requestAction(HgAction(ACT_PULL, workFolderPath, params)); + params << "pull" << m_remoteRepoPath; + m_runner->requestAction(HgAction(ACT_PULL, m_workFolderPath, params)); } } @@ -877,14 +903,13 @@ { if (ConfirmCommentDialog::confirm (this, tr("Confirm push"), - format3(tr("Confirm push to remote repository"), - tr("You are about to push your changes to the following remote repository:"), - remoteRepoPath), + tr("<qt><h3>Push to remote repository?</h3></qt>"), + tr("<qt><p>You are about to push your changes to the remote repository at <code>%1</code>.</p></qt>").arg(xmlEncode(m_remoteRepoPath)), tr("Push"))) { QStringList params; - params << "push" << "--new-branch" << remoteRepoPath; - runner->requestAction(HgAction(ACT_PUSH, workFolderPath, params)); + params << "push" << "--new-branch" << m_remoteRepoPath; + m_runner->requestAction(HgAction(ACT_PUSH, m_workFolderPath, params)); } } @@ -910,24 +935,25 @@ void MainWindow::clearState() { - foreach (Changeset *cs, currentParents) delete cs; - currentParents.clear(); - foreach (Changeset *cs, currentHeads) delete cs; - currentHeads.clear(); - currentBranch = ""; - lastStatOutput = ""; - lastRevertedFiles.clear(); - mergeTargetRevision = ""; - mergeCommitComment = ""; - stateUnknown = true; - needNewLog = true; - if (fsWatcher) { + DEBUG << "MainWindow::clearState" << endl; + foreach (Changeset *cs, m_currentParents) delete cs; + m_currentParents.clear(); + foreach (Changeset *cs, m_currentHeads) delete cs; + m_currentHeads.clear(); + m_currentBranch = ""; + m_lastStatOutput = ""; + m_lastRevertedFiles.clear(); + m_mergeTargetRevision = ""; + m_mergeCommitComment = ""; + m_stateUnknown = true; + m_needNewLog = true; + if (m_fsWatcher) { delete m_fsWatcherGeneralTimer; m_fsWatcherGeneralTimer = 0; delete m_fsWatcherRestoreTimer; m_fsWatcherRestoreTimer = 0; - delete fsWatcher; - fsWatcher = 0; + delete m_fsWatcher; + m_fsWatcher = 0; } } @@ -957,17 +983,17 @@ params << "serve"; - runner->requestAction(HgAction(ACT_SERVE, workFolderPath, params)); + m_runner->requestAction(HgAction(ACT_SERVE, m_workFolderPath, params)); QMessageBox::information(this, tr("Serve"), msg, QMessageBox::Close); - runner->killCurrentActions(); + m_runner->killCurrentActions(); } void MainWindow::startupDialog() { StartupDialog *dlg = new StartupDialog(this); - if (dlg->exec()) firstStart = false; + if (dlg->exec()) m_firstStart = false; } void MainWindow::open() @@ -1045,13 +1071,13 @@ { // This will involve rewriting the local .hgrc - QDir hgDir(workFolderPath + "/.hg"); + QDir hgDir(m_workFolderPath + "/.hg"); if (!hgDir.exists()) { //!!! visible error! return; } - QFileInfo hgrc(workFolderPath + "/.hg/hgrc"); + QFileInfo hgrc(m_workFolderPath + "/.hg/hgrc"); if (hgrc.exists() && !hgrc.isWritable()) { //!!! visible error! return; @@ -1080,7 +1106,7 @@ s.setValue("default", d->getArgument()); } - stateUnknown = true; + m_stateUnknown = true; hgQueryPaths(); } @@ -1298,8 +1324,8 @@ return complainAboutFilePath(local); } - workFolderPath = local; - remoteRepoPath = ""; + m_workFolderPath = local; + m_remoteRepoPath = ""; return true; } @@ -1331,8 +1357,8 @@ if (local == "") return false; } - workFolderPath = local; - remoteRepoPath = remote; + m_workFolderPath = local; + m_remoteRepoPath = remote; hgCloneFromRemote(); return true; @@ -1363,8 +1389,8 @@ return complainAboutUnknownFolder(local); } - workFolderPath = local; - remoteRepoPath = ""; + m_workFolderPath = local; + m_remoteRepoPath = ""; hgInit(); return true; } @@ -1375,7 +1401,7 @@ settingsDlg->exec(); if (settingsDlg->presentationChanged()) { - hgTabs->updateFileStates(); + m_hgTabs->updateFileStates(); updateToolBarStyle(); hgRefresh(); } @@ -1427,8 +1453,8 @@ void MainWindow::updateFileSystemWatcher() { bool justCreated = false; - if (!fsWatcher) { - fsWatcher = new QFileSystemWatcher(); + if (!m_fsWatcher) { + m_fsWatcher = new QFileSystemWatcher(); justCreated = true; } @@ -1438,18 +1464,18 @@ // annoying because it would be the normal case for us. So we'll // check for duplicates ourselves. QSet<QString> alreadyWatched; - QStringList dl(fsWatcher->directories()); + QStringList dl(m_fsWatcher->directories()); foreach (QString d, dl) alreadyWatched.insert(d); std::deque<QString> pending; - pending.push_back(workFolderPath); + pending.push_back(m_workFolderPath); while (!pending.empty()) { QString path = pending.front(); pending.pop_front(); if (!alreadyWatched.contains(path)) { - fsWatcher->addPath(path); + m_fsWatcher->addPath(path); DEBUG << "Added to file system watcher: " << path << endl; } @@ -1476,9 +1502,9 @@ m_fsWatcherGeneralTimer->start(); if (justCreated) { - connect(fsWatcher, SIGNAL(directoryChanged(QString)), + connect(m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(fsDirectoryChanged(QString))); - connect(fsWatcher, SIGNAL(fileChanged(QString)), + connect(m_fsWatcher, SIGNAL(fileChanged(QString)), this, SLOT(fsFileChanged(QString))); } } @@ -1486,7 +1512,7 @@ void MainWindow::suspendFileSystemWatcher() { DEBUG << "MainWindow::suspendFileSystemWatcher" << endl; - if (fsWatcher) { + if (m_fsWatcher) { m_fsWatcherSuspended = true; if (m_fsWatcherRestoreTimer) { delete m_fsWatcherRestoreTimer; @@ -1518,7 +1544,7 @@ void MainWindow::actuallyRestoreFileSystemWatcher() { DEBUG << "MainWindow::actuallyRestoreFileSystemWatcher" << endl; - if (fsWatcher) { + if (m_fsWatcher) { m_fsWatcherSuspended = false; m_fsWatcherGeneralTimer->start(); } @@ -1546,6 +1572,11 @@ } } +QString MainWindow::format1(QString head) +{ + return QString("<qt><h3>%1</h3></qt>").arg(head); +} + QString MainWindow::format3(QString head, QString intro, QString code) { code = xmlEncode(code).replace("\n", "<br>") @@ -1568,7 +1599,7 @@ void MainWindow::showIncoming(QString output) { - runner->hide(); + m_runner->hide(); IncomingDialog *d = new IncomingDialog(this, output); d->exec(); delete d; @@ -1588,72 +1619,82 @@ void MainWindow::showPushResult(QString output) { + QString head; QString report; int n = extractChangeCount(output); if (n > 0) { - report = tr("Pushed %n changeset(s)", "", n); + head = tr("Pushed %n changeset(s)", "", n); + report = tr("<qt>Successfully pushed to the remote repository at <code>%1</code>.</qt>").arg(xmlEncode(m_remoteRepoPath)); } else if (n == 0) { - report = tr("No changes to push"); + head = tr("No changes to push"); + report = tr("The remote repository already contains all changes that have been committed locally."); + if (m_hgTabs->canCommit()) { + report = tr("%1<p>You do have some uncommitted changes. If you wish to push those to the remote repository, commit them locally first.").arg(report); + } } else { - report = tr("Push complete"); + head = tr("Push complete"); } - report = format3(report, tr("The push command output was:"), output); - runner->hide(); - QMessageBox::information(this, "Push complete", report); + m_runner->hide(); + + MoreInformationDialog::information(this, tr("Push complete"), + head, report, output); } void MainWindow::showPullResult(QString output) { + QString head; QString report; int n = extractChangeCount(output); if (n > 0) { - report = tr("Pulled %n changeset(s)", "", n); + head = tr("Pulled %n changeset(s)", "", n); + report = tr("The new changes will be highlighted in the history.<br>Use Update to bring these changes into your working copy."); } else if (n == 0) { - report = tr("No changes to pull"); + head = tr("No changes to pull"); + report = tr("Your local repository already contains all changes found in the remote repository."); } else { - report = tr("Pull complete"); + head = tr("Pull complete"); } - report = format3(report, tr("The pull command output was:"), output); - runner->hide(); - - //!!! and something about updating - - QMessageBox::information(this, "Pull complete", report); + m_runner->hide(); + + MoreInformationDialog::information(this, tr("Pull complete"), + head, report, output); } void MainWindow::reportNewRemoteHeads(QString output) { bool headsAreLocal = false; - if (currentParents.size() == 1) { - int currentBranchHeads = 0; + if (m_currentParents.size() == 1) { + int m_currentBranchHeads = 0; bool parentIsHead = false; - Changeset *parent = currentParents[0]; - foreach (Changeset *head, currentHeads) { - if (head->isOnBranch(currentBranch)) { - ++currentBranchHeads; + Changeset *parent = m_currentParents[0]; + foreach (Changeset *head, m_currentHeads) { + if (head->isOnBranch(m_currentBranch)) { + ++m_currentBranchHeads; } if (parent->id() == head->id()) { parentIsHead = true; } } - if (currentBranchHeads == 2 && parentIsHead) { + if (m_currentBranchHeads == 2 && parentIsHead) { headsAreLocal = true; } } if (headsAreLocal) { - QMessageBox::warning - (this, tr("Push failed"), - format3(tr("Push failed"), - tr("Your local repository could not be pushed to the remote repository.<br><br>You may need to merge the changes locally first.<br><br>The output of the push command was:"), - output)); + MoreInformationDialog::warning + (this, + tr("Push failed"), + tr("Push failed"), + tr("Your local repository could not be pushed to the remote repository.<br><br>You may need to merge the changes locally first."), + output); } else { - QMessageBox::warning - (this, tr("Push failed"), - format3(tr("Push failed"), - 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:"), - output)); + MoreInformationDialog::warning + (this, + tr("Push failed"), + tr("Push failed"), + 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."), + output); } } @@ -1689,33 +1730,32 @@ // uh huh return; case ACT_TEST_HG: - QMessageBox::warning - (this, tr("Failed to run Mercurial"), - format3(tr("Failed to run Mercurial"), - tr("The Mercurial program either could not be found or failed to run.<br>Check that the Mercurial program path is correct in %1.<br><br>%2").arg(setstr).arg(output == "" ? QString("") : tr("The test command said:")), - output)); + MoreInformationDialog::warning + (this, + tr("Failed to run Mercurial"), + tr("Failed to run Mercurial"), + tr("The Mercurial program either could not be found or failed to run.<br>Check that the Mercurial program path is correct in %1.").arg(setstr), + output); settings(); return; case ACT_TEST_HG_EXT: QMessageBox::warning - (this, tr("Failed to run Mercurial"), - format3(tr("Failed to run Mercurial with extension enabled"), - tr("The Mercurial program failed to run with the EasyMercurial interaction extension enabled.<br>This may indicate an installation problem with EasyMercurial.<br><br>You may be able to continue working if you switch off “Use EasyHg Mercurial Extension” in %1. Note that remote repositories that require authentication may not work if you do this.<br><br>%2").arg(setstr).arg(output == "" ? QString("") : tr("The test command said:")), - output)); + (this, + tr("Failed to run Mercurial"), + tr("Failed to run Mercurial with extension enabled"), + tr("The Mercurial program failed to run with the EasyMercurial interaction extension enabled.<br>This may indicate an installation problem with EasyMercurial.<br><br>You may be able to continue working if you switch off “Use EasyHg Mercurial Extension” in %1. Note that remote repositories that require authentication may not work if you do this.").arg(setstr), + output); settings(); return; case ACT_CLONEFROMREMOTE: // if clone fails, we have no repo - workFolderPath = ""; + m_workFolderPath = ""; enableDisableActions(); break; case ACT_INCOMING: // returns non-zero code and no output if the check was // successful but there are no changes pending - - //!!! -- won't do, there may legitimately be warnings, - //!!! -- e.g. certificate not verified - if (output.trimmed() == "") { + if (output.replace(QRegExp("(^|\\n)warning: [^\\n]*\\n"), "").trimmed() == "") { showIncoming(""); return; } @@ -1750,6 +1790,8 @@ command += " " + arg; } + //!!! + QString message = tr("<qt><h3>Command failed</h3>" "<p>The following command failed:</p>" "<code>%1</code>" @@ -1789,23 +1831,23 @@ LogList ll = lp.parse(); DEBUG << ll.size() << " results" << endl; if (!ll.empty()) { - remoteRepoPath = lp.parse()[0]["default"].trimmed(); - DEBUG << "Set remote path to " << remoteRepoPath << endl; + m_remoteRepoPath = lp.parse()[0]["default"].trimmed(); + DEBUG << "Set remote path to " << m_remoteRepoPath << endl; } else { - remoteRepoPath = ""; + m_remoteRepoPath = ""; } - MultiChoiceDialog::addRecentArgument("local", workFolderPath); - MultiChoiceDialog::addRecentArgument("remote", remoteRepoPath); - hgTabs->setWorkFolderAndRepoNames(workFolderPath, remoteRepoPath); + MultiChoiceDialog::addRecentArgument("local", m_workFolderPath); + MultiChoiceDialog::addRecentArgument("remote", m_remoteRepoPath); + updateWorkFolderAndRepoNames(); break; } case ACT_QUERY_BRANCH: - currentBranch = output.trimmed(); + m_currentBranch = output.trimmed(); break; case ACT_STAT: - lastStatOutput = output; + m_lastStatOutput = output; updateFileSystemWatcher(); break; @@ -1820,13 +1862,13 @@ } output = winnowed.join("\n"); } - DEBUG << "lastStatOutput = " << lastStatOutput << endl; + DEBUG << "m_lastStatOutput = " << m_lastStatOutput << endl; DEBUG << "resolve output = " << output << endl; - hgTabs->updateWorkFolderFileList(lastStatOutput + output); + m_hgTabs->updateWorkFolderFileList(m_lastStatOutput + output); break; case ACT_RESOLVE_MARK: - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_INCOMING: @@ -1835,12 +1877,12 @@ case ACT_ANNOTATE: presentLongStdoutToUser(output); - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_PULL: showPullResult(output); - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_PUSH: @@ -1848,111 +1890,149 @@ break; case ACT_INIT: - MultiChoiceDialog::addRecentArgument("init", workFolderPath); - MultiChoiceDialog::addRecentArgument("local", workFolderPath); + MultiChoiceDialog::addRecentArgument("init", m_workFolderPath); + MultiChoiceDialog::addRecentArgument("local", m_workFolderPath); enableDisableActions(); - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_CLONEFROMREMOTE: - MultiChoiceDialog::addRecentArgument("local", workFolderPath); - MultiChoiceDialog::addRecentArgument("remote", remoteRepoPath); - MultiChoiceDialog::addRecentArgument("remote", workFolderPath, true); - QMessageBox::information(this, tr("Clone"), tr("<qt><h3>Clone successful</h3><pre>%1</pre>").arg(xmlEncode(output))); + MultiChoiceDialog::addRecentArgument("local", m_workFolderPath); + MultiChoiceDialog::addRecentArgument("remote", m_remoteRepoPath); + MultiChoiceDialog::addRecentArgument("remote", m_workFolderPath, true); + MoreInformationDialog::information + (this, + tr("Clone"), + tr("Clone successful"), + tr("The remote repository was successfully cloned to the local folder <code>%1</code>.").arg(xmlEncode(m_workFolderPath)), + output); enableDisableActions(); - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_LOG: - hgTabs->setNewLog(output); - needNewLog = false; + m_hgTabs->setNewLog(output); + m_needNewLog = false; break; case ACT_LOG_INCREMENTAL: - hgTabs->addIncrementalLog(output); + m_hgTabs->addIncrementalLog(output); break; case ACT_QUERY_PARENTS: { - foreach (Changeset *cs, currentParents) delete cs; - currentParents = Changeset::parseChangesets(output); - QStringList parentIds = Changeset::getIds(currentParents); - hgTabs->setCurrent(parentIds, currentBranch); + foreach (Changeset *cs, m_currentParents) delete cs; + m_currentParents = Changeset::parseChangesets(output); + QStringList parentIds = Changeset::getIds(m_currentParents); + m_hgTabs->setCurrent(parentIds, m_currentBranch); } break; case ACT_QUERY_HEADS: { - oldHeadIds = Changeset::getIds(currentHeads); + oldHeadIds = Changeset::getIds(m_currentHeads); Changesets newHeads = Changeset::parseChangesets(output); QStringList newHeadIds = Changeset::getIds(newHeads); if (oldHeadIds != newHeadIds) { DEBUG << "Heads changed, will prompt an incremental log if appropriate" << endl; + DEBUG << "Old heads: " << oldHeadIds.join(",") << endl; + DEBUG << "New heads: " << newHeadIds.join(",") << endl; headsChanged = true; - foreach (Changeset *cs, currentHeads) delete cs; - currentHeads = newHeads; + foreach (Changeset *cs, m_currentHeads) delete cs; + m_currentHeads = newHeads; } } break; case ACT_COMMIT: - hgTabs->clearSelections(); - justMerged = false; - shouldHgStat = true; + m_hgTabs->clearSelections(); + m_justMerged = false; + m_shouldHgStat = true; break; case ACT_REVERT: - hgMarkResolved(lastRevertedFiles); - justMerged = false; + hgMarkResolved(m_lastRevertedFiles); + m_justMerged = false; break; case ACT_REMOVE: case ACT_ADD: - hgTabs->clearSelections(); - shouldHgStat = true; + m_hgTabs->clearSelections(); + m_shouldHgStat = true; break; case ACT_TAG: - needNewLog = true; - shouldHgStat = true; + m_needNewLog = true; + m_shouldHgStat = true; break; case ACT_NEW_BRANCH: - shouldHgStat = true; - hgTabs->showWorkTab(); + m_shouldHgStat = true; + m_hgTabs->showWorkTab(); break; - case ACT_DIFF_SUMMARY: + case ACT_UNCOMMITTED_SUMMARY: QMessageBox::information(this, tr("Change summary"), format3(tr("Summary of uncommitted changes"), "", output)); break; + case ACT_DIFF_SUMMARY: + { + // Output has log info first, diff following after a blank line + output.replace("\r\n", "\n"); + QStringList olist = output.split("\n\n", QString::SkipEmptyParts); + if (olist.size() > 1) output = olist[1]; + + Changeset *cs = (Changeset *)completedAction.extraData; + if (cs) { + QMessageBox::information + (this, tr("Change summary"), + format3(tr("Summary of changes"), + cs->formatHtml(), + output)); + } else if (output == "") { + // Can happen, for a merge commit (depending on parent) + QMessageBox::information(this, tr("Change summary"), + format3(tr("Summary of changes"), + tr("No changes"), + output)); + } else { + QMessageBox::information(this, tr("Change summary"), + format3(tr("Summary of changes"), + "", + output)); + } + break; + } + case ACT_FOLDERDIFF: case ACT_CHGSETDIFF: case ACT_SERVE: case ACT_HG_IGNORE: - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_UPDATE: QMessageBox::information(this, tr("Update"), tr("<qt><h3>Update successful</h3><p>%1</p>").arg(xmlEncode(output))); - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_MERGE: - //!!! use format3? - QMessageBox::information(this, tr("Merge"), tr("<qt><h3>Merge successful</h3><pre>%1</pre>").arg(xmlEncode(output))); - shouldHgStat = true; - justMerged = true; + MoreInformationDialog::information + (this, tr("Merge"), tr("Merge successful"), + tr("Remember to test and commit the result before making any further changes."), + output); + m_shouldHgStat = true; + m_justMerged = true; break; case ACT_RETRY_MERGE: QMessageBox::information(this, tr("Resolved"), - tr("<qt><h3>Merge resolved</h3><p>Merge resolved successfully.</p>")); - shouldHgStat = true; - justMerged = true; + tr("<qt><h3>Merge resolved</h3><p>Merge resolved successfully.<br>Remember to test and commit the result before making any further changes.</p>")); + m_shouldHgStat = true; + m_justMerged = true; break; default: @@ -1979,7 +2059,7 @@ settings.beginGroup("General"); if (settings.value("useextension", true).toBool()) { hgTestExtension(); - } else if (workFolderPath == "") { + } else if (m_workFolderPath == "") { open(); } else { hgQueryPaths(); @@ -1988,7 +2068,7 @@ } case ACT_TEST_HG_EXT: - if (workFolderPath == "") { + if (m_workFolderPath == "") { open(); } else{ hgQueryPaths(); @@ -2012,7 +2092,7 @@ break; case ACT_QUERY_HEADS: - if (headsChanged && !needNewLog) { + if (headsChanged && !m_needNewLog) { hgLogIncremental(oldHeadIds); } else { hgQueryParents(); @@ -2024,7 +2104,7 @@ break; case ACT_QUERY_PARENTS: - if (needNewLog) { + if (m_needNewLog) { hgLog(); } else { // we're done @@ -2038,8 +2118,8 @@ break; default: - if (shouldHgStat) { - shouldHgStat = false; + if (m_shouldHgStat) { + m_shouldHgStat = false; hgQueryPaths(); } else { noMore = true; @@ -2048,69 +2128,72 @@ } if (noMore) { - stateUnknown = false; + m_stateUnknown = false; enableDisableActions(); - hgTabs->updateHistory(); + m_hgTabs->updateHistory(); } } void MainWindow::connectActions() { - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - - connect(hgRefreshAct, SIGNAL(triggered()), this, SLOT(hgRefresh())); - connect(hgRemoveAct, SIGNAL(triggered()), this, SLOT(hgRemove())); - connect(hgAddAct, SIGNAL(triggered()), this, SLOT(hgAdd())); - connect(hgCommitAct, SIGNAL(triggered()), this, SLOT(hgCommit())); - connect(hgFolderDiffAct, SIGNAL(triggered()), this, SLOT(hgFolderDiff())); - connect(hgUpdateAct, SIGNAL(triggered()), this, SLOT(hgUpdate())); - connect(hgRevertAct, SIGNAL(triggered()), this, SLOT(hgRevert())); - connect(hgMergeAct, SIGNAL(triggered()), this, SLOT(hgMerge())); - connect(hgIgnoreAct, SIGNAL(triggered()), this, SLOT(hgIgnore())); - - connect(settingsAct, SIGNAL(triggered()), this, SLOT(settings())); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); - connect(changeRemoteRepoAct, SIGNAL(triggered()), this, SLOT(changeRemoteRepo())); - - connect(hgIncomingAct, SIGNAL(triggered()), this, SLOT(hgIncoming())); - connect(hgPullAct, SIGNAL(triggered()), this, SLOT(hgPull())); - connect(hgPushAct, SIGNAL(triggered()), this, SLOT(hgPush())); - - connect(hgAnnotateAct, SIGNAL(triggered()), this, SLOT(hgAnnotate())); - connect(hgServeAct, SIGNAL(triggered()), this, SLOT(hgServe())); + connect(m_exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(m_aboutAct, SIGNAL(triggered()), this, SLOT(about())); + + connect(m_hgRefreshAct, SIGNAL(triggered()), this, SLOT(hgRefresh())); + connect(m_hgRemoveAct, SIGNAL(triggered()), this, SLOT(hgRemove())); + connect(m_hgAddAct, SIGNAL(triggered()), this, SLOT(hgAdd())); + connect(m_hgCommitAct, SIGNAL(triggered()), this, SLOT(hgCommit())); + connect(m_hgFolderDiffAct, SIGNAL(triggered()), this, SLOT(hgFolderDiff())); + connect(m_hgUpdateAct, SIGNAL(triggered()), this, SLOT(hgUpdate())); + connect(m_hgRevertAct, SIGNAL(triggered()), this, SLOT(hgRevert())); + connect(m_hgMergeAct, SIGNAL(triggered()), this, SLOT(hgMerge())); + connect(m_hgIgnoreAct, SIGNAL(triggered()), this, SLOT(hgIgnore())); + + connect(m_settingsAct, SIGNAL(triggered()), this, SLOT(settings())); + connect(m_openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(m_changeRemoteRepoAct, SIGNAL(triggered()), this, SLOT(changeRemoteRepo())); + + connect(m_hgIncomingAct, SIGNAL(triggered()), this, SLOT(hgIncoming())); + connect(m_hgPullAct, SIGNAL(triggered()), this, SLOT(hgPull())); + connect(m_hgPushAct, SIGNAL(triggered()), this, SLOT(hgPush())); + + connect(m_hgAnnotateAct, SIGNAL(triggered()), this, SLOT(hgAnnotate())); + connect(m_hgServeAct, SIGNAL(triggered()), this, SLOT(hgServe())); } void MainWindow::connectTabsSignals() { - connect(hgTabs, SIGNAL(commit()), + connect(m_hgTabs, SIGNAL(commit()), this, SLOT(hgCommit())); - connect(hgTabs, SIGNAL(revert()), + connect(m_hgTabs, SIGNAL(revert()), this, SLOT(hgRevert())); - connect(hgTabs, SIGNAL(diffWorkingFolder()), + connect(m_hgTabs, SIGNAL(diffWorkingFolder()), this, SLOT(hgFolderDiff())); - connect(hgTabs, SIGNAL(showSummary()), + connect(m_hgTabs, SIGNAL(showSummary()), this, SLOT(hgShowSummary())); - connect(hgTabs, SIGNAL(updateTo(QString)), + connect(m_hgTabs, SIGNAL(updateTo(QString)), this, SLOT(hgUpdateToRev(QString))); - connect(hgTabs, SIGNAL(diffToCurrent(QString)), + connect(m_hgTabs, SIGNAL(diffToCurrent(QString)), this, SLOT(hgDiffToCurrent(QString))); - connect(hgTabs, SIGNAL(diffToParent(QString, QString)), + connect(m_hgTabs, SIGNAL(diffToParent(QString, QString)), this, SLOT(hgDiffToParent(QString, QString))); - connect(hgTabs, SIGNAL(mergeFrom(QString)), + connect(m_hgTabs, SIGNAL(showSummary(Changeset *)), + this, SLOT(hgShowSummaryFor(Changeset *))); + + connect(m_hgTabs, SIGNAL(mergeFrom(QString)), this, SLOT(hgMergeFrom(QString))); - connect(hgTabs, SIGNAL(newBranch(QString)), + connect(m_hgTabs, SIGNAL(newBranch(QString)), this, SLOT(hgNewBranch(QString))); - connect(hgTabs, SIGNAL(tag(QString)), + connect(m_hgTabs, SIGNAL(tag(QString)), this, SLOT(hgTag(QString))); } @@ -2118,7 +2201,7 @@ { DEBUG << "MainWindow::enableDisableActions" << endl; - QString dirname = QDir(workFolderPath).dirName(); + QString dirname = QDir(m_workFolderPath).dirName(); if (dirname != "") { setWindowTitle(tr("EasyMercurial: %1").arg(dirname)); } else { @@ -2133,32 +2216,32 @@ bool workFolderExist = true; bool localRepoExist = true; - remoteRepoActionsEnabled = true; - if (remoteRepoPath.isEmpty()) { - remoteRepoActionsEnabled = false; + m_remoteRepoActionsEnabled = true; + if (m_remoteRepoPath.isEmpty()) { + m_remoteRepoActionsEnabled = false; } - localRepoActionsEnabled = true; - if (workFolderPath.isEmpty()) { - localRepoActionsEnabled = false; + m_localRepoActionsEnabled = true; + if (m_workFolderPath.isEmpty()) { + m_localRepoActionsEnabled = false; workFolderExist = false; } - if (workFolderPath == "" || !workFolderDir.exists(workFolderPath)) { - localRepoActionsEnabled = false; + if (m_workFolderPath == "" || !workFolderDir.exists(m_workFolderPath)) { + m_localRepoActionsEnabled = false; workFolderExist = false; } else { workFolderExist = true; } - if (!localRepoDir.exists(workFolderPath + "/.hg")) { - localRepoActionsEnabled = false; + if (!localRepoDir.exists(m_workFolderPath + "/.hg")) { + m_localRepoActionsEnabled = false; localRepoExist = false; } - hgIncomingAct -> setEnabled(remoteRepoActionsEnabled && remoteRepoActionsEnabled); - hgPullAct -> setEnabled(remoteRepoActionsEnabled && remoteRepoActionsEnabled); - hgPushAct -> setEnabled(remoteRepoActionsEnabled && remoteRepoActionsEnabled); + m_hgIncomingAct -> setEnabled(m_remoteRepoActionsEnabled && m_remoteRepoActionsEnabled); + m_hgPullAct -> setEnabled(m_remoteRepoActionsEnabled && m_remoteRepoActionsEnabled); + m_hgPushAct -> setEnabled(m_remoteRepoActionsEnabled && m_remoteRepoActionsEnabled); bool haveDiff = false; QSettings settings; @@ -2168,26 +2251,26 @@ } settings.endGroup(); - hgRefreshAct -> setEnabled(localRepoActionsEnabled); - hgFolderDiffAct -> setEnabled(localRepoActionsEnabled && haveDiff); - hgRevertAct -> setEnabled(localRepoActionsEnabled); - hgAddAct -> setEnabled(localRepoActionsEnabled); - hgRemoveAct -> setEnabled(localRepoActionsEnabled); - hgUpdateAct -> setEnabled(localRepoActionsEnabled); - hgCommitAct -> setEnabled(localRepoActionsEnabled); - hgMergeAct -> setEnabled(localRepoActionsEnabled); - hgAnnotateAct -> setEnabled(localRepoActionsEnabled); - hgServeAct -> setEnabled(localRepoActionsEnabled); - hgIgnoreAct -> setEnabled(localRepoActionsEnabled); - - DEBUG << "localRepoActionsEnabled = " << localRepoActionsEnabled << endl; - DEBUG << "canCommit = " << hgTabs->canCommit() << endl; - - hgAddAct->setEnabled(localRepoActionsEnabled && hgTabs->canAdd()); - hgRemoveAct->setEnabled(localRepoActionsEnabled && hgTabs->canRemove()); - hgCommitAct->setEnabled(localRepoActionsEnabled && hgTabs->canCommit()); - hgRevertAct->setEnabled(localRepoActionsEnabled && hgTabs->canRevert()); - hgFolderDiffAct->setEnabled(localRepoActionsEnabled && hgTabs->canDiff()); + m_hgRefreshAct -> setEnabled(m_localRepoActionsEnabled); + m_hgFolderDiffAct -> setEnabled(m_localRepoActionsEnabled && haveDiff); + m_hgRevertAct -> setEnabled(m_localRepoActionsEnabled); + m_hgAddAct -> setEnabled(m_localRepoActionsEnabled); + m_hgRemoveAct -> setEnabled(m_localRepoActionsEnabled); + m_hgUpdateAct -> setEnabled(m_localRepoActionsEnabled); + m_hgCommitAct -> setEnabled(m_localRepoActionsEnabled); + m_hgMergeAct -> setEnabled(m_localRepoActionsEnabled); + m_hgAnnotateAct -> setEnabled(m_localRepoActionsEnabled); + m_hgServeAct -> setEnabled(m_localRepoActionsEnabled); + m_hgIgnoreAct -> setEnabled(m_localRepoActionsEnabled); + + DEBUG << "m_localRepoActionsEnabled = " << m_localRepoActionsEnabled << endl; + DEBUG << "canCommit = " << m_hgTabs->canCommit() << endl; + + m_hgAddAct->setEnabled(m_localRepoActionsEnabled && m_hgTabs->canAdd()); + m_hgRemoveAct->setEnabled(m_localRepoActionsEnabled && m_hgTabs->canRemove()); + m_hgCommitAct->setEnabled(m_localRepoActionsEnabled && m_hgTabs->canCommit()); + m_hgRevertAct->setEnabled(m_localRepoActionsEnabled && m_hgTabs->canRevert()); + m_hgFolderDiffAct->setEnabled(m_localRepoActionsEnabled && m_hgTabs->canDiff()); // A default merge makes sense if: // * there is only one parent (if there are two, we have an uncommitted merge) and @@ -2204,24 +2287,24 @@ bool emptyRepo = false; bool noWorkingCopy = false; bool newBranch = false; - int currentBranchHeads = 0; - - if (currentParents.size() == 1) { + int m_currentBranchHeads = 0; + + if (m_currentParents.size() == 1) { bool parentIsHead = false; - Changeset *parent = currentParents[0]; - foreach (Changeset *head, currentHeads) { - DEBUG << "head branch " << head->branch() << ", current branch " << currentBranch << endl; - if (head->isOnBranch(currentBranch)) { - ++currentBranchHeads; + Changeset *parent = m_currentParents[0]; + foreach (Changeset *head, m_currentHeads) { + DEBUG << "head branch " << head->branch() << ", current branch " << m_currentBranch << endl; + if (head->isOnBranch(m_currentBranch)) { + ++m_currentBranchHeads; } if (parent->id() == head->id()) { parentIsHead = true; } } - if (currentBranchHeads == 2 && parentIsHead) { + if (m_currentBranchHeads == 2 && parentIsHead) { canMerge = true; } - if (currentBranchHeads == 0 && parentIsHead) { + if (m_currentBranchHeads == 0 && parentIsHead) { // Just created a new branch newBranch = true; } @@ -2229,13 +2312,13 @@ canUpdate = true; DEBUG << "parent id = " << parent->id() << endl; DEBUG << " head ids "<<endl; - foreach (Changeset *h, currentHeads) { + foreach (Changeset *h, m_currentHeads) { DEBUG << "head id = " << h->id() << endl; } } - justMerged = false; - } else if (currentParents.size() == 0) { - if (currentHeads.size() == 0) { + m_justMerged = false; + } else if (m_currentParents.size() == 0) { + if (m_currentHeads.size() == 0) { // No heads -> empty repo emptyRepo = true; } else { @@ -2245,125 +2328,125 @@ noWorkingCopy = true; canUpdate = true; } - justMerged = false; + m_justMerged = false; } else { haveMerge = true; - justMerged = true; + m_justMerged = true; } - hgMergeAct->setEnabled(localRepoActionsEnabled && - (canMerge || hgTabs->canResolve())); - hgUpdateAct->setEnabled(localRepoActionsEnabled && - (canUpdate && !hgTabs->haveChangesToCommit())); + m_hgMergeAct->setEnabled(m_localRepoActionsEnabled && + (canMerge || m_hgTabs->canResolve())); + m_hgUpdateAct->setEnabled(m_localRepoActionsEnabled && + (canUpdate && !m_hgTabs->haveChangesToCommit())); // Set the state field on the file status widget QString branchText; - if (currentBranch == "" || currentBranch == "default") { + if (m_currentBranch == "" || m_currentBranch == "default") { branchText = tr("the default branch"); } else { - branchText = tr("branch \"%1\"").arg(currentBranch); + branchText = tr("branch \"%1\"").arg(m_currentBranch); } - if (stateUnknown) { - if (workFolderPath == "") { - hgTabs->setState(tr("No repository open")); + if (m_stateUnknown) { + if (m_workFolderPath == "") { + m_workStatus->setState(tr("No repository open")); } else { - hgTabs->setState(tr("(Examining repository)")); + m_workStatus->setState(tr("(Examining repository)")); } } else if (emptyRepo) { - hgTabs->setState(tr("Nothing committed to this repository yet")); + m_workStatus->setState(tr("Nothing committed to this repository yet")); } else if (noWorkingCopy) { - hgTabs->setState(tr("No working copy yet: consider updating")); + m_workStatus->setState(tr("No working copy yet: consider updating")); } else if (canMerge) { - hgTabs->setState(tr("<b>Awaiting merge</b> on %1").arg(branchText)); - } else if (!hgTabs->getAllUnresolvedFiles().empty()) { - hgTabs->setState(tr("Have unresolved files following merge on %1").arg(branchText)); + m_workStatus->setState(tr("<b>Awaiting merge</b> on %1").arg(branchText)); + } else if (!m_hgTabs->getAllUnresolvedFiles().empty()) { + m_workStatus->setState(tr("Have unresolved files following merge on %1").arg(branchText)); } else if (haveMerge) { - hgTabs->setState(tr("Have merged but not yet committed on %1").arg(branchText)); + m_workStatus->setState(tr("Have merged but not yet committed on %1").arg(branchText)); } else if (newBranch) { - hgTabs->setState(tr("On %1. New branch: has not yet been committed").arg(branchText)); + m_workStatus->setState(tr("On %1. New branch: has not yet been committed").arg(branchText)); } else if (canUpdate) { - if (hgTabs->haveChangesToCommit()) { + if (m_hgTabs->haveChangesToCommit()) { // have uncommitted changes - hgTabs->setState(tr("On %1. Not at the head of the branch").arg(branchText)); + m_workStatus->setState(tr("On %1. Not at the head of the branch").arg(branchText)); } else { // no uncommitted changes - hgTabs->setState(tr("On %1. Not at the head of the branch: consider updating").arg(branchText)); + m_workStatus->setState(tr("On %1. Not at the head of the branch: consider updating").arg(branchText)); } - } else if (currentBranchHeads > 1) { - hgTabs->setState(tr("At one of %n heads of %1", "", currentBranchHeads).arg(branchText)); + } else if (m_currentBranchHeads > 1) { + m_workStatus->setState(tr("At one of %n heads of %1", "", m_currentBranchHeads).arg(branchText)); } else { - hgTabs->setState(tr("At the head of %1").arg(branchText)); + m_workStatus->setState(tr("At the head of %1").arg(branchText)); } } void MainWindow::createActions() { //File actions - openAct = new QAction(QIcon(":/images/fileopen.png"), tr("Open..."), this); - 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")); - - settingsAct = new QAction(QIcon(":/images/settings.png"), tr("Settings..."), this); - settingsAct -> setStatusTip(tr("View and change application settings")); - - exitAct = new QAction(QIcon(":/images/exit.png"), tr("Quit"), this); - exitAct->setShortcuts(QKeySequence::Quit); - exitAct->setStatusTip(tr("Quit EasyMercurial")); + m_openAct = new QAction(QIcon(":/images/fileopen.png"), tr("Open..."), this); + m_openAct -> setStatusTip(tr("Open an existing repository or working folder")); + + m_changeRemoteRepoAct = new QAction(tr("Change Remote Location..."), this); + m_changeRemoteRepoAct->setStatusTip(tr("Change the default remote repository for pull and push actions")); + + m_settingsAct = new QAction(QIcon(":/images/settings.png"), tr("Settings..."), this); + m_settingsAct -> setStatusTip(tr("View and change application settings")); + + m_exitAct = new QAction(QIcon(":/images/exit.png"), tr("Quit"), this); + m_exitAct->setShortcuts(QKeySequence::Quit); + m_exitAct->setStatusTip(tr("Quit EasyMercurial")); //Repository actions - hgRefreshAct = new QAction(QIcon(":/images/status.png"), tr("Refresh"), this); - hgRefreshAct->setStatusTip(tr("Refresh the window to show the current state of the working folder")); - - hgIncomingAct = new QAction(QIcon(":/images/incoming.png"), tr("Preview"), this); - hgIncomingAct -> setStatusTip(tr("See what changes are available in the remote repository waiting to be pulled")); - - hgPullAct = new QAction(QIcon(":/images/pull.png"), tr("Pull"), this); - hgPullAct -> setStatusTip(tr("Pull changes from the remote repository to the local repository")); - - hgPushAct = new QAction(QIcon(":/images/push.png"), tr("Push"), this); - hgPushAct->setStatusTip(tr("Push changes from the local repository to the remote repository")); + m_hgRefreshAct = new QAction(QIcon(":/images/status.png"), tr("Refresh"), this); + m_hgRefreshAct->setStatusTip(tr("Refresh the window to show the current state of the working folder")); + + m_hgIncomingAct = new QAction(QIcon(":/images/incoming.png"), tr("Preview"), this); + m_hgIncomingAct -> setStatusTip(tr("See what changes are available in the remote repository waiting to be pulled")); + + m_hgPullAct = new QAction(QIcon(":/images/pull.png"), tr("Pull"), this); + m_hgPullAct -> setStatusTip(tr("Pull changes from the remote repository to the local repository")); + + m_hgPushAct = new QAction(QIcon(":/images/push.png"), tr("Push"), this); + m_hgPushAct->setStatusTip(tr("Push changes from the local repository to the remote repository")); //Workfolder actions - hgFolderDiffAct = new QAction(QIcon(":/images/folderdiff.png"), tr("Diff"), this); - hgFolderDiffAct->setStatusTip(tr("See what has changed in the working folder compared with the last committed state")); - - hgRevertAct = new QAction(QIcon(":/images/undo.png"), tr("Revert"), this); - hgRevertAct->setStatusTip(tr("Throw away your changes and return to the last committed state")); - - hgAddAct = new QAction(QIcon(":/images/add.png"), tr("Add"), this); - hgAddAct -> setStatusTip(tr("Mark the selected file(s) to be added on the next commit")); + m_hgFolderDiffAct = new QAction(QIcon(":/images/folderdiff.png"), tr("Diff"), this); + m_hgFolderDiffAct->setStatusTip(tr("See what has changed in the working folder compared with the last committed state")); + + m_hgRevertAct = new QAction(QIcon(":/images/undo.png"), tr("Revert"), this); + m_hgRevertAct->setStatusTip(tr("Throw away your changes and return to the last committed state")); + + m_hgAddAct = new QAction(QIcon(":/images/add.png"), tr("Add"), this); + m_hgAddAct -> setStatusTip(tr("Mark the selected file(s) to be added on the next commit")); //!!! needs to be modified for number - hgRemoveAct = new QAction(QIcon(":/images/remove.png"), tr("Remove"), this); - hgRemoveAct -> setStatusTip(tr("Mark the selected file(s) to be removed from version control on the next commit")); - - hgUpdateAct = new QAction(QIcon(":/images/update.png"), tr("Update"), this); - hgUpdateAct->setStatusTip(tr("Update the working folder to the head of the current repository branch")); + m_hgRemoveAct = new QAction(QIcon(":/images/remove.png"), tr("Remove"), this); + m_hgRemoveAct -> setStatusTip(tr("Mark the selected file(s) to be removed from version control on the next commit")); + + m_hgUpdateAct = new QAction(QIcon(":/images/update.png"), tr("Update"), this); + m_hgUpdateAct->setStatusTip(tr("Update the working folder to the head of the current repository branch")); //!!! needs to be modified when files selected - hgCommitAct = new QAction(QIcon(":/images/commit.png"), tr("Commit"), this); - hgCommitAct->setStatusTip(tr("Commit your changes to the local repository")); - - hgMergeAct = new QAction(QIcon(":/images/merge.png"), tr("Merge"), this); - hgMergeAct->setStatusTip(tr("Merge the two independent sets of changes in the local repository into the working folder")); + m_hgCommitAct = new QAction(QIcon(":/images/commit.png"), tr("Commit"), this); + m_hgCommitAct->setStatusTip(tr("Commit your changes to the local repository")); + + m_hgMergeAct = new QAction(QIcon(":/images/merge.png"), tr("Merge"), this); + m_hgMergeAct->setStatusTip(tr("Merge the two independent sets of changes in the local repository into the working folder")); //Advanced actions //!!! needs to be modified for number - hgAnnotateAct = new QAction(tr("Annotate"), this); - hgAnnotateAct -> setStatusTip(tr("Show line-by-line version information for selected file")); - - hgIgnoreAct = new QAction(tr("Edit .hgignore File"), this); - hgIgnoreAct -> setStatusTip(tr("Edit the .hgignore file, containing the names of files that should be ignored by Mercurial")); - - hgServeAct = new QAction(tr("Serve via HTTP"), this); - hgServeAct -> setStatusTip(tr("Serve local repository via http for workgroup access")); + m_hgAnnotateAct = new QAction(tr("Annotate"), this); + m_hgAnnotateAct -> setStatusTip(tr("Show line-by-line version information for selected file")); + + m_hgIgnoreAct = new QAction(tr("Edit .hgignore File"), this); + m_hgIgnoreAct -> setStatusTip(tr("Edit the .hgignore file, containing the names of files that should be ignored by Mercurial")); + + m_hgServeAct = new QAction(tr("Serve via HTTP"), this); + m_hgServeAct -> setStatusTip(tr("Serve local repository via http for workgroup access")); //Help actions - aboutAct = new QAction(tr("About EasyMercurial"), this); + m_aboutAct = new QAction(tr("About EasyMercurial"), this); // Miscellaneous QShortcut *clearSelectionsShortcut = new QShortcut(Qt::Key_Escape, this); @@ -2373,56 +2456,56 @@ void MainWindow::createMenus() { - fileMenu = menuBar()->addMenu(tr("File")); - - fileMenu -> addAction(openAct); - fileMenu -> addAction(changeRemoteRepoAct); - fileMenu -> addSeparator(); - - advancedMenu = fileMenu->addMenu(tr("Advanced")); - - fileMenu -> addAction(settingsAct); - - fileMenu -> addSeparator(); - fileMenu -> addAction(exitAct); - - advancedMenu -> addAction(hgIgnoreAct); - advancedMenu -> addSeparator(); - advancedMenu -> addAction(hgServeAct); - - helpMenu = menuBar()->addMenu(tr("Help")); - helpMenu->addAction(aboutAct); + m_fileMenu = menuBar()->addMenu(tr("File")); + + m_fileMenu -> addAction(m_openAct); + m_fileMenu -> addAction(m_changeRemoteRepoAct); + m_fileMenu -> addSeparator(); + + m_advancedMenu = m_fileMenu->addMenu(tr("Advanced")); + + m_fileMenu -> addAction(m_settingsAct); + + m_fileMenu -> addSeparator(); + m_fileMenu -> addAction(m_exitAct); + + m_advancedMenu -> addAction(m_hgIgnoreAct); + m_advancedMenu -> addSeparator(); + m_advancedMenu -> addAction(m_hgServeAct); + + m_helpMenu = menuBar()->addMenu(tr("Help")); + m_helpMenu->addAction(m_aboutAct); } void MainWindow::createToolBars() { - fileToolBar = addToolBar(tr("File")); - fileToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); - fileToolBar -> addAction(openAct); - fileToolBar -> addAction(hgRefreshAct); - fileToolBar -> addSeparator(); - fileToolBar -> setMovable(false); - - repoToolBar = addToolBar(tr(REPOMENU_TITLE)); - repoToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); - repoToolBar->addAction(hgIncomingAct); - repoToolBar->addAction(hgPullAct); - repoToolBar->addAction(hgPushAct); - repoToolBar -> setMovable(false); - - workFolderToolBar = addToolBar(tr(WORKFOLDERMENU_TITLE)); - addToolBar(Qt::LeftToolBarArea, workFolderToolBar); - workFolderToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); - workFolderToolBar->addAction(hgFolderDiffAct); - workFolderToolBar->addSeparator(); - workFolderToolBar->addAction(hgRevertAct); - workFolderToolBar->addAction(hgUpdateAct); - workFolderToolBar->addAction(hgCommitAct); - workFolderToolBar->addAction(hgMergeAct); - workFolderToolBar->addSeparator(); - workFolderToolBar->addAction(hgAddAct); - workFolderToolBar->addAction(hgRemoveAct); - workFolderToolBar -> setMovable(false); + m_fileToolBar = addToolBar(tr("File")); + m_fileToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); + m_fileToolBar -> addAction(m_openAct); + m_fileToolBar -> addAction(m_hgRefreshAct); + m_fileToolBar -> addSeparator(); + m_fileToolBar -> setMovable(false); + + m_repoToolBar = addToolBar(tr(REPOMENU_TITLE)); + m_repoToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); + m_repoToolBar->addAction(m_hgIncomingAct); + m_repoToolBar->addAction(m_hgPullAct); + m_repoToolBar->addAction(m_hgPushAct); + m_repoToolBar -> setMovable(false); + + m_workFolderToolBar = addToolBar(tr(WORKFOLDERMENU_TITLE)); + addToolBar(Qt::LeftToolBarArea, m_workFolderToolBar); + m_workFolderToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); + m_workFolderToolBar->addAction(m_hgFolderDiffAct); + m_workFolderToolBar->addSeparator(); + m_workFolderToolBar->addAction(m_hgRevertAct); + m_workFolderToolBar->addAction(m_hgUpdateAct); + m_workFolderToolBar->addAction(m_hgCommitAct); + m_workFolderToolBar->addAction(m_hgMergeAct); + m_workFolderToolBar->addSeparator(); + m_workFolderToolBar->addAction(m_hgAddAct); + m_workFolderToolBar->addAction(m_hgRemoveAct); + m_workFolderToolBar -> setMovable(false); updateToolBarStyle(); } @@ -2441,46 +2524,48 @@ } } +void MainWindow::updateWorkFolderAndRepoNames() +{ + m_hgTabs->setLocalPath(m_workFolderPath); + + m_workStatus->setLocalPath(m_workFolderPath); + m_workStatus->setRemoteURL(m_remoteRepoPath); +} + void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); } - -//!!! review these: - void MainWindow::readSettings() { QDir workFolder; QSettings settings; - remoteRepoPath = settings.value("remoterepopath", "").toString(); - workFolderPath = settings.value("workfolderpath", "").toString(); - if (!workFolder.exists(workFolderPath)) + m_remoteRepoPath = settings.value("remoterepopath", "").toString(); + m_workFolderPath = settings.value("workfolderpath", "").toString(); + if (!workFolder.exists(m_workFolderPath)) { - workFolderPath = ""; + m_workFolderPath = ""; } QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("size", QSize(400, 400)).toSize(); - firstStart = settings.value("firststart", QVariant(true)).toBool(); - -//!!! initialFileTypesBits = (unsigned char) settings.value("viewFileTypes", QVariant(DEFAULT_HG_STAT_BITS)).toInt(); + m_firstStart = settings.value("firststart", QVariant(true)).toBool(); + resize(size); move(pos); } - void MainWindow::writeSettings() { QSettings settings; settings.setValue("pos", pos()); settings.setValue("size", size()); - settings.setValue("remoterepopath", remoteRepoPath); - settings.setValue("workfolderpath", workFolderPath); - settings.setValue("firststart", firstStart); - //!!!settings.setValue("viewFileTypes", hgTabs -> getFileTypesBits()); + settings.setValue("remoterepopath", m_remoteRepoPath); + settings.setValue("workfolderpath", m_workFolderPath); + settings.setValue("firststart", m_firstStart); }
--- a/mainwindow.h Wed Feb 09 12:03:15 2011 +0000 +++ b/mainwindow.h Mon Feb 28 13:09:37 2011 +0000 @@ -34,26 +34,14 @@ class QTimer; QT_END_NAMESPACE +class WorkStatusWidget; + class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QString myDirPath); - HgTabWidget *hgTabs; - void writeSettings(); - - //Paths to remote repo & workfolder - //Local repo is directory "./hg/" under work folder - QString remoteRepoPath; - QString workFolderPath; - QString currentBranch; - Changesets currentHeads; - Changesets currentParents; - int commitsSincePush; - bool stateUnknown; - bool hgIsOK; - bool needNewLog; protected: void closeEvent(QCloseEvent *event); @@ -83,6 +71,7 @@ void hgAdd(); void hgCommit(); void hgShowSummary(); + void hgShowSummaryFor(Changeset *); void hgFolderDiff(); void hgDiffToCurrent(QString); void hgDiffToParent(QString, QString); @@ -127,6 +116,7 @@ void splitChangeSets(QStringList *list, QString hgLogOutput); void reportNewRemoteHeads(QString); void presentLongStdoutToUser(QString stdo); + void writeSettings(); QStringList listAllUpIpV4Addresses(); QString filterTag(QString tag); @@ -155,6 +145,7 @@ void showPullResult(QString); void showPushResult(QString); int extractChangeCount(QString); + QString format1(QString); QString format3(QString, QString, QString); void clearState(); @@ -163,71 +154,86 @@ void suspendFileSystemWatcher(); void restoreFileSystemWatcher(); - bool firstStart; + void updateWorkFolderAndRepoNames(); - bool showAllFiles; + WorkStatusWidget *m_workStatus; + HgTabWidget *m_hgTabs; + + QString m_remoteRepoPath; + QString m_workFolderPath; + QString m_currentBranch; + Changesets m_currentHeads; + Changesets m_currentParents; + int m_commitsSincePush; + bool m_stateUnknown; + bool m_hgIsOK; + bool m_needNewLog; + + bool m_firstStart; + + bool m_showAllFiles; //Actions enabled flags - bool remoteRepoActionsEnabled; - bool localRepoActionsEnabled; + bool m_remoteRepoActionsEnabled; + bool m_localRepoActionsEnabled; QString m_myDirPath; - //File menu actions - QAction *openAct; - QAction *changeRemoteRepoAct; - QAction *settingsAct; - QAction *exitAct; + // File menu actions + QAction *m_openAct; + QAction *m_changeRemoteRepoAct; + QAction *m_settingsAct; + QAction *m_exitAct; - //Repo actions - QAction *hgIncomingAct; - QAction *hgPushAct; - QAction *hgPullAct; - QAction *hgRefreshAct; - QAction *hgFolderDiffAct; - QAction *hgChgSetDiffAct; - QAction *hgRevertAct; - QAction *hgAddAct; - QAction *hgRemoveAct; - QAction *hgUpdateAct; - QAction *hgCommitAct; - QAction *hgMergeAct; - QAction *hgUpdateToRevAct; - QAction *hgAnnotateAct; - QAction *hgIgnoreAct; - QAction *hgServeAct; + // Repo actions + QAction *m_hgIncomingAct; + QAction *m_hgPushAct; + QAction *m_hgPullAct; + QAction *m_hgRefreshAct; + QAction *m_hgFolderDiffAct; + QAction *m_hgChgSetDiffAct; + QAction *m_hgRevertAct; + QAction *m_hgAddAct; + QAction *m_hgRemoveAct; + QAction *m_hgUpdateAct; + QAction *m_hgCommitAct; + QAction *m_hgMergeAct; + QAction *m_hgUpdateToRevAct; + QAction *m_hgAnnotateAct; + QAction *m_hgIgnoreAct; + QAction *m_hgServeAct; - //Menus - QMenu *fileMenu; - QMenu *advancedMenu; - QMenu *helpMenu; + // Menus + QMenu *m_fileMenu; + QMenu *m_advancedMenu; + QMenu *m_helpMenu; - //Help menu actions - QAction *aboutAct; + // Help menu actions + QAction *m_aboutAct; - QToolBar *fileToolBar; - QToolBar *repoToolBar; - QToolBar *workFolderToolBar; + QToolBar *m_fileToolBar; + QToolBar *m_repoToolBar; + QToolBar *m_workFolderToolBar; - HgRunner *runner; + HgRunner *m_runner; - bool shouldHgStat; + bool m_shouldHgStat; QString getDiffBinaryName(); QString getMergeBinaryName(); QString getEditorBinaryName(); - QFileSystemWatcher *fsWatcher; + QFileSystemWatcher *m_fsWatcher; QTimer *m_fsWatcherGeneralTimer; QTimer *m_fsWatcherRestoreTimer; bool m_fsWatcherSuspended; - QString lastStatOutput; - QStringList lastRevertedFiles; + QString m_lastStatOutput; + QStringList m_lastRevertedFiles; - bool justMerged; - QString mergeTargetRevision; - QString mergeCommitComment; + bool m_justMerged; + QString m_mergeTargetRevision; + QString m_mergeCommitComment; }; #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moreinformationdialog.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -0,0 +1,141 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on hgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "moreinformationdialog.h" + +#include <QMessageBox> +#include <QLabel> +#include <QGridLayout> +#include <QTextEdit> +#include <QDialogButtonBox> +#include <QPushButton> +#include <QApplication> +#include <QStyle> + +MoreInformationDialog::MoreInformationDialog(QString title, + QString head, + QString text, + QString more, + QWidget *parent) : + QDialog(parent) +{ + setWindowTitle(title); + + QGridLayout *layout = new QGridLayout; + layout->setSpacing(10); + setLayout(layout); + + m_iconLabel = new QLabel; + layout->addWidget(m_iconLabel, 0, 0, 2, 1, Qt::AlignTop); + + QLabel *headLabel = new QLabel(QString("<qt><h3>%1</h3></qt>").arg(head)); + layout->addWidget(headLabel, 0, 1); + + QLabel *textLabel = new QLabel(text); + textLabel->setTextFormat(Qt::RichText); + textLabel->setWordWrap(true); + layout->addWidget(textLabel, 1, 1, Qt::AlignTop); + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok); + connect(bb, SIGNAL(accepted()), this, SLOT(accept())); + layout->addWidget(bb, 2, 0, 1, 2); + + m_moreButton = bb->addButton(tr("More Details..."), + QDialogButtonBox::ActionRole); + m_moreButton->setAutoDefault(false); + m_moreButton->setDefault(false); + + connect(m_moreButton, SIGNAL(clicked()), this, SLOT(moreClicked())); + + bb->button(QDialogButtonBox::Ok)->setDefault(true); + + m_moreText = new QTextEdit(); + m_moreText->setAcceptRichText(false); + m_moreText->document()->setPlainText(more); + m_moreText->setMinimumWidth(360); + m_moreText->setReadOnly(true); + m_moreText->setLineWrapMode(QTextEdit::NoWrap); + + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + m_moreText->setFont(font); + + layout->addWidget(m_moreText, 3, 0, 1, 2); + + m_moreText->hide(); + if (more == "") m_moreButton->hide(); + + layout->setRowStretch(1, 20); + layout->setColumnStretch(1, 20); + setMinimumWidth(400); +} + +MoreInformationDialog::~MoreInformationDialog() +{ +} + +void +MoreInformationDialog::moreClicked() +{ + if (m_moreText->isVisible()) { + m_moreText->hide(); + m_moreButton->setText(tr("Show Details...")); + } else { + m_moreText->show(); + m_moreButton->setText(tr("Hide Details...")); + } + adjustSize(); +} + +void +MoreInformationDialog::setIcon(QIcon icon) +{ + QStyle *style = qApp->style(); + int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this); + m_iconLabel->setPixmap(icon.pixmap(iconSize, iconSize)); +} + +void +MoreInformationDialog::critical(QWidget *parent, QString title, QString head, + QString text, QString more) +{ + MoreInformationDialog d(title, head, text, more, parent); + QStyle *style = qApp->style(); + d.setIcon(style->standardIcon(QStyle::SP_MessageBoxCritical, 0, &d)); + d.exec(); +} + +void +MoreInformationDialog::information(QWidget *parent, QString title, QString head, + QString text, QString more) +{ + MoreInformationDialog d(title, head, text, more, parent); + QStyle *style = qApp->style(); + d.setIcon(style->standardIcon(QStyle::SP_MessageBoxInformation, 0, &d)); + d.exec(); +} + +void +MoreInformationDialog::warning(QWidget *parent, QString title, QString head, + QString text, QString more) +{ + MoreInformationDialog d(title, head, text, more, parent); + QStyle *style = qApp->style(); + d.setIcon(style->standardIcon(QStyle::SP_MessageBoxWarning, 0, &d)); + d.exec(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moreinformationdialog.h Mon Feb 28 13:09:37 2011 +0000 @@ -0,0 +1,63 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on hgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef MORE_INFORMATION_DIALOG_H +#define MORE_INFORMATION_DIALOG_H + +#include <QString> +#include <QDialog> + +class QLabel; +class QTextEdit; +class QPushButton; + +/** + * Provide methods like the QMessageBox static methods, to call up + * dialogs with "More information" buttons in them. QMessageBox does + * have an optional additional-details field, but it doesn't behave + * quite as we'd like with regard to layout + */ + +class MoreInformationDialog : public QDialog +{ + Q_OBJECT + +public: + MoreInformationDialog(QString title, + QString head, + QString text, + QString more, + QWidget *parent = 0); + + ~MoreInformationDialog(); + + void setIcon(QIcon); + + static void critical(QWidget *parent, QString title, QString head, QString text, QString more); + static void information(QWidget *parent, QString title, QString head, QString text, QString more); + static void warning(QWidget *parent, QString title, QString head, QString text, QString more); + +private slots: + void moreClicked(); + +private: + QLabel *m_iconLabel; + QPushButton *m_moreButton; + QTextEdit *m_moreText; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/workstatuswidget.cpp Mon Feb 28 13:09:37 2011 +0000 @@ -0,0 +1,125 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on HgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "workstatuswidget.h" +#include "debug.h" +#include "clickablelabel.h" + +#include <QGridLayout> +#include <QSpacerItem> +#include <QLabel> +#include <QProcess> +#include <QDir> + +WorkStatusWidget::WorkStatusWidget(QWidget *parent) : + QWidget(parent) +{ + QGridLayout *layout = new QGridLayout; + layout->setMargin(6); + layout->setSpacing(6); + setLayout(layout); + + int row = 0; + +#ifndef Q_OS_MAC + layout->addItem(new QSpacerItem(1, 1), row, 0); + ++row; +#endif + + layout->addWidget(new QLabel(tr("Local:")), row, 1); + + m_openButton = new ClickableLabel; + QFont f(m_openButton->font()); + f.setBold(true); + m_openButton->setFont(f); + m_openButton->setMouseUnderline(true); + connect(m_openButton, SIGNAL(clicked()), this, SLOT(openButtonClicked())); + layout->addWidget(m_openButton, row, 2, 1, 2, Qt::AlignLeft); + + ++row; + layout->addWidget(new QLabel(tr("Remote:")), row, 1); + m_remoteURLLabel = new QLabel; + layout->addWidget(m_remoteURLLabel, row, 2, 1, 2); + + ++row; + layout->addWidget(new QLabel(tr("State:")), row, 1); + m_stateLabel = new QLabel; + layout->addWidget(m_stateLabel, row, 2, 1, 2); + + layout->setColumnStretch(2, 20); + + +} + +WorkStatusWidget::~WorkStatusWidget() +{ +} + +void +WorkStatusWidget::setLocalPath(QString p) +{ + m_localPath = p; + m_openButton->setText(p); + m_openButton->setEnabled(QDir(m_localPath).exists()); +} + +void +WorkStatusWidget::setRemoteURL(QString r) +{ + m_remoteURL = r; + m_remoteURLLabel->setText(r); +} + +void +WorkStatusWidget::setState(QString b) +{ + m_state = b; + updateStateLabel(); +} + +void +WorkStatusWidget::updateStateLabel() +{ + m_stateLabel->setText(m_state); +} + +void +WorkStatusWidget::openButtonClicked() +{ + QDir d(m_localPath); + if (d.exists()) { + QStringList args; + QString path = d.canonicalPath(); +#if defined Q_OS_WIN32 + // Although the Win32 API is quite happy to have + // forward slashes as directory separators, Windows + // Explorer is not + path = path.replace('/', '\\'); + args << path; + QProcess::execute("c:/windows/explorer.exe", args); +#else + args << path; + QProcess::execute( +#if defined Q_OS_MAC + "/usr/bin/open", +#else + "/usr/bin/xdg-open", +#endif + args); +#endif + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/workstatuswidget.h Mon Feb 28 13:09:37 2011 +0000 @@ -0,0 +1,62 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on HgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef WORKSTATUSWIDGET_H +#define WORKSTATUSWIDGET_H + +#include <QWidget> + +class QLabel; +class QPushButton; +class QFileInfo; +class ClickableLabel; +class QCheckBox; + +class WorkStatusWidget : public QWidget +{ + Q_OBJECT + +public: + WorkStatusWidget(QWidget *parent = 0); + ~WorkStatusWidget(); + + QString localPath() const { return m_localPath; } + void setLocalPath(QString p); + + QString remoteURL() const { return m_remoteURL; } + void setRemoteURL(QString u); + + QString state() const { return m_state; } + void setState(QString b); + +private slots: + void openButtonClicked(); + +private: + QString m_localPath; + ClickableLabel *m_openButton; + + QString m_remoteURL; + QLabel *m_remoteURLLabel; + + QString m_state; + QLabel *m_stateLabel; + + void updateStateLabel(); +}; + +#endif