diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index 2dea6e1b251..9a6adf03c81 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -314,7 +314,7 @@ PluginView::PluginView(QWidget *parent) m_categoryView->setSelectionMode(QAbstractItemView::SingleSelection); m_categoryView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_model = new LeveledTreeModel(this); + m_model = new TreeModel(this); m_model->setHeader({ tr("Name"), tr("Load"), tr("Version"), tr("Vendor") }); m_sortModel = new CategorySortFilterModel(this); @@ -368,7 +368,7 @@ void PluginView::setFilter(const QString &filter) PluginSpec *PluginView::pluginForIndex(const QModelIndex &index) const { const QModelIndex &sourceIndex = m_sortModel->mapToSource(index); - PluginItem *item = m_model->secondLevelItemForIndex(sourceIndex); + PluginItem *item = m_model->itemForIndexAtLevel<2>(sourceIndex); return item ? item->m_spec: 0; } @@ -455,7 +455,7 @@ bool PluginView::setPluginsEnabled(const QSet &plugins, bool enabl QSet affectedPlugins = plugins + additionalPlugins; foreach (PluginSpec *spec, affectedPlugins) { - PluginItem *item = m_model->findSecondLevelItem([spec](PluginItem *item) { + PluginItem *item = m_model->findItemAtLevel<2>([spec](PluginItem *item) { return item->m_spec == spec; }); QTC_ASSERT(item, continue); diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index 90016f529c7..50fe7482e03 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -71,7 +71,7 @@ private: bool setPluginsEnabled(const QSet &plugins, bool enable); Utils::TreeView *m_categoryView; - Utils::LeveledTreeModel *m_model; + Utils::TreeModel *m_model; QSortFilterProxyModel *m_sortModel; friend class Internal::CollectionItem; diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 33639fa9c3f..54bb76d7971 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -777,6 +777,11 @@ QModelIndex TreeItem::index() const return m_model->indexForItem(this); } +QAbstractItemModel *TreeItem::model() const +{ + return m_model; +} + void TreeItem::clear() { while (m_children.size()) { @@ -793,7 +798,7 @@ void TreeItem::expand() m_model->requestExpansion(index()); } -void TreeItem::propagateModel(TreeModel *m) +void TreeItem::propagateModel(BaseTreeModel *m) { QTC_ASSERT(m, return); QTC_ASSERT(m_model == 0 || m_model == m, return); @@ -811,7 +816,7 @@ void TreeItem::propagateModel(TreeModel *m) to use in a QTreeView. */ -TreeModel::TreeModel(QObject *parent) +BaseTreeModel::BaseTreeModel(QObject *parent) : QAbstractItemModel(parent), m_root(new TreeItem) { @@ -822,7 +827,7 @@ TreeModel::TreeModel(QObject *parent) #endif } -TreeModel::TreeModel(TreeItem *root, QObject *parent) +BaseTreeModel::BaseTreeModel(TreeItem *root, QObject *parent) : QAbstractItemModel(parent), m_root(root) { @@ -830,7 +835,7 @@ TreeModel::TreeModel(TreeItem *root, QObject *parent) m_root->propagateModel(this); } -TreeModel::~TreeModel() +BaseTreeModel::~BaseTreeModel() { QTC_ASSERT(m_root, return); QTC_ASSERT(m_root->m_parent == 0, return); @@ -839,7 +844,7 @@ TreeModel::~TreeModel() delete m_root; } -QModelIndex TreeModel::parent(const QModelIndex &idx) const +QModelIndex BaseTreeModel::parent(const QModelIndex &idx) const { CHECK_INDEX(idx); if (!idx.isValid()) @@ -862,7 +867,7 @@ QModelIndex TreeModel::parent(const QModelIndex &idx) const return QModelIndex(); } -int TreeModel::rowCount(const QModelIndex &idx) const +int BaseTreeModel::rowCount(const QModelIndex &idx) const { CHECK_INDEX(idx); if (!idx.isValid()) @@ -874,7 +879,7 @@ int TreeModel::rowCount(const QModelIndex &idx) const return item->childCount(); } -int TreeModel::columnCount(const QModelIndex &idx) const +int BaseTreeModel::columnCount(const QModelIndex &idx) const { CHECK_INDEX(idx); if (idx.column() > 0) @@ -882,7 +887,7 @@ int TreeModel::columnCount(const QModelIndex &idx) const return m_columnCount; } -bool TreeModel::setData(const QModelIndex &idx, const QVariant &data, int role) +bool BaseTreeModel::setData(const QModelIndex &idx, const QVariant &data, int role) { TreeItem *item = itemForIndex(idx); bool res = item ? item->setData(idx.column(), data, role) : false; @@ -891,13 +896,13 @@ bool TreeModel::setData(const QModelIndex &idx, const QVariant &data, int role) return res; } -QVariant TreeModel::data(const QModelIndex &idx, int role) const +QVariant BaseTreeModel::data(const QModelIndex &idx, int role) const { TreeItem *item = itemForIndex(idx); return item ? item->data(idx.column(), role) : QVariant(); } -QVariant TreeModel::headerData(int section, Qt::Orientation orientation, +QVariant BaseTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section < m_header.size()) @@ -907,13 +912,13 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation, return QVariant(); } -bool TreeModel::hasChildren(const QModelIndex &idx) const +bool BaseTreeModel::hasChildren(const QModelIndex &idx) const { TreeItem *item = itemForIndex(idx); return !item || item->hasChildren(); } -Qt::ItemFlags TreeModel::flags(const QModelIndex &idx) const +Qt::ItemFlags BaseTreeModel::flags(const QModelIndex &idx) const { if (!idx.isValid()) return 0; @@ -922,7 +927,7 @@ Qt::ItemFlags TreeModel::flags(const QModelIndex &idx) const : (Qt::ItemIsEnabled|Qt::ItemIsSelectable); } -bool TreeModel::canFetchMore(const QModelIndex &idx) const +bool BaseTreeModel::canFetchMore(const QModelIndex &idx) const { if (!idx.isValid()) return false; @@ -930,7 +935,7 @@ bool TreeModel::canFetchMore(const QModelIndex &idx) const return item ? item->canFetchMore() : false; } -void TreeModel::fetchMore(const QModelIndex &idx) +void BaseTreeModel::fetchMore(const QModelIndex &idx) { if (!idx.isValid()) return; @@ -939,17 +944,17 @@ void TreeModel::fetchMore(const QModelIndex &idx) item->fetchMore(); } -TreeItem *TreeModel::rootItem() const +TreeItem *BaseTreeModel::rootItem() const { return m_root; } -int TreeModel::topLevelItemCount() const +int BaseTreeModel::topLevelItemCount() const { return m_root->childCount(); } -void TreeModel::setRootItem(TreeItem *item) +void BaseTreeModel::setRootItem(TreeItem *item) { QTC_ASSERT(item, return); QTC_ASSERT(item->m_model == 0, return); @@ -971,18 +976,18 @@ void TreeModel::setRootItem(TreeItem *item) emit layoutChanged(); } -void TreeModel::setHeader(const QStringList &displays) +void BaseTreeModel::setHeader(const QStringList &displays) { m_header = displays; m_columnCount = displays.size(); } -void TreeModel::setHeaderToolTip(const QStringList &tips) +void BaseTreeModel::setHeaderToolTip(const QStringList &tips) { m_headerToolTip = tips; } -QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const +QModelIndex BaseTreeModel::index(int row, int column, const QModelIndex &parent) const { CHECK_INDEX(parent); if (!hasIndex(row, column, parent)) @@ -995,7 +1000,7 @@ QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) con return createIndex(row, column, (void*)(item->childAt(row))); } -TreeItem *TreeModel::itemForIndex(const QModelIndex &idx) const +TreeItem *BaseTreeModel::itemForIndex(const QModelIndex &idx) const { CHECK_INDEX(idx); TreeItem *item = idx.isValid() ? static_cast(idx.internalPointer()) : m_root; @@ -1004,7 +1009,7 @@ TreeItem *TreeModel::itemForIndex(const QModelIndex &idx) const return item; } -QModelIndex TreeModel::indexForItem(const TreeItem *item) const +QModelIndex BaseTreeModel::indexForItem(const TreeItem *item) const { QTC_ASSERT(item, return QModelIndex()); if (item == m_root) @@ -1021,7 +1026,7 @@ QModelIndex TreeModel::indexForItem(const TreeItem *item) const /*! Destroys all items in them model except the invisible root item. */ -void TreeModel::clear() +void BaseTreeModel::clear() { if (m_root) m_root->removeChildren(); @@ -1033,7 +1038,7 @@ void TreeModel::clear() \note The item is not destroyed, ownership is effectively passed to the caller. */ -TreeItem *TreeModel::takeItem(TreeItem *item) +TreeItem *BaseTreeModel::takeItem(TreeItem *item) { #if USE_MODEL_TEST (void) new ModelTest(this, this); @@ -1054,7 +1059,7 @@ TreeItem *TreeModel::takeItem(TreeItem *item) return item; } -void TreeModel::destroyItem(TreeItem *item) +void BaseTreeModel::destroyItem(TreeItem *item) { delete takeItem(item); } diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 3ddc070d41b..5c3506b6866 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -33,7 +33,7 @@ namespace Utils { -class TreeModel; +class BaseTreeModel; class QTCREATOR_UTILS_EXPORT TreeItem { @@ -69,8 +69,7 @@ public: TreeItem *childAt(int index) const; QVector children() const { return m_children; } QModelIndex index() const; - - TreeModel *model() const { return m_model; } + QAbstractItemModel *model() const; template void forSelectedChildren(const Predicate &pred) const { @@ -89,33 +88,32 @@ public: } // Levels are 1-based: Child at Level 1 is an immediate child. + template - void forFirstLevelChildren(Predicate pred) const { - foreach (TreeItem *item, m_children) - pred(static_cast(item)); + void forChildrenAtLevel(int level, Predicate pred) const + { + if (level == 1) { + foreach (TreeItem *item, m_children) + pred(static_cast(item)); + } else { + foreach (TreeItem *item, m_children) + item->forChildrenAtLevel(level - 1, pred); + } } template - void forSecondLevelChildren(Predicate pred) const { - foreach (TreeItem *item1, m_children) - foreach (TreeItem *item2, item1->m_children) - pred(static_cast(item2)); - } - - template - T findFirstLevelChild(Predicate pred) const { - foreach (TreeItem *item, m_children) - if (pred(static_cast(item))) - return static_cast(item); - return 0; - } - - template - T findSecondLevelChild(Predicate pred) const { - foreach (TreeItem *item1, m_children) - foreach (TreeItem *item2, item1->children()) - if (pred(static_cast(item2))) - return static_cast(item2); + T findChildAtLevel(int level, Predicate pred) const + { + if (level == 1) { + foreach (TreeItem *item, m_children) + if (pred(static_cast(item))) + return static_cast(item); + } else { + foreach (TreeItem *item, m_children) { + if (auto found = item->findChildAtLevel(level - 1, pred)) + return found; + } + } return 0; } @@ -135,15 +133,15 @@ private: void operator=(const TreeItem &) Q_DECL_EQ_DELETE; void clear(); - void propagateModel(TreeModel *m); + void propagateModel(BaseTreeModel *m); TreeItem *m_parent; // Not owned. - TreeModel *m_model; // Not owned. + BaseTreeModel *m_model; // Not owned. Qt::ItemFlags m_flags; protected: QVector m_children; // Owned. - friend class TreeModel; + friend class BaseTreeModel; }; // A TreeItem with children all of the same type. @@ -167,12 +165,12 @@ public: template void forFirstLevelChildren(Predicate pred) const { - return TreeItem::forFirstLevelChildren(pred); + return TreeItem::forChildrenAtLevel(1, pred); } template ChildType *findFirstLevelChild(Predicate pred) const { - return TreeItem::findFirstLevelChild(pred); + return TreeItem::findChildAtLevel(1, pred); } ParentType *parent() const { @@ -195,14 +193,14 @@ private: // A general purpose multi-level model where each item can have its // own (TreeItem-derived) type. -class QTCREATOR_UTILS_EXPORT TreeModel : public QAbstractItemModel +class QTCREATOR_UTILS_EXPORT BaseTreeModel : public QAbstractItemModel { Q_OBJECT -public: - explicit TreeModel(QObject *parent = 0); - explicit TreeModel(TreeItem *root, QObject *parent = 0); - ~TreeModel() override; +protected: + explicit BaseTreeModel(QObject *parent = 0); + explicit BaseTreeModel(TreeItem *root, QObject *parent = 0); + ~BaseTreeModel() override; void setHeader(const QStringList &displays); void setHeaderToolTip(const QStringList &tips); @@ -243,87 +241,124 @@ protected: int m_columnCount; }; -// A multi-level model with uniform types per level. -// All items below second level have to have identitical types. -template -class LeveledTreeModel : public TreeModel +namespace Internal { + +// SelectType selects the Nth type from the list +// If there are not enough types in the list, 'TreeItem' is used. +template struct SelectType; + +template struct SelectType +{ + using Type = typename SelectType::Type; +}; + +template struct SelectType<0, First, Rest...> +{ + using Type = First; +}; + +template struct SelectType +{ + using Type = TreeItem; +}; + + +// BestItem selects T0 if all types are equal and 'TreeItem' otherwise +template struct BestItemType; + +template struct BestItemType +{ + using Type = TreeItem; +}; + +template struct BestItemType +{ + using Type = typename BestItemType::Type; +}; + +template struct BestItemType +{ + using Type = First; +}; + +template<> struct BestItemType<> +{ + using Type = TreeItem; + +}; + +} // namespace Internal + +// A multi-level model with possibly uniform types per level. +template +class TreeModel : public BaseTreeModel { public: - explicit LeveledTreeModel(QObject *parent = 0) : TreeModel(new RootItem, parent) {} - explicit LeveledTreeModel(RootItem *root, QObject *parent = 0) : TreeModel(root, parent) {} + using RootItem = typename Internal::SelectType<0, LevelItemTypes...>::Type; + using BestItem = typename Internal::BestItemType::Type; - template - void forFirstLevelItems(const Predicate &pred) const { - m_root->forFirstLevelChildren(pred); + explicit TreeModel(QObject *parent = 0) : BaseTreeModel(new RootItem, parent) {} + explicit TreeModel(RootItem *root, QObject *parent = 0) : BaseTreeModel(root, parent) {} + + using BaseTreeModel::clear; + using BaseTreeModel::columnCount; + using BaseTreeModel::data; + using BaseTreeModel::destroyItem; + using BaseTreeModel::hasChildren; + using BaseTreeModel::index; + using BaseTreeModel::indexForItem; + using BaseTreeModel::rowCount; + using BaseTreeModel::setData; + using BaseTreeModel::setHeader; + using BaseTreeModel::setHeaderToolTip; + using BaseTreeModel::takeItem; + using BaseTreeModel::topLevelItemCount; + + template + void forItemsAtLevel(const Predicate &pred) const { + m_root->forChildrenAtLevel::Type *>(Level, pred); } - template - void forSecondLevelItems(const Predicate &pred) const { - m_root->forSecondLevelChildren(pred); - } - - template - FirstLevelItem *findFirstLevelItem(const Predicate &pred) const { - return m_root->findFirstLevelChild(pred); - } - - template - SecondLevelItem *findSecondLevelItem(const Predicate &pred) const { - return m_root->findSecondLevelChild(pred); + template + typename Internal::SelectType::Type *findItemAtLevel(const Predicate &pred) const { + return m_root->findChildAtLevel::Type *>(Level, pred); } RootItem *rootItem() const { - return static_cast(TreeModel::rootItem()); + return static_cast(BaseTreeModel::rootItem()); } - - FirstLevelItem *firstLevelItemForIndex(const QModelIndex &idx) const { - TreeItem *item = TreeModel::itemForIndex(idx); - return item && item->level() == 1 ? static_cast(item) : 0; + template + typename Internal::SelectType::Type *itemForIndexAtLevel(const QModelIndex &idx) const { + TreeItem *item = BaseTreeModel::itemForIndex(idx); + return item && item->level() == Level ? static_cast::Type *>(item) : 0; } - SecondLevelItem *secondLevelItemForIndex(const QModelIndex &idx) const { - TreeItem *item = TreeModel::itemForIndex(idx); - return item && item->level() == 2 ? static_cast(item) : 0; - } -}; - -// A model where all non-root nodes are the same. -template -class UniformTreeModel : public LeveledTreeModel -{ -public: - using BaseType = LeveledTreeModel; - - explicit UniformTreeModel(QObject *parent = 0) : BaseType(parent) {} - - ItemType *nonRootItemForIndex(const QModelIndex &idx) const { - TreeItem *item = TreeModel::itemForIndex(idx); - return item && item->parent() ? static_cast(item) : 0; + BestItem *nonRootItemForIndex(const QModelIndex &idx) const { + TreeItem *item = BaseTreeModel::itemForIndex(idx); + return item && item->parent() ? static_cast(item) : 0; } template - ItemType *findNonRooItem(const Predicate &pred) const { + BestItem *findNonRooItem(const Predicate &pred) const { TreeItem *root = this->rootItem(); - return root->findAnyChild(pred); + return root->findAnyChild(pred); } template void forSelectedItems(const Predicate &pred) const { TreeItem *root = this->rootItem(); - root->forSelectedChildren(pred); + root->forSelectedChildren(pred); } template void forAllItems(const Predicate &pred) const { TreeItem *root = this->rootItem(); - root->forAllChildren(pred); + root->forAllChildren(pred); } - ItemType *itemForIndex(const QModelIndex &idx) const { - return static_cast(BaseType::itemForIndex(idx)); + BestItem *itemForIndex(const QModelIndex &idx) const { + return static_cast(BaseTreeModel::itemForIndex(idx)); } }; diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 907951ed24d..f5abf8ff115 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -128,7 +128,7 @@ void TestResultItem::updateResult() /********************************* TestResultModel *****************************************/ TestResultModel::TestResultModel(QObject *parent) - : Utils::TreeModel(parent), + : Utils::TreeModel<>(parent), m_widthOfLineNumber(0), m_maxWidthOfFileName(0), m_disabled(0) diff --git a/src/plugins/autotest/testresultmodel.h b/src/plugins/autotest/testresultmodel.h index ee933bd0b6e..b9853c97c06 100644 --- a/src/plugins/autotest/testresultmodel.h +++ b/src/plugins/autotest/testresultmodel.h @@ -51,7 +51,7 @@ private: TestResultPtr m_testResult; }; -class TestResultModel : public Utils::TreeModel +class TestResultModel : public Utils::TreeModel<> { public: explicit TestResultModel(QObject *parent = 0); diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index 706f1331ce8..6bf92e58afe 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -42,7 +42,7 @@ namespace Autotest { namespace Internal { TestTreeModel::TestTreeModel(QObject *parent) : - TreeModel(parent), + TreeModel<>(parent), m_parser(new TestCodeParser(this)), m_connectionsInitialized(false) { diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h index 71291019375..c57be8a4738 100644 --- a/src/plugins/autotest/testtreemodel.h +++ b/src/plugins/autotest/testtreemodel.h @@ -40,7 +40,7 @@ class TestParseResult; using TestParseResultPtr = QSharedPointer; -class TestTreeModel : public Utils::TreeModel +class TestTreeModel : public Utils::TreeModel<> { Q_OBJECT public: diff --git a/src/plugins/baremetal/gdbserverproviderssettingspage.cpp b/src/plugins/baremetal/gdbserverproviderssettingspage.cpp index 0d2fdd1d305..90f39ba3b23 100644 --- a/src/plugins/baremetal/gdbserverproviderssettingspage.cpp +++ b/src/plugins/baremetal/gdbserverproviderssettingspage.cpp @@ -94,7 +94,7 @@ public: GdbServerProviderModel::GdbServerProviderModel(QObject *parent) - : TreeModel(parent) + : TreeModel<>(parent) { setHeader({tr("Name"), tr("Type")}); diff --git a/src/plugins/baremetal/gdbserverproviderssettingspage.h b/src/plugins/baremetal/gdbserverproviderssettingspage.h index be8e00c4224..b8fa04cc4b3 100644 --- a/src/plugins/baremetal/gdbserverproviderssettingspage.h +++ b/src/plugins/baremetal/gdbserverproviderssettingspage.h @@ -46,7 +46,7 @@ class GdbServerProviderFactory; class GdbServerProviderNode; class GdbServerProvidersSettingsWidget; -class GdbServerProviderModel : public Utils::TreeModel +class GdbServerProviderModel : public Utils::TreeModel<> { Q_OBJECT diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp index 36fee7b5070..af5eab2d67c 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp @@ -66,7 +66,7 @@ private: }; ClangStaticAnalyzerDiagnosticModel::ClangStaticAnalyzerDiagnosticModel(QObject *parent) - : Utils::TreeModel(parent) + : Utils::TreeModel<>(parent) { setHeader(QStringList() << tr("Issue") << tr("Location")); } diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h index d4bdcfbf58a..8b4be2745b0 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h @@ -40,7 +40,7 @@ namespace ProjectExplorer { class Project; } namespace ClangStaticAnalyzer { namespace Internal { -class ClangStaticAnalyzerDiagnosticModel : public Utils::TreeModel +class ClangStaticAnalyzerDiagnosticModel : public Utils::TreeModel<> { Q_OBJECT diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index c7b19033550..3b0a9ff7103 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -57,7 +57,7 @@ class CMakeToolTreeItem; // CMakeToolItemModel // -------------------------------------------------------------------------- -class CMakeToolItemModel : public LeveledTreeModel +class CMakeToolItemModel : public TreeModel { Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::CMakeSettingsPage) @@ -229,12 +229,12 @@ void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &disp CMakeToolTreeItem *CMakeToolItemModel::cmakeToolItem(const Core::Id &id) const { - return findSecondLevelItem([id](CMakeToolTreeItem *n) { return n->m_id == id; }); + return findItemAtLevel<2>([id](CMakeToolTreeItem *n) { return n->m_id == id; }); } CMakeToolTreeItem *CMakeToolItemModel::cmakeToolItem(const QModelIndex &index) const { - return secondLevelItemForIndex(index); + return itemForIndexAtLevel<2>(index); } void CMakeToolItemModel::removeCMakeTool(const Core::Id &id) @@ -252,7 +252,7 @@ void CMakeToolItemModel::apply() CMakeToolManager::deregisterCMakeTool(id); QList toRegister; - forSecondLevelItems([&toRegister](CMakeToolTreeItem *item) { + forItemsAtLevel<2>([&toRegister](CMakeToolTreeItem *item) { item->m_changed = false; if (CMakeTool *cmake = CMakeToolManager::findById(item->m_id)) { cmake->setDisplayName(item->m_name); @@ -304,7 +304,7 @@ void CMakeToolItemModel::setDefaultItemId(const Core::Id &id) QString CMakeToolItemModel::uniqueDisplayName(const QString &base) const { QStringList names; - forSecondLevelItems([&names](CMakeToolTreeItem *item) { names << item->m_name; }); + forItemsAtLevel<2>([&names](CMakeToolTreeItem *item) { names << item->m_name; }); return ProjectExplorer::Project::makeUnique(base, names); } diff --git a/src/plugins/coreplugin/locator/locatorsettingspage.cpp b/src/plugins/coreplugin/locator/locatorsettingspage.cpp index 076c67e3c64..8599cc63b25 100644 --- a/src/plugins/coreplugin/locator/locatorsettingspage.cpp +++ b/src/plugins/coreplugin/locator/locatorsettingspage.cpp @@ -190,7 +190,7 @@ QWidget *LocatorSettingsPage::widget() m_ui.filterList->setUniformRowHeights(true); m_ui.filterList->setActivationMode(Utils::DoubleClickActivation); - m_model = new TreeModel(m_ui.filterList); + m_model = new TreeModel<>(m_ui.filterList); initializeModel(); m_proxyModel = new CategorySortFilterModel(m_ui.filterList); m_proxyModel->setSourceModel(m_model); diff --git a/src/plugins/coreplugin/locator/locatorsettingspage.h b/src/plugins/coreplugin/locator/locatorsettingspage.h index 47cde6d5adf..f9e4383d466 100644 --- a/src/plugins/coreplugin/locator/locatorsettingspage.h +++ b/src/plugins/coreplugin/locator/locatorsettingspage.h @@ -28,6 +28,7 @@ #include "ui_locatorsettingspage.h" #include +#include #include #include @@ -37,13 +38,6 @@ class QListWidgetItem; class QSortFilterProxyModel; QT_END_NAMESPACE -namespace Utils { - -class TreeModel; -class TreeItem; - -} // Utils - namespace Core { class ILocatorFilter; @@ -77,7 +71,7 @@ private: Ui::LocatorSettingsWidget m_ui; Locator *m_plugin; QPointer m_widget; - Utils::TreeModel *m_model; + Utils::TreeModel<> *m_model; QSortFilterProxyModel *m_proxyModel; Utils::TreeItem *m_customFilterRoot; QList m_filters; diff --git a/src/plugins/coreplugin/variablechooser.cpp b/src/plugins/coreplugin/variablechooser.cpp index 6ffe92cbd55..8553b9e0ceb 100644 --- a/src/plugins/coreplugin/variablechooser.cpp +++ b/src/plugins/coreplugin/variablechooser.cpp @@ -109,7 +109,7 @@ public: public: VariableChooser *q; - TreeModel m_model; + TreeModel<> m_model; QPointer m_lineEdit; QPointer m_textEdit; diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 775f493bc2d..d018fbe9dc5 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -947,7 +947,7 @@ static bool isSimilarTo(const BreakpointParameters ¶ms, const BreakpointResp Breakpoint BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needle) const { // Search a breakpoint we might refer to. - return Breakpoint(findFirstLevelItem([needle](BreakpointItem *b) { + return Breakpoint(findItemAtLevel<1>([needle](BreakpointItem *b) { if (b->m_response.id.isValid() && b->m_response.id.majorPart() == needle.id.majorPart()) return true; return isSimilarTo(b->m_params, needle); @@ -956,21 +956,21 @@ Breakpoint BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needle) Breakpoint BreakHandler::findBreakpointByResponseId(const BreakpointResponseId &id) const { - return Breakpoint(findFirstLevelItem([id](BreakpointItem *b) { + return Breakpoint(findItemAtLevel<1>([id](BreakpointItem *b) { return b->m_response.id.majorPart() == id.majorPart(); })); } Breakpoint BreakHandler::findBreakpointByFunction(const QString &functionName) const { - return Breakpoint(findFirstLevelItem([functionName](BreakpointItem *b) { + return Breakpoint(findItemAtLevel<1>([functionName](BreakpointItem *b) { return b->m_params.functionName == functionName; })); } Breakpoint BreakHandler::findBreakpointByAddress(quint64 address) const { - return Breakpoint(findFirstLevelItem([address](BreakpointItem *b) { + return Breakpoint(findItemAtLevel<1>([address](BreakpointItem *b) { return b->m_params.address == address || b->m_params.address == address; })); } @@ -978,14 +978,14 @@ Breakpoint BreakHandler::findBreakpointByAddress(quint64 address) const Breakpoint BreakHandler::findBreakpointByFileAndLine(const QString &fileName, int lineNumber, bool useMarkerPosition) { - return Breakpoint(findFirstLevelItem([=](BreakpointItem *b) { + return Breakpoint(findItemAtLevel<1>([=](BreakpointItem *b) { return b->isLocatedAt(fileName, lineNumber, useMarkerPosition); })); } Breakpoint BreakHandler::breakpointById(BreakpointModelId id) const { - return Breakpoint(findFirstLevelItem([id](BreakpointItem *b) { return b->m_id == id; })); + return Breakpoint(findItemAtLevel<1>([id](BreakpointItem *b) { return b->m_id == id; })); } QVariant BreakHandler::data(const QModelIndex &idx, int role) const @@ -1005,7 +1005,7 @@ void BreakHandler::deletionHelper(BreakpointModelId id) Breakpoint BreakHandler::findWatchpoint(const BreakpointParameters ¶ms) const { - return Breakpoint(findFirstLevelItem([params](BreakpointItem *b) { + return Breakpoint(findItemAtLevel<1>([params](BreakpointItem *b) { return b->m_params.isWatchpoint() && b->m_params.address == params.address && b->m_params.size == params.size @@ -1017,7 +1017,7 @@ Breakpoint BreakHandler::findWatchpoint(const BreakpointParameters ¶ms) cons void BreakHandler::saveBreakpoints() { QList list; - forFirstLevelItems([&list](BreakpointItem *b) { + forItemsAtLevel<1>([&list](BreakpointItem *b) { const BreakpointParameters ¶ms = b->m_params; QMap map; if (params.type != BreakpointByFileAndLine) @@ -1121,12 +1121,12 @@ void BreakHandler::loadBreakpoints() void BreakHandler::updateMarkers() { - forFirstLevelItems([](BreakpointItem *b) { b->updateMarker(); }); + forItemsAtLevel<1>([](BreakpointItem *b) { b->updateMarker(); }); } Breakpoint BreakHandler::findBreakpointByIndex(const QModelIndex &index) const { - return Breakpoint(firstLevelItemForIndex(index)); + return Breakpoint(itemForIndexAtLevel<1>(index)); } Breakpoints BreakHandler::findBreakpointsByIndex(const QList &list) const @@ -1736,7 +1736,7 @@ void BreakHandler::breakByFunction(const QString &functionName) { // One breakpoint per function is enough for now. This does not handle // combinations of multiple conditions and ignore counts, though. - bool found = findFirstLevelItem([functionName](BreakpointItem *b) { + bool found = findItemAtLevel<1>([functionName](BreakpointItem *b) { const BreakpointParameters ¶ms = b->m_params; return params.functionName == functionName && params.condition.isEmpty() @@ -1828,7 +1828,7 @@ void BreakHandler::changeLineNumberFromMarkerHelper(BreakpointModelId id) Breakpoints BreakHandler::allBreakpoints() const { Breakpoints items; - forFirstLevelItems([&items](BreakpointItem *b) { items.append(Breakpoint(b)); }); + forItemsAtLevel<1>([&items](BreakpointItem *b) { items.append(Breakpoint(b)); }); return items; } @@ -1840,7 +1840,7 @@ Breakpoints BreakHandler::unclaimedBreakpoints() const Breakpoints BreakHandler::engineBreakpoints(DebuggerEngine *engine) const { Breakpoints items; - forFirstLevelItems([&items, engine](BreakpointItem *b) { + forItemsAtLevel<1>([&items, engine](BreakpointItem *b) { if (b->m_engine == engine) items.append(Breakpoint(b)); }); @@ -1850,7 +1850,7 @@ Breakpoints BreakHandler::engineBreakpoints(DebuggerEngine *engine) const QStringList BreakHandler::engineBreakpointPaths(DebuggerEngine *engine) const { QSet set; - forFirstLevelItems([&set, engine](BreakpointItem *b) { + forItemsAtLevel<1>([&set, engine](BreakpointItem *b) { if (b->m_engine == engine) { if (b->m_params.type == BreakpointByFileAndLine) set.insert(QFileInfo(b->m_params.fileName).dir().path()); @@ -1990,7 +1990,7 @@ bool BreakHandler::contextMenuEvent(const ItemViewEvent &ev) [this] { deleteAllBreakpoints(); }); // Delete by file: Find indices of breakpoints of the same file. - BreakpointItem *item = firstLevelItemForIndex(ev.index()); + BreakpointItem *item = itemForIndexAtLevel<1>(ev.index()); Breakpoints breakpointsInFile; QString file; if (item) { diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index 82426abbd0d..e31fc81fa11 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -159,7 +159,7 @@ inline uint qHash(const Debugger::Internal::Breakpoint &b) { return b.hash(); } typedef QList Breakpoints; -using BreakModel = Utils::LeveledTreeModel, BreakpointItem, LocationItem>; +using BreakModel = Utils::TreeModel, BreakpointItem, LocationItem>; class BreakHandler : public BreakModel { diff --git a/src/plugins/debugger/console/consoleitemmodel.cpp b/src/plugins/debugger/console/consoleitemmodel.cpp index fc65764c71a..fe72ddc3150 100644 --- a/src/plugins/debugger/console/consoleitemmodel.cpp +++ b/src/plugins/debugger/console/consoleitemmodel.cpp @@ -38,7 +38,7 @@ namespace Internal { /////////////////////////////////////////////////////////////////////// ConsoleItemModel::ConsoleItemModel(QObject *parent) : - Utils::TreeModel(new ConsoleItem, parent), + Utils::TreeModel<>(new ConsoleItem, parent), m_maxSizeOfFileName(0) { clear(); @@ -46,7 +46,7 @@ ConsoleItemModel::ConsoleItemModel(QObject *parent) : void ConsoleItemModel::clear() { - Utils::TreeModel::clear(); + Utils::TreeModel<>::clear(); appendItem(new ConsoleItem(ConsoleItem::InputType)); emit selectEditableRow(index(0, 0, QModelIndex()), QItemSelectionModel::ClearAndSelect); } diff --git a/src/plugins/debugger/console/consoleitemmodel.h b/src/plugins/debugger/console/consoleitemmodel.h index 03f0203f014..023b69ec329 100644 --- a/src/plugins/debugger/console/consoleitemmodel.h +++ b/src/plugins/debugger/console/consoleitemmodel.h @@ -37,7 +37,7 @@ QT_END_NAMESPACE namespace Debugger { namespace Internal { -class ConsoleItemModel : public Utils::TreeModel +class ConsoleItemModel : public Utils::TreeModel<> { Q_OBJECT public: diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index 359451bb3a8..701a84c6711 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -99,7 +99,7 @@ public: // DebuggerItemModel // -------------------------------------------------------------------------- -class DebuggerItemModel : public LeveledTreeModel +class DebuggerItemModel : public TreeModel { Q_DECLARE_TR_FUNCTIONS(Debugger::DebuggerOptionsPage) @@ -139,7 +139,7 @@ void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed) void DebuggerItemModel::updateDebugger(const DebuggerItem &item) { auto matcher = [item](DebuggerTreeItem *n) { return n->m_item.m_id == item.id(); }; - DebuggerTreeItem *treeItem = findSecondLevelItem(matcher); + DebuggerTreeItem *treeItem = findItemAtLevel<2>(matcher); QTC_ASSERT(treeItem, return); TreeItem *parent = treeItem->parent(); @@ -178,7 +178,7 @@ void DebuggerItemModel::apply() foreach (const QVariant &id, m_removedItems) DebuggerItemManager::deregisterDebugger(id); - forSecondLevelItems([](DebuggerTreeItem *item) { + forItemsAtLevel<2>([](DebuggerTreeItem *item) { item->m_changed = false; DebuggerItemManager::updateOrAddDebugger(item->m_item); }); diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index a34a0b41c0d..d3e179f1c9a 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -212,8 +212,8 @@ public: ToolTipWatchItem::ToolTipWatchItem(TreeItem *item) { - const TreeModel *model = item->model(); - QModelIndex idx = model->indexForItem(item); + const QAbstractItemModel *model = item->model(); + QModelIndex idx = item->index(); name = model->data(idx.sibling(idx.row(), 0), Qt::DisplayRole).toString(); value = model->data(idx.sibling(idx.row(), 1), Qt::DisplayRole).toString(); type = model->data(idx.sibling(idx.row(), 2), Qt::DisplayRole).toString(); @@ -231,7 +231,7 @@ ToolTipWatchItem::ToolTipWatchItem(TreeItem *item) // ///////////////////////////////////////////////////////////////////////// -class ToolTipModel : public UniformTreeModel +class ToolTipModel : public TreeModel { public: ToolTipModel() diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp index b388322ce36..398152b9e44 100644 --- a/src/plugins/debugger/moduleshandler.cpp +++ b/src/plugins/debugger/moduleshandler.cpp @@ -250,7 +250,7 @@ QAbstractItemModel *ModulesHandler::model() const ModuleItem *ModulesHandler::moduleFromPath(const QString &modulePath) const { // Recent modules are more likely to be unloaded first. - return m_model->findFirstLevelItem([modulePath](ModuleItem *item) { + return m_model->findItemAtLevel<1>([modulePath](ModuleItem *item) { return item->module.modulePath == modulePath; }); } @@ -263,7 +263,7 @@ void ModulesHandler::removeAll() Modules ModulesHandler::modules() const { Modules mods; - m_model->forFirstLevelItems([&mods](ModuleItem *item) { mods.append(item->module); }); + m_model->forItemsAtLevel<1>([&mods](ModuleItem *item) { mods.append(item->module); }); return mods; } @@ -302,13 +302,13 @@ void ModulesHandler::updateModule(const Module &module) void ModulesHandler::beginUpdateAll() { - m_model->forFirstLevelItems([](ModuleItem *item) { item->updated = false; }); + m_model->forItemsAtLevel<1>([](ModuleItem *item) { item->updated = false; }); } void ModulesHandler::endUpdateAll() { QList toDestroy; - m_model->forFirstLevelItems([&toDestroy](ModuleItem *item) { + m_model->forItemsAtLevel<1>([&toDestroy](ModuleItem *item) { if (!item->updated) toDestroy.append(item); }); diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h index bdb425e0eb2..2be31da5ffa 100644 --- a/src/plugins/debugger/moduleshandler.h +++ b/src/plugins/debugger/moduleshandler.h @@ -110,7 +110,7 @@ typedef QVector Modules; // ////////////////////////////////////////////////////////////////// -using ModulesModel = Utils::LeveledTreeModel, ModuleItem>; +using ModulesModel = Utils::TreeModel, ModuleItem>; class ModulesHandler : public QObject { diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp index 41b92dff903..9ab72f0801a 100644 --- a/src/plugins/debugger/registerhandler.cpp +++ b/src/plugins/debugger/registerhandler.cpp @@ -677,8 +677,8 @@ bool RegisterHandler::contextMenuEvent(const ItemViewEvent &ev) const bool actionsEnabled = m_engine->debuggerActionsEnabled(); const DebuggerState state = m_engine->state(); - RegisterItem *registerItem = firstLevelItemForIndex(ev.index()); - RegisterSubItem *registerSubItem = secondLevelItemForIndex(ev.index()); + RegisterItem *registerItem = itemForIndexAtLevel<1>(ev.index()); + RegisterSubItem *registerSubItem = itemForIndexAtLevel<2>(ev.index()); const quint64 address = registerItem ? registerItem->addressValue() : 0; const QString registerName = registerItem ? registerItem->m_reg.name : QString(); diff --git a/src/plugins/debugger/registerhandler.h b/src/plugins/debugger/registerhandler.h index 05793784312..45675bf90da 100644 --- a/src/plugins/debugger/registerhandler.h +++ b/src/plugins/debugger/registerhandler.h @@ -101,7 +101,7 @@ public: class RegisterSubItem; class RegisterItem; using RegisterRootItem = Utils::TypedTreeItem; -using RegisterModel = Utils::LeveledTreeModel; +using RegisterModel = Utils::TreeModel; typedef QMap RegisterMap; diff --git a/src/plugins/debugger/threadshandler.cpp b/src/plugins/debugger/threadshandler.cpp index 4c2cc2ba2b7..87b6efba3ad 100644 --- a/src/plugins/debugger/threadshandler.cpp +++ b/src/plugins/debugger/threadshandler.cpp @@ -263,7 +263,7 @@ bool ThreadsHandler::setData(const QModelIndex &idx, const QVariant &data, int r static ThreadItem *itemForThreadId(const ThreadsHandler *handler, ThreadId threadId) { const auto matcher = [threadId](ThreadItem *item) { return item->threadData.id == threadId; }; - return handler->findFirstLevelItem(matcher); + return handler->findItemAtLevel<1>(matcher); } static int indexForThreadId(const ThreadsHandler *handler, ThreadId threadId) @@ -361,7 +361,7 @@ void ThreadsHandler::setThreads(const Threads &threads) void ThreadsHandler::updateThreadBox() { QStringList list; - forFirstLevelItems([&list](ThreadItem *item) { + forItemsAtLevel<1>([&list](ThreadItem *item) { list.append(QString::fromLatin1("#%1 %2").arg(item->threadData.id.raw()).arg(item->threadData.name)); }); Internal::setThreadBoxContents(list, indexForThreadId(this, m_currentId)); @@ -382,7 +382,7 @@ void ThreadsHandler::removeAll() bool ThreadsHandler::notifyGroupExited(const QString &groupId) { QList list; - forFirstLevelItems([&list, groupId](ThreadItem *item) { + forItemsAtLevel<1>([&list, groupId](ThreadItem *item) { if (item->threadData.groupId == groupId) list.append(item); }); @@ -409,7 +409,7 @@ void ThreadsHandler::notifyRunning(const QString &data) void ThreadsHandler::notifyAllRunning() { - forFirstLevelItems([](ThreadItem *item) { item->notifyRunning(); }); + forItemsAtLevel<1>([](ThreadItem *item) { item->notifyRunning(); }); } void ThreadsHandler::notifyRunning(ThreadId threadId) @@ -434,7 +434,7 @@ void ThreadsHandler::notifyStopped(const QString &data) void ThreadsHandler::notifyAllStopped() { - forFirstLevelItems([](ThreadItem *item) { item->notifyStopped(); }); + forItemsAtLevel<1>([](ThreadItem *item) { item->notifyStopped(); }); } void ThreadsHandler::notifyStopped(ThreadId threadId) diff --git a/src/plugins/debugger/threadshandler.h b/src/plugins/debugger/threadshandler.h index a7d0d6ef310..c95001f8676 100644 --- a/src/plugins/debugger/threadshandler.h +++ b/src/plugins/debugger/threadshandler.h @@ -42,7 +42,7 @@ class DebuggerEngine; class GdbMi; class ThreadItem; -class ThreadsHandler : public Utils::LeveledTreeModel, ThreadItem> +class ThreadsHandler : public Utils::TreeModel, ThreadItem> { Q_OBJECT diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 88c2272f189..d16a35f059b 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -2018,7 +2018,7 @@ void WatchHandler::notifyUpdateStarted(const QStringList &inames) auto marker = [](WatchItem *item) { item->outdated = true; }; if (inames.isEmpty()) { - m_model->forFirstLevelItems([marker](WatchItem *item) { + m_model->forItemsAtLevel<1>([marker](WatchItem *item) { item->forAllChildren(marker); }); } else { diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 11d50d73c32..cf62cf2aede 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -38,7 +38,7 @@ class WatchModel; typedef QVector DisplayFormats; -class WatchModelBase : public Utils::UniformTreeModel +class WatchModelBase : public Utils::TreeModel { Q_OBJECT diff --git a/src/plugins/projectexplorer/kitmodel.cpp b/src/plugins/projectexplorer/kitmodel.cpp index d543022c51a..6f904f483dd 100644 --- a/src/plugins/projectexplorer/kitmodel.cpp +++ b/src/plugins/projectexplorer/kitmodel.cpp @@ -103,7 +103,7 @@ public: // -------------------------------------------------------------------------- KitModel::KitModel(QBoxLayout *parentLayout, QObject *parent) - : LeveledTreeModel(parent), + : TreeModel(parent), m_parentLayout(parentLayout) { setHeader(QStringList(tr("Name"))); @@ -196,7 +196,7 @@ void KitModel::isAutoDetectedChanged() void KitModel::validateKitNames() { QHash nameHash; - forSecondLevelItems([&nameHash](KitNode *n) { + forItemsAtLevel<2>([&nameHash](KitNode *n) { const QString displayName = n->widget->displayName(); if (nameHash.contains(displayName)) ++nameHash[displayName]; @@ -204,7 +204,7 @@ void KitModel::validateKitNames() nameHash.insert(displayName, 1); }); - forSecondLevelItems([&nameHash](KitNode *n) { + forItemsAtLevel<2>([&nameHash](KitNode *n) { const QString displayName = n->widget->displayName(); n->widget->setHasUniqueName(nameHash.value(displayName) == 1); }); @@ -213,7 +213,7 @@ void KitModel::validateKitNames() void KitModel::apply() { // Add/update dirty nodes before removing kits. This ensures the right kit ends up as default. - forSecondLevelItems([](KitNode *n) { + forItemsAtLevel<2>([](KitNode *n) { if (n->widget->isDirty()) { n->widget->apply(); n->update(); @@ -241,7 +241,7 @@ void KitModel::markForRemoval(Kit *k) } if (node == m_defaultNode) - setDefaultNode(findSecondLevelItem([node](KitNode *kn) { return kn != node; })); + setDefaultNode(findItemAtLevel<2>([node](KitNode *kn) { return kn != node; })); takeItem(node); if (node->widget->configures(0)) @@ -273,7 +273,7 @@ Kit *KitModel::markForAddition(Kit *baseKit) KitNode *KitModel::findWorkingCopy(Kit *k) const { - return findSecondLevelItem([k](KitNode *n) { return n->widget->workingCopy() == k; }); + return findItemAtLevel<2>([k](KitNode *n) { return n->widget->workingCopy() == k; }); } KitNode *KitModel::createNode(Kit *k) @@ -338,12 +338,12 @@ void KitModel::removeKit(Kit *k) } } - KitNode *node = findSecondLevelItem([k](KitNode *n) { + KitNode *node = findItemAtLevel<2>([k](KitNode *n) { return n->widget->configures(k); }); if (node == m_defaultNode) - setDefaultNode(findSecondLevelItem([node](KitNode *kn) { return kn != node; })); + setDefaultNode(findItemAtLevel<2>([node](KitNode *kn) { return kn != node; })); destroyItem(node); @@ -354,7 +354,7 @@ void KitModel::removeKit(Kit *k) void KitModel::changeDefaultKit() { Kit *defaultKit = KitManager::defaultKit(); - KitNode *node = findSecondLevelItem([defaultKit](KitNode *n) { + KitNode *node = findItemAtLevel<2>([defaultKit](KitNode *n) { return n->widget->configures(defaultKit); }); setDefaultNode(node); diff --git a/src/plugins/projectexplorer/kitmodel.h b/src/plugins/projectexplorer/kitmodel.h index 299f8f67b51..8070eefe30a 100644 --- a/src/plugins/projectexplorer/kitmodel.h +++ b/src/plugins/projectexplorer/kitmodel.h @@ -48,7 +48,7 @@ class KitNode; // KitModel: // -------------------------------------------------------------------------- -class KitModel : public Utils::LeveledTreeModel +class KitModel : public Utils::TreeModel { Q_OBJECT diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index 01d9aa46700..32c95d3b28b 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -81,7 +81,7 @@ public: case Qt::DecorationRole: { QVariant icon; - forSecondLevelChildren([this, &icon](TreeItem *item) { + forChildrenAtLevel(2, [this, &icon](TreeItem *item) { QVariant sicon = item->data(0, Qt::DecorationRole); if (sicon.isValid()) icon = sicon; @@ -166,14 +166,13 @@ public: // SelectorModel // -class SelectorModel - : public LeveledTreeModel +class SelectorModel : public TreeModel { Q_OBJECT public: SelectorModel(QObject *parent) - : LeveledTreeModel(parent) + : TreeModel(parent) { setRootItem(new RootItem); setHeader({ ProjectWindow::tr("Projects") }); @@ -406,7 +405,7 @@ void ProjectWindow::updatePanel() ProjectItem *ProjectWindow::itemForProject(Project *project) const { - return m_selectorModel->findFirstLevelItem([project](ProjectItem *item) { + return m_selectorModel->findItemAtLevel<1>([project](ProjectItem *item) { return item->project() == project; }); } diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index fa67b87bc6f..7d7980a965b 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -339,7 +339,7 @@ ProjectWizardPage::~ProjectWizardPage() delete m_ui; } -void ProjectWizardPage::setModel(TreeModel *model) +void ProjectWizardPage::setModel(Utils::TreeModel<> *model) { delete m_model; m_model = model; @@ -492,8 +492,7 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const QStringList & setAdditionalInfo(selector.deployingProjects()); - auto model = new TreeModel(tree); - setModel(model); + setModel(new TreeModel<>(tree)); setBestNode(selector.bestChoice()); setAddingSubProject(action == AddSubProject); } diff --git a/src/plugins/projectexplorer/projectwizardpage.h b/src/plugins/projectexplorer/projectwizardpage.h index c05d6e79fe3..ce4f77d6251 100644 --- a/src/plugins/projectexplorer/projectwizardpage.h +++ b/src/plugins/projectexplorer/projectwizardpage.h @@ -31,6 +31,7 @@ #include #include +#include QT_BEGIN_NAMESPACE class QTreeView; @@ -38,7 +39,6 @@ class QModelIndex; QT_END_NAMESPACE namespace Core { class IVersionControl; } -namespace Utils { class TreeModel; } namespace ProjectExplorer { namespace Internal { @@ -87,7 +87,7 @@ private: void setAdditionalInfo(const QString &text); void setAddingSubProject(bool addingSubProject); - void setModel(Utils::TreeModel *model); + void setModel(Utils::TreeModel<> *model); void setBestNode(ProjectExplorer::Internal::AddNewTree *tree); void setVersionControls(const QStringList &); void setProjectToolTip(const QString &); @@ -95,7 +95,7 @@ private: Ui::WizardPage *m_ui; QStringList m_projectToolTips; - Utils::TreeModel *m_model = nullptr; + Utils::TreeModel<> *m_model = nullptr; QList m_activeVersionControls; QString m_commonDirectory; diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 3ef0228a8fd..0ae5a7e4854 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -229,7 +229,7 @@ public: void apply(); public: - LeveledTreeModel m_model; + TreeModel m_model; QList m_factories; QTreeView *m_toolChainView; DetailsWidget *m_container; @@ -293,7 +293,7 @@ void ToolChainOptionsWidget::removeToolChain(ToolChain *tc) } StaticTreeItem *parent = parentForToolChain(tc); - auto item = parent->findFirstLevelChild([tc](ToolChainTreeItem *item) { + auto item = parent->findChildAtLevel(1, [tc](ToolChainTreeItem *item) { return item->toolChain == tc; }); m_model.destroyItem(item); diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 9a3f2c8b691..7bed927f1ff 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -223,7 +223,7 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent) m_autoItem = new StaticTreeItem(tr("Auto-detected")); m_manualItem = new StaticTreeItem(tr("Manual")); - m_model = new LeveledTreeModel(); + m_model = new TreeModel(); m_model->setHeader({tr("Name"), tr("qmake Location"), tr("Type")}); m_model->rootItem()->appendChild(m_autoItem); m_model->rootItem()->appendChild(m_manualItem); @@ -299,7 +299,7 @@ QtVersionItem *QtOptionsPageWidget::currentItem() const { QModelIndex idx = m_ui->qtdirList->selectionModel()->currentIndex(); QModelIndex sourceIdx = m_filterModel->mapToSource(idx); - return m_model->secondLevelItemForIndex(sourceIdx); + return m_model->itemForIndexAtLevel<2>(sourceIdx); } void QtOptionsPageWidget::cleanUpQtVersions() @@ -336,7 +336,7 @@ void QtOptionsPageWidget::cleanUpQtVersions() void QtOptionsPageWidget::toolChainsUpdated() { - m_model->forSecondLevelItems([this](QtVersionItem *item) { + m_model->forItemsAtLevel<2>([this](QtVersionItem *item) { if (item == currentItem()) updateDescriptionLabel(); else @@ -346,7 +346,7 @@ void QtOptionsPageWidget::toolChainsUpdated() void QtOptionsPageWidget::qtVersionsDumpUpdated(const FileName &qmakeCommand) { - m_model->forSecondLevelItems([this, qmakeCommand](QtVersionItem *item) { + m_model->forItemsAtLevel<2>([this, qmakeCommand](QtVersionItem *item) { if (item->version()->qmakeCommand() == qmakeCommand) item->version()->recheckDumper(); }); @@ -454,7 +454,7 @@ bool QtOptionsPageWidget::isNameUnique(const BaseQtVersion *version) { const QString name = version->displayName().trimmed(); - return !m_model->findSecondLevelItem([name, version](QtVersionItem *item) { + return !m_model->findItemAtLevel<2>([name, version](QtVersionItem *item) { BaseQtVersion *v = item->version(); return v != version && v->displayName().trimmed() == name; }); @@ -513,7 +513,7 @@ void QtOptionsPageWidget::updateQtVersions(const QList &additions, const QL QList toAdd = additions; // Find existing items to remove/change: - m_model->forSecondLevelItems([&](QtVersionItem *item) { + m_model->forItemsAtLevel<2>([&](QtVersionItem *item) { int id = item->uniqueId(); if (removals.contains(id)) { toRemove.append(item); @@ -539,7 +539,7 @@ void QtOptionsPageWidget::updateQtVersions(const QList &additions, const QL parent->appendChild(item); } - m_model->forSecondLevelItems([this](QtVersionItem *item) { updateVersionItem(item); }); + m_model->forItemsAtLevel<2>([this](QtVersionItem *item) { updateVersionItem(item); }); } QtOptionsPageWidget::~QtOptionsPageWidget() @@ -758,7 +758,7 @@ void QtOptionsPageWidget::updateCurrentQtName() item->version()->setUnexpandedDisplayName(m_versionUi->nameEdit->text()); updateDescriptionLabel(); - m_model->forSecondLevelItems([this](QtVersionItem *item) { updateVersionItem(item); }); + m_model->forItemsAtLevel<2>([this](QtVersionItem *item) { updateVersionItem(item); }); } void QtOptionsPageWidget::apply() @@ -768,7 +768,7 @@ void QtOptionsPageWidget::apply() QList versions; - m_model->forSecondLevelItems([this, &versions](QtVersionItem *item) { + m_model->forItemsAtLevel<2>([this, &versions](QtVersionItem *item) { item->setChanged(false); versions.append(item->version()->clone()); }); diff --git a/src/plugins/qtsupport/qtoptionspage.h b/src/plugins/qtsupport/qtoptionspage.h index 4c70decc9a1..09363c89bc1 100644 --- a/src/plugins/qtsupport/qtoptionspage.h +++ b/src/plugins/qtsupport/qtoptionspage.h @@ -113,7 +113,7 @@ private: bool isNameUnique(const BaseQtVersion *version); void updateVersionItem(QtVersionItem *item); - Utils::LeveledTreeModel *m_model; + Utils::TreeModel *m_model; QSortFilterProxyModel *m_filterModel; Utils::TreeItem *m_autoItem; Utils::TreeItem *m_manualItem; diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp index a137948cc05..a6ff62ebdf8 100644 --- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp +++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp @@ -85,7 +85,7 @@ private: ErrorListModel::ErrorListModel(QObject *parent) - : Utils::TreeModel(parent) + : Utils::TreeModel<>(parent) { setHeader(QStringList() << tr("Issue") << tr("Location")); } diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.h b/src/plugins/valgrind/xmlprotocol/errorlistmodel.h index 6112d152a86..722808fe7e8 100644 --- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.h +++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.h @@ -37,7 +37,7 @@ namespace XmlProtocol { class Error; class Frame; -class ErrorListModel : public Utils::TreeModel +class ErrorListModel : public Utils::TreeModel<> { Q_OBJECT diff --git a/tests/auto/utils/treemodel/tst_treemodel.cpp b/tests/auto/utils/treemodel/tst_treemodel.cpp index 603a92dc5b8..e87f30183e0 100644 --- a/tests/auto/utils/treemodel/tst_treemodel.cpp +++ b/tests/auto/utils/treemodel/tst_treemodel.cpp @@ -27,6 +27,8 @@ #include +#include + //TESTED_COMPONENT=src/libs/utils/treemodel using namespace Utils; @@ -36,6 +38,7 @@ class tst_TreeModel : public QObject Q_OBJECT private slots: + void testTypes(); void testIteration(); void testMixed(); }; @@ -58,7 +61,7 @@ static TreeItem *createItem(const QString &name) void tst_TreeModel::testIteration() { - TreeModel m; + TreeModel<> m; TreeItem *r = m.rootItem(); TreeItem *group0 = createItem("group0"); TreeItem *group1 = createItem("group1"); @@ -95,7 +98,7 @@ struct ItemB : public TreeItem {}; void tst_TreeModel::testMixed() { - LeveledTreeModel m; + TreeModel m; TreeItem *r = m.rootItem(); TreeItem *ra; r->appendChild(new ItemA); @@ -104,14 +107,28 @@ void tst_TreeModel::testMixed() ra->appendChild(new ItemB); int n = 0; - m.forFirstLevelItems([&n](ItemA *) { ++n; }); + m.forItemsAtLevel<1>([&n](ItemA *) { ++n; }); QCOMPARE(n, 2); n = 0; - m.forSecondLevelItems([&n](ItemB *) { ++n; }); + m.forItemsAtLevel<2>([&n](ItemB *) { ++n; }); QCOMPARE(n, 2); } +void tst_TreeModel::testTypes() +{ + struct A {}; + struct B {}; + struct C {}; + + static_assert(std::is_same::Type, A>::value, ""); + static_assert(std::is_same::Type, TreeItem>::value, ""); + static_assert(std::is_same::Type, TreeItem>::value, ""); + static_assert(std::is_same::Type, A>::value, ""); + static_assert(std::is_same::Type, B>::value, ""); + static_assert(std::is_same::Type, C>::value, ""); + static_assert(std::is_same::Type, TreeItem>::value, ""); +} QTEST_MAIN(tst_TreeModel)