# HG changeset patch # User Chris Cannam # Date 1298898577 0 # Node ID 5b4aa1c244071d2e7d15595dead07558027627d0 # Parent f7cdd5b31aedb5df01f6d75dd84152d1a04782c7# Parent b280a2dc051278d1a7c018d4e27ae0c1e6796d27 Merge branch status_outside_tabs into branch new-branches, and make a new branch diff -r f7cdd5b31aed -r 5b4aa1c24407 changesetitem.cpp --- 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(" Revision: %1") @@ -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(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(); diff -r f7cdd5b31aed -r 5b4aa1c24407 changesetitem.h --- 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 m_parentDiffActions; + QMap m_summaryActions; }; #endif // CHANGESETITEM_H diff -r f7cdd5b31aed -r 5b4aa1c24407 changesetscene.cpp --- 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(it); + if (csit && csit->getId() == id) return csit; + } + return 0; +} + + diff -r f7cdd5b31aed -r 5b4aa1c24407 changesetscene.h --- 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 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); diff -r f7cdd5b31aed -r 5b4aa1c24407 confirmcommentdialog.cpp --- 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 = "" + intro; - text += "

"; + + if (intro == "") text = ""; + else text = "" + intro + "

"; + + text += ""; foreach (QString file, files) { text += "   " + xmlEncode(file) + "
"; } text += "
"; + 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 = "" + introTextWithCount + ""; } - return confirm(parent, title, text, okButtonText); + return confirm(parent, title, text, "", okButtonText); } bool ConfirmCommentDialog::confirmDangerousFilesAction(QWidget *parent, @@ -143,7 +157,7 @@ } else { text = "" + introTextWithCount + ""; } - return confirmDangerous(parent, title, text, okButtonText); + return confirmDangerous(parent, title, text, "", okButtonText); } bool ConfirmCommentDialog::confirmAndGetShortComment(QWidget *parent, diff -r f7cdd5b31aed -r 5b4aa1c24407 confirmcommentdialog.h --- 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); diff -r f7cdd5b31aed -r 5b4aa1c24407 easyhg-extdiff.sh --- 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" ] + diff -r f7cdd5b31aed -r 5b4aa1c24407 easyhg-merge.sh --- 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" ] diff -r f7cdd5b31aed -r 5b4aa1c24407 easyhg.pro --- 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 diff -r f7cdd5b31aed -r 5b4aa1c24407 filestatuswidget.cpp --- 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 #include @@ -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("


"), ++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); -} diff -r f7cdd5b31aed -r 5b4aa1c24407 filestatuswidget.h --- 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); diff -r f7cdd5b31aed -r 5b4aa1c24407 hgaction.h --- 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 { diff -r f7cdd5b31aed -r 5b4aa1c24407 hgtabwidget.cpp --- 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 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() diff -r f7cdd5b31aed -r 5b4aa1c24407 hgtabwidget.h --- 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); diff -r f7cdd5b31aed -r 5b4aa1c24407 historywidget.cpp --- 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))); diff -r f7cdd5b31aed -r 5b4aa1c24407 historywidget.h --- 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); diff -r f7cdd5b31aed -r 5b4aa1c24407 incomingdialog.cpp --- 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("

%1

%2") .arg(tr("The command output was:")) .arg(xmlEncode(text).replace("\n", "
")); - } + } else { + body = tr("Your local repository already contains all changes found in the remote repository."); + } 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("

%1

").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); } diff -r f7cdd5b31aed -r 5b4aa1c24407 mainwindow.cpp --- 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("

Pull from remote repository?

"), + tr("

You are about to pull changes from the remote repository at %1.

").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("

Push to remote repository?

"), + tr("

You are about to push your changes to the remote repository at %1.

").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 alreadyWatched; - QStringList dl(fsWatcher->directories()); + QStringList dl(m_fsWatcher->directories()); foreach (QString d, dl) alreadyWatched.insert(d); std::deque 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("

%1

").arg(head); +} + QString MainWindow::format3(QString head, QString intro, QString code) { code = xmlEncode(code).replace("\n", "
") @@ -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("Successfully pushed to the remote repository at %1.").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

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.
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.

You may need to merge the changes locally first.

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.

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.

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.

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.

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.
Check that the Mercurial program path is correct in %1.

%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.
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.
This may indicate an installation problem with EasyMercurial.

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.

%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.
This may indicate an installation problem with EasyMercurial.

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("

Command failed

" "

The following command failed:

" "%1" @@ -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("

Clone successful

%1
").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 %1.").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("

Update successful

%1

").arg(xmlEncode(output))); - shouldHgStat = true; + m_shouldHgStat = true; break; case ACT_MERGE: - //!!! use format3? - QMessageBox::information(this, tr("Merge"), tr("

Merge successful

%1
").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("

Merge resolved

Merge resolved successfully.

")); - shouldHgStat = true; - justMerged = true; + tr("

Merge resolved

Merge resolved successfully.
Remember to test and commit the result before making any further changes.

")); + 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 "<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("Awaiting merge 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("Awaiting merge 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); } diff -r f7cdd5b31aed -r 5b4aa1c24407 mainwindow.h --- 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 diff -r f7cdd5b31aed -r 5b4aa1c24407 moreinformationdialog.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include + +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("

%1

").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(); +} + diff -r f7cdd5b31aed -r 5b4aa1c24407 moreinformationdialog.h --- /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 +#include + +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 diff -r f7cdd5b31aed -r 5b4aa1c24407 workstatuswidget.cpp --- /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 +#include +#include +#include +#include + +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 + } +} diff -r f7cdd5b31aed -r 5b4aa1c24407 workstatuswidget.h --- /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 + +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