changeset 43:c32067cd19f8

* Some experiments towards a graph history view
author Chris Cannam
date Sun, 07 Nov 2010 19:59:54 +0000
parents 9a89dedf260a
children bed7ab59f62e
files changeset.cpp changeset.h changesetitem.cpp changesetitem.h hgexplorer.pro hgexpwidget.cpp hgexpwidget.h hgrunner.cpp logparser.cpp logparser.h main.cpp mainwindow.cpp
diffstat 12 files changed, 251 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/changeset.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -0,0 +1,1 @@
+#include "changeset.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/changeset.h	Sun Nov 07 19:59:54 2010 +0000
@@ -0,0 +1,66 @@
+#ifndef CHANGESET_H
+#define CHANGESET_H
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QList>
+
+class Changeset : public QObject
+{
+    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 branch READ branch WRITE setBranch NOTIFY branchChanged STORED true);
+    Q_PROPERTY(QString date READ date WRITE setDate NOTIFY dateChanged STORED true);
+    Q_PROPERTY(QString age READ age WRITE setAge NOTIFY ageChanged STORED true);
+    Q_PROPERTY(QStringList parents READ parents WRITE setParents NOTIFY parentsChanged STORED true);
+    Q_PROPERTY(QString comment READ comment WRITE setComment NOTIFY commentChanged STORED true);
+
+public:
+    Changeset() : QObject() { }
+
+    QString id() const { return m_id; }
+    QString author() const { return m_author; }
+    QString branch() const { return m_branch; }
+    QString date() const { return m_date; }
+    QString age() const { return m_age; }
+    QStringList parents() const { return m_parents; }
+    QString comment() const { return m_comment; }
+
+    int number() const {
+        return id().split(':')[0].toInt();
+    }
+
+signals:
+    void idChanged(QString id);
+    void authorChanged(QString author);
+    void branchChanged(QString branch);
+    void dateChanged(QString date);
+    void ageChanged(QString age);
+    void parentsChanged(QStringList parents);
+    void commentChanged(QString comment);
+
+public slots:
+    void setId(QString id) { m_id = id; emit idChanged(id); }
+    void setAuthor(QString author) { m_author = author; emit authorChanged(author); }
+    void setBranch(QString branch) { m_branch = branch; emit branchChanged(branch); }
+    void setDate(QString date) { m_date = date; emit dateChanged(date); }
+    void setAge(QString age) { m_age = age; emit ageChanged(age); }
+    void setParents(QStringList parents) { m_parents = parents; emit parentsChanged(parents); }
+    void setComment(QString comment) { m_comment = comment; emit commentChanged(comment); }
+
+private:
+    QString m_id;
+    QString m_author;
+    QString m_branch;
+    QString m_date;
+    QString m_age;
+    QStringList m_parents;
+    QString m_comment;
+};
+
+typedef QList<Changeset *> Changesets;
+
+#endif // CHANGESET_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/changesetitem.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -0,0 +1,21 @@
+#include "changesetitem.h"
+#include "changeset.h"
+
+#include <QPainter>
+
+QRectF
+ChangesetItem::boundingRect() const
+{
+    int n = m_changeset->number();
+    return QRectF(0, 0, 250, 50);
+}
+
+void
+ChangesetItem::paint(QPainter *paint, const QStyleOptionGraphicsItem *option,
+                     QWidget *w)
+{
+    paint->drawText(50, 0, m_changeset->comment());
+    paint->drawRect(QRectF(0, 0, 50, 50));
+
+//    paint->drawRect(QRectF(0, 0, 50, 50));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/changesetitem.h	Sun Nov 07 19:59:54 2010 +0000
@@ -0,0 +1,20 @@
+#ifndef CHANGESETITEM_H
+#define CHANGESETITEM_H
+
+#include <QGraphicsItem>
+
+class Changeset;
+
+class ChangesetItem : public QGraphicsItem
+{
+public:
+    ChangesetItem(Changeset *cs) : m_changeset(cs) { }
+
+    virtual QRectF boundingRect() const;
+    virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+
+private:
+    Changeset *m_changeset;
+};
+
+#endif // CHANGESETITEM_H
--- a/hgexplorer.pro	Thu Jun 24 23:41:21 2010 +0300
+++ b/hgexplorer.pro	Sun Nov 07 19:59:54 2010 +0000
@@ -1,25 +1,31 @@
-TEMPLATE = app
-TARGET = hgexplorer
-unix {
-    DESTDIR = .
-}
-
-HEADERS = mainwindow.h \
-    hgexpwidget.h \
-    common.h \
-    hgrunner.h \
-    settingsdialog.h
-SOURCES = main.cpp \
-    mainwindow.cpp \
-    hgexpwidget.cpp \
-    hgrunner.cpp \
-    settingsdialog.cpp \
-    common.cpp
-
-# ! [0]
-RESOURCES = hgexplorer.qrc
-win32 {
-    RC_FILE = hgexplorer.rc
-}
-
-QT += network
+TEMPLATE = app
+TARGET = hgexplorer
+unix {
+    DESTDIR = .
+}
+
+HEADERS = mainwindow.h \
+    hgexpwidget.h \
+    common.h \
+    hgrunner.h \
+    settingsdialog.h \
+    changeset.h \
+    changesetitem.h \
+    logparser.h
+SOURCES = main.cpp \
+    mainwindow.cpp \
+    hgexpwidget.cpp \
+    hgrunner.cpp \
+    settingsdialog.cpp \
+    common.cpp \
+    changeset.cpp \
+    changesetitem.cpp \
+    logparser.cpp
+
+# ! [0]
+RESOURCES = hgexplorer.qrc
+win32 {
+    RC_FILE = hgexplorer.rc
+}
+
+QT += network
--- a/hgexpwidget.cpp	Thu Jun 24 23:41:21 2010 +0300
+++ b/hgexpwidget.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -8,6 +8,9 @@
 
 #include "hgexpwidget.h"
 #include "common.h"
+#include "logparser.h"
+#include "changeset.h"
+#include "changesetitem.h"
 
 #define REMOTE_REPO_STR  "Remote repository: "
 #define LOCAL_REPO_STR   "Local repository: "
@@ -84,6 +87,11 @@
     mainLayout -> addWidget(grpWorkFolder, 12);
     addTab(workPageWidget, tr("Work"));
 
+    // History graph page
+    historyGraphPageWidget = new QGraphicsView;
+    addTab(historyGraphPageWidget, tr("History (graph)"));
+
+
     //History page
     //History page
     //History page
@@ -232,9 +240,22 @@
     localRepoHgLogList -> clear();
     localRepoHgLogList -> addItems(splitChangeSets(hgLogList));
 
+    //!!!
+    QGraphicsView *gv = static_cast<QGraphicsView *>(historyGraphPageWidget);
+    gv->scene()->deleteLater();
+    QGraphicsScene *scene = new QGraphicsScene();
+    Changesets csets = parseChangeSets(hgLogList);
+    foreach (Changeset *cs, csets) {
+        ChangesetItem *item = new ChangesetItem(cs);
+        item->setX(0);
+        item->setY(cs->number() * 100);
+        scene->addItem(item);
+    }
+    gv->setScene(scene);
 }
 
 
+
 int HgExpWidget::findLineStart(int nowIndex, QString str)
 {
     if (nowIndex < 0)
@@ -256,6 +277,8 @@
 
 QStringList HgExpWidget::splitChangeSets(QString chgSetsStr)
 {
+    return LogParser(chgSetsStr).split();
+    /*
     int currChgSet;
     int currChgSetLineStart;
 
@@ -293,6 +316,21 @@
     }
 
     return tmp;
+    */
+}
+
+Changesets HgExpWidget::parseChangeSets(QString changeSetsStr)
+{
+    Changesets csets;
+    LogList log = LogParser(changeSetsStr).parse();
+    foreach (LogEntry e, log) {
+        Changeset *cs = new Changeset();
+        foreach (QString key, e.keys()) {
+            cs->setProperty(key.toLocal8Bit().data(), e.value(key));
+        }
+        csets.push_back(cs);
+    }
+    return csets;
 }
 
 QString HgExpWidget::getCurrentFileListLine()
--- a/hgexpwidget.h	Thu Jun 24 23:41:21 2010 +0300
+++ b/hgexpwidget.h	Sun Nov 07 19:59:54 2010 +0000
@@ -9,6 +9,7 @@
 #include <QtCore>
 #include <QMenu>
 
+#include "changeset.h"
 #include "common.h"
 
 #define NUM_STAT_FILE_TYPES 7
@@ -48,6 +49,7 @@
 private:
     QGroupBox   *grpRemoteRepo;
     QWidget     *workPageWidget;
+    QWidget     *historyGraphPageWidget;
     QWidget     *historyPageWidget;
     QWidget     *headsPageWidget;
 
@@ -72,6 +74,8 @@
 
     QString     findRev(QString itemText, QString& smallRev);
     QStringList splitChangeSets(QString chgSetsStr);
+    Changesets  parseChangeSets(QString changeSetsStr);
+
     int findLineStart(int nowIndex, QString chgSetsStr);
     void contextMenuEvent (QContextMenuEvent * event);
 };
--- a/hgrunner.cpp	Thu Jun 24 23:41:21 2010 +0300
+++ b/hgrunner.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -6,6 +6,7 @@
 #include <QtCore>
 #include <QtGui>
 
+#include <iostream>
 #include <unistd.h>
 
 HgRunner::HgRunner(QWidget * parent): QProgressBar(parent)
@@ -40,6 +41,7 @@
     exitStatus = procExitStatus;
     stdOut = proc -> readAllStandardOutput();
     stdErr = proc -> readAllStandardError();
+    std::cerr << "stdout was " << stdOut.toStdString() << std::endl;
 }
 
 void HgRunner::presentErrorToUser()
@@ -149,6 +151,10 @@
     lastHgCommand = hgExePathAndName;
     lastParams = params.join(" ");
 
+    std::cerr << "HgRunner: starting: " << hgExePathAndName.toStdString();
+    foreach (QString param, params) std::cerr << param.toStdString() << " ";
+    std::cerr << std::endl;
+
     proc -> start(hgExePathAndName, params);
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/logparser.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -0,0 +1,34 @@
+#include "logparser.h"
+
+#include <QStringList>
+#include <QRegExp>
+
+LogParser::LogParser(QString text) : m_text(text)
+{
+    m_text.replace("\r\n", "\n");
+}
+
+QStringList LogParser::split()
+{
+    return m_text.split("\n\n", QString::SkipEmptyParts);
+}
+
+LogList LogParser::parse()
+{
+    LogList results;
+    QRegExp re("^(\\w+):\\s+(.*)$");
+    QStringList entries = split();
+    foreach (QString entry, entries) {
+        LogEntry dictionary;
+        QStringList lines = entry.split('\n');
+        foreach (QString line, lines) {
+            if (re.indexIn(line) == 0) {
+                QString key = re.cap(1);
+                QString value = re.cap(2);
+                dictionary[key] = value;
+            }
+        }
+        results.push_back(dictionary);
+    }
+    return results;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/logparser.h	Sun Nov 07 19:59:54 2010 +0000
@@ -0,0 +1,24 @@
+#ifndef LOGPARSER_H
+#define LOGPARSER_H
+
+#include <QObject>
+#include <QString>
+#include <QList>
+#include <QMap>
+
+typedef QMap<QString, QString> LogEntry;
+typedef QList<LogEntry> LogList;
+
+class LogParser : public QObject
+{
+public:
+    LogParser(QString text);
+
+    QStringList split();
+    LogList parse();
+
+private:
+    QString m_text;
+};
+
+#endif // LOGPARSER_H
--- a/main.cpp	Thu Jun 24 23:41:21 2010 +0300
+++ b/main.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -21,7 +21,7 @@
     QApplication app(argc, argv);
 
     app.setApplicationName(APPNAME);
-
+/*
     #ifdef Q_WS_X11
     app.setStyle(new QCleanlooksStyle);
     #endif
@@ -29,7 +29,7 @@
     #ifdef Q_WS_WIN
     app.setStyle(new QWindowsXPStyle);
     #endif
-
+*/
     MainWindow mainWin;
     mainWin.show();
     return app.exec();
--- a/mainwindow.cpp	Thu Jun 24 23:41:21 2010 +0300
+++ b/mainwindow.cpp	Sun Nov 07 19:59:54 2010 +0000
@@ -119,7 +119,9 @@
     if (runningAction == ACT_NONE)
     {
         QStringList params;
-        params << "glog";
+        params << "log";
+        params << "--template";
+        params << "id: {rev}:{node|short}\\nauthor: {author}\\nbranch: {branches}\\ndate: {date|isodate}\\nage: {date|age}\\nparents: {parents}\\ncomment: {desc|json}\\n\\n";
 
         runner -> startProc(getHgBinaryName(), workFolderPath, params);
         runningAction = ACT_LOG;
@@ -1370,7 +1372,7 @@
     fileToolBar = addToolBar(tr("File"));
     fileToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE));
     fileToolBar -> addAction(settingsAct);
-    fileToolBar -> addAction(exitAct);
+    fileToolBar -> addAction(hgStatAct);
     fileToolBar -> addSeparator();
     fileToolBar -> addAction(hgChgSetDiffAct);
     fileToolBar -> setMovable(false);
@@ -1385,7 +1387,6 @@
     workFolderToolBar = addToolBar(tr(WORKFOLDERMENU_TITLE));
     addToolBar(Qt::LeftToolBarArea, workFolderToolBar);
     workFolderToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE));
-    workFolderToolBar->addAction(hgStatAct);
     workFolderToolBar->addSeparator();
     workFolderToolBar->addAction(hgFileDiffAct);
     workFolderToolBar->addAction(hgFolderDiffAct);