QtBase  v6.3.1
qtreewidget.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets 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 The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qtreewidget.h"
41 
42 #include <qheaderview.h>
43 #include <qpainter.h>
44 #include <qitemdelegate.h>
45 #include <qstack.h>
46 #include <qdebug.h>
47 #include <private/qtreewidget_p.h>
48 #include <private/qwidgetitemdata_p.h>
49 #include <private/qtreewidgetitemiterator_p.h>
50 
51 #include <QtCore/private/qduplicatetracker_p.h>
52 
53 #include <algorithm>
54 
56 
58 {
59 public:
60  inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
61  { return *i1 < *i2; }
62 };
63 
65 {
66 public:
67  inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
68  { return *i2 < *i1; }
69 };
70 
71 /*
72  \class QTreeModel
73  \brief The QTreeModel class manages the items stored in a tree view.
74 
75  \ingroup model-view
76  \inmodule QtWidgets
77 
78 */
79 
116  rootItem(new QTreeWidgetItem),
117  headerItem(new QTreeWidgetItem)
118 {
119  rootItem->view = parent;
120  rootItem->itemFlags = Qt::ItemIsDropEnabled;
121  headerItem->view = parent;
122  setColumnCount(columns);
123 }
124 
131  : QAbstractItemModel(dd, parent), rootItem(new QTreeWidgetItem), headerItem(new QTreeWidgetItem)
132 {
133  rootItem->view = parent;
134  rootItem->itemFlags = Qt::ItemIsDropEnabled;
135  headerItem->view = parent;
136 }
137 
145 {
146  clear();
147  headerItem->view = nullptr;
148  delete headerItem;
149  rootItem->view = nullptr;
150  delete rootItem;
151 }
152 
160 {
161  SkipSorting skipSorting(this);
162  beginResetModel();
163  for (int i = 0; i < rootItem->childCount(); ++i) {
164  QTreeWidgetItem *item = rootItem->children.at(i);
165  item->par = nullptr;
166  item->view = nullptr;
167  delete item;
168  }
169  rootItem->children.clear();
170  sortPendingTimer.stop();
171  endResetModel();
172 }
173 
180 void QTreeModel::setColumnCount(int columns)
181 {
182  SkipSorting skipSorting(this);
183  if (columns < 0)
184  return;
185  if (!headerItem) {
186  headerItem = new QTreeWidgetItem();
187  headerItem->view = view();
188  }
189  int count = columnCount();
190  if (count == columns)
191  return;
192 
193  if (columns < count) {
194  beginRemoveColumns(QModelIndex(), columns, count - 1);
195  headerItem->values.resize(columns);
197  } else {
198  beginInsertColumns(QModelIndex(), count, columns - 1);
199  headerItem->values.resize(columns);
200  for (int i = count; i < columns; ++i) {// insert data without emitting the dataChanged signal
201  headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
202  headerItem->d->display.append(QString::number(i + 1));
203  }
205  }
206 }
207 
217 {
218  if (!index.isValid())
219  return nullptr;
220  return static_cast<QTreeWidgetItem*>(index.internalPointer());
221 }
222 
231 {
232  executePendingSort();
233 
234  if (!item || (item == rootItem))
235  return QModelIndex();
236  const QTreeWidgetItem *par = item->parent();
237  QTreeWidgetItem *itm = const_cast<QTreeWidgetItem*>(item);
238  if (!par)
239  par = rootItem;
240  int row;
241  int guess = item->d->rowGuess;
242  if (guess >= 0
243  && par->children.count() > guess
244  && par->children.at(guess) == itm) {
245  row = guess;
246  } else {
247  row = par->children.lastIndexOf(itm);
248  itm->d->rowGuess = row;
249  }
250  return createIndex(row, column, itm);
251 }
252 
262 {
263  executePendingSort();
264 
265  int c = columnCount(parent);
266  if (row < 0 || column < 0 || column >= c)
267  return QModelIndex();
268 
269  QTreeWidgetItem *parentItem = parent.isValid() ? item(parent) : rootItem;
270  if (parentItem && row < parentItem->childCount()) {
271  QTreeWidgetItem *itm = parentItem->child(row);
272  if (itm)
273  return createIndex(row, column, itm);
274  return QModelIndex();
275  }
276 
277  return QModelIndex();
278 }
279 
289 {
290  SkipSorting skipSorting(this); //The reason we don't sort here is that this might be called from a valid QPersistentModelIndex
291  //We don't want it to become suddenly invalid
292 
293  if (!child.isValid())
294  return QModelIndex();
295  QTreeWidgetItem *itm = static_cast<QTreeWidgetItem *>(child.internalPointer());
296  if (!itm || itm == rootItem)
297  return QModelIndex();
298  QTreeWidgetItem *parent = itm->parent();
299  return index(parent, 0);
300 }
301 
310 {
311  if (!parent.isValid())
312  return rootItem->childCount();
313 
314  QTreeWidgetItem *parentItem = item(parent);
315  if (parentItem)
316  return parentItem->childCount();
317  return 0;
318 }
319 
329 {
330  Q_UNUSED(index);
331  if (!headerItem)
332  return 0;
333  return headerItem->columnCount();
334 }
335 
337 {
338  if (!parent.isValid())
339  return (rootItem->childCount() > 0);
340 
341  QTreeWidgetItem *itm = item(parent);
342  if (!itm)
343  return false;
344  switch (itm->d->policy) {
346  return true;
348  return false;
350  return (itm->childCount() > 0);
351  }
352  return false;
353 }
354 
364 {
365  if (!index.isValid())
366  return QVariant();
367  QTreeWidgetItem *itm = item(index);
368  if (itm)
369  return itm->data(index.column(), role);
370  return QVariant();
371 }
372 
383 bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
384 {
385  if (!index.isValid())
386  return false;
387  QTreeWidgetItem *itm = item(index);
388  if (itm) {
389  itm->setData(index.column(), role, value);
390  return true;
391  }
392  return false;
393 }
394 
396 {
398  return false;
399  QTreeWidgetItem *itm = item(index);
400  if (!itm)
401  return false;
402  const auto beginIter = itm->values.at(index.column()).cbegin();
403  const auto endIter = itm->values.at(index.column()).cend();
404  if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); })
405  && !itm->d->display.at(index.column()).isValid()) {
406  return true; //it's already cleared
407  }
408  itm->d->display[index.column()] = QVariant();
409  itm->values[index.column()].clear();
411  return true;
412 }
413 
415 {
416  QMap<int, QVariant> roles;
417  QTreeWidgetItem *itm = item(index);
418  if (itm) {
419  int column = index.column();
420  if (column < itm->values.count()) {
421  for (int i = 0; i < itm->values.at(column).count(); ++i) {
422  roles.insert(itm->values.at(column).at(i).role,
423  itm->values.at(column).at(i).value);
424  }
425  }
426 
427  // the two special cases
428  QVariant displayValue = itm->data(column, Qt::DisplayRole);
429  if (displayValue.isValid())
430  roles.insert(Qt::DisplayRole, displayValue);
431 
432  QVariant checkValue = itm->data(column, Qt::CheckStateRole);
433  if (checkValue.isValid())
434  roles.insert(Qt::CheckStateRole, checkValue);
435  }
436  return roles;
437 }
438 
444 {
445  SkipSorting skipSorting(this);
446  if (count < 1 || row < 0 || row > rowCount(parent) || parent.column() > 0)
447  return false;
448 
450  QTreeWidgetItem *par = item(parent);
451  while (count > 0) {
453  item->view = view();
454  item->par = par;
455  if (par)
456  par->children.insert(row++, item);
457  else
458  rootItem->children.insert(row++, item);
459  --count;
460  }
461  endInsertRows();
462  return true;
463 }
464 
470 {
471  SkipSorting skipSorting(this);
472  if (count < 1 || column < 0 || column > columnCount(parent) || parent.column() > 0 || !headerItem)
473  return false;
474 
476 
477  int oldCount = columnCount(parent);
478  column = qBound(0, column, oldCount);
479  headerItem->values.resize(oldCount + count);
480  for (int i = oldCount; i < oldCount + count; ++i) {
481  headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
482  headerItem->d->display.append(QString::number(i + 1));
483  }
484 
485  QStack<QTreeWidgetItem*> itemstack;
486  itemstack.push(0);
487  while (!itemstack.isEmpty()) {
488  QTreeWidgetItem *par = itemstack.pop();
489  QList<QTreeWidgetItem*> children = par ? par->children : rootItem->children;
490  for (int row = 0; row < children.count(); ++row) {
492  if (child->children.count())
493  itemstack.push(child);
494  child->values.insert(column, count, QList<QWidgetItemData>());
495  }
496  }
497 
499  return true;
500 }
501 
507  if (count < 1 || row < 0 || (row + count) > rowCount(parent))
508  return false;
509  QTreeWidgetItem *parentItem = item(parent);
510  // if parentItem is valid, begin/end RemoveRows is handled by takeChild below
511  if (!parentItem)
513  for (int i = row + count - 1; i >= row; --i) {
514  QTreeWidgetItem *child = parentItem ? parentItem->takeChild(i) : rootItem->children.takeAt(i);
515  Q_ASSERT(child);
516  child->view = nullptr;
517  delete child;
518  }
519  if (!parentItem)
520  endRemoveRows();
521  return true;
522 }
523 
532 QVariant QTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
533 {
534  if (orientation != Qt::Horizontal)
535  return QVariant();
536 
537  if (headerItem)
538  return headerItem->data(section, role);
539  if (role == Qt::DisplayRole)
540  return QString::number(section + 1);
541  return QVariant();
542 }
543 
554 bool QTreeModel::setHeaderData(int section, Qt::Orientation orientation,
555  const QVariant &value, int role)
556 {
557  if (section < 0 || orientation != Qt::Horizontal || !headerItem || section >= columnCount())
558  return false;
559 
560  headerItem->setData(section, role, value);
561  return true;
562 }
563 
571 Qt::ItemFlags QTreeModel::flags(const QModelIndex &index) const
572 {
573  if (!index.isValid())
574  return rootItem->flags();
575  QTreeWidgetItem *itm = item(index);
576  Q_ASSERT(itm);
577  return itm->flags();
578 }
579 
588 {
589  SkipSorting skipSorting(this);
590  sortPendingTimer.stop();
591 
593  return;
594 
595  //layoutAboutToBeChanged and layoutChanged will be called by sortChildren
596  rootItem->sortChildren(column, order, true);
597 }
598 
603  int start, int end, const QModelIndex &parent)
604 {
605  if (isChanging())
606  return;
607 
608  sortPendingTimer.stop();
609 
611  return;
612 
613  SkipSorting skipSorting(this);
614 
615  QTreeWidgetItem *itm = item(parent);
616  if (!itm)
617  itm = rootItem;
618  QList<QTreeWidgetItem*> lst = itm->children;
619 
620  int count = end - start + 1;
622  for (int i = 0; i < count; ++i) {
623  sorting[i].first = lst.at(start + i);
624  sorting[i].second = start + i;
625  }
626 
628  std::stable_sort(sorting.begin(), sorting.end(), compare);
629 
630  QModelIndexList oldPersistentIndexes;
631  QModelIndexList newPersistentIndexes;
633  bool changed = false;
634 
635  for (int i = 0; i < count; ++i) {
636  int oldRow = sorting.at(i).second;
637 
638  int tmpitepos = lit - lst.begin();
639  QTreeWidgetItem *item = lst.takeAt(oldRow);
640  if (tmpitepos > lst.size())
641  --tmpitepos;
642  lit = lst.begin() + tmpitepos;
643 
644  lit = sortedInsertionIterator(lit, lst.end(), order, item);
645  int newRow = qMax<qsizetype>(lit - lst.begin(), 0);
646 
647  if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)) && !(*lst.at(oldRow - 1) < *item ))
648  newRow = oldRow;
649 
650  lit = lst.insert(lit, item);
651  if (newRow != oldRow) {
652  // we are going to change the persistent indexes, so we need to prepare
653  if (!changed) { // this will only happen once
654  changed = true;
655  emit layoutAboutToBeChanged({parent}, QAbstractItemModel::VerticalSortHint); // the selection model needs to know
656  oldPersistentIndexes = persistentIndexList();
657  newPersistentIndexes = oldPersistentIndexes;
658  }
659  for (int j = i + 1; j < count; ++j) {
660  int otherRow = sorting.at(j).second;
661  if (oldRow < otherRow && newRow >= otherRow)
662  --sorting[j].second;
663  else if (oldRow > otherRow && newRow <= otherRow)
664  ++sorting[j].second;
665  }
666  for (int k = 0; k < newPersistentIndexes.count(); ++k) {
667  QModelIndex pi = newPersistentIndexes.at(k);
668  if (pi.parent() != parent)
669  continue;
670  int oldPersistentRow = pi.row();
671  int newPersistentRow = oldPersistentRow;
672  if (oldPersistentRow == oldRow)
673  newPersistentRow = newRow;
674  else if (oldRow < oldPersistentRow && newRow >= oldPersistentRow)
675  newPersistentRow = oldPersistentRow - 1;
676  else if (oldRow > oldPersistentRow && newRow <= oldPersistentRow)
677  newPersistentRow = oldPersistentRow + 1;
678  if (newPersistentRow != oldPersistentRow)
679  newPersistentIndexes[k] = createIndex(newPersistentRow,
680  pi.column(), pi.internalPointer());
681  }
682  }
683  }
684 
685  if (changed) {
686  itm->children = lst;
687  changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
689  }
690 }
691 
703 {
704  return *(left.first) < *(right.first);
705 }
706 
718 {
719  return *(right.first) < *(left.first);
720 }
721 
729 {
730  if (order == Qt::AscendingOrder)
731  return std::lower_bound(begin, end, item, QTreeModelLessThan());
732  return std::lower_bound(begin, end, item, QTreeModelGreaterThan());
733 }
734 
736 {
737  auto v = view();
738  if (v)
739  return v->mimeTypes();
740  return {};
741 }
742 
744 {
745  return QAbstractItemModel::mimeData(cachedIndexes);
746 }
747 
749 {
751  std::transform(indexes.begin(), indexes.end(), std::back_inserter(items),
752  [this](const QModelIndex &idx) -> QTreeWidgetItem * { return item(idx); });
753 
754  // Ensure we only have one item as an item may have more than
755  // one index selected if there is more than one column
756  std::sort(items.begin(), items.end());
757  items.erase(std::unique(items.begin(), items.end()), items.end());
758 
759  // cachedIndexes is a little hack to avoid copying from QModelIndexList to
760  // QList<QTreeWidgetItem*> and back again in the view
761  cachedIndexes = indexes;
763  cachedIndexes.clear();
764  return mimeData;
765 }
766 
768  int row, int column, const QModelIndex &parent)
769 {
770  if (row == -1 && column == -1)
771  row = rowCount(parent); // append
772  return view()->dropMimeData(item(parent), row, data, action);
773 }
774 
775 Qt::DropActions QTreeModel::supportedDropActions() const
776 {
777  return view()->supportedDropActions();
778 }
779 
781 {
782  SkipSorting skipSorting(this); //this is kind of wrong, but not doing this would kill performance
783  QModelIndex left = index(item, 0);
786 }
787 
788 bool QTreeModel::isChanging() const
789 {
790  Q_D(const QTreeModel);
791  return !d->changes.isEmpty();
792 }
793 
801 {
802  if (signalsBlocked())
803  return;
804 
805  if (headerItem == item && column < item->columnCount()) {
806  if (column == -1)
808  else
810  return;
811  }
812 
813  SkipSorting skipSorting(this); //This is a little bit wrong, but not doing it would kill performance
814 
815  QModelIndex bottomRight, topLeft;
816  if (column == -1) {
817  topLeft = index(item, 0);
818  bottomRight = createIndex(topLeft.row(), columnCount() - 1, item);
819  } else {
820  topLeft = index(item, column);
821  bottomRight = topLeft;
822  }
823  emit dataChanged(topLeft, bottomRight, roles);
824 }
825 
827 {
828  QModelIndex par = index(parent, 0);
829  beginInsertRows(par, row, row + count - 1);
830 }
831 
833 {
834  endInsertRows();
835 }
836 
838 {
839  Q_ASSERT(row >= 0);
840  Q_ASSERT(count > 0);
841  beginRemoveRows(index(parent, 0), row, row + count - 1);
842  if (!parent)
843  parent = rootItem;
844  // now update the iterators
845  for (int i = 0; i < iterators.count(); ++i) {
846  for (int j = 0; j < count; j++) {
847  QTreeWidgetItem *c = parent->child(row + j);
848  iterators[i]->d_func()->ensureValidIterator(c);
849  }
850  }
851 }
852 
854 {
855  endRemoveRows();
856 }
857 
859 {
860  // see QTreeViewItem::operator<
861  Q_UNUSED(column);
862  if (isChanging())
863  return;
864 
865  // store the original order of indexes
867  for (int i = 0; i < sorting.count(); ++i) {
868  sorting[i].first = items->at(i);
869  sorting[i].second = i;
870  }
871 
872  // do the sorting
874  std::stable_sort(sorting.begin(), sorting.end(), compare);
875 
876  QModelIndexList fromList;
877  QModelIndexList toList;
878  int colCount = columnCount();
879  for (int r = 0; r < sorting.count(); ++r) {
880  int oldRow = sorting.at(r).second;
881  if (oldRow == r)
882  continue;
883  QTreeWidgetItem *item = sorting.at(r).first;
884  items->replace(r, item);
885  for (int c = 0; c < colCount; ++c) {
886  QModelIndex from = createIndex(oldRow, c, item);
887  if (static_cast<QAbstractItemModelPrivate *>(d_ptr.data())->persistent.indexes.contains(from)) {
888  QModelIndex to = createIndex(r, c, item);
889  fromList << from;
890  toList << to;
891  }
892  }
893  }
894  changePersistentIndexList(fromList, toList);
895 }
896 
898 {
899  if (ev->timerId() == sortPendingTimer.timerId()) {
900  executePendingSort();
901  } else {
903  }
904 }
905 
1016 {
1017  const QTreeModel *model = treeModel();
1018  if (!model || !view->selectionModel())
1019  return;
1020  const QModelIndex index = model->index(this, 0);
1024  d->selected = select;
1025 }
1026 
1036 {
1037  return d->selected;
1038 }
1039 
1053 {
1054  const QTreeModel *model = treeModel();
1055  if (!model)
1056  return;
1057  if (this == model->headerItem) {
1058  view->header()->setHidden(hide);
1059  } else {
1060  const QModelIndex index = view->d_func()->index(this);
1061  view->setRowHidden(index.row(), index.parent(), hide);
1062  }
1063  d->hidden = hide;
1064 }
1065 
1076 {
1077  const QTreeModel *model = treeModel();
1078  if (!model)
1079  return false;
1080  if (this == model->headerItem)
1081  return view->header()->isHidden();
1082  if (view->d_func()->hiddenIndexes.isEmpty())
1083  return false;
1084  QTreeModel::SkipSorting skipSorting(model);
1085  return view->d_func()->isRowHidden(view->d_func()->index(this));
1086 }
1087 
1098 {
1099  const QTreeModel *model = treeModel();
1100  if (!model)
1101  return;
1102  QTreeModel::SkipSorting skipSorting(model);
1103  view->setExpanded(view->d_func()->index(this), expand);
1104 }
1105 
1115 {
1116  const QTreeModel *model = treeModel();
1117  if (!model)
1118  return false;
1119  QTreeModel::SkipSorting skipSorting(model);
1120  return view->isExpanded(view->d_func()->index(this));
1121 }
1122 
1133 {
1134  const QTreeModel *model = treeModel();
1135  if (!model || this == model->headerItem)
1136  return; // We can't set the header items to spanning
1137  const QModelIndex index = model->index(this, 0);
1138  view->setFirstColumnSpanned(index.row(), index.parent(), span);
1139 }
1140 
1150 {
1151  const QTreeModel *model = treeModel();
1152  if (!model || this == model->headerItem)
1153  return false;
1154  const QModelIndex index = model->index(this, 0);
1155  return view->isFirstColumnSpanned(index.row(), index.parent());
1156 }
1157 
1391 
1401  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1402 {
1403  for (int i = 0; i < strings.count(); ++i)
1404  setText(i, strings.at(i));
1405 }
1406 
1417  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1418 {
1419  // do not set this->view here otherwise insertChild() will fail
1420  if (QTreeModel *model = treeModel(treeview)) {
1421  model->rootItem->addChild(this);
1422  values.reserve(model->headerItem->columnCount());
1423  }
1424 }
1425 
1437  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1438 {
1439  for (int i = 0; i < strings.count(); ++i)
1440  setText(i, strings.at(i));
1441  // do not set this->view here otherwise insertChild() will fail
1442  if (QTreeModel *model = treeModel(treeview)) {
1443  model->rootItem->addChild(this);
1444  values.reserve(model->headerItem->columnCount());
1445  }
1446 }
1447 
1457  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1458 {
1459  // do not set this->view here otherwise insertChild() will fail
1460  if (QTreeModel *model = treeModel(treeview)) {
1461  int i = model->rootItem->children.indexOf(after) + 1;
1462  model->rootItem->insertChild(i, this);
1463  values.reserve(model->headerItem->columnCount());
1464  }
1465 }
1466 
1473  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1474 {
1475  if (parent)
1476  parent->addChild(this);
1477 }
1478 
1486  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1487 {
1488  for (int i = 0; i < strings.count(); ++i)
1489  setText(i, strings.at(i));
1490  if (parent)
1491  parent->addChild(this);
1492 }
1493 
1503  : rtti(type), d(new QTreeWidgetItemPrivate(this))
1504 {
1505  if (parent) {
1506  int i = parent->children.indexOf(after) + 1;
1507  parent->insertChild(i, this);
1508  }
1509 }
1510 
1520 {
1521  QTreeModel *model = treeModel();
1522  QTreeModel::SkipSorting skipSorting(model);
1523 
1524  if (par) {
1525  int i = par->children.indexOf(this);
1526  if (i >= 0) {
1527  if (model) model->beginRemoveItems(par, i, 1);
1528  // users _could_ do changes when connected to rowsAboutToBeRemoved,
1529  // so we check again to make sure 'i' is valid
1530  if (!par->children.isEmpty() && par->children.at(i) == this)
1531  par->children.takeAt(i);
1532  if (model) model->endRemoveItems();
1533  }
1534  } else if (model) {
1535  if (this == model->headerItem) {
1536  model->headerItem = nullptr;
1537  } else {
1538  int i = model->rootItem->children.indexOf(this);
1539  if (i >= 0) {
1540  model->beginRemoveItems(nullptr, i, 1);
1541  // users _could_ do changes when connected to rowsAboutToBeRemoved,
1542  // so we check again to make sure 'i' is valid
1543  if (!model->rootItem->children.isEmpty() && model->rootItem->children.at(i) == this)
1544  model->rootItem->children.takeAt(i);
1545  model->endRemoveItems();
1546  }
1547  }
1548  }
1549  // at this point the persistent indexes for the children should also be invalidated
1550  // since we invalidated the parent
1551  for (int i = 0; i < children.count(); ++i) {
1552  QTreeWidgetItem *child = children.at(i);
1553  // make sure the child does not try to remove itself from our children list
1554  child->par = nullptr;
1555  // make sure the child does not try to remove itself from the top level list
1556  child->view = nullptr;
1557  delete child;
1558  }
1559 
1560  children.clear();
1561  delete d;
1562 }
1563 
1568 {
1569  QTreeWidgetItem *copy = nullptr;
1570 
1572  QStack<QTreeWidgetItem*> parentStack;
1573  stack.push(this);
1574  parentStack.push(0);
1575 
1576  QTreeWidgetItem *root = nullptr;
1577  const QTreeWidgetItem *item = nullptr;
1578  QTreeWidgetItem *parent = nullptr;
1579  while (!stack.isEmpty()) {
1580  // get current item, and copied parent
1581  item = stack.pop();
1582  parent = parentStack.pop();
1583 
1584  // copy item
1585  copy = new QTreeWidgetItem(*item);
1586  if (!root)
1587  root = copy;
1588 
1589  // set parent and add to parents children list
1590  if (parent) {
1591  copy->par = parent;
1592  parent->children.insert(0, copy);
1593  }
1594 
1595  for (int i = 0; i < item->childCount(); ++i) {
1596  stack.push(item->child(i));
1597  parentStack.push(copy);
1598  }
1599  }
1600  return root;
1601 }
1602 
1611 {
1612  if (d->policy == policy)
1613  return;
1614  d->policy = policy;
1615 
1616  if (!view)
1617  return;
1618 
1620 }
1621 
1629 {
1630  return d->policy;
1631 }
1632 
1642 {
1643  const bool enable = (flags & Qt::ItemIsEnabled);
1644  const bool changedState = bool(itemFlags & Qt::ItemIsEnabled) != enable;
1645  const bool changedExplicit = d->disabled != !enable;
1646 
1647  d->disabled = !enable;
1648 
1649  if (enable && par && !(par->itemFlags & Qt::ItemIsEnabled)) // inherit from parent
1650  itemFlags = flags & ~Qt::ItemIsEnabled;
1651  else // this item is explicitly disabled or has no parent
1652  itemFlags = flags;
1653 
1654  if (changedState && changedExplicit) { // if the propagate the change to the children
1655  QStack<QTreeWidgetItem*> parents;
1656  parents.push(this);
1657  while (!parents.isEmpty()) {
1658  QTreeWidgetItem *parent = parents.pop();
1659  for (int i = 0; i < parent->children.count(); ++i) {
1660  QTreeWidgetItem *child = parent->children.at(i);
1661  if (!child->d->disabled) { // if not explicitly disabled
1662  parents.push(child);
1663  if (enable)
1664  child->itemFlags = child->itemFlags | Qt::ItemIsEnabled;
1665  else
1666  child->itemFlags = child->itemFlags & ~Qt::ItemIsEnabled;
1667  child->itemChanged(); // ### we may want to optimize this
1668  }
1669  }
1670  }
1671  }
1672  itemChanged();
1673 }
1674 
1676 {
1677  QTreeModel *model = item->treeModel();
1678  if (!model)
1679  return;
1680  QStack<QTreeWidgetItem *> parents;
1681  parents.push(item);
1682  while (!parents.isEmpty()) {
1683  QTreeWidgetItem *parent = parents.pop();
1684  if (parent->d->hidden) {
1685  const QModelIndex index = model->index(parent, 0);
1686  item->view->setRowHidden(index.row(), index.parent(), inserting);
1687  }
1688  for (int i = 0; i < parent->children.count(); ++i) {
1689  QTreeWidgetItem *child = parent->children.at(i);
1690  parents.push(child);
1691  }
1692  }
1693 }
1694 
1696 {
1697  Q_ASSERT(item);
1698  const bool enable = item->par ? (item->par->itemFlags.testFlag(Qt::ItemIsEnabled)) : true;
1699 
1700  QStack<QTreeWidgetItem*> parents;
1701  parents.push(item);
1702  while (!parents.isEmpty()) {
1703  QTreeWidgetItem *parent = parents.pop();
1704  if (!parent->d->disabled) { // if not explicitly disabled
1705  Qt::ItemFlags oldFlags = parent->itemFlags;
1706  if (enable)
1707  parent->itemFlags = parent->itemFlags | Qt::ItemIsEnabled;
1708  else
1709  parent->itemFlags = parent->itemFlags & ~Qt::ItemIsEnabled;
1710  if (parent->itemFlags != oldFlags)
1711  parent->itemChanged();
1712  }
1713 
1714  for (int i = 0; i < parent->children.count(); ++i) {
1715  QTreeWidgetItem *child = parent->children.at(i);
1716  parents.push(child);
1717  }
1718  }
1719 }
1732 Qt::ItemFlags QTreeWidgetItem::flags() const
1733 {
1734  return itemFlags;
1735 }
1736 
1747 void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
1748 {
1749  if (column < 0)
1750  return;
1751 
1752  QTreeModel *model = treeModel();
1753  switch (role) {
1754  case Qt::EditRole:
1755  case Qt::DisplayRole: {
1756  if (values.count() <= column) {
1757  if (model && this == model->headerItem)
1758  model->setColumnCount(column + 1);
1759  else
1760  values.resize(column + 1);
1761  }
1762  if (d->display.count() <= column) {
1763  for (int i = d->display.count() - 1; i < column - 1; ++i)
1764  d->display.append(QVariant());
1765  d->display.append(value);
1766  } else if (d->display[column] != value) {
1767  d->display[column] = value;
1768  } else {
1769  return; // value is unchanged
1770  }
1771  } break;
1772  case Qt::CheckStateRole:
1773  if ((itemFlags & Qt::ItemIsAutoTristate) && value != Qt::PartiallyChecked) {
1774  for (int i = 0; i < children.count(); ++i) {
1775  QTreeWidgetItem *child = children.at(i);
1776  if (child->data(column, role).isValid()) {// has a CheckState
1777  Qt::ItemFlags f = itemFlags; // a little hack to avoid multiple dataChanged signals
1778  itemFlags &= ~Qt::ItemIsAutoTristate;
1779  child->setData(column, role, value);
1780  itemFlags = f;
1781  }
1782  }
1783  }
1784  Q_FALLTHROUGH();
1785  default:
1786  if (column < values.count()) {
1787  bool found = false;
1788  const QList<QWidgetItemData> column_values = values.at(column);
1789  for (int i = 0; i < column_values.count(); ++i) {
1790  if (column_values.at(i).role == role) {
1791  if (column_values.at(i).value == value)
1792  return; // value is unchanged
1793  values[column][i].value = value;
1794  found = true;
1795  break;
1796  }
1797  }
1798  if (!found)
1799  values[column].append(QWidgetItemData(role, value));
1800  } else {
1801  if (model && this == model->headerItem)
1802  model->setColumnCount(column + 1);
1803  else
1804  values.resize(column + 1);
1805  values[column].append(QWidgetItemData(role, value));
1806  }
1807  }
1808 
1809  if (model) {
1810  const QList<int> roles((role == Qt::DisplayRole || role == Qt::EditRole)
1812  : QList<int>({ role }));
1813  model->emitDataChanged(this, column, roles);
1814  if (role == Qt::CheckStateRole) {
1815  QTreeWidgetItem *p;
1816  for (p = par; p && (p->itemFlags & Qt::ItemIsAutoTristate); p = p->par)
1817  model->emitDataChanged(p, column, roles);
1818  }
1819  }
1820 }
1821 
1826 {
1827  switch (role) {
1828  case Qt::EditRole:
1829  case Qt::DisplayRole:
1830  if (column >= 0 && column < d->display.count())
1831  return d->display.at(column);
1832  break;
1833  case Qt::CheckStateRole:
1834  // special case for check state in tristate
1835  if (children.count() && (itemFlags & Qt::ItemIsAutoTristate))
1836  return childrenCheckState(column);
1837  Q_FALLTHROUGH();
1838  default:
1839  if (column >= 0 && column < values.size()) {
1840  const QList<QWidgetItemData> &column_values = values.at(column);
1841  for (const auto &column_value : column_values) {
1842  if (column_value.role == role)
1843  return column_value.value;
1844  }
1845  }
1846  }
1847  return QVariant();
1848 }
1849 
1856 {
1857  int column = view ? view->sortColumn() : 0;
1859  const QVariant v2 = other.data(column, Qt::DisplayRole);
1861 }
1862 
1863 #ifndef QT_NO_DATASTREAM
1864 
1871 {
1872  // convert from streams written before we introduced display (4.2.0)
1873  if (in.version() < QDataStream::Qt_4_2) {
1874  d->display.clear();
1875  in >> values;
1876  // move the display value over to the display string list
1877  for (int column = 0; column < values.count(); ++column) {
1878  d->display << QVariant();
1879  for (int i = 0; i < values.at(column).count(); ++i) {
1880  if (values.at(column).at(i).role == Qt::DisplayRole) {
1881  d->display[column] = values.at(column).at(i).value;
1882  values[column].remove(i--);
1883  }
1884  }
1885  }
1886  } else {
1887  in >> values >> d->display;
1888  }
1889 }
1890 
1897 {
1898  out << values << d->display;
1899 }
1900 #endif // QT_NO_DATASTREAM
1901 
1913  : rtti(Type),
1914  values(other.values),
1916  itemFlags(other.itemFlags)
1917 {
1918  d->display = other.d->display;
1919 }
1920 
1930 {
1931  values = other.values;
1932  d->display = other.d->display;
1933  d->policy = other.d->policy;
1934  itemFlags = other.itemFlags;
1935  return *this;
1936 }
1937 
1944 {
1945  if (child) {
1946  insertChild(children.count(), child);
1947  child->d->rowGuess = children.count() - 1;
1948  }
1949 }
1950 
1957 {
1958  if (index < 0 || index > children.count() || child == nullptr || child->view != nullptr || child->par != nullptr)
1959  return;
1960 
1961  if (QTreeModel *model = treeModel()) {
1962  QTreeModel::SkipSorting skipSorting(model);
1963  if (model->rootItem == this)
1964  child->par = nullptr;
1965  else
1966  child->par = this;
1967  if (view->isSortingEnabled()) {
1968  // do a delayed sort instead
1969  if (!model->sortPendingTimer.isActive())
1970  model->sortPendingTimer.start(0, model);
1971  }
1972  model->beginInsertItems(this, index, 1);
1973  int cols = model->columnCount();
1975  stack.push(child);
1976  while (!stack.isEmpty()) {
1977  QTreeWidgetItem *i = stack.pop();
1978  i->view = view;
1979  i->values.reserve(cols);
1980  for (int c = 0; c < i->children.count(); ++c)
1981  stack.push(i->children.at(c));
1982  }
1983  children.insert(index, child);
1984  d->updateHiddenStatus(child, true);
1985  model->endInsertItems();
1986  } else {
1987  child->par = this;
1988  children.insert(index, child);
1989  }
1990  if (child->par)
1992 }
1993 
1999 {
2000  (void)takeChild(children.indexOf(child));
2001 }
2002 
2007 {
2008  // we move this outside the check of the index to allow executing
2009  // pending sorts from inline functions, using this function (hack)
2010  QTreeModel *model = treeModel();
2011  if (model) {
2012  // This will trigger a layoutChanged signal, thus we might want to optimize
2013  // this function by not emitting the rowsRemoved signal etc to the view.
2014  // On the other hand we also need to make sure that the selectionmodel
2015  // is updated in case we take an item that is selected.
2016  model->skipPendingSort = false;
2017  model->executePendingSort();
2018  }
2019  if (index >= 0 && index < children.count()) {
2020  if (model) model->beginRemoveItems(this, index, 1);
2021  d->updateHiddenStatus(children.at(index), false);
2022  QTreeWidgetItem *item = children.takeAt(index);
2023  item->par = nullptr;
2025  stack.push(item);
2026  while (!stack.isEmpty()) {
2027  QTreeWidgetItem *i = stack.pop();
2028  i->view = nullptr;
2029  for (int c = 0; c < i->children.count(); ++c)
2030  stack.push(i->children.at(c));
2031  }
2032  d->propagateDisabled(item);
2033  if (model) model->endRemoveRows();
2034  return item;
2035  }
2036  return nullptr;
2037 }
2038 
2047 {
2048  insertChildren(this->children.count(), children);
2049 }
2050 
2059 {
2060  if (index < 0 || index > this->children.count() || children.isEmpty())
2061  return;
2062 
2063  if (view && view->isSortingEnabled()) {
2064  for (int n = 0; n < children.count(); ++n)
2065  insertChild(index, children.at(n));
2066  return;
2067  }
2068  QTreeModel *model = treeModel();
2070  QList<QTreeWidgetItem*> itemsToInsert;
2071  for (int n = 0; n < children.count(); ++n) {
2072  QTreeWidgetItem *child = children.at(n);
2073  if (child->view || child->par)
2074  continue;
2075  itemsToInsert.append(child);
2076  if (view && model) {
2077  if (child->childCount() == 0)
2078  child->view = view;
2079  else
2080  stack.push(child);
2081  }
2082  if (model && (model->rootItem == this))
2083  child->par = nullptr;
2084  else
2085  child->par = this;
2086  }
2087  if (!itemsToInsert.isEmpty()) {
2088  while (!stack.isEmpty()) {
2089  QTreeWidgetItem *i = stack.pop();
2090  i->view = view;
2091  for (int c = 0; c < i->children.count(); ++c)
2092  stack.push(i->children.at(c));
2093  }
2094  if (model) model->beginInsertItems(this, index, itemsToInsert.count());
2095  for (int n = 0; n < itemsToInsert.count(); ++n) {
2096  QTreeWidgetItem *child = itemsToInsert.at(n);
2097  this->children.insert(index + n, child);
2098  if (child->par)
2100  d->updateHiddenStatus(child, true);
2101  }
2102  if (model) model->endInsertItems();
2103  }
2104 }
2105 
2112 {
2113  QList<QTreeWidgetItem*> removed;
2114  if (children.count() > 0) {
2115  QTreeModel *model = treeModel();
2116  if (model) {
2117  // This will trigger a layoutChanged signal, thus we might want to optimize
2118  // this function by not emitting the rowsRemoved signal etc to the view.
2119  // On the other hand we also need to make sure that the selectionmodel
2120  // is updated in case we take an item that is selected.
2121  model->executePendingSort();
2122  }
2123  if (model) model->beginRemoveItems(this, 0, children.count());
2124  for (int n = 0; n < children.count(); ++n) {
2125  QTreeWidgetItem *item = children.at(n);
2126  item->par = nullptr;
2128  stack.push(item);
2129  while (!stack.isEmpty()) {
2130  QTreeWidgetItem *i = stack.pop();
2131  i->view = nullptr;
2132  for (int c = 0; c < i->children.count(); ++c)
2133  stack.push(i->children.at(c));
2134  }
2135  d->propagateDisabled(item);
2136  }
2137  removed = children;
2138  children.clear(); // detach
2139  if (model) model->endRemoveItems();
2140  }
2141  return removed;
2142 }
2143 
2144 
2146 {
2147  QTreeModel *model = q->treeModel();
2148  if (!model)
2149  return;
2150  model->sortItems(&q->children, column, order);
2151  if (climb) {
2152  QList<QTreeWidgetItem*>::iterator it = q->children.begin();
2153  for (; it != q->children.end(); ++it) {
2154  //here we call the private object's method to avoid emitting
2155  //the layoutAboutToBeChanged and layoutChanged signals
2156  (*it)->d->sortChildren(column, order, climb);
2157  }
2158  }
2159 }
2160 
2169 {
2170  QTreeModel *model = treeModel();
2171  if (!model)
2172  return;
2173  if (model->isChanging())
2174  return;
2175  QTreeModel::SkipSorting skipSorting(model);
2176  int oldSortColumn = view->d_func()->explicitSortColumn;
2177  view->d_func()->explicitSortColumn = column;
2179  d->sortChildren(column, order, climb);
2181  view->d_func()->explicitSortColumn = oldSortColumn;
2182 }
2183 
2192 QVariant QTreeWidgetItem::childrenCheckState(int column) const
2193 {
2194  if (column < 0)
2195  return QVariant();
2196  bool checkedChildren = false;
2197  bool uncheckedChildren = false;
2198  for (const auto *child : children) {
2200  if (!value.isValid())
2201  return QVariant();
2202 
2203  switch (static_cast<Qt::CheckState>(value.toInt()))
2204  {
2205  case Qt::Unchecked:
2206  uncheckedChildren = true;
2207  break;
2208  case Qt::Checked:
2209  checkedChildren = true;
2210  break;
2211  case Qt::PartiallyChecked:
2212  default:
2213  return Qt::PartiallyChecked;
2214  }
2215 
2216  if (uncheckedChildren && checkedChildren)
2217  return Qt::PartiallyChecked;
2218  }
2219 
2220  if (uncheckedChildren)
2221  return Qt::Unchecked;
2222  else if (checkedChildren)
2223  return Qt::Checked;
2224  else
2225  return QVariant(); // value was not defined
2226 }
2227 
2241 {
2242  itemChanged();
2243 }
2244 
2248 void QTreeWidgetItem::itemChanged()
2249 {
2250  if (QTreeModel *model = treeModel())
2251  model->itemChanged(this);
2252 }
2253 
2257 void QTreeWidgetItem::executePendingSort() const
2258 {
2259  if (QTreeModel *model = treeModel())
2260  model->executePendingSort();
2261 }
2262 
2267 QTreeModel *QTreeWidgetItem::treeModel(QTreeWidget *v) const
2268 {
2269  if (!v)
2270  v = view;
2271  return (v ? qobject_cast<QTreeModel*>(v->model()) : nullptr);
2272 }
2273 
2274 
2275 #ifndef QT_NO_DATASTREAM
2286 {
2287  item.write(out);
2288  return out;
2289 }
2290 
2301 {
2302  item.read(in);
2303  return in;
2304 }
2305 #endif // QT_NO_DATASTREAM
2306 
2307 
2309 {
2310  Q_Q(QTreeWidget);
2311  emit q->itemPressed(item(index), index.column());
2312 }
2313 
2315 {
2316  Q_Q(QTreeWidget);
2317  emit q->itemClicked(item(index), index.column());
2318 }
2319 
2321 {
2322  Q_Q(QTreeWidget);
2323  emit q->itemDoubleClicked(item(index), index.column());
2324 }
2325 
2327 {
2328  Q_Q(QTreeWidget);
2329  emit q->itemActivated(item(index), index.column());
2330 }
2331 
2333 {
2334  Q_Q(QTreeWidget);
2335  emit q->itemEntered(item(index), index.column());
2336 }
2337 
2339 {
2340  Q_Q(QTreeWidget);
2341  QTreeWidgetItem *indexItem = item(index);
2342  if (indexItem)
2343  emit q->itemChanged(indexItem, index.column());
2344 }
2345 
2347 {
2348  Q_Q(QTreeWidget);
2349  emit q->itemExpanded(item(index));
2350 }
2351 
2353 {
2354  Q_Q(QTreeWidget);
2355  emit q->itemCollapsed(item(index));
2356 }
2357 
2359  const QModelIndex &previous)
2360 {
2361  Q_Q(QTreeWidget);
2362  QTreeWidgetItem *currentItem = item(current);
2363  QTreeWidgetItem *previousItem = item(previous);
2364  emit q->currentItemChanged(currentItem, previousItem);
2365 }
2366 
2368 {
2369  if (sortingEnabled) {
2372  treeModel()->sort(column, order);
2373  }
2374 }
2375 
2377 {
2378  Q_Q(QTreeWidget);
2379  QModelIndexList indices = selected.indexes();
2380  int i;
2381  QTreeModel *m = treeModel();
2382  for (i = 0; i < indices.count(); ++i) {
2383  QTreeWidgetItem *item = m->item(indices.at(i));
2384  item->d->selected = true;
2385  }
2386 
2387  indices = deselected.indexes();
2388  for (i = 0; i < indices.count(); ++i) {
2389  QTreeWidgetItem *item = m->item(indices.at(i));
2390  item->d->selected = false;
2391  }
2392 
2393  emit q->itemSelectionChanged();
2394 }
2395 
2397  const QModelIndex &bottomRight)
2398 {
2399  if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
2400  && !treeModel()->sortPendingTimer.isActive()) {
2402  if (column >= topLeft.column() && column <= bottomRight.column()) {
2404  treeModel()->ensureSorted(column, order, topLeft.row(),
2405  bottomRight.row(), topLeft.parent());
2406  }
2407  }
2408 }
2409 
2576 {
2577  QTreeView::setModel(new QTreeModel(1, this));
2579  SLOT(_q_emitItemPressed(QModelIndex)));
2581  SLOT(_q_emitItemClicked(QModelIndex)));
2583  SLOT(_q_emitItemDoubleClicked(QModelIndex)));
2585  SLOT(_q_emitItemActivated(QModelIndex)));
2587  SLOT(_q_emitItemEntered(QModelIndex)));
2589  SLOT(_q_emitItemExpanded(QModelIndex)));
2591  SLOT(_q_emitItemCollapsed(QModelIndex)));
2593  this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
2595  this, SLOT(_q_emitItemChanged(QModelIndex)));
2597  this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
2598  connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
2599  this, SLOT(_q_sort()));
2601  this, SLOT(_q_selectionChanged(QItemSelection,QItemSelection)));
2602  header()->setSectionsClickable(false);
2603 }
2604 
2610 {
2611 }
2612 
2613 /*
2614  Returns the number of header columns in the view.
2615 
2616  \sa sortColumn(), currentColumn(), topLevelItemCount()
2617 */
2618 
2620 {
2621  Q_D(const QTreeWidget);
2622  return d->model->columnCount();
2623 }
2624 
2625 /*
2626  Sets the number of header \a columns in the tree widget.
2627 */
2628 
2630 {
2631  Q_D(QTreeWidget);
2632  if (columns < 0)
2633  return;
2634  d->treeModel()->setColumnCount(columns);
2635 }
2636 
2649 {
2650  Q_D(const QTreeWidget);
2651  return d->treeModel()->rootItem;
2652 }
2653 
2662 {
2663  Q_D(const QTreeWidget);
2664  return d->treeModel()->rootItem->child(index);
2665 }
2666 
2677 {
2678  Q_D(const QTreeWidget);
2679  return d->treeModel()->rootItem->childCount();
2680 }
2681 
2691 {
2692  Q_D(QTreeWidget);
2693  d->treeModel()->rootItem->insertChild(index, item);
2694 }
2695 
2704 {
2706 }
2707 
2716 {
2717  Q_D(QTreeWidget);
2718  return d->treeModel()->rootItem->takeChild(index);
2719 }
2720 
2728 {
2729  Q_D(const QTreeWidget);
2730  d->treeModel()->executePendingSort();
2731  return d->treeModel()->rootItem->children.indexOf(item);
2732 }
2733 
2744 {
2745  Q_D(QTreeWidget);
2746  d->treeModel()->rootItem->insertChildren(index, items);
2747 }
2748 
2755 {
2757 }
2758 
2766 {
2767  Q_D(const QTreeWidget);
2768  return d->treeModel()->headerItem;
2769 }
2770 
2781 {
2782  Q_D(QTreeWidget);
2783  if (!item)
2784  return;
2785  item->view = this;
2786 
2787  int oldCount = columnCount();
2788  if (oldCount < item->columnCount())
2789  d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount() - 1);
2790  else if (oldCount > item->columnCount())
2791  d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount - 1);
2792  delete d->treeModel()->headerItem;
2793  d->treeModel()->headerItem = item;
2794  if (oldCount < item->columnCount())
2795  d->treeModel()->endInsertColumns();
2796  else if (oldCount > item->columnCount())
2797  d->treeModel()->endRemoveColumns();
2798  d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount);
2799 }
2800 
2801 
2811 {
2812  Q_D(QTreeWidget);
2813  if (columnCount() < labels.count())
2814  setColumnCount(labels.count());
2815  QTreeWidgetItem *item = d->treeModel()->headerItem;
2816  for (int i = 0; i < labels.count(); ++i)
2817  item->setText(i, labels.at(i));
2818 }
2819 
2833 {
2834  Q_D(const QTreeWidget);
2835  return d->item(currentIndex());
2836 }
2837 
2845 {
2846  return currentIndex().column();
2847 }
2848 
2858 {
2859  setCurrentItem(item, 0);
2860 }
2861 
2869 {
2870  Q_D(QTreeWidget);
2871  setCurrentIndex(d->index(item, column));
2872 }
2873 
2882  QItemSelectionModel::SelectionFlags command)
2883 {
2884  Q_D(QTreeWidget);
2885  d->selectionModel->setCurrentIndex(d->index(item, column), command);
2886 }
2887 
2888 
2896 {
2897  Q_D(const QTreeWidget);
2898  return d->item(indexAt(p));
2899 }
2900 
2915 {
2916  Q_D(const QTreeWidget);
2917  //the visual rect for an item is across all columns. So we need to determine
2918  //what is the first and last column and get their visual index rects
2919  const QModelIndex base = d->index(item);
2920  const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
2921  const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
2922  const QModelIndex first = base.sibling(base.row(), firstVisiblesection);
2923  const QModelIndex last = base.sibling(base.row(), lastVisibleSection);
2924  return visualRect(first) | visualRect(last);
2925 }
2926 
2935 {
2936  Q_D(const QTreeWidget);
2937  return (d->explicitSortColumn != -1
2938  ? d->explicitSortColumn
2939  : header()->sortIndicatorSection());
2940 }
2941 
2950 {
2951  Q_D(QTreeWidget);
2953  d->model->sort(column, order);
2954 }
2955 
2961 {
2962  Q_D(QTreeWidget);
2963  edit(d->index(item, column));
2964 }
2965 
2973 {
2974  Q_D(QTreeWidget);
2976 }
2977 
2988 {
2989  Q_D(QTreeWidget);
2991 }
2992 
3003 {
3004  Q_D(const QTreeWidget);
3006 }
3007 
3015 {
3016  Q_D(const QTreeWidget);
3017  return QAbstractItemView::indexWidget(d->index(item, column));
3018 }
3019 
3044 {
3045  Q_D(QTreeWidget);
3047 }
3048 
3055 {
3056  Q_D(const QTreeWidget);
3057  const QModelIndexList indexes = selectionModel()->selectedIndexes();
3059  items.reserve(indexes.count());
3061  for (const auto &index : indexes) {
3062  QTreeWidgetItem *item = d->item(index);
3063  if (item->isHidden() || seen.hasSeen(item))
3064  continue;
3065  items.append(item);
3066  }
3067  return items;
3068 }
3069 
3074 {
3075  Q_D(const QTreeWidget);
3076  QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()),
3077  Qt::DisplayRole, text, -1, flags);
3079  const int indexesSize = indexes.size();
3080  items.reserve(indexesSize);
3081  for (int i = 0; i < indexesSize; ++i)
3082  items.append(d->item(indexes.at(i)));
3083  return items;
3084 }
3085 
3086 
3093 {
3094  Q_D(const QTreeWidget);
3095  if (item == d->treeModel()->headerItem)
3096  return nullptr;
3097  const QModelIndex index = d->index(item);
3098  const QModelIndex above = indexAbove(index);
3099  return d->item(above);
3100 }
3101 
3108 {
3109  Q_D(const QTreeWidget);
3110  if (item == d->treeModel()->headerItem)
3111  return nullptr;
3112  const QModelIndex index = d->index(item);
3113  const QModelIndex below = indexBelow(index);
3114  return d->item(below);
3115 }
3116 
3121 {
3122  Q_D(QTreeWidget);
3124  QItemSelection newSelection = selectionModel->selection();
3125  if (!newSelection.isEmpty())
3126  d->_q_selectionChanged(newSelection, QItemSelection());
3127 }
3128 
3136 {
3137  Q_D(QTreeWidget);
3138  QTreeView::scrollTo(d->index(item), hint);
3139 }
3140 
3148 {
3149  Q_D(QTreeWidget);
3150  QTreeModel::SkipSorting skipSorting(d->treeModel());
3151  expand(d->index(item));
3152 }
3153 
3161 {
3162  Q_D(QTreeWidget);
3163  QTreeModel::SkipSorting skipSorting(d->treeModel());
3164  collapse(d->index(item));
3165 }
3166 
3177 {
3178  Q_D(QTreeWidget);
3179  selectionModel()->clear();
3180  d->treeModel()->clear();
3181 }
3182 
3190 {
3191  return model()->QAbstractItemModel::mimeTypes();
3192 }
3193 
3203 {
3204  Q_D(const QTreeWidget);
3205  if (d->treeModel()->cachedIndexes.isEmpty()) {
3206  QList<QModelIndex> indexes;
3207  for (const auto *item : items) {
3208  if (Q_UNLIKELY(!item)) {
3209  qWarning("QTreeWidget::mimeData: Null-item passed");
3210  return nullptr;
3211  }
3212 
3213  for (int c = 0; c < item->values.count(); ++c) {
3214  const QModelIndex index = indexFromItem(item, c);
3215  if (Q_UNLIKELY(!index.isValid())) {
3216  qWarning() << "QTreeWidget::mimeData: No index associated with item :" << item;
3217  return nullptr;
3218  }
3219  indexes << index;
3220  }
3221  }
3222  return d->model->QAbstractItemModel::mimeData(indexes);
3223  }
3224  return d->treeModel()->internalMimeData();
3225 }
3226 
3239 {
3240  QModelIndex idx;
3241  if (parent) idx = indexFromItem(parent);
3242  return model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx);
3243 }
3244 
3250 Qt::DropActions QTreeWidget::supportedDropActions() const
3251 {
3252  return model()->QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
3253 }
3254 
3263 {
3264  Q_D(const QTreeWidget);
3265  return d->index(item, column);
3266 }
3267 
3274 {
3275  Q_D(const QTreeWidget);
3276  return d->item(index);
3277 }
3278 
3279 #if QT_CONFIG(draganddrop)
3281 void QTreeWidget::dropEvent(QDropEvent *event) {
3282  Q_D(QTreeWidget);
3283  if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
3284  dragDropMode() == QAbstractItemView::InternalMove)) {
3285  QModelIndex topIndex;
3286  int col = -1;
3287  int row = -1;
3288  // check whether a subclass has already accepted the event, ie. moved the data
3289  if (!event->isAccepted() && d->dropOn(event, &row, &col, &topIndex)) {
3290  const QList<QModelIndex> idxs = selectedIndexes();
3292  const int indexesCount = idxs.count();
3293  indexes.reserve(indexesCount);
3294  for (const auto &idx : idxs)
3295  indexes.append(idx);
3296 
3297  if (indexes.contains(topIndex))
3298  return;
3299 
3300  // When removing items the drop location could shift
3301  QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
3302 
3303  // Remove the items
3305  for (const auto &index : indexes) {
3307  if (!parent || !parent->parent()) {
3308  taken.append(takeTopLevelItem(index.row()));
3309  } else {
3310  taken.append(parent->parent()->takeChild(index.row()));
3311  }
3312  }
3313 
3314  // insert them back in at their new positions
3315  for (int i = 0; i < indexes.count(); ++i) {
3316  // Either at a specific point or appended
3317  if (row == -1) {
3318  if (topIndex.isValid()) {
3319  QTreeWidgetItem *parent = itemFromIndex(topIndex);
3320  parent->insertChild(parent->childCount(), taken.takeFirst());
3321  } else {
3323  }
3324  } else {
3325  int r = dropRow.row() >= 0 ? dropRow.row() : row;
3326  if (topIndex.isValid()) {
3327  QTreeWidgetItem *parent = itemFromIndex(topIndex);
3328  parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst());
3329  } else {
3330  insertTopLevelItem(qMin(r, topLevelItemCount()), taken.takeFirst());
3331  }
3332  }
3333  }
3334 
3335  event->accept();
3336  }
3337  // either we or a subclass accepted the move event, so assume that the data was
3338  // moved and that QAbstractItemView shouldn't remove the source when QDrag::exec returns
3339  if (event->isAccepted())
3340  d->dropEventMoved = true;
3341  }
3342 
3343  QTreeView::dropEvent(event);
3344 }
3345 #endif
3346 
3351 void QTreeWidget::setModel(QAbstractItemModel * /*model*/)
3352 {
3353  Q_ASSERT(!"QTreeWidget::setModel() - Changing the model of the QTreeWidget is not allowed.");
3354 }
3355 
3360 {
3361  Q_D(QTreeWidget);
3362  if (e->type() == QEvent::Polish)
3363  d->treeModel()->executePendingSort();
3364  return QTreeView::event(e);
3365 }
3366 
3370 void QTreeModelPrivate::executePendingOperations() const
3371 {
3372  q_func()->executePendingSort();
3373 }
3374 
3376 
3377 #include "moc_qtreewidget.cpp"
3378 #include "moc_qtreewidget_p.cpp"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
FT_UInt idx
Definition: cffcmap.c:135
The QAbstractItemModel class provides the abstract interface for item model classes.
QModelIndexList persistentIndexList() const
void beginRemoveColumns(const QModelIndex &parent, int first, int last)
void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to)
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
QObject * parent() const
Definition: qobject.h:409
virtual QMimeData * mimeData(const QModelIndexList &indexes) const
void layoutChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
bool checkIndex(const QModelIndex &index, CheckIndexOptions options=CheckIndexOption::NoOption) const
void headerDataChanged(Qt::Orientation orientation, int first, int last)
void beginInsertColumns(const QModelIndex &parent, int first, int last)
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
void beginRemoveRows(const QModelIndex &parent, int first, int last)
virtual Q_INVOKABLE QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const =0
void beginInsertRows(const QModelIndex &parent, int first, int last)
static bool variantLessThan(const QVariant &v1, const QVariant &v2)
struct QAbstractItemModelPrivate::Persistent persistent
QWidget * indexWidget(const QModelIndex &index) const
void activated(const QModelIndex &index)
QAbstractItemModel * model() const
void setCurrentIndex(const QModelIndex &index)
void doubleClicked(const QModelIndex &index)
bool event(QEvent *event) override
void entered(const QModelIndex &index)
QModelIndex currentIndex() const
bool isPersistentEditorOpen(const QModelIndex &index) const
void setIndexWidget(const QModelIndex &index, QWidget *widget)
void openPersistentEditor(const QModelIndex &index)
void pressed(const QModelIndex &index)
void clicked(const QModelIndex &index)
void edit(const QModelIndex &index)
QItemSelectionModel * selectionModel() const
void closePersistentEditor(const QModelIndex &index)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int timerId() const noexcept
Definition: qbasictimer.h:69
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
bool hasSeen(const T &s)
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
@ Polish
Definition: qcoreevent.h:124
void setSectionsClickable(bool clickable)
void setSortIndicator(int logicalIndex, Qt::SortOrder order)
Qt::SortOrder sortIndicatorOrder() const
int logicalIndexAt(int position) const
int sortIndicatorSection() const
The QItemSelection class manages information about selected items in a model.
Q_CORE_EXPORT QModelIndexList indexes() const
QModelIndexList selectedIndexes
virtual void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
qsizetype size() const noexcept
Definition: qlist.h:414
bool isEmpty() const noexcept
Definition: qlist.h:418
iterator erase(const_iterator begin, const_iterator end)
Definition: qlist.h:893
iterator insert(qsizetype i, parameter_type t)
Definition: qlist.h:499
iterator end()
Definition: qlist.h:624
T takeAt(qsizetype i)
Definition: qlist.h:607
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
value_type takeFirst()
Definition: qlist.h:564
qsizetype count() const noexcept
Definition: qlist.h:415
iterator begin()
Definition: qlist.h:623
void reserve(qsizetype size)
Definition: qlist.h:757
void replace(qsizetype i, parameter_type t)
Definition: qlist.h:541
void resize(qsizetype size)
Definition: qlist.h:420
T & first()
Definition: qlist.h:643
const_iterator cend() const noexcept
Definition: qlist.h:629
void append(parameter_type t)
Definition: qlist.h:469
const_iterator cbegin() const noexcept
Definition: qlist.h:628
void clear()
Definition: qlist.h:445
Definition: qmap.h:222
iterator insert(const Key &key, const T &value)
Definition: qmap.h:719
The QMimeData class provides a container for data that records information about its MIME type.
Definition: qmimedata.h:52
The QModelIndex class is used to locate data in a data model.
constexpr int row() const noexcept
QModelIndex parent() const
constexpr int column() const noexcept
constexpr bool isValid() const noexcept
bool contains(const Key &key) const noexcept
Definition: qhash.h:1510
const QObjectList & children() const
Definition: qobject.h:206
virtual void timerEvent(QTimerEvent *event)
Definition: qobject.cpp:1399
bool signalsBlocked() const noexcept
Definition: qobject.h:151
QScopedPointer< QObjectData > d_ptr
Definition: qobject.h:436
The QPersistentModelIndex class is used to locate data in a data model.
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
T * data() const noexcept
int columnCount(const QModelIndex &parent=QModelIndex()) const override
The QStack class is a template class that provides a stack.
Definition: qstack.h:49
T pop()
Definition: qstack.h:54
void push(const T &t)
Definition: qstack.h:53
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString number(int, int base=10)
Definition: qstring.cpp:7538
The QStringList class provides a list of strings.
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:367
int timerId() const
Definition: qcoreevent.h:372
bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
Definition: qtreewidget.cpp:67
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) override
void ensureSorted(int column, Qt::SortOrder order, int start, int end, const QModelIndex &parent)
int rowCount(const QModelIndex &parent) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
bool insertColumns(int column, int count, const QModelIndex &) override
void emitDataChanged(QTreeWidgetItem *item, int column, const QList< int > &roles)
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
void endInsertItems()
void itemChanged(QTreeWidgetItem *item)
void setColumnCount(int columns)
friend class QTreeWidgetItem
Definition: qtreewidget_p.h:75
void clear()
bool insertRows(int row, int count, const QModelIndex &) override
void sortItems(QList< QTreeWidgetItem * > *items, int column, Qt::SortOrder order)
QMimeData * internalMimeData() const
QTreeWidgetItem * item(const QModelIndex &index) const
Qt::DropActions supportedDropActions() const override
QMimeData * mimeData(const QModelIndexList &indexes) const override
QTreeModel(int columns=0, QTreeWidget *parent=nullptr)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
void sort(int column, Qt::SortOrder order) override
static bool itemLessThan(const QPair< QTreeWidgetItem *, int > &left, const QPair< QTreeWidgetItem *, int > &right)
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
bool clearItemData(const QModelIndex &index) override
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
static QList< QTreeWidgetItem * >::iterator sortedInsertionIterator(const QList< QTreeWidgetItem * >::iterator &begin, const QList< QTreeWidgetItem * >::iterator &end, Qt::SortOrder order, QTreeWidgetItem *item)
QStringList mimeTypes() const override
QMap< int, QVariant > itemData(const QModelIndex &index) const override
QModelIndex index(const QTreeWidgetItem *item, int column) const
bool hasChildren(const QModelIndex &parent) const override
void timerEvent(QTimerEvent *) override
void beginRemoveItems(QTreeWidgetItem *parent, int row, int count)
void beginInsertItems(QTreeWidgetItem *parent, int row, int count)
void endRemoveItems()
static bool itemGreaterThan(const QPair< QTreeWidgetItem *, int > &left, const QPair< QTreeWidgetItem *, int > &right)
QTreeWidget * view() const
Definition: qtreewidget_p.h:84
bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
Definition: qtreewidget.cpp:60
The QTreeView class provides a default model/view implementation of a tree view.
Definition: qtreeview.h:56
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >()) override
Definition: qtreeview.cpp:677
bool isSortingEnabled() const
Definition: qtreeview.cpp:888
void expand(const QModelIndex &index)
Definition: qtreeview.cpp:762
void setSelectionModel(QItemSelectionModel *selectionModel) override
Definition: qtreeview.cpp:270
void collapse(const QModelIndex &index)
Definition: qtreeview.cpp:797
void setModel(QAbstractItemModel *model) override
Definition: qtreeview.cpp:214
QModelIndex indexBelow(const QModelIndex &index) const
Definition: qtreeview.cpp:2097
bool isExpanded(const QModelIndex &index) const
Definition: qtreeview.cpp:834
QHeaderView * header() const
Definition: qtreeview.cpp:295
void setExpanded(const QModelIndex &index, bool expand)
Definition: qtreeview.cpp:846
QModelIndex indexAt(const QPoint &p) const override
Definition: qtreeview.cpp:2057
void currentChanged(const QModelIndex &current, const QModelIndex &previous) override
Definition: qtreeview.cpp:4013
QModelIndex indexAbove(const QModelIndex &index) const
Definition: qtreeview.cpp:2081
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override
Definition: qtreeview.cpp:4045
void setFirstColumnSpanned(int row, const QModelIndex &parent, bool span)
Definition: qtreeview.cpp:652
QModelIndexList selectedIndexes() const override
Definition: qtreeview.cpp:2430
void collapsed(const QModelIndex &index)
void scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible) override
Definition: qtreeview.cpp:1144
void setRowHidden(int row, const QModelIndex &parent, bool hide)
Definition: qtreeview.cpp:608
bool isRowHidden(int row, const QModelIndex &parent) const
Definition: qtreeview.cpp:595
QRect visualRect(const QModelIndex &index) const override
Definition: qtreeview.cpp:1104
bool isFirstColumnSpanned(int row, const QModelIndex &parent) const
Definition: qtreeview.cpp:634
void expanded(const QModelIndex &index)
QHeaderView * header
Definition: qtreeview_p.h:189
The QTreeWidget class provides a tree view that uses a predefined tree model.
Definition: qtreewidget.h:250
void expandItem(const QTreeWidgetItem *item)
void addTopLevelItems(const QList< QTreeWidgetItem * > &items)
QTreeWidgetItem * topLevelItem(int index) const
QModelIndex indexFromItem(const QTreeWidgetItem *item, int column=0) const
void sortItems(int column, Qt::SortOrder order)
void closePersistentEditor(QTreeWidgetItem *item, int column=0)
QTreeWidgetItem * invisibleRootItem() const
QList< QTreeWidgetItem * > findItems(const QString &text, Qt::MatchFlags flags, int column=0) const
QRect visualItemRect(const QTreeWidgetItem *item) const
virtual bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action)
void addTopLevelItem(QTreeWidgetItem *item)
bool event(QEvent *e) override
QWidget * itemWidget(QTreeWidgetItem *item, int column) const
void collapseItem(const QTreeWidgetItem *item)
QTreeWidgetItem * takeTopLevelItem(int index)
virtual QMimeData * mimeData(const QList< QTreeWidgetItem * > &items) const
friend class QTreeModel
Definition: qtreewidget.h:255
void openPersistentEditor(QTreeWidgetItem *item, int column=0)
QTreeWidget(QWidget *parent=nullptr)
virtual QStringList mimeTypes() const
QTreeWidgetItem * itemAbove(const QTreeWidgetItem *item) const
void insertTopLevelItems(int index, const QList< QTreeWidgetItem * > &items)
void setSelectionModel(QItemSelectionModel *selectionModel) override
bool isPersistentEditorOpen(const QModelIndex &index) const
void setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
QList< QTreeWidgetItem * > selectedItems() const
void editItem(QTreeWidgetItem *item, int column=0)
QTreeWidgetItem * itemAt(const QPoint &p) const
int columnCount
the number of columns displayed in the tree widget
Definition: qtreewidget.h:252
void setCurrentItem(QTreeWidgetItem *item)
void insertTopLevelItem(int index, QTreeWidgetItem *item)
QTreeWidgetItem * headerItem() const
void setHeaderItem(QTreeWidgetItem *item)
int sortColumn() const
int indexOfTopLevelItem(QTreeWidgetItem *item) const
QTreeWidgetItem * itemFromIndex(const QModelIndex &index) const
QTreeWidgetItem * itemBelow(const QTreeWidgetItem *item) const
QTreeWidgetItem * currentItem() const
virtual Qt::DropActions supportedDropActions() const
void scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint=EnsureVisible)
int topLevelItemCount
the number of top-level items
Definition: qtreewidget.h:253
void setColumnCount(int columns)
void setHeaderLabels(const QStringList &labels)
int currentColumn() const
The QTreeWidgetItem class provides an item for use with the QTreeWidget convenience class.
Definition: qtreewidget.h:59
void setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy)
void insertChildren(int index, const QList< QTreeWidgetItem * > &children)
void setExpanded(bool expand)
void setHidden(bool hide)
void setText(int column, const QString &text)
Definition: qtreewidget.h:215
QTreeWidgetItem & operator=(const QTreeWidgetItem &other)
QTreeWidgetItem * child(int index) const
Definition: qtreewidget.h:169
bool isFirstColumnSpanned() const
bool isSelected() const
QTreeWidgetItem * takeChild(int index)
virtual bool operator<(const QTreeWidgetItem &other) const
virtual void setData(int column, int role, const QVariant &value)
void setFirstColumnSpanned(bool span)
QTreeWidgetItem(int type=Type)
virtual void read(QDataStream &in)
QTreeWidgetItem * parent() const
Definition: qtreewidget.h:168
void insertChild(int index, QTreeWidgetItem *child)
void addChildren(const QList< QTreeWidgetItem * > &children)
void setFlags(Qt::ItemFlags flags)
QDataStream & operator<<(QDataStream &out, const QTreeWidgetItem &item)
bool isHidden() const
void sortChildren(int column, Qt::SortOrder order)
Definition: qtreewidget.h:189
@ DontShowIndicatorWhenChildless
Definition: qtreewidget.h:97
QDataStream & operator>>(QDataStream &in, QTreeWidgetItem &item)
int childCount() const
Definition: qtreewidget.h:175
virtual ~QTreeWidgetItem()
void setSelected(bool select)
Qt::ItemFlags flags() const
void removeChild(QTreeWidgetItem *child)
QTreeWidgetItem::ChildIndicatorPolicy childIndicatorPolicy() const
bool isExpanded() const
int columnCount() const
Definition: qtreewidget.h:176
void addChild(QTreeWidgetItem *child)
virtual QVariant data(int column, int role) const
virtual void write(QDataStream &out) const
virtual QTreeWidgetItem * clone() const
QList< QTreeWidgetItem * > takeChildren()
void sortChildren(int column, Qt::SortOrder order, bool climb)
void updateHiddenStatus(QTreeWidgetItem *item, bool inserting)
QTreeWidgetItem::ChildIndicatorPolicy policy
void propagateDisabled(QTreeWidgetItem *item)
QTreeWidgetItem * item(const QModelIndex &index) const
void _q_emitItemChanged(const QModelIndex &index)
void _q_emitItemCollapsed(const QModelIndex &index)
void _q_emitItemDoubleClicked(const QModelIndex &index)
void _q_emitItemEntered(const QModelIndex &index)
void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
QTreeModel * treeModel() const
void _q_emitItemClicked(const QModelIndex &index)
void _q_emitItemActivated(const QModelIndex &index)
void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index)
void _q_emitItemPressed(const QModelIndex &index)
void _q_emitItemExpanded(const QModelIndex &index)
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
bool isValid() const
Definition: qvariant.h:582
T value() const
Definition: qvariant.h:378
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
Definition: base.h:37
#define this
Definition: dialogs.cpp:56
QOpenGLWidget * widget
[1]
QString text
[meta data]
double pi
[0]
double e
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
Definition: qnamespace.h:55
CheckState
Definition: qnamespace.h:1495
@ Unchecked
Definition: qnamespace.h:1496
@ Checked
Definition: qnamespace.h:1498
@ PartiallyChecked
Definition: qnamespace.h:1497
Orientation
Definition: qnamespace.h:123
@ Horizontal
Definition: qnamespace.h:124
@ EditRole
Definition: qnamespace.h:1504
@ CheckStateRole
Definition: qnamespace.h:1513
@ DisplayRole
Definition: qnamespace.h:1502
SortOrder
Definition: qnamespace.h:146
@ AscendingOrder
Definition: qnamespace.h:147
DropAction
Definition: qnamespace.h:1484
@ MoveAction
Definition: qnamespace.h:1486
@ ItemIsEnabled
Definition: qnamespace.h:1537
@ ItemIsDropEnabled
Definition: qnamespace.h:1535
@ ItemIsAutoTristate
Definition: qnamespace.h:1538
action
Definition: devices.py:78
constexpr struct q20::ranges::@310 all_of
void
Definition: png.h:1080
#define Q_FALLTHROUGH()
#define Q_UNLIKELY(x)
std::pair< T1, T2 > QPair
Definition: qcontainerfwd.h:56
EGLOutputLayerEXT EGLint EGLAttrib value
@ text
#define qWarning
Definition: qlogging.h:179
#define SLOT(a)
Definition: qobjectdefs.h:87
#define SIGNAL(a)
Definition: qobjectdefs.h:88
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLenum type
Definition: qopengl.h:270
GLint GLfloat GLfloat GLfloat v2
GLenum GLsizei GLsizei GLint * values
[16]
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLboolean r
[2]
GLuint index
[2]
GLuint GLuint end
GLsizei const GLchar ** strings
[1]
GLenum GLenum GLsizei count
GLdouble GLdouble right
GLfloat GLfloat f
GLint left
GLbitfield flags
GLint GLfloat GLfloat v1
GLboolean enable
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLenum GLuint GLintptr offset
GLint first
GLfloat n
GLsizei GLenum const void * indices
GLenum GLenum GLsizei void GLsizei void * column
Definition: qopenglext.h:2747
struct _cl_event * event
Definition: qopenglext.h:2998
GLuint GLenum GLenum transform
Definition: qopenglext.h:11564
const GLubyte * c
Definition: qopenglext.h:12701
GLuint in
Definition: qopenglext.h:8870
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLenum GLenum GLsizei void * row
Definition: qopenglext.h:2747
GLenum GLenum GLsizei void GLsizei void void * span
Definition: qopenglext.h:2747
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLfixed GLfixed GLint GLint order
Definition: qopenglext.h:5206
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define emit
Definition: qtmetamacros.h:85
QSqlQueryModel * model
[16]
Q_UNUSED(salary)
[21]
QTextStream out(stdout)
[7]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
edit hide()
selection select(topLeft, bottomRight)
QList< QTreeWidgetItem * > items
QLayoutItem * child
[0]
QSizePolicy policy
QStringList::Iterator it
QMultiHash< QModelIndex, QPersistentModelIndexData * > indexes
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition: qlist.h:966
bool contains(const AT &t) const noexcept
Definition: qlist.h:78
qsizetype lastIndexOf(const AT &t, qsizetype from=-1) const noexcept
Definition: qlist.h:973
Definition: moc.h:48
void compare(Input input, FnUnderTest fn_under_test, const QByteArray &output)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent