#
#
# delete "res/overlays/added_missing.png"
#
# delete "res/overlays/dropped_added.png"
#
# delete "res/overlays/dropped_added_missing.png"
#
# delete "res/overlays/dropped_rename_target.png"
#
# delete "res/overlays/dropped_rename_target_missing.png"
#
# delete "res/overlays/dropped_unknown_ignored.png"
#
# delete "res/overlays/patched.png"
#
# delete "res/overlays/rename_source.png"
#
# delete "res/overlays/rename_source_added.png"
#
# delete "res/overlays/rename_source_added_missing.png"
#
# delete "res/overlays/rename_source_target.png"
#
# delete "res/overlays/rename_source_target_missing.png"
#
# delete "res/overlays/rename_source_unknown_ignored.png"
#
# delete "res/overlays/rename_target.png"
#
# delete "res/overlays/rename_target_missing.png"
#
# delete "res/overlays/unchanged.png"
#
# add_file "res/overlays/attributes_changed.png"
# content [b378d7c64f993f0f067b2d44e3bed6d7d9e88a63]
#
# add_file "res/overlays/content_attributes_changed.png"
# content [27e2d457a286431fce1a3edd2ab1d1595ad17b4e]
#
# add_file "res/overlays/content_changed.png"
# content [458a3dd29e94f6855cad81403e6d86a33e3746da]
#
# add_file "res/overlays/invalid.png"
# content [553b78c6a8a34cb8fd1a50602663903f86334673]
#
# add_file "res/overlays/renamed.png"
# content [f6cc05b35d05b9859cc8a4ce953f6fa991ec45f9]
#
# patch "guitone.pro"
# from [3fd3843b740f3d8859e4647497bbe315d23707ea]
# to [1c7014b14dc27560b3de131703a35530cfdf98f3]
#
# patch "res/guitone.qrc"
# from [f79689930cf514724cb11d18e452cba44630c2b6]
# to [22e8f7b57aeec704d4237a2502392ad102f98a03]
#
# patch "res/overlays/added.png"
# from [a3f896a257fd0fdeb51c38e8ccd5b569e445a3d2]
# to [b67d5b01ff0bd6531e43bbfeb84cae1f89b58f81]
#
# patch "res/overlays/cdup.png"
# from [9d51d79a1e09b20ef68e57325dbaece4cf7cd83f]
# to [2e2c22895f69da156bfd0b3c0404472546251209]
#
# patch "res/overlays/dropped.png"
# from [2d5080548f7ae87568f38c65e1afe4e4cef5f9ba]
# to [1c141a16629b660b73db312730e864ba59f94826]
#
# patch "res/overlays/ignored.png"
# from [875c76ae4acd950981e7af4a48b0bf994df48cda]
# to [693320730927109d650f9101f1ee33ca5ab24503]
#
# patch "res/overlays/missing.png"
# from [824de43651c95cd61882e2e584ec76b5f689b67d]
# to [8de09f78d3970b31758b4df5bf84af0469ba892f]
#
# patch "res/overlays/unknown.png"
# from [65f32f869d61bc9250db08354f1d4f9c0c4c8e2c]
# to [6a570f0a61cef0ec50367ed47400651f812db5c8]
#
# patch "src/model/Inventory.cpp"
# from [5f1c07927812405f93f4290686c37dd9b77a2098]
# to [0b85908036de2c631f54520b95647496d4da7e94]
#
# patch "src/model/Inventory.h"
# from [915db6a5693802dac41f20d550b54c86e89eb39a]
# to [5d55d16c1fea9407de59a2c88b040f906f57bb3d]
#
# patch "src/model/InventoryItem.cpp"
# from [439c5422abaf9736f91c1b462d16e200e0e1d721]
# to [adff7c83b3515ff7672b1ebe4db8690c5733bacb]
#
# patch "src/model/InventoryItem.h"
# from [0498e1d8a79804da34e4e789ad05e544026aa2b0]
# to [f9a843860c2aa346bcd442e2d502dfac7a618386]
#
# patch "src/model/InventoryProxyModel.cpp"
# from [e03c57d82a6e0ec6f1b842523a7a87278f7ac983]
# to [8bb35e56494804f307d473bed5b01bae40b7bc37]
#
# patch "src/model/InventoryProxyModel.h"
# from [61eb7da315ee67909835aeacd223141f8fc40fdd]
# to [a7239616d0752740a3dfc9bd65d6d31ad2fe1973]
#
# patch "src/util/IconProvider.cpp"
# from [eade6accc5f04c14c3f153b036d08e08e2c81499]
# to [50010e2667d22c4df62b561115be814e694d6a27]
#
# patch "src/util/IconProvider.h"
# from [0331678a530715a50344d5fb07943f02ad24bccf]
# to [2b2f908c2f64b59def8971d445238252fde01e66]
#
# patch "src/view/InventoryView.cpp"
# from [0207a6e08fed77d118b60410c1e432ee5ba458ad]
# to [50873ebddf25b10ff14a51696a346c1c2e858170]
#
# patch "src/view/Splitter.cpp"
# from [4ef814b5b7fcb03120f6f889aa279fdd0518df5f]
# to [52ebbc624ae37b76a88cdb95b1e3f574a86e5b79]
#
# patch "src/view/WorkspaceMenuBar.cpp"
# from [79395e00c0a347b59a71f00738882d0e58d69fce]
# to [7f8026a44fa642d0bc6ef70be9694c4074e445f2]
#
# patch "src/view/WorkspaceMenuBar.h"
# from [00dd3c433ab74935e3b0b8c4227a651f367724ae]
# to [37f078fffd28f79bcdf6960b71884577cebea6f3]
#
# patch "src/view/WorkspaceWindow.cpp"
# from [c0edca2787683a449e4f3a1a540cbeb2a122fe83]
# to [da5b5622acc662e7f09e64ede5852682ca0d452f]
#
# set "res/overlays/attributes_changed.png"
# attr "mtn:manual_merge"
# value "true"
#
# set "res/overlays/content_attributes_changed.png"
# attr "mtn:manual_merge"
# value "true"
#
# set "res/overlays/content_changed.png"
# attr "mtn:manual_merge"
# value "true"
#
# set "res/overlays/invalid.png"
# attr "mtn:manual_merge"
# value "true"
#
# set "res/overlays/renamed.png"
# attr "mtn:manual_merge"
# value "true"
#
============================================================
# res/overlays/attributes_changed.png is binary
============================================================
# res/overlays/content_attributes_changed.png is binary
============================================================
# res/overlays/content_changed.png is binary
============================================================
# res/overlays/invalid.png is binary
============================================================
# res/overlays/renamed.png is binary
============================================================
--- guitone.pro 3fd3843b740f3d8859e4647497bbe315d23707ea
+++ guitone.pro 1c7014b14dc27560b3de131703a35530cfdf98f3
@@ -1,9 +1,9 @@ GUITONE_VERSION = "0.7"
#
# global version strings
#
GUITONE_VERSION = "0.7"
-MIN_MTN_INT_VERSION = "5.0"
-MAX_MTN_INT_VERSION = "6.0"
+MIN_MTN_INT_VERSION = "6.0"
+MAX_MTN_INT_VERSION = "7.0"
#
# common configuration
============================================================
--- res/guitone.qrc f79689930cf514724cb11d18e452cba44630c2b6
+++ res/guitone.qrc 22e8f7b57aeec704d4237a2502392ad102f98a03
@@ -9,26 +9,15 @@
icons/blue_dot.png
icons/arrow_down.png
overlays/added.png
- overlays/added_missing.png
- overlays/cdup.png
overlays/dropped.png
- overlays/dropped_added.png
- overlays/dropped_added_missing.png
- overlays/dropped_rename_target.png
- overlays/dropped_rename_target_missing.png
- overlays/dropped_unknown_ignored.png
overlays/ignored.png
overlays/missing.png
- overlays/patched.png
- overlays/rename_source.png
- overlays/rename_source_added.png
- overlays/rename_source_added_missing.png
- overlays/rename_source_target.png
- overlays/rename_source_target_missing.png
- overlays/rename_source_unknown_ignored.png
- overlays/rename_target.png
- overlays/rename_target_missing.png
- overlays/unchanged.png
+ overlays/renamed.png
overlays/unknown.png
+ overlays/content_attributes_changed.png
+ overlays/content_changed.png
+ overlays/attributes_changed.png
+ overlays/invalid.png
+ overlays/cdup.png
============================================================
# res/overlays/added.png is binary
============================================================
# res/overlays/cdup.png is binary
============================================================
# res/overlays/dropped.png is binary
============================================================
# res/overlays/ignored.png is binary
============================================================
# res/overlays/missing.png is binary
============================================================
# res/overlays/unknown.png is binary
============================================================
--- src/model/Inventory.cpp 5f1c07927812405f93f4290686c37dd9b77a2098
+++ src/model/Inventory.cpp 0b85908036de2c631f54520b95647496d4da7e94
@@ -19,20 +19,15 @@
***************************************************************************/
#include "Inventory.h"
-#include "InventoryItem.h"
#include "MonotoneUtil.h"
-#include "IconProvider.h"
+#include "BasicIOParser.h"
#include
Inventory::Inventory(QObject * parent)
: QAbstractItemModel(parent), AutomateCommand(0), workspacePath()
{
- // create a dummy item since the view needs at least one item
- // in the model, otherwise the app crashes
- rootItem = new InventoryItem();
- regex = new QRegExp("^(R|D|[ ])(R|A|[ ])(M|P|U|I|[ ])\\s(\\d+)\\s(\\d+)\\s(.+)$");
- regex->setMinimal(true);
+ rootItem = new PseudoItem("__root", PseudoItem::Root);
connect(
this, SIGNAL(modelCreated()),
@@ -43,7 +38,6 @@ Inventory::~Inventory()
Inventory::~Inventory()
{
delete rootItem;
- delete regex;
}
void Inventory::setWorkspacePath(const WorkspacePath & ws)
@@ -51,10 +45,17 @@ void Inventory::setWorkspacePath(const W
workspacePath = ws;
}
-void Inventory::readInventory()
+void Inventory::readInventory(const QString & path)
{
I(!workspacePath.isEmpty());
- MonotoneTask task(QStringList() << "inventory");
+
+ QStringList cmd = QStringList() << "inventory";
+ if (!path.isEmpty())
+ {
+ cmd << path;
+ }
+
+ MonotoneTask task(cmd);
AutomateCommand::enqueueWorkspaceTask(workspacePath, task);
}
@@ -75,102 +76,52 @@ void Inventory::processTaskResult(const
return;
}
- QStringList lines = task.getOutputUtf8().split("\n", QString::SkipEmptyParts);
- QMap renameMap;
- QMap::iterator renameIter;
+ BasicIOParser parser(task.getOutputUtf8());
+ I(parser.parse());
+ StanzaList stanzas = parser.getStanzas();
QList items;
- InventoryItem * item;
- int status(0);
- int from_id(0);
- int to_id(0);
- QString path("");
- bool isDirectory(false);
-
- for (QStringList::Iterator it = lines.begin(); it != lines.end(); ++it)
+ foreach (Stanza st, stanzas)
{
- if (!parseInventoryLine(*it, status, from_id, to_id, path, isDirectory))
- {
- continue;
- }
-
- // this item is given a parent explicitely later on
- item = new InventoryItem(isDirectory);
- item->setPath(path);
- item->setStatus(status);
-
- if (from_id > 0)
- {
- renameMap[-from_id] = item;
- }
- if (to_id > 0)
- {
- renameMap[to_id] = item;
- }
-
+ InventoryItem * item = new InventoryItem(st);
items.push_back(item);
}
- int id = 0;
-
- while (true)
- {
- renameIter = renameMap.find(++id);
- if (renameIter == renameMap.end()) break;
-
- renameMap[id]->setRenamedFrom(renameMap[-id]);
- renameMap[-id]->setRenamedTo(renameMap[id]);
- }
-
flatItemList.clear();
flatItemList = items;
- // FIXME: we shouldn't really add a workspace root item here, but
- // mtn automate inventory currently doesn't print the root workspace dir
- InventoryItem * branch = new InventoryItem(true, true);
- branch->setParent(rootItem);
- branch->setPath(".");
- branch->setStatus(0);
- branch->setChildren(buildTreeRecursive(items, NULL));
-
- // remove any older item
rootItem->deleteAllChildren();
- rootItem->appendChild(branch);
+ rootItem->setChildren(buildTreeRecursive(items, NULL));
- // reset the model to repaint the view completly
- // (all QModelIndexes are discarded through that, e.g. selections!)
+ // invalidate model indexes and request a repaint
reset();
- // restore the normal cursor
- qApp->restoreOverrideCursor();
-
emit modelCreated();
}
void Inventory::loadBranchName()
{
- QList children = rootItem->getChildren();
+ QList children = rootItem->getChildren();
I(children.size() > 0);
children[0]->setLabel(MonotoneUtil::getBranchName(workspacePath));
dataChanged(index(0, 0, QModelIndex()), index(0, 2, QModelIndex()));
}
-QList Inventory::buildTreeRecursive(QList & items, InventoryItem * parentItem)
+QList Inventory::buildTreeRecursive(QList & items, ModelItem * parentItem)
{
- QList finalItems;
+ QList finalItems;
QString parentPath = "";
- if (parentItem != NULL)
+ InventoryItem * parent = dynamic_cast(parentItem);
+ if (parent)
{
- parentPath = parentItem->getPath();
+ parentPath = parent->getPath();
}
- // add pseudo item "cd up" for each directory level
- InventoryItem * cdUp = new InventoryItem(true);
+ ModelItem * cdUp = new PseudoItem("..", PseudoItem::CdUp);
cdUp->setParent(parentItem);
- cdUp->setPath(parentPath + QString("/.."));
finalItems.append(cdUp);
InventoryItem * currentItem;
@@ -199,7 +150,7 @@ QList Inventory::buildT
// it seems to be a valid item
//
- // if the item is directory a directory, catch items inside it
+ // if the item is a directory, catch items inside it
if (currentItem->isDirectory())
{
currentItem->setChildren(buildTreeRecursive(items, currentItem));
@@ -215,7 +166,7 @@ QModelIndex Inventory::index(int row, in
QModelIndex Inventory::index(int row, int column, const QModelIndex & parent) const
{
- InventoryItem * parentItem;
+ ModelItem * parentItem;
if (!parent.isValid())
{
@@ -223,10 +174,11 @@ QModelIndex Inventory::index(int row, in
}
else
{
- parentItem = static_cast(parent.internalPointer());
+ parentItem = static_cast(parent.internalPointer());
+ I(parentItem);
}
- InventoryItem * childItem = parentItem->child(row);
+ ModelItem * childItem = parentItem->child(row);
if (childItem)
{
@@ -236,71 +188,56 @@ QModelIndex Inventory::index(int row, in
return QModelIndex();
}
-int Inventory::columnCount(const QModelIndex &parent) const
+int Inventory::columnCount(const QModelIndex & parent) const
{
- if (parent.isValid())
- {
- return static_cast(parent.internalPointer())->columnCount();
- }
-
- return rootItem->columnCount();
+ Q_UNUSED(parent);
+ return 3;
}
-QVariant Inventory::data(const QModelIndex &index, int role) const
+QVariant Inventory::data(const QModelIndex & index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
- InventoryItem * item = static_cast(index.internalPointer());
-
- if ((role == Qt::DecorationRole) && (index.column() == 0))
- {
- IconProvider * provider = IconProvider::singleton();
- return provider->getIcon(item);
- }
- else
- {
- return item->data(index.column(), role);
- }
+ ModelItem * item = static_cast(index.internalPointer());
+ I(item);
+ return item->data(index.column(), role);
}
-bool Inventory::setData(const QModelIndex & idx, const QVariant & value, int role)
+Qt::ItemFlags Inventory::flags(const QModelIndex & index) const
{
- Q_UNUSED(idx);
- Q_UNUSED(value);
- Q_UNUSED(role);
- return false;
-}
-
-bool Inventory::setItemData(const QModelIndex & index, const QMap & roles)
-{
- Q_UNUSED(index);
- Q_UNUSED(roles);
- return false;
-}
-
-Qt::ItemFlags Inventory::flags(const QModelIndex &index) const
-{
if (!index.isValid()) return 0;
QFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
- InventoryItem * item = static_cast(index.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
+ I(item);
- if (item->isCdUp() || item->isRootDirectory()) return flags;
+ // no special flags for pseudo items
+ PseudoItem * psitem = dynamic_cast(item);
+ if (psitem)
+ {
+ return flags;
+ }
- /*
- // Disabled until we have figured out how to implement renaming properly
- flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
+ InventoryItem * invitem = dynamic_cast(item);
+ if (invitem)
+ {
+ /*
+ // Disabled until we have figured out how to implement renaming properly
+ if (item->isNewNode())
+ {
+ flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
- if (item->isDirectory())
- {
- flags |= Qt::ItemIsDropEnabled;
+ if (item->isDirectory())
+ {
+ flags |= Qt::ItemIsDropEnabled;
+ }
+ }
+ */
}
- */
-
return flags;
}
@@ -322,121 +259,32 @@ QModelIndex Inventory::parent(const QMod
return QModelIndex();
}
- InventoryItem * childItem = static_cast(index.internalPointer());
- InventoryItem * parentItem = childItem->parent();
+ ModelItem * childItem = static_cast(index.internalPointer());
+ I(childItem);
+ ModelItem * parentItem = childItem->parent();
if (parentItem == rootItem)
{
return QModelIndex();
}
+ I(parentItem);
return createIndex(parentItem->row(), 0, parentItem);
}
-int Inventory::rowCount(const QModelIndex& parent) const
+int Inventory::rowCount(const QModelIndex & parent) const
{
- InventoryItem * parentItem = rootItem;
+ ModelItem * parentItem = rootItem;
if (parent.isValid())
{
- parentItem = static_cast(parent.internalPointer());
+ parentItem = static_cast(parent.internalPointer());
}
+ I(parentItem);
return parentItem->childCount();
}
-bool Inventory::parseInventoryLine(
- const QString &inputString,
- int &status,
- int &from_id,
- int &to_id,
- QString &path,
- bool &isDirectory)
-{
- if (regex->indexIn(inputString) == -1)
- {
- W(QString("Couldn't parse inventory line %1").arg(inputString));
- return false;
- }
-
- QStringList list = regex->capturedTexts();
- status = 0;
-
- // the first match
- if (list[1].compare("R") == 0)
- {
- status |= InventoryItem::RenamedFrom;
- } else
- if (list[1].compare("D") == 0)
- {
- status |= InventoryItem::Dropped;
- }
- else
- if (list[1].compare(" ") != 0)
- {
- W(QString("Unknown status first tripel %1").arg(list[1]));
- }
-
- // the second match
- if (list[2].compare("R") == 0)
- {
- status |= InventoryItem::RenamedTo;
- } else
- if (list[2].compare("A") == 0)
- {
- status |= InventoryItem::Added;
- }
- else
- if (list[2].compare(" ") != 0)
- {
- W(QString("Unknown status second tripel %1").arg(list[2]));
- }
-
- // the third match
- if (list[3].compare("M") == 0)
- {
- status |= InventoryItem::Missing;
- } else
- if (list[3].compare("P") == 0)
- {
- status |= InventoryItem::Patched;
- } else
- if (list[3].compare("U") == 0)
- {
- status |= InventoryItem::Unknown;
- } else
- if (list[3].compare("I") == 0)
- {
- status |= InventoryItem::Ignored;
- }
- else
- if (list[3].compare(" ") == 0)
- {
- status |= InventoryItem::Unchanged;
- }
- else
- {
- W(QString("Unknown status third tripel %1").arg(list[3]));
- }
-
- I(InventoryItem::ValidStates.contains(status));
-
- // now determine if the file has been renamed
- from_id = list[4].toInt();
- to_id = list[5].toInt();
- path = list[6].trimmed();
-
- isDirectory = false;
- if (path.endsWith('/'))
- {
- isDirectory = true;
- path = path.left(path.length() - 1);
- }
-
- // parsing was successful
- return true;
-}
-
//! TODO move this somewhere else without the inventory model dependency
QMap Inventory::findUnaccountedRenames()
{
@@ -474,7 +322,7 @@ QMap Inventory
// this is a new entry not recorded in the base roster
if (missingItem->hasStatus(InventoryItem::Added) ||
- missingItem->hasStatus(InventoryItem::RenamedTo))
+ missingItem->hasStatus(InventoryItem::RenameTarget))
{
entry.path = missingItem->getPath();
entry.is_dir = missingItem->isDirectory();
============================================================
--- src/model/Inventory.h 915db6a5693802dac41f20d550b54c86e89eb39a
+++ src/model/Inventory.h 5d55d16c1fea9407de59a2c88b040f906f57bb3d
@@ -22,12 +22,10 @@
#define INVENTORY_H
#include "AutomateCommand.h"
+#include "InventoryItem.h"
-#include
#include
-class InventoryItem;
-
class Inventory : public QAbstractItemModel, public AutomateCommand
{
Q_OBJECT
@@ -39,8 +37,6 @@ public:
// needed Qt Model methods
QVariant data(const QModelIndex &, int) const;
- bool setData(const QModelIndex &, const QVariant &, int role = Qt::EditRole);
- bool setItemData(const QModelIndex &, const QMap &);
Qt::ItemFlags flags(const QModelIndex &) const;
QVariant headerData(int, Qt::Orientation, int) const;
QModelIndex index(int, int, const QModelIndex &) const;
@@ -50,15 +46,13 @@ public slots:
public slots:
void setWorkspacePath(const WorkspacePath &);
- void readInventory();
+ void readInventory(const QString & path = QString());
private:
void processTaskResult(const MonotoneTask &);
- bool parseInventoryLine(const QString &, int &, int &, int &, QString &, bool &);
- QList buildTreeRecursive(QList &, InventoryItem*);
+ QList buildTreeRecursive(QList &, ModelItem *);
- InventoryItem * rootItem;
- QRegExp * regex;
+ ModelItem * rootItem;
QString branchName;
QList flatItemList;
WorkspacePath workspacePath;
============================================================
--- src/model/InventoryItem.cpp 439c5422abaf9736f91c1b462d16e200e0e1d721
+++ src/model/InventoryItem.cpp adff7c83b3515ff7672b1ebe4db8690c5733bacb
@@ -19,158 +19,163 @@
***************************************************************************/
#include "InventoryItem.h"
-#include "vocab.h"
#include
#include
-const int InventoryItem::RenamedFrom = 1;
-const int InventoryItem::RenamedTo = 2;
-const int InventoryItem::Added = 4;
-const int InventoryItem::Dropped = 8;
-const int InventoryItem::Missing = 16;
-const int InventoryItem::Patched = 32;
-const int InventoryItem::Unchanged = 64;
-const int InventoryItem::Unknown = 128;
-const int InventoryItem::Ignored = 256;
+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;
-//
-// initialize the array with all 26 valid states (out of 45 possible)
-//
-const QList InventoryItem::ValidStates = QList()
- << InventoryItem::Unchanged // ' '
- << InventoryItem::Patched // ' P'
- << InventoryItem::Unknown // ' U'
- << InventoryItem::Ignored // ' I'
- << InventoryItem::Missing // ' M'
- << ( InventoryItem::Added | InventoryItem::Patched ) // ' AP'
- << ( InventoryItem::Added | InventoryItem::Missing ) // ' AM'
- << ( InventoryItem::RenamedTo | InventoryItem::Unchanged ) // ' R '
- << ( InventoryItem::RenamedTo | InventoryItem::Patched ) // ' RP'
- << ( InventoryItem::RenamedTo | InventoryItem::Missing ) // ' RM'
- << ( InventoryItem::Dropped | InventoryItem::Unchanged ) // 'D '
- << ( InventoryItem::Dropped | InventoryItem::Unknown ) // 'D U'
- << ( InventoryItem::Dropped | InventoryItem::Ignored ) // 'D I'
- << ( InventoryItem::Dropped | InventoryItem::Added | InventoryItem::Patched ) // 'DAP'
- << ( InventoryItem::Dropped | InventoryItem::Added | InventoryItem::Missing ) // 'DAM'
- << ( InventoryItem::Dropped | InventoryItem::RenamedTo | InventoryItem::Unchanged ) // 'DR '
- << ( InventoryItem::Dropped | InventoryItem::RenamedTo | InventoryItem::Patched ) // 'DRP'
- << ( InventoryItem::Dropped | InventoryItem::RenamedTo | InventoryItem::Missing ) // 'DRM'
- << ( InventoryItem::RenamedFrom | InventoryItem::Unchanged ) // 'R '
- << ( InventoryItem::RenamedFrom | InventoryItem::Unknown ) // 'R U'
- << ( InventoryItem::RenamedFrom | InventoryItem::Ignored ) // 'R I'
- << ( InventoryItem::RenamedFrom | InventoryItem::Added | InventoryItem::Patched ) // 'RAP'
- << ( InventoryItem::RenamedFrom | InventoryItem::Added | InventoryItem::Missing ) // 'RAM'
- << ( InventoryItem::RenamedFrom | InventoryItem::RenamedTo | InventoryItem::Unchanged )// 'RR '
- << ( InventoryItem::RenamedFrom | InventoryItem::RenamedTo | InventoryItem::Patched ) // 'RRP'
- << ( InventoryItem::RenamedFrom | InventoryItem::RenamedTo | InventoryItem::Missing ); // 'RRM'
-
-InventoryItem::InventoryItem(bool isDir /* =false */, bool isRoot /* =false */)
+InventoryItem::InventoryItem(const Stanza & stanza)
+ : ModelItem(), status(0)
{
- parentItem = this;
- path = "";
- label = "";
- status = 0;
- dirFlag = isDir;
- rootFlag = isRoot;
-}
+ foreach (StanzaEntry en, stanza)
+ {
+ if (en.sym == "path")
+ {
+ I(en.vals.size() == 1);
+ path = en.vals.at(0);
+ continue;
+ }
-InventoryItem::InventoryItem(const InventoryItem * other)
-{
- dirFlag = other->isDirectory();
- rootFlag = other->isRootDirectory();
- renamed_from = other->getRenamedFrom();
- renamed_to = other->getRenamedTo();
- parentItem = other->parent();
- children = other->getChildren();
- status = other->getStatus();
- path = other->getPath();
- label = other->getLabel();
-}
+ if (en.sym == "old_path")
+ {
+ I(en.vals.size() == 1);
+ old_path = en.vals.at(0);
+ continue;
+ }
-InventoryItem::~InventoryItem()
-{
- qDeleteAll(children);
- children.clear();
-}
+ if (en.sym == "new_path")
+ {
+ I(en.vals.size() == 1);
+ new_path = en.vals.at(0);
+ continue;
+ }
-QString InventoryItem::getItemName() const
-{
- if (label.size() > 0)
- {
- return label;
- }
-
- return getFilename();
-}
+ 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;
+ }
-void InventoryItem::deleteAllChildren(void)
-{
- parentItem = this;
- path = "";
- status = 0;
- dirFlag = false;
- rootFlag = false;
- qDeleteAll(children);
- children.clear();
-}
+ 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;
+ }
-void InventoryItem::appendChild(InventoryItem* child)
-{
- child->setParent(this);
- children.append(child);
-}
+ 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;
+ }
-void InventoryItem::setChildren(QList items)
-{
- // set the current element as parent for each children
- QList::iterator iter;
+ if (en.sym == "status")
+ {
+ I(en.vals.size() > 0);
+ foreach (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 (QString val, en.vals)
+ {
+ if (val == "content")
+ status |= ContentsChanged;
+ else if (val == "attrs")
+ status |= AttributesChanged;
+ else
+ I(false);
+ }
+ continue;
+ }
+ }
- InventoryItem *item;
- for (iter = items.begin(); iter != items.end(); ++iter)
- {
- item = (*iter);
- item->setParent(this);
- }
-
- children.clear();
- children = items;
+ // we should have received at least a path, status and fs_type entry
+ I(!path.isNull());
+ I(status > 0);
+ I(fs_type > 0);
}
-int InventoryItem::row() const
+InventoryItem::InventoryItem(const InventoryItem * other) : ModelItem(other)
{
- if (parentItem)
- return parentItem->children.indexOf(const_cast(this));
+ path = other->getPath();
+ old_path = other->getRenameSource();
+ new_path = other->getRenameTarget();
- return 0;
+ fs_type = other->getFSType();
+ old_type = other->getOldType();
+ new_type = other->getNewType();
+
+ status = other->getStatus();
}
QVariant InventoryItem::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")));
- case 2: return QVariant(QString(tr("Additional info")));
- default: return QVariant();
- }
- }
-
+ if (role == Qt::DisplayRole && parentItem != this)
+ {
switch (column)
- {
- case 0: return QVariant(getItemName());
+ {
+ case 0: return QVariant(getLabel());
case 1: return QVariant(getStatusString());
case 2: return QVariant(getRenameInfo());
default: return QVariant();
- }
- }
- else if (role == Qt::FontRole && column == 0)
- {
+ }
+ }
+ else if (role == Qt::FontRole && column == 0)
+ {
QFont font;
font.setBold(false);
if (hasChangedRecursive())
@@ -178,13 +183,25 @@ QVariant InventoryItem::data(int column,
font.setBold(true);
}
return QVariant(font);
- }
- else
- {
- return QVariant();
- }
+ }
+ else if (role == Qt::ForegroundRole)
+ {
+ if (hasStatus(Invalid))
+ {
+ return QVariant(Qt::red);
+ }
+ return QVariant();
+ }
+
+ return ModelItem::data(column, role);
}
+QString InventoryItem::getLabel() const
+{
+ if (!label.isEmpty()) return label;
+ return getFilename();
+}
+
QString InventoryItem::getFilename() const
{
int pos = path.lastIndexOf('/');
@@ -206,64 +223,95 @@ bool InventoryItem::hasStatus(int status
bool InventoryItem::hasStatus(int statusBits) const
{
- return (status & statusBits) == statusBits;
+ return (status & statusBits) == statusBits;
}
bool InventoryItem::hasNotStatus(int statusBits) const
{
- return (status & statusBits) == 0;
+ return (status & statusBits) == 0;
}
int InventoryItem::getStatusRecursive() const
{
int overallStatus = status;
-
+
if (!isDirectory())
{
return overallStatus;
}
-
+
for (int i=0,s=children.size(); i(children.at(i));
+ InventoryItem * item = static_cast(children.at(i));
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
+ return
(state & Added) == Added ||
(state & Dropped) == Dropped ||
- (state & RenamedFrom) == RenamedFrom ||
- (state & RenamedTo) == RenamedTo ||
- (state & Patched) == Patched;
+ (state & RenameSource) == RenameSource ||
+ (state & RenameTarget) == RenameTarget ||
+ (state & Invalid) == Invalid ||
+ (state & AttributesChanged) == AttributesChanged ||
+ (state & ContentsChanged) == ContentsChanged;
}
QString InventoryItem::getStatusString() const
{
- // do not return the status for
- if (isCdUp()) return "";
-
QStringList list;
-
- // at first the possible old states
- if (this->hasStatus(InventoryItem::RenamedFrom))
+
+ // 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"));
}
-
- // now the possible new states
- if (this->hasStatus(InventoryItem::RenamedTo))
+
+ // the possible new states
+ if (this->hasStatus(InventoryItem::RenameTarget))
{
list.append(tr("Rename Target"));
}
@@ -271,20 +319,16 @@ QString InventoryItem::getStatusString()
{
list.append(tr("Added"));
}
-
- // and finally the file states
+
+ // the file states
if (this->hasStatus(InventoryItem::Missing))
{
list.append(tr("Missing"));
}
- if (this->hasStatus(InventoryItem::Patched))
+ if (this->hasStatus(InventoryItem::Known))
{
- list.append(tr("Modified"));
+ list.append(tr("Known"));
}
- if (this->hasStatus(InventoryItem::Unchanged))
- {
- list.append(tr("Unchanged"));
- }
if (this->hasStatus(InventoryItem::Unknown))
{
list.append(tr("Unknown"));
@@ -293,25 +337,28 @@ QString InventoryItem::getStatusString()
{
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(", ");
}
QString InventoryItem::getRenameInfo() const
{
QStringList strings;
- if (hasStatus(RenamedFrom))
+ if (hasStatus(RenameSource))
{
- InventoryItem * item = getRenamedTo();
- I(item);
- strings << tr("new name: %1").arg(item->getPath());
+ strings << tr("new name: %1").arg(new_path);
}
-
- if (hasStatus(RenamedTo))
+
+ if (hasStatus(RenameTarget))
{
- InventoryItem * item = getRenamedFrom();
- I(item);
- strings << tr("old name: %1").arg(item->getPath());
+ strings << tr("old name: %1").arg(old_path);
}
return strings.join(", ");
}
============================================================
--- src/model/InventoryItem.h 0498e1d8a79804da34e4e789ad05e544026aa2b0
+++ src/model/InventoryItem.h f9a843860c2aa346bcd442e2d502dfac7a618386
@@ -21,84 +21,210 @@
#ifndef INVENTORY_ITEM_H
#define INVENTORY_ITEM_H
+#include "IconProvider.h"
+#include "vocab.h"
+
#include
-class InventoryItem : public QObject
+class ModelItem : public QObject
{
Q_OBJECT
public:
- InventoryItem(bool isDir = false, bool isRoot = false);
- InventoryItem(const InventoryItem *);
- ~InventoryItem(void);
+ ModelItem(const QString & l = QString()) : parentItem(0), label(l) {}
+ ModelItem(const ModelItem * other)
+ {
+ parentItem = other->parent();
+ children = other->getChildren();
+ label = other->getLabel();
+ }
- inline void setRenamedFrom(InventoryItem * from) { renamed_from = from; }
- inline void setRenamedTo(InventoryItem * to) { renamed_to = to; }
- inline InventoryItem * getRenamedFrom(void) const { return renamed_from; }
- inline InventoryItem * getRenamedTo(void) const { return renamed_to; }
+ virtual ~ModelItem() { deleteAllChildren(); }
- inline void setParent(InventoryItem * p) { parentItem = p; }
- inline InventoryItem * parent() const { return parentItem; }
- inline QList getChildren(void) const { return children; }
+ virtual void setLabel(const QString & l) { label = l; }
+ virtual QString getLabel() const { return label; }
- inline QString getPath(void) const { return path; }
- inline void setPath(const QString & p) { path = p; }
+ void deleteAllChildren()
+ {
+ qDeleteAll(children);
+ children.clear();
+ }
- inline bool isCdUp() const { return getFilename() == ".."; }
- inline bool isTracked() const { return hasNotStatus(Ignored | Unknown); }
- inline bool isDirectory(void) const { return dirFlag; }
- inline bool isRootDirectory(void) const { return rootFlag; }
- inline int getStatus(void) const { return status; }
- inline void setStatus(int st) { status = st; }
- inline void setLabel(const QString & l) { label = l; }
- inline QString getLabel() const { return label; }
+ void appendChild(ModelItem * child)
+ {
+ child->setParent(this);
+ children.append(child);
+ }
- inline InventoryItem * child(int row) const { return children.value(row); }
- inline int childCount(void) const { return children.count(); };
- inline int columnCount(void) const { return 3; }
+ void setChildren(QList items)
+ {
+ foreach (ModelItem * item, items)
+ {
+ item->setParent(this);
+ }
+ deleteAllChildren();
+ children = items;
+ }
- void setChildren(QList);
- void deleteAllChildren(void);
+ QList getChildren() const
+ {
+ return children;
+ }
- QString getRelativePath(const QString&) const;
- QString getFilename(void) const;
- QString getBaseDirectory(void) const;
+ void setParent(ModelItem * p)
+ {
+ parentItem = p;
+ }
+ ModelItem * parent() const
+ {
+ return parentItem;
+ }
+
+ ModelItem * child(int row) const
+ {
+ if (row < children.size())
+ {
+ return children.value(row);
+ }
+ return 0;
+ }
+
+ int childCount() const
+ {
+ return children.count();
+ }
+
+ int row() const
+ {
+ if (parentItem)
+ {
+ return parentItem->children.indexOf(const_cast(this));
+ }
+ return 0;
+ }
+
+ virtual QVariant 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")));
+ case 2: return QVariant(QString(tr("Additional info")));
+ 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();
+ }
+
+protected:
+ ModelItem * parentItem;
+ QList children;
+ QString label;
+};
+
+class PseudoItem : public ModelItem
+{
+ Q_OBJECT
+public:
+ enum Type { CdUp, Root };
+
+ PseudoItem(const QString & l, Type t) : ModelItem(l), type(t)
+ {
+ if (type == Root)
+ parentItem = this;
+ }
+
+ bool isCdUp() const { return type == CdUp; }
+ bool isRoot() const { return type == Root; }
+
+private:
+ Type type;
+};
+
+class InventoryItem : public ModelItem
+{
+ Q_OBJECT
+public:
+ enum FileType { File = 1, Directory, None };
+
+ InventoryItem(const Stanza &);
+ InventoryItem(const InventoryItem *);
+
+ inline QString getRenameSource() const { return old_path; }
+ inline QString getRenameTarget() const { return new_path; }
+ inline FileType getFSType() const { return fs_type; }
+ inline FileType getOldType() const { return old_type; }
+ inline FileType getNewType() const { return new_type; }
+ inline QString getPath() const { return path; }
+ inline int getStatus() const { return status; }
+ inline bool isDirectory() const { return fs_type == Directory ||
+ old_type == Directory ||
+ new_type == Directory; }
+
+ QString getRelativePath(const QString &) const;
+ QString getFilename() const;
+ QString getBaseDirectory() const;
+ QString getLabel() const;
+ QString getStatusString() const;
+ QString getRenameInfo() const;
+
bool hasStatus(int) const;
bool hasNotStatus(int) const;
+
+ bool isNewNode() const;
+ bool isOldNode() const;
+ bool isTracked() const;
+ bool hasChanged() const;
+
int getStatusRecursive() const;
bool hasChangedRecursive() const;
- /* needed for Qt model class */
- int row(void) const;
- void appendChild(InventoryItem*);
QVariant data(int, int) const;
- static const int RenamedFrom;
- static const int RenamedTo;
+ static const int RenameSource;
+ static const int RenameTarget;
static const int Added;
static const int Dropped;
static const int Missing;
- static const int Patched;
- static const int Unchanged;
+ static const int Ignored;
+ static const int Known;
static const int Unknown;
- static const int Ignored;
+ static const int Invalid;
+ static const int AttributesChanged;
+ static const int ContentsChanged;
- static const QList ValidStates;
-
private:
- QString getItemName(void) const;
- QString getStatusString(void) const;
- QString getRenameInfo(void) const;
+ InventoryItem * parentItem;
+ QList children;
- InventoryItem * renamed_from;
- InventoryItem * renamed_to;
- InventoryItem * parentItem;
- QList children;
+ QString path;
+ QString old_path;
+ QString new_path;
+
+ FileType fs_type;
+ FileType old_type;
+ FileType new_type;
+
int status;
- bool dirFlag;
- bool rootFlag;
- QString path;
- QString label;
};
#endif
============================================================
--- src/model/InventoryProxyModel.cpp e03c57d82a6e0ec6f1b842523a7a87278f7ac983
+++ src/model/InventoryProxyModel.cpp 8bb35e56494804f307d473bed5b01bae40b7bc37
@@ -32,20 +32,29 @@ bool InventoryProxyModel::filterAcceptsR
bool InventoryProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
- InventoryItem * item = static_cast(index.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
- // display the pseudo CdUp item only in the file list regardless of the
- // state of the item
- if (item->isCdUp())
+ PseudoItem * psitem = dynamic_cast(item);
+ if (psitem)
{
// only display this item if this is not the folder tree view
// and the parent of the item's parent is invalid (i.e. there is no
// way to cdUp anymore)
- return !folderTree && sourceParent.parent().isValid();
+ if (psitem->isCdUp())
+ return !folderTree && sourceParent.parent().isValid();
+
+ // always return the root item
+ if (psitem->isRoot())
+ return true;
+
+ I(false);
}
+ InventoryItem * invitem = dynamic_cast(item);
+ I(invitem);
+
// hide ignored files (not recursively)
- if (item->hasStatus(InventoryItem::Ignored) && hideIgnored)
+ if (invitem->hasStatus(InventoryItem::Ignored) && hideIgnored)
{
return false;
}
@@ -53,66 +62,71 @@ bool InventoryProxyModel::filterAcceptsR
bool acceptRow = true;
// check the view options
- int state = item->getStatusRecursive();
- bool patched = state & InventoryItem::Patched;
- bool added = state & InventoryItem::Added;
- bool dropped = state & InventoryItem::Dropped;
- bool renamed = state & InventoryItem::RenamedFrom ||
- state & InventoryItem::RenamedTo;
- bool unknown = state & InventoryItem::Unknown;
- bool missing = state & InventoryItem::Missing;
- bool ignored = state & InventoryItem::Ignored;
- bool changed = patched || added || dropped || renamed;
+ int state = invitem->getStatusRecursive();
+ bool cntchanged = state & InventoryItem::ContentsChanged;
+ bool attrchanged = state & InventoryItem::ContentsChanged;
+ bool added = state & InventoryItem::Added;
+ bool dropped = state & InventoryItem::Dropped;
+ bool renamed = state & InventoryItem::RenameSource ||
+ state & InventoryItem::RenameTarget;
+ bool unknown = state & InventoryItem::Unknown;
+ bool missing = state & InventoryItem::Missing;
+ bool ignored = state & InventoryItem::Ignored;
+ bool invalid = state & InventoryItem::Invalid;
+ bool changed = cntchanged || attrchanged || added || dropped || renamed;
- acceptRow &= viewOption != Changed || changed;
- acceptRow &= viewOption != Patched || patched;
- acceptRow &= viewOption != Added || added;
- acceptRow &= viewOption != Dropped || dropped;
- acceptRow &= viewOption != Renamed || renamed;
- acceptRow &= viewOption != Unknown || unknown;
- acceptRow &= viewOption != Missing || missing;
- acceptRow &= viewOption != Ignored || ignored;
+ acceptRow &= viewOption != Changed || changed;
+ acceptRow &= viewOption != ContentsChanged || cntchanged;
+ acceptRow &= viewOption != AttributesChanged || attrchanged;
+ acceptRow &= viewOption != Added || added;
+ acceptRow &= viewOption != Dropped || dropped;
+ acceptRow &= viewOption != Renamed || renamed;
+ acceptRow &= viewOption != Unknown || unknown;
+ acceptRow &= viewOption != Missing || missing;
+ acceptRow &= viewOption != Ignored || ignored;
+ acceptRow &= viewOption != Invalid || invalid;
// check if we should only display folders
- acceptRow &= !folderTree || item->isDirectory();
+ acceptRow &= !folderTree || invitem->isDirectory();
return acceptRow;
}
bool InventoryProxyModel::lessThan(const QModelIndex & left, const QModelIndex & right) const
{
- // TODO: Needs some tweaking for correct sorting when clicked on different headers
- // f.e. status strings are sorted differently based on their translation
- InventoryItem * itemLeft = static_cast(left.internalPointer());
- InventoryItem * itemRight = static_cast(right.internalPointer());
+ ModelItem * itemLeft = static_cast(left.internalPointer());
+ ModelItem * itemRight = static_cast(right.internalPointer());
+ InventoryItem * invitemLeft = dynamic_cast(itemLeft);
+ InventoryItem * invitemRight = dynamic_cast(itemRight);
+
// We shall sort by the name of the item
if (sortColumn == 0)
{
- // place cd up items always on the first position
- if (itemLeft->isCdUp() || itemRight->isCdUp()) return false;
+ // place pseudo items always right on top
+ if (!invitemLeft || !invitemRight) return false;
- if (itemLeft->isDirectory() && itemRight->isDirectory())
+ if (invitemLeft->isDirectory() && invitemRight->isDirectory())
{
- return itemLeft->getFilename() < itemRight->getFilename();
+ return invitemLeft->getFilename() < invitemRight->getFilename();
}
- if (!itemLeft->isDirectory() && !itemRight->isDirectory())
+ if (!invitemLeft->isDirectory() && !invitemRight->isDirectory())
{
- return itemLeft->getFilename() < itemRight->getFilename();
+ return invitemLeft->getFilename() < invitemRight->getFilename();
}
- if (itemLeft->isDirectory() && !itemRight->isDirectory())
+ if (invitemLeft->isDirectory() && !invitemRight->isDirectory())
{
return true;
}
- // last case: !itemLeft->isDirectory() && itemRight->isDirectory()
+ // last case: !invitemLeft->isDirectory() && invitemRight->isDirectory()
return false;
}
// we shall sort only by status
else if (sortColumn == 1)
{
- return itemLeft->getStatus() < itemRight->getStatus();
+ return invitemLeft->getStatusString() < invitemRight->getStatusString();
}
// anything else
else
============================================================
--- src/model/InventoryProxyModel.h 61eb7da315ee67909835aeacd223141f8fc40fdd
+++ src/model/InventoryProxyModel.h a7239616d0752740a3dfc9bd65d6d31ad2fe1973
@@ -27,8 +27,9 @@ public:
{
Q_OBJECT
public:
- enum ViewOption { All = 0, Changed, Patched, Added, Dropped,
- Renamed, Missing, Unknown, Ignored };
+ enum ViewOption { All = 0, Changed, ContentsChanged, AttributesChanged,
+ Added, Dropped, Renamed, Missing, Unknown, Ignored,
+ Invalid };
InventoryProxyModel(QObject *, bool);
~InventoryProxyModel();
============================================================
--- src/util/IconProvider.cpp eade6accc5f04c14c3f153b036d08e08e2c81499
+++ src/util/IconProvider.cpp 50010e2667d22c4df62b561115be814e694d6a27
@@ -25,7 +25,6 @@
#include
#include
-const int IconProvider::CdUp = -1;
IconProvider * IconProvider::instance = 0;
IconProvider * IconProvider::singleton()
@@ -37,125 +36,37 @@ IconProvider * IconProvider::singleton()
return instance;
}
-/**
- * There are 45 possible status combinations, of which 19 are invalid.
- * We only provide for the 26 valid ones own icons
- * (more info: http://venge.net/monotone/docs/Automation.html#Automation)
- *
- * Basic codes
- * -----------
- *
- * M 0 0 missing
- * AP 0 0 added
- * D 0 0 dropped
- * R 1 0 renamed-from-this
- * R 0 1 renamed-to-this
- * P 0 0 patched
- * 0 0 unchanged
- * U 0 0 unknown
- * I 0 0 ignored
- *
- * Combinations and used icons
- * ---------------------------
- *
- * In general, we don't show the "patched" state if there is another
- * state up to the item (added, renamed, etc.)
- *
- * ' ': unchanged.png
- * ' P': patched.png
- * ' U': unknown.png
- * ' I': ignored.png
- * ' M': missing.png
- *
- * ' AP': added.png
- * ' AM': added_missing.png
- *
- * ' R ': rename_target.png
- * ' RP': rename_target.png
- * ' RM': rename_target_missing.png
- *
- * 'D ': dropped.png
- * 'D U': dropped_unknown_ignored.png
- * 'D I': dropped_unknown_ignored.png
- *
- * 'DAP': dropped_added.png
- * 'DAM': dropped_added_missing.png
- *
- * 'DR ': dropped_rename_target.png
- * 'DRP': dropped_rename_target.png
- * 'DRM': dropped_rename_target_missing.png
- *
- * 'R ': rename_source.png
- * 'R U': rename_source_unknown_ignored.png
- * 'R I': rename_source_unknown_ignored.png
- *
- * 'RAP': rename_source_added.png
- * 'RAM': rename_source_added_missing.png
- *
- * 'RR ': rename_source_target.png
- * 'RRP': rename_source_target.png
- * 'RRM': rename_source_target_missing.png
- */
-
IconProvider::IconProvider()
{
QStyle *style = QApplication::style();
- //
// default icons if no state matches
- //
- fileIcons[0] = QIcon(style->standardPixmap(QStyle::SP_FileIcon));
- folderIcons[0] = QIcon(style->standardPixmap(QStyle::SP_DirClosedIcon));
- folderIcons[0].addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon), QIcon::Active, QIcon::On);
-
- //
- // assign possible item states to the appropriate overlay
- //
- QMap states;
- states[InventoryItem::Unchanged] = QString(":/overlays/unchanged.png");
- states[InventoryItem::Patched] = QString(":/overlays/patched.png");
- states[InventoryItem::Unknown] = QString(":/overlays/unknown.png");
- states[InventoryItem::Ignored] = QString(":/overlays/ignored.png");
- states[InventoryItem::Missing] = QString(":/overlays/missing.png");
-
- states[InventoryItem::Added|InventoryItem::Patched] = QString(":/overlays/added.png");
- states[InventoryItem::Added|InventoryItem::Missing] = QString(":/overlays/added_missing.png");
-
- states[InventoryItem::RenamedTo|InventoryItem::Unchanged] = QString(":/overlays/rename_target.png");
- states[InventoryItem::RenamedTo|InventoryItem::Patched] = QString(":/overlays/rename_target.png");
- states[InventoryItem::RenamedTo|InventoryItem::Missing] = QString(":/overlays/rename_target_missing.png");
-
- states[InventoryItem::Dropped|InventoryItem::Unchanged] = QString(":/overlays/dropped.png");
- states[InventoryItem::Dropped|InventoryItem::Unknown] = QString(":/overlays/dropped_unknown_ignored.png");
- states[InventoryItem::Dropped|InventoryItem::Ignored] = QString(":/overlays/dropped_unknown_ignored.png");
-
- states[InventoryItem::Dropped|InventoryItem::Added|InventoryItem::Patched] = QString(":/overlays/dropped_added.png");
- states[InventoryItem::Dropped|InventoryItem::Added|InventoryItem::Missing] = QString(":/overlays/dropped_added_missing.png");
+ fileIcons["default"] = QIcon(style->standardPixmap(QStyle::SP_FileIcon));
+ folderIcons["default"] = QIcon(style->standardPixmap(QStyle::SP_DirClosedIcon));
+ folderIcons["default"].addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon),
+ QIcon::Active, QIcon::On);
- states[InventoryItem::Dropped|InventoryItem::RenamedTo|InventoryItem::Unchanged] = QString(":/overlays/dropped_rename_target.png");
- states[InventoryItem::Dropped|InventoryItem::RenamedTo|InventoryItem::Patched] = QString(":/overlays/dropped_rename_target.png");
- states[InventoryItem::Dropped|InventoryItem::RenamedTo|InventoryItem::Missing] = QString(":/overlays/dropped_rename_target_missing.png");
+ // node overlay states
+ QMap states;
+ states["added"] = QString(":/overlays/added.png");
+ states["attr_changed"] = QString(":/overlays/attributes_changed.png");
+ states["cont_attr_changed"] = QString(":/overlays/content_attributes_changed.png");
+ states["cont_changed"] = QString(":/overlays/content_changed.png");
+ states["dropped"] = QString(":/overlays/dropped.png");
+ states["ignored"] = QString(":/overlays/ignored.png");
+ states["invalid"] = QString(":/overlays/invalid.png");
+ states["missing"] = QString(":/overlays/missing.png");
+ states["renamed"] = QString(":/overlays/renamed.png");
+ states["unknown"] = QString(":/overlays/unknown.png");
- states[InventoryItem::RenamedFrom|InventoryItem::Unchanged] = QString(":/overlays/rename_source.png");
- states[InventoryItem::RenamedFrom|InventoryItem::Unknown] = QString(":/overlays/rename_source_unknown_ignored.png");
- states[InventoryItem::RenamedFrom|InventoryItem::Ignored] = QString(":/overlays/rename_source_unknown_ignored.png");
+ // special overlay states
+ states["cdup"] = QString(":/overlays/cdup.png");
- states[InventoryItem::RenamedFrom|InventoryItem::Added|InventoryItem::Patched] = QString(":/overlays/rename_source_added.png");
- states[InventoryItem::RenamedFrom|InventoryItem::Added|InventoryItem::Missing] = QString(":/overlays/rename_source_added_missing.png");
-
- states[InventoryItem::RenamedFrom|InventoryItem::RenamedTo|InventoryItem::Unchanged] = QString(":/overlays/rename_source_target.png");
- states[InventoryItem::RenamedFrom|InventoryItem::RenamedTo|InventoryItem::Patched] = QString(":/overlays/rename_source_target.png");
- states[InventoryItem::RenamedFrom|InventoryItem::RenamedTo|InventoryItem::Missing] = QString(":/overlays/rename_source_target_missing.png");
-
- // some special icon overlays
- states[IconProvider::CdUp] = QString(":/overlays/cdup.png");
-
- QMapIterator i(states);
-
+ QMapIterator i(states);
+
while (i.hasNext())
{
i.next();
- int state = i.key();
QImage overlay(i.value());
overlay.createAlphaMask();
@@ -164,20 +75,20 @@ IconProvider::IconProvider()
QImage fileImage(style->standardPixmap(QStyle::SP_FileIcon).toImage());
QImage folderImageClosed(style->standardPixmap(QStyle::SP_DirClosedIcon).toImage());
QImage folderImageOpened(style->standardPixmap(QStyle::SP_DirOpenIcon).toImage());
-
- // note: the overlays are scaled to fit the different icon sizes
+
+ // note: the overlays are scaled to fit the different icon sizes
// on different platforms / with different stylings, so the overlay
// always perfectly fits the actual image
-
+
// file icon
QPainter filePainter(&fileImage);
filePainter.drawImage(
- 0, 0,
+ 0, 0,
overlay.scaled(fileImage.width(), fileImage.height())
);
filePainter.end();
- fileIcons[state] = QIcon(QPixmap::fromImage(fileImage));
-
+ fileIcons[i.key()] = QIcon(QPixmap::fromImage(fileImage));
+
// folder icons
QPainter folderPainter1(&folderImageClosed);
folderPainter1.drawImage(
@@ -191,49 +102,120 @@ IconProvider::IconProvider()
overlay.scaled(folderImageOpened.width(), folderImageOpened.height())
);
folderPainter2.end();
-
- folderIcons[state] = QIcon(QPixmap::fromImage(folderImageClosed));
- folderIcons[state].addPixmap(QPixmap::fromImage(folderImageOpened), QIcon::Active, QIcon::On);
+
+ folderIcons[i.key()] = QIcon(QPixmap::fromImage(folderImageClosed));
+ folderIcons[i.key()].addPixmap(QPixmap::fromImage(folderImageOpened),
+ QIcon::Active, QIcon::On);
}
}
IconProvider::~IconProvider() {}
-QIcon IconProvider::getIcon(InventoryItem * item) const
+QIcon IconProvider::getIcon(const ModelItem * item) const
{
- if (item->isCdUp())
+ const PseudoItem * psitem = qobject_cast(item);
+ if (psitem)
{
- return folderIcons.value(IconProvider::CdUp);
+ if (psitem->isCdUp())
+ {
+ return folderIcons.value("cdup");
+ }
+ // FIXME: do we want to create a special node item?
+ return folderIcons.value("default");
}
-
- int status = item->getStatus();
- if (item->isDirectory())
- {
- if (folderIcons.contains(status))
+ const InventoryItem * invitem = qobject_cast(item);
+ if (invitem)
+ {
+ // we do not display all possible item state combinations, but
+ // give certain ones a precedence over others:
+ //
+ // 1) invalid state
+ // 2) missing state
+ // 3) content/attribute changes
+ // 4) content changes
+ // 5) attribute changes
+ // 6) tree changes (adds, drops, renames, new-state preferred!)
+ // 7) unknown node
+ // 8) ignored node
+
+ QString state = "default";
+
+ if (invitem->hasStatus(InventoryItem::Invalid))
{
- return folderIcons.value(status);
+ state = "invalid";
}
- // default icon
- return folderIcons.value(0);
+ else
+ if (invitem->hasStatus(InventoryItem::Missing))
+ {
+ state = "missing";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::AttributesChanged |
+ InventoryItem::ContentsChanged))
+ {
+ state = "cont_attr_changed";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::ContentsChanged))
+ {
+ state = "cont_changed";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::AttributesChanged))
+ {
+ state = "attr_changed";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::RenameTarget))
+ {
+ state = "renamed";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::Added))
+ {
+ state = "added";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::RenameSource))
+ {
+ state = "renamed";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::Dropped))
+ {
+ state = "dropped";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::Unknown))
+ {
+ state = "unknown";
+ }
+ else
+ if (invitem->hasStatus(InventoryItem::Ignored))
+ {
+ state = "ignored";
+ }
+
+ if (invitem->isDirectory())
+ {
+ return folderIcons.value(state);
+ }
+
+ return fileIcons.value(state);
}
-
- if (fileIcons.contains(status))
- {
- return fileIcons.value(status);
- }
- // default icon
- return fileIcons.value(0);
+
+ // default file icon for any other ModelItem
+ return fileIcons.value("default");
}
-
QIcon IconProvider::getPlainFileIcon() const
{
- return fileIcons.value(0);
+ return fileIcons.value("default");
}
QIcon IconProvider::getPlainFolderIcon() const
{
- return folderIcons.value(0);
+ return folderIcons.value("default");
}
============================================================
--- src/util/IconProvider.h 0331678a530715a50344d5fb07943f02ad24bccf
+++ src/util/IconProvider.h 2b2f908c2f64b59def8971d445238252fde01e66
@@ -24,27 +24,27 @@
#include
#include
-class InventoryItem;
+class ModelItem;
class IconProvider
{
public:
static IconProvider * singleton();
-
- ~IconProvider();
-
- QIcon getIcon(InventoryItem* item) const;
+
+ ~IconProvider();
+
+ QIcon getIcon(const ModelItem * item) const;
QIcon getPlainFileIcon() const;
QIcon getPlainFolderIcon() const;
-
+
static const int CdUp;
private:
IconProvider();
static IconProvider * instance;
-
- QMap fileIcons;
- QMap folderIcons;
+
+ QMap fileIcons;
+ QMap folderIcons;
};
#endif
============================================================
--- src/view/InventoryView.cpp 0207a6e08fed77d118b60410c1e432ee5ba458ad
+++ src/view/InventoryView.cpp 50873ebddf25b10ff14a51696a346c1c2e858170
@@ -241,55 +241,72 @@ void InventoryView::slotContextMenuReque
if (indexList.size() == 1)
{
- QModelIndex sourceIndex = static_cast(indexList[0].model())->mapToSource(indexList[0]);
+ QModelIndex sourceIndex = static_cast
+ (indexList[0].model())->mapToSource(indexList[0]);
+ ModelItem * item = static_cast
+ (sourceIndex.internalPointer());
+ InventoryItem * invitem = dynamic_cast
+ (item);
- InventoryItem* item = static_cast(sourceIndex.internalPointer());
+ // only display the popup for real workspace items
+ if (!invitem)
+ return;
- if (item->isDirectory())
+ if (invitem->isDirectory())
{
menu.addAction(actChdir);
}
- menu.addAction(actOpen);
+ if (invitem->isNewNode() &&
+ invitem->hasNotStatus(InventoryItem::Missing) &&
+ invitem->hasNotStatus(InventoryItem::Invalid))
+ {
+ menu.addAction(actOpen);
+ }
- if (item->hasStatus(InventoryItem::Unknown))
+ if (invitem->hasStatus(InventoryItem::Unknown))
{
menu.addAction(actAdd);
menu.addAction(actIgnore);
}
- if (item->hasStatus(InventoryItem::Ignored))
+ if (invitem->hasStatus(InventoryItem::Ignored))
{
menu.addAction(actUnignore);
}
- if (item->hasChangedRecursive())
+ if (invitem->hasChangedRecursive())
{
menu.addAction(actCommit);
menu.addAction(actRevisionDiff);
}
- if (item->hasNotStatus(InventoryItem::Ignored) &&
- item->hasNotStatus(InventoryItem::Unknown) &&
- !item->isRootDirectory() && !item->isCdUp())
+ // FIXME: we currently exclude the workspace root for this.
+ // While its reasonable for the remove action, the root could
+ // actually be renamed by pivot_root - decide whether we want
+ // to implement that here or offer a workspace menu and dialog
+ // for this rather rare use case
+ if (invitem->hasNotStatus(InventoryItem::Ignored) &&
+ invitem->hasNotStatus(InventoryItem::Unknown) &&
+ !invitem->getPath().isEmpty())
{
menu.addAction(actRemove);
menu.addAction(actRename);
// as long as it is not unchanged, it can be converted
- if (item->hasNotStatus(InventoryItem::Unchanged))
+ if (invitem->hasChanged())
{
menu.addAction(actRevert);
- if (item->hasNotStatus(InventoryItem::Added) &&
- !item->isDirectory())
+ if (invitem->hasStatus(InventoryItem::ContentsChanged) &&
+ invitem->hasNotStatus(InventoryItem::Added))
{
menu.addAction(actFileDiff);
}
}
- if (item->hasNotStatus(InventoryItem::Added) &&
- !item->isDirectory())
+ if (invitem->hasNotStatus(InventoryItem::Added) &&
+ !invitem->isDirectory())
{
menu.addAction(actFileHistory);
}
@@ -300,34 +317,38 @@ void InventoryView::slotContextMenuReque
//
QFont activeFont;
activeFont.setBold(true);
- QFont normalFont;
- normalFont.setBold(false);
- if (item->isDirectory())
+ if (invitem->isDirectory())
{
- actOpen->setFont(normalFont);
actChdir->setFont(activeFont);
}
else
{
- if (item->hasStatus(InventoryItem::Patched) &&
- item->hasNotStatus(InventoryItem::Added))
+ if (invitem->hasStatus(InventoryItem::ContentsChanged) &&
+ invitem->hasNotStatus(InventoryItem::Added))
{
actFileDiff->setFont(activeFont);
- actOpen->setFont(normalFont);
}
else
+ if (invitem->isNewNode() &&
+ invitem->hasNotStatus(InventoryItem::Missing) &&
+ invitem->hasNotStatus(InventoryItem::Invalid))
{
- actFileDiff->setFont(normalFont);
actOpen->setFont(activeFont);
}
+ else
+ if (invitem->hasChanged())
+ {
+ actRevert->setFont(activeFont);
+ }
}
menu.exec(pos);
}
else
{
- InventoryItem * item;
+ ModelItem * item;
+ InventoryItem * invitem;
QModelIndex sourceIndex;
QStringList actions;
@@ -344,24 +365,29 @@ void InventoryView::slotContextMenuReque
QMap actionCounter;
- foreach(QString action, actions)
+ foreach (QString action, actions)
{
actionCounter.insert(action, 0);
}
- foreach(QModelIndex index, indexList)
+ foreach (QModelIndex index, indexList)
{
sourceIndex =
static_cast(index.model())
->mapToSource(index);
- item = static_cast(sourceIndex.internalPointer());
+ item = static_cast(sourceIndex.internalPointer());
+ invitem = dynamic_cast(item);
- if (!item->isTracked())
+ // skip actions on anything other than InventoryItems
+ if (!invitem)
+ continue;
+
+ if (!invitem->isTracked())
{
actionCounter["add"]++;
- if (item->hasStatus(InventoryItem::Unknown))
+ if (invitem->hasStatus(InventoryItem::Unknown))
{
actionCounter["ignore"]++;
}
@@ -372,7 +398,7 @@ void InventoryView::slotContextMenuReque
continue;
}
- if (item->hasChangedRecursive())
+ if (invitem->hasChangedRecursive())
{
actionCounter["commit"]++;
actionCounter["revert"]++;
@@ -420,16 +446,20 @@ void InventoryView::changeDirectory(cons
void InventoryView::changeDirectory(const QModelIndex & proxyIndex)
{
- QModelIndex source = static_cast(model())->mapToSource(proxyIndex);
- InventoryItem * item = static_cast(source.internalPointer());
+ QModelIndex source = dynamic_cast
+ (model())->mapToSource(proxyIndex);
if (type == FileList)
{
// retranslate the proxy index to an index of the current model
QModelIndex proxyFileIndex =
- static_cast(model())->mapFromSource(source);
+ dynamic_cast(model())->mapFromSource(source);
- if (item->isCdUp())
+ ModelItem * item = static_cast
+ (source.internalPointer());
+
+ PseudoItem * psitem = dynamic_cast(item);
+ if (psitem && psitem->isCdUp())
{
// list the contents of the parent of the parent directory
setRootIndex(proxyFileIndex.parent().parent());
@@ -458,9 +488,13 @@ void InventoryView::slotOpen()
QModelIndex index(getSingleSelection());
if (!index.isValid()) return;
- InventoryItem * item = static_cast(index.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
+ InventoryItem * invitem = dynamic_cast(item);
- emit openFile(item->getPath());
+ if (!invitem)
+ return;
+
+ emit openFile(invitem->getPath());
}
void InventoryView::slotAdd()
@@ -509,15 +543,19 @@ void InventoryView::slotFileDiff()
QModelIndex index(getSingleSelection());
if (!index.isValid()) return;
- InventoryItem * item = static_cast(index.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
+ InventoryItem * invitem = dynamic_cast(item);
- if (item->isDirectory() || !item->hasStatus(InventoryItem::Patched))
+ if (!invitem)
+ return;
+
+ if (!invitem->hasStatus(InventoryItem::ContentsChanged))
{
- D("File is a directory or not patched/unknown.");
+ D("File has no content changes");
return;
}
- emit diffFile(item->getPath());
+ emit diffFile(invitem->getPath());
}
void InventoryView::slotFileHistory()
@@ -525,22 +563,22 @@ void InventoryView::slotFileHistory()
QModelIndex index(getSingleSelection());
if (!index.isValid()) return;
- InventoryItem * item = static_cast(index.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
+ InventoryItem * invitem = dynamic_cast(item);
- QString path = item->getPath();
+ if (!invitem)
+ return;
+ QString path = invitem->getPath();
+
// determine the original path, if needed
- if (item->hasStatus(InventoryItem::RenamedFrom))
+ if (invitem->hasStatus(InventoryItem::RenameSource))
{
- InventoryItem * newItem = item->getRenamedTo();
- I(newItem != 0);
- path = newItem->getPath();
+ path = invitem->getRenameTarget();
}
- if (item->hasStatus(InventoryItem::RenamedTo))
+ if (invitem->hasStatus(InventoryItem::RenameTarget))
{
- InventoryItem * oldItem = item->getRenamedFrom();
- I(oldItem != 0);
- path = oldItem->getPath();
+ path = invitem->getRenameSource();
}
emit fileHistory(path);
@@ -551,9 +589,13 @@ void InventoryView::slotRevisionDiff()
QModelIndex index(getSingleSelection());
if (!index.isValid()) return;
- InventoryItem * item = static_cast(index.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
+ InventoryItem * invitem = dynamic_cast(item);
- emit diffRevision(item->getPath(), QString(), QString());
+ if (!invitem)
+ return;
+
+ emit diffRevision(invitem->getPath(), QString(), QString());
}
QModelIndex InventoryView::getSingleSelection(bool mapToSource /* = true */)
@@ -583,17 +625,23 @@ void InventoryView::itemClicked(const QM
QModelIndex sourceIndex =
static_cast(index.model())->mapToSource(index);
- InventoryItem * item = static_cast(sourceIndex.internalPointer());
+ ModelItem * item = static_cast(index.internalPointer());
+ InventoryItem * invitem = dynamic_cast(item);
+ PseudoItem * psitem = dynamic_cast(item);
- if (item->isDirectory())
+ if ((invitem && invitem->isDirectory()) ||
+ (psitem && psitem->isCdUp()))
{
emit directoryChanged(index);
changeDirectory(index);
return;
}
- if (item->hasStatus(InventoryItem::Patched) &&
- item->hasNotStatus(InventoryItem::Added))
+ if (!invitem)
+ return;
+
+ if (invitem->hasStatus(InventoryItem::ContentsChanged) &&
+ invitem->hasNotStatus(InventoryItem::Added))
{
slotFileDiff();
return;
============================================================
--- src/view/Splitter.cpp 4ef814b5b7fcb03120f6f889aa279fdd0518df5f
+++ src/view/Splitter.cpp 52ebbc624ae37b76a88cdb95b1e3f574a86e5b79
@@ -20,6 +20,7 @@
#include "Splitter.h"
#include "Settings.h"
+#include "vocab.h"
#include
@@ -32,6 +33,7 @@ Splitter::~Splitter()
Splitter::~Splitter()
{
+ L(QString("saving state of splitter %1").arg(objectName()));
saveState();
}
============================================================
--- src/view/WorkspaceMenuBar.cpp 79395e00c0a347b59a71f00738882d0e58d69fce
+++ src/view/WorkspaceMenuBar.cpp 7f8026a44fa642d0bc6ef70be9694c4074e445f2
@@ -33,9 +33,12 @@ WorkspaceMenuBar::WorkspaceMenuBar(QWidg
actionAll_changed_files = new QAction(tr("All changed files"), this);
actionAll_changed_files->setCheckable(true);
actionAll_changed_files->setShortcut(tr("Alt+C"));
- actionPatched_files = new QAction(tr("Patched files"), this);
- actionPatched_files->setCheckable(true);
- actionPatched_files->setShortcut(tr("Alt+P"));
+ actionChangedContent_files = new QAction(tr("Files with changed contents"), this);
+ actionChangedContent_files->setCheckable(true);
+ actionChangedContent_files->setShortcut(tr("Alt+P"));
+ actionChangedAttributes_files = new QAction(tr("Files with changed attributes"), this);
+ actionChangedAttributes_files->setCheckable(true);
+ actionChangedAttributes_files->setShortcut(tr("Alt+T"));
actionAdded_files = new QAction(tr("Added files"), this);
actionAdded_files->setCheckable(true);
actionAdded_files->setShortcut(tr("Alt+N"));
@@ -54,18 +57,23 @@ WorkspaceMenuBar::WorkspaceMenuBar(QWidg
actionIgnored_files = new QAction(tr("Ignored files"), this);
actionIgnored_files->setCheckable(true);
actionIgnored_files->setShortcut(tr("Alt+I"));
+ actionInvalid_files = new QAction(tr("Invalid files"), this);
+ actionInvalid_files->setCheckable(true);
+ actionInvalid_files->setShortcut(tr("Alt+V"));
// FIXME: yeah, I know, magic values suck, but registering enums
// to be usable in Qt's signal/slot system sucks for the moment, too
actionAll_files->setData(QVariant(0));
actionAll_changed_files->setData(QVariant(1));
- actionPatched_files->setData(QVariant(2));
- actionAdded_files->setData(QVariant(3));
- actionRemoved_files->setData(QVariant(4));
- actionRenamed_files->setData(QVariant(5));
- actionMissing_files->setData(QVariant(6));
- actionUnknown_files->setData(QVariant(7));
- actionIgnored_files->setData(QVariant(8));
+ actionChangedContent_files->setData(QVariant(2));
+ actionChangedAttributes_files->setData(QVariant(3));
+ actionAdded_files->setData(QVariant(4));
+ actionRemoved_files->setData(QVariant(5));
+ actionRenamed_files->setData(QVariant(6));
+ actionMissing_files->setData(QVariant(7));
+ actionUnknown_files->setData(QVariant(8));
+ actionIgnored_files->setData(QVariant(9));
+ actionInvalid_files->setData(QVariant(10));
menuShow = new QMenu(tr("Show"), this);
@@ -73,12 +81,15 @@ WorkspaceMenuBar::WorkspaceMenuBar(QWidg
menuShow->addSeparator();
menuShow->addAction(actionAll_changed_files);
menuShow->addAction(actionAdded_files);
- menuShow->addAction(actionPatched_files);
+ menuShow->addAction(actionChangedContent_files);
+ menuShow->addAction(actionChangedAttributes_files);
menuShow->addAction(actionRemoved_files);
menuShow->addAction(actionRenamed_files);
menuShow->addAction(actionMissing_files);
menuShow->addAction(actionUnknown_files);
menuShow->addAction(actionIgnored_files);
+ menuShow->addSeparator();
+ menuShow->addAction(actionInvalid_files);
actionHide_ignored_files = new QAction(tr("Hide ignored files"), this);
actionHide_ignored_files->setShortcut(tr("Ctrl+H"));
============================================================
--- src/view/WorkspaceMenuBar.h 00dd3c433ab74935e3b0b8c4227a651f367724ae
+++ src/view/WorkspaceMenuBar.h 37f078fffd28f79bcdf6960b71884577cebea6f3
@@ -45,13 +45,15 @@ protected:
QAction * actionExpand_tree;
QAction * actionAll_files;
QAction * actionAll_changed_files;
- QAction * actionPatched_files;
+ QAction * actionChangedContent_files;
+ QAction * actionChangedAttributes_files;
QAction * actionAdded_files;
QAction * actionRemoved_files;
QAction * actionRenamed_files;
QAction * actionMissing_files;
QAction * actionUnknown_files;
QAction * actionIgnored_files;
+ QAction * actionInvalid_files;
QAction * actionUpdate_workspace;
QAction * actionCommit_revision;
============================================================
--- src/view/WorkspaceWindow.cpp c0edca2787683a449e4f3a1a540cbeb2a122fe83
+++ src/view/WorkspaceWindow.cpp da5b5622acc662e7f09e64ede5852682ca0d452f
@@ -301,24 +301,28 @@ void WorkspaceWindow::readAttributes(con
void WorkspaceWindow::readAttributes(const QModelIndex & index)
{
- QModelIndex sourceIndex = static_cast(index.model())->mapToSource(index);
- InventoryItem * item = static_cast(sourceIndex.internalPointer());
+ QModelIndex sourceIndex = static_cast
+ (index.model())->mapToSource(index);
+ ModelItem * item = static_cast
+ (sourceIndex.internalPointer());
+ InventoryItem * invitem = dynamic_cast
+ (item);
- if (item->isRootDirectory() || item->isCdUp())
+ if (!invitem)
{
- D("item is pseudo item (root or cdup)");
+ D("item is not inventory item");
attrModel->revert();
return;
}
- if (item->hasStatus(InventoryItem::Dropped) || !item->isTracked())
+ if (invitem->isOldNode() || !invitem->isTracked())
{
- D("item is not tracked or dropped");
+ D("item is old node or not tracked");
attrModel->revert();
return;
}
- attrModel->readAttributes(item->getPath());
+ attrModel->readAttributes(invitem->getPath());
}
void WorkspaceWindow::invalidWorkspaceFormat(const QString & error)