# HG changeset patch # User Chris Cannam # Date 1289561521 0 # Node ID 384420567575eb04271e87f4c71d91a30b0784df # Parent bf3ab0ffb559ca700401eed78d63a5652801a1fc * Use the date when laying out rows diff -r bf3ab0ffb559 -r 384420567575 changeset.h --- a/changeset.h Thu Nov 11 22:27:24 2010 +0000 +++ b/changeset.h Fri Nov 12 11:32:01 2010 +0000 @@ -14,7 +14,8 @@ Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged STORED true); Q_PROPERTY(QString branch READ branch WRITE setBranch NOTIFY branchChanged STORED true); Q_PROPERTY(QString tag READ tag WRITE setTag NOTIFY tagChanged STORED true); - Q_PROPERTY(QString datetime READ datetime WRITE setdatetime NOTIFY datetimeChanged STORED true); + Q_PROPERTY(QString datetime READ datetime WRITE setDatetime NOTIFY datetimeChanged STORED true); + Q_PROPERTY(qulonglong timestamp READ timestamp WRITE setTimestamp NOTIFY timestampChanged STORED true); Q_PROPERTY(QString age READ age WRITE setAge NOTIFY ageChanged STORED true); Q_PROPERTY(QStringList parents READ parents WRITE setParents NOTIFY parentsChanged STORED true); Q_PROPERTY(QStringList children READ children WRITE setChildren NOTIFY childrenChanged STORED true); @@ -28,6 +29,7 @@ QString branch() const { return m_branch; } QString tag() const { return m_tag; } QString datetime() const { return m_datetime; } + qulonglong timestamp() const { return m_timestamp; } QString age() const { return m_age; } QStringList parents() const { return m_parents; } QStringList children() const { return m_children; } @@ -52,6 +54,7 @@ void branchChanged(QString branch); void tagChanged(QString tag); void datetimeChanged(QString datetime); + void timestampChanged(qulonglong timestamp); void ageChanged(QString age); void parentsChanged(QStringList parents); void childrenChanged(QStringList children); @@ -62,7 +65,8 @@ void setAuthor(QString author) { m_author = author; emit authorChanged(author); } void setBranch(QString branch) { m_branch = branch; emit branchChanged(branch); } void setTag(QString tag) { m_tag = tag; emit tagChanged(tag); } - void setdatetime(QString datetime) { m_datetime = datetime; emit datetimeChanged(datetime); } + void setDatetime(QString datetime) { m_datetime = datetime; emit datetimeChanged(datetime); } + void setTimestamp(qulonglong timestamp) { m_timestamp = timestamp; emit timestampChanged(timestamp); } void setAge(QString age) { m_age = age; emit ageChanged(age); } void setParents(QStringList parents) { m_parents = parents; emit parentsChanged(parents); } void setChildren(QStringList children) { m_children = children; emit childrenChanged(m_children); } @@ -75,6 +79,7 @@ QString m_branch; QString m_tag; QString m_datetime; + qulonglong m_timestamp; QString m_age; QStringList m_parents; QStringList m_children; diff -r bf3ab0ffb559 -r 384420567575 grapher.cpp --- a/grapher.cpp Thu Nov 11 22:27:24 2010 +0000 +++ b/grapher.cpp Fri Nov 12 11:32:01 2010 +0000 @@ -68,6 +68,28 @@ row = row - 1; } + // row is now an upper bound on our eventual row (because we want + // to be above all parents). But we also want to ensure we are + // above all nodes that have earlier dates (to the nearest day). + // m_rowDates maps each row to a date: use that. + + QString date = cs->date(); + + // n.b. this relies on the fact that the date component of an ISO + // date/time sorts correctly in a dictionary sort + while (m_rowDates.contains(row) && m_rowDates[row] < date) { + --row; + } + + // We have already laid out all nodes that have earlier timestamps + // than this one, so we know (among other things) that we can + // safely fill in this row has having this date, if it isn't in + // the map yet (it cannot have an earlier date) + + if (!m_rowDates.contains(row)) { + m_rowDates[row] = date; + } + std::cerr << "putting " << cs->id().toStdString() << " at row " << row << std::endl; @@ -178,9 +200,7 @@ Changeset *child = m_changesets[childId]; if (child->parents().size() > 1) { int childRow = m_items[childId]->row(); - std::cerr << "I'm at " << row << ", child with >1 parents is at " << childRow << std::endl; for (int r = row; r > childRow; --r) { - std::cerr << "setting row " << r << ", col " << col << std::endl; m_alloc[r].insert(col); } } @@ -201,12 +221,13 @@ } } if (special.size() == 2) { - m_items[special[0]]->setColumn - (findAvailableColumn(item->row() - 1, col - 1, true)); - m_items[special[1]]->setColumn - (findAvailableColumn(item->row() - 1, col + 1, true)); - m_handled.insert(special[0]); - m_handled.insert(special[1]); + for (int i = 0; i < 2; ++i) { + int off = i * 2 - 1; // 0 -> -1, 1 -> 1 + ChangesetItem *it = m_items[special[i]]; + it->setColumn(findAvailableColumn(it->row(), col + off, true)); + m_alloc[it->row()].insert(it->column()); + m_handled.insert(special[i]); + } } } } @@ -271,6 +292,12 @@ } } +static bool +compareChangesetsByDate(Changeset *const &a, Changeset *const &b) +{ + return a->timestamp() < b->timestamp(); +} + void Grapher::layout(Changesets csets) { @@ -314,14 +341,14 @@ } } - // Layout in reverse order, i.e. forward chronological order. - // This ensures that parents will normally be laid out before - // their children -- though we can recurse from layout() if we - // find any weird exceptions + // We need to lay out the changesets in forward chronological + // order. We have no guarantees about the order in which + // changesets appear in the list -- in a simple repository they + // will generally be reverse chronological, but that's far from + // guaranteed. So, sort explicitly using the date comparator + // above - //!!! changesets are not in any chronological order, necessarily: - // we need to sort by datetime() [or, better, numerical date] - // and then use m_rowDateMap + qStableSort(csets.begin(), csets.end(), compareChangesetsByDate); m_handled.clear(); for (int i = csets.size() - 1; i >= 0; --i) { diff -r bf3ab0ffb559 -r 384420567575 hgexpwidget.cpp --- a/hgexpwidget.cpp Thu Nov 11 22:27:24 2010 +0000 +++ b/hgexpwidget.cpp Fri Nov 12 11:32:01 2010 +0000 @@ -348,6 +348,8 @@ QStringList parents = e.value(key).split (" ", QString::SkipEmptyParts); cs->setParents(parents); + } else if (key == "timestamp") { + cs->setTimestamp(e.value(key).split(" ")[0].toULongLong()); } else { cs->setProperty(key.toLocal8Bit().data(), e.value(key)); } diff -r bf3ab0ffb559 -r 384420567575 mainwindow.cpp --- a/mainwindow.cpp Thu Nov 11 22:27:24 2010 +0000 +++ b/mainwindow.cpp Fri Nov 12 11:32:01 2010 +0000 @@ -126,7 +126,7 @@ QStringList params; params << "log"; params << "--template"; - params << "id: {rev}:{node|short}\\nauthor: {author}\\nbranch: {branches}\\ntag: {tag}\\ndatetime: {date|isodate}\\nage: {date|age}\\nparents: {parents}\\ncomment: {desc|json}\\n\\n"; + params << "id: {rev}:{node|short}\\nauthor: {author}\\nbranch: {branches}\\ntag: {tag}\\ndatetime: {date|isodate}\\ntimestamp: {date|hgdate}\\nage: {date|age}\\nparents: {parents}\\ncomment: {desc|json}\\n\\n"; runner -> startProc(getHgBinaryName(), workFolderPath, params); runningAction = ACT_LOG;