/guitone-1.0rc5/src/model/InventoryItem.cpp
# · C++ · 557 lines · 460 code · 69 blank · 28 comment · 158 complexity · ca3eab2e97be174e2772674761dc5610 MD5 · raw file
- /***************************************************************************
- * Copyright (C) 2006 by Thomas Keller *
- * me@thomaskeller.biz *
- * *
- * 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 3 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, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
- #include "InventoryItem.h"
- #include <QStringList>
- #include <QFont>
- ModelItem::ModelItem(const QString & l) : parentItem(0), label(l)
- {}
- ModelItem::ModelItem(const ModelItem * other)
- {
- parentItem = other->parent();
- children = other->getChildren();
- label = other->getLabel();
- }
- ModelItem::~ModelItem()
- {
- deleteAllChildren();
- }
- void ModelItem::setLabel(const QString & l)
- {
- label = l;
- }
- QString ModelItem::getLabel() const
- {
- return label;
- }
- void ModelItem::deleteAllChildren()
- {
- qDeleteAll(children);
- children.clear();
- }
- void ModelItem::appendChild(ModelItem * child)
- {
- child->setParent(this);
- children.append(child);
- }
- void ModelItem::removeChild(ModelItem * child)
- {
- int idx = children.indexOf(child);
- if (idx == -1) return;
- children.removeAt(idx);
- }
- void ModelItem::setChildren(QList<ModelItem *> items)
- {
- deleteAllChildren();
- foreach (ModelItem * item, items)
- {
- appendChild(item);
- }
- }
- QList<ModelItem *> ModelItem::getChildren() const
- {
- return children;
- }
- void ModelItem::setParent(ModelItem * p)
- {
- parentItem = p;
- }
- ModelItem * ModelItem::parent() const
- {
- return parentItem;
- }
- ModelItem * ModelItem::child(int row) const
- {
- if (row < children.size())
- {
- return children.value(row);
- }
- return 0;
- }
- int ModelItem::childCount() const
- {
- return children.count();
- }
- int ModelItem::row() const
- {
- if (parentItem)
- {
- return parentItem->children.indexOf(const_cast<ModelItem *>(this));
- }
- return 0;
- }
- QVariant ModelItem::data(int column, int role) const
- {
- if (role == Qt::DisplayRole)
- {
- // return column headers for root item
- if (parentItem == this)
- {
- switch (column)
- {
- case 0: return QVariant(QString(tr("File")));
- case 1: return QVariant(QString(tr("Status")));
- default: return QVariant();
- }
- }
- switch (column)
- {
- case 0: return QVariant(label);
- default: return QVariant();
- }
- }
- if (role == Qt::DecorationRole && column == 0)
- {
- IconProvider * provider = IconProvider::singleton();
- return provider->getIcon(this);
- }
- return QVariant();
- }
- bool ModelItem::isRoot() const
- {
- return this == parentItem;
- }
- const int InventoryItem::RenameSource = 1;
- const int InventoryItem::RenameTarget = 2;
- const int InventoryItem::Added = 4;
- const int InventoryItem::Dropped = 8;
- const int InventoryItem::Missing = 16;
- const int InventoryItem::Known = 32;
- const int InventoryItem::Unknown = 64;
- const int InventoryItem::Ignored = 128;
- const int InventoryItem::Invalid = 256;
- const int InventoryItem::ContentsChanged = 512;
- const int InventoryItem::AttributesChanged = 1024;
- QString InventoryItem::translateFileType(const FileType & t)
- {
- switch (t)
- {
- case File: return tr("File");
- case Directory: return tr("Directory");
- case None: return tr("None");
- default: return "-";
- }
- }
- InventoryItem::InventoryItem(const Stanza & stanza)
- : ModelItem(), fs_type(Undefined), old_type(Undefined), new_type(Undefined),
- status(0), aboutToBeExpanded(false)
- {
- foreach (const StanzaEntry & en, stanza)
- {
- if (en.sym == "path")
- {
- I(en.vals.size() == 1);
- path = en.vals.at(0);
- continue;
- }
- if (en.sym == "old_path")
- {
- I(en.vals.size() == 1);
- old_path = en.vals.at(0);
- continue;
- }
- if (en.sym == "new_path")
- {
- I(en.vals.size() == 1);
- new_path = en.vals.at(0);
- continue;
- }
- if (en.sym == "old_type")
- {
- I(en.vals.size() == 1);
- if (en.vals.at(0) == "file")
- old_type = File;
- else if (en.vals.at(0) == "directory")
- old_type = Directory;
- else
- I(false);
- continue;
- }
- if (en.sym == "new_type")
- {
- I(en.vals.size() == 1);
- if (en.vals.at(0) == "file")
- new_type = File;
- else if (en.vals.at(0) == "directory")
- new_type = Directory;
- else
- I(false);
- continue;
- }
- if (en.sym == "fs_type")
- {
- I(en.vals.size() == 1);
- if (en.vals.at(0) == "file")
- fs_type = File;
- else if (en.vals.at(0) == "directory")
- fs_type = Directory;
- else if (en.vals.at(0) == "none")
- fs_type = None;
- else
- I(false);
- continue;
- }
- if (en.sym == "status")
- {
- I(en.vals.size() > 0);
- foreach (const QString & val, en.vals)
- {
- if (val == "rename_source")
- status |= RenameSource;
- else if (val == "rename_target")
- status |= RenameTarget;
- else if (val == "added")
- status |= Added;
- else if (val == "dropped")
- status |= Dropped;
- else if (val == "known")
- status |= Known;
- else if (val == "unknown")
- status |= Unknown;
- else if (val == "ignored")
- status |= Ignored;
- else if (val == "missing")
- status |= Missing;
- else if (val == "invalid")
- status |= Invalid;
- else
- I(false);
- }
- continue;
- }
- if (en.sym == "changes")
- {
- I(en.vals.size() > 0 && en.vals.size() < 3);
- foreach (const QString & val, en.vals)
- {
- if (val == "content")
- status |= ContentsChanged;
- else if (val == "attrs")
- status |= AttributesChanged;
- else
- I(false);
- }
- continue;
- }
- if (en.sym == "birth")
- {
- I(en.vals.size() == 1);
- birthRev = en.vals.at(0);
- }
- }
- // we should have received at least a path, status and fs_type entry
- I(!path.isNull());
- I(status > 0);
- I(fs_type > 0);
- }
- InventoryItem::InventoryItem(const InventoryItem * other) : ModelItem(other)
- {
- path = other->getPath();
- old_path = other->getRenameSource();
- new_path = other->getRenameTarget();
- fs_type = other->getFSType();
- old_type = other->getOldType();
- new_type = other->getNewType();
- birthRev = other->getBirthRevision();
- status = other->getStatus();
- }
- QVariant InventoryItem::data(int column, int role) const
- {
- if (role == Qt::DisplayRole && parentItem != this)
- {
- switch (column)
- {
- case 0: return QVariant(getLabel());
- case 1: return QVariant(getStatusString());
- default: return QVariant();
- }
- }
- else if (role == Qt::FontRole && column == 0)
- {
- QFont font;
- font.setBold(false);
- if (hasChangedRecursive())
- {
- font.setBold(true);
- }
- return QVariant(font);
- }
- else if (role == Qt::ForegroundRole)
- {
- if (hasStatus(Invalid))
- {
- return QVariant(Qt::red);
- }
- return QVariant();
- }
- else if (role == Qt::EditRole && column == 0)
- {
- return QVariant(getFilename());
- }
- return ModelItem::data(column, role);
- }
- QString InventoryItem::getLabel() const
- {
- if (!label.isEmpty()) return label;
- return getFilename();
- }
- QString InventoryItem::getFilename() const
- {
- int pos = path.lastIndexOf('/');
- return pos == -1 ? path : path.right(path.length() - pos - 1);
- }
- QString InventoryItem::getRelativePath(const QString & part) const
- {
- int partLen = part.length();
- I(path.left(partLen).compare(part) == 0);
- return path.right(path.length() - partLen);
- }
- QString InventoryItem::getBaseDirectory() const
- {
- int pos = path.lastIndexOf('/');
- return pos == -1 ? QString("") : path.left(pos);
- }
- bool InventoryItem::hasStatus(int statusBits) const
- {
- return (status & statusBits) == statusBits;
- }
- bool InventoryItem::hasNotStatus(int statusBits) const
- {
- return (status & statusBits) == 0;
- }
- void InventoryItem::setStatusRecursive(int statusBits)
- {
- status = statusBits;
- if (!isDirectory())
- {
- return;
- }
- for (int i=0,s=children.size(); i<s; i++)
- {
- InventoryItem * item = qobject_cast<InventoryItem *>(children.at(i));
- // skip everything other than InventoryItems
- if (!item) continue;
- item->setStatusRecursive(statusBits);
- }
- }
- int InventoryItem::getStatusRecursive() const
- {
- int overallStatus = status;
- if (!isDirectory())
- {
- return overallStatus;
- }
- for (int i=0,s=children.size(); i<s; i++)
- {
- InventoryItem * item = qobject_cast<InventoryItem *>(children.at(i));
- // skip everything other than InventoryItems
- if (!item) continue;
- overallStatus |= item->getStatusRecursive();
- }
- return overallStatus;
- }
- bool InventoryItem::isNewNode() const
- {
- return hasStatus(Known) || hasStatus(Missing)
- || hasStatus(Added) || hasStatus(RenameTarget);
- }
- bool InventoryItem::isOldNode() const
- {
- return hasStatus(Dropped) || hasStatus(RenameSource);
- }
- bool InventoryItem::isTracked() const
- {
- return hasNotStatus(Ignored | Unknown);
- }
- bool InventoryItem::hasChanged() const
- {
- return hasStatus(Added) || hasStatus(Dropped)
- || hasStatus(RenameSource) || hasStatus(RenameTarget)
- || hasStatus(Invalid) || hasStatus(AttributesChanged)
- || hasStatus(ContentsChanged);
- }
- bool InventoryItem::hasChangedRecursive() const
- {
- int state = getStatusRecursive();
- return
- (state & Added) == Added ||
- (state & Dropped) == Dropped ||
- (state & RenameSource) == RenameSource ||
- (state & RenameTarget) == RenameTarget ||
- (state & Invalid) == Invalid ||
- (state & AttributesChanged) == AttributesChanged ||
- (state & ContentsChanged) == ContentsChanged;
- }
- QString InventoryItem::getStatusString() const
- {
- QStringList list;
- // the patch states
- if (this->hasStatus(InventoryItem::ContentsChanged))
- {
- list.append(tr("Contents modified"));
- }
- if (this->hasStatus(InventoryItem::AttributesChanged))
- {
- list.append(tr("Attributes modified"));
- }
- // the possible old node states
- if (this->hasStatus(InventoryItem::RenameSource))
- {
- list.append(tr("Rename Source"));
- }
- if (this->hasStatus(InventoryItem::Dropped))
- {
- list.append(tr("Dropped"));
- }
- // the possible new states
- if (this->hasStatus(InventoryItem::RenameTarget))
- {
- list.append(tr("Rename Target"));
- }
- if (this->hasStatus(InventoryItem::Added))
- {
- list.append(tr("Added"));
- }
- // the file states
- if (this->hasStatus(InventoryItem::Missing))
- {
- list.append(tr("Missing"));
- }
- if (this->hasStatus(InventoryItem::Known))
- {
- list.append(tr("Known"));
- }
- if (this->hasStatus(InventoryItem::Unknown))
- {
- list.append(tr("Unknown"));
- }
- if (this->hasStatus(InventoryItem::Ignored))
- {
- list.append(tr("Ignored"));
- }
- // a state which occurs if the node's file type has been
- // mangled (f.e. node is recorded as file, but exists in fs as directory)
- if (this->hasStatus(InventoryItem::Invalid))
- {
- list.append(tr("Invalid"));
- }
- return list.join(", ");
- }
- bool InventoryItem::isExpanded(int level) const
- {
- I(level >= 0);
- if (!isDirectory())
- return true;
- if (childCount() == 0)
- return false;
- if (level > 0)
- {
- foreach (ModelItem * child, children)
- {
- InventoryItem * invitem = dynamic_cast<InventoryItem *>(child);
- if (!invitem)
- continue;
- if (!invitem->isExpanded(level - 1))
- return false;
- }
- }
- return true;
- }
- bool InventoryItem::isAboutToBeExpanded() const
- {
- return aboutToBeExpanded;
- }
- void InventoryItem::setAboutToBeExpanded()
- {
- aboutToBeExpanded = true;
- // set the dirty status for all current descendants as well
- foreach (ModelItem * child, children)
- {
- InventoryItem * invitem = dynamic_cast<InventoryItem *>(child);
- if (!invitem) continue;
- invitem->setAboutToBeExpanded();
- }
- }