# HG changeset patch # User Chris Cannam # Date 1289159994 0 # Node ID c32067cd19f8edcd580a98a41648f971d095ff7f # Parent 9a89dedf260a7898a4b0d5c2c3754c5b51a72834 * Some experiments towards a graph history view diff -r 9a89dedf260a -r c32067cd19f8 changeset.cpp --- /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" diff -r 9a89dedf260a -r c32067cd19f8 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 +#include +#include +#include + +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 Changesets; + +#endif // CHANGESET_H diff -r 9a89dedf260a -r c32067cd19f8 changesetitem.cpp --- /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 + +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)); +} diff -r 9a89dedf260a -r c32067cd19f8 changesetitem.h --- /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 + +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 diff -r 9a89dedf260a -r c32067cd19f8 hgexplorer.pro --- 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 diff -r 9a89dedf260a -r c32067cd19f8 hgexpwidget.cpp --- 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(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() diff -r 9a89dedf260a -r c32067cd19f8 hgexpwidget.h --- 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 #include +#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); }; diff -r 9a89dedf260a -r c32067cd19f8 hgrunner.cpp --- 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 #include +#include #include 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); } diff -r 9a89dedf260a -r c32067cd19f8 logparser.cpp --- /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 +#include + +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; +} diff -r 9a89dedf260a -r c32067cd19f8 logparser.h --- /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 +#include +#include +#include + +typedef QMap LogEntry; +typedef QList LogList; + +class LogParser : public QObject +{ +public: + LogParser(QString text); + + QStringList split(); + LogList parse(); + +private: + QString m_text; +}; + +#endif // LOGPARSER_H diff -r 9a89dedf260a -r c32067cd19f8 main.cpp --- 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(); diff -r 9a89dedf260a -r c32067cd19f8 mainwindow.cpp --- 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);