Mercurial > hg > easyhg
comparison src/historywidget.cpp @ 370:b9c153e00e84
Move source files to src/
author | Chris Cannam |
---|---|
date | Thu, 24 Mar 2011 10:27:51 +0000 |
parents | historywidget.cpp@4811eb34e819 |
children | f051d210521e |
comparison
equal
deleted
inserted
replaced
369:19cce6d2c470 | 370:b9c153e00e84 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 EasyMercurial | |
5 | |
6 Based on HgExplorer by Jari Korhonen | |
7 Copyright (c) 2010 Jari Korhonen | |
8 Copyright (c) 2011 Chris Cannam | |
9 Copyright (c) 2011 Queen Mary, University of London | |
10 | |
11 This program is free software; you can redistribute it and/or | |
12 modify it under the terms of the GNU General Public License as | |
13 published by the Free Software Foundation; either version 2 of the | |
14 License, or (at your option) any later version. See the file | |
15 COPYING included with this distribution for more information. | |
16 */ | |
17 | |
18 #include "historywidget.h" | |
19 | |
20 #include "changesetscene.h" | |
21 #include "panned.h" | |
22 #include "panner.h" | |
23 #include "grapher.h" | |
24 #include "debug.h" | |
25 #include "uncommitteditem.h" | |
26 | |
27 #include <iostream> | |
28 | |
29 #include <QGridLayout> | |
30 | |
31 HistoryWidget::HistoryWidget() : | |
32 m_showUncommitted(false), | |
33 m_refreshNeeded(false) | |
34 { | |
35 m_panned = new Panned; | |
36 m_panner = new Panner; | |
37 | |
38 m_panned->setDragMode(QGraphicsView::ScrollHandDrag); | |
39 m_panned->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); | |
40 | |
41 QGridLayout *layout = new QGridLayout; | |
42 layout->addWidget(m_panned, 0, 0); | |
43 layout->addWidget(m_panner, 0, 1); | |
44 m_panner->setMaximumWidth(80); | |
45 m_panner->connectToPanned(m_panned); | |
46 | |
47 setLayout(layout); | |
48 } | |
49 | |
50 HistoryWidget::~HistoryWidget() | |
51 { | |
52 clearChangesets(); | |
53 } | |
54 | |
55 QGraphicsScene *HistoryWidget::scene() | |
56 { | |
57 return m_panned->scene(); | |
58 } | |
59 | |
60 void HistoryWidget::clearChangesets() | |
61 { | |
62 foreach (Changeset *cs, m_changesets) delete cs; | |
63 m_changesets.clear(); | |
64 } | |
65 | |
66 void HistoryWidget::setCurrent(QStringList ids, QString branch, | |
67 bool showUncommitted) | |
68 { | |
69 if (m_currentIds == ids && | |
70 m_currentBranch == branch && | |
71 m_showUncommitted == showUncommitted) return; | |
72 | |
73 DEBUG << "HistoryWidget::setCurrent: " << ids.size() << " ids, " | |
74 << "showUncommitted: " << showUncommitted << endl; | |
75 | |
76 m_currentIds.clear(); | |
77 m_currentBranch = branch; | |
78 m_showUncommitted = showUncommitted; | |
79 | |
80 if (ids.empty()) return; | |
81 | |
82 foreach (QString id, ids) { | |
83 m_currentIds.push_back(id); | |
84 } | |
85 | |
86 m_refreshNeeded = true; | |
87 } | |
88 | |
89 void HistoryWidget::parseNewLog(QString log) | |
90 { | |
91 DEBUG << "HistoryWidget::parseNewLog: log has " << log.length() << " chars" << endl; | |
92 Changesets csets = Changeset::parseChangesets(log); | |
93 DEBUG << "HistoryWidget::parseNewLog: log has " << csets.size() << " changesets" << endl; | |
94 replaceChangesets(csets); | |
95 m_refreshNeeded = true; | |
96 } | |
97 | |
98 void HistoryWidget::parseIncrementalLog(QString log) | |
99 { | |
100 DEBUG << "HistoryWidget::parseIncrementalLog: log has " << log.length() << " chars" << endl; | |
101 Changesets csets = Changeset::parseChangesets(log); | |
102 DEBUG << "HistoryWidget::parseIncrementalLog: log has " << csets.size() << " changesets" << endl; | |
103 if (!csets.empty()) { | |
104 addChangesets(csets); | |
105 } | |
106 m_refreshNeeded = true; | |
107 } | |
108 | |
109 void HistoryWidget::replaceChangesets(Changesets csets) | |
110 { | |
111 QSet<QString> oldIds; | |
112 foreach (Changeset *cs, m_changesets) { | |
113 oldIds.insert(cs->id()); | |
114 } | |
115 | |
116 QSet<QString> newIds; | |
117 foreach (Changeset *cs, csets) { | |
118 if (!oldIds.contains(cs->id())) { | |
119 newIds.insert(cs->id()); | |
120 } | |
121 } | |
122 | |
123 if (newIds.size() == csets.size()) { | |
124 // completely new set, unrelated to the old: don't mark new | |
125 m_newIds.clear(); | |
126 } else { | |
127 m_newIds = newIds; | |
128 } | |
129 | |
130 clearChangesets(); | |
131 m_changesets = csets; | |
132 } | |
133 | |
134 void HistoryWidget::addChangesets(Changesets csets) | |
135 { | |
136 m_newIds.clear(); | |
137 | |
138 if (csets.empty()) return; | |
139 | |
140 foreach (Changeset *cs, csets) { | |
141 m_newIds.insert(cs->id()); | |
142 } | |
143 | |
144 DEBUG << "addChangesets: " << csets.size() << " new changesets have (" | |
145 << m_changesets.size() << " already)" << endl; | |
146 | |
147 csets << m_changesets; | |
148 m_changesets = csets; | |
149 } | |
150 | |
151 void HistoryWidget::update() | |
152 { | |
153 if (m_refreshNeeded) { | |
154 layoutAll(); | |
155 } | |
156 } | |
157 | |
158 void HistoryWidget::layoutAll() | |
159 { | |
160 m_refreshNeeded = false; | |
161 | |
162 setChangesetParents(); | |
163 | |
164 ChangesetScene *scene = new ChangesetScene(); | |
165 ChangesetItem *tipItem = 0; | |
166 | |
167 QGraphicsScene *oldScene = m_panned->scene(); | |
168 | |
169 m_panned->setScene(0); | |
170 m_panner->setScene(0); | |
171 | |
172 delete oldScene; | |
173 | |
174 QGraphicsItem *toFocus = 0; | |
175 | |
176 if (!m_changesets.empty()) { | |
177 Grapher g(scene); | |
178 try { | |
179 g.layout(m_changesets, | |
180 m_showUncommitted ? m_currentIds : QStringList(), | |
181 m_currentBranch); | |
182 } catch (std::string s) { | |
183 std::cerr << "Internal error: Layout failed: " << s << std::endl; | |
184 } | |
185 toFocus = g.getUncommittedItem(); | |
186 if (!toFocus) { | |
187 toFocus = g.getItemFor(m_changesets[0]); | |
188 } | |
189 } | |
190 | |
191 m_panned->setScene(scene); | |
192 m_panner->setScene(scene); | |
193 | |
194 updateNewAndCurrentItems(); | |
195 | |
196 if (toFocus) { | |
197 toFocus->ensureVisible(); | |
198 } | |
199 | |
200 connectSceneSignals(); | |
201 } | |
202 | |
203 void HistoryWidget::setChangesetParents() | |
204 { | |
205 for (int i = 0; i < m_changesets.size(); ++i) { | |
206 Changeset *cs = m_changesets[i]; | |
207 // Need to reset this, as Grapher::layout will recalculate it | |
208 // and we don't want to end up with twice the children for | |
209 // each parent... | |
210 cs->setChildren(QStringList()); | |
211 } | |
212 for (int i = 0; i+1 < m_changesets.size(); ++i) { | |
213 Changeset *cs = m_changesets[i]; | |
214 if (cs->parents().empty()) { | |
215 QStringList list; | |
216 list.push_back(m_changesets[i+1]->id()); | |
217 cs->setParents(list); | |
218 } | |
219 } | |
220 } | |
221 | |
222 void HistoryWidget::updateNewAndCurrentItems() | |
223 { | |
224 QGraphicsScene *scene = m_panned->scene(); | |
225 if (!scene) return; | |
226 | |
227 QList<QGraphicsItem *> items = scene->items(); | |
228 foreach (QGraphicsItem *it, items) { | |
229 | |
230 ChangesetItem *csit = dynamic_cast<ChangesetItem *>(it); | |
231 if (!csit) continue; | |
232 | |
233 QString id = csit->getChangeset()->id(); | |
234 | |
235 bool current = m_currentIds.contains(id); | |
236 if (current) { | |
237 DEBUG << "id " << id << " is current" << endl; | |
238 } | |
239 bool newid = m_newIds.contains(id); | |
240 if (newid) { | |
241 DEBUG << "id " << id << " is new" << endl; | |
242 } | |
243 | |
244 if (csit->isCurrent() != current || csit->isNew() != newid) { | |
245 csit->setCurrent(current); | |
246 csit->setNew(newid); | |
247 csit->update(); | |
248 } | |
249 } | |
250 } | |
251 | |
252 void HistoryWidget::connectSceneSignals() | |
253 { | |
254 ChangesetScene *scene = qobject_cast<ChangesetScene *>(m_panned->scene()); | |
255 if (!scene) return; | |
256 | |
257 connect(scene, SIGNAL(commit()), | |
258 this, SIGNAL(commit())); | |
259 | |
260 connect(scene, SIGNAL(revert()), | |
261 this, SIGNAL(revert())); | |
262 | |
263 connect(scene, SIGNAL(diffWorkingFolder()), | |
264 this, SIGNAL(diffWorkingFolder())); | |
265 | |
266 connect(scene, SIGNAL(showSummary()), | |
267 this, SIGNAL(showSummary())); | |
268 | |
269 connect(scene, SIGNAL(showWork()), | |
270 this, SIGNAL(showWork())); | |
271 | |
272 connect(scene, SIGNAL(newBranch()), | |
273 this, SIGNAL(newBranch())); | |
274 | |
275 connect(scene, SIGNAL(noBranch()), | |
276 this, SIGNAL(noBranch())); | |
277 | |
278 connect(scene, SIGNAL(updateTo(QString)), | |
279 this, SIGNAL(updateTo(QString))); | |
280 | |
281 connect(scene, SIGNAL(diffToCurrent(QString)), | |
282 this, SIGNAL(diffToCurrent(QString))); | |
283 | |
284 connect(scene, SIGNAL(diffToParent(QString, QString)), | |
285 this, SIGNAL(diffToParent(QString, QString))); | |
286 | |
287 connect(scene, SIGNAL(showSummary(Changeset *)), | |
288 this, SIGNAL(showSummary(Changeset *))); | |
289 | |
290 connect(scene, SIGNAL(mergeFrom(QString)), | |
291 this, SIGNAL(mergeFrom(QString))); | |
292 | |
293 connect(scene, SIGNAL(newBranch(QString)), | |
294 this, SIGNAL(newBranch(QString))); | |
295 | |
296 connect(scene, SIGNAL(tag(QString)), | |
297 this, SIGNAL(tag(QString))); | |
298 } |