Mercurial > hg > easyhg
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/historywidget.cpp Thu Mar 24 10:27:51 2011 +0000 @@ -0,0 +1,298 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + EasyMercurial + + Based on HgExplorer by Jari Korhonen + Copyright (c) 2010 Jari Korhonen + Copyright (c) 2011 Chris Cannam + Copyright (c) 2011 Queen Mary, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "historywidget.h" + +#include "changesetscene.h" +#include "panned.h" +#include "panner.h" +#include "grapher.h" +#include "debug.h" +#include "uncommitteditem.h" + +#include <iostream> + +#include <QGridLayout> + +HistoryWidget::HistoryWidget() : + m_showUncommitted(false), + m_refreshNeeded(false) +{ + m_panned = new Panned; + m_panner = new Panner; + + m_panned->setDragMode(QGraphicsView::ScrollHandDrag); + m_panned->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(m_panned, 0, 0); + layout->addWidget(m_panner, 0, 1); + m_panner->setMaximumWidth(80); + m_panner->connectToPanned(m_panned); + + setLayout(layout); +} + +HistoryWidget::~HistoryWidget() +{ + clearChangesets(); +} + +QGraphicsScene *HistoryWidget::scene() +{ + return m_panned->scene(); +} + +void HistoryWidget::clearChangesets() +{ + foreach (Changeset *cs, m_changesets) delete cs; + m_changesets.clear(); +} + +void HistoryWidget::setCurrent(QStringList ids, QString branch, + bool showUncommitted) +{ + if (m_currentIds == ids && + m_currentBranch == branch && + m_showUncommitted == showUncommitted) return; + + DEBUG << "HistoryWidget::setCurrent: " << ids.size() << " ids, " + << "showUncommitted: " << showUncommitted << endl; + + m_currentIds.clear(); + m_currentBranch = branch; + m_showUncommitted = showUncommitted; + + if (ids.empty()) return; + + foreach (QString id, ids) { + m_currentIds.push_back(id); + } + + m_refreshNeeded = true; +} + +void HistoryWidget::parseNewLog(QString log) +{ + DEBUG << "HistoryWidget::parseNewLog: log has " << log.length() << " chars" << endl; + Changesets csets = Changeset::parseChangesets(log); + DEBUG << "HistoryWidget::parseNewLog: log has " << csets.size() << " changesets" << endl; + replaceChangesets(csets); + m_refreshNeeded = true; +} + +void HistoryWidget::parseIncrementalLog(QString log) +{ + DEBUG << "HistoryWidget::parseIncrementalLog: log has " << log.length() << " chars" << endl; + Changesets csets = Changeset::parseChangesets(log); + DEBUG << "HistoryWidget::parseIncrementalLog: log has " << csets.size() << " changesets" << endl; + if (!csets.empty()) { + addChangesets(csets); + } + m_refreshNeeded = true; +} + +void HistoryWidget::replaceChangesets(Changesets csets) +{ + QSet<QString> oldIds; + foreach (Changeset *cs, m_changesets) { + oldIds.insert(cs->id()); + } + + QSet<QString> newIds; + foreach (Changeset *cs, csets) { + if (!oldIds.contains(cs->id())) { + newIds.insert(cs->id()); + } + } + + if (newIds.size() == csets.size()) { + // completely new set, unrelated to the old: don't mark new + m_newIds.clear(); + } else { + m_newIds = newIds; + } + + clearChangesets(); + m_changesets = csets; +} + +void HistoryWidget::addChangesets(Changesets csets) +{ + m_newIds.clear(); + + if (csets.empty()) return; + + foreach (Changeset *cs, csets) { + m_newIds.insert(cs->id()); + } + + DEBUG << "addChangesets: " << csets.size() << " new changesets have (" + << m_changesets.size() << " already)" << endl; + + csets << m_changesets; + m_changesets = csets; +} + +void HistoryWidget::update() +{ + if (m_refreshNeeded) { + layoutAll(); + } +} + +void HistoryWidget::layoutAll() +{ + m_refreshNeeded = false; + + setChangesetParents(); + + ChangesetScene *scene = new ChangesetScene(); + ChangesetItem *tipItem = 0; + + QGraphicsScene *oldScene = m_panned->scene(); + + m_panned->setScene(0); + m_panner->setScene(0); + + delete oldScene; + + QGraphicsItem *toFocus = 0; + + if (!m_changesets.empty()) { + Grapher g(scene); + try { + g.layout(m_changesets, + m_showUncommitted ? m_currentIds : QStringList(), + m_currentBranch); + } catch (std::string s) { + std::cerr << "Internal error: Layout failed: " << s << std::endl; + } + toFocus = g.getUncommittedItem(); + if (!toFocus) { + toFocus = g.getItemFor(m_changesets[0]); + } + } + + m_panned->setScene(scene); + m_panner->setScene(scene); + + updateNewAndCurrentItems(); + + if (toFocus) { + toFocus->ensureVisible(); + } + + connectSceneSignals(); +} + +void HistoryWidget::setChangesetParents() +{ + for (int i = 0; i < m_changesets.size(); ++i) { + Changeset *cs = m_changesets[i]; + // Need to reset this, as Grapher::layout will recalculate it + // and we don't want to end up with twice the children for + // each parent... + cs->setChildren(QStringList()); + } + for (int i = 0; i+1 < m_changesets.size(); ++i) { + Changeset *cs = m_changesets[i]; + if (cs->parents().empty()) { + QStringList list; + list.push_back(m_changesets[i+1]->id()); + cs->setParents(list); + } + } +} + +void HistoryWidget::updateNewAndCurrentItems() +{ + QGraphicsScene *scene = m_panned->scene(); + if (!scene) return; + + QList<QGraphicsItem *> items = scene->items(); + foreach (QGraphicsItem *it, items) { + + ChangesetItem *csit = dynamic_cast<ChangesetItem *>(it); + if (!csit) continue; + + QString id = csit->getChangeset()->id(); + + bool current = m_currentIds.contains(id); + if (current) { + DEBUG << "id " << id << " is current" << endl; + } + bool newid = m_newIds.contains(id); + if (newid) { + DEBUG << "id " << id << " is new" << endl; + } + + if (csit->isCurrent() != current || csit->isNew() != newid) { + csit->setCurrent(current); + csit->setNew(newid); + csit->update(); + } + } +} + +void HistoryWidget::connectSceneSignals() +{ + ChangesetScene *scene = qobject_cast<ChangesetScene *>(m_panned->scene()); + if (!scene) return; + + connect(scene, SIGNAL(commit()), + this, SIGNAL(commit())); + + connect(scene, SIGNAL(revert()), + this, SIGNAL(revert())); + + connect(scene, SIGNAL(diffWorkingFolder()), + this, SIGNAL(diffWorkingFolder())); + + connect(scene, SIGNAL(showSummary()), + this, SIGNAL(showSummary())); + + connect(scene, SIGNAL(showWork()), + this, SIGNAL(showWork())); + + connect(scene, SIGNAL(newBranch()), + this, SIGNAL(newBranch())); + + connect(scene, SIGNAL(noBranch()), + this, SIGNAL(noBranch())); + + connect(scene, SIGNAL(updateTo(QString)), + this, SIGNAL(updateTo(QString))); + + connect(scene, SIGNAL(diffToCurrent(QString)), + this, SIGNAL(diffToCurrent(QString))); + + connect(scene, SIGNAL(diffToParent(QString, QString)), + this, SIGNAL(diffToParent(QString, QString))); + + connect(scene, SIGNAL(showSummary(Changeset *)), + this, SIGNAL(showSummary(Changeset *))); + + connect(scene, SIGNAL(mergeFrom(QString)), + this, SIGNAL(mergeFrom(QString))); + + connect(scene, SIGNAL(newBranch(QString)), + this, SIGNAL(newBranch(QString))); + + connect(scene, SIGNAL(tag(QString)), + this, SIGNAL(tag(QString))); +}