# HG changeset patch # User Chris Cannam # Date 1290178459 0 # Node ID 10eb97683aa98b1fd85ce3a18481eac408333956 # Parent a773c6e7b3012353fd003841e3992349add46f72 * Show branch names even for changes with children, if those children are on a different branch * Pick up remote repo path from local repo via hg paths * Some work towards breaking down files into various groups based on status * Add /usr/local/bin to path for hg (temporary hack I hope) diff -r a773c6e7b301 -r 10eb97683aa9 changesetitem.cpp --- a/changesetitem.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/changesetitem.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -23,7 +23,7 @@ #include ChangesetItem::ChangesetItem(Changeset *cs) : - m_changeset(cs), m_column(0), m_row(0), m_wide(false) + m_changeset(cs), m_showBranch(false), m_column(0), m_row(0), m_wide(false) { m_font = QFont(); m_font.setPixelSize(11); @@ -93,11 +93,12 @@ paint->setPen(QPen(Qt::black)); - if (m_changeset->children().empty()) { + if (m_showBranch) { // write branch name f.setBold(true); paint->setFont(f); QString branch = m_changeset->branch(); + if (branch == "") branch = "default"; int wid = width - 3; branch = TextAbbrev::abbreviate(branch, QFontMetrics(f), wid); paint->drawText(x0, -fh + fm.ascent() - 4, branch); diff -r a773c6e7b301 -r 10eb97683aa9 changesetitem.h --- a/changesetitem.h Thu Nov 18 18:08:18 2010 +0000 +++ b/changesetitem.h Fri Nov 19 14:54:19 2010 +0000 @@ -41,9 +41,13 @@ bool isWide() const { return m_wide; } void setWide(bool w) { m_wide = w; } + bool shouldShowBranch() const { return m_showBranch; } + void setShowBranch(bool s) { m_showBranch = s; } + private: QFont m_font; Changeset *m_changeset; + bool m_showBranch; int m_column; int m_row; bool m_wide; diff -r a773c6e7b301 -r 10eb97683aa9 common.cpp --- a/common.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/common.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -33,7 +33,12 @@ QString path = QProcessEnvironment::systemEnvironment().value("PATH"); DEBUG << "findExecutable: seeking location for binary " << name - << ": system path is " << path; + << ": system path is " << path << endl; +#ifndef Q_OS_WIN32 + path = path + ":/usr/local/bin"; + DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)" + << endl; +#endif #ifdef Q_OS_WIN32 QChar pathSep = ';'; #else diff -r a773c6e7b301 -r 10eb97683aa9 easyhg.pro --- a/easyhg.pro Thu Nov 18 18:08:18 2010 +0000 +++ b/easyhg.pro Fri Nov 19 14:54:19 2010 +0000 @@ -30,7 +30,8 @@ startupdialog.h \ repositorydialog.h \ multichoicedialog.h \ - selectablelabel.h + selectablelabel.h \ + statparser.h SOURCES = main.cpp \ mainwindow.cpp \ hgexpwidget.cpp \ @@ -52,7 +53,8 @@ startupdialog.cpp \ repositorydialog.cpp \ multichoicedialog.cpp \ - selectablelabel.cpp + selectablelabel.cpp \ + statparser.cpp macx-* { SOURCES += common_osx.mm diff -r a773c6e7b301 -r 10eb97683aa9 grapher.cpp --- a/grapher.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/grapher.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -353,6 +353,8 @@ m_scene->addItem(item); } + // Add the connecting lines + foreach (Changeset *cs, csets) { QString id = cs->id(); ChangesetItem *item = m_items[id]; @@ -369,6 +371,21 @@ } } + // Add the branch labels + foreach (Changeset *cs, csets) { + QString id = cs->id(); + ChangesetItem *item = m_items[id]; + bool haveChildOnSameBranch = false; + foreach (QString childId, cs->children()) { + Changeset *child = m_changesets[childId]; + if (child->branch() == cs->branch()) { + haveChildOnSameBranch = true; + break; + } + } + item->setShowBranch(!haveChildOnSameBranch); + } + // We need to lay out the changesets in forward chronological // order. We have no guarantees about the order in which // changesets appear in the list -- in a simple repository they diff -r a773c6e7b301 -r 10eb97683aa9 hgrunner.cpp --- a/hgrunner.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/hgrunner.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -99,9 +99,11 @@ saveOutput(); isRunning = false; - if (procExitCode == 0 || procExitStatus == QProcess::NormalExit) { + if (procExitCode == 0 && procExitStatus == QProcess::NormalExit) { + DEBUG << "HgRunner::finished: Command completed successfully: stderr says: " << stdErr << endl; emit commandCompleted(); } else { + DEBUG << "HgRunner::finished: Command failed: stderr says: " << stdErr << endl; emit commandFailed(); } } diff -r a773c6e7b301 -r 10eb97683aa9 logparser.cpp --- a/logparser.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/logparser.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -17,10 +17,13 @@ #include "logparser.h" +#include "debug.h" + #include #include -LogParser::LogParser(QString text) : m_text(text) +LogParser::LogParser(QString text, QString separator) : + m_text(text), m_sep(separator) { m_text.replace("\r\n", "\n"); } @@ -33,7 +36,7 @@ LogList LogParser::parse() { LogList results; - QRegExp re("^(\\w+):\\s+(.*)$"); + QRegExp re(QString("^(\\w+)\\s*%1\\s+(.*)$").arg(m_sep)); QStringList entries = split(); foreach (QString entry, entries) { LogEntry dictionary; @@ -42,7 +45,7 @@ if (re.indexIn(line) == 0) { QString key = re.cap(1); QString value = re.cap(2); - dictionary[key] = value; + dictionary[key.trimmed()] = value; } } results.push_back(dictionary); diff -r a773c6e7b301 -r 10eb97683aa9 logparser.h --- a/logparser.h Thu Nov 18 18:08:18 2010 +0000 +++ b/logparser.h Fri Nov 19 14:54:19 2010 +0000 @@ -29,13 +29,14 @@ class LogParser : public QObject { public: - LogParser(QString text); + LogParser(QString text, QString separator = ":"); QStringList split(); LogList parse(); private: QString m_text; + QString m_sep; }; #endif // LOGPARSER_H diff -r a773c6e7b301 -r 10eb97683aa9 mainwindow.cpp --- a/mainwindow.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/mainwindow.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -35,6 +35,7 @@ #include "startupdialog.h" #include "colourset.h" #include "debug.h" +#include "logparser.h" MainWindow::MainWindow() @@ -83,7 +84,7 @@ open(); } - hgStat(); + hgPaths(); } @@ -148,6 +149,17 @@ } } +void MainWindow::hgPaths() +{ + if (runningAction == ACT_NONE) + { + QStringList params; + params << "paths"; + runner -> startHgCommand(workFolderPath, params); + runningAction = ACT_PATHS; + } +} + void MainWindow::hgHeads() { if (runningAction == ACT_NONE) @@ -739,7 +751,7 @@ hgExp->clearLists(); enableDisableActions(); - hgStat(); + hgPaths(); } delete d; @@ -981,6 +993,10 @@ void MainWindow::commandFailed() { DEBUG << "MainWindow::commandFailed" << endl; + runningAction = ACT_NONE; + runner -> hideProgBar(); + + //!!! N.B hg incoming returns failure even if successful, if there were no changes } void MainWindow::commandCompleted() @@ -1003,8 +1019,24 @@ //Successful running. switch(runningAction) { + case ACT_PATHS: + { + QString stdout = runner->getStdOut(); + DEBUG << "stdout is " << stdout << endl; + LogParser lp(stdout, "="); + 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; + } + MultiChoiceDialog::addRecentArgument("local", workFolderPath); + MultiChoiceDialog::addRecentArgument("remote", remoteRepoPath); + enableDisableActions(); + break; + } + case ACT_STAT: - MultiChoiceDialog::addRecentArgument("local", workFolderPath); hgExp -> updateWorkFolderFileList(runner -> getStdOut()); break; @@ -1097,8 +1129,13 @@ } - //Typical sequence goes stat -> heads -> parents -> log - if (runningAction == ACT_STAT) + //Typical sequence goes paths -> stat -> heads -> parents -> log + if (runningAction == ACT_PATHS) + { + runningAction = ACT_NONE; + hgStat(); + } + else if (runningAction == ACT_STAT) { runningAction = ACT_NONE; hgHeads(); @@ -1132,7 +1169,7 @@ runningAction = ACT_NONE; if (shouldHgStat) { - hgStat(); + hgPaths(); } } } @@ -1149,8 +1186,8 @@ connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); - connect(hgStatAct, SIGNAL(triggered()), this, SLOT(hgStat())); - connect(hgExp, SIGNAL(workFolderViewTypesChanged()), this, SLOT(hgStat())); + connect(hgStatAct, SIGNAL(triggered()), this, SLOT(hgPaths())); + connect(hgExp, SIGNAL(workFolderViewTypesChanged()), this, SLOT(hgPaths())); connect(hgRemoveAct, SIGNAL(triggered()), this, SLOT(hgRemove())); connect(hgAddAct, SIGNAL(triggered()), this, SLOT(hgAdd())); connect(hgCommitAct, SIGNAL(triggered()), this, SLOT(hgCommit())); diff -r a773c6e7b301 -r 10eb97683aa9 mainwindow.h --- a/mainwindow.h Thu Nov 18 18:08:18 2010 +0000 +++ b/mainwindow.h Fri Nov 19 14:54:19 2010 +0000 @@ -33,6 +33,7 @@ enum HGACTIONS { ACT_NONE, + ACT_PATHS, ACT_STAT, ACT_HEADS, ACT_PARENTS, @@ -80,6 +81,7 @@ void closeEvent(QCloseEvent *event); public slots: + void hgPaths(); void hgStat(); void tabChanged(int currTab); void commandCompleted(); diff -r a773c6e7b301 -r 10eb97683aa9 multichoicedialog.cpp --- a/multichoicedialog.cpp Thu Nov 18 18:08:18 2010 +0000 +++ b/multichoicedialog.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -52,20 +52,24 @@ f.setPointSize(f.pointSize() * 0.9); m_descriptionLabel->setFont(f); - m_urlLabel = new QLabel(tr("URL:")); + m_urlLabel = new QLabel(tr("&URL:")); outer->addWidget(m_urlLabel, 3, 0); m_urlCombo = new QComboBox(); m_urlCombo->setEditable(true); + m_urlLabel->setBuddy(m_urlCombo); connect(m_urlCombo, SIGNAL(editTextChanged(const QString &)), this, SLOT(urlChanged(const QString &))); outer->addWidget(m_urlCombo, 3, 1, 1, 2); - m_fileLabel = new QLabel(tr("File:")); + m_fileLabel = new QLabel(tr("&File:")); outer->addWidget(m_fileLabel, 4, 0); m_fileCombo = new QComboBox(); m_fileCombo->setEditable(true); + m_fileLabel->setBuddy(m_fileCombo); + connect(m_fileCombo, SIGNAL(editTextChanged(const QString &)), + this, SLOT(fileChanged(const QString &))); outer->addWidget(m_fileCombo, 4, 1); outer->setColumnStretch(1, 20); @@ -78,7 +82,10 @@ connect(bbox, SIGNAL(accepted()), this, SLOT(accept())); connect(bbox, SIGNAL(rejected()), this, SLOT(reject())); outer->addWidget(bbox, 5, 0, 1, 3); - + + m_okButton = bbox->button(QDialogButtonBox::Ok); + m_okButton->setEnabled(false); + setMinimumWidth(480); } @@ -215,6 +222,17 @@ } void +MultiChoiceDialog::fileChanged(const QString &s) +{ + if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) { + m_okButton->setEnabled(getArgument() != "" && + getAdditionalArgument() != ""); + } else { + m_okButton->setEnabled(getArgument() != ""); + } +} + +void MultiChoiceDialog::choiceChanged() { DEBUG << "choiceChanged" << endl; @@ -263,7 +281,7 @@ break; case FileArg: - m_fileLabel->setText(tr("File:")); + m_fileLabel->setText(tr("&File:")); m_fileLabel->show(); m_fileCombo->show(); m_fileCombo->addItems(rf->getRecent()); @@ -271,7 +289,7 @@ break; case DirectoryArg: - m_fileLabel->setText(tr("Folder:")); + m_fileLabel->setText(tr("&Folder:")); m_fileLabel->show(); m_fileCombo->show(); m_fileCombo->addItems(rf->getRecent()); @@ -287,7 +305,7 @@ m_urlLabel->show(); m_urlCombo->show(); m_urlCombo->addItems(rf->getRecent()); - m_fileLabel->setText(tr("Folder:")); + m_fileLabel->setText(tr("&Folder:")); m_fileLabel->show(); m_fileCombo->show(); m_fileCombo->lineEdit()->setText(QDir::homePath()); diff -r a773c6e7b301 -r 10eb97683aa9 multichoicedialog.h --- a/multichoicedialog.h Thu Nov 18 18:08:18 2010 +0000 +++ b/multichoicedialog.h Fri Nov 19 14:54:19 2010 +0000 @@ -61,6 +61,7 @@ private slots: void choiceChanged(); void urlChanged(const QString &); + void fileChanged(const QString &); void browse(); private: @@ -79,6 +80,7 @@ QAbstractButton *m_browseButton; QLabel *m_urlLabel; QComboBox *m_urlCombo; + QAbstractButton *m_okButton; }; #endif // MULTICHOICEDIALOG_H diff -r a773c6e7b301 -r 10eb97683aa9 statparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/statparser.cpp Fri Nov 19 14:54:19 2010 +0000 @@ -0,0 +1,25 @@ +#include "statparser.h" + +#include + +StatParser::StatParser(QString text) +{ + text.replace("\r\n", "\n"); + + QMap buckets; + buckets['M'] = &modified; + buckets['A'] = &added; + buckets['R'] = &removed; + buckets['!'] = &missing; + buckets['?'] = &unknown; + + QStringList lines = text.split("\n", QString::SkipEmptyParts); + foreach (QString line, lines) { + if (line.length() < 3 || line[2] != ' ') continue; + QChar tag = line[0]; + QString file = line.right(line.length() - 2); + if (buckets.contains(tag)) { + buckets[tag]->push_back(file); + } + } +} diff -r a773c6e7b301 -r 10eb97683aa9 statparser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/statparser.h Fri Nov 19 14:54:19 2010 +0000 @@ -0,0 +1,38 @@ +/* -*- 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) 2010 Chris Cannam + Copyright (c) 2010 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 STATPARSER_H +#define STATPARSER_H + +#include +#include + +class StatParser : public QObject +{ + Q_OBJECT +public: + StatParser(QString text); + + QStringList modified; + QStringList added; + QStringList unknown; + QStringList removed; + QStringList missing; + +}; + +#endif // STATPARSER_H