| Chris@57 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@57 | 2 | 
| Chris@57 | 3 /* | 
| Chris@57 | 4     EasyMercurial | 
| Chris@57 | 5 | 
| Chris@57 | 6     Based on HgExplorer by Jari Korhonen | 
| Chris@57 | 7     Copyright (c) 2010 Jari Korhonen | 
| Chris@57 | 8     Copyright (c) 2010 Chris Cannam | 
| Chris@57 | 9     Copyright (c) 2010 Queen Mary, University of London | 
| Chris@57 | 10 | 
| Chris@57 | 11     This program is free software; you can redistribute it and/or | 
| Chris@57 | 12     modify it under the terms of the GNU General Public License as | 
| Chris@57 | 13     published by the Free Software Foundation; either version 2 of the | 
| Chris@57 | 14     License, or (at your option) any later version.  See the file | 
| Chris@57 | 15     COPYING included with this distribution for more information. | 
| Chris@57 | 16 */ | 
| jtkorhonen@0 | 17 | 
| jtkorhonen@0 | 18 #include "hgexpwidget.h" | 
| jtkorhonen@0 | 19 #include "common.h" | 
| Chris@43 | 20 #include "logparser.h" | 
| Chris@43 | 21 #include "changeset.h" | 
| Chris@43 | 22 #include "changesetitem.h" | 
| Chris@44 | 23 #include "grapher.h" | 
| cannam@45 | 24 #include "panner.h" | 
| cannam@45 | 25 #include "panned.h" | 
| Chris@88 | 26 #include "filestatuswidget.h" | 
| Chris@44 | 27 | 
| Chris@50 | 28 #include <QClipboard> | 
| Chris@50 | 29 #include <QContextMenuEvent> | 
| Chris@50 | 30 #include <QApplication> | 
| Chris@50 | 31 | 
| Chris@44 | 32 #include <iostream> | 
| jtkorhonen@0 | 33 | 
| Chris@88 | 34 HgExpWidget::HgExpWidget(QWidget *parent, QString remoteRepo, | 
| Chris@88 | 35                          QString workFolderPath, | 
| Chris@88 | 36                          unsigned char viewFileTypesBits) : | 
| Chris@88 | 37     QTabWidget(parent) | 
| jtkorhonen@0 | 38 { | 
| Chris@91 | 39     // Work page | 
| Chris@88 | 40     fileStatusWidget = new FileStatusWidget; | 
| Chris@89 | 41     fileStatusWidget->setLocalPath(workFolderPath); | 
| Chris@89 | 42     fileStatusWidget->setRemoteURL(remoteRepo); | 
| Chris@89 | 43     addTab(fileStatusWidget, tr("My work")); | 
| Chris@88 | 44 | 
| Chris@43 | 45     // History graph page | 
| cannam@45 | 46     historyGraphPageWidget = new QWidget; | 
| cannam@45 | 47     Panned *panned = new Panned; | 
| cannam@45 | 48     Panner *panner = new Panner; | 
| cannam@45 | 49     historyGraphWidget = panned; | 
| cannam@45 | 50     historyGraphPanner = panner; | 
| cannam@45 | 51     QGridLayout *layout = new QGridLayout; | 
| cannam@45 | 52     layout->addWidget(historyGraphWidget, 0, 0); | 
| cannam@45 | 53     layout->addWidget(historyGraphPanner, 0, 1); | 
| cannam@45 | 54     panner->setMaximumWidth(80); | 
| cannam@45 | 55     panner->connectToPanned(panned); | 
| cannam@45 | 56     historyGraphPageWidget->setLayout(layout); | 
| Chris@58 | 57     addTab(historyGraphPageWidget, tr("History")); | 
| jtkorhonen@32 | 58 } | 
| jtkorhonen@32 | 59 | 
| Chris@94 | 60 void HgExpWidget::clearSelections() | 
| Chris@94 | 61 { | 
| Chris@94 | 62     fileStatusWidget->clearSelections(); | 
| Chris@94 | 63 } | 
| Chris@94 | 64 | 
| Chris@90 | 65 bool HgExpWidget::canCommit() const | 
| Chris@90 | 66 { | 
| Chris@90 | 67     return fileStatusWidget->haveChangesToCommit(); | 
| Chris@90 | 68 } | 
| jtkorhonen@0 | 69 | 
| jtkorhonen@0 | 70 void HgExpWidget::updateWorkFolderFileList(QString fileList) | 
| jtkorhonen@0 | 71 { | 
| Chris@94 | 72     fileStates.parseStates(fileList); | 
| Chris@92 | 73     fileStatusWidget->setFileStates(fileStates); | 
| jtkorhonen@0 | 74 } | 
| jtkorhonen@0 | 75 | 
| jtkorhonen@0 | 76 void HgExpWidget::updateLocalRepoHgLogList(QString hgLogList) | 
| jtkorhonen@0 | 77 { | 
| Chris@43 | 78     //!!! | 
| cannam@45 | 79     Panned *panned = static_cast<Panned *>(historyGraphWidget); | 
| cannam@45 | 80     Panner *panner = static_cast<Panner *>(historyGraphPanner); | 
| Chris@43 | 81     QGraphicsScene *scene = new QGraphicsScene(); | 
| Chris@43 | 82     Changesets csets = parseChangeSets(hgLogList); | 
| Chris@44 | 83     if (csets.empty()) return; | 
| Chris@53 | 84     Grapher g(scene); | 
| Chris@44 | 85     try { | 
| Chris@53 | 86 	g.layout(csets); | 
| Chris@44 | 87     } catch (std::string s) { | 
| Chris@44 | 88 	std::cerr << "Internal error: Layout failed: " << s << std::endl; | 
| Chris@44 | 89     } | 
| Chris@87 | 90     QGraphicsScene *oldScene = panned->scene(); | 
| cannam@45 | 91     panned->setScene(scene); | 
| cannam@45 | 92     panner->setScene(scene); | 
| Chris@87 | 93     if (oldScene) delete oldScene; | 
| Chris@53 | 94     ChangesetItem *tipItem = g.getItemFor(csets[0]); | 
| Chris@53 | 95     if (tipItem) tipItem->ensureVisible(); | 
| jtkorhonen@0 | 96 } | 
| jtkorhonen@0 | 97 | 
| Chris@43 | 98 Changesets HgExpWidget::parseChangeSets(QString changeSetsStr) | 
| Chris@43 | 99 { | 
| Chris@43 | 100     Changesets csets; | 
| Chris@43 | 101     LogList log = LogParser(changeSetsStr).parse(); | 
| Chris@43 | 102     foreach (LogEntry e, log) { | 
| Chris@43 | 103         Changeset *cs = new Changeset(); | 
| Chris@43 | 104         foreach (QString key, e.keys()) { | 
| Chris@44 | 105 	    if (key == "parents") { | 
| Chris@44 | 106 		QStringList parents = e.value(key).split | 
| Chris@44 | 107 		    (" ", QString::SkipEmptyParts); | 
| Chris@44 | 108 		cs->setParents(parents); | 
| Chris@52 | 109 	    } else if (key == "timestamp") { | 
| Chris@52 | 110 		cs->setTimestamp(e.value(key).split(" ")[0].toULongLong()); | 
| Chris@44 | 111 	    } else { | 
| Chris@44 | 112 		cs->setProperty(key.toLocal8Bit().data(), e.value(key)); | 
| Chris@44 | 113 	    } | 
| Chris@43 | 114         } | 
| Chris@43 | 115         csets.push_back(cs); | 
| Chris@43 | 116     } | 
| Chris@44 | 117     for (int i = 0; i+1 < csets.size(); ++i) { | 
| Chris@44 | 118 	Changeset *cs = csets[i]; | 
| Chris@44 | 119 	if (cs->parents().empty()) { | 
| Chris@44 | 120 	    QStringList list; | 
| Chris@44 | 121 	    list.push_back(csets[i+1]->id()); | 
| Chris@44 | 122 	    cs->setParents(list); | 
| Chris@44 | 123 	} | 
| Chris@44 | 124     } | 
| Chris@43 | 125     return csets; | 
| jtkorhonen@0 | 126 } | 
| jtkorhonen@0 | 127 | 
| jtkorhonen@0 | 128 void HgExpWidget::setWorkFolderAndRepoNames(QString workFolderPath, QString remoteRepoPath) | 
| jtkorhonen@0 | 129 { | 
| Chris@89 | 130     fileStatusWidget->setLocalPath(workFolderPath); | 
| Chris@89 | 131     fileStatusWidget->setRemoteURL(remoteRepoPath); | 
| jtkorhonen@0 | 132 } |