forked from qt-creator/qt-creator
TreeModel: Move some base TreeItem code out-of-line
Avoid code explosion. Change-Id: I7d239a4560e90b68cc4991341adf940a98776254 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -777,6 +777,61 @@ QAbstractItemModel *TreeItem::model() const
|
|||||||
return m_model;
|
return m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TreeItem::forAllChildren(const std::function<void (TreeItem *)> &pred) const
|
||||||
|
{
|
||||||
|
foreach (TreeItem *item, m_children) {
|
||||||
|
pred(item);
|
||||||
|
item->forAllChildren(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeItem::forSelectedChildren(const std::function<bool (TreeItem *)> &pred) const
|
||||||
|
{
|
||||||
|
foreach (TreeItem *item, m_children) {
|
||||||
|
if (pred(item))
|
||||||
|
item->forSelectedChildren(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeItem::forChildrenAtLevel(int level, const std::function<void(TreeItem *)> &pred) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(level > 0, return);
|
||||||
|
if (level == 1) {
|
||||||
|
foreach (TreeItem *item, m_children)
|
||||||
|
pred(item);
|
||||||
|
} else {
|
||||||
|
foreach (TreeItem *item, m_children)
|
||||||
|
item->forChildrenAtLevel(level - 1, pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeItem *TreeItem::findChildAtLevel(int level, const std::function<bool(TreeItem *)> &pred) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(level > 0, return 0);
|
||||||
|
if (level == 1) {
|
||||||
|
foreach (TreeItem *item, m_children)
|
||||||
|
if (pred(item))
|
||||||
|
return item;
|
||||||
|
} else {
|
||||||
|
foreach (TreeItem *item, m_children) {
|
||||||
|
if (auto found = item->findChildAtLevel(level - 1, pred))
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeItem *TreeItem::findAnyChild(const std::function<bool(TreeItem *)> &pred) const
|
||||||
|
{
|
||||||
|
foreach (TreeItem *item, m_children) {
|
||||||
|
if (pred(item))
|
||||||
|
return item;
|
||||||
|
if (TreeItem *found = item->findAnyChild(pred))
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void TreeItem::clear()
|
void TreeItem::clear()
|
||||||
{
|
{
|
||||||
while (m_children.size()) {
|
while (m_children.size()) {
|
||||||
|
|||||||
@@ -70,62 +70,13 @@ public:
|
|||||||
QModelIndex index() const;
|
QModelIndex index() const;
|
||||||
QAbstractItemModel *model() const;
|
QAbstractItemModel *model() const;
|
||||||
|
|
||||||
template <class T, class Predicate>
|
void forSelectedChildren(const std::function<bool(TreeItem *)> &pred) const;
|
||||||
void forSelectedChildren(const Predicate &pred) const {
|
void forAllChildren(const std::function<void(TreeItem *)> &pred) const;
|
||||||
foreach (TreeItem *item, m_children) {
|
TreeItem *findAnyChild(const std::function<bool(TreeItem *)> &pred) const;
|
||||||
if (pred(static_cast<T>(item)))
|
|
||||||
item->forSelectedChildren<T, Predicate>(pred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, typename Predicate>
|
|
||||||
void forAllChildren(const Predicate &pred) const {
|
|
||||||
foreach (TreeItem *item, m_children) {
|
|
||||||
pred(static_cast<T>(item));
|
|
||||||
item->forAllChildren<T, Predicate>(pred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Levels are 1-based: Child at Level 1 is an immediate child.
|
// Levels are 1-based: Child at Level 1 is an immediate child.
|
||||||
|
void forChildrenAtLevel(int level, const std::function<void(TreeItem *)> &pred) const;
|
||||||
template <class T, typename Predicate>
|
TreeItem *findChildAtLevel(int level, const std::function<bool(TreeItem *)> &pred) const;
|
||||||
void forChildrenAtLevel(int level, Predicate pred) const
|
|
||||||
{
|
|
||||||
if (level == 1) {
|
|
||||||
foreach (TreeItem *item, m_children)
|
|
||||||
pred(static_cast<T>(item));
|
|
||||||
} else {
|
|
||||||
foreach (TreeItem *item, m_children)
|
|
||||||
item->forChildrenAtLevel<T, Predicate>(level - 1, pred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, typename Predicate>
|
|
||||||
T findChildAtLevel(int level, Predicate pred) const
|
|
||||||
{
|
|
||||||
if (level == 1) {
|
|
||||||
foreach (TreeItem *item, m_children)
|
|
||||||
if (pred(static_cast<T>(item)))
|
|
||||||
return static_cast<T>(item);
|
|
||||||
} else {
|
|
||||||
foreach (TreeItem *item, m_children) {
|
|
||||||
if (auto found = item->findChildAtLevel<T, Predicate>(level - 1, pred))
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, typename Predicate>
|
|
||||||
T findAnyChild(Predicate pred) const {
|
|
||||||
foreach (TreeItem *item, m_children) {
|
|
||||||
if (pred(static_cast<T>(item)))
|
|
||||||
return static_cast<T>(item);
|
|
||||||
if (T found = item->findAnyChild<T>(pred))
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeItem(const TreeItem &) = delete;
|
TreeItem(const TreeItem &) = delete;
|
||||||
@@ -156,17 +107,20 @@ public:
|
|||||||
|
|
||||||
template <typename Predicate>
|
template <typename Predicate>
|
||||||
void forAllChildren(const Predicate &pred) const {
|
void forAllChildren(const Predicate &pred) const {
|
||||||
return TreeItem::forAllChildren<ChildType *, Predicate>(pred);
|
const auto pred0 = [pred](TreeItem *treeItem) { pred(static_cast<ChildType *>(treeItem)); };
|
||||||
|
TreeItem::forAllChildren(pred0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Predicate>
|
template <typename Predicate>
|
||||||
void forFirstLevelChildren(Predicate pred) const {
|
void forFirstLevelChildren(Predicate pred) const {
|
||||||
return TreeItem::forChildrenAtLevel<ChildType *, Predicate>(1, pred);
|
const auto pred0 = [pred](TreeItem *treeItem) { pred(static_cast<ChildType *>(treeItem)); };
|
||||||
|
TreeItem::forChildrenAtLevel(1, pred0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Predicate>
|
template <typename Predicate>
|
||||||
ChildType *findFirstLevelChild(Predicate pred) const {
|
ChildType *findFirstLevelChild(Predicate pred) const {
|
||||||
return TreeItem::findChildAtLevel<ChildType *, Predicate>(1, pred);
|
const auto pred0 = [pred](TreeItem *treeItem) { return pred(static_cast<ChildType *>(treeItem)); };
|
||||||
|
return static_cast<ChildType *>(TreeItem::findChildAtLevel(1, pred0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ParentType *parent() const {
|
ParentType *parent() const {
|
||||||
@@ -257,7 +211,6 @@ template<int N> struct SelectType<N>
|
|||||||
using Type = TreeItem;
|
using Type = TreeItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// BestItem<T0, T1, T2, ... > selects T0 if all types are equal and 'TreeItem' otherwise
|
// BestItem<T0, T1, T2, ... > selects T0 if all types are equal and 'TreeItem' otherwise
|
||||||
template<typename ...All> struct BestItemType;
|
template<typename ...All> struct BestItemType;
|
||||||
|
|
||||||
@@ -310,12 +263,16 @@ public:
|
|||||||
|
|
||||||
template <int Level, class Predicate>
|
template <int Level, class Predicate>
|
||||||
void forItemsAtLevel(const Predicate &pred) const {
|
void forItemsAtLevel(const Predicate &pred) const {
|
||||||
m_root->forChildrenAtLevel<typename Internal::SelectType<Level, LevelItemTypes...>::Type *>(Level, pred);
|
using ItemType = typename Internal::SelectType<Level, LevelItemTypes...>::Type;
|
||||||
|
const auto pred0 = [pred](TreeItem *treeItem) { pred(static_cast<ItemType *>(treeItem)); };
|
||||||
|
m_root->forChildrenAtLevel(Level, pred0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int Level, class Predicate>
|
template <int Level, class Predicate>
|
||||||
typename Internal::SelectType<Level, LevelItemTypes...>::Type *findItemAtLevel(const Predicate &pred) const {
|
typename Internal::SelectType<Level, LevelItemTypes...>::Type *findItemAtLevel(const Predicate &pred) const {
|
||||||
return m_root->findChildAtLevel<typename Internal::SelectType<Level, LevelItemTypes...>::Type *>(Level, pred);
|
using ItemType = typename Internal::SelectType<Level, LevelItemTypes...>::Type;
|
||||||
|
const auto pred0 = [pred](TreeItem *treeItem) { return pred(static_cast<ItemType *>(treeItem)); };
|
||||||
|
return static_cast<ItemType *>(m_root->findChildAtLevel(Level, pred0));
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem *rootItem() const {
|
RootItem *rootItem() const {
|
||||||
@@ -335,20 +292,20 @@ public:
|
|||||||
|
|
||||||
template <class Predicate>
|
template <class Predicate>
|
||||||
BestItem *findNonRooItem(const Predicate &pred) const {
|
BestItem *findNonRooItem(const Predicate &pred) const {
|
||||||
TreeItem *root = this->rootItem();
|
const auto pred0 = [pred](TreeItem *treeItem) -> bool { return pred(static_cast<BestItem *>(treeItem)); };
|
||||||
return root->findAnyChild<BestItem *>(pred);
|
return static_cast<BestItem *>(m_root->findAnyChild(pred0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Predicate>
|
template <class Predicate>
|
||||||
void forSelectedItems(const Predicate &pred) const {
|
void forSelectedItems(const Predicate &pred) const {
|
||||||
TreeItem *root = this->rootItem();
|
const auto pred0 = [pred](TreeItem *treeItem) -> bool { return pred(static_cast<BestItem *>(treeItem)); };
|
||||||
root->forSelectedChildren<BestItem *, Predicate>(pred);
|
m_root->forSelectedChildren(pred0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Predicate>
|
template <class Predicate>
|
||||||
void forAllItems(const Predicate &pred) const {
|
void forAllItems(const Predicate &pred) const {
|
||||||
TreeItem *root = this->rootItem();
|
const auto pred0 = [pred](TreeItem *treeItem) -> void { pred(static_cast<BestItem *>(treeItem)); };
|
||||||
root->forAllChildren<BestItem *, Predicate>(pred);
|
m_root->forAllChildren(pred0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BestItem *itemForIndex(const QModelIndex &idx) const {
|
BestItem *itemForIndex(const QModelIndex &idx) const {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
|
|
||||||
case Qt::DecorationRole: {
|
case Qt::DecorationRole: {
|
||||||
QVariant icon;
|
QVariant icon;
|
||||||
forChildrenAtLevel<TreeItem *>(2, [this, &icon](TreeItem *item) {
|
forChildrenAtLevel(2, [this, &icon](TreeItem *item) {
|
||||||
QVariant sicon = item->data(0, Qt::DecorationRole);
|
QVariant sicon = item->data(0, Qt::DecorationRole);
|
||||||
if (sicon.isValid())
|
if (sicon.isValid())
|
||||||
icon = sicon;
|
icon = sicon;
|
||||||
|
|||||||
@@ -293,8 +293,8 @@ void ToolChainOptionsWidget::removeToolChain(ToolChain *tc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
StaticTreeItem *parent = parentForToolChain(tc);
|
StaticTreeItem *parent = parentForToolChain(tc);
|
||||||
auto item = parent->findChildAtLevel<ToolChainTreeItem *>(1, [tc](ToolChainTreeItem *item) {
|
auto item = parent->findChildAtLevel(1, [tc](TreeItem *item) {
|
||||||
return item->toolChain == tc;
|
return static_cast<ToolChainTreeItem *>(item)->toolChain == tc;
|
||||||
});
|
});
|
||||||
m_model.destroyItem(item);
|
m_model.destroyItem(item);
|
||||||
|
|
||||||
|
|||||||
@@ -1415,9 +1415,9 @@ void tst_Dumpers::dumper()
|
|||||||
//qDebug() << "NUM CHECKS" << data.checks.size();
|
//qDebug() << "NUM CHECKS" << data.checks.size();
|
||||||
Check check = data.checks.at(i);
|
Check check = data.checks.at(i);
|
||||||
QString iname = "local." + check.iname;
|
QString iname = "local." + check.iname;
|
||||||
WatchItem *item = local.findAnyChild<WatchItem *>([iname](WatchItem *item) {
|
WatchItem *item = static_cast<WatchItem *>(local.findAnyChild([iname](Utils::TreeItem *item) {
|
||||||
return item->internalName() == iname;
|
return static_cast<WatchItem *>(item)->internalName() == iname;
|
||||||
});
|
}));
|
||||||
if (item) {
|
if (item) {
|
||||||
seenINames.insert(iname);
|
seenINames.insert(iname);
|
||||||
//qDebug() << "CHECKS" << i << check.iname;
|
//qDebug() << "CHECKS" << i << check.iname;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ static int countLevelItems(TreeItem *base, int level)
|
|||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int bl = base->level();
|
int bl = base->level();
|
||||||
base->forAllChildren<TreeItem *>([level, bl, &n](TreeItem *item) {
|
base->forAllChildren([level, bl, &n](TreeItem *item) {
|
||||||
if (item->level() == bl + level)
|
if (item->level() == bl + level)
|
||||||
++n;
|
++n;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user