changeset 168:4bad3c5c053a

* Add "Show summary" feature * Add simplistic kinetic scrolling to history widget
author Chris Cannam
date Tue, 14 Dec 2010 17:20:10 +0000
parents 94be1e218655
children c7fa56707ae9
files changesetitem.cpp changesetitem.h changesetscene.cpp changesetscene.h dateitem.cpp dateitem.h easyhg_en.qm easyhg_en.ts grapher.cpp hgaction.h hgtabwidget.cpp hgtabwidget.h historywidget.cpp historywidget.h mainwindow.cpp mainwindow.h panned.cpp panned.h uncommitteditem.cpp uncommitteditem.h
diffstat 20 files changed, 491 insertions(+), 236 deletions(-) [+]
line wrap: on
line diff
--- a/changesetitem.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/changesetitem.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -41,6 +41,7 @@
     m_font.setPixelSize(11);
     m_font.setBold(false);
     m_font.setItalic(false);
+    setCursor(Qt::ArrowCursor);
 }
 
 QString
--- a/changesetitem.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/changesetitem.h	Tue Dec 14 17:20:10 2010 +0000
@@ -18,7 +18,7 @@
 #ifndef CHANGESETITEM_H
 #define CHANGESETITEM_H
 
-#include <QGraphicsItem>
+#include <QGraphicsObject>
 #include <QFont>
 
 class Changeset;
@@ -26,10 +26,9 @@
 
 class QAction;
 
-class ChangesetItem : public QObject, public QGraphicsItem
+class ChangesetItem : public QGraphicsObject
 {
     Q_OBJECT
-    Q_INTERFACES(QGraphicsItem)
 
 public:
     ChangesetItem(Changeset *cs);
--- a/changesetscene.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/changesetscene.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -18,6 +18,7 @@
 #include "changesetscene.h"
 #include "changesetitem.h"
 #include "uncommitteditem.h"
+#include "dateitem.h"
 
 ChangesetScene::ChangesetScene()
     : QGraphicsScene(), m_detailShown(0)
@@ -32,6 +33,9 @@
     connect(item, SIGNAL(detailShown()),
             this, SLOT(changesetDetailShown()));
 
+    connect(item, SIGNAL(detailHidden()),
+            this, SLOT(changesetDetailHidden()));
+
     connect(item, SIGNAL(updateTo(QString)),
             this, SIGNAL(updateTo(QString)));
 
@@ -62,11 +66,23 @@
     connect(item, SIGNAL(diff()),
             this, SIGNAL(diffWorkingFolder()));
 
+    connect(item, SIGNAL(showSummary()),
+            this, SIGNAL(showSummary()));
+
     connect(item, SIGNAL(showWork()),
             this, SIGNAL(showWork()));
 }
 
 void
+ChangesetScene::addDateItem(DateItem *item)
+{
+    addItem(item);
+
+    connect(item, SIGNAL(clicked()),
+            this, SLOT(dateItemClicked()));
+}
+
+void
 ChangesetScene::changesetDetailShown()
 {
     ChangesetItem *csi = qobject_cast<ChangesetItem *>(sender());
@@ -78,3 +94,17 @@
     m_detailShown = csi;
 }
 
+void
+ChangesetScene::changesetDetailHidden()
+{
+    m_detailShown = 0;
+}
+
+void
+ChangesetScene::dateItemClicked()
+{
+    if (m_detailShown) {
+        m_detailShown->hideDetail();
+    }
+}
+
--- a/changesetscene.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/changesetscene.h	Tue Dec 14 17:20:10 2010 +0000
@@ -22,6 +22,7 @@
 
 class ChangesetItem;
 class UncommittedItem;
+class DateItem;
 
 class ChangesetScene : public QGraphicsScene
 {
@@ -32,11 +33,13 @@
 
     void addChangesetItem(ChangesetItem *item);
     void addUncommittedItem(UncommittedItem *item);
+    void addDateItem(DateItem *item);
 
 signals:
     void commit();
     void revert();
     void diffWorkingFolder();
+    void showSummary();
     void showWork();
 
     void updateTo(QString id);
@@ -45,8 +48,10 @@
     void mergeFrom(QString id);
     void tag(QString id);
 
-public slots:
+private slots:
     void changesetDetailShown();
+    void changesetDetailHidden();
+    void dateItemClicked();
 
 private:
     ChangesetItem *m_detailShown;
--- a/dateitem.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/dateitem.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -17,9 +17,19 @@
 
 #include "dateitem.h"
 
+#include "debug.h"
+
 #include <QPainter>
 #include <QBrush>
 #include <QFont>
+#include <QGraphicsSceneMouseEvent>
+
+DateItem::DateItem() :
+    m_minrow(0), m_maxrow(0),
+    m_mincol(0), m_maxcol(0),
+    m_even(false)
+{
+}
 
 void
 DateItem::setRows(int minrow, int n)
@@ -37,6 +47,16 @@
     setX(m_mincol * 100);
 }
 
+void
+DateItem::mousePressEvent(QGraphicsSceneMouseEvent *e)
+{
+    DEBUG << "DateItem::mousePressEvent" << endl;
+    if (e->button() == Qt::LeftButton) {
+        emit clicked();
+    }
+    e->ignore();
+}
+
 QRectF
 DateItem::boundingRect() const
 {
--- a/dateitem.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/dateitem.h	Tue Dec 14 17:20:10 2010 +0000
@@ -18,15 +18,14 @@
 #ifndef DATEITEM_H
 #define DATEITEM_H
 
-#include <QGraphicsRectItem>
+#include <QGraphicsObject>
 
-class DateItem : public QGraphicsItem
+class DateItem : public QGraphicsObject
 {
+    Q_OBJECT
+
 public:
-    DateItem() :
-	m_minrow(0), m_maxrow(0),
-	m_mincol(0), m_maxcol(0),
-	m_even(false) {}
+    DateItem();
 
     virtual QRectF boundingRect() const;
     virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
@@ -39,6 +38,12 @@
     QString dateString() const { return m_dateString; }
     void setDateString(QString s) { m_dateString = s; }
 
+signals:
+    void clicked();
+
+protected:
+    virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
+
 private:
     QString m_dateString;
     int m_minrow;
Binary file easyhg_en.qm has changed
--- a/easyhg_en.ts	Wed Dec 08 16:57:18 2010 +0000
+++ b/easyhg_en.ts	Tue Dec 14 17:20:10 2010 +0000
@@ -4,42 +4,42 @@
 <context>
     <name>ChangesetItem</name>
     <message>
-        <location filename="changesetitem.cpp" line="111"/>
-        <source>&lt;qt&gt;&amp;nbsp;&lt;b&gt;Revision: &lt;/b&gt;%1&lt;/qt&gt;</source>
+        <location filename="changesetitem.cpp" line="112"/>
+        <source>&lt;qt&gt;&lt;b&gt;&amp;nbsp;Revision: &lt;/b&gt;%1&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="118"/>
+        <location filename="changesetitem.cpp" line="119"/>
         <source>Copy identifier to clipboard</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="127"/>
+        <location filename="changesetitem.cpp" line="128"/>
         <source>Diff to parent %1</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="136"/>
+        <location filename="changesetitem.cpp" line="138"/>
         <source>Diff to parent</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="141"/>
+        <location filename="changesetitem.cpp" line="143"/>
         <source>Diff to current working folder</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="146"/>
+        <location filename="changesetitem.cpp" line="148"/>
         <source>Update to this revision</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="149"/>
+        <location filename="changesetitem.cpp" line="151"/>
         <source>Merge from here to current</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="changesetitem.cpp" line="154"/>
+        <location filename="changesetitem.cpp" line="156"/>
         <source>Add tag...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -71,7 +71,8 @@
     </message>
     <message>
         <location filename="filestatuswidget.cpp" line="65"/>
-        <source>You have made no changes.</source>
+        <source>You have no uncommitted changes.</source>
+        <oldsource>You have made no changes.</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -101,41 +102,51 @@
     </message>
     <message>
         <location filename="filestatuswidget.cpp" line="73"/>
+        <source>In Conflict:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="filestatuswidget.cpp" line="74"/>
         <source>Untracked:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="75"/>
+        <location filename="filestatuswidget.cpp" line="76"/>
         <source>You have not changed these files.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="76"/>
+        <location filename="filestatuswidget.cpp" line="77"/>
         <source>You have changed these files since you last committed them.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="77"/>
+        <location filename="filestatuswidget.cpp" line="78"/>
         <source>These files will be added to version control next time you commit.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="78"/>
+        <location filename="filestatuswidget.cpp" line="79"/>
         <source>These files will be removed from version control next time you commit.&lt;br&gt;They will not be deleted from the local folder.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="80"/>
+        <location filename="filestatuswidget.cpp" line="81"/>
         <source>These files are recorded in the version control, but absent from your working folder.&lt;br&gt;If you intended to delete them, select them and use Remove to tell the version control system about it.&lt;br&gt;If you deleted them by accident, select them and use Revert to restore their previous contents.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="83"/>
+        <location filename="filestatuswidget.cpp" line="84"/>
+        <source>These files are unresolved following an incomplete merge.&lt;br&gt;Select a file and use Merge to try to resolve the merge again.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="filestatuswidget.cpp" line="85"/>
         <source>These files are in your working folder but are not under version control.&lt;br&gt;Select a file and use Add to place it under version control or Ignore to remove it from this list.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="filestatuswidget.cpp" line="86"/>
+        <location filename="filestatuswidget.cpp" line="88"/>
         <source>Files highlighted &lt;font color=#d40000&gt;in red&lt;/font&gt; have appeared since your most recent commit or update.</source>
         <translation type="unfinished"></translation>
     </message>
@@ -143,37 +154,37 @@
 <context>
     <name>HgRunner</name>
     <message>
-        <location filename="hgrunner.cpp" line="119"/>
+        <location filename="hgrunner.cpp" line="143"/>
         <source>User name:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="hgrunner.cpp" line="121"/>
+        <location filename="hgrunner.cpp" line="145"/>
         <source>User name for &quot;%1&quot;:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="hgrunner.cpp" line="125"/>
+        <location filename="hgrunner.cpp" line="149"/>
         <source>Enter user name</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="hgrunner.cpp" line="146"/>
+        <location filename="hgrunner.cpp" line="170"/>
         <source>Password:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="hgrunner.cpp" line="149"/>
+        <location filename="hgrunner.cpp" line="173"/>
         <source>Password for &quot;%1&quot; at &quot;%2&quot;:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="hgrunner.cpp" line="152"/>
+        <location filename="hgrunner.cpp" line="176"/>
         <source>Password for user &quot;%1&quot;:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="hgrunner.cpp" line="158"/>
+        <location filename="hgrunner.cpp" line="182"/>
         <source>Enter password</source>
         <translation type="unfinished"></translation>
     </message>
@@ -215,69 +226,61 @@
 <context>
     <name>MainWindow</name>
     <message>
-        <location filename="mainwindow.cpp" line="63"/>
-        <location filename="mainwindow.cpp" line="1045"/>
+        <location filename="mainwindow.cpp" line="64"/>
+        <location filename="mainwindow.cpp" line="1133"/>
         <source>EasyMercurial</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="130"/>
+        <location filename="mainwindow.cpp" line="132"/>
         <source>About EasyMercurial</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="131"/>
+        <location filename="mainwindow.cpp" line="133"/>
         <source>&lt;qt&gt;&lt;h2&gt;About EasyMercurial&lt;/h2&gt;&lt;p&gt;EasyMercurial is a simple user interface for the Mercurial version control system.&lt;/p&gt;&lt;p&gt;EasyMercurial is based on hgExplorer by Jari Korhonen, with thanks.&lt;br&gt;EasyMercurial development carried out by Chris Cannam for soundsoftware.ac.uk at the Centre for Digital Music, Queen Mary, University of London.&lt;ul&gt;&lt;li&gt;Copyright &amp;copy; 2010 Jari Korhonen&lt;/li&gt;&lt;li&gt;Copyright &amp;copy; 2010 Chris Cannam&lt;/li&gt;&lt;li&gt;Copyright &amp;copy; 2010 Queen Mary, University of London&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; 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.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="321"/>
+        <location filename="mainwindow.cpp" line="300"/>
         <source>Commit files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="370"/>
+        <location filename="mainwindow.cpp" line="351"/>
         <source>Tag</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="371"/>
+        <location filename="mainwindow.cpp" line="352"/>
         <source>Enter tag:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="526"/>
+        <location filename="mainwindow.cpp" line="528"/>
         <source>Revert files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="326"/>
-        <location filename="mainwindow.cpp" line="328"/>
-        <location filename="mainwindow.cpp" line="531"/>
+        <location filename="mainwindow.cpp" line="305"/>
+        <location filename="mainwindow.cpp" line="307"/>
         <location filename="mainwindow.cpp" line="533"/>
+        <location filename="mainwindow.cpp" line="535"/>
         <source>&lt;h3&gt;%1&lt;/h3&gt;&lt;p&gt;%2</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="327"/>
+        <location filename="mainwindow.cpp" line="306"/>
         <source>You are about to commit the following files:</source>
         <translation type="unfinished"></translation>
     </message>
-    <message numerus="yes">
-        <location filename="mainwindow.cpp" line="329"/>
-        <source>You are about to commit %n file(s):</source>
-        <translation type="unfinished">
-            <numerusform>You are about to commit %n file:</numerusform>
-            <numerusform>You are about to commit %n files:</numerusform>
-        </translation>
-    </message>
     <message>
-        <location filename="mainwindow.cpp" line="532"/>
+        <location filename="mainwindow.cpp" line="534"/>
         <source>You are about to &lt;b&gt;revert&lt;/b&gt; the following files to their previous committed state.&lt;br&gt;&lt;br&gt;This will &lt;b&gt;throw away any changes&lt;/b&gt; that you have made to these files but have not committed:</source>
         <translation type="unfinished"></translation>
     </message>
     <message numerus="yes">
-        <location filename="mainwindow.cpp" line="534"/>
+        <location filename="mainwindow.cpp" line="536"/>
         <source>You are about to &lt;b&gt;revert&lt;/b&gt; %n file(s).&lt;br&gt;&lt;br&gt;This will &lt;b&gt;throw away any changes&lt;/b&gt; that you have made to these files but have not committed.</source>
         <oldsource>You are about to &lt;b&gt;revert&lt;/b&gt; %n files.&lt;br&gt;&lt;br&gt;This will &lt;b&gt;throw away any changes&lt;/b&gt; that you have made to these files but have not committed.</oldsource>
         <translation type="unfinished">
@@ -286,185 +289,200 @@
         </translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="621"/>
+        <location filename="mainwindow.cpp" line="648"/>
+        <source>Merge from the default branch</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="650"/>
+        <source>Merge from branch &quot;%1&quot;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="656"/>
+        <source>Merge from %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="705"/>
         <source>Confirm pull</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="622"/>
+        <location filename="mainwindow.cpp" line="706"/>
         <source>Confirm pull from remote repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="623"/>
+        <location filename="mainwindow.cpp" line="707"/>
         <source>You are about to pull from the following remote repository:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="636"/>
+        <location filename="mainwindow.cpp" line="720"/>
         <source>Confirm push</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="637"/>
+        <location filename="mainwindow.cpp" line="721"/>
         <source>Confirm push to remote repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="638"/>
+        <location filename="mainwindow.cpp" line="722"/>
         <source>You are about to push to the following remote repository:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="714"/>
+        <location filename="mainwindow.cpp" line="802"/>
         <source>Open Repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="715"/>
+        <location filename="mainwindow.cpp" line="803"/>
         <source>&lt;qt&gt;&lt;big&gt;What would you like to open?&lt;/big&gt;&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="719"/>
+        <location filename="mainwindow.cpp" line="807"/>
         <source>&lt;qt&gt;&lt;center&gt;&lt;img src=&quot;:images/browser-64.png&quot;&gt;&lt;br&gt;Remote repository&lt;/center&gt;&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="720"/>
+        <location filename="mainwindow.cpp" line="808"/>
         <source>Open a remote Mercurial repository, by cloning from its URL into a local folder.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="724"/>
+        <location filename="mainwindow.cpp" line="812"/>
         <source>&lt;qt&gt;&lt;center&gt;&lt;img src=&quot;:images/hglogo-64.png&quot;&gt;&lt;br&gt;Local repository&lt;/center&gt;&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="725"/>
+        <location filename="mainwindow.cpp" line="813"/>
         <source>Open an existing local Mercurial repository.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="729"/>
+        <location filename="mainwindow.cpp" line="817"/>
         <source>&lt;qt&gt;&lt;center&gt;&lt;img src=&quot;:images/hdd_unmount-64.png&quot;&gt;&lt;br&gt;File folder&lt;/center&gt;&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="730"/>
+        <location filename="mainwindow.cpp" line="818"/>
         <source>Open a local folder, by creating a Mercurial repository in it.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="779"/>
+        <location filename="mainwindow.cpp" line="867"/>
         <source>File chosen</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="780"/>
+        <location filename="mainwindow.cpp" line="868"/>
         <source>&lt;qt&gt;&lt;b&gt;Folder required&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open &quot;%1&quot;.&lt;br&gt;This is a file; to open a repository, you need to choose a folder.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="787"/>
-        <location filename="mainwindow.cpp" line="857"/>
+        <location filename="mainwindow.cpp" line="875"/>
+        <location filename="mainwindow.cpp" line="945"/>
         <source>Folder does not exist</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="788"/>
+        <location filename="mainwindow.cpp" line="876"/>
         <source>&lt;qt&gt;&lt;b&gt;Folder does not exist&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open &quot;%1&quot;.&lt;br&gt;This folder does not exist, and it cannot be created because its parent does not exist either.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="795"/>
-        <location filename="mainwindow.cpp" line="811"/>
+        <location filename="mainwindow.cpp" line="883"/>
+        <location filename="mainwindow.cpp" line="899"/>
         <source>Path is in existing repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="796"/>
+        <location filename="mainwindow.cpp" line="884"/>
         <source>&lt;qt&gt;&lt;b&gt;Path is in an existing repository&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to initialise a repository at &quot;%1&quot;.&lt;br&gt;This path is already inside an existing repository.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="803"/>
-        <location filename="mainwindow.cpp" line="819"/>
+        <location filename="mainwindow.cpp" line="891"/>
+        <location filename="mainwindow.cpp" line="907"/>
         <source>Path is a file</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="804"/>
+        <location filename="mainwindow.cpp" line="892"/>
         <source>&lt;qt&gt;&lt;b&gt;Path is a file&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to initialise a repository at &quot;%1&quot;.&lt;br&gt;This is an existing file; it is only possible to initialise in folders.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="812"/>
+        <location filename="mainwindow.cpp" line="900"/>
         <source>&lt;qt&gt;&lt;b&gt;Local path is in an existing repository&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open a remote repository by cloning it to the local path &quot;%1&quot;.&lt;br&gt;This path is already inside an existing repository.&lt;br&gt;Please provide a new folder name for the local repository.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="820"/>
+        <location filename="mainwindow.cpp" line="908"/>
         <source>&lt;qt&gt;&lt;b&gt;Local path is a file&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open a remote repository by cloning it to the local path &quot;%1&quot;.&lt;br&gt;This path is an existing file.&lt;br&gt;Please provide a new folder name for the local repository.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="827"/>
+        <location filename="mainwindow.cpp" line="915"/>
         <source>Folder exists</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="828"/>
+        <location filename="mainwindow.cpp" line="916"/>
         <source>&lt;qt&gt;&lt;b&gt;Local folder already exists&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open a remote repository by cloning it to the local path &quot;%1&quot;.&lt;br&gt;This is the path of an existing folder.&lt;br&gt;Please provide a new folder name for the local repository.&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="835"/>
+        <location filename="mainwindow.cpp" line="923"/>
         <source>Path is inside a repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="836"/>
+        <location filename="mainwindow.cpp" line="924"/>
         <source>&lt;qt&gt;&lt;b&gt;Open the repository that contains this path?&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open &quot;%1&quot;.&lt;br&gt;This is not the root folder of a repository.&lt;br&gt;But it is inside a repository, whose root is at &quot;%2&quot;. &lt;br&gt;&lt;br&gt;Would you like to open that repository instead?&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="846"/>
+        <location filename="mainwindow.cpp" line="934"/>
         <source>Folder has no repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="847"/>
+        <location filename="mainwindow.cpp" line="935"/>
         <source>&lt;qt&gt;&lt;b&gt;Initialise a repository here?&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open &quot;%1&quot;.&lt;br&gt;This folder does not contain a Mercurial repository.&lt;br&gt;&lt;br&gt;Would you like to initialise a repository here?&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="858"/>
+        <location filename="mainwindow.cpp" line="946"/>
         <source>&lt;qt&gt;&lt;b&gt;Initialise a new repository?&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to open &quot;%1&quot;.&lt;br&gt;This folder does not yet exist.&lt;br&gt;&lt;br&gt;Would you like to create the folder and initialise a new empty repository in it?&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="868"/>
+        <location filename="mainwindow.cpp" line="956"/>
         <source>Repository exists</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="869"/>
+        <location filename="mainwindow.cpp" line="957"/>
         <source>&lt;qt&gt;&lt;b&gt;Open existing repository?&lt;/b&gt;&lt;br&gt;&lt;br&gt;You asked to initialise a new repository at &quot;%1&quot;.&lt;br&gt;This folder already contains a repository.  Would you like to open it?&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1034"/>
+        <location filename="mainwindow.cpp" line="1122"/>
         <source>Ok</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1045"/>
+        <location filename="mainwindow.cpp" line="1133"/>
         <source>Mercurial command did not return any output.</source>
         <translation type="unfinished"></translation>
     </message>
     <message numerus="yes">
-        <location filename="mainwindow.cpp" line="1127"/>
+        <location filename="mainwindow.cpp" line="1216"/>
         <source>Pushed %n changeset(s)</source>
         <translation type="unfinished">
             <numerusform>Pushed %n changeset</numerusform>
@@ -472,22 +490,22 @@
         </translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1129"/>
+        <location filename="mainwindow.cpp" line="1218"/>
         <source>No changes to push</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1131"/>
+        <location filename="mainwindow.cpp" line="1220"/>
         <source>Push complete</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1133"/>
+        <location filename="mainwindow.cpp" line="1222"/>
         <source>The push command output was:</source>
         <translation type="unfinished"></translation>
     </message>
     <message numerus="yes">
-        <location filename="mainwindow.cpp" line="1143"/>
+        <location filename="mainwindow.cpp" line="1232"/>
         <source>Pulled %n changeset(s)</source>
         <translation type="unfinished">
             <numerusform>Pulled %n changeset</numerusform>
@@ -495,361 +513,383 @@
         </translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1145"/>
+        <location filename="mainwindow.cpp" line="1234"/>
         <source>No changes to pull</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1147"/>
+        <location filename="mainwindow.cpp" line="1236"/>
         <source>Pull complete</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1149"/>
+        <location filename="mainwindow.cpp" line="1238"/>
         <source>The pull command output was:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1190"/>
+        <location filename="mainwindow.cpp" line="1285"/>
         <source>&lt;qt&gt;&lt;h3&gt;Command failed&lt;/h3&gt;&lt;p&gt;The following command failed:&lt;/p&gt;&lt;code&gt;%1&lt;/code&gt;%2&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1196"/>
+        <location filename="mainwindow.cpp" line="1291"/>
         <source>&lt;p&gt;Its output said:&lt;/p&gt;&lt;code&gt;%1&lt;/code&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1201"/>
+        <location filename="mainwindow.cpp" line="1296"/>
         <source>Command failed</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1351"/>
-        <location filename="mainwindow.cpp" line="1694"/>
+        <location filename="mainwindow.cpp" line="1445"/>
+        <source>Change summary</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1446"/>
+        <source>Summary of uncommitted changes</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1459"/>
+        <location filename="mainwindow.cpp" line="1464"/>
+        <location filename="mainwindow.cpp" line="1831"/>
         <source>Update</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1356"/>
-        <location filename="mainwindow.cpp" line="1700"/>
+        <location filename="mainwindow.cpp" line="601"/>
+        <location filename="mainwindow.cpp" line="626"/>
+        <location filename="mainwindow.cpp" line="1837"/>
         <source>Merge</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1362"/>
-        <source>Merge retry</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1363"/>
-        <source>Merge retry successful.</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1625"/>
+        <location filename="mainwindow.cpp" line="1750"/>
         <source>the default branch</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1627"/>
+        <location filename="mainwindow.cpp" line="1752"/>
         <source>branch &quot;%1&quot;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1630"/>
+        <location filename="mainwindow.cpp" line="1771"/>
         <source>On %1. Not at the head of the branch: consider updating</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1632"/>
+        <location filename="mainwindow.cpp" line="1760"/>
         <source>&lt;b&gt;Awaiting merge&lt;/b&gt; on %1</source>
         <translation type="unfinished"></translation>
     </message>
+    <message numerus="yes">
+        <location filename="mainwindow.cpp" line="308"/>
+        <source>You are about to commit %n file(s).</source>
+        <translation type="unfinished">
+            <numerusform>You are about to commit %n file.</numerusform>
+            <numerusform>You are about to commit %n files.</numerusform>
+        </translation>
+    </message>
     <message>
-        <location filename="mainwindow.cpp" line="1634"/>
+        <location filename="mainwindow.cpp" line="1459"/>
+        <source>&lt;qt&gt;&lt;h3&gt;Update successful&lt;/h3&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1464"/>
+        <source>&lt;qt&gt;&lt;h3&gt;Merge successful&lt;/h3&gt;&lt;p&gt;%1&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1470"/>
+        <source>Resolved</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1471"/>
+        <source>&lt;qt&gt;&lt;h3&gt;Merge resolved&lt;/h3&gt;&lt;p&gt;Merge resolved successfully.&lt;/p&gt;</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1758"/>
+        <source>Nothing committed to this repository yet</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1762"/>
+        <source>Have unresolved files following merge on %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1764"/>
+        <source>Have merged but not yet committed on %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1768"/>
+        <source>On %1. Not at the head of the branch</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message numerus="yes">
+        <location filename="mainwindow.cpp" line="1774"/>
+        <source>At one of %n heads of %1</source>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
+    </message>
+    <message>
+        <location filename="mainwindow.cpp" line="1776"/>
         <source>At the head of %1</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1643"/>
+        <location filename="mainwindow.cpp" line="1783"/>
         <source>Init local repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1644"/>
+        <location filename="mainwindow.cpp" line="1784"/>
         <source>Create an empty local repository in selected folder</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1646"/>
+        <location filename="mainwindow.cpp" line="1786"/>
         <source>Clone from remote</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1647"/>
+        <location filename="mainwindow.cpp" line="1787"/>
         <source>Clone from remote repository into local repository in selected folder</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1649"/>
+        <location filename="mainwindow.cpp" line="1789"/>
         <source>Open...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1650"/>
+        <location filename="mainwindow.cpp" line="1790"/>
         <source>Open repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1653"/>
+        <location filename="mainwindow.cpp" line="1793"/>
         <source>Settings...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1654"/>
+        <location filename="mainwindow.cpp" line="1794"/>
         <source>View and change application settings</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1657"/>
+        <location filename="mainwindow.cpp" line="1797"/>
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1659"/>
+        <location filename="mainwindow.cpp" line="1799"/>
         <source>Exit application</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1663"/>
+        <location filename="mainwindow.cpp" line="1803"/>
         <source>Refresh</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1664"/>
+        <location filename="mainwindow.cpp" line="1804"/>
         <source>Refresh (info of) status of workfolder files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1666"/>
+        <location filename="mainwindow.cpp" line="1806"/>
         <source>Preview</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1667"/>
+        <location filename="mainwindow.cpp" line="1807"/>
         <source>View info of changesets incoming to us from remote repository (on pull operation)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1669"/>
+        <location filename="mainwindow.cpp" line="1809"/>
         <source>Pull</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1670"/>
+        <location filename="mainwindow.cpp" line="1810"/>
         <source>Pull changesets from remote repository to local repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1672"/>
+        <location filename="mainwindow.cpp" line="1812"/>
         <source>Push</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1673"/>
+        <location filename="mainwindow.cpp" line="1813"/>
         <source>Push local changesets to remote repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1676"/>
-        <location filename="mainwindow.cpp" line="1679"/>
+        <location filename="mainwindow.cpp" line="1816"/>
         <source>Diff</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1677"/>
-        <source>Filediff: View differences between selected working folder file and local repository file</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1680"/>
+        <location filename="mainwindow.cpp" line="1817"/>
         <source>Folderdiff: View all differences between working folder files and local repository files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1682"/>
+        <location filename="mainwindow.cpp" line="1819"/>
         <source>View changesetdiff</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1683"/>
+        <location filename="mainwindow.cpp" line="1820"/>
         <source>Change set diff: View differences between all files of 2 repository changesets</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1685"/>
+        <location filename="mainwindow.cpp" line="1822"/>
         <source>Revert</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1686"/>
+        <location filename="mainwindow.cpp" line="1823"/>
         <source>Undo selected working folder file changes (return to local repository version)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1688"/>
+        <location filename="mainwindow.cpp" line="1825"/>
         <source>Add</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1689"/>
+        <location filename="mainwindow.cpp" line="1826"/>
         <source>Add working folder file(s) (selected or all yet untracked) to local repository (on next commit)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1691"/>
+        <location filename="mainwindow.cpp" line="1828"/>
         <source>Remove</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1692"/>
+        <location filename="mainwindow.cpp" line="1829"/>
         <source>Remove selected working folder file from local repository (on next commit)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1695"/>
+        <location filename="mainwindow.cpp" line="1832"/>
         <source>Update working folder from local repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1697"/>
+        <location filename="mainwindow.cpp" line="1834"/>
         <source>Commit</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1698"/>
+        <location filename="mainwindow.cpp" line="1835"/>
         <source>Save selected file(s) or all changed files in working folder (and all subfolders) to local repository</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1701"/>
+        <location filename="mainwindow.cpp" line="1838"/>
         <source>Merge two local repository changesets to working folder</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1707"/>
+        <location filename="mainwindow.cpp" line="1844"/>
         <source>Annotate</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1708"/>
+        <location filename="mainwindow.cpp" line="1845"/>
         <source>Show line-by-line version information for selected file</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1710"/>
-        <source>Resolve (list)</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1711"/>
-        <source>Resolve (list): Show list of files needing merge</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1713"/>
-        <source>Resolve (mark)</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1714"/>
-        <source>Resolve (mark): Mark selected file status as resolved</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1716"/>
-        <source>Retry merge</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1717"/>
-        <source>Retry merge after failed merge attempt.</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="mainwindow.cpp" line="1719"/>
+        <location filename="mainwindow.cpp" line="1847"/>
         <source>Tag revision</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1720"/>
+        <location filename="mainwindow.cpp" line="1848"/>
         <source>Give decsriptive name (tag) to current workfolder parent revision.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1722"/>
+        <location filename="mainwindow.cpp" line="1850"/>
         <source>Edit .hgignore</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1723"/>
+        <location filename="mainwindow.cpp" line="1851"/>
         <source>Edit .hgignore file (file contains names of files that should be ignored by mercurial)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1725"/>
+        <location filename="mainwindow.cpp" line="1853"/>
         <source>Serve (via http)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1726"/>
+        <location filename="mainwindow.cpp" line="1854"/>
         <source>Serve local repository via http for workgroup access</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1729"/>
+        <location filename="mainwindow.cpp" line="1857"/>
         <source>About</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1730"/>
+        <location filename="mainwindow.cpp" line="1858"/>
         <source>Show the application&apos;s About box</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1732"/>
+        <location filename="mainwindow.cpp" line="1860"/>
         <source>About Qt</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1733"/>
+        <location filename="mainwindow.cpp" line="1861"/>
         <source>Show the Qt library&apos;s About box</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1736"/>
+        <location filename="mainwindow.cpp" line="1864"/>
         <source>Clear selections</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1742"/>
-        <location filename="mainwindow.cpp" line="1777"/>
+        <location filename="mainwindow.cpp" line="1870"/>
+        <location filename="mainwindow.cpp" line="1905"/>
         <source>File</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1753"/>
+        <location filename="mainwindow.cpp" line="1881"/>
         <source>Advanced</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1770"/>
+        <location filename="mainwindow.cpp" line="1898"/>
         <source>Help</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="mainwindow.cpp" line="1816"/>
+        <location filename="mainwindow.cpp" line="1942"/>
         <source>Ready</source>
         <translation type="unfinished"></translation>
     </message>
@@ -892,7 +932,7 @@
 <context>
     <name>QApplication</name>
     <message>
-        <location filename="main.cpp" line="29"/>
+        <location filename="main.cpp" line="30"/>
         <source>EasyMercurial</source>
         <translation type="unfinished"></translation>
     </message>
@@ -901,32 +941,38 @@
     <name>QObject</name>
     <message>
         <location filename="changeset.cpp" line="72"/>
-        <source>Identifier</source>
+        <source>Identifier:</source>
+        <oldsource>Identifier</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="changeset.cpp" line="73"/>
-        <source>Author</source>
+        <source>Author:</source>
+        <oldsource>Author</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="changeset.cpp" line="74"/>
-        <source>Date</source>
+        <source>Date:</source>
+        <oldsource>Date</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="changeset.cpp" line="75"/>
-        <source>Branch</source>
+        <source>Branch:</source>
+        <oldsource>Branch</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="changeset.cpp" line="76"/>
-        <source>Tag</source>
+        <source>Tag:</source>
+        <oldsource>Tag</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="changeset.cpp" line="77"/>
-        <source>Comment</source>
+        <source>Comment:</source>
+        <oldsource>Comment</oldsource>
         <translation type="unfinished"></translation>
     </message>
 </context>
@@ -969,37 +1015,42 @@
 <context>
     <name>UncommittedItem</name>
     <message>
-        <location filename="uncommitteditem.cpp" line="71"/>
-        <source>&lt;qt&gt;&amp;nbsp;&lt;b&gt;Uncommitted changes&lt;/b&gt;&lt;/qt&gt;</source>
+        <location filename="uncommitteditem.cpp" line="72"/>
+        <source>&lt;qt&gt;&lt;b&gt;&amp;nbsp;Uncommitted changes&lt;/b&gt;&lt;/qt&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="uncommitteditem.cpp" line="77"/>
+        <location filename="uncommitteditem.cpp" line="78"/>
         <source>Diff</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="uncommitteditem.cpp" line="82"/>
+        <location filename="uncommitteditem.cpp" line="80"/>
+        <source>Show summary</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="uncommitteditem.cpp" line="85"/>
         <source>Commit...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="uncommitteditem.cpp" line="84"/>
+        <location filename="uncommitteditem.cpp" line="87"/>
         <source>Revert...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="uncommitteditem.cpp" line="130"/>
+        <location filename="uncommitteditem.cpp" line="133"/>
         <source>Uncommitted changes</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="uncommitteditem.cpp" line="135"/>
+        <location filename="uncommitteditem.cpp" line="138"/>
         <source>Uncommitted</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="uncommitteditem.cpp" line="139"/>
+        <location filename="uncommitteditem.cpp" line="142"/>
         <source>changes</source>
         <translation type="unfinished"></translation>
     </message>
--- a/grapher.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/grapher.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -546,7 +546,7 @@
                 item->setRows(changeRow, n);
                 item->setEven(even);
                 item->setZValue(-1);
-                m_scene->addItem(item);
+                m_scene->addDateItem(item);
                 even = !even;
             }
             prevDate = date;
@@ -562,7 +562,7 @@
         item->setRows(changeRow, n+1);
         item->setEven(even);
         item->setZValue(-1);
-        m_scene->addItem(item);
+        m_scene->addDateItem(item);
         even = !even;
     }
 }
--- a/hgaction.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/hgaction.h	Tue Dec 14 17:20:10 2010 +0000
@@ -41,6 +41,7 @@
     ACT_INIT,
     ACT_COMMIT,
     ACT_ANNOTATE,
+    ACT_DIFF_SUMMARY,
     ACT_FOLDERDIFF,
     ACT_CHGSETDIFF,
     ACT_UPDATE,
--- a/hgtabwidget.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/hgtabwidget.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -49,6 +49,9 @@
     connect(m_historyWidget, SIGNAL(revert()),
             this, SIGNAL(revert()));
     
+    connect(m_historyWidget, SIGNAL(showSummary()),
+            this, SIGNAL(showSummary()));
+    
     connect(m_historyWidget, SIGNAL(diffWorkingFolder()),
             this, SIGNAL(diffWorkingFolder()));
 
--- a/hgtabwidget.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/hgtabwidget.h	Tue Dec 14 17:20:10 2010 +0000
@@ -84,6 +84,7 @@
     void commit();
     void revert();
     void diffWorkingFolder();
+    void showSummary();
 
     void updateTo(QString id);
     void diffToParent(QString id, QString parent);
--- a/historywidget.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/historywidget.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -35,6 +35,8 @@
     m_panned = new Panned;
     m_panner = new Panner;
 
+    m_panned->setDragMode(QGraphicsView::ScrollHandDrag);
+
     QGridLayout *layout = new QGridLayout;
     layout->addWidget(m_panned, 0, 0);
     layout->addWidget(m_panner, 0, 1);
@@ -259,6 +261,9 @@
     connect(scene, SIGNAL(diffWorkingFolder()),
             this, SIGNAL(diffWorkingFolder()));
 
+    connect(scene, SIGNAL(showSummary()),
+            this, SIGNAL(showSummary()));
+
     connect(scene, SIGNAL(showWork()),
             this, SIGNAL(showWork()));
     
--- a/historywidget.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/historywidget.h	Tue Dec 14 17:20:10 2010 +0000
@@ -49,6 +49,7 @@
     void commit();
     void revert();
     void diffWorkingFolder();
+    void showSummary();
     void showWork();
 
     void updateTo(QString id);
--- a/mainwindow.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/mainwindow.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -305,7 +305,7 @@
          tr("<h3>%1</h3><p>%2").arg(cf)
          .arg(tr("You are about to commit the following files:")),
          tr("<h3>%1</h3><p>%2").arg(cf)
-         .arg(tr("You are about to commit %n file(s):", "", reportFiles.size())),
+         .arg(tr("You are about to commit %n file(s).", "", reportFiles.size())),
          reportFiles,
          comment)) {
 
@@ -438,6 +438,15 @@
     mergeBinaryName = merge;
 }
 
+void MainWindow::hgShowSummary()
+{
+    QStringList params;
+    
+    params << "diff" << "--stat";
+
+    runner->requestAction(HgAction(ACT_DIFF_SUMMARY, workFolderPath, params));
+}
+
 void MainWindow::hgFolderDiff()
 {
     if (diffBinaryName == "") return;
@@ -1166,15 +1175,16 @@
 
 QString MainWindow::format3(QString head, QString intro, QString code)
 {
+    code = xmlEncode(code).replace("\n", "<br>").replace(" ", "&nbsp;");
     if (intro == "") {
-        return QString("<qt><h3>%1</h3><code>%2</code>")
-            .arg(head).arg(xmlEncode(code).replace("\n", "<br>"));
+        return QString("<qt><h3>%1</h3><p><code>%2</code></p>")
+            .arg(head).arg(code);
     } else if (code == "") {
         return QString("<qt><h3>%1</h3><p>%2</p>")
             .arg(head).arg(intro);
     } else {
-        return QString("<qt><h3>%1</h3><p>%2</p><code>%3</code>")
-            .arg(head).arg(intro).arg(xmlEncode(code).replace("\n", "<br>"));
+        return QString("<qt><h3>%1</h3><p>%2</p><p><code>%3</code></p>")
+            .arg(head).arg(intro).arg(code);
     }
 }
 
@@ -1431,6 +1441,13 @@
         shouldHgStat = true;
         break;
 
+    case ACT_DIFF_SUMMARY:
+        QMessageBox::information(this, tr("Change summary"),
+                                 format3(tr("Summary of uncommitted changes"),
+                                         "",
+                                         output));
+        break;
+
     case ACT_FOLDERDIFF:
     case ACT_CHGSETDIFF:
     case ACT_SERVE:
@@ -1576,6 +1593,9 @@
     
     connect(hgTabs, SIGNAL(diffWorkingFolder()),
             this, SLOT(hgFolderDiff()));
+    
+    connect(hgTabs, SIGNAL(showSummary()),
+            this, SLOT(hgShowSummary()));
 
     connect(hgTabs, SIGNAL(updateTo(QString)),
             this, SLOT(hgUpdateToRev(QString)));
--- a/mainwindow.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/mainwindow.h	Tue Dec 14 17:20:10 2010 +0000
@@ -74,6 +74,7 @@
     void hgRemove();
     void hgAdd();
     void hgCommit();
+    void hgShowSummary();
     void hgFolderDiff();
     void hgDiffToCurrent(QString);
     void hgDiffToParent(QString, QString);
--- a/panned.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/panned.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -20,11 +20,18 @@
 
 #include <QScrollBar>
 #include <QWheelEvent>
+#include <QTimer>
+
+#include <cmath>
 
 #include <iostream>
 
-Panned::Panned()
+Panned::Panned() :
+    m_dragging(false)
 {
+    m_dragTimer = new QTimer(this);
+    m_dragTimerMs = 50;
+    connect(m_dragTimer, SIGNAL(timeout()), this, SLOT(dragTimerTimeout()));
     setRenderHints(QPainter::Antialiasing |
                    QPainter::TextAntialiasing);
 }
@@ -149,6 +156,93 @@
 }
 
 void
+Panned::mousePressEvent(QMouseEvent *ev)
+{
+    if (dragMode() != QGraphicsView::ScrollHandDrag ||
+        ev->button() != Qt::LeftButton) {
+        QGraphicsView::mousePressEvent(ev);
+        return;
+    }
+
+    DEBUG << "Panned::mousePressEvent: have left button in drag mode" << endl;
+
+    setDragMode(QGraphicsView::NoDrag);
+    QGraphicsView::mousePressEvent(ev);
+    setDragMode(QGraphicsView::ScrollHandDrag);
+
+    if (!ev->isAccepted()) {
+        ev->accept();
+        m_dragging = true;
+        m_lastDragPos = ev->pos();
+        m_lastOrigin = QPoint(horizontalScrollBar()->value(),
+                              verticalScrollBar()->value());
+        m_velocity = QPointF(0, 0);
+        m_dragTimer->start(m_dragTimerMs);
+    }
+
+}
+
+void
+Panned::mouseMoveEvent(QMouseEvent *ev)
+{
+    if (!m_dragging) {
+        QGraphicsView::mouseMoveEvent(ev);
+        return;
+    }
+    DEBUG << "Panned::mouseMoveEvent: dragging" << endl;
+    ev->accept();
+    QScrollBar *hBar = horizontalScrollBar();
+    QScrollBar *vBar = verticalScrollBar();
+    QPoint delta = ev->pos() - m_lastDragPos;
+    hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
+    vBar->setValue(vBar->value() - delta.y());
+    m_lastDragPos = ev->pos();
+}
+
+void
+Panned::mouseReleaseEvent(QMouseEvent *ev)
+{
+    if (!m_dragging) {
+        QGraphicsView::mouseReleaseEvent(ev);
+        return;
+    }
+    DEBUG << "Panned::mouseReleaseEvent: dragging" << endl;
+    ev->accept();
+    m_dragging = false;
+}
+
+void
+Panned::dragTimerTimeout()
+{
+    QPoint origin = QPoint(horizontalScrollBar()->value(),
+                           verticalScrollBar()->value());
+    if (m_dragging) {
+        m_velocity = QPointF
+            (float(origin.x() - m_lastOrigin.x()) / m_dragTimerMs,
+             float(origin.y() - m_lastOrigin.y()) / m_dragTimerMs);
+        m_lastOrigin = origin;
+        DEBUG << "Panned::dragTimerTimeout: velocity = " << m_velocity << endl;
+    } else {
+        if (origin == m_lastOrigin) {
+            m_dragTimer->stop();
+        }
+        float x = m_velocity.x(), y = m_velocity.y();
+        if (fabsf(x) > 1.0/m_dragTimerMs) x = x * 0.9f;
+        else x = 0.f;
+        if (fabsf(y) > 1.0/m_dragTimerMs) y = y * 0.9f;
+        else y = 0.f;
+        m_velocity = QPointF(x, y);
+        DEBUG << "Panned::dragTimerTimeout: velocity adjusted to " << m_velocity << endl;
+        m_lastOrigin = origin;
+        //!!! need to store origin in floats
+        horizontalScrollBar()->setValue(m_lastOrigin.x() +
+                                        m_velocity.x() * m_dragTimerMs);
+        verticalScrollBar()->setValue(m_lastOrigin.y() +
+                                      m_velocity.y() * m_dragTimerMs);
+    }
+}
+
+void
 Panned::leaveEvent(QEvent *)
 {
     emit mouseLeaves();
--- a/panned.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/panned.h	Tue Dec 14 17:20:10 2010 +0000
@@ -22,6 +22,7 @@
 
 class QWheelEvent;
 class QEvent;
+class QTimer;
 
 class Panned : public QGraphicsView
 {
@@ -46,9 +47,23 @@
     void zoomIn();
     void zoomOut();
 
+private slots:
+    void dragTimerTimeout();
+
 protected:
     QRectF m_pannedRect;
 
+    QPoint m_lastDragPos;
+    QPoint m_lastOrigin;
+    QPointF m_velocity;
+    bool m_dragging;
+    int m_dragTimerMs;
+    QTimer *m_dragTimer;
+
+    virtual void mousePressEvent(QMouseEvent *);
+    virtual void mouseMoveEvent(QMouseEvent *);
+    virtual void mouseReleaseEvent(QMouseEvent *);
+
     virtual void paintEvent(QPaintEvent *);
     virtual void resizeEvent(QResizeEvent *);
     virtual void drawForeground(QPainter *, const QRectF &);
--- a/uncommitteditem.cpp	Wed Dec 08 16:57:18 2010 +0000
+++ b/uncommitteditem.cpp	Tue Dec 14 17:20:10 2010 +0000
@@ -35,6 +35,7 @@
     m_font.setPixelSize(11);
     m_font.setBold(false);
     m_font.setItalic(false);
+    setCursor(Qt::ArrowCursor);
 }
 
 QRectF
@@ -76,6 +77,8 @@
 
     QAction *dif = menu->addAction(tr("Diff"));
     connect(dif, SIGNAL(triggered()), this, SIGNAL(diff()));
+    QAction *stat = menu->addAction(tr("Show summary"));
+    connect(stat, SIGNAL(triggered()), this, SIGNAL(showSummary()));
     
     menu->addSeparator();
 
--- a/uncommitteditem.h	Wed Dec 08 16:57:18 2010 +0000
+++ b/uncommitteditem.h	Tue Dec 14 17:20:10 2010 +0000
@@ -18,13 +18,12 @@
 #ifndef UNCOMMITTEDITEM_H
 #define UNCOMMITTEDITEM_H
 
-#include <QGraphicsItem>
+#include <QGraphicsObject>
 #include <QFont>
 
-class UncommittedItem : public QObject, public QGraphicsItem
+class UncommittedItem : public QGraphicsObject
 {
     Q_OBJECT
-    Q_INTERFACES(QGraphicsItem)
 
 public:
     UncommittedItem();
@@ -50,6 +49,7 @@
     void commit();
     void revert();
     void diff();
+    void showSummary();
     void showWork();
 
 protected: