Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtreewidgetitemiterator.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <private/qtreewidgetitemiterator_p.h>
5#include "qtreewidget.h"
6#include "qtreewidget_p.h"
7#include "qwidgetitemdata_p.h"
8
10
39 : d_ptr(new QTreeWidgetItemIteratorPrivate(*(it.d_ptr))),
40 current(it.current), flags(it.flags)
41{
43 Q_ASSERT(d->m_model);
44 d->m_model->iterators.append(this);
45}
46
57: current(nullptr), flags(flags)
58{
60 QTreeModel *model = qobject_cast<QTreeModel*>(widget->model());
62 d_ptr.reset(new QTreeWidgetItemIteratorPrivate(this, model));
63 model->iterators.append(this);
64 if (!model->rootItem->children.isEmpty()) current = model->rootItem->child(0);
65 if (current && !matchesFlags(current))
66 ++(*this);
67}
68
79 : d_ptr(new QTreeWidgetItemIteratorPrivate(
81 current(item), flags(flags)
82{
85 QTreeModel *model = qobject_cast<QTreeModel*>(item->view->model());
87 model->iterators.append(this);
88
89 // Initialize m_currentIndex and m_parentIndex as it would be if we had traversed from
90 // the beginning.
91 QTreeWidgetItem *parent = item;
92 parent = parent->parent();
93 QTreeWidgetItem *root = d->m_model->rootItem;
94 d->m_currentIndex = (parent ? parent : root)->indexOfChild(item);
95
96 while (parent) {
97 QTreeWidgetItem *itm = parent;
98 parent = parent->parent();
99 const int index = (parent ? parent : root)->indexOfChild(itm);
100 d->m_parentIndex.prepend(index);
101 }
102
103 if (current && !matchesFlags(current))
104 ++(*this);
105}
106
112{
113 d_func()->m_model->iterators.removeAll(this);
114}
115
122{
124 if (d_func()->m_model != it.d_func()->m_model) {
125 d_func()->m_model->iterators.removeAll(this);
126 it.d_func()->m_model->iterators.append(this);
127 }
128 current = it.current;
129 flags = it.flags;
130 d->operator=(*it.d_func());
131 return *this;
132}
133
141{
142 if (current)
143 do {
144 current = d_func()->next(current);
145 } while (current && !matchesFlags(current));
146 return *this;
147}
148
156{
157 if (current)
158 do {
159 current = d_func()->previous(current);
160 } while (current && !matchesFlags(current));
161 return *this;
162}
163
167bool QTreeWidgetItemIterator::matchesFlags(const QTreeWidgetItem *item) const
168{
169 if (!item)
170 return false;
171
172 if (flags == All)
173 return true;
174
175 {
176 Qt::ItemFlags itemFlags = item->flags();
177 if ((flags & Selectable) && !(itemFlags & Qt::ItemIsSelectable))
178 return false;
179 if ((flags & NotSelectable) && (itemFlags & Qt::ItemIsSelectable))
180 return false;
181 if ((flags & DragEnabled) && !(itemFlags & Qt::ItemIsDragEnabled))
182 return false;
183 if ((flags & DragDisabled) && (itemFlags & Qt::ItemIsDragEnabled))
184 return false;
185 if ((flags & DropEnabled) && !(itemFlags & Qt::ItemIsDropEnabled))
186 return false;
187 if ((flags & DropDisabled) && (itemFlags & Qt::ItemIsDropEnabled))
188 return false;
189 if ((flags & Enabled) && !(itemFlags & Qt::ItemIsEnabled))
190 return false;
191 if ((flags & Disabled) && (itemFlags & Qt::ItemIsEnabled))
192 return false;
193 if ((flags & Editable) && !(itemFlags & Qt::ItemIsEditable))
194 return false;
195 if ((flags & NotEditable) && (itemFlags & Qt::ItemIsEditable))
196 return false;
197 }
198
199 if (flags & (Checked|NotChecked)) {
200 // ### We only test the check state for column 0
201 Qt::CheckState check = item->checkState(0);
202 // PartiallyChecked matches as Checked.
203 if ((flags & Checked) && (check == Qt::Unchecked))
204 return false;
205 if ((flags & NotChecked) && (check != Qt::Unchecked))
206 return false;
207 }
208
209 if ((flags & HasChildren) && !item->childCount())
210 return false;
211 if ((flags & NoChildren) && item->childCount())
212 return false;
213
214 if ((flags & Hidden) && !item->isHidden())
215 return false;
216 if ((flags & NotHidden) && item->isHidden())
217 return false;
218
219 if ((flags & Selected) && !item->isSelected())
220 return false;
221 if ((flags & Unselected) && item->isSelected())
222 return false;
223
224 return true;
225}
226
227/*
228 * Implementation of QTreeWidgetItemIteratorPrivate
229 */
230QTreeWidgetItem* QTreeWidgetItemIteratorPrivate::nextSibling(const QTreeWidgetItem* item) const
231{
232 Q_ASSERT(item);
233 QTreeWidgetItem *next = nullptr;
234 if (QTreeWidgetItem *par = item->parent()) {
235 int i = par->indexOfChild(const_cast<QTreeWidgetItem*>(item));
236 next = par->child(i + 1);
237 } else {
238 QTreeWidget *tw = item->treeWidget();
239 int i = tw->indexOfTopLevelItem(const_cast<QTreeWidgetItem*>(item));
240 next = tw->topLevelItem(i + 1);
241 }
242 return next;
243}
244
245QTreeWidgetItem *QTreeWidgetItemIteratorPrivate::next(const QTreeWidgetItem *current)
246{
247 if (!current) return nullptr;
248
249 QTreeWidgetItem *next = nullptr;
250 if (current->childCount()) {
251 // walk the child
252 m_parentIndex.push(m_currentIndex);
253 m_currentIndex = 0;
254 next = current->child(0);
255 } else {
256 // walk the sibling
257 QTreeWidgetItem *parent = current->parent();
258 next = parent ? parent->child(m_currentIndex + 1)
259 : m_model->rootItem->child(m_currentIndex + 1);
260 while (!next && parent) {
261 // if we had no sibling walk up the parent and try the sibling of that
262 parent = parent->parent();
263 m_currentIndex = m_parentIndex.pop();
264 next = parent ? parent->child(m_currentIndex + 1)
265 : m_model->rootItem->child(m_currentIndex + 1);
266 }
267 if (next) ++(m_currentIndex);
268 }
269 return next;
270}
271
272QTreeWidgetItem *QTreeWidgetItemIteratorPrivate::previous(const QTreeWidgetItem *current)
273{
274 if (!current) return nullptr;
275
276 QTreeWidgetItem *prev = nullptr;
277 // walk the previous sibling
278 QTreeWidgetItem *parent = current->parent();
279 prev = parent ? parent->child(m_currentIndex - 1)
280 : m_model->rootItem->child(m_currentIndex - 1);
281 if (prev) {
282 // Yes, we had a previous sibling but we need go down to the last leafnode.
283 --m_currentIndex;
284 while (prev && prev->childCount()) {
285 m_parentIndex.push(m_currentIndex);
286 m_currentIndex = prev->childCount() - 1;
287 prev = prev->child(m_currentIndex);
288 }
289 } else if (parent) {
290 m_currentIndex = m_parentIndex.pop();
291 prev = parent;
292 }
293 return prev;
294}
295
296void QTreeWidgetItemIteratorPrivate::ensureValidIterator(const QTreeWidgetItem *itemToBeRemoved)
297{
299 Q_ASSERT(itemToBeRemoved);
300
301 if (!q->current) return;
302 QTreeWidgetItem *nextItem = q->current;
303
304 // Do not walk to the ancestor to find the other item if they have the same parent.
305 if (nextItem->parent() != itemToBeRemoved->parent()) {
306 while (nextItem->parent() && nextItem != itemToBeRemoved) {
307 nextItem = nextItem->parent();
308 }
309 }
310 // If the item to be removed is an ancestor of the current iterator item,
311 // we need to adjust the iterator.
312 if (nextItem == itemToBeRemoved) {
313 QTreeWidgetItem *parent = nextItem;
314 nextItem = nullptr;
315 while (parent && !nextItem) {
316 nextItem = nextSibling(parent);
317 parent = parent->parent();
318 }
319 if (nextItem) {
320 // Ooooh... Set the iterator to the next valid item
321 *q = QTreeWidgetItemIterator(nextItem, q->flags);
322 if (!(q->matchesFlags(nextItem))) ++(*q);
323 } else {
324 // set it to null.
325 q->current = nullptr;
326 m_parentIndex.clear();
327 return;
328 }
329 }
330 if (nextItem->parent() == itemToBeRemoved->parent()) {
331 // They have the same parent, i.e. we have to adjust the m_currentIndex member of the iterator
332 // if the deleted item is to the left of the nextItem.
333
334 QTreeWidgetItem *par = itemToBeRemoved->parent(); // We know they both have the same parent.
335 QTreeWidget *tw = itemToBeRemoved->treeWidget(); // ..and widget
336 int indexOfItemToBeRemoved = par ? par->indexOfChild(const_cast<QTreeWidgetItem *>(itemToBeRemoved))
337 : tw->indexOfTopLevelItem(const_cast<QTreeWidgetItem *>(itemToBeRemoved));
338 int indexOfNextItem = par ? par->indexOfChild(nextItem) : tw->indexOfTopLevelItem(nextItem);
339
340 if (indexOfItemToBeRemoved <= indexOfNextItem) {
341 // A sibling to the left of us was deleted, adjust the m_currentIndex member of the iterator.
342 // Note that the m_currentIndex will be wrong until the item is actually removed!
343 m_currentIndex--;
344 }
345 }
346}
347
bool isSelected() const
Returns true if this item is selected; otherwise, false is returned.
GraphicsItemFlags flags() const
Returns this item's flags.
bool isEmpty() const noexcept
Definition qlist.h:401
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:201
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
QTreeWidgetItemIterator(const QTreeWidgetItemIterator &it)
Constructs an iterator for the same QTreeWidget as it.
QTreeWidgetItemIterator & operator++()
The prefix {++} operator ({++it}) advances the iterator to the next matching item and returns a refer...
~QTreeWidgetItemIterator()
Destroys the iterator.
QTreeWidgetItemIterator & operator--()
The prefix {–} operator ({–it}) advances the iterator to the previous matching item and returns a ref...
QTreeWidgetItemIterator & operator=(const QTreeWidgetItemIterator &it)
Assignment.
The QTreeWidgetItem class provides an item for use with the QTreeWidget convenience class.
Definition qtreewidget.h:23
QTreeWidgetItem * child(int index) const
Returns the item at the given index in the list of the item's children.
QTreeWidgetItem * parent() const
Returns the item's parent.
int childCount() const
Returns the number of child items.
int indexOfChild(QTreeWidgetItem *child) const
Returns the index of the given child in the item's list of children.
The QTreeWidget class provides a tree view that uses a predefined tree model.
#define this
Definition dialogs.cpp:9
QOpenGLWidget * widget
[1]
QSet< QString >::iterator it
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
CheckState
@ Unchecked
@ ItemIsEditable
@ ItemIsDragEnabled
@ ItemIsSelectable
@ ItemIsEnabled
@ ItemIsDropEnabled
T qobject_cast(QObject *object)
\variable QObject::staticMetaObject
Definition qobject.h:419
GLuint index
[2]
GLbitfield flags
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QSqlQueryModel * model
[16]
QObject::connect nullptr
QGraphicsItem * item
QQuickView * view
[0]