Qt 4.8
qtreewidgetitemiterator.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <private/qtreewidgetitemiterator_p.h>
43 #include "qtreewidget.h"
44 #include "qtreewidget_p.h"
45 #include "qwidgetitemdata_p.h"
46 
47 #ifndef QT_NO_TREEWIDGET
48 
50 
81  current(it.current), flags(it.flags)
82 {
84  Q_ASSERT(d->m_model);
85  d->m_model->iterators.append(this);
86 }
87 
98 : current(0), flags(flags)
99 {
100  Q_ASSERT(widget);
101  QTreeModel *model = qobject_cast<QTreeModel*>(widget->model());
102  Q_ASSERT(model);
103  d_ptr.reset(new QTreeWidgetItemIteratorPrivate(this, model));
104  model->iterators.append(this);
105  if (!model->rootItem->children.isEmpty()) current = model->rootItem->child(0);
106  if (current && !matchesFlags(current))
107  ++(*this);
108 }
109 
121  this, qobject_cast<QTreeModel*>(item->view->model()))),
122  current(item), flags(flags)
123 {
125  Q_ASSERT(item);
126  QTreeModel *model = qobject_cast<QTreeModel*>(item->view->model());
127  Q_ASSERT(model);
128  model->iterators.append(this);
129 
130  // Initialize m_currentIndex and m_parentIndex as it would be if we had traversed from
131  // the beginning.
133  parent = parent->parent();
134  QTreeWidgetItem *root = d->m_model->rootItem;
135  d->m_currentIndex = (parent ? parent : root)->indexOfChild(item);
136 
137  while (parent) {
138  QTreeWidgetItem *itm = parent;
139  parent = parent->parent();
140  const int index = (parent ? parent : root)->indexOfChild(itm);
141  d->m_parentIndex.prepend(index);
142  }
143 
144  if (current && !matchesFlags(current))
145  ++(*this);
146 }
147 
153 {
154  d_func()->m_model->iterators.removeAll(this);
155 }
156 
163 {
165  if (d_func()->m_model != it.d_func()->m_model) {
166  d_func()->m_model->iterators.removeAll(this);
167  it.d_func()->m_model->iterators.append(this);
168  }
169  current = it.current;
170  flags = it.flags;
171  d->operator=(*it.d_func());
172  return *this;
173 }
174 
182 {
183  if (current)
184  do {
185  current = d_func()->next(current);
186  } while (current && !matchesFlags(current));
187  return *this;
188 }
189 
197 {
198  if (current)
199  do {
200  current = d_func()->previous(current);
201  } while (current && !matchesFlags(current));
202  return *this;
203 }
204 
209 {
210  if (!item)
211  return false;
212 
213  if (flags == All)
214  return true;
215 
216  {
217  Qt::ItemFlags itemFlags = item->flags();
218  if ((flags & Selectable) && !(itemFlags & Qt::ItemIsSelectable))
219  return false;
220  if ((flags & NotSelectable) && (itemFlags & Qt::ItemIsSelectable))
221  return false;
222  if ((flags & DragEnabled) && !(itemFlags & Qt::ItemIsDragEnabled))
223  return false;
224  if ((flags & DragDisabled) && (itemFlags & Qt::ItemIsDragEnabled))
225  return false;
226  if ((flags & DropEnabled) && !(itemFlags & Qt::ItemIsDropEnabled))
227  return false;
228  if ((flags & DropDisabled) && (itemFlags & Qt::ItemIsDropEnabled))
229  return false;
230  if ((flags & Enabled) && !(itemFlags & Qt::ItemIsEnabled))
231  return false;
232  if ((flags & Disabled) && (itemFlags & Qt::ItemIsEnabled))
233  return false;
234  if ((flags & Editable) && !(itemFlags & Qt::ItemIsEditable))
235  return false;
236  if ((flags & NotEditable) && (itemFlags & Qt::ItemIsEditable))
237  return false;
238  }
239 
240  if (flags & (Checked|NotChecked)) {
241  // ### We only test the check state for column 0
242  Qt::CheckState check = item->checkState(0);
243  // PartiallyChecked matches as Checked.
244  if ((flags & Checked) && (check == Qt::Unchecked))
245  return false;
246  if ((flags & NotChecked) && (check != Qt::Unchecked))
247  return false;
248  }
249 
250  if ((flags & HasChildren) && !item->childCount())
251  return false;
252  if ((flags & NoChildren) && item->childCount())
253  return false;
254 
255  if ((flags & Hidden) && !item->isHidden())
256  return false;
257  if ((flags & NotHidden) && item->isHidden())
258  return false;
259 
260  if ((flags & Selected) && !item->isSelected())
261  return false;
262  if ((flags & Unselected) && item->isSelected())
263  return false;
264 
265  return true;
266 }
267 
268 /*
269  * Implementation of QTreeWidgetItemIteratorPrivate
270  */
272 {
273  Q_ASSERT(item);
274  QTreeWidgetItem *next = 0;
275  if (QTreeWidgetItem *par = item->parent()) {
276  int i = par->indexOfChild(const_cast<QTreeWidgetItem*>(item));
277  next = par->child(i + 1);
278  } else {
279  QTreeWidget *tw = item->treeWidget();
280  int i = tw->indexOfTopLevelItem(const_cast<QTreeWidgetItem*>(item));
281  next = tw->topLevelItem(i + 1);
282  }
283  return next;
284 }
285 
287 {
288  if (!current) return 0;
289 
290  QTreeWidgetItem *next = 0;
291  if (current->childCount()) {
292  // walk the child
293  m_parentIndex.push(m_currentIndex);
294  m_currentIndex = 0;
295  next = current->child(0);
296  } else {
297  // walk the sibling
298  QTreeWidgetItem *parent = current->parent();
299  next = parent ? parent->child(m_currentIndex + 1)
300  : m_model->rootItem->child(m_currentIndex + 1);
301  while (!next && parent) {
302  // if we had no sibling walk up the parent and try the sibling of that
303  parent = parent->parent();
304  m_currentIndex = m_parentIndex.pop();
305  next = parent ? parent->child(m_currentIndex + 1)
306  : m_model->rootItem->child(m_currentIndex + 1);
307  }
308  if (next) ++(m_currentIndex);
309  }
310  return next;
311 }
312 
314 {
315  if (!current) return 0;
316 
317  QTreeWidgetItem *prev = 0;
318  // walk the previous sibling
319  QTreeWidgetItem *parent = current->parent();
320  prev = parent ? parent->child(m_currentIndex - 1)
321  : m_model->rootItem->child(m_currentIndex - 1);
322  if (prev) {
323  // Yes, we had a previous sibling but we need go down to the last leafnode.
324  --m_currentIndex;
325  while (prev && prev->childCount()) {
326  m_parentIndex.push(m_currentIndex);
327  m_currentIndex = prev->childCount() - 1;
328  prev = prev->child(m_currentIndex);
329  }
330  } else if (parent) {
331  m_currentIndex = m_parentIndex.pop();
332  prev = parent;
333  }
334  return prev;
335 }
336 
338 {
340  Q_ASSERT(itemToBeRemoved);
341 
342  if (!q->current) return;
343  QTreeWidgetItem *nextItem = q->current;
344 
345  // Do not walk to the ancestor to find the other item if they have the same parent.
346  if (nextItem->parent() != itemToBeRemoved->parent()) {
347  while (nextItem->parent() && nextItem != itemToBeRemoved) {
348  nextItem = nextItem->parent();
349  }
350  }
351  // If the item to be removed is an ancestor of the current iterator item,
352  // we need to adjust the iterator.
353  if (nextItem == itemToBeRemoved) {
354  QTreeWidgetItem *parent = nextItem;
355  nextItem = 0;
356  while (parent && !nextItem) {
357  nextItem = nextSibling(parent);
358  parent = parent->parent();
359  }
360  if (nextItem) {
361  // Ooooh... Set the iterator to the next valid item
362  *q = QTreeWidgetItemIterator(nextItem, q->flags);
363  if (!(q->matchesFlags(nextItem))) ++(*q);
364  } else {
365  // set it to null.
366  q->current = 0;
367  m_parentIndex.clear();
368  return;
369  }
370  }
371  if (nextItem->parent() == itemToBeRemoved->parent()) {
372  // They have the same parent, i.e. we have to adjust the m_currentIndex member of the iterator
373  // if the deleted item is to the left of the nextItem.
374 
375  QTreeWidgetItem *par = itemToBeRemoved->parent(); // We know they both have the same parent.
376  QTreeWidget *tw = itemToBeRemoved->treeWidget(); // ..and widget
377  int indexOfItemToBeRemoved = par ? par->indexOfChild(const_cast<QTreeWidgetItem *>(itemToBeRemoved))
378  : tw->indexOfTopLevelItem(const_cast<QTreeWidgetItem *>(itemToBeRemoved));
379  int indexOfNextItem = par ? par->indexOfChild(nextItem) : tw->indexOfTopLevelItem(nextItem);
380 
381  if (indexOfItemToBeRemoved <= indexOfNextItem) {
382  // A sibling to the left of us was deleted, adjust the m_currentIndex member of the iterator.
383  // Note that the m_currentIndex will be wrong until the item is actually removed!
384  m_currentIndex--;
385  }
386  }
387 }
388 
474 
475 #endif // QT_NO_TREEWIDGET
T qobject_cast(QObject *object)
Definition: qobject.h:375
double d
Definition: qnumeric_p.h:62
CheckState
Definition: qnamespace.h:1607
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QPointer< QWidget > widget
Qt::ItemFlags flags() const
Returns the flags used to describe the item.
#define it(className, varName)
The QTreeWidget class provides a tree view that uses a predefined tree model.
Definition: qtreewidget.h:260
~QTreeWidgetItemIterator()
Destroys the iterator.
QTreeWidgetItem * item(const QModelIndex &index) const
Returns the tree view item corresponding to the index given.
bool isHidden() const
Returns true if the item is hidden, otherwise returns false.
Definition: qtreewidget.h:405
int childCount() const
Returns the number of child items.
Definition: qtreewidget.h:190
bool matchesFlags(const QTreeWidgetItem *item) const
QTreeWidgetItemIterator & operator++()
The prefix ++ operator (++it) advances the iterator to the next matching item and returns a reference...
QTreeWidget * view
Definition: qtreewidget.h:219
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_D(Class)
Definition: qglobal.h:2482
int indexOfTopLevelItem(QTreeWidgetItem *item)
QScopedPointer< QTreeWidgetItemIteratorPrivate > d_ptr
QTreeWidgetItem * nextSibling(const QTreeWidgetItem *item) const
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
#define Q_Q(Class)
Definition: qglobal.h:2483
QTreeWidgetItem * topLevelItem(int index) const
Returns the top level item at the given index, or 0 if the item does not exist.
Qt::CheckState checkState(int column) const
Returns the check state of the label in the given column.
Definition: qtreewidget.h:162
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
The QTreeWidgetItemIterator class provides a way to iterate over the items in a QTreeWidget instance...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QList< QTreeWidgetItemIterator * > iterators
QTreeWidgetItem * parent() const
Returns the item&#39;s parent.
Definition: qtreewidget.h:183
void ensureValidIterator(const QTreeWidgetItem *itemToBeRemoved)
QTreeWidget * view() const
Definition: qtreewidget_p.h:85
QTreeWidgetItem * rootItem
QTreeWidgetItemIterator(const QTreeWidgetItemIterator &it)
Constructs an iterator for the same QTreeWidget as it.
friend class QTreeWidgetItemIteratorPrivate
Definition: qtreewidget_p.h:79
bool isSelected() const
Returns true if the item is selected, otherwise returns false.
Definition: qtreewidget.h:399
void reset(T *other=0)
Deletes the existing object it is pointing to if any, and sets its pointer to other.
QTreeWidgetItem * next(const QTreeWidgetItem *current)
The QTreeWidgetItem class provides an item for use with the QTreeWidget convenience class...
Definition: qtreewidget.h:63
QTreeWidgetItem * child(int index) const
Returns the item at the given index in the list of the item&#39;s children.
Definition: qtreewidget.h:184
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
QTreeWidgetItemIterator & operator=(const QTreeWidgetItemIterator &it)
Assignment.
quint16 index
QScopedPointer< QObjectData > d_ptr
Definition: qobject.h:320
int indexOfChild(QTreeWidgetItem *child) const
Returns the index of the given child in the item&#39;s list of children.
Definition: qtreewidget.h:250
QTreeWidgetItemIterator & operator--()
The prefix – operator (–it) advances the iterator to the previous matching item and returns a refer...
QList< QTreeWidgetItem * > children
Definition: qtreewidget.h:222
QAbstractItemModel * model() const
Returns the model that this view is presenting.
Qt::ItemFlags flags(const QModelIndex &index) const
Returns the flags for the item referred to the given index.
QTreeWidgetItem * previous(const QTreeWidgetItem *current)
QTreeWidget * treeWidget() const
Returns the tree widget that contains the item.
Definition: qtreewidget.h:85