# # # patch "res/forms/dialogs/preferences.ui" # from [20aacc62fd1b9ea4c9c0afdf60f834531daafdf2] # to [d8f13336ba5bd1d55142b90bdad43f52cdb1c5b8] # # patch "src/model/Branches.cpp" # from [1cdf76f9fd36b1008012543750606d8d40d5574f] # to [68640cc21cb8741e349be14703f4b78b101db7d7] # # patch "src/model/Branches.h" # from [282a518befacd48337105670f1a00fa89bb759d3] # to [aac5902d3666e210b470e5e38b242ddb453450b5] # # patch "src/util/Settings.cpp" # from [6f7890495fbe7859d349114be2cea5536c6044ee] # to [66eea129ecb197d95578dc3abc07a9415922690a] # # patch "src/util/TreeBuilder.cpp" # from [0505566d5bd338cf0ff59cc25be61d861644ad7f] # to [2329dcc898832540de2c76b501da0026761390f9] # # patch "src/util/TreeBuilder.h" # from [de247f223522318c2a48426553bbd374aec491e4] # to [7ac6ccefb09e382e4ec50108631322156311402d] # # patch "src/view/dialogs/Preferences.cpp" # from [608c1282c24b69935efed352c24f8deb302ca8f4] # to [bbfd35ef1eb2cce93eace1e023f06296102fcd97] # ============================================================ --- res/forms/dialogs/preferences.ui 20aacc62fd1b9ea4c9c0afdf60f834531daafdf2 +++ res/forms/dialogs/preferences.ui d8f13336ba5bd1d55142b90bdad43f52cdb1c5b8 @@ -437,7 +437,7 @@ The highlight color determines the backg - Pick a color for merge revisions and revisions which are not on the same branch in the changeset browser. + Pick a color for suspended branches, merge revisions and revisions which are not on the same branch in the changeset browser. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop @@ -465,23 +465,8 @@ The highlight color determines the backg - - - - SizeableLabel { - qproperty-relativeSize: 0.85; -} - - - merge revisions - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - + 0 @@ -502,7 +487,7 @@ The highlight color determines the backg - + SizeableLabel { @@ -517,8 +502,30 @@ The highlight color determines the backg + + + + + 0 + 0 + + + + + 30 + 20 + + + + QFrame::Panel + + + QFrame::Sunken + + + - + 0 @@ -539,6 +546,36 @@ The highlight color determines the backg + + + + SizeableLabel { + qproperty-relativeSize: 0.85; +} + + + merge revisions + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + SizeableLabel { + qproperty-relativeSize: 0.85; +} + + + suspended branches + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + ============================================================ --- src/model/Branches.cpp 1cdf76f9fd36b1008012543750606d8d40d5574f +++ src/model/Branches.cpp 68640cc21cb8741e349be14703f4b78b101db7d7 @@ -17,13 +17,13 @@ ***************************************************************************/ #include "Branches.h" +#include "BasicIOParser.h" +#include "Settings.h" Branches::Branches(QObject * parent, const DatabaseFile & db, bool display_tree) - : QAbstractItemModel(parent), AutomateCommand(0), - tree(display_tree), databaseFile(db) -{ - builder = 0; -} + : QStandardItemModel(parent), AutomateCommand(0), + tree(display_tree), builder(0), databaseFile(db) +{} Branches::~Branches() { @@ -33,10 +33,19 @@ void Branches::readBranches() void Branches::readBranches() { - branches.clear(); + activeHeadsMap.clear(); + branchItemMap.clear(); + clear(); reset(); - MonotoneTaskPtr task(new MonotoneTask(QStringList() << "branches")); + suspendedBranchesBrush = QBrush(QColor( + Settings::getString("ChangesetBrowserSuspendedBranches") + )); + + MonotoneTaskPtr task(new MonotoneTask( + QStringList() << "branches", + QStringList() << "ignore-suspend-certs" << "" + )); AutomateCommand::enqueueDatabaseTask(databaseFile, task); } @@ -49,127 +58,100 @@ void Branches::processTaskResult(const M return; } - // - // The ToolTipRole is used in two regards here: - // - // a) if the branch model is displayed as tree of branches - // a user can hover over an individual branch part and see - // the complete branch name in the tooltip - // b) since we use a qstandarditemmodel internally to store the - // actual string data of each branch, we need to use some role - // anyways to store the full branch name internally to be able - // to use it for further processing, so we re-use the tooltip - // role there again to query these info - // - // Of course this will break badly as soon as we want to put more - // info into the tooltip than just the actual branch name... - // - branches.setHorizontalHeaderItem(0, new QStandardItem(tr("Branches"))); - if (tree) + QString cmd = task->getArguments().at(0); + if (cmd == "branches") { - builder = new TreeBuilder(branches.invisibleRootItem(), this); - builder->addList(task->getDecodedOutput()); - } - else - { QStringList branchList = task->getDecodedOutput() .split("\n", QString::SkipEmptyParts); + foreach (const QString & branch, branchList) { - QStandardItem * item = new QStandardItem(); - item->setData(branch, Qt::DisplayRole); - item->setData(branch, Qt::ToolTipRole); - branches.appendRow(item); + MonotoneTaskPtr task(new MonotoneTask( + QStringList() << "select" << "h:" + branch, + QStringList() << "ignore-suspend-certs" << "" + )); + AutomateCommand::enqueueDatabaseTask(databaseFile, task); } - } - reset(); - emit branchesRead(); -} -int Branches::columnCount(const QModelIndex & parent) const -{ - QStandardItem * item = branchFromIndex(parent); - if (item) - { - return item->columnCount(); - } - return branches.columnCount(); -} + setHorizontalHeaderItem(0, new QStandardItem(tr("Branches"))); + if (tree) + { + builder = new TreeBuilder(branchItemMap, invisibleRootItem(), this); + builder->addList(branchList); + } + else + { + foreach (const QString & branch, branchList) + { + QStandardItem * item = new QStandardItem(); + item->setData(branch, Qt::DisplayRole); + item->setData(branch, Qt::ToolTipRole); + appendRow(item); + branchItemMap.insert(branch, item); + } + } -Qt::ItemFlags Branches::flags(const QModelIndex & index) const -{ - if (!index.isValid()) - return 0; - - QFlags flags = Qt::ItemIsEnabled; - if (rowCount(index) == 0) + reset(); + emit branchesRead(); + } + else if (cmd == "select") { - flags |= Qt::ItemIsSelectable; - } + QString branch = task->getArguments().at(1).mid(2); + QStringList headList = task->getDecodedOutput() + .split("\n", QString::SkipEmptyParts); - return flags; -} + foreach (const QString & head, headList) + { + activeHeadsMap[branch].insert(head); -QVariant Branches::data(const QModelIndex & index, int role) const -{ - QStandardItem * item = branchFromIndex(index); - if (item) - { - return item->data(role); + MonotoneTaskPtr task(new MonotoneTask( + QStringList() << "certs" << head + )); + AutomateCommand::enqueueDatabaseTask(databaseFile, task); + } } - return QVariant(); -} - -QVariant Branches::headerData(int section, Qt::Orientation orientation, int role) const -{ - return branches.headerData(section, orientation, role); -} - -int Branches::rowCount(const QModelIndex & parent) const -{ - QStandardItem * item = branchFromIndex(parent); - if (item) + else if (cmd == "certs") { - return item->rowCount(); - } - return branches.rowCount(); -} + QString head = task->getArguments().at(1); + BasicIOParser parser(task->getDecodedOutput()); + I(parser.parse()); -QModelIndex Branches::index(int row, int column, const QModelIndex & parent) const -{ - return createIndex(row, column, getBranchItem(row, column, parent)); -} + CertList certList; + certList.revision = head; + certList.fill(parser.getStanzas()); -QModelIndex Branches::parent(const QModelIndex & index) const -{ - QStandardItem * item = branchFromIndex(index); - if (item) - { - QStandardItem * parent = item->parent(); - if (parent) + QStringList suspendedBranches = certList.findByNameValues("suspend"); + foreach (const QString & suspendedBranch, suspendedBranches) { - return createIndex(parent->row(), parent->column(), parent); + activeHeadsMap[suspendedBranch].remove(head); + + if (activeHeadsMap[suspendedBranch].size() == 0 && + branchItemMap.contains(suspendedBranch)) + { + QStandardItem * item = branchItemMap.value(suspendedBranch); + item->setData(QVariant(suspendedBranchesBrush), Qt::ForegroundRole); + + QModelIndex index = indexFromItem(item); + emit dataChanged(index, index); + } } } - return QModelIndex(); } -QStandardItem * Branches::getBranchItem(int row, int column, const QModelIndex & parent) const +Qt::ItemFlags Branches::flags(const QModelIndex & index) const { - if (parent.isValid()) - { - return static_cast(parent.internalPointer())->child(row, column); - } - return branches.item(row, column); -} + if (!index.isValid()) + return 0; -QStandardItem * Branches::branchFromIndex(const QModelIndex & index) const -{ - if (index.isValid()) + // tree parents group branches, but are not valid branches itself + // so we don't want them to be selectable + QFlags flags = Qt::ItemIsEnabled; + if (rowCount(index) == 0) { - return static_cast(index.internalPointer()); + flags |= Qt::ItemIsSelectable; } - return 0; + + return flags; } ============================================================ --- src/model/Branches.h 282a518befacd48337105670f1a00fa89bb759d3 +++ src/model/Branches.h aac5902d3666e210b470e5e38b242ddb453450b5 @@ -22,24 +22,18 @@ #include "AutomateCommand.h" #include "TreeBuilder.h" -#include -#include +#include +#include +#include -class Branches : public QAbstractItemModel, public AutomateCommand +class Branches : public QStandardItemModel, public AutomateCommand { Q_OBJECT public: Branches(QObject *, const DatabaseFile &, bool); virtual ~Branches(); - // needed Qt Model methods - QVariant data(const QModelIndex &, int) const; - QVariant headerData(int, Qt::Orientation, int) const; - Qt::ItemFlags flags(const QModelIndex &) const; - QModelIndex index(int, int, const QModelIndex &) const; - QModelIndex parent(const QModelIndex &) const; - int rowCount(const QModelIndex &) const; - int columnCount(const QModelIndex &) const; + Qt::ItemFlags flags(const QModelIndex & index) const; public slots: void readBranches(); @@ -49,13 +43,15 @@ private: private: void processTaskResult(const MonotoneTaskPtr &); - QStandardItem * getBranchItem(int row, int column, const QModelIndex & index) const; - QStandardItem * branchFromIndex(const QModelIndex & index) const; + QMap > activeHeadsMap; + QMap branchItemMap; + bool tree; TreeBuilder * builder; - QStandardItemModel branches; + DatabaseFile databaseFile; + QBrush suspendedBranchesBrush; }; #endif ============================================================ --- src/util/Settings.cpp 6f7890495fbe7859d349114be2cea5536c6044ee +++ src/util/Settings.cpp 66eea129ecb197d95578dc3abc07a9415922690a @@ -43,6 +43,7 @@ Settings::Settings() : inner(0) defaults.insert("AnnotationColorHighlight", "#EEEEEE"); defaults.insert("DiffColorAddedLines", "#90EE90"); defaults.insert("DiffColorRemovedLines", "#FFCC99"); + defaults.insert("ChangesetBrowserSuspendedBranches", "#AAAAAA"); defaults.insert("ChangesetBrowserMergeRevisions", "#32CD32"); defaults.insert("ChangesetBrowserOutOfBranchRevisions", "#AAAAAA"); ============================================================ --- src/util/TreeBuilder.cpp 0505566d5bd338cf0ff59cc25be61d861644ad7f +++ src/util/TreeBuilder.cpp 2329dcc898832540de2c76b501da0026761390f9 @@ -19,8 +19,9 @@ #include "TreeBuilder.h" #include "vocab.h" -TreeBuilder::TreeBuilder(QStandardItem * r, QObject * parent) - : QObject(parent), root(r), sep('.') {} +TreeBuilder::TreeBuilder(QMap & map, + QStandardItem * r, QObject * parent) + : QObject(parent), treeMap(map), root(r), sep('.') {} TreeBuilder::~TreeBuilder() {}; @@ -91,10 +92,8 @@ QStandardItem * TreeBuilder::add(const Q return it; } -void TreeBuilder::addList(const QString & branches) +void TreeBuilder::addList(const QStringList & branchList) { - QStringList branchList = branches.split("\n", QString::SkipEmptyParts); - foreach (const QString & branch, branchList) { add(branch); @@ -124,6 +123,7 @@ void TreeBuilder::addData(QStandardItem branch = branch.left(branch.length() - 1); } + treeMap.insert(branch, child); child->setData(branch, Qt::ToolTipRole); } ============================================================ --- src/util/TreeBuilder.h de247f223522318c2a48426553bbd374aec491e4 +++ src/util/TreeBuilder.h 7ac6ccefb09e382e4ec50108631322156311402d @@ -26,17 +26,18 @@ public: Q_OBJECT public: - TreeBuilder(QStandardItem *, QObject * parent = 0); + TreeBuilder(QMap &, QStandardItem *, QObject * parent = 0); ~TreeBuilder(); QStandardItem * add(const QString &); QStandardItem * add(const QString &, QStandardItem *); - void addList(const QString &); + void addList(const QStringList &); private: void addData(QStandardItem *); int overlap(const QString &, const QString &); + QMap & treeMap; QStandardItem * root; QChar sep; }; ============================================================ --- src/view/dialogs/Preferences.cpp 608c1282c24b69935efed352c24f8deb302ca8f4 +++ src/view/dialogs/Preferences.cpp bbfd35ef1eb2cce93eace1e023f06296102fcd97 @@ -130,6 +130,10 @@ void Preferences::init() QColor(Settings::getString("DiffColorRemovedLines")) ); + colorPickerSuspendedBranches->setSelectedColor( + QColor(Settings::getString("ChangesetBrowserSuspendedBranches")) + ); + colorPickerMergeRevisions->setSelectedColor( QColor(Settings::getString("ChangesetBrowserMergeRevisions")) ); @@ -224,6 +228,8 @@ void Preferences::accept() Settings::setString("DiffColorRemovedLines", colorPickerRemovedLines->getSelectedColor().name()); + Settings::setString("ChangesetBrowserSuspendedBranches", + colorPickerSuspendedBranches->getSelectedColor().name()); Settings::setString("ChangesetBrowserMergeRevisions", colorPickerMergeRevisions->getSelectedColor().name()); Settings::setString("ChangesetBrowserOutOfBranchRevisions",