# # # patch "src/model/Inventory.cpp" # from [38d53b03b3303315ba61b72f5241ffa81e24f8f3] # to [9f7bc8a94c7149580c0c3cd900e8b5a6e31186c7] # # patch "src/model/Inventory.h" # from [c9834d77c69b3b9d7c6dc35a5a8bc6118a5b01ec] # to [61bd1cbd1c9cb2c142f95205f66df308dcc836c8] # ============================================================ --- src/model/Inventory.cpp 38d53b03b3303315ba61b72f5241ffa81e24f8f3 +++ src/model/Inventory.cpp 9f7bc8a94c7149580c0c3cd900e8b5a6e31186c7 @@ -21,20 +21,20 @@ #include "Inventory.h" #include "InventoryItem.h" #include "Guitone.h" +#include "MonotoneUtil.h" #include "IconProvider.h" #include -Inventory::Inventory(QObject *parent) : QAbstractItemModel(parent) +Inventory::Inventory(QObject * parent, const QString & db) + : QAbstractItemModel(parent), AutomateCommand(db) { // 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); - - mtnDelegate = new MonotoneDelegate(this); - + connect( this, SIGNAL(modelCreated()), this, SLOT(loadBranchName()) @@ -45,26 +45,38 @@ Inventory::~Inventory() { delete rootItem; delete regex; - delete mtnDelegate; } -bool Inventory::readInventory() +void Inventory::readInventory() { - QStringList cmd; - cmd << "inventory"; - - return mtnDelegate->triggerCommand(cmd); + MonotoneTask task(QStringList() << "inventory"); + AutomateCommand::enqueueTask(task); } -void Inventory::parseOutput() +void Inventory::processTaskResult(const MonotoneTask & task) { - QStringList lines = AutomateCommand::data.split("\n", QString::SkipEmptyParts); - QMap renameMap; - QMap::iterator renameIter; + if (task.getReturnCode() != 0) + { + if (task.getReturnCode() == 2) + { + emit invalidWorkspaceFormat( + MonotoneUtil::stripMtnPrefix(task.getOutputUtf8()) + ); + return; + } + C(QString("Command returned with a non-zero return code (%1)") + .arg(task.getOutputUtf8())); + return; + } + + QStringList lines = task.getOutputUtf8().split("\n", QString::SkipEmptyParts); + QMap renameMap; + QMap::iterator renameIter; + QList items; InventoryItem * item; - + int status(0); int from_id(0); int to_id(0); @@ -77,12 +89,12 @@ void Inventory::parseOutput() { 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; @@ -108,19 +120,19 @@ void Inventory::parseOutput() 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->setStatus(0); branch->setChildren(buildTreeRecursive(items, NULL)); - + // remove any older item rootItem->deleteAllChildren(); rootItem->appendChild(branch); - + // reset the model to repaint the view completly // (all QModelIndexes are discarded through that, e.g. selections!) reset(); @@ -136,24 +148,24 @@ void Inventory::loadBranchName() #ifdef Q_WS_WIN32 W("Querying branch name disabled, will lead to program halt."); #else - QList children = rootItem->getChildren(); + QList children = rootItem->getChildren(); I(children.size() > 0); - children[0]->setLabel(MonotoneDelegate::getBranchName(this)); + children[0]->setLabel(MonotoneUtil::getBranchName(getDbPath())); emit layoutChanged(); #endif } -QList Inventory::buildTreeRecursive(QList & items, InventoryItem * parentItem) +QList Inventory::buildTreeRecursive(QList & items, InventoryItem * parentItem) { QList finalItems; QString parentPath = ""; - + if (parentItem != NULL) { parentPath = parentItem->getPath(); } - + // add pseudo item "cd up" for each directory level InventoryItem * cdUp = new InventoryItem(true); cdUp->setParent(parentItem); @@ -161,7 +173,7 @@ QList Inventory::buildTr finalItems.append(cdUp); InventoryItem * currentItem; - + while (items.size() > 0) { currentItem = items.front(); @@ -196,12 +208,11 @@ QList Inventory::buildTr finalItems.push_back(currentItem); } - + return finalItems; } -QModelIndex Inventory::index(int row, int column, const QModelIndex &parent) -const +QModelIndex Inventory::index(int row, int column, const QModelIndex & parent) const { InventoryItem * parentItem; @@ -241,7 +252,7 @@ QVariant Inventory::data(const QModelInd return QVariant(); } - InventoryItem * item = static_cast(index.internalPointer()); + InventoryItem * item = static_cast(index.internalPointer()); if ((role == Qt::DecorationRole) && (index.column() == 0)) { @@ -256,34 +267,39 @@ bool Inventory::setData(const QModelInde bool Inventory::setData(const QModelIndex & idx, const QVariant & value, int role) { + 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()); - + if (item->isCdUp() || item->isRootDirectory()) return flags; - + /* // Disabled until we have figured out how to implement renaming properly flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled; - + if (item->isDirectory()) { flags |= Qt::ItemIsDropEnabled; } */ - + return flags; } @@ -298,14 +314,14 @@ QVariant Inventory::headerData(int secti return QVariant(); } -QModelIndex Inventory::parent(const QModelIndex& index) const +QModelIndex Inventory::parent(const QModelIndex & index) const { if (!index.isValid()) { return QModelIndex(); } - InventoryItem * childItem = static_cast(index.internalPointer()); + InventoryItem * childItem = static_cast(index.internalPointer()); InventoryItem * parentItem = childItem->parent(); if (parentItem == rootItem) @@ -329,113 +345,94 @@ bool Inventory::parseInventoryLine( } bool Inventory::parseInventoryLine( - const QString &inputString, - int &status, - int &from_id, - int &to_id, - QString &path, - bool &isDirectory) + 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; - } + if (regex->indexIn(inputString) == -1) + { + W(QString("Couldn't parse inventory line %1").arg(inputString)); + return false; + } - QStringList list = regex->capturedTexts(); - status = 0; + 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 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 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; - } + // 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; - } + 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(); + + // 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; -} -bool Inventory::handleError(int errCode) -{ - if (errCode != 2) return false; - - // FIXME: normally there should only be an error if the workspace format - // itself is not readable (i.e. wrong monotone version for the given - // workspace version), but who knows what could bomb out here as well. in the - // meantime we ensure the user gets a proper error message. in the - // future we could do the task of upgrading a workspace / database - // format right here in guitone - // Starting with mtn 0.33 invalid databases are catched as early as - // automate stdio is run, only for 0.32 and below the database is checked - // on the very first command. - - emit invalidWorkspaceFormat(Monotone::stripMtnPrefix(AutomateCommand::data)); + // parsing was successful return true; } @@ -443,34 +440,34 @@ QMap Inventory { QList missingItems; QList unknownItems; - + foreach (InventoryItem * item, flatItemList) { if (item->hasStatus(InventoryItem::Missing)) { missingItems.append(item); } - + if (item->hasStatus(InventoryItem::Unknown)) { unknownItems.append(item); } } - + // TODO: progess bar here! - - QString parentRev = MonotoneDelegate::getBaseWorkspaceRevision(this); + + QString parentRev = MonotoneUtil::getBaseWorkspaceRevision(getDbPath()); FileEntryList parentList = - MonotoneDelegate::getRevisionManifest(this, parentRev); - + MonotoneUtil::getRevisionManifest(getDbPath(), parentRev); + QMap unaccountedRenames; QMap fileIds; - + foreach (InventoryItem * missingItem, missingItems) { FileEntryList candidates; FileEntry entry; - + // this is a new entry not recorded in the base roster if (missingItem->hasStatus(InventoryItem::Added) || missingItem->hasStatus(InventoryItem::RenamedTo)) @@ -491,21 +488,21 @@ QMap Inventory } I(found); } - + foreach (InventoryItem * unknownItem, unknownItems) { QString unknownPath = unknownItem->getPath(); - + // calculate the file id of the unknown file if (!unknownItem->isDirectory() && !fileIds.contains(unknownPath)) { - QString fileid = MonotoneDelegate::getFileId(this, unknownPath); + QString fileid = MonotoneUtil::getFileId(getDbPath(), unknownPath); // file was not readable, etc. if (fileid.isEmpty()) continue; fileIds.insert(unknownPath, fileid); } - + // at first do a simple file name check if ((missingItem->getFilename() == unknownItem->getFilename()) && (missingItem->isDirectory() == unknownItem->isDirectory())) @@ -514,24 +511,24 @@ QMap Inventory if (fileIds.contains(unknownPath)) { can.fileid = fileIds.value(unknownPath); - } + } candidates.append(can); continue; } - + // we can't do anything for directories from here on if (missingItem->isDirectory() || unknownItem->isDirectory()) continue; - + // we now rely on the fact that we have a fileid I(fileIds.contains(unknownPath)); - + if (fileIds.value(unknownPath) == entry.fileid) { candidates.append(FileEntry(unknownPath, false, entry.fileid)); } } - + // only add those missing items to the map which are having any // candidates, i.e. are likely to be renamed if (candidates.size() > 0) @@ -539,7 +536,7 @@ QMap Inventory unaccountedRenames.insert(entry, candidates); } } - + return unaccountedRenames; } ============================================================ --- src/model/Inventory.h c9834d77c69b3b9d7c6dc35a5a8bc6118a5b01ec +++ src/model/Inventory.h 61bd1cbd1c9cb2c142f95205f66df308dcc836c8 @@ -22,7 +22,6 @@ #define INVENTORY_H #include "AutomateCommand.h" -#include "MonotoneDelegate.h" #include #include @@ -32,42 +31,39 @@ class Inventory : public QAbstractItemMo class Inventory : public QAbstractItemModel, public AutomateCommand { Q_OBJECT +public: + Inventory(QObject *, const QString &); + ~Inventory(); + void readInventory(); + QMap findUnaccountedRenames(); - public: - Inventory(QObject *parent); - ~Inventory(); - bool readInventory(); - QMap findUnaccountedRenames(); - - // 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; - QModelIndex parent(const QModelIndex&) const; - int rowCount(const QModelIndex&) const; - int columnCount(const QModelIndex&) const; - - private: - void parseOutput(); - bool handleError(int); - bool parseInventoryLine(const QString &, int &, int &, int &, QString &, bool &); - QList buildTreeRecursive(QList &, InventoryItem*); - - InventoryItem * rootItem; - QRegExp * regex; - MonotoneDelegate * mtnDelegate; - QString branchName; - QList flatItemList; - - private slots: - void loadBranchName(); + // 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; + QModelIndex parent(const QModelIndex &) const; + int rowCount(const QModelIndex &) const; + int columnCount(const QModelIndex &) const; - signals: - void modelCreated(); - void invalidWorkspaceFormat(const QString &); +private: + void processTaskResult(const MonotoneTask &); + bool parseInventoryLine(const QString &, int &, int &, int &, QString &, bool &); + QList buildTreeRecursive(QList &, InventoryItem*); + + InventoryItem * rootItem; + QRegExp * regex; + QString branchName; + QList flatItemList; + +private slots: + void loadBranchName(); + +signals: + void modelCreated(); + void invalidWorkspaceFormat(const QString &); }; #endif