KDStateMachineEditor API Documentation 2.1
Loading...
Searching...
No Matches
objecttreemodel.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDAB State Machine Editor Library.
3
4 SPDX-FileCopyrightText: 2014 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: Kevin Funk <kevin.funk@kdab.com>
6
7 SPDX-License-Identifier: LGPL-2.1-only OR LicenseRef-KDAB-KDStateMachineEditor
8
9 Licensees holding valid commercial KDAB State Machine Editor Library
10 licenses may use this file in accordance with the KDAB State Machine Editor
11 Library License Agreement provided with the Software.
12
13 Contact info@kdab.com if any conditions of this licensing are not clear to you.
14*/
15
16#include "objecttreemodel.h"
17
18#include "debug.h"
19
20using namespace KDSME;
21
22namespace KDSME {
23
24class ObjectTreeModelPrivate
25{
26 explicit ObjectTreeModelPrivate(ObjectTreeModel *qq)
27 : q_ptr(qq)
28 {
29 }
30
31 Q_DECLARE_PUBLIC(ObjectTreeModel)
32 ObjectTreeModel *const q_ptr;
33 QList<QObject *> m_rootObjects;
34
35 QList<QObject *> children(QObject *parent) const;
36
37 [[nodiscard]] QObject *mapModelIndex2QObject(const QModelIndex &index) const;
38 QModelIndex indexForObject(QObject *object) const;
39};
40
41}
42
43QList<QObject *> ObjectTreeModelPrivate::children(QObject *parent) const
44{
45 if (!parent) {
46 return m_rootObjects;
47 }
48 return parent->children();
49}
50
51QObject *ObjectTreeModelPrivate::mapModelIndex2QObject(const QModelIndex &index) const
52{
53 if (!index.isValid()) {
54 return nullptr;
55 }
56
57 auto *parent = reinterpret_cast<QObject *>(index.internalPointer());
58 if (!parent) {
59 return m_rootObjects[index.row()];
60 }
61 QObjectList c = children(parent);
62 return c[index.row()];
63}
64
65QModelIndex ObjectTreeModelPrivate::indexForObject(QObject *object) const
66{
67 if (!object) {
68 return QModelIndex();
69 }
70
71 Q_Q(const ObjectTreeModel);
72 int row = static_cast<int>(m_rootObjects.indexOf(object));
73 if (row != -1) {
74 return q->index(row, 0, QModelIndex());
75 }
76
77 row = static_cast<int>(children(object->parent()).indexOf(object));
78 if (row == -1) {
79 return {};
80 }
81 return q->index(row, 0, indexForObject(object->parent()));
82}
83
84ObjectTreeModel::AppendOperation::AppendOperation(ObjectTreeModel *model, QObject *parent, int count, int index)
85 : m_model(model)
86{
87 Q_ASSERT(m_model);
88 const QModelIndex parentIndex = m_model->indexForObject(parent);
89 Q_ASSERT(parentIndex.isValid());
90 const int first = index >= 0 ? index : m_model->rowCount(parentIndex);
91 const int last = first + count - 1;
92 Q_ASSERT(first >= 0 && last >= 0);
93 Q_ASSERT(first <= last);
94
95 m_model->beginInsertRows(parentIndex, first, last);
96}
97
99{
100 m_model->endInsertRows();
101}
102
104 : m_model(model)
105{
106 Q_ASSERT(m_model);
107 Q_ASSERT(object);
108 Q_ASSERT(object->parent());
109 Q_ASSERT(!m_model->rootObjects().contains(object));
110 const QModelIndex indexObj = m_model->indexForObject(object);
111 const QModelIndex parentIndex = m_model->indexForObject(object->parent());
112 m_model->beginRemoveRows(parentIndex, indexObj.row(), indexObj.row());
113}
114
116{
117 m_model->endRemoveRows();
118}
119
121 : m_model(model)
122{
123 if (m_model) {
124 m_model->beginResetModel();
125 }
126}
127
129{
130 if (m_model) {
131 m_model->endResetModel();
132 }
133}
134
136 : m_model(model)
137{
138 // some sanity checks
139 if (!object || (object->parent() == newParent) || (object == newParent)) {
140 m_model = nullptr;
141 }
142
143 if (m_model) {
144 const QModelIndex indexObj = m_model->indexForObject(object);
145 QObject *parentObj = object->parent(); // cppcheck-suppress constVariablePointer
146 const QModelIndex parentIndex = m_model->indexForObject(parentObj);
147 const QModelIndex destinationParentIndex = m_model->indexForObject(newParent);
148 Q_ASSERT(destinationParentIndex.isValid());
149 const bool success = m_model->beginMoveRows(parentIndex, indexObj.row(), indexObj.row(), destinationParentIndex, m_model->rowCount(destinationParentIndex));
150 Q_ASSERT(success);
151 Q_UNUSED(success);
152 }
153}
154
156{
157 if (m_model) {
158 m_model->endMoveRows();
159 }
160}
161
163 : QAbstractItemModel(parent)
164 , d_ptr(new ObjectTreeModelPrivate(this))
165{
166}
167
172
173QHash<int, QByteArray> ObjectTreeModel::roleNames() const
174{
175 QHash<int, QByteArray> roleNames = QAbstractItemModel::roleNames();
176 roleNames.insert(ObjectRole, "object");
177 roleNames.insert(ObjectIdRole, "objectid");
178 return roleNames;
179}
180
182{
183 Q_D(ObjectTreeModel);
184 if (!object || d->m_rootObjects.contains(object)) {
185 return;
186 }
187
188 const int row = static_cast<int>(d->m_rootObjects.count());
189 beginInsertRows({}, row, row);
190 d->m_rootObjects << object;
191 endInsertRows();
192}
193
194QList<QObject *> ObjectTreeModel::rootObjects() const
195{
196 Q_D(const ObjectTreeModel);
197 return d->m_rootObjects;
198}
199
200void ObjectTreeModel::setRootObject(QObject *rootObject)
201{
202 setRootObjects(QList<QObject *>() << rootObject);
203}
204
205void ObjectTreeModel::setRootObjects(const QList<QObject *> &rootObjects)
206{
207 Q_D(ObjectTreeModel);
208 beginResetModel();
209 d->m_rootObjects.clear();
210 for (QObject *object : rootObjects) { // cppcheck-suppress constVariablePointer
211 if (object)
212 d->m_rootObjects << object;
213 }
214 endResetModel();
215}
216
218{
219 Q_D(ObjectTreeModel);
220 beginResetModel();
221 d->m_rootObjects.clear();
222 endResetModel();
223}
224
225QVariant ObjectTreeModel::data(const QModelIndex &index, int role) const
226{
227 if (!index.isValid()) {
228 return {};
229 }
230
231 Q_D(const ObjectTreeModel);
232 QObject *obj = d->mapModelIndex2QObject(index);
233 Q_ASSERT(obj);
234 switch (role) {
235 case Qt::DisplayRole:
236 return QString { u"0x" + QString::number(reinterpret_cast<quint64>(obj), 16) };
237 case ObjectRole:
238 return QVariant::fromValue(obj);
239 case ObjectIdRole:
240 return reinterpret_cast<quint64>(obj);
241 default:
242 return {};
243 }
244}
245
246int ObjectTreeModel::columnCount(const QModelIndex &parent) const
247{
248 Q_UNUSED(parent);
249 return 1;
250}
251
252int ObjectTreeModel::rowCount(const QModelIndex &parent) const
253{
254 Q_D(const ObjectTreeModel);
255 return static_cast<int>(d->children(d->mapModelIndex2QObject(parent)).count());
256}
257
258QModelIndex ObjectTreeModel::index(int row, int column, const QModelIndex &parent) const
259{
260 Q_D(const ObjectTreeModel);
261 if (row < 0 || column < 0 || column >= columnCount(parent)) {
262 return QModelIndex();
263 }
264
265 if (!parent.isValid() && row < rowCount()) {
266 return createIndex(row, column, nullptr);
267 }
268
269 QObject *parentObject = d->mapModelIndex2QObject(parent);
270 if (!parentObject)
271 return QModelIndex();
272 const QObjectList c = d->children(parentObject);
273 if (row >= c.size()) {
274 return QModelIndex();
275 }
276
277 return createIndex(row, column, parentObject);
278}
279
280QModelIndex ObjectTreeModel::indexForObject(QObject *object) const
281{
282 Q_D(const ObjectTreeModel);
283 return d->indexForObject(object);
284}
285
286QModelIndex ObjectTreeModel::parent(const QModelIndex &index) const
287{
288 Q_D(const ObjectTreeModel);
289 if (!index.isValid()) {
290 return QModelIndex();
291 }
292
293 QObject *object = d->mapModelIndex2QObject(index);
294 QObject *parent = object->parent();
295 if (!parent) {
296 return QModelIndex();
297 }
298
299 QObject *grandParent = parent->parent();
300 const int row = static_cast<int>(d->children(grandParent).indexOf(parent));
301 return createIndex(row, 0, grandParent);
302}
AppendOperation(ObjectTreeModel *model, QObject *parent, int count=1, int index=-1)
RemoveOperation(ObjectTreeModel *model, QObject *object)
ReparentOperation(ObjectTreeModel *model, QObject *object, QObject *newParent)
ObjectTreeModelPrivate *const d_ptr
QModelIndex indexForObject(QObject *object) const
void appendRootObject(QObject *object)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void setRootObject(QObject *rootObject)
ObjectTreeModel(QObject *parent=nullptr)
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QList< QObject * > rootObjects() const
QModelIndex index(int row, int column, const QModelIndex &parent={}) const override
QModelIndex parent(const QModelIndex &index) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QHash< int, QByteArray > roleNames() const override
void setRootObjects(const QList< QObject * > &rootObjects)
@ ObjectIdRole
return quint64
@ ObjectRole
return QObject*

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDStateMachineEditor
Create Qt State Machine metacode using a graphical user interface
https://github.com/KDAB/KDStateMachineEditor
Generated on Tue Jul 15 2025 15:21:47 for KDStateMachineEditor API Documentation by doxygen 1.9.8