changeset 125:63c2f3f61c79

* Add Incoming dialog and better layouts for dialogs generally
author Chris Cannam
date Mon, 29 Nov 2010 17:03:17 +0000
parents 1f27f71a7034
children f41bbd0c7c27
files changeset.cpp changeset.h changesetdetailitem.cpp changesetitem.cpp easyhg.pro incomingdialog.cpp incomingdialog.h mainwindow.cpp mainwindow.h
diffstat 9 files changed, 246 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/changeset.cpp	Mon Nov 29 11:38:25 2010 +0000
+++ b/changeset.cpp	Mon Nov 29 17:03:17 2010 +0000
@@ -16,6 +16,7 @@
 */
 
 #include "changeset.h"
+#include "common.h"
 
 #include <QVariant>
 
@@ -36,3 +37,56 @@
     }
 }
 
+QString Changeset::getLogTemplate()
+{
+    return "id: {rev}:{node|short}\\nuser: {author}\\nbranch: {branches}\\ntag: {tag}\\ndatetime: {date|isodate}\\ntimestamp: {date|hgdate}\\nage: {date|age}\\nparents: {parents}\\ncomment: {desc|json}\\n\\n";
+}
+
+QString Changeset::formatHtml()
+{
+    QString description;
+    QString rowTemplate = "<tr><td><b>%1</b></td><td>%2</td></tr>";
+
+    description = "<qt><table border=0>";
+
+    QString c = comment().trimmed();
+    c = c.replace(QRegExp("^\""), "");
+    c = c.replace(QRegExp("\"$"), "");
+    c = c.replace("\\\"", "\"");
+    c = xmlEncode(c);
+    c = c.replace("\\n", "<br>");
+
+    QStringList propNames, propTexts;
+    
+    propNames << "id"
+	      << "user"
+	      << "datetime"
+	      << "branch"
+	      << "tag"
+	      << "comment";
+
+    propTexts << QObject::tr("Identifier")
+	      << QObject::tr("Author")
+	      << QObject::tr("Date")
+	      << QObject::tr("Branch")
+	      << QObject::tr("Tag")
+	      << QObject::tr("Comment");
+
+    for (int i = 0; i < propNames.size(); ++i) {
+	QString prop = propNames[i];
+	QString value;
+	if (prop == "comment") value = c;
+	else {
+	    value = xmlEncode(property(prop.toLocal8Bit().data()).toString());
+	}
+	if (value != "") {
+	    description += rowTemplate
+		.arg(xmlEncode(propTexts[i]))
+		.arg(value);
+	}
+    }
+
+    description += "</table></qt>";
+
+    return description;
+}
--- a/changeset.h	Mon Nov 29 11:38:25 2010 +0000
+++ b/changeset.h	Mon Nov 29 17:03:17 2010 +0000
@@ -35,7 +35,7 @@
     Q_OBJECT
 
     Q_PROPERTY(QString id READ id WRITE setId NOTIFY idChanged STORED true);
-    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged STORED true);
+    Q_PROPERTY(QString user READ user WRITE setUser NOTIFY userChanged STORED true);
     Q_PROPERTY(QString branch READ branch WRITE setBranch NOTIFY branchChanged STORED true);
     Q_PROPERTY(QString tag READ tag WRITE setTag NOTIFY tagChanged STORED true);
     Q_PROPERTY(QString datetime READ datetime WRITE setDatetime NOTIFY datetimeChanged STORED true);
@@ -50,7 +50,7 @@
     explicit Changeset(const LogEntry &e);
 
     QString id() const { return m_id; }
-    QString author() const { return m_author; }
+    QString user() const { return m_user; }
     QString branch() const { return m_branch; }
     QString tag() const { return m_tag; }
     QString datetime() const { return m_datetime; }
@@ -69,8 +69,8 @@
         return id().split(':')[0].toInt();
     }
 
-    QString authorName() const {
-	QString a = author();
+    QString userName() const {
+	QString a = user();
 	return a.replace(QRegExp("\\s*<[^>]*>"), "");
     }
 
@@ -95,9 +95,13 @@
         return csets;
     }
 
+    static QString getLogTemplate();
+
+    QString formatHtml();
+    
 signals:
     void idChanged(QString id);
-    void authorChanged(QString author);
+    void userChanged(QString user);
     void branchChanged(QString branch);
     void tagChanged(QString tag);
     void datetimeChanged(QString datetime);
@@ -109,7 +113,7 @@
 
 public slots:
     void setId(QString id) { m_id = id; emit idChanged(id); }
-    void setAuthor(QString author) { m_author = author; emit authorChanged(author); }
+    void setUser(QString user) { m_user = user; emit userChanged(user); }
     void setBranch(QString branch) { m_branch = branch; emit branchChanged(branch); }
     void setTag(QString tag) { m_tag = tag; emit tagChanged(tag); }
     void setDatetime(QString datetime) { m_datetime = datetime; emit datetimeChanged(datetime); }
@@ -122,7 +126,7 @@
 
 private:
     QString m_id;
-    QString m_author;
+    QString m_user;
     QString m_branch;
     QString m_tag;
     QString m_datetime;
--- a/changesetdetailitem.cpp	Mon Nov 29 11:38:25 2010 +0000
+++ b/changesetdetailitem.cpp	Mon Nov 29 17:03:17 2010 +0000
@@ -58,7 +58,7 @@
     
     ColourSet *colourSet = ColourSet::instance();
     QColor branchColour = colourSet->getColourFor(m_changeset->branch());
-    QColor userColour = colourSet->getColourFor(m_changeset->author());
+    QColor userColour = colourSet->getColourFor(m_changeset->user());
 
     QFont f(m_font);
 
@@ -120,55 +120,7 @@
 ChangesetDetailItem::makeDocument()
 {
     delete m_doc;
-
-    QString description;
-    QString rowTemplate = "<tr><td><b>%1</b></td><td>%2</td></tr>";
-
-    description = "<qt><table border=0>";
-
-    QString comment = m_changeset->comment().trimmed();
-    comment = comment.replace(QRegExp("^\""), "");
-    comment = comment.replace(QRegExp("\"$"), "");
-    comment = comment.replace("\\\"", "\"");
-    comment = xmlEncode(comment);
-    comment = comment.replace("\\n", "<br>");
-
-    QStringList propNames, propTexts;
-    
-    propNames << "id"
-	      << "author"
-	      << "datetime"
-	      << "branch"
-	      << "tag"
-	      << "comment";
-
-    propTexts << QObject::tr("Identifier")
-	      << QObject::tr("Author")
-	      << QObject::tr("Date")
-	      << QObject::tr("Branch")
-	      << QObject::tr("Tag")
-	      << QObject::tr("Comment");
-
-    for (int i = 0; i < propNames.size(); ++i) {
-	QString prop = propNames[i];
-	QString value;
-	if (prop == "comment") value = comment;
-	else {
-	    value = xmlEncode(m_changeset->property
-			      (prop.toLocal8Bit().data()).toString());
-	}
-	if (value != "") {
-	    description += rowTemplate
-		.arg(xmlEncode(propTexts[i]))
-		.arg(value);
-	}
-    }
-
-    description += "</table></qt>";
-
-    DEBUG << "ChangesetDetailItem: description = " << description << endl;
-
     m_doc = new QTextDocument;
-    m_doc->setHtml(description);
+    m_doc->setHtml(m_changeset->formatHtml());
 }
 
--- a/changesetitem.cpp	Mon Nov 29 11:38:25 2010 +0000
+++ b/changesetitem.cpp	Mon Nov 29 17:03:17 2010 +0000
@@ -89,7 +89,7 @@
     
     ColourSet *colourSet = ColourSet::instance();
     QColor branchColour = colourSet->getColourFor(m_changeset->branch());
-    QColor userColour = colourSet->getColourFor(m_changeset->author());
+    QColor userColour = colourSet->getColourFor(m_changeset->user());
 
     QFont f(m_font);
 
@@ -130,7 +130,7 @@
     paint->setPen(QPen(Qt::white));
 
     int wid = width - 5;
-    QString person = TextAbbrev::abbreviate(m_changeset->authorName(), fm, wid);
+    QString person = TextAbbrev::abbreviate(m_changeset->userName(), fm, wid);
     paint->drawText(x0 + 3, fm.ascent(), person);
 
     paint->setPen(QPen(Qt::black));
--- a/easyhg.pro	Mon Nov 29 11:38:25 2010 +0000
+++ b/easyhg.pro	Mon Nov 29 17:03:17 2010 +0000
@@ -36,7 +36,8 @@
     confirmcommentdialog.h \
     hgaction.h \
     historywidget.h \
-    changesetscene.h
+    changesetscene.h \
+    incomingdialog.h
 SOURCES = main.cpp \
     mainwindow.cpp \
     hgtabwidget.cpp \
@@ -63,7 +64,8 @@
     filestatuswidget.cpp \
     confirmcommentdialog.cpp \
     historywidget.cpp \
-    changesetscene.cpp
+    changesetscene.cpp \
+    incomingdialog.cpp
 
 macx-* {
     SOURCES += common_osx.mm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/incomingdialog.cpp	Mon Nov 29 17:03:17 2010 +0000
@@ -0,0 +1,83 @@
+/* -*- 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.
+*/
+
+#include "incomingdialog.h"
+#include "changeset.h"
+#include "common.h"
+
+#include <QScrollArea>
+#include <QApplication>
+#include <QDialogButtonBox>
+#include <QLabel>
+#include <QGridLayout>
+#include <QStyle>
+
+IncomingDialog::IncomingDialog(QWidget *w, QString text) :
+    QDialog(w)
+{
+    QString head;
+    QString body;
+    bool scroll;
+
+    Changesets csets = Changeset::parseChangesets(text);
+    if (csets.empty()) {
+	head = tr("No changes waiting to pull");
+	if (text.trimmed() != "") {
+	    body = QString("<p>%1</p><code>%2</code>")
+		.arg(tr("The command output was:"))
+		.arg(xmlEncode(text).replace("\n", "<br>"));
+	}
+	scroll = false;
+    } else {
+        head = tr("There are %n change(s) ready to pull", "", csets.size());
+	foreach (Changeset *cs, csets) {
+	    body += cs->formatHtml() + "<p>";
+	    delete cs;
+	}
+	scroll = true;
+    }
+
+    QGridLayout *layout = new QGridLayout;
+    setLayout(layout);
+
+    QLabel *info = new QLabel;
+    QStyle *style = qApp->style();
+    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);
+
+    QLabel *headLabel = new QLabel(QString("<qt><h3>%1</h3></qt>").arg(head));
+    layout->addWidget(headLabel, 0, 1);
+
+    QLabel *textLabel = new QLabel(body);
+
+    if (scroll) {
+	QScrollArea *sa = new QScrollArea;
+	layout->addWidget(sa, 1, 1);
+	layout->setRowStretch(1, 20);
+	sa->setWidget(textLabel);
+    } else {
+	layout->addWidget(textLabel, 1, 1);
+    }
+
+    QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok);
+    connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
+    layout->addWidget(bb, 2, 0, 1, 2);
+}
+
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/incomingdialog.h	Mon Nov 29 17:03:17 2010 +0000
@@ -0,0 +1,31 @@
+/* -*- 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 INCOMING_DIALOG_H
+#define INCOMING_DIALOG_H
+
+#include <QDialog>
+
+class IncomingDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    IncomingDialog(QWidget *parent, QString incoming);
+};
+
+#endif
--- a/mainwindow.cpp	Mon Nov 29 11:38:25 2010 +0000
+++ b/mainwindow.cpp	Mon Nov 29 17:03:17 2010 +0000
@@ -29,6 +29,7 @@
 #include <QToolButton>
 #include <QSettings>
 #include <QInputDialog>
+#include <QRegExp>
 
 #include "mainwindow.h"
 #include "multichoicedialog.h"
@@ -37,6 +38,7 @@
 #include "debug.h"
 #include "logparser.h"
 #include "confirmcommentdialog.h"
+#include "incomingdialog.h"
 
 
 MainWindow::MainWindow()
@@ -185,7 +187,7 @@
     QStringList params;
     params << "log";
     params << "--template";
-    params << "id: {rev}:{node|short}\\nauthor: {author}\\nbranch: {branches}\\ntag: {tag}\\ndatetime: {date|isodate}\\ntimestamp: {date|hgdate}\\nage: {date|age}\\nparents: {parents}\\ncomment: {desc|json}\\n\\n";
+    params << Changeset::getLogTemplate();
     
     runner->requestAction(HgAction(ACT_LOG, workFolderPath, params));
 }
@@ -201,7 +203,7 @@
     }
         
     params << "--template";
-    params << "id: {rev}:{node|short}\\nauthor: {author}\\nbranch: {branches}\\ntag: {tag}\\ndatetime: {date|isodate}\\ntimestamp: {date|hgdate}\\nage: {date|age}\\nparents: {parents}\\ncomment: {desc|json}\\n\\n";
+    params << Changeset::getLogTemplate();
     
     runner->requestAction(HgAction(ACT_LOG_INCREMENTAL, workFolderPath, params));
 }
@@ -580,6 +582,7 @@
     QStringList params;
 
     params << "incoming" << "--newest-first" << remoteRepoPath;
+    params << "--template" << Changeset::getLogTemplate();
 
     runner->requestAction(HgAction(ACT_INCOMING, workFolderPath, params));
 }
@@ -1035,22 +1038,70 @@
     hgStat();
 }
 
+QString MainWindow::format3(QString head, QString intro, QString code)
+{
+    if (intro == "") {
+        return QString("<qt><h3>%1</h3><code>%2</code>")
+            .arg(head).arg(xmlEncode(code).replace("\n", "<br>"));
+    } else {
+        return QString("<qt><h3>%1</h3><p>%2</p><code>%3</code>")
+            .arg(head).arg(intro).arg(xmlEncode(code).replace("\n", "<br>"));
+    }
+}
+
 void MainWindow::showIncoming(QString output)
 {
     runner->hide();
-    QMessageBox::information(this, "Incoming", output);
+    IncomingDialog *d = new IncomingDialog(this, output);
+    d->exec();
+    delete d;
+}
+
+int MainWindow::extractChangeCount(QString text)
+{
+    QRegExp re("added (\\d+) ch\\w+ with (\\d+) ch\\w+ to (\\d+) f\\w+");
+    if (re.indexIn(text) >= 0) {
+        return re.cap(1).toInt();
+    } else if (text.contains("no changes")) {
+        return 0;
+    } else {
+        return -1; // unknown
+    }
 }
 
 void MainWindow::showPushResult(QString output)
 {
+    QString report;
+    int n = extractChangeCount(output);
+    if (n > 0) {
+        report = tr("Pushed %n changeset(s)", "", n);
+    } else if (n == 0) {
+        report = tr("No changes to push");
+    } else {
+        report = tr("Push complete");
+    }
+    report = format3(report, tr("The push command output was:"), output);
     runner->hide();
-    QMessageBox::information(this, "Push", output);
+    QMessageBox::information(this, "Push complete", report);
 }
 
 void MainWindow::showPullResult(QString output)
 {
+    QString report;
+    int n = extractChangeCount(output);
+    if (n > 0) {
+        report = tr("Pulled %n changeset(s)", "", n);
+    } else if (n == 0) {
+        report = tr("No changes to pull");
+    } else {
+        report = tr("Pull complete");
+    }
+    report = format3(report, tr("The pull command output was:"), output);
     runner->hide();
-    QMessageBox::information(this, "Pull", output);
+
+    //!!! and something about updating
+
+    QMessageBox::information(this, "Pull complete", report);
 }
 
 void MainWindow::commandFailed(HgAction action, QString stderr)
@@ -1066,6 +1117,7 @@
     case ACT_INCOMING:
         // returns non-zero code if the check was successful but there
         // are no changes pending
+        if (stderr.trimmed() == "") showIncoming("");
         return;
     case ACT_FOLDERDIFF:
     case ACT_FILEDIFF:
--- a/mainwindow.h	Mon Nov 29 11:38:25 2010 +0000
+++ b/mainwindow.h	Mon Nov 29 17:03:17 2010 +0000
@@ -135,6 +135,8 @@
     void showIncoming(QString);
     void showPullResult(QString);
     void showPushResult(QString);
+    int extractChangeCount(QString);
+    QString format3(QString, QString, QString);
 
     void clearState();