Chris@116: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@116: Chris@116: /* Chris@116: EasyMercurial Chris@116: Chris@116: Based on HgExplorer by Jari Korhonen Chris@116: Copyright (c) 2010 Jari Korhonen Chris@116: Copyright (c) 2010 Chris Cannam Chris@116: Copyright (c) 2010 Queen Mary, University of London Chris@116: Chris@116: This program is free software; you can redistribute it and/or Chris@116: modify it under the terms of the GNU General Public License as Chris@116: published by the Free Software Foundation; either version 2 of the Chris@116: License, or (at your option) any later version. See the file Chris@116: COPYING included with this distribution for more information. Chris@116: */ Chris@116: Chris@116: #include "historywidget.h" Chris@116: Chris@119: #include "changesetscene.h" Chris@116: #include "panned.h" Chris@116: #include "panner.h" Chris@116: #include "grapher.h" Chris@116: #include "debug.h" Chris@129: #include "uncommitteditem.h" Chris@116: Chris@116: #include Chris@116: Chris@116: #include Chris@116: Chris@116: HistoryWidget::HistoryWidget() Chris@116: { Chris@116: m_panned = new Panned; Chris@116: m_panner = new Panner; Chris@129: m_uncommitted = new UncommittedItem(); Chris@129: m_uncommitted->setRow(-1); Chris@116: Chris@116: QGridLayout *layout = new QGridLayout; Chris@116: layout->addWidget(m_panned, 0, 0); Chris@116: layout->addWidget(m_panner, 0, 1); Chris@116: m_panner->setMaximumWidth(80); Chris@116: m_panner->connectToPanned(m_panned); Chris@116: Chris@116: setLayout(layout); Chris@116: } Chris@116: Chris@116: HistoryWidget::~HistoryWidget() Chris@116: { Chris@116: clearChangesets(); Chris@129: delete m_uncommitted; Chris@116: } Chris@116: Chris@116: void HistoryWidget::clearChangesets() Chris@116: { Chris@116: foreach (Changeset *cs, m_changesets) delete cs; Chris@116: m_changesets.clear(); Chris@116: } Chris@128: Chris@128: void HistoryWidget::setCurrent(QStringList ids) Chris@128: { Chris@128: if (m_currentIds == ids) return; Chris@128: DEBUG << "HistoryWidget::setCurrent: " << ids.size() << " ids" << endl; Chris@128: m_currentIds = ids; Chris@128: updateCurrentItems(); Chris@128: } Chris@128: Chris@128: void HistoryWidget::showUncommittedChanges(bool show) Chris@128: { Chris@129: QGraphicsScene *scene = m_panned->scene(); Chris@129: if (!scene) return; Chris@129: Chris@129: if (show) { Chris@129: if (m_uncommitted->scene() == scene) return; Chris@129: scene->addItem(m_uncommitted); Chris@129: m_uncommitted->ensureVisible(); Chris@129: } else { Chris@129: if (m_uncommitted->scene() != scene) return; Chris@129: scene->removeItem(m_uncommitted); Chris@129: } Chris@128: } Chris@116: Chris@120: void HistoryWidget::parseNewLog(QString log) Chris@120: { Chris@120: DEBUG << "HistoryWidget::parseNewLog: log has " << log.length() << " chars" << endl; Chris@122: Changesets csets = Changeset::parseChangesets(log); Chris@120: DEBUG << "HistoryWidget::parseNewLog: log has " << csets.size() << " changesets" << endl; Chris@120: clearChangesets(); Chris@120: m_changesets = csets; Chris@120: layoutAll(); Chris@120: } Chris@120: Chris@120: void HistoryWidget::parseIncrementalLog(QString log) Chris@120: { Chris@120: DEBUG << "HistoryWidget::parseIncrementalLog: log has " << log.length() << " chars" << endl; Chris@122: Changesets csets = Changeset::parseChangesets(log); Chris@120: DEBUG << "HistoryWidget::parseIncrementalLog: log has " << csets.size() << " changesets" << endl; Chris@120: if (!csets.empty()) { Chris@122: csets << m_changesets; Chris@122: m_changesets = csets; Chris@120: layoutAll(); Chris@120: } Chris@120: } Chris@120: Chris@120: void HistoryWidget::layoutAll() Chris@116: { Chris@122: setChangesetParents(); Chris@129: showUncommittedChanges(false); // detach the item from our scene Chris@122: Chris@119: ChangesetScene *scene = new ChangesetScene(); Chris@116: ChangesetItem *tipItem = 0; Chris@116: Chris@120: if (!m_changesets.empty()) { Chris@116: Grapher g(scene); Chris@116: try { Chris@120: g.layout(m_changesets); Chris@116: } catch (std::string s) { Chris@116: std::cerr << "Internal error: Layout failed: " << s << std::endl; Chris@116: } Chris@120: tipItem = g.getItemFor(m_changesets[0]); Chris@120: DEBUG << "tipItem is " << tipItem << " for tip changeset " Chris@120: << m_changesets[0]->id() << endl; Chris@116: } Chris@116: Chris@116: QGraphicsScene *oldScene = m_panned->scene(); Chris@116: m_panned->setScene(scene); Chris@116: m_panner->setScene(scene); Chris@116: Chris@116: if (oldScene) delete oldScene; Chris@116: if (tipItem) tipItem->ensureVisible(); Chris@128: Chris@128: updateCurrentItems(); Chris@116: } Chris@116: Chris@122: void HistoryWidget::setChangesetParents() Chris@116: { Chris@122: for (int i = 0; i+1 < m_changesets.size(); ++i) { Chris@122: Changeset *cs = m_changesets[i]; Chris@123: // Need to reset this, as Grapher::layout will recalculate it Chris@123: // and we don't want to end up with twice the children for Chris@123: // each parent... Chris@123: cs->setChildren(QStringList()); Chris@116: if (cs->parents().empty()) { Chris@116: QStringList list; Chris@122: list.push_back(m_changesets[i+1]->id()); Chris@116: cs->setParents(list); Chris@116: } Chris@116: } Chris@116: } Chris@128: Chris@128: void HistoryWidget::updateCurrentItems() Chris@128: { Chris@128: QGraphicsScene *scene = m_panned->scene(); Chris@128: if (!scene) return; Chris@128: QList items = scene->items(); Chris@128: foreach (QGraphicsItem *it, items) { Chris@128: ChangesetItem *csit = dynamic_cast(it); Chris@128: if (csit) { Chris@128: QString id = csit->getChangeset()->id(); Chris@128: bool current = m_currentIds.contains(id); Chris@128: if (current) { Chris@128: DEBUG << "id " << id << " is current" << endl; Chris@128: } Chris@128: csit->setCurrent(current); Chris@129: m_uncommitted->setRow(csit->row() - 1); Chris@129: m_uncommitted->setColumn(csit->column()); Chris@129: m_uncommitted->setWide(csit->isWide()); Chris@129: m_uncommitted->setBranch(csit->getChangeset()->branch()); Chris@128: } Chris@128: } Chris@128: } Chris@128: