| 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 | 
| Chris@96 | 18 #include "hgtabwidget.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@96 | 34 HgTabWidget::HgTabWidget(QWidget *parent, | 
| Chris@95 | 35                          QString remoteRepo, | 
| Chris@95 | 36                          QString workFolderPath) : | 
| Chris@106 | 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@95 | 43     connect(fileStatusWidget, SIGNAL(selectionChanged()), | 
| Chris@95 | 44             this, SIGNAL(selectionChanged())); | 
| Chris@89 | 45     addTab(fileStatusWidget, tr("My work")); | 
| Chris@88 | 46 | 
| Chris@43 | 47     // History graph page | 
| cannam@45 | 48     historyGraphPageWidget = new QWidget; | 
| cannam@45 | 49     Panned *panned = new Panned; | 
| cannam@45 | 50     Panner *panner = new Panner; | 
| cannam@45 | 51     historyGraphWidget = panned; | 
| cannam@45 | 52     historyGraphPanner = panner; | 
| cannam@45 | 53     QGridLayout *layout = new QGridLayout; | 
| cannam@45 | 54     layout->addWidget(historyGraphWidget, 0, 0); | 
| cannam@45 | 55     layout->addWidget(historyGraphPanner, 0, 1); | 
| cannam@45 | 56     panner->setMaximumWidth(80); | 
| cannam@45 | 57     panner->connectToPanned(panned); | 
| cannam@45 | 58     historyGraphPageWidget->setLayout(layout); | 
| Chris@58 | 59     addTab(historyGraphPageWidget, tr("History")); | 
| jtkorhonen@32 | 60 } | 
| jtkorhonen@32 | 61 | 
| Chris@96 | 62 void HgTabWidget::clearSelections() | 
| Chris@94 | 63 { | 
| Chris@94 | 64     fileStatusWidget->clearSelections(); | 
| Chris@94 | 65 } | 
| Chris@94 | 66 | 
| Chris@96 | 67 bool HgTabWidget::canCommit() const | 
| Chris@90 | 68 { | 
| Chris@90 | 69     return fileStatusWidget->haveChangesToCommit(); | 
| Chris@90 | 70 } | 
| jtkorhonen@0 | 71 | 
| Chris@96 | 72 bool HgTabWidget::canAdd() const | 
| Chris@95 | 73 { | 
| Chris@95 | 74     if (fileStatusWidget->getSelectedAddableFiles().empty()) return false; | 
| Chris@95 | 75     if (!fileStatusWidget->getSelectedCommittableFiles().empty()) return false; | 
| Chris@95 | 76     if (!fileStatusWidget->getSelectedRemovableFiles().empty()) return false; | 
| Chris@95 | 77     return true; | 
| Chris@95 | 78 } | 
| Chris@95 | 79 | 
| Chris@96 | 80 bool HgTabWidget::canRemove() const | 
| Chris@95 | 81 { | 
| Chris@95 | 82     if (fileStatusWidget->getSelectedRemovableFiles().empty()) return false; | 
| Chris@95 | 83     if (!fileStatusWidget->getSelectedAddableFiles().empty()) return false; | 
| Chris@95 | 84     return true; | 
| Chris@95 | 85 } | 
| Chris@95 | 86 | 
| Chris@96 | 87 bool HgTabWidget::canDoDiff() const | 
| Chris@95 | 88 { | 
| Chris@95 | 89     return canCommit(); | 
| Chris@95 | 90 } | 
| Chris@95 | 91 | 
| Chris@96 | 92 QStringList HgTabWidget::getAllSelectedFiles() const | 
| Chris@95 | 93 { | 
| Chris@95 | 94     return fileStatusWidget->getAllSelectedFiles(); | 
| Chris@95 | 95 } | 
| Chris@95 | 96 | 
| Chris@96 | 97 QStringList HgTabWidget::getSelectedCommittableFiles() const | 
| Chris@95 | 98 { | 
| Chris@95 | 99     return fileStatusWidget->getSelectedCommittableFiles(); | 
| Chris@95 | 100 } | 
| Chris@95 | 101 | 
| Chris@96 | 102 QStringList HgTabWidget::getSelectedAddableFiles() const | 
| Chris@95 | 103 { | 
| Chris@95 | 104     return fileStatusWidget->getSelectedAddableFiles(); | 
| Chris@95 | 105 } | 
| Chris@95 | 106 | 
| Chris@96 | 107 QStringList HgTabWidget::getSelectedRemovableFiles() const | 
| Chris@95 | 108 { | 
| Chris@95 | 109     return fileStatusWidget->getSelectedRemovableFiles(); | 
| Chris@95 | 110 } | 
| Chris@95 | 111 | 
| Chris@103 | 112 QStringList HgTabWidget::getAllCommittableFiles() const | 
| Chris@103 | 113 { | 
| Chris@103 | 114     return fileStatusWidget->getAllCommittableFiles(); | 
| Chris@103 | 115 } | 
| Chris@103 | 116 | 
| Chris@103 | 117 QStringList HgTabWidget::getAllAddableFiles() const | 
| Chris@103 | 118 { | 
| Chris@103 | 119     return fileStatusWidget->getAllAddableFiles(); | 
| Chris@103 | 120 } | 
| Chris@103 | 121 | 
| Chris@103 | 122 QStringList HgTabWidget::getAllRemovableFiles() const | 
| Chris@103 | 123 { | 
| Chris@103 | 124     return fileStatusWidget->getAllRemovableFiles(); | 
| Chris@103 | 125 } | 
| Chris@103 | 126 | 
| Chris@96 | 127 void HgTabWidget::updateWorkFolderFileList(QString fileList) | 
| jtkorhonen@0 | 128 { | 
| Chris@94 | 129     fileStates.parseStates(fileList); | 
| Chris@92 | 130     fileStatusWidget->setFileStates(fileStates); | 
| jtkorhonen@0 | 131 } | 
| jtkorhonen@0 | 132 | 
| Chris@96 | 133 void HgTabWidget::updateLocalRepoHgLogList(QString hgLogList) | 
| jtkorhonen@0 | 134 { | 
| Chris@43 | 135     //!!! | 
| cannam@45 | 136     Panned *panned = static_cast<Panned *>(historyGraphWidget); | 
| cannam@45 | 137     Panner *panner = static_cast<Panner *>(historyGraphPanner); | 
| Chris@43 | 138     QGraphicsScene *scene = new QGraphicsScene(); | 
| Chris@43 | 139     Changesets csets = parseChangeSets(hgLogList); | 
| Chris@44 | 140     if (csets.empty()) return; | 
| Chris@53 | 141     Grapher g(scene); | 
| Chris@44 | 142     try { | 
| Chris@106 | 143         g.layout(csets); | 
| Chris@44 | 144     } catch (std::string s) { | 
| Chris@106 | 145         std::cerr << "Internal error: Layout failed: " << s << std::endl; | 
| Chris@44 | 146     } | 
| Chris@87 | 147     QGraphicsScene *oldScene = panned->scene(); | 
| cannam@45 | 148     panned->setScene(scene); | 
| cannam@45 | 149     panner->setScene(scene); | 
| Chris@87 | 150     if (oldScene) delete oldScene; | 
| Chris@53 | 151     ChangesetItem *tipItem = g.getItemFor(csets[0]); | 
| Chris@53 | 152     if (tipItem) tipItem->ensureVisible(); | 
| Chris@108 | 153     //!!! track lifecycle of those Changesets | 
| jtkorhonen@0 | 154 } | 
| jtkorhonen@0 | 155 | 
| Chris@96 | 156 Changesets HgTabWidget::parseChangeSets(QString changeSetsStr) | 
| Chris@43 | 157 { | 
| Chris@108 | 158     Changesets csets = Changeset::parseChangesets(changeSetsStr); | 
| Chris@44 | 159     for (int i = 0; i+1 < csets.size(); ++i) { | 
| Chris@106 | 160         Changeset *cs = csets[i]; | 
| Chris@106 | 161         if (cs->parents().empty()) { | 
| Chris@106 | 162             QStringList list; | 
| Chris@106 | 163             list.push_back(csets[i+1]->id()); | 
| Chris@106 | 164             cs->setParents(list); | 
| Chris@106 | 165         } | 
| Chris@44 | 166     } | 
| Chris@43 | 167     return csets; | 
| jtkorhonen@0 | 168 } | 
| jtkorhonen@0 | 169 | 
| Chris@96 | 170 void HgTabWidget::setWorkFolderAndRepoNames(QString workFolderPath, QString remoteRepoPath) | 
| jtkorhonen@0 | 171 { | 
| Chris@89 | 172     fileStatusWidget->setLocalPath(workFolderPath); | 
| Chris@89 | 173     fileStatusWidget->setRemoteURL(remoteRepoPath); | 
| jtkorhonen@0 | 174 } | 
| Chris@106 | 175 | 
| Chris@106 | 176 void HgTabWidget::setBranch(QString branch) | 
| Chris@106 | 177 { | 
| Chris@106 | 178     fileStatusWidget->setBranch(branch); | 
| Chris@106 | 179 } |