comparison grapher.cpp @ 153:70fe12873106

* Show both parents of uncommitted merge; fixes to right-button menus
author Chris Cannam
date Thu, 02 Dec 2010 17:55:21 +0000
parents 38faf16df9b6
children 4bad3c5c053a
comparison
equal deleted inserted replaced
152:2b997861174b 153:70fe12873106
108 m_rowDates[row] = date; 108 m_rowDates[row] = date;
109 } 109 }
110 110
111 // If we're the parent of the uncommitted item, make a note of our 111 // If we're the parent of the uncommitted item, make a note of our
112 // row (we need it later, to avoid overwriting the connecting line) 112 // row (we need it later, to avoid overwriting the connecting line)
113 if (m_uncommittedParentId == id) { 113 if (!m_uncommittedParents.empty() && m_uncommittedParents[0] == id) {
114 m_uncommittedParentRow = row; 114 m_uncommittedParentRow = row;
115 } 115 }
116 116
117 DEBUG << "putting " << cs->id().toStdString() << " at row " << row 117 DEBUG << "putting " << cs->id().toStdString() << " at row " << row
118 << endl; 118 << endl;
156 156
157 case 1: 157 case 1:
158 parentId = cs->parents()[0]; 158 parentId = cs->parents()[0];
159 159
160 if (!m_changesets.contains(parentId) || 160 if (!m_changesets.contains(parentId) ||
161 m_changesets[parentId]->branch() != branch) { 161 !m_changesets[parentId]->isOnBranch(branch)) {
162 // new branch 162 // new branch
163 col = m_branchHomes[branch]; 163 col = m_branchHomes[branch];
164 } else { 164 } else {
165 col = m_items[parentId]->column(); 165 col = m_items[parentId]->column();
166 } 166 }
174 // have multiple children on the same branch -- spreading them 174 // have multiple children on the same branch -- spreading them
175 // out rather than having affinity to a specific branch) 175 // out rather than having affinity to a specific branch)
176 176
177 foreach (QString parentId, cs->parents()) { 177 foreach (QString parentId, cs->parents()) {
178 if (!m_changesets.contains(parentId)) continue; 178 if (!m_changesets.contains(parentId)) continue;
179 if (m_changesets[parentId]->branch() == branch) { 179 if (m_changesets[parentId]->isOnBranch(branch)) {
180 ChangesetItem *parentItem = m_items[parentId]; 180 ChangesetItem *parentItem = m_items[parentId];
181 col += parentItem->column(); 181 col += parentItem->column();
182 parentsOnSameBranch++; 182 parentsOnSameBranch++;
183 } 183 }
184 } 184 }
196 196
197 m_alloc[row].insert(col); 197 m_alloc[row].insert(col);
198 item->setColumn(col); 198 item->setColumn(col);
199 m_handled.insert(id); 199 m_handled.insert(id);
200 200
201 // If we're the parent of the uncommitted item, it should be given 201 // If we're the first parent of the uncommitted item, it should be
202 // the same column as us (ideally) 202 // given the same column as us (we already noted that its
203 203 // connecting line would end at our row)
204 if (m_uncommittedParentId == id) { 204
205 int ucol = findAvailableColumn(row-1, col, true); 205 if (m_uncommittedParents.contains(id)) {
206 m_uncommitted->setColumn(ucol); 206 if (m_uncommittedParents[0] == id) {
207 m_haveAllocatedUncommittedColumn = true; 207 int ucol = findAvailableColumn(row-1, col, true);
208 m_uncommitted->setColumn(ucol);
209 m_haveAllocatedUncommittedColumn = true;
210 }
211 // also, if the uncommitted item has a different branch from
212 // any of its parents, tell it to show the branch
213 if (!cs->isOnBranch(m_uncommitted->branch())) {
214 DEBUG << "Uncommitted branch " << m_uncommitted->branch()
215 << " differs from my branch " << cs->branch()
216 << ", asking it to show branch" << endl;
217 m_uncommitted->setShowBranch(true);
218 }
208 } 219 }
209 220
210 // Normally the children will lay out themselves, but we can do 221 // Normally the children will lay out themselves, but we can do
211 // a better job in some special cases: 222 // a better job in some special cases:
212 223
220 DEBUG << "reserving connection line space" << endl; 231 DEBUG << "reserving connection line space" << endl;
221 if (!m_changesets.contains(childId)) continue; 232 if (!m_changesets.contains(childId)) continue;
222 Changeset *child = m_changesets[childId]; 233 Changeset *child = m_changesets[childId];
223 int childRow = m_items[childId]->row(); 234 int childRow = m_items[childId]->row();
224 if (child->parents().size() > 1 || 235 if (child->parents().size() > 1 ||
225 child->branch() == cs->branch()) { 236 child->isOnBranch(cs->branch())) {
226 for (int r = row-1; r > childRow; --r) { 237 for (int r = row-1; r > childRow; --r) {
227 m_alloc[r].insert(col); 238 m_alloc[r].insert(col);
228 } 239 }
229 } 240 }
230 } 241 }
235 if (nchildren > 1) { 246 if (nchildren > 1) {
236 QList<QString> special; 247 QList<QString> special;
237 foreach (QString childId, cs->children()) { 248 foreach (QString childId, cs->children()) {
238 if (!m_changesets.contains(childId)) continue; 249 if (!m_changesets.contains(childId)) continue;
239 Changeset *child = m_changesets[childId]; 250 Changeset *child = m_changesets[childId];
240 if (child->branch() == branch && 251 if (child->isOnBranch(branch) &&
241 child->parents().size() == 1) { 252 child->parents().size() == 1) {
242 special.push_back(childId); 253 special.push_back(childId);
243 } 254 }
244 } 255 }
245 if (special.size() == 2) { 256 if (special.size() == 2) {
285 m_branchRanges[branch] = p; 296 m_branchRanges[branch] = p;
286 } 297 }
287 } 298 }
288 299
289 m_branchHomes[""] = 0; 300 m_branchHomes[""] = 0;
301 m_branchHomes["default"] = 0;
290 302
291 foreach (QString branch, m_branchRanges.keys()) { 303 foreach (QString branch, m_branchRanges.keys()) {
292 if (branch == "") continue; 304 if (branch == "") continue;
293 QSet<int> taken; 305 QSet<int> taken;
294 taken.insert(0); 306 taken.insert(0);
337 { 349 {
338 if (!cs || !m_items.contains(cs->id())) return 0; 350 if (!cs || !m_items.contains(cs->id())) return 0;
339 return m_items[cs->id()]; 351 return m_items[cs->id()];
340 } 352 }
341 353
342 void Grapher::layout(Changesets csets, QString uncommittedSproutsFrom) 354 void Grapher::layout(Changesets csets,
355 QStringList uncommittedParents,
356 QString uncommittedBranch)
343 { 357 {
344 m_changesets.clear(); 358 m_changesets.clear();
345 m_items.clear(); 359 m_items.clear();
346 m_alloc.clear(); 360 m_alloc.clear();
347 m_branchHomes.clear(); 361 m_branchHomes.clear();
348 362
349 m_uncommittedParentId = uncommittedSproutsFrom; 363 m_uncommittedParents = uncommittedParents;
350 m_haveAllocatedUncommittedColumn = false; 364 m_haveAllocatedUncommittedColumn = false;
351 m_uncommittedParentRow = 0; 365 m_uncommittedParentRow = 0;
352 m_uncommitted = 0; 366 m_uncommitted = 0;
353 367
354 DEBUG << "Grapher::layout: Have " << csets.size() << " changesets" << endl; 368 DEBUG << "Grapher::layout: Have " << csets.size() << " changesets" << endl;
397 } 411 }
398 } 412 }
399 413
400 // Add uncommitted item and connecting line as necessary 414 // Add uncommitted item and connecting line as necessary
401 415
402 if (m_uncommittedParentId != "") { 416 if (!m_uncommittedParents.empty()) {
403 m_uncommitted = new UncommittedItem(); 417 m_uncommitted = new UncommittedItem();
418 m_uncommitted->setBranch(uncommittedBranch);
404 m_scene->addUncommittedItem(m_uncommitted); 419 m_scene->addUncommittedItem(m_uncommitted);
405 ConnectionItem *conn = new ConnectionItem(); 420 foreach (QString p, m_uncommittedParents) {
406 conn->setParent(m_items[m_uncommittedParentId]); 421 ConnectionItem *conn = new ConnectionItem();
407 conn->setChild(m_uncommitted); 422 conn->setConnectionType(ConnectionItem::Merge);
408 m_scene->addItem(conn); 423 conn->setParent(m_items[p]);
424 conn->setChild(m_uncommitted);
425 m_scene->addItem(conn);
426 }
409 } 427 }
410 428
411 // Add the branch labels 429 // Add the branch labels
412 430
413 foreach (Changeset *cs, csets) { 431 foreach (Changeset *cs, csets) {
471 if (i < mincol) mincol = i; 489 if (i < mincol) mincol = i;
472 if (i > maxcol) maxcol = i; 490 if (i > maxcol) maxcol = i;
473 } 491 }
474 } 492 }
475 493
494 int datemincol = mincol, datemaxcol = maxcol;
495
496 if (mincol == maxcol) {
497 --datemincol;
498 ++datemaxcol;
499 } else if (m_alloc[minrow].contains(mincol)) {
500 --datemincol;
501 }
502
476 // We've given the uncommitted item a column, but not a row yet -- 503 // We've given the uncommitted item a column, but not a row yet --
477 // it always goes at the top 504 // it always goes at the top
478 505
479 if (m_uncommitted) { 506 if (m_uncommitted) {
480 --minrow; 507 --minrow;
504 int changeRow = 0; 531 int changeRow = 0;
505 532
506 bool even = false; 533 bool even = false;
507 int n = 0; 534 int n = 0;
508 535
509 if (mincol == maxcol) {
510 --mincol;
511 ++maxcol;
512 }
513
514 for (int row = minrow; row <= maxrow; ++row) { 536 for (int row = minrow; row <= maxrow; ++row) {
515 537
516 QString date = m_rowDates[row]; 538 QString date = m_rowDates[row];
517 n++; 539 n++;
518 540
519 if (date != prevDate) { 541 if (date != prevDate) {
520 if (prevDate != "") { 542 if (prevDate != "") {
521 DateItem *item = new DateItem(); 543 DateItem *item = new DateItem();
522 item->setDateString(prevDate); 544 item->setDateString(prevDate);
523 item->setCols(mincol, maxcol - mincol + 1); 545 item->setCols(datemincol, datemaxcol - datemincol + 1);
524 item->setRows(changeRow, n); 546 item->setRows(changeRow, n);
525 item->setEven(even); 547 item->setEven(even);
526 item->setZValue(-1); 548 item->setZValue(-1);
527 m_scene->addItem(item); 549 m_scene->addItem(item);
528 even = !even; 550 even = !even;
534 } 556 }
535 557
536 if (n > 0) { 558 if (n > 0) {
537 DateItem *item = new DateItem(); 559 DateItem *item = new DateItem();
538 item->setDateString(prevDate); 560 item->setDateString(prevDate);
539 item->setCols(mincol, maxcol - mincol + 1); 561 item->setCols(datemincol, datemaxcol - datemincol + 1);
540 item->setRows(changeRow, n+1); 562 item->setRows(changeRow, n+1);
541 item->setEven(even); 563 item->setEven(even);
542 item->setZValue(-1); 564 item->setZValue(-1);
543 m_scene->addItem(item); 565 m_scene->addItem(item);
544 even = !even; 566 even = !even;