# # # add_file "guitone/src/model/Manifest.cpp" # content [2f05aa8a463676daeba4d5a1be5d849cacd8b269] # # add_file "guitone/src/model/Manifest.h" # content [e6d99d6259e723aa8aec62782c98db9d37d82f36] # # patch "guitone/guitone.pro" # from [89ffc63cab6945f7c72dd91d072bfa7425ae9d33] # to [fa6591e3761c27f496f59500e56dfa6cf9fcfbce] # ============================================================ --- guitone/src/model/Manifest.cpp 2f05aa8a463676daeba4d5a1be5d849cacd8b269 +++ guitone/src/model/Manifest.cpp 2f05aa8a463676daeba4d5a1be5d849cacd8b269 @@ -0,0 +1,230 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "Manifest.h" +#include "StanzaParser.h" + +Manifest::Manifest(QObject *parent) : QAbstractItemModel(parent) +{ + mtnDelegate = new MonotoneDelegate(this); + root = NULL; +} + +Manifest::~Manifest() +{ + delete mtnDelegate; +} + +bool Manifest::readManifest(const QString & rev) +{ + // reset the view + reset(); + + QStringList cmd; + cmd << "get_manifest_of" << rev; + + return mtnDelegate->triggerCommand(cmd); +} + +void Manifest::parseOutput() +{ + StanzaParser* parser = new StanzaParser(AutomateCommand::data); + StanzaList list = parser->getStanzas(); + + QMap directoryMap; + + for (int i=0, size = list.size(); i < size; ++i) + { + Stanza stanza = list.at(i); + ManifestEntry * mEntry = NULL; + + for (int j=0, size2 = stanza.size(); j < size2; j++) + { + StanzaEntry entry = stanza.at(j); + + // skip the format version + if (j == 0) + { + if (entry.sym == "format_version") break; + mEntry = new ManifestEntry(); + } + + Q_ASSERT(mEntry); + + if (entry.sym == "dir") + { + Q_ASSERT(entry.vals.size() == 1); + mEntry->path = entry.vals.at(0); + mEntry->is_directory = true; + + // check if this is the root entry + if (mEntry->path == "") + { + Q_ASSERT(!root); + root = mEntry; + } + + directoryMap.insert(mEntry->path, mEntry); + } + + if (entry.sym == "file") + { + Q_ASSERT(entry.vals.size() == 1); + mEntry->path = entry.vals.at(0); + mEntry->is_directory = false; + } + + if (j == 0 && mEntry != root) + { + int pos = mEntry->path.indexOf("/"); + QString basePath = ""; + if (pos > -1) + { + basePath = mEntry->path.left(pos); + } + Q_ASSERT(directoryMap.contains(basePath)); + ManifestEntry * parent = directoryMap.value(basePath); + mEntry->parent = parent; + parent->children.append(mEntry); + continue; + } + + if (entry.sym == "content") + { + Q_ASSERT(entry.vals.size() == 1); + mEntry->hash = entry.vals.at(0); + continue; + } + + if (entry.sym == "attr") + { + Q_ASSERT(entry.vals.size() == 2); + mEntry->attributes.insert(entry.vals.at(0), entry.vals.at(1)); + continue; + } + + qWarning("Manifest::parseOutput(): Unknown symbol %s.", qPrintable(entry.sym)); + } + } + + // reset any connected view(s) + reset(); + + // signal that we've finished (whoever listens to that) + emit manifestRead(); +} + +int Manifest::columnCount(const QModelIndex &parent) const +{ + return 2; +} + +QVariant Manifest::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + + if (role != Qt::DisplayRole) + { + return QVariant(); + } + + ManifestEntry * entry = static_cast(index.internalPointer()); + switch (index.column()) + { + case 0: return QVariant(entry->filename()); + case 1: return QVariant(entry->hash); + } + return QVariant(); +} + +Qt::ItemFlags Manifest::flags(const QModelIndex &index) const +{ + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant Manifest::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + switch (section) + { + case 0: return QVariant(tr("File")); + case 1: return QVariant(tr("Hash")); + } + } + return QVariant(); +} + +int Manifest::rowCount(const QModelIndex& parent) const +{ + ManifestEntry * parentEntry = root; + + if (parent.isValid()) + { + parentEntry = static_cast(parent.internalPointer()); + } + + return parentEntry->children.size(); +} + +QModelIndex Manifest::index(int row, int column, const QModelIndex& parent) const +{ + ManifestEntry * parentEntry; + + if (!parent.isValid()) + { + parentEntry = root; + } + else + { + parentEntry = static_cast(parent.internalPointer()); + } + + ManifestEntry * entry = parentEntry->child(row); + + if (entry) + { + return createIndex(row, column, entry); + } + + return QModelIndex(); +} + +QModelIndex Manifest::parent(const QModelIndex& index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + ManifestEntry * child = static_cast(index.internalPointer()); + ManifestEntry * parent = child->parent; + + if (parent == root) + { + return QModelIndex(); + } + + return createIndex(parent->row(), 0, parent); +} + ============================================================ --- guitone/src/model/Manifest.h e6d99d6259e723aa8aec62782c98db9d37d82f36 +++ guitone/src/model/Manifest.h e6d99d6259e723aa8aec62782c98db9d37d82f36 @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef MANIFEST_H +#define MANIFEST_H + +#include "AutomateCommand.h" +#include "MonotoneDelegate.h" + +#include +#include +#include + +struct ManifestEntry +{ + ManifestEntry * parent; + QList children; + QString path; + QString hash; + bool is_directory; + QMap attributes; + + ManifestEntry() : parent(NULL), path(""), hash(""), is_directory(true) {} + + inline QString filename() + { + return path.right(path.size() - path.lastIndexOf("/")); + } + inline int row() + { + if (parent) + return parent->children.indexOf(const_cast(this)); + return 0; + } + inline ManifestEntry* child(int row) + { + return children.value(row); + } + inline int childCount() + { + return children.size(); + } +}; + +class Manifest : public QAbstractItemModel, public AutomateCommand +{ + Q_OBJECT +public: + Manifest(QObject*); + virtual ~Manifest(); + + // needed Qt Model methods + QVariant data(const QModelIndex&, int) const; + Qt::ItemFlags flags(const QModelIndex&) const; + QVariant headerData(int, Qt::Orientation, int) const; + QModelIndex index(int, int, const QModelIndex&) const; + QModelIndex parent(const QModelIndex&) const; + int rowCount(const QModelIndex&) const; + int columnCount(const QModelIndex&) const; + +public slots: + bool readManifest(const QString &); + +signals: + void manifestRead(); + +private: + void parseOutput(); + ManifestEntry * root; + MonotoneDelegate * mtnDelegate; +}; + +#endif ============================================================ --- guitone/guitone.pro 89ffc63cab6945f7c72dd91d072bfa7425ae9d33 +++ guitone/guitone.pro fa6591e3761c27f496f59500e56dfa6cf9fcfbce @@ -45,6 +45,7 @@ HEADERS += src/view/MainWindow.h \ src/model/Changeset.h \ src/model/ChangesetModel.h \ src/model/Toposort.h \ + src/model/Manifest.h \ src/util/IconProvider.h \ src/util/StanzaParser.h \ src/util/Settings.h \ @@ -86,6 +87,7 @@ SOURCES += src/view/MainWindow.cpp \ src/model/Changeset.cpp \ src/model/ChangesetModel.cpp \ src/model/Toposort.cpp \ + src/model/Manifest.cpp \ src/util/IconProvider.cpp \ src/util/StanzaParser.cpp \ src/util/Settings.cpp \