47 auto invalidate = [
this] {
48 m_rowCache[0].parent =
nullptr;
49 m_rowCache[1].parent =
nullptr;
51 connect(
this, &QAbstractItemModel::rowsInserted,
this, invalidate);
52 connect(
this, &QAbstractItemModel::rowsRemoved,
this, invalidate);
53 connect(
this, &QAbstractItemModel::rowsMoved,
this, invalidate);
54 connect(
this, &QAbstractItemModel::modelReset,
this, invalidate);
55 connect(
this, &QAbstractItemModel::layoutChanged,
this, invalidate);
58 using node_type = NodeType;
60 virtual NodeType& rootNode() = 0;
61 virtual const NodeType& rootNode()
const = 0;
63 NodeType& nodeFromModelIndex(
const QModelIndex& index)
const
65 auto n = index.isValid() ?
static_cast<NodeType*
>(index.internalPointer())
66 :
const_cast<NodeType*
>(&rootNode());
72 QModelIndex parent(
const QModelIndex& index)
const final override
76 if(index.model() !=
this)
79 const auto& node = nodeFromModelIndex(index);
80 auto parentNode = node.parent();
85 auto grandparentNode = parentNode->parent();
90 const int rowParent = grandparentNode->indexOfChild(parentNode);
94 return createIndex(rowParent, 0, parentNode);
97 QModelIndex index(
int row,
int column,
const QModelIndex& parent)
const final override
99 if(!hasIndex(row, column, parent))
100 return QModelIndex();
102 auto& parentItem = nodeFromModelIndex(parent);
103 if(!parentItem.hasChild(row))
104 return QModelIndex();
113 auto* cache = &m_rowCache[0];
114 if(m_rowCache[0].parent != &parentItem)
116 if(m_rowCache[1].parent == &parentItem)
118 cache = &m_rowCache[1];
123 cache = (m_lastUsed == 0) ? &m_rowCache[1] : &m_rowCache[0];
124 cache->parent = &parentItem;
126 cache->rows.reserve(parentItem.childCount());
127 for(
auto& child : parentItem)
128 cache->rows.push_back(&child);
131 m_lastUsed = int(cache - &m_rowCache[0]);
132 return createIndex(row, column, cache->rows[row]);
135 int rowCount(
const QModelIndex& parent)
const final override
137 if(parent.column() > 0)
140 const auto& parentNode = nodeFromModelIndex(parent);
141 return parentNode.childCount();
144 bool hasChildren(
const QModelIndex& parent)
const final override
146 const auto& parentNode = nodeFromModelIndex(parent);
147 return parentNode.childCount() > 0;
154 std::vector<NodeType*> rows;
156 mutable RowCache m_rowCache[2];
157 mutable int m_lastUsed{};
void iterate(const QModelIndex &idx, const F &f)
idx: should be the root index of the view
Definition TreeNodeItemModel.hpp:20