Mercurial > hg > easyhg
comparison grapher.cpp @ 52:384420567575
* Use the date when laying out rows
author | Chris Cannam |
---|---|
date | Fri, 12 Nov 2010 11:32:01 +0000 |
parents | bf3ab0ffb559 |
children | 3c46b2ac45d3 |
comparison
equal
deleted
inserted
replaced
51:bf3ab0ffb559 | 52:384420567575 |
---|---|
64 row = parentItem->row(); | 64 row = parentItem->row(); |
65 haveRow = true; | 65 haveRow = true; |
66 } | 66 } |
67 } | 67 } |
68 row = row - 1; | 68 row = row - 1; |
69 } | |
70 | |
71 // row is now an upper bound on our eventual row (because we want | |
72 // to be above all parents). But we also want to ensure we are | |
73 // above all nodes that have earlier dates (to the nearest day). | |
74 // m_rowDates maps each row to a date: use that. | |
75 | |
76 QString date = cs->date(); | |
77 | |
78 // n.b. this relies on the fact that the date component of an ISO | |
79 // date/time sorts correctly in a dictionary sort | |
80 while (m_rowDates.contains(row) && m_rowDates[row] < date) { | |
81 --row; | |
82 } | |
83 | |
84 // We have already laid out all nodes that have earlier timestamps | |
85 // than this one, so we know (among other things) that we can | |
86 // safely fill in this row has having this date, if it isn't in | |
87 // the map yet (it cannot have an earlier date) | |
88 | |
89 if (!m_rowDates.contains(row)) { | |
90 m_rowDates[row] = date; | |
69 } | 91 } |
70 | 92 |
71 std::cerr << "putting " << cs->id().toStdString() << " at row " << row | 93 std::cerr << "putting " << cs->id().toStdString() << " at row " << row |
72 << std::endl; | 94 << std::endl; |
73 | 95 |
176 foreach (QString childId, cs->children()) { | 198 foreach (QString childId, cs->children()) { |
177 if (!m_changesets.contains(childId)) continue; | 199 if (!m_changesets.contains(childId)) continue; |
178 Changeset *child = m_changesets[childId]; | 200 Changeset *child = m_changesets[childId]; |
179 if (child->parents().size() > 1) { | 201 if (child->parents().size() > 1) { |
180 int childRow = m_items[childId]->row(); | 202 int childRow = m_items[childId]->row(); |
181 std::cerr << "I'm at " << row << ", child with >1 parents is at " << childRow << std::endl; | |
182 for (int r = row; r > childRow; --r) { | 203 for (int r = row; r > childRow; --r) { |
183 std::cerr << "setting row " << r << ", col " << col << std::endl; | |
184 m_alloc[r].insert(col); | 204 m_alloc[r].insert(col); |
185 } | 205 } |
186 } | 206 } |
187 } | 207 } |
188 | 208 |
199 child->parents().size() == 1) { | 219 child->parents().size() == 1) { |
200 special.push_back(childId); | 220 special.push_back(childId); |
201 } | 221 } |
202 } | 222 } |
203 if (special.size() == 2) { | 223 if (special.size() == 2) { |
204 m_items[special[0]]->setColumn | 224 for (int i = 0; i < 2; ++i) { |
205 (findAvailableColumn(item->row() - 1, col - 1, true)); | 225 int off = i * 2 - 1; // 0 -> -1, 1 -> 1 |
206 m_items[special[1]]->setColumn | 226 ChangesetItem *it = m_items[special[i]]; |
207 (findAvailableColumn(item->row() - 1, col + 1, true)); | 227 it->setColumn(findAvailableColumn(it->row(), col + off, true)); |
208 m_handled.insert(special[0]); | 228 m_alloc[it->row()].insert(it->column()); |
209 m_handled.insert(special[1]); | 229 m_handled.insert(special[i]); |
230 } | |
210 } | 231 } |
211 } | 232 } |
212 } | 233 } |
213 | 234 |
214 bool | 235 bool |
269 foreach (QString branch, m_branchRanges.keys()) { | 290 foreach (QString branch, m_branchRanges.keys()) { |
270 std::cerr << branch.toStdString() << ": " << m_branchRanges[branch].first << " - " << m_branchRanges[branch].second << ", home " << m_branchHomes[branch] << std::endl; | 291 std::cerr << branch.toStdString() << ": " << m_branchRanges[branch].first << " - " << m_branchRanges[branch].second << ", home " << m_branchHomes[branch] << std::endl; |
271 } | 292 } |
272 } | 293 } |
273 | 294 |
295 static bool | |
296 compareChangesetsByDate(Changeset *const &a, Changeset *const &b) | |
297 { | |
298 return a->timestamp() < b->timestamp(); | |
299 } | |
300 | |
274 void | 301 void |
275 Grapher::layout(Changesets csets) | 302 Grapher::layout(Changesets csets) |
276 { | 303 { |
277 m_changesets.clear(); | 304 m_changesets.clear(); |
278 m_items.clear(); | 305 m_items.clear(); |
312 conn->setParent(m_items[parentId]); | 339 conn->setParent(m_items[parentId]); |
313 m_scene->addItem(conn); | 340 m_scene->addItem(conn); |
314 } | 341 } |
315 } | 342 } |
316 | 343 |
317 // Layout in reverse order, i.e. forward chronological order. | 344 // We need to lay out the changesets in forward chronological |
318 // This ensures that parents will normally be laid out before | 345 // order. We have no guarantees about the order in which |
319 // their children -- though we can recurse from layout() if we | 346 // changesets appear in the list -- in a simple repository they |
320 // find any weird exceptions | 347 // will generally be reverse chronological, but that's far from |
321 | 348 // guaranteed. So, sort explicitly using the date comparator |
322 //!!! changesets are not in any chronological order, necessarily: | 349 // above |
323 // we need to sort by datetime() [or, better, numerical date] | 350 |
324 // and then use m_rowDateMap | 351 qStableSort(csets.begin(), csets.end(), compareChangesetsByDate); |
325 | 352 |
326 m_handled.clear(); | 353 m_handled.clear(); |
327 for (int i = csets.size() - 1; i >= 0; --i) { | 354 for (int i = csets.size() - 1; i >= 0; --i) { |
328 layoutRow(csets[i]->id()); | 355 layoutRow(csets[i]->id()); |
329 } | 356 } |