Chris@44
|
1
|
Chris@44
|
2 #include "grapher.h"
|
Chris@44
|
3
|
Chris@44
|
4 #include <QSet>
|
Chris@44
|
5 #include <QMap>
|
Chris@44
|
6
|
Chris@44
|
7 #include <iostream>
|
Chris@44
|
8
|
Chris@44
|
9 typedef QSet<int> ColumnSet;
|
Chris@44
|
10 typedef QMap<int, ColumnSet> GridAlloc;
|
Chris@44
|
11 typedef QMap<QString, Changeset *> IdChangesetMap;
|
Chris@44
|
12 typedef QSet<Changeset *> ChangesetSet;
|
Chris@44
|
13
|
Chris@44
|
14 ChangesetItem *
|
Chris@44
|
15 layout(Changeset *cs,
|
Chris@44
|
16 IdChangesetMap idCsetMap,
|
Chris@44
|
17 ChangesetItemMap items,
|
Chris@44
|
18 GridAlloc &alloc,
|
Chris@44
|
19 ChangesetSet &handled)
|
Chris@44
|
20 {
|
Chris@44
|
21 if (!cs) {
|
Chris@44
|
22 throw std::string("Null Changeset");
|
Chris@44
|
23 }
|
Chris@44
|
24 if (!items.contains(cs)) {
|
Chris@44
|
25 throw std::string("Changeset not in item map");
|
Chris@44
|
26 }
|
Chris@44
|
27 ChangesetItem *item = items[cs];
|
Chris@44
|
28 if (handled.contains(cs)) {
|
Chris@44
|
29 return item;
|
Chris@44
|
30 }
|
Chris@44
|
31 int row = 0;
|
Chris@44
|
32 int col = 0;
|
Chris@44
|
33 if (!cs->parents().empty()) {
|
Chris@44
|
34 bool haveRow = false;
|
Chris@44
|
35 foreach (QString parentId, cs->parents()) {
|
Chris@44
|
36 if (parentId == "") continue; //!!!
|
Chris@44
|
37 std::cerr << "recursing to parent \"" << parentId.toStdString() << "\" of \"" << cs->id().toStdString() << "\"" << std::endl;
|
Chris@44
|
38 ChangesetItem *parentItem =
|
Chris@44
|
39 layout(idCsetMap[parentId],
|
Chris@44
|
40 idCsetMap,
|
Chris@44
|
41 items,
|
Chris@44
|
42 alloc,
|
Chris@44
|
43 handled);
|
Chris@44
|
44 if (!haveRow || parentItem->row() < row) {
|
Chris@44
|
45 row = parentItem->row();
|
Chris@44
|
46 haveRow = true;
|
Chris@44
|
47 }
|
Chris@44
|
48 col += parentItem->column();
|
Chris@44
|
49 }
|
Chris@44
|
50 col /= cs->parents().size();
|
Chris@44
|
51 row = row - 1;
|
Chris@44
|
52 while (alloc[row].contains(col)) {
|
Chris@44
|
53 if (col > 0) col = -col;
|
Chris@44
|
54 else col = -col + 1;
|
Chris@44
|
55 }
|
Chris@44
|
56 alloc[row].insert(col);
|
Chris@44
|
57 }
|
Chris@44
|
58 item->setColumn(col);
|
Chris@44
|
59 item->setRow(row);
|
Chris@44
|
60 item->setX(col * 100);
|
Chris@44
|
61 item->setY(row * 100);
|
Chris@44
|
62 handled.insert(cs);
|
Chris@44
|
63 return item;
|
Chris@44
|
64 }
|
Chris@44
|
65
|
Chris@44
|
66 void
|
Chris@44
|
67 Grapher::layout(Changesets csets, ChangesetItemMap items)
|
Chris@44
|
68 {
|
Chris@44
|
69 IdChangesetMap idCsetMap;
|
Chris@44
|
70 foreach (Changeset *cs, csets) {
|
Chris@44
|
71 std::cerr << cs->id().toStdString() << std::endl;
|
Chris@44
|
72 if (cs->id() == "") {
|
Chris@44
|
73 throw std::string("Changeset has no ID");
|
Chris@44
|
74 }
|
Chris@44
|
75 if (idCsetMap.contains(cs->id())) {
|
Chris@44
|
76 throw std::string("Changeset ID is already in map");
|
Chris@44
|
77 }
|
Chris@44
|
78 idCsetMap[cs->id()] = cs;
|
Chris@44
|
79 }
|
Chris@44
|
80
|
Chris@44
|
81 GridAlloc alloc;
|
Chris@44
|
82 ChangesetSet handled;
|
Chris@44
|
83 foreach (Changeset *cs, csets) {
|
Chris@44
|
84 ::layout(cs, idCsetMap, items, alloc, handled);
|
Chris@44
|
85 }
|
Chris@44
|
86 }
|
Chris@44
|
87
|