source: trunk/src/gui/itemviews/qtreewidget.cpp@ 1147

Last change on this file since 1147 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 97.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qtreewidget.h"
43
44#ifndef QT_NO_TREEWIDGET
45#include <qheaderview.h>
46#include <qpainter.h>
47#include <qitemdelegate.h>
48#include <qstack.h>
49#include <qdebug.h>
50#include <private/qtreewidget_p.h>
51#include <private/qwidgetitemdata_p.h>
52#include <private/qtreewidgetitemiterator_p.h>
53
54QT_BEGIN_NAMESPACE
55
56// workaround for VC++ 6.0 linker bug (?)
57typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&);
58
59class QTreeModelLessThan
60{
61public:
62 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
63 { return *i1 < *i2; }
64};
65
66class QTreeModelGreaterThan
67{
68public:
69 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
70 { return *i2 < *i1; }
71};
72
73/*
74 \class QTreeModel
75 \brief The QTreeModel class manages the items stored in a tree view.
76
77 \ingroup model-view
78
79*/
80
81/*!
82 \enum QTreeWidgetItem::ChildIndicatorPolicy
83 \since 4.3
84
85 \value ShowIndicator The controls for expanding and collapsing will be shown for this item even if there are no children.
86 \value DontShowIndicator The controls for expanding and collapsing will never be shown even if there are children. If the node is forced open the user will not be able to expand or collapse the item.
87 \value DontShowIndicatorWhenChildless The controls for expanding and collapsing will be shown if the item contains children.
88*/
89
90/*!
91 \fn void QTreeWidgetItem::setDisabled(bool disabled)
92 \since 4.3
93
94 Disables the item if \a disabled is true; otherwise enables the item.
95
96 \sa setFlags()
97*/
98
99/*!
100 \fn bool QTreeWidgetItem::isDisabled() const
101 \since 4.3
102
103 Returns true if the item is disabled; otherwise returns false.
104
105 \sa setFlags()
106*/
107
108/*!
109 \internal
110
111 Constructs a tree model with a \a parent object and the given
112 number of \a columns.
113*/
114
115QTreeModel::QTreeModel(int columns, QTreeWidget *parent)
116 : QAbstractItemModel(parent), rootItem(new QTreeWidgetItem),
117 headerItem(new QTreeWidgetItem), skipPendingSort(false)
118{
119 rootItem->view = parent;
120 rootItem->itemFlags = Qt::ItemIsDropEnabled;
121 headerItem->view = parent;
122 setColumnCount(columns);
123}
124
125/*!
126 \internal
127
128*/
129
130QTreeModel::QTreeModel(QTreeModelPrivate &dd, QTreeWidget *parent)
131 : QAbstractItemModel(dd, parent), rootItem(new QTreeWidgetItem),
132 headerItem(new QTreeWidgetItem), skipPendingSort(false)
133{
134 rootItem->view = parent;
135 rootItem->itemFlags = Qt::ItemIsDropEnabled;
136 headerItem->view = parent;
137}
138
139/*!
140 \internal
141
142 Destroys this tree model.
143*/
144
145QTreeModel::~QTreeModel()
146{
147 clear();
148 delete headerItem;
149 rootItem->view = 0;
150 delete rootItem;
151}
152
153/*!
154 \internal
155
156 Removes all items in the model.
157*/
158
159void QTreeModel::clear()
160{
161 SkipSorting skipSorting(this);
162 for (int i = 0; i < rootItem->childCount(); ++i) {
163 QTreeWidgetItem *item = rootItem->children.at(i);
164 item->par = 0;
165 item->view = 0;
166 delete item;
167 }
168 rootItem->children.clear();
169 sortPendingTimer.stop();
170 reset();
171}
172
173/*!
174 \internal
175
176 Sets the number of \a columns in the tree model.
177*/
178
179void QTreeModel::setColumnCount(int columns)
180{
181 SkipSorting skipSorting(this);
182 if (columns < 0)
183 return;
184 if (!headerItem) {
185 headerItem = new QTreeWidgetItem();
186 headerItem->view = view();
187 }
188 int count = columnCount();
189 if (count == columns)
190 return;
191
192 if (columns < count) {
193 beginRemoveColumns(QModelIndex(), columns, count - 1);
194 headerItem->values.resize(columns);
195 endRemoveColumns();
196 } else {
197 beginInsertColumns(QModelIndex(), count, columns - 1);
198 headerItem->values.resize(columns);
199 for (int i = count; i < columns; ++i) {// insert data without emitting the dataChanged signal
200 headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
201 headerItem->d->display.append(QString::number(i + 1));
202 }
203 endInsertColumns();
204 }
205}
206
207/*!
208 \internal
209
210 Returns the tree view item corresponding to the \a index given.
211
212 \sa QModelIndex
213*/
214
215QTreeWidgetItem *QTreeModel::item(const QModelIndex &index) const
216{
217 if (!index.isValid())
218 return 0;
219 return static_cast<QTreeWidgetItem*>(index.internalPointer());
220}
221
222/*!
223 \internal
224
225 Returns the model index that refers to the
226 tree view \a item and \a column.
227*/
228
229QModelIndex QTreeModel::index(const QTreeWidgetItem *item, int column) const
230{
231 executePendingSort();
232
233 if (!item || (item == rootItem))
234 return QModelIndex();
235 const QTreeWidgetItem *par = item->parent();
236 QTreeWidgetItem *itm = const_cast<QTreeWidgetItem*>(item);
237 if (!par)
238 par = rootItem;
239 int row;
240 int guess = item->d->rowGuess;
241 if (guess >= 0
242 && par->children.count() > guess
243 && par->children.at(guess) == itm) {
244 row = guess;
245 } else {
246 row = par->children.lastIndexOf(itm);
247 itm->d->rowGuess = row;
248 }
249 return createIndex(row, column, itm);
250}
251
252/*!
253 \internal
254 \reimp
255
256 Returns the model index with the given \a row,
257 \a column and \a parent.
258*/
259
260QModelIndex QTreeModel::index(int row, int column, const QModelIndex &parent) const
261{
262 executePendingSort();
263
264 int c = columnCount(parent);
265 if (row < 0 || column < 0 || column >= c)
266 return QModelIndex();
267
268 QTreeWidgetItem *parentItem = parent.isValid() ? item(parent) : rootItem;
269 if (parentItem && row < parentItem->childCount()) {
270 QTreeWidgetItem *itm = parentItem->child(row);
271 if (itm)
272 return createIndex(row, column, itm);
273 return QModelIndex();
274 }
275
276 return QModelIndex();
277}
278
279/*!
280 \internal
281 \reimp
282
283 Returns the parent model index of the index given as
284 the \a child.
285*/
286
287QModelIndex QTreeModel::parent(const QModelIndex &child) const
288{
289 SkipSorting skipSorting(this); //The reason we don't sort here is that this might be called from a valid QPersistentModelIndex
290 //We don't want it to become suddenly invalid
291
292 if (!child.isValid())
293 return QModelIndex();
294 QTreeWidgetItem *itm = static_cast<QTreeWidgetItem *>(child.internalPointer());
295 if (!itm || itm == rootItem)
296 return QModelIndex();
297 QTreeWidgetItem *parent = itm->parent();
298 return index(parent, 0);
299}
300
301/*!
302 \internal
303 \reimp
304
305 Returns the number of rows in the \a parent model index.
306*/
307
308int QTreeModel::rowCount(const QModelIndex &parent) const
309{
310 if (!parent.isValid())
311 return rootItem->childCount();
312
313 QTreeWidgetItem *parentItem = item(parent);
314 if (parentItem)
315 return parentItem->childCount();
316 return 0;
317}
318
319/*!
320 \internal
321 \reimp
322
323 Returns the number of columns in the item referred to by
324 the given \a index.
325*/
326
327int QTreeModel::columnCount(const QModelIndex &index) const
328{
329 Q_UNUSED(index);
330 if (!headerItem)
331 return 0;
332 return headerItem->columnCount();
333}
334
335bool QTreeModel::hasChildren(const QModelIndex &parent) const
336{
337 if (!parent.isValid())
338 return (rootItem->childCount() > 0);
339
340 QTreeWidgetItem *itm = item(parent);
341 if (!itm)
342 return false;
343 switch (itm->d->policy) {
344 case QTreeWidgetItem::ShowIndicator:
345 return true;
346 case QTreeWidgetItem::DontShowIndicator:
347 return false;
348 case QTreeWidgetItem::DontShowIndicatorWhenChildless:
349 return (itm->childCount() > 0);
350 }
351 return false;
352}
353
354/*!
355 \internal
356 \reimp
357
358 Returns the data corresponding to the given model \a index
359 and \a role.
360*/
361
362QVariant QTreeModel::data(const QModelIndex &index, int role) const
363{
364 if (!index.isValid())
365 return QVariant();
366 QTreeWidgetItem *itm = item(index);
367 if (itm)
368 return itm->data(index.column(), role);
369 return QVariant();
370}
371
372/*!
373 \internal
374 \reimp
375
376 Sets the data for the item specified by the \a index and \a role
377 to that referred to by the \a value.
378
379 Returns true if successful; otherwise returns false.
380*/
381
382bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
383{
384 if (!index.isValid())
385 return false;
386 QTreeWidgetItem *itm = item(index);
387 if (itm) {
388 itm->setData(index.column(), role, value);
389 return true;
390 }
391 return false;
392}
393
394QMap<int, QVariant> QTreeModel::itemData(const QModelIndex &index) const
395{
396 QMap<int, QVariant> roles;
397 QTreeWidgetItem *itm = item(index);
398 if (itm) {
399 int column = index.column();
400 if (column < itm->values.count()) {
401 for (int i = 0; i < itm->values.at(column).count(); ++i) {
402 roles.insert(itm->values.at(column).at(i).role,
403 itm->values.at(column).at(i).value);
404 }
405 }
406
407 // the two special cases
408 QVariant displayValue = itm->data(column, Qt::DisplayRole);
409 if (displayValue.isValid())
410 roles.insert(Qt::DisplayRole, displayValue);
411
412 QVariant checkValue = itm->data(column, Qt::CheckStateRole);
413 if (checkValue.isValid())
414 roles.insert(Qt::CheckStateRole, checkValue);
415 }
416 return roles;
417}
418
419/*!
420 \internal
421 \reimp
422*/
423bool QTreeModel::insertRows(int row, int count, const QModelIndex &parent)
424{
425 SkipSorting skipSorting(this);
426 if (count < 1 || row < 0 || row > rowCount(parent) || parent.column() > 0)
427 return false;
428
429 beginInsertRows(parent, row, row + count - 1);
430 QTreeWidgetItem *par = item(parent);
431 while (count > 0) {
432 QTreeWidgetItem *item = new QTreeWidgetItem();
433 item->view = view();
434 item->par = par;
435 if (par)
436 par->children.insert(row++, item);
437 else
438 rootItem->children.insert(row++, item);
439 --count;
440 }
441 endInsertRows();
442 return true;
443}
444
445/*!
446 \internal
447 \reimp
448*/
449bool QTreeModel::insertColumns(int column, int count, const QModelIndex &parent)
450{
451 SkipSorting skipSorting(this);
452 if (count < 1 || column < 0 || column > columnCount(parent) || parent.column() > 0 || !headerItem)
453 return false;
454
455 beginInsertColumns(parent, column, column + count - 1);
456
457 int oldCount = columnCount(parent);
458 column = qBound(0, column, oldCount);
459 headerItem->values.resize(oldCount + count);
460 for (int i = oldCount; i < oldCount + count; ++i) {
461 headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
462 headerItem->d->display.append(QString::number(i + 1));
463 }
464
465 QStack<QTreeWidgetItem*> itemstack;
466 itemstack.push(0);
467 while (!itemstack.isEmpty()) {
468 QTreeWidgetItem *par = itemstack.pop();
469 QList<QTreeWidgetItem*> children = par ? par->children : rootItem->children;
470 for (int row = 0; row < children.count(); ++row) {
471 QTreeWidgetItem *child = children.at(row);
472 if (child->children.count())
473 itemstack.push(child);
474 child->values.insert(column, count, QVector<QWidgetItemData>());
475 }
476 }
477
478 endInsertColumns();
479 return true;
480}
481
482/*!
483 \internal
484 \reimp
485*/
486bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) {
487 if (count < 1 || row < 0 || (row + count) > rowCount(parent))
488 return false;
489
490 beginRemoveRows(parent, row, row + count - 1);
491
492 bool blockSignal = signalsBlocked();
493 blockSignals(true);
494
495 QTreeWidgetItem *itm = item(parent);
496 for (int i = row + count - 1; i >= row; --i) {
497 QTreeWidgetItem *child = itm ? itm->takeChild(i) : rootItem->children.takeAt(i);
498 Q_ASSERT(child);
499 child->view = 0;
500 delete child;
501 child = 0;
502 }
503 blockSignals(blockSignal);
504
505 endRemoveRows();
506 return true;
507}
508
509/*!
510 \internal
511 \reimp
512
513 Returns the header data corresponding to the given header \a section,
514 \a orientation and data \a role.
515*/
516
517QVariant QTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
518{
519 if (orientation != Qt::Horizontal)
520 return QVariant();
521
522 if (headerItem)
523 return headerItem->data(section, role);
524 if (role == Qt::DisplayRole)
525 return QString::number(section + 1);
526 return QVariant();
527}
528
529/*!
530 \internal
531 \reimp
532
533 Sets the header data for the item specified by the header \a section,
534 \a orientation and data \a role to the given \a value.
535
536 Returns true if successful; otherwise returns false.
537*/
538
539bool QTreeModel::setHeaderData(int section, Qt::Orientation orientation,
540 const QVariant &value, int role)
541{
542 if (section < 0 || orientation != Qt::Horizontal || !headerItem || section >= columnCount())
543 return false;
544
545 headerItem->setData(section, role, value);
546 return true;
547}
548
549/*!
550 \reimp
551
552 Returns the flags for the item referred to the given \a index.
553
554*/
555
556Qt::ItemFlags QTreeModel::flags(const QModelIndex &index) const
557{
558 if (!index.isValid())
559 return rootItem->flags();
560 QTreeWidgetItem *itm = item(index);
561 Q_ASSERT(itm);
562 return itm->flags();
563}
564
565/*!
566 \internal
567
568 Sorts the entire tree in the model in the given \a order,
569 by the values in the given \a column.
570*/
571
572void QTreeModel::sort(int column, Qt::SortOrder order)
573{
574 SkipSorting skipSorting(this);
575 sortPendingTimer.stop();
576
577 if (column < 0 || column >= columnCount())
578 return;
579
580 //layoutAboutToBeChanged and layoutChanged will be called by sortChildren
581 rootItem->sortChildren(column, order, true);
582}
583
584/*!
585 \internal
586*/
587void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
588 int start, int end, const QModelIndex &parent)
589{
590 if (isChanging())
591 return;
592
593 sortPendingTimer.stop();
594
595 if (column < 0 || column >= columnCount())
596 return;
597
598 SkipSorting skipSorting(this);
599
600 QTreeWidgetItem *itm = item(parent);
601 if (!itm)
602 itm = rootItem;
603 QList<QTreeWidgetItem*> lst = itm->children;
604
605 int count = end - start + 1;
606 QVector < QPair<QTreeWidgetItem*,int> > sorting(count);
607 for (int i = 0; i < count; ++i) {
608 sorting[i].first = lst.at(start + i);
609 sorting[i].second = start + i;
610 }
611
612 LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
613 qStableSort(sorting.begin(), sorting.end(), compare);
614
615 QModelIndexList oldPersistentIndexes;
616 QModelIndexList newPersistentIndexes;
617 QList<QTreeWidgetItem*>::iterator lit = lst.begin();
618 bool changed = false;
619
620 for (int i = 0; i < count; ++i) {
621 int oldRow = sorting.at(i).second;
622 QTreeWidgetItem *item = lst.takeAt(oldRow);
623 lit = sortedInsertionIterator(lit, lst.end(), order, item);
624 int newRow = qMax(lit - lst.begin(), 0);
625
626 if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)) && !(*lst.at(oldRow - 1) < *item ))
627 newRow = oldRow;
628
629 lit = lst.insert(lit, item);
630 if (newRow != oldRow) {
631 // we are going to change the persistent indexes, so we need to prepare
632 if (!changed) { // this will only happen once
633 changed = true;
634 emit layoutAboutToBeChanged(); // the selection model needs to know
635 oldPersistentIndexes = persistentIndexList();
636 newPersistentIndexes = oldPersistentIndexes;
637 }
638 for (int j = i + 1; j < count; ++j) {
639 int otherRow = sorting.at(j).second;
640 if (oldRow < otherRow && newRow >= otherRow)
641 --sorting[j].second;
642 else if (oldRow > otherRow && newRow <= otherRow)
643 ++sorting[j].second;
644 }
645 for (int k = 0; k < newPersistentIndexes.count(); ++k) {
646 QModelIndex pi = newPersistentIndexes.at(k);
647 if (pi.parent() != parent)
648 continue;
649 int oldPersistentRow = pi.row();
650 int newPersistentRow = oldPersistentRow;
651 if (oldPersistentRow == oldRow)
652 newPersistentRow = newRow;
653 else if (oldRow < oldPersistentRow && newRow >= oldPersistentRow)
654 newPersistentRow = oldPersistentRow - 1;
655 else if (oldRow > oldPersistentRow && newRow <= oldPersistentRow)
656 newPersistentRow = oldPersistentRow + 1;
657 if (newPersistentRow != oldPersistentRow)
658 newPersistentIndexes[k] = createIndex(newPersistentRow,
659 pi.column(), pi.internalPointer());
660 }
661 }
662 }
663
664 if (changed) {
665 itm->children = lst;
666 changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
667 emit layoutChanged();
668 }
669}
670
671/*!
672 \internal
673
674 Returns true if the value of the \a left item is
675 less than the value of the \a right item.
676
677 Used by the sorting functions.
678*/
679
680bool QTreeModel::itemLessThan(const QPair<QTreeWidgetItem*,int> &left,
681 const QPair<QTreeWidgetItem*,int> &right)
682{
683 return *(left.first) < *(right.first);
684}
685
686/*!
687 \internal
688
689 Returns true if the value of the \a left item is
690 greater than the value of the \a right item.
691
692 Used by the sorting functions.
693*/
694
695bool QTreeModel::itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left,
696 const QPair<QTreeWidgetItem*,int> &right)
697{
698 return *(right.first) < *(left.first);
699}
700
701/*!
702 \internal
703*/
704QList<QTreeWidgetItem*>::iterator QTreeModel::sortedInsertionIterator(
705 const QList<QTreeWidgetItem*>::iterator &begin,
706 const QList<QTreeWidgetItem*>::iterator &end,
707 Qt::SortOrder order, QTreeWidgetItem *item)
708{
709 if (order == Qt::AscendingOrder)
710 return qLowerBound(begin, end, item, QTreeModelLessThan());
711 return qLowerBound(begin, end, item, QTreeModelGreaterThan());
712}
713
714QStringList QTreeModel::mimeTypes() const
715{
716 return view()->mimeTypes();
717}
718
719QMimeData *QTreeModel::internalMimeData() const
720{
721 return QAbstractItemModel::mimeData(cachedIndexes);
722}
723
724QMimeData *QTreeModel::mimeData(const QModelIndexList &indexes) const
725{
726 QList<QTreeWidgetItem*> items;
727 for (int i = 0; i < indexes.count(); ++i) {
728 if (indexes.at(i).column() == 0) // only one item per row
729 items << item(indexes.at(i));
730 }
731
732 // cachedIndexes is a little hack to avoid copying from QModelIndexList to
733 // QList<QTreeWidgetItem*> and back again in the view
734 cachedIndexes = indexes;
735 QMimeData *mimeData = view()->mimeData(items);
736 cachedIndexes.clear();
737 return mimeData;
738}
739
740bool QTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
741 int row, int column, const QModelIndex &parent)
742{
743 if (row == -1 && column == -1)
744 row = rowCount(parent); // append
745 return view()->dropMimeData(item(parent), row, data, action);
746}
747
748Qt::DropActions QTreeModel::supportedDropActions() const
749{
750 return view()->supportedDropActions();
751}
752
753void QTreeModel::itemChanged(QTreeWidgetItem *item)
754{
755 SkipSorting skipSorting(this); //this is kind of wrong, but not doing this would kill performence
756 QModelIndex left = index(item, 0);
757 QModelIndex right = index(item, item->columnCount() - 1);
758 emit dataChanged(left, right);
759}
760
761bool QTreeModel::isChanging() const
762{
763 Q_D(const QTreeModel);
764 return !d->changes.isEmpty();
765}
766
767/*!
768 \internal
769 Emits the dataChanged() signal for the given \a item.
770 if column is -1 then all columns have changed
771*/
772
773void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column)
774{
775 if (signalsBlocked())
776 return;
777
778 if (headerItem == item && column < item->columnCount()) {
779 if (column == -1)
780 emit headerDataChanged(Qt::Horizontal, 0, columnCount() - 1);
781 else
782 emit headerDataChanged(Qt::Horizontal, column, column);
783 return;
784 }
785
786 SkipSorting skipSorting(this); //This is a little bit wrong, but not doing it would kill performence
787
788 QModelIndex bottomRight, topLeft;
789 if (column == -1) {
790 topLeft = index(item, 0);
791 bottomRight = createIndex(topLeft.row(), columnCount() - 1, item);
792 } else {
793 topLeft = index(item, column);
794 bottomRight = topLeft;
795 }
796 emit dataChanged(topLeft, bottomRight);
797}
798
799void QTreeModel::beginInsertItems(QTreeWidgetItem *parent, int row, int count)
800{
801 QModelIndex par = index(parent, 0);
802 beginInsertRows(par, row, row + count - 1);
803}
804
805void QTreeModel::endInsertItems()
806{
807 endInsertRows();
808}
809
810void QTreeModel::beginRemoveItems(QTreeWidgetItem *parent, int row, int count)
811{
812 Q_ASSERT(row >= 0);
813 Q_ASSERT(count > 0);
814 beginRemoveRows(index(parent, 0), row, row + count - 1);
815 if (!parent)
816 parent = rootItem;
817 // now update the iterators
818 for (int i = 0; i < iterators.count(); ++i) {
819 for (int j = 0; j < count; j++) {
820 QTreeWidgetItem *c = parent->child(row + j);
821 iterators[i]->d_func()->ensureValidIterator(c);
822 }
823 }
824}
825
826void QTreeModel::endRemoveItems()
827{
828 endRemoveRows();
829}
830
831void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortOrder order)
832{
833 // see QTreeViewItem::operator<
834 Q_UNUSED(column);
835 if (isChanging())
836 return;
837
838 // store the original order of indexes
839 QVector< QPair<QTreeWidgetItem*,int> > sorting(items->count());
840 for (int i = 0; i < sorting.count(); ++i) {
841 sorting[i].first = items->at(i);
842 sorting[i].second = i;
843 }
844
845 // do the sorting
846 LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
847 qStableSort(sorting.begin(), sorting.end(), compare);
848
849 QModelIndexList fromList;
850 QModelIndexList toList;
851 int colCount = columnCount();
852 for (int r = 0; r < sorting.count(); ++r) {
853 int oldRow = sorting.at(r).second;
854 if (oldRow == r)
855 continue;
856 QTreeWidgetItem *item = sorting.at(r).first;
857 items->replace(r, item);
858 for (int c = 0; c < colCount; ++c) {
859 QModelIndex from = createIndex(oldRow, c, item);
860 if (static_cast<QAbstractItemModelPrivate *>(d_ptr.data())->persistent.indexes.contains(from)) {
861 QModelIndex to = createIndex(r, c, item);
862 fromList << from;
863 toList << to;
864 }
865 }
866 }
867 changePersistentIndexList(fromList, toList);
868}
869
870void QTreeModel::timerEvent(QTimerEvent *ev)
871{
872 if (ev->timerId() == sortPendingTimer.timerId()) {
873 executePendingSort();
874 } else {
875 QAbstractItemModel::timerEvent(ev);
876 }
877}
878
879/*!
880 \class QTreeWidgetItem
881
882 \brief The QTreeWidgetItem class provides an item for use with the
883 QTreeWidget convenience class.
884
885 \ingroup model-view
886
887 Tree widget items are used to hold rows of information for tree widgets.
888 Rows usually contain several columns of data, each of which can contain
889 a text label and an icon.
890
891 The QTreeWidgetItem class is a convenience class that replaces the
892 QListViewItem class in Qt 3. It provides an item for use with
893 the QTreeWidget class.
894
895 Items are usually constructed with a parent that is either a QTreeWidget
896 (for top-level items) or a QTreeWidgetItem (for items on lower levels of
897 the tree). For example, the following code constructs a top-level item
898 to represent cities of the world, and adds a entry for Oslo as a child
899 item:
900
901 \snippet doc/src/snippets/qtreewidget-using/mainwindow.cpp 3
902
903 Items can be added in a particular order by specifying the item they
904 follow when they are constructed:
905
906 \snippet doc/src/snippets/qtreewidget-using/mainwindow.cpp 5
907
908 Each column in an item can have its own background brush which is set with
909 the setBackground() function. The current background brush can be
910 found with background().
911 The text label for each column can be rendered with its own font and brush.
912 These are specified with the setFont() and setForeground() functions,
913 and read with font() and foreground().
914
915 The main difference between top-level items and those in lower levels of
916 the tree is that a top-level item has no parent(). This information
917 can be used to tell the difference between items, and is useful to know
918 when inserting and removing items from the tree.
919 Children of an item can be removed with takeChild() and inserted at a
920 given index in the list of children with the insertChild() function.
921
922 By default, items are enabled, selectable, checkable, and can be the source
923 of a drag and drop operation.
924 Each item's flags can be changed by calling setFlags() with the appropriate
925 value (see \l{Qt::ItemFlags}). Checkable items can be checked and unchecked
926 with the setCheckState() function. The corresponding checkState() function
927 indicates whether the item is currently checked.
928
929 \section1 Subclassing
930
931 When subclassing QTreeWidgetItem to provide custom items, it is possible to
932 define new types for them so that they can be distinguished from standard
933 items. The constructors for subclasses that require this feature need to
934 call the base class constructor with a new type value equal to or greater
935 than \l UserType.
936
937 \sa QTreeWidget, QTreeWidgetItemIterator, {Model/View Programming},
938 QListWidgetItem, QTableWidgetItem
939*/
940
941/*!
942 \enum QTreeWidgetItem::ItemType
943
944 This enum describes the types that are used to describe tree widget items.
945
946 \value Type The default type for tree widget items.
947 \value UserType The minimum value for custom types. Values below UserType are
948 reserved by Qt.
949
950 You can define new user types in QTreeWidgetItem subclasses to ensure that
951 custom items are treated specially; for example, when items are sorted.
952
953 \sa type()
954*/
955
956/*!
957 \fn int QTreeWidgetItem::type() const
958
959 Returns the type passed to the QTreeWidgetItem constructor.
960*/
961
962/*!
963 \fn void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order)
964 \since 4.2
965
966 Sorts the children of the item using the given \a order,
967 by the values in the given \a column.
968
969 \note This function does nothing if the item is not associated with a
970 QTreeWidget.
971*/
972
973/*!
974 \fn QTreeWidget *QTreeWidgetItem::treeWidget() const
975
976 Returns the tree widget that contains the item.
977*/
978
979/*!
980 \fn void QTreeWidgetItem::setSelected(bool select)
981 \since 4.2
982
983 Sets the selected state of the item to \a select.
984
985 \sa isSelected()
986
987*/
988
989/*!
990 \fn bool QTreeWidgetItem::isSelected() const
991 \since 4.2
992
993 Returns true if the item is selected, otherwise returns false.
994
995 \sa setSelected()
996*/
997
998/*!
999 \fn void QTreeWidgetItem::setHidden(bool hide)
1000 \since 4.2
1001
1002 Hides the item if \a hide is true, otherwise shows the item.
1003
1004 \sa isHidden()
1005*/
1006
1007/*!
1008 \fn bool QTreeWidgetItem::isHidden() const
1009 \since 4.2
1010
1011 Returns true if the item is hidden, otherwise returns false.
1012
1013 \sa setHidden()
1014*/
1015
1016/*!
1017 \fn void QTreeWidgetItem::setExpanded(bool expand)
1018 \since 4.2
1019
1020 Expands the item if \a expand is true, otherwise collapses the item.
1021 \warning The QTreeWidgetItem must be added to the QTreeWidget before calling this function.
1022
1023 \sa isExpanded()
1024*/
1025
1026/*!
1027 \fn bool QTreeWidgetItem::isExpanded() const
1028 \since 4.2
1029
1030 Returns true if the item is expanded, otherwise returns false.
1031
1032 \sa setExpanded()
1033*/
1034
1035/*!
1036 \fn void QTreeWidgetItem::setFirstColumnSpanned(bool span)
1037 \since 4.3
1038
1039 Sets the first section to span all columns if \a span is true;
1040 otherwise all item sections are shown.
1041
1042 \sa isFirstColumnSpanned()
1043*/
1044
1045/*!
1046 \fn bool QTreeWidgetItem::isFirstColumnSpanned() const
1047 \since 4.3
1048
1049 Returns true if the item is spanning all the columns in a row; otherwise returns false.
1050
1051 \sa setFirstColumnSpanned()
1052*/
1053
1054/*!
1055 \fn QString QTreeWidgetItem::text(int column) const
1056
1057 Returns the text in the specified \a column.
1058
1059 \sa setText()
1060*/
1061
1062/*!
1063 \fn void QTreeWidgetItem::setText(int column, const QString &text)
1064
1065 Sets the text to be displayed in the given \a column to the given \a text.
1066
1067 \sa text() setFont() setForeground()
1068*/
1069
1070/*!
1071 \fn QIcon QTreeWidgetItem::icon(int column) const
1072
1073 Returns the icon that is displayed in the specified \a column.
1074
1075 \sa setIcon(), {QAbstractItemView::iconSize}{iconSize}
1076*/
1077
1078/*!
1079 \fn void QTreeWidgetItem::setIcon(int column, const QIcon &icon)
1080
1081 Sets the icon to be displayed in the given \a column to \a icon.
1082
1083 \sa icon(), setText(), {QAbstractItemView::iconSize}{iconSize}
1084*/
1085
1086/*!
1087 \fn QString QTreeWidgetItem::statusTip(int column) const
1088
1089 Returns the status tip for the contents of the given \a column.
1090
1091 \sa setStatusTip()
1092*/
1093
1094/*!
1095 \fn void QTreeWidgetItem::setStatusTip(int column, const QString &statusTip)
1096
1097 Sets the status tip for the given \a column to the given \a statusTip.
1098 QTreeWidget mouse tracking needs to be enabled for this feature to work.
1099
1100 \sa statusTip() setToolTip() setWhatsThis()
1101*/
1102
1103/*!
1104 \fn QString QTreeWidgetItem::toolTip(int column) const
1105
1106 Returns the tool tip for the given \a column.
1107
1108 \sa setToolTip()
1109*/
1110
1111/*!
1112 \fn void QTreeWidgetItem::setToolTip(int column, const QString &toolTip)
1113
1114 Sets the tooltip for the given \a column to \a toolTip.
1115
1116 \sa toolTip() setStatusTip() setWhatsThis()
1117*/
1118
1119/*!
1120 \fn QString QTreeWidgetItem::whatsThis(int column) const
1121
1122 Returns the "What's This?" help for the contents of the given \a column.
1123
1124 \sa setWhatsThis()
1125*/
1126
1127/*!
1128 \fn void QTreeWidgetItem::setWhatsThis(int column, const QString &whatsThis)
1129
1130 Sets the "What's This?" help for the given \a column to \a whatsThis.
1131
1132 \sa whatsThis() setStatusTip() setToolTip()
1133*/
1134
1135/*!
1136 \fn QFont QTreeWidgetItem::font(int column) const
1137
1138 Returns the font used to render the text in the specified \a column.
1139
1140 \sa setFont()
1141*/
1142
1143/*!
1144 \fn void QTreeWidgetItem::setFont(int column, const QFont &font)
1145
1146 Sets the font used to display the text in the given \a column to the given
1147 \a font.
1148
1149 \sa font() setText() setForeground()
1150*/
1151
1152/*!
1153 \fn QColor QTreeWidgetItem::backgroundColor(int column) const
1154 \obsolete
1155
1156 This function is deprecated. Use background() instead.
1157*/
1158
1159/*!
1160 \fn void QTreeWidgetItem::setBackgroundColor(int column, const QColor &color)
1161 \obsolete
1162
1163 This function is deprecated. Use setBackground() instead.
1164*/
1165
1166/*!
1167 \fn QBrush QTreeWidgetItem::background(int column) const
1168 \since 4.2
1169
1170 Returns the brush used to render the background of the specified \a column.
1171
1172 \sa foreground()
1173*/
1174
1175/*!
1176 \fn void QTreeWidgetItem::setBackground(int column, const QBrush &brush)
1177 \since 4.2
1178
1179 Sets the background brush of the label in the given \a column to the
1180 specified \a brush.
1181
1182 \sa setForeground()
1183*/
1184
1185/*!
1186 \fn QColor QTreeWidgetItem::textColor(int column) const
1187 \obsolete
1188
1189 This function is deprecated. Use foreground() instead.
1190*/
1191
1192/*!
1193 \fn void QTreeWidgetItem::setTextColor(int column, const QColor &color)
1194 \obsolete
1195
1196 This function is deprecated. Use setForeground() instead.
1197*/
1198
1199/*!
1200 \fn QBrush QTreeWidgetItem::foreground(int column) const
1201 \since 4.2
1202
1203 Returns the brush used to render the foreground (e.g. text) of the
1204 specified \a column.
1205
1206 \sa background()
1207*/
1208
1209/*!
1210 \fn void QTreeWidgetItem::setForeground(int column, const QBrush &brush)
1211 \since 4.2
1212
1213 Sets the foreground brush of the label in the given \a column to the
1214 specified \a brush.
1215
1216 \sa setBackground()
1217*/
1218
1219/*!
1220 \fn Qt::CheckState QTreeWidgetItem::checkState(int column) const
1221
1222 Returns the check state of the label in the given \a column.
1223
1224 \sa Qt::CheckState
1225*/
1226
1227/*!
1228 \fn void QTreeWidgetItem::setCheckState(int column, Qt::CheckState state)
1229
1230 Sets the item in the given \a column check state to be \a state.
1231
1232 \sa checkState()
1233*/
1234
1235/*!
1236 \fn QSize QTreeWidgetItem::sizeHint(int column) const
1237 \since 4.1
1238
1239 Returns the size hint set for the tree item in the given
1240 \a column (see \l{QSize}).
1241*/
1242
1243/*!
1244 \fn void QTreeWidgetItem::setSizeHint(int column, const QSize &size)
1245 \since 4.1
1246
1247 Sets the size hint for the tree item in the given \a column to be \a size.
1248 If no size hint is set, the item delegate will compute the size hint based
1249 on the item data.
1250*/
1251
1252/*!
1253 \fn QTreeWidgetItem *QTreeWidgetItem::parent() const
1254
1255 Returns the item's parent.
1256
1257 \sa child()
1258*/
1259
1260/*!
1261 \fn QTreeWidgetItem *QTreeWidgetItem::child(int index) const
1262
1263 Returns the item at the given \a index in the list of the item's children.
1264
1265 \sa parent()
1266*/
1267
1268/*!
1269 \fn int QTreeWidgetItem::childCount() const
1270
1271 Returns the number of child items.
1272*/
1273
1274/*!
1275 \fn int QTreeWidgetItem::columnCount() const
1276
1277 Returns the number of columns in the item.
1278*/
1279
1280/*!
1281 \fn int QTreeWidgetItem::textAlignment(int column) const
1282
1283 Returns the text alignment for the label in the given \a column
1284 (see \l{Qt::AlignmentFlag}).
1285*/
1286
1287/*!
1288 \fn void QTreeWidgetItem::setTextAlignment(int column, int alignment)
1289
1290 Sets the text alignment for the label in the given \a column to
1291 the \a alignment specified (see \l{Qt::AlignmentFlag}).
1292*/
1293
1294/*!
1295 \fn int QTreeWidgetItem::indexOfChild(QTreeWidgetItem *child) const
1296
1297 Returns the index of the given \a child in the item's list of children.
1298*/
1299
1300/*!
1301 Constructs a tree widget item of the specified \a type. The item
1302 must be inserted into a tree widget.
1303
1304 \sa type()
1305*/
1306QTreeWidgetItem::QTreeWidgetItem(int type)
1307 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1308 itemFlags(Qt::ItemIsSelectable
1309 |Qt::ItemIsUserCheckable
1310 |Qt::ItemIsEnabled
1311 |Qt::ItemIsDragEnabled
1312 |Qt::ItemIsDropEnabled)
1313{
1314}
1315
1316
1317/*!
1318 Constructs a tree widget item of the specified \a type. The item
1319 must be inserted into a tree widget.
1320 The given list of \a strings will be set as the item text for each
1321 column in the item.
1322
1323 \sa type()
1324*/
1325QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type)
1326 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1327 itemFlags(Qt::ItemIsSelectable
1328 |Qt::ItemIsUserCheckable
1329 |Qt::ItemIsEnabled
1330 |Qt::ItemIsDragEnabled
1331 |Qt::ItemIsDropEnabled)
1332{
1333 for (int i = 0; i < strings.count(); ++i)
1334 setText(i, strings.at(i));
1335}
1336
1337/*!
1338 \fn QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *parent, int type)
1339
1340 Constructs a tree widget item of the specified \a type and appends it
1341 to the items in the given \a parent.
1342
1343 \sa type()
1344*/
1345
1346QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, int type)
1347 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1348 itemFlags(Qt::ItemIsSelectable
1349 |Qt::ItemIsUserCheckable
1350 |Qt::ItemIsEnabled
1351 |Qt::ItemIsDragEnabled
1352 |Qt::ItemIsDropEnabled)
1353{
1354 if (view && view->model()) {
1355 QTreeModel *model = qobject_cast<QTreeModel*>(view->model());
1356 model->rootItem->addChild(this);
1357 values.reserve(model->headerItem->columnCount());
1358 }
1359}
1360
1361/*!
1362 \fn QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *parent, const QStringList &strings, int type)
1363
1364 Constructs a tree widget item of the specified \a type and appends it
1365 to the items in the given \a parent. The given list of \a strings will be set as
1366 the item text for each column in the item.
1367
1368 \sa type()
1369*/
1370
1371QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type)
1372 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1373 itemFlags(Qt::ItemIsSelectable
1374 |Qt::ItemIsUserCheckable
1375 |Qt::ItemIsEnabled
1376 |Qt::ItemIsDragEnabled
1377 |Qt::ItemIsDropEnabled)
1378{
1379 for (int i = 0; i < strings.count(); ++i)
1380 setText(i, strings.at(i));
1381 if (view && view->model()) {
1382 QTreeModel *model = qobject_cast<QTreeModel*>(view->model());
1383 model->rootItem->addChild(this);
1384 values.reserve(model->headerItem->columnCount());
1385 }
1386}
1387
1388/*!
1389 \fn QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *parent, QTreeWidgetItem *preceding, int type)
1390
1391 Constructs a tree widget item of the specified \a type and inserts it into
1392 the given \a parent after the \a preceding item.
1393
1394 \sa type()
1395*/
1396QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type)
1397 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1398 itemFlags(Qt::ItemIsSelectable
1399 |Qt::ItemIsUserCheckable
1400 |Qt::ItemIsEnabled
1401 |Qt::ItemIsDragEnabled
1402 |Qt::ItemIsDropEnabled)
1403{
1404 if (view) {
1405 QTreeModel *model = qobject_cast<QTreeModel*>(view->model());
1406 if (model) {
1407 int i = model->rootItem->children.indexOf(after) + 1;
1408 model->rootItem->insertChild(i, this);
1409 values.reserve(model->headerItem->columnCount());
1410 }
1411 }
1412}
1413
1414/*!
1415 Constructs a tree widget item and append it to the given \a parent.
1416
1417 \sa type()
1418*/
1419QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type)
1420 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1421 itemFlags(Qt::ItemIsSelectable
1422 |Qt::ItemIsUserCheckable
1423 |Qt::ItemIsEnabled
1424 |Qt::ItemIsDragEnabled
1425 |Qt::ItemIsDropEnabled)
1426{
1427 if (parent)
1428 parent->addChild(this);
1429}
1430
1431/*!
1432 Constructs a tree widget item and append it to the given \a parent.
1433 The given list of \a strings will be set as the item text for each column in the item.
1434
1435 \sa type()
1436*/
1437QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type)
1438 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1439 itemFlags(Qt::ItemIsSelectable
1440 |Qt::ItemIsUserCheckable
1441 |Qt::ItemIsEnabled
1442 |Qt::ItemIsDragEnabled
1443 |Qt::ItemIsDropEnabled)
1444{
1445 for (int i = 0; i < strings.count(); ++i)
1446 setText(i, strings.at(i));
1447 if (parent)
1448 parent->addChild(this);
1449}
1450
1451/*!
1452 \fn QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding, int type)
1453
1454 Constructs a tree widget item of the specified \a type that is inserted
1455 into the \a parent after the \a preceding child item.
1456
1457 \sa type()
1458*/
1459QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type)
1460 : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0),
1461 itemFlags(Qt::ItemIsSelectable
1462 |Qt::ItemIsUserCheckable
1463 |Qt::ItemIsEnabled
1464 |Qt::ItemIsDragEnabled
1465 |Qt::ItemIsDropEnabled)
1466{
1467 if (parent) {
1468 int i = parent->children.indexOf(after) + 1;
1469 parent->insertChild(i, this);
1470 }
1471}
1472
1473/*!
1474 Destroys this tree widget item.
1475
1476 The item will be removed from \l{QTreeWidget}s to which it has
1477 been added. This makes it safe to delete an item at any time.
1478
1479*/
1480
1481QTreeWidgetItem::~QTreeWidgetItem()
1482{
1483 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
1484 bool wasSkipSort = false;
1485 if (model) {
1486 wasSkipSort = model->skipPendingSort;
1487 model->skipPendingSort = true;
1488 }
1489 if (par) {
1490 int i = par->children.indexOf(this);
1491 if (i >= 0) {
1492 if (model) model->beginRemoveItems(par, i, 1);
1493 // users _could_ do changes when connected to rowsAboutToBeRemoved,
1494 // so we check again to make sure 'i' is valid
1495 if (!par->children.isEmpty() && par->children.at(i) == this)
1496 par->children.takeAt(i);
1497 if (model) model->endRemoveItems();
1498 }
1499 } else if (model) {
1500 if (this == model->headerItem) {
1501 model->headerItem = 0;
1502 } else {
1503 int i = model->rootItem->children.indexOf(this);
1504 if (i >= 0) {
1505 model->beginRemoveItems(0, i, 1);
1506 // users _could_ do changes when connected to rowsAboutToBeRemoved,
1507 // so we check again to make sure 'i' is valid
1508 if (!model->rootItem->children.isEmpty() && model->rootItem->children.at(i) == this)
1509 model->rootItem->children.takeAt(i);
1510 model->endRemoveItems();
1511 }
1512 }
1513 }
1514 // at this point the persistent indexes for the children should also be invalidated
1515 // since we invalidated the parent
1516 for (int i = 0; i < children.count(); ++i) {
1517 QTreeWidgetItem *child = children.at(i);
1518 // make sure the child does not try to remove itself from our children list
1519 child->par = 0;
1520 // make sure the child does not try to remove itself from the top level list
1521 child->view = 0;
1522 delete child;
1523 }
1524
1525 children.clear();
1526 delete d;
1527 if (model) {
1528 model->skipPendingSort = wasSkipSort;
1529 }
1530}
1531
1532/*!
1533 Creates a deep copy of the item and of its children.
1534*/
1535QTreeWidgetItem *QTreeWidgetItem::clone() const
1536{
1537 QTreeWidgetItem *copy = 0;
1538
1539 QStack<const QTreeWidgetItem*> stack;
1540 QStack<QTreeWidgetItem*> parentStack;
1541 stack.push(this);
1542 parentStack.push(0);
1543
1544 QTreeWidgetItem *root = 0;
1545 const QTreeWidgetItem *item = 0;
1546 QTreeWidgetItem *parent = 0;
1547 while (!stack.isEmpty()) {
1548 // get current item, and copied parent
1549 item = stack.pop();
1550 parent = parentStack.pop();
1551
1552 // copy item
1553 copy = new QTreeWidgetItem(*item);
1554 if (!root)
1555 root = copy;
1556
1557 // set parent and add to parents children list
1558 if (parent) {
1559 copy->par = parent;
1560 parent->children.insert(0, copy);
1561 }
1562
1563 for (int i = 0; i < item->childCount(); ++i) {
1564 stack.push(item->child(i));
1565 parentStack.push(copy);
1566 }
1567 }
1568 return root;
1569}
1570
1571/*!
1572 Sets the item indicator \a policy. This policy decides when the
1573 tree branch expand/collapse indicator is shown.
1574 The default value is ShowForChildren.
1575
1576 \sa childIndicatorPolicy()
1577*/
1578void QTreeWidgetItem::setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy)
1579{
1580 if (d->policy == policy)
1581 return;
1582 d->policy = policy;
1583
1584 if (!view)
1585 return;
1586
1587 view->scheduleDelayedItemsLayout();
1588}
1589
1590/*!
1591 Returns the item indicator policy. This policy decides when the
1592 tree branch expand/collapse indicator is shown.
1593
1594 \sa setChildIndicatorPolicy()
1595*/
1596QTreeWidgetItem::ChildIndicatorPolicy QTreeWidgetItem::childIndicatorPolicy() const
1597{
1598 return d->policy;
1599}
1600
1601/*!
1602 \fn void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
1603
1604 Sets the flags for the item to the given \a flags. These determine whether
1605 the item can be selected or modified. This is often used to disable an item.
1606
1607 \sa flags()
1608*/
1609void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
1610{
1611 const bool enable = (flags & Qt::ItemIsEnabled);
1612 const bool changedState = bool(itemFlags & Qt::ItemIsEnabled) != enable;
1613 const bool changedExplicit = d->disabled != !enable;
1614
1615 d->disabled = !enable;
1616
1617 if (enable && par && !(par->itemFlags & Qt::ItemIsEnabled)) // inherit from parent
1618 itemFlags = flags & ~Qt::ItemIsEnabled;
1619 else // this item is explicitly disabled or has no parent
1620 itemFlags = flags;
1621
1622 if (changedState && changedExplicit) { // if the propagate the change to the children
1623 QStack<QTreeWidgetItem*> parents;
1624 parents.push(this);
1625 while (!parents.isEmpty()) {
1626 QTreeWidgetItem *parent = parents.pop();
1627 for (int i = 0; i < parent->children.count(); ++i) {
1628 QTreeWidgetItem *child = parent->children.at(i);
1629 if (!child->d->disabled) { // if not explicitly disabled
1630 parents.push(child);
1631 if (enable)
1632 child->itemFlags = child->itemFlags | Qt::ItemIsEnabled;
1633 else
1634 child->itemFlags = child->itemFlags & ~Qt::ItemIsEnabled;
1635 child->itemChanged(); // ### we may want to optimize this
1636 }
1637 }
1638 }
1639 }
1640 itemChanged();
1641}
1642
1643void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item)
1644{
1645 Q_ASSERT(item);
1646 const bool enable = item->par ? (item->par->itemFlags.testFlag(Qt::ItemIsEnabled)) : true;
1647
1648 QStack<QTreeWidgetItem*> parents;
1649 parents.push(item);
1650 while (!parents.isEmpty()) {
1651 QTreeWidgetItem *parent = parents.pop();
1652 if (!parent->d->disabled) { // if not explicitly disabled
1653 Qt::ItemFlags oldFlags = parent->itemFlags;
1654 if (enable)
1655 parent->itemFlags = parent->itemFlags | Qt::ItemIsEnabled;
1656 else
1657 parent->itemFlags = parent->itemFlags & ~Qt::ItemIsEnabled;
1658 if (parent->itemFlags != oldFlags)
1659 parent->itemChanged();
1660 }
1661
1662 for (int i = 0; i < parent->children.count(); ++i) {
1663 QTreeWidgetItem *child = parent->children.at(i);
1664 parents.push(child);
1665 }
1666 }
1667}
1668/*!
1669 \fn Qt::ItemFlags QTreeWidgetItem::flags() const
1670
1671 Returns the flags used to describe the item. These determine whether
1672 the item can be checked, edited, and selected.
1673
1674 The default value for flags is
1675 Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled.
1676 If the item was constructed with a parent, flags will in addition contain Qt::ItemIsDropEnabled.
1677
1678 \sa setFlags()
1679*/
1680Qt::ItemFlags QTreeWidgetItem::flags() const
1681{
1682 return itemFlags;
1683}
1684
1685/*!
1686 Sets the value for the item's \a column and \a role to the given
1687 \a value.
1688
1689 The \a role describes the type of data specified by \a value, and is defined by
1690 the Qt::ItemDataRole enum.
1691*/
1692void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
1693{
1694 if (column < 0)
1695 return;
1696
1697 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
1698 switch (role) {
1699 case Qt::EditRole:
1700 case Qt::DisplayRole: {
1701 if (values.count() <= column) {
1702 if (model && this == model->headerItem)
1703 model->setColumnCount(column + 1);
1704 else
1705 values.resize(column + 1);
1706 }
1707 if (d->display.count() <= column) {
1708 for (int i = d->display.count() - 1; i < column - 1; ++i)
1709 d->display.append(QVariant());
1710 d->display.append(value);
1711 } else if (d->display[column] != value) {
1712 d->display[column] = value;
1713 } else {
1714 return; // value is unchanged
1715 }
1716 } break;
1717 case Qt::CheckStateRole:
1718 if (itemFlags & Qt::ItemIsTristate) {
1719 for (int i = 0; i < children.count(); ++i) {
1720 QTreeWidgetItem *child = children.at(i);
1721 if (child->data(column, role).isValid()) {// has a CheckState
1722 Qt::ItemFlags f = itemFlags; // a little hack to avoid multiple dataChanged signals
1723 itemFlags &= ~Qt::ItemIsTristate;
1724 child->setData(column, role, value);
1725 itemFlags = f;
1726 }
1727 }
1728 }
1729 // Don't break, but fall through
1730 default:
1731 if (column < values.count()) {
1732 bool found = false;
1733 QVector<QWidgetItemData> column_values = values.at(column);
1734 for (int i = 0; i < column_values.count(); ++i) {
1735 if (column_values.at(i).role == role) {
1736 if (column_values.at(i).value == value)
1737 return; // value is unchanged
1738 values[column][i].value = value;
1739 found = true;
1740 break;
1741 }
1742 }
1743 if (!found)
1744 values[column].append(QWidgetItemData(role, value));
1745 } else {
1746 if (model && this == model->headerItem)
1747 model->setColumnCount(column + 1);
1748 else
1749 values.resize(column + 1);
1750 values[column].append(QWidgetItemData(role, value));
1751 }
1752 }
1753
1754 if (model) {
1755 model->emitDataChanged(this, column);
1756 if (role == Qt::CheckStateRole) {
1757 QTreeWidgetItem *p;
1758 for (p = par; p && (p->itemFlags & Qt::ItemIsTristate); p = p->par)
1759 model->emitDataChanged(p, column);
1760 }
1761 }
1762}
1763
1764/*!
1765 Returns the value for the item's \a column and \a role.
1766*/
1767QVariant QTreeWidgetItem::data(int column, int role) const
1768{
1769 switch (role) {
1770 case Qt::EditRole:
1771 case Qt::DisplayRole:
1772 if (column >= 0 && column < d->display.count())
1773 return d->display.at(column);
1774 break;
1775 case Qt::CheckStateRole:
1776 // special case for check state in tristate
1777 if (children.count() && (itemFlags & Qt::ItemIsTristate))
1778 return childrenCheckState(column);
1779 // fallthrough intended
1780 default:
1781 if (column >= 0 && column < values.size()) {
1782 const QVector<QWidgetItemData> &column_values = values.at(column);
1783 for (int i = 0; i < column_values.count(); ++i)
1784 if (column_values.at(i).role == role)
1785 return column_values.at(i).value;
1786 }
1787 }
1788 return QVariant();
1789}
1790
1791/*!
1792 Returns true if the text in the item is less than the text in the
1793 \a other item, otherwise returns false.
1794*/
1795
1796bool QTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
1797{
1798 int column = view ? view->sortColumn() : 0;
1799 const QVariant v1 = data(column, Qt::DisplayRole);
1800 const QVariant v2 = other.data(column, Qt::DisplayRole);
1801 return QAbstractItemModelPrivate::variantLessThan(v1, v2);
1802}
1803
1804#ifndef QT_NO_DATASTREAM
1805
1806/*!
1807 Reads the item from stream \a in. This only reads data into a single item.
1808
1809 \sa write()
1810*/
1811void QTreeWidgetItem::read(QDataStream &in)
1812{
1813 // convert from streams written before we introduced display (4.2.0)
1814 if (in.version() < QDataStream::Qt_4_2) {
1815 d->display.clear();
1816 in >> values;
1817 // move the display value over to the display string list
1818 for (int column = 0; column < values.count(); ++column) {
1819 d->display << QVariant();
1820 for (int i = 0; i < values.at(column).count(); ++i) {
1821 if (values.at(column).at(i).role == Qt::DisplayRole) {
1822 d->display[column] = values.at(column).at(i).value;
1823 values[column].remove(i--);
1824 }
1825 }
1826 }
1827 } else {
1828 in >> values >> d->display;
1829 }
1830}
1831
1832/*!
1833 Writes the item to stream \a out. This only writes data from one single item.
1834
1835 \sa read()
1836*/
1837void QTreeWidgetItem::write(QDataStream &out) const
1838{
1839 out << values << d->display;
1840}
1841#endif // QT_NO_DATASTREAM
1842
1843/*!
1844 \since 4.1
1845
1846 Constructs a copy of \a other. Note that type() and treeWidget()
1847 are not copied.
1848
1849 This function is useful when reimplementing clone().
1850
1851 \sa data(), flags()
1852*/
1853QTreeWidgetItem::QTreeWidgetItem(const QTreeWidgetItem &other)
1854 : rtti(Type), values(other.values), view(0),
1855 d(new QTreeWidgetItemPrivate(this)), par(0),
1856 itemFlags(other.itemFlags)
1857{
1858 d->display = other.d->display;
1859}
1860
1861/*!
1862 Assigns \a other's data and flags to this item. Note that type()
1863 and treeWidget() are not copied.
1864
1865 This function is useful when reimplementing clone().
1866
1867 \sa data(), flags()
1868*/
1869QTreeWidgetItem &QTreeWidgetItem::operator=(const QTreeWidgetItem &other)
1870{
1871 values = other.values;
1872 d->display = other.d->display;
1873 d->policy = other.d->policy;
1874 itemFlags = other.itemFlags;
1875 return *this;
1876}
1877
1878/*!
1879 Appends the \a child item to the list of children.
1880
1881 \sa insertChild() takeChild()
1882*/
1883void QTreeWidgetItem::addChild(QTreeWidgetItem *child)
1884{
1885 if (child) {
1886 insertChild(children.count(), child);
1887 child->d->rowGuess = children.count() - 1;
1888 }
1889}
1890
1891/*!
1892 Inserts the \a child item at \a index in the list of children.
1893
1894 If the child has already been inserted somewhere else it wont be inserted again.
1895*/
1896void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
1897{
1898 if (index < 0 || index > children.count() || child == 0 || child->view != 0 || child->par != 0)
1899 return;
1900
1901 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0)) {
1902 const bool wasSkipSort = model->skipPendingSort;
1903 model->skipPendingSort = true;
1904 if (model->rootItem == this)
1905 child->par = 0;
1906 else
1907 child->par = this;
1908 if (view->isSortingEnabled()) {
1909 // do a delayed sort instead
1910 if (!model->sortPendingTimer.isActive())
1911 model->sortPendingTimer.start(0, model);
1912 }
1913 model->beginInsertItems(this, index, 1);
1914 int cols = model->columnCount();
1915 QStack<QTreeWidgetItem*> stack;
1916 stack.push(child);
1917 while (!stack.isEmpty()) {
1918 QTreeWidgetItem *i = stack.pop();
1919 i->view = view;
1920 i->values.reserve(cols);
1921 for (int c = 0; c < i->children.count(); ++c)
1922 stack.push(i->children.at(c));
1923 }
1924 children.insert(index, child);
1925 model->endInsertItems();
1926 model->skipPendingSort = wasSkipSort;
1927 } else {
1928 child->par = this;
1929 children.insert(index, child);
1930 }
1931 if (child->par)
1932 d->propagateDisabled(child);
1933}
1934
1935/*!
1936 Removes the given item indicated by \a child.
1937 The removed item will not be deleted.
1938*/
1939void QTreeWidgetItem::removeChild(QTreeWidgetItem *child)
1940{
1941 (void)takeChild(children.indexOf(child));
1942}
1943
1944/*!
1945 Removes the item at \a index and returns it, otherwise return 0.
1946*/
1947QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
1948{
1949 // we move this outside the check of the index to allow executing
1950 // pending sorts from inline functions, using this function (hack)
1951 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
1952 if (model) {
1953 // This will trigger a layoutChanged signal, thus we might want to optimize
1954 // this function by not emitting the rowsRemoved signal etc to the view.
1955 // On the other hand we also need to make sure that the selectionmodel
1956 // is updated in case we take an item that is selected.
1957 model->skipPendingSort = false;
1958 model->executePendingSort();
1959 }
1960 if (index >= 0 && index < children.count()) {
1961 if (model) model->beginRemoveItems(this, index, 1);
1962 QTreeWidgetItem *item = children.takeAt(index);
1963 item->par = 0;
1964 QStack<QTreeWidgetItem*> stack;
1965 stack.push(item);
1966 while (!stack.isEmpty()) {
1967 QTreeWidgetItem *i = stack.pop();
1968 i->view = 0;
1969 for (int c = 0; c < i->children.count(); ++c)
1970 stack.push(i->children.at(c));
1971 }
1972 d->propagateDisabled(item);
1973 if (model) model->endRemoveRows();
1974 return item;
1975 }
1976 return 0;
1977}
1978
1979/*!
1980 \since 4.1
1981
1982 Appends the given list of \a children to the item.
1983
1984 \sa insertChildren() takeChildren()
1985*/
1986void QTreeWidgetItem::addChildren(const QList<QTreeWidgetItem*> &children)
1987{
1988 insertChildren(this->children.count(), children);
1989}
1990
1991/*!
1992 \since 4.1
1993
1994 Inserts the given list of \a children into the list of the item children at \a index .
1995
1996 Children that have already been inserted somewhere else wont be inserted.
1997*/
1998void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &children)
1999{
2000 if (view && view->isSortingEnabled()) {
2001 for (int n = 0; n < children.count(); ++n)
2002 insertChild(index, children.at(n));
2003 return;
2004 }
2005 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
2006 QStack<QTreeWidgetItem*> stack;
2007 QList<QTreeWidgetItem*> itemsToInsert;
2008 for (int n = 0; n < children.count(); ++n) {
2009 QTreeWidgetItem *child = children.at(n);
2010 if (child->view || child->par)
2011 continue;
2012 itemsToInsert.append(child);
2013 if (view && model) {
2014 if (child->childCount() == 0)
2015 child->view = view;
2016 else
2017 stack.push(child);
2018 }
2019 if (model && (model->rootItem == this))
2020 child->par = 0;
2021 else
2022 child->par = this;
2023 }
2024 if (!itemsToInsert.isEmpty()) {
2025 while (!stack.isEmpty()) {
2026 QTreeWidgetItem *i = stack.pop();
2027 i->view = view;
2028 for (int c = 0; c < i->children.count(); ++c)
2029 stack.push(i->children.at(c));
2030 }
2031 if (model) model->beginInsertItems(this, index, itemsToInsert.count());
2032 for (int n = 0; n < itemsToInsert.count(); ++n) {
2033 QTreeWidgetItem *child = itemsToInsert.at(n);
2034 this->children.insert(index + n, child);
2035 if (child->par)
2036 d->propagateDisabled(child);
2037 }
2038 if (model) model->endInsertItems();
2039 }
2040}
2041
2042/*!
2043 \since 4.1
2044
2045 Removes the list of children and returns it, otherwise returns an empty list.
2046*/
2047QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
2048{
2049 QList<QTreeWidgetItem*> removed;
2050 if (children.count() > 0) {
2051 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
2052 if (model) {
2053 // This will trigger a layoutChanged signal, thus we might want to optimize
2054 // this function by not emitting the rowsRemoved signal etc to the view.
2055 // On the other hand we also need to make sure that the selectionmodel
2056 // is updated in case we take an item that is selected.
2057 model->executePendingSort();
2058 }
2059 if (model) model->beginRemoveItems(this, 0, children.count());
2060 for (int n = 0; n < children.count(); ++n) {
2061 QTreeWidgetItem *item = children.at(n);
2062 item->par = 0;
2063 QStack<QTreeWidgetItem*> stack;
2064 stack.push(item);
2065 while (!stack.isEmpty()) {
2066 QTreeWidgetItem *i = stack.pop();
2067 i->view = 0;
2068 for (int c = 0; c < i->children.count(); ++c)
2069 stack.push(i->children.at(c));
2070 }
2071 d->propagateDisabled(item);
2072 }
2073 removed = children;
2074 children.clear(); // detach
2075 if (model) model->endRemoveItems();
2076 }
2077 return removed;
2078}
2079
2080
2081void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool climb)
2082{
2083 QTreeModel *model = (q->view ? qobject_cast<QTreeModel*>(q->view->model()) : 0);
2084 if (!model)
2085 return;
2086 model->sortItems(&q->children, column, order);
2087 if (climb) {
2088 QList<QTreeWidgetItem*>::iterator it = q->children.begin();
2089 for (; it != q->children.end(); ++it) {
2090 //here we call the private object's method to avoid emitting
2091 //the layoutAboutToBeChanged and layoutChanged signals
2092 (*it)->d->sortChildren(column, order, climb);
2093 }
2094 }
2095}
2096
2097/*!
2098 \internal
2099
2100 Sorts the children by the value in the given \a column, in the \a order
2101 specified. If \a climb is true, the items below each of the children will
2102 also be sorted.
2103*/
2104void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order, bool climb)
2105{
2106 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
2107 if (!model)
2108 return;
2109 if (model->isChanging())
2110 return;
2111 int oldSortColumn = view->d_func()->explicitSortColumn;
2112 view->d_func()->explicitSortColumn = column;
2113 emit model->layoutAboutToBeChanged();
2114 d->sortChildren(column, order, climb);
2115 emit model->layoutChanged();
2116 view->d_func()->explicitSortColumn = oldSortColumn;
2117}
2118
2119/*!
2120 \internal
2121
2122 Calculates the checked state of the item based on the checked state
2123 of its children. E.g. if all children checked => this item is also
2124 checked; if some children checked => this item is partially checked;
2125 if no children checked => this item is unchecked.
2126*/
2127QVariant QTreeWidgetItem::childrenCheckState(int column) const
2128{
2129 if (column < 0)
2130 return QVariant();
2131 bool checkedChildren = false;
2132 bool uncheckedChildren = false;
2133 for (int i = 0; i < children.count(); ++i) {
2134 QVariant value = children.at(i)->data(column, Qt::CheckStateRole);
2135 if (!value.isValid())
2136 return QVariant();
2137
2138 switch (static_cast<Qt::CheckState>(value.toInt()))
2139 {
2140 case Qt::Unchecked:
2141 uncheckedChildren = true;
2142 break;
2143 case Qt::Checked:
2144 checkedChildren = true;
2145 break;
2146 case Qt::PartiallyChecked:
2147 default:
2148 return Qt::PartiallyChecked;
2149 }
2150 }
2151
2152 if (uncheckedChildren && checkedChildren)
2153 return Qt::PartiallyChecked;
2154 if (uncheckedChildren)
2155 return Qt::Unchecked;
2156 else if (checkedChildren)
2157 return Qt::Checked;
2158 else
2159 return QVariant(); // value was not defined
2160}
2161
2162/*!
2163 \since 4.5
2164
2165 Causes the model associated with this item to emit a
2166 \l{QAbstractItemModel::dataChanged()}{dataChanged}() signal for this
2167 item.
2168
2169 You normally only need to call this function if you have subclassed
2170 QTreeWidgetItem and reimplemented data() and/or setData().
2171
2172 \sa setData()
2173*/
2174void QTreeWidgetItem::emitDataChanged()
2175{
2176 itemChanged();
2177}
2178
2179/*!
2180 \internal
2181*/
2182void QTreeWidgetItem::itemChanged()
2183{
2184 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0))
2185 model->itemChanged(this);
2186}
2187
2188/*!
2189 \internal
2190*/
2191void QTreeWidgetItem::executePendingSort() const
2192{
2193 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0))
2194 model->executePendingSort();
2195}
2196
2197
2198#ifndef QT_NO_DATASTREAM
2199/*!
2200 \relates QTreeWidgetItem
2201
2202 Writes the tree widget item \a item to stream \a out.
2203
2204 This operator uses QTreeWidgetItem::write().
2205
2206 \sa {Serializing Qt Data Types}
2207*/
2208QDataStream &operator<<(QDataStream &out, const QTreeWidgetItem &item)
2209{
2210 item.write(out);
2211 return out;
2212}
2213
2214/*!
2215 \relates QTreeWidgetItem
2216
2217 Reads a tree widget item from stream \a in into \a item.
2218
2219 This operator uses QTreeWidgetItem::read().
2220
2221 \sa {Serializing Qt Data Types}
2222*/
2223QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item)
2224{
2225 item.read(in);
2226 return in;
2227}
2228#endif // QT_NO_DATASTREAM
2229
2230
2231void QTreeWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
2232{
2233 Q_Q(QTreeWidget);
2234 emit q->itemPressed(item(index), index.column());
2235}
2236
2237void QTreeWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
2238{
2239 Q_Q(QTreeWidget);
2240 emit q->itemClicked(item(index), index.column());
2241}
2242
2243void QTreeWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
2244{
2245 Q_Q(QTreeWidget);
2246 emit q->itemDoubleClicked(item(index), index.column());
2247}
2248
2249void QTreeWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
2250{
2251 Q_Q(QTreeWidget);
2252 emit q->itemActivated(item(index), index.column());
2253}
2254
2255void QTreeWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
2256{
2257 Q_Q(QTreeWidget);
2258 emit q->itemEntered(item(index), index.column());
2259}
2260
2261void QTreeWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
2262{
2263 Q_Q(QTreeWidget);
2264 QTreeWidgetItem *indexItem = item(index);
2265 if (indexItem)
2266 emit q->itemChanged(indexItem, index.column());
2267}
2268
2269void QTreeWidgetPrivate::_q_emitItemExpanded(const QModelIndex &index)
2270{
2271 Q_Q(QTreeWidget);
2272 emit q->itemExpanded(item(index));
2273}
2274
2275void QTreeWidgetPrivate::_q_emitItemCollapsed(const QModelIndex &index)
2276{
2277 Q_Q(QTreeWidget);
2278 emit q->itemCollapsed(item(index));
2279}
2280
2281void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
2282 const QModelIndex &previous)
2283{
2284 Q_Q(QTreeWidget);
2285 QTreeWidgetItem *currentItem = item(current);
2286 QTreeWidgetItem *previousItem = item(previous);
2287 emit q->currentItemChanged(currentItem, previousItem);
2288}
2289
2290void QTreeWidgetPrivate::_q_sort()
2291{
2292 if (sortingEnabled) {
2293 int column = header->sortIndicatorSection();
2294 Qt::SortOrder order = header->sortIndicatorOrder();
2295 treeModel()->sort(column, order);
2296 }
2297}
2298
2299void QTreeWidgetPrivate::_q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
2300{
2301 Q_Q(QTreeWidget);
2302 QModelIndexList indices = selected.indexes();
2303 int i;
2304 QTreeModel *m = treeModel();
2305 for (i = 0; i < indices.count(); ++i) {
2306 QTreeWidgetItem *item = m->item(indices.at(i));
2307 item->d->selected = true;
2308 }
2309
2310 indices = deselected.indexes();
2311 for (i = 0; i < indices.count(); ++i) {
2312 QTreeWidgetItem *item = m->item(indices.at(i));
2313 item->d->selected = false;
2314 }
2315
2316 emit q->itemSelectionChanged();
2317}
2318
2319void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
2320 const QModelIndex &bottomRight)
2321{
2322 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
2323 && !treeModel()->sortPendingTimer.isActive()) {
2324 int column = header->sortIndicatorSection();
2325 if (column >= topLeft.column() && column <= bottomRight.column()) {
2326 Qt::SortOrder order = header->sortIndicatorOrder();
2327 treeModel()->ensureSorted(column, order, topLeft.row(),
2328 bottomRight.row(), topLeft.parent());
2329 }
2330 }
2331}
2332
2333/*!
2334 \class QTreeWidget
2335
2336 \brief The QTreeWidget class provides a tree view that uses a predefined
2337 tree model.
2338
2339 \ingroup model-view
2340
2341
2342 The QTreeWidget class is a convenience class that provides a standard
2343 tree widget with a classic item-based interface similar to that used by
2344 the QListView class in Qt 3.
2345 This class is based on Qt's Model/View architecture and uses a default
2346 model to hold items, each of which is a QTreeWidgetItem.
2347
2348 Developers who do not need the flexibility of the Model/View framework
2349 can use this class to create simple hierarchical lists very easily. A more
2350 flexible approach involves combining a QTreeView with a standard item model.
2351 This allows the storage of data to be separated from its representation.
2352
2353 In its simplest form, a tree widget can be constructed in the following way:
2354
2355 \snippet doc/src/snippets/code/src_gui_itemviews_qtreewidget.cpp 0
2356
2357 Before items can be added to the tree widget, the number of columns must
2358 be set with setColumnCount(). This allows each item to have one or more
2359 labels or other decorations. The number of columns in use can be found
2360 with the columnCount() function.
2361
2362 The tree can have a header that contains a section for each column in
2363 the widget. It is easiest to set up the labels for each section by
2364 supplying a list of strings with setHeaderLabels(), but a custom header
2365 can be constructed with a QTreeWidgetItem and inserted into the tree
2366 with the setHeaderItem() function.
2367
2368 The items in the tree can be sorted by column according to a predefined
2369 sort order. If sorting is enabled, the user can sort the items by clicking
2370 on a column header. Sorting can be enabled or disabled by calling
2371 \l{QTreeView::setSortingEnabled()}{setSortingEnabled()}. The
2372 \l{QTreeView::isSortingEnabled()}{isSortingEnabled()} function indicates
2373 whether sorting is enabled.
2374
2375 \table 100%
2376 \row \o \inlineimage windowsxp-treeview.png Screenshot of a Windows XP style tree widget
2377 \o \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree widget
2378 \o \inlineimage plastique-treeview.png Screenshot of a Plastique style tree widget
2379 \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} tree widget.
2380 \o A \l{Macintosh Style Widget Gallery}{Macintosh style} tree widget.
2381 \o A \l{Plastique Style Widget Gallery}{Plastique style} tree widget.
2382 \endtable
2383
2384 \sa QTreeWidgetItem, QTreeWidgetItemIterator, QTreeView,
2385 {Model/View Programming}, {Settings Editor Example}
2386*/
2387
2388/*!
2389 \property QTreeWidget::columnCount
2390 \brief the number of columns displayed in the tree widget
2391
2392 By default, this property has a value of 1.
2393*/
2394
2395/*!
2396 \fn void QTreeWidget::itemActivated(QTreeWidgetItem *item, int column)
2397
2398 This signal is emitted when the user activates an item by single-
2399 or double-clicking (depending on the platform, i.e. on the
2400 QStyle::SH_ItemView_ActivateItemOnSingleClick style hint) or
2401 pressing a special key (e.g., \key Enter).
2402
2403 The specified \a item is the item that was clicked, or 0 if no
2404 item was clicked. The \a column is the item's column that was
2405 clicked, or -1 if no item was clicked.
2406*/
2407
2408/*!
2409 \fn void QTreeWidget::itemPressed(QTreeWidgetItem *item, int column)
2410
2411 This signal is emitted when the user presses a mouse button inside
2412 the widget.
2413
2414 The specified \a item is the item that was clicked, or 0 if no
2415 item was clicked. The \a column is the item's column that was
2416 clicked, or -1 if no item was clicked.
2417*/
2418
2419/*!
2420 \fn void QTreeWidget::itemClicked(QTreeWidgetItem *item, int column)
2421
2422 This signal is emitted when the user clicks inside the widget.
2423
2424 The specified \a item is the item that was clicked. The \a column is the
2425 item's column that was clicked. If no item was clicked, no signal will be
2426 emitted.
2427*/
2428
2429/*!
2430 \fn void QTreeWidget::itemDoubleClicked(QTreeWidgetItem *item, int column)
2431
2432 This signal is emitted when the user double clicks inside the
2433 widget.
2434
2435 The specified \a item is the item that was clicked, or 0 if no
2436 item was clicked. The \a column is the item's column that was
2437 clicked. If no item was double clicked, no signal will be emitted.
2438*/
2439
2440/*!
2441 \fn void QTreeWidget::itemExpanded(QTreeWidgetItem *item)
2442
2443 This signal is emitted when the specified \a item is expanded so that
2444 all of its children are displayed.
2445
2446 \note This signal will not be emitted if an item changes its state when
2447 expandAll() is invoked.
2448
2449 \sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem()
2450*/
2451
2452/*!
2453 \fn void QTreeWidget::itemCollapsed(QTreeWidgetItem *item)
2454
2455 This signal is emitted when the specified \a item is collapsed so that
2456 none of its children are displayed.
2457
2458 \note This signal will not be emitted if an item changes its state when
2459 collapseAll() is invoked.
2460
2461 \sa QTreeWidgetItem::isExpanded(), itemExpanded(), collapseItem()
2462*/
2463
2464/*!
2465 \fn void QTreeWidget::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
2466
2467 This signal is emitted when the current item changes. The current
2468 item is specified by \a current, and this replaces the \a previous
2469 current item.
2470
2471 \sa setCurrentItem()
2472*/
2473
2474/*!
2475 \fn void QTreeWidget::itemSelectionChanged()
2476
2477 This signal is emitted when the selection changes in the tree widget.
2478 The current selection can be found with selectedItems().
2479*/
2480
2481/*!
2482 \fn void QTreeWidget::itemEntered(QTreeWidgetItem *item, int column)
2483
2484 This signal is emitted when the mouse cursor enters an \a item over the
2485 specified \a column.
2486 QTreeWidget mouse tracking needs to be enabled for this feature to work.
2487*/
2488
2489/*!
2490 \fn void QTreeWidget::itemChanged(QTreeWidgetItem *item, int column)
2491
2492 This signal is emitted when the contents of the \a column in the specified
2493 \a item changes.
2494*/
2495
2496/*!
2497 \since 4.3
2498
2499 \fn void QTreeWidget::removeItemWidget(QTreeWidgetItem *item, int column)
2500
2501 Removes the widget set in the given \a item in the given \a column.
2502*/
2503
2504/*!
2505 Constructs a tree widget with the given \a parent.
2506*/
2507QTreeWidget::QTreeWidget(QWidget *parent)
2508 : QTreeView(*new QTreeWidgetPrivate(), parent)
2509{
2510 QTreeView::setModel(new QTreeModel(1, this));
2511 connect(this, SIGNAL(pressed(QModelIndex)),
2512 SLOT(_q_emitItemPressed(QModelIndex)));
2513 connect(this, SIGNAL(clicked(QModelIndex)),
2514 SLOT(_q_emitItemClicked(QModelIndex)));
2515 connect(this, SIGNAL(doubleClicked(QModelIndex)),
2516 SLOT(_q_emitItemDoubleClicked(QModelIndex)));
2517 connect(this, SIGNAL(activated(QModelIndex)),
2518 SLOT(_q_emitItemActivated(QModelIndex)));
2519 connect(this, SIGNAL(entered(QModelIndex)),
2520 SLOT(_q_emitItemEntered(QModelIndex)));
2521 connect(this, SIGNAL(expanded(QModelIndex)),
2522 SLOT(_q_emitItemExpanded(QModelIndex)));
2523 connect(this, SIGNAL(collapsed(QModelIndex)),
2524 SLOT(_q_emitItemCollapsed(QModelIndex)));
2525 connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
2526 this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
2527 connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
2528 this, SLOT(_q_emitItemChanged(QModelIndex)));
2529 connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
2530 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
2531 connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
2532 this, SLOT(_q_sort()));
2533 connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
2534 this, SLOT(_q_selectionChanged(QItemSelection,QItemSelection)));
2535 header()->setClickable(false);
2536}
2537
2538/*!
2539 Destroys the tree widget and all its items.
2540*/
2541
2542QTreeWidget::~QTreeWidget()
2543{
2544}
2545
2546/*
2547 Retuns the number of header columns in the view.
2548
2549 \sa sortColumn(), currentColumn(), topLevelItemCount()
2550*/
2551
2552int QTreeWidget::columnCount() const
2553{
2554 Q_D(const QTreeWidget);
2555 return d->model->columnCount();
2556}
2557
2558/*
2559 Sets the number of header \a columns in the tree widget.
2560*/
2561
2562void QTreeWidget::setColumnCount(int columns)
2563{
2564 Q_D(QTreeWidget);
2565 if (columns < 0)
2566 return;
2567 d->treeModel()->setColumnCount(columns);
2568}
2569
2570/*!
2571 \since 4.2
2572
2573 Returns the tree widget's invisible root item.
2574
2575 The invisible root item provides access to the tree widget's top-level items
2576 through the QTreeWidgetItem API, making it possible to write functions that
2577 can treat top-level items and their children in a uniform way; for example,
2578 recursive functions.
2579*/
2580
2581QTreeWidgetItem *QTreeWidget::invisibleRootItem() const
2582{
2583 Q_D(const QTreeWidget);
2584 return d->treeModel()->rootItem;
2585}
2586
2587/*!
2588 Returns the top level item at the given \a index, or 0 if the item does
2589 not exist.
2590
2591 \sa topLevelItemCount(), insertTopLevelItem()
2592*/
2593
2594QTreeWidgetItem *QTreeWidget::topLevelItem(int index) const
2595{
2596 Q_D(const QTreeWidget);
2597 return d->treeModel()->rootItem->child(index);
2598}
2599
2600/*!
2601 \property QTreeWidget::topLevelItemCount
2602 \brief the number of top-level items
2603
2604 By default, this property has a value of 0.
2605
2606 \sa columnCount(), currentItem()
2607*/
2608
2609int QTreeWidget::topLevelItemCount() const
2610{
2611 Q_D(const QTreeWidget);
2612 return d->treeModel()->rootItem->childCount();
2613}
2614
2615/*!
2616 Inserts the \a item at \a index in the top level in the view.
2617
2618 If the item has already been inserted somewhere else it wont be inserted.
2619
2620 \sa addTopLevelItem(), columnCount()
2621*/
2622
2623void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem *item)
2624{
2625 Q_D(QTreeWidget);
2626 d->treeModel()->rootItem->insertChild(index, item);
2627}
2628
2629/*!
2630 \since 4.1
2631
2632 Appends the \a item as a top-level item in the widget.
2633
2634 \sa insertTopLevelItem()
2635*/
2636void QTreeWidget::addTopLevelItem(QTreeWidgetItem *item)
2637{
2638 insertTopLevelItem(topLevelItemCount(), item);
2639}
2640
2641/*!
2642 Removes the top-level item at the given \a index in the tree and
2643 returns it, otherwise returns 0;
2644
2645 \sa insertTopLevelItem(), topLevelItem(), topLevelItemCount()
2646*/
2647
2648QTreeWidgetItem *QTreeWidget::takeTopLevelItem(int index)
2649{
2650 Q_D(QTreeWidget);
2651 return d->treeModel()->rootItem->takeChild(index);
2652}
2653
2654/*!
2655 \internal
2656*/
2657int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item)
2658{
2659 Q_D(QTreeWidget);
2660 d->treeModel()->executePendingSort();
2661 return d->treeModel()->rootItem->children.indexOf(item);
2662}
2663
2664/*!
2665 Returns the index of the given top-level \a item, or -1 if the item
2666 cannot be found.
2667
2668 \sa sortItems(), topLevelItemCount()
2669 */
2670int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) const
2671{
2672 Q_D(const QTreeWidget);
2673 d->treeModel()->executePendingSort();
2674 return d->treeModel()->rootItem->children.indexOf(item);
2675}
2676
2677/*!
2678 \since 4.1
2679
2680 Inserts the list of \a items at \a index in the top level in the view.
2681
2682 Items that have already been inserted somewhere else wont be inserted.
2683
2684 \sa addTopLevelItems()
2685*/
2686void QTreeWidget::insertTopLevelItems(int index, const QList<QTreeWidgetItem*> &items)
2687{
2688 Q_D(QTreeWidget);
2689 d->treeModel()->rootItem->insertChildren(index, items);
2690}
2691
2692/*!
2693 Appends the list of \a items as a top-level items in the widget.
2694
2695 \sa insertTopLevelItems()
2696*/
2697void QTreeWidget::addTopLevelItems(const QList<QTreeWidgetItem*> &items)
2698{
2699 insertTopLevelItems(topLevelItemCount(), items);
2700}
2701
2702/*!
2703 Returns the item used for the tree widget's header.
2704
2705 \sa setHeaderItem()
2706*/
2707
2708QTreeWidgetItem *QTreeWidget::headerItem() const
2709{
2710 Q_D(const QTreeWidget);
2711 return d->treeModel()->headerItem;
2712}
2713
2714/*!
2715 Sets the header \a item for the tree widget. The label for each column in
2716 the header is supplied by the corresponding label in the item.
2717
2718 The tree widget takes ownership of the item.
2719
2720 \sa headerItem(), setHeaderLabels()
2721*/
2722
2723void QTreeWidget::setHeaderItem(QTreeWidgetItem *item)
2724{
2725 Q_D(QTreeWidget);
2726 if (!item)
2727 return;
2728 item->view = this;
2729
2730 int oldCount = columnCount();
2731 if (oldCount < item->columnCount())
2732 d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount());
2733 else
2734 d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount);
2735 delete d->treeModel()->headerItem;
2736 d->treeModel()->headerItem = item;
2737 if (oldCount < item->columnCount())
2738 d->treeModel()->endInsertColumns();
2739 else
2740 d->treeModel()->endRemoveColumns();
2741 d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount);
2742}
2743
2744
2745/*!
2746 Adds a column in the header for each item in the \a labels list, and sets
2747 the label for each column.
2748
2749 Note that setHeaderLabels() won't remove existing columns.
2750
2751 \sa setHeaderItem(), setHeaderLabel()
2752*/
2753void QTreeWidget::setHeaderLabels(const QStringList &labels)
2754{
2755 Q_D(QTreeWidget);
2756 if (columnCount() < labels.count())
2757 setColumnCount(labels.count());
2758 QTreeWidgetItem *item = d->treeModel()->headerItem;
2759 for (int i = 0; i < labels.count(); ++i)
2760 item->setText(i, labels.at(i));
2761}
2762
2763/*!
2764 \fn void QTreeWidget::setHeaderLabel(const QString &label)
2765 \since 4.2
2766
2767 Same as setHeaderLabels(QStringList(\a label)).
2768*/
2769
2770/*!
2771 Returns the current item in the tree widget.
2772
2773 \sa setCurrentItem(), currentItemChanged()
2774*/
2775QTreeWidgetItem *QTreeWidget::currentItem() const
2776{
2777 Q_D(const QTreeWidget);
2778 return d->item(currentIndex());
2779}
2780
2781/*!
2782 \since 4.1
2783 Returns the current column in the tree widget.
2784
2785 \sa setCurrentItem(), columnCount()
2786*/
2787int QTreeWidget::currentColumn() const
2788{
2789 return currentIndex().column();
2790}
2791
2792/*!
2793 Sets the current \a item in the tree widget.
2794
2795 Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
2796 the item is also be selected.
2797
2798 \sa currentItem(), currentItemChanged()
2799*/
2800void QTreeWidget::setCurrentItem(QTreeWidgetItem *item)
2801{
2802 setCurrentItem(item, 0);
2803}
2804
2805/*!
2806 \since 4.1
2807 Sets the current \a item in the tree widget and the current column to \a column.
2808
2809 \sa currentItem()
2810*/
2811void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column)
2812{
2813 Q_D(QTreeWidget);
2814 setCurrentIndex(d->index(item, column));
2815}
2816
2817/*!
2818 \since 4.4
2819 Sets the current \a item in the tree widget and the current column to \a column,
2820 using the given \a command.
2821
2822 \sa currentItem()
2823*/
2824void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column,
2825 QItemSelectionModel::SelectionFlags command)
2826{
2827 Q_D(QTreeWidget);
2828 d->selectionModel->setCurrentIndex(d->index(item, column), command);
2829}
2830
2831
2832/*!
2833 Returns a pointer to the item at the coordinates \a p.
2834
2835 \sa visualItemRect()
2836*/
2837QTreeWidgetItem *QTreeWidget::itemAt(const QPoint &p) const
2838{
2839 Q_D(const QTreeWidget);
2840 return d->item(indexAt(p));
2841}
2842
2843/*!
2844 \fn QTreeWidgetItem *QTreeWidget::itemAt(int x, int y) const
2845 \overload
2846
2847 Returns a pointer to the item at the coordinates (\a x, \a y).
2848*/
2849
2850/*!
2851 Returns the rectangle on the viewport occupied by the item at \a item.
2852
2853 \sa itemAt()
2854*/
2855QRect QTreeWidget::visualItemRect(const QTreeWidgetItem *item) const
2856{
2857 Q_D(const QTreeWidget);
2858 //the visual rect for an item is across all columns. So we need to determine
2859 //what is the first and last column and get their visual index rects
2860 QModelIndex base = d->index(item);
2861 const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
2862 const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
2863 QModelIndex first = base.sibling(base.row(), header()->logicalIndex(firstVisiblesection));
2864 QModelIndex last = base.sibling(base.row(), header()->logicalIndex(lastVisibleSection));
2865 return visualRect(first) | visualRect(last);
2866}
2867
2868/*!
2869 \since 4.1
2870
2871 Returns the column used to sort the contents of the widget.
2872
2873 \sa sortItems()
2874*/
2875int QTreeWidget::sortColumn() const
2876{
2877 Q_D(const QTreeWidget);
2878 return (d->explicitSortColumn != -1
2879 ? d->explicitSortColumn
2880 : header()->sortIndicatorSection());
2881}
2882
2883/*!
2884 Sorts the items in the widget in the specified \a order by the values in
2885 the given \a column.
2886
2887 \sa sortColumn()
2888*/
2889
2890void QTreeWidget::sortItems(int column, Qt::SortOrder order)
2891{
2892 Q_D(QTreeWidget);
2893 header()->setSortIndicator(column, order);
2894 d->model->sort(column, order);
2895}
2896
2897/*!
2898 \internal
2899
2900 ### Qt 5: remove
2901*/
2902void QTreeWidget::setSortingEnabled(bool enable)
2903{
2904 QTreeView::setSortingEnabled(enable);
2905}
2906
2907/*!
2908 \internal
2909
2910 ### Qt 5: remove
2911*/
2912bool QTreeWidget::isSortingEnabled() const
2913{
2914 return QTreeView::isSortingEnabled();
2915}
2916
2917/*!
2918 Starts editing the \a item in the given \a column if it is editable.
2919*/
2920
2921void QTreeWidget::editItem(QTreeWidgetItem *item, int column)
2922{
2923 Q_D(QTreeWidget);
2924 edit(d->index(item, column));
2925}
2926
2927/*!
2928 Opens a persistent editor for the \a item in the given \a column.
2929
2930 \sa closePersistentEditor()
2931*/
2932
2933void QTreeWidget::openPersistentEditor(QTreeWidgetItem *item, int column)
2934{
2935 Q_D(QTreeWidget);
2936 QAbstractItemView::openPersistentEditor(d->index(item, column));
2937}
2938
2939/*!
2940 Closes the persistent editor for the \a item in the given \a column.
2941
2942 This function has no effect if no persistent editor is open for this
2943 combination of item and column.
2944
2945 \sa openPersistentEditor()
2946*/
2947
2948void QTreeWidget::closePersistentEditor(QTreeWidgetItem *item, int column)
2949{
2950 Q_D(QTreeWidget);
2951 QAbstractItemView::closePersistentEditor(d->index(item, column));
2952}
2953
2954/*!
2955 \since 4.1
2956
2957 Returns the widget displayed in the cell specified by \a item and the given \a column.
2958
2959 \note The tree takes ownership of the widget.
2960
2961*/
2962QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const
2963{
2964 Q_D(const QTreeWidget);
2965 return QAbstractItemView::indexWidget(d->index(item, column));
2966}
2967
2968/*!
2969 \since 4.1
2970
2971 Sets the given \a widget to be displayed in the cell specified by the given
2972 \a item and \a column.
2973
2974 The given \a widget's \l {QWidget::}{autoFillBackground} property must be
2975 set to true, otherwise the widget's background will be transparent, showing
2976 both the model data and the tree widget item.
2977
2978 This function should only be used to display static content in the place of
2979 a tree widget item. If you want to display custom dynamic content or
2980 implement a custom editor widget, use QTreeView and subclass QItemDelegate
2981 instead.
2982
2983 This function cannot be called before the item hierarchy has been set up,
2984 i.e., the QTreeWidgetItem that will hold \a widget must have been added to
2985 the view before \a widget is set.
2986
2987 \note The tree takes ownership of the widget.
2988
2989 \sa {Delegate Classes}
2990*/
2991void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
2992{
2993 Q_D(QTreeWidget);
2994 QAbstractItemView::setIndexWidget(d->index(item, column), widget);
2995}
2996
2997/*!
2998 Returns true if the \a item is selected; otherwise returns false.
2999
3000 \sa itemSelectionChanged()
3001
3002 \obsolete
3003
3004 This function is deprecated. Use \l{QTreeWidgetItem::isSelected()} instead.
3005*/
3006bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const
3007{
3008 if (!item)
3009 return false;
3010 return item->d->selected;
3011}
3012
3013/*!
3014 If \a select is true, the given \a item is selected; otherwise it is
3015 deselected.
3016
3017 \sa itemSelectionChanged()
3018
3019 \obsolete
3020
3021 This function is deprecated. Use \l{QTreeWidgetItem::setSelected()} instead.
3022*/
3023void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select)
3024{
3025 Q_D(QTreeWidget);
3026
3027 if (!item)
3028 return;
3029
3030 selectionModel()->select(d->index(item), (select ? QItemSelectionModel::Select
3031 : QItemSelectionModel::Deselect)
3032 |QItemSelectionModel::Rows);
3033 item->d->selected = select;
3034}
3035
3036/*!
3037 Returns a list of all selected non-hidden items.
3038
3039 \sa itemSelectionChanged()
3040*/
3041QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
3042{
3043 Q_D(const QTreeWidget);
3044 QModelIndexList indexes = selectionModel()->selectedIndexes();
3045 QList<QTreeWidgetItem*> items;
3046 items.reserve(indexes.count());
3047 QSet<QTreeWidgetItem *> seen;
3048 seen.reserve(indexes.count());
3049 for (int i = 0; i < indexes.count(); ++i) {
3050 QTreeWidgetItem *item = d->item(indexes.at(i));
3051 if (isItemHidden(item) || seen.contains(item))
3052 continue;
3053 seen.insert(item);
3054 items.append(item);
3055 }
3056 return items;
3057}
3058
3059/*!
3060 Returns a list of items that match the given \a text, using the given \a flags, in the given \a column.
3061*/
3062QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFlags flags, int column) const
3063{
3064 Q_D(const QTreeWidget);
3065 QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()),
3066 Qt::DisplayRole, text, -1, flags);
3067 QList<QTreeWidgetItem*> items;
3068 for (int i = 0; i < indexes.size(); ++i)
3069 items.append(d->item(indexes.at(i)));
3070 return items;
3071}
3072
3073/*!
3074 Returns true if the \a item is explicitly hidden, otherwise returns false.
3075
3076 \obsolete
3077
3078 This function is deprecated. Use \l{QTreeWidgetItem::isHidden()} instead.
3079*/
3080bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
3081{
3082 Q_D(const QTreeWidget);
3083 if (item == d->treeModel()->headerItem)
3084 return header()->isHidden();
3085 if (d->hiddenIndexes.isEmpty())
3086 return false;
3087 QTreeModel::SkipSorting skipSorting(d->treeModel());
3088 return d->isRowHidden(d->index(item));
3089}
3090
3091/*!
3092 Hides the given \a item if \a hide is true; otherwise shows the item.
3093
3094 \sa itemChanged()
3095
3096 \obsolete
3097
3098 This function is deprecated. Use \l{QTreeWidgetItem::setHidden()} instead.
3099*/
3100void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
3101{
3102 Q_D(QTreeWidget);
3103 if (item == d->treeModel()->headerItem) {
3104 header()->setHidden(hide);
3105 } else {
3106 const QModelIndex index = d->index(item);
3107 setRowHidden(index.row(), index.parent(), hide);
3108 }
3109}
3110
3111/*!
3112 Returns true if the given \a item is open; otherwise returns false.
3113
3114 \sa itemExpanded()
3115
3116 \obsolete
3117
3118 This function is deprecated. Use \l{QTreeWidgetItem::isExpanded()} instead.
3119*/
3120bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const
3121{
3122 Q_D(const QTreeWidget);
3123 QTreeModel::SkipSorting skipSorting(d->treeModel());
3124 return isExpanded(d->index(item));
3125}
3126
3127/*!
3128 Sets the item referred to by \a item to either closed or opened,
3129 depending on the value of \a expand.
3130
3131 \sa expandItem(), collapseItem(), itemExpanded()
3132
3133 \obsolete
3134
3135 This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead.
3136*/
3137void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand)
3138{
3139 Q_D(QTreeWidget);
3140 QTreeModel::SkipSorting skipSorting(d->treeModel());
3141 setExpanded(d->index(item), expand);
3142}
3143
3144/*!
3145 \since 4.3
3146
3147 Returns true if the given \a item is set to show only one section over all columns;
3148 otherwise returns false.
3149
3150 \sa setFirstItemColumnSpanned()
3151*/
3152bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const
3153{
3154 Q_D(const QTreeWidget);
3155 if (item == d->treeModel()->headerItem)
3156 return false; // We can't set the header items to spanning
3157 const QModelIndex index = d->index(item);
3158 return isFirstColumnSpanned(index.row(), index.parent());
3159}
3160
3161/*!
3162 \since 4.3
3163
3164 Sets the given \a item to only show one section for all columns if \a span is true;
3165 otherwise the item will show one section per column.
3166
3167 \sa isFirstItemColumnSpanned()
3168*/
3169void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span)
3170{
3171 Q_D(QTreeWidget);
3172 if (item == d->treeModel()->headerItem)
3173 return; // We can't set header items to spanning
3174 const QModelIndex index = d->index(item);
3175 setFirstColumnSpanned(index.row(), index.parent(), span);
3176}
3177
3178/*!
3179 \since 4.3
3180
3181 Returns the item above the given \a item.
3182*/
3183QTreeWidgetItem *QTreeWidget::itemAbove(const QTreeWidgetItem *item) const
3184{
3185 Q_D(const QTreeWidget);
3186 if (item == d->treeModel()->headerItem)
3187 return 0;
3188 const QModelIndex index = d->index(item);
3189 const QModelIndex above = indexAbove(index);
3190 return d->item(above);
3191}
3192
3193/*!
3194 \since 4.3
3195
3196 Returns the item visually below the given \a item.
3197*/
3198QTreeWidgetItem *QTreeWidget::itemBelow(const QTreeWidgetItem *item) const
3199{
3200 Q_D(const QTreeWidget);
3201 if (item == d->treeModel()->headerItem)
3202 return 0;
3203 const QModelIndex index = d->index(item);
3204 const QModelIndex below = indexBelow(index);
3205 return d->item(below);
3206}
3207
3208/*!
3209 \reimp
3210 */
3211void QTreeWidget::setSelectionModel(QItemSelectionModel *selectionModel)
3212{
3213 Q_D(QTreeWidget);
3214 QTreeView::setSelectionModel(selectionModel);
3215 QItemSelection newSelection = selectionModel->selection();
3216 if (!newSelection.isEmpty())
3217 d->_q_selectionChanged(newSelection, QItemSelection());
3218}
3219
3220/*!
3221 Ensures that the \a item is visible, scrolling the view if necessary using
3222 the specified \a hint.
3223
3224 \sa currentItem(), itemAt(), topLevelItem()
3225*/
3226void QTreeWidget::scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint)
3227{
3228 Q_D(QTreeWidget);
3229 QTreeView::scrollTo(d->index(item), hint);
3230}
3231
3232/*!
3233 Expands the \a item. This causes the tree containing the item's children
3234 to be expanded.
3235
3236 \sa collapseItem(), currentItem(), itemAt(), topLevelItem(), itemExpanded()
3237*/
3238void QTreeWidget::expandItem(const QTreeWidgetItem *item)
3239{
3240 Q_D(QTreeWidget);
3241 QTreeModel::SkipSorting skipSorting(d->treeModel());
3242 expand(d->index(item));
3243}
3244
3245/*!
3246 Closes the \a item. This causes the tree containing the item's children
3247 to be collapsed.
3248
3249 \sa expandItem(), currentItem(), itemAt(), topLevelItem()
3250*/
3251void QTreeWidget::collapseItem(const QTreeWidgetItem *item)
3252{
3253 Q_D(QTreeWidget);
3254 QTreeModel::SkipSorting skipSorting(d->treeModel());
3255 collapse(d->index(item));
3256}
3257
3258/*!
3259 Clears the tree widget by removing all of its items and selections.
3260
3261 \bold{Note:} Since each item is removed from the tree widget before being
3262 deleted, the return value of QTreeWidgetItem::treeWidget() will be invalid
3263 when called from an item's destructor.
3264
3265 \sa takeTopLevelItem(), topLevelItemCount(), columnCount()
3266*/
3267void QTreeWidget::clear()
3268{
3269 Q_D(QTreeWidget);
3270 selectionModel()->clear();
3271 d->treeModel()->clear();
3272}
3273
3274/*!
3275 Returns a list of MIME types that can be used to describe a list of
3276 treewidget items.
3277
3278 \sa mimeData()
3279*/
3280QStringList QTreeWidget::mimeTypes() const
3281{
3282 return model()->QAbstractItemModel::mimeTypes();
3283}
3284
3285/*!
3286 Returns an object that contains a serialized description of the specified
3287 \a items. The format used to describe the items is obtained from the
3288 mimeTypes() function.
3289
3290 If the list of items is empty, 0 is returned rather than a serialized
3291 empty list.
3292*/
3293QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const
3294{
3295 Q_D(const QTreeWidget);
3296 if (d->treeModel()->cachedIndexes.isEmpty()) {
3297 QList<QModelIndex> indexes;
3298 for (int i = 0; i < items.count(); ++i) {
3299 QTreeWidgetItem *item = items.at(i);
3300 for (int c = 0; c < item->values.count(); ++c) {
3301 indexes << indexFromItem(item, c);
3302 }
3303 }
3304 return d->model->QAbstractItemModel::mimeData(indexes);
3305 }
3306 return d->treeModel()->internalMimeData();
3307}
3308
3309/*!
3310 Handles the \a data supplied by a drag and drop operation that ended with
3311 the given \a action in the \a index in the given \a parent item.
3312
3313 The default implementation returns true if the drop was
3314 successfully handled by decoding the mime data and inserting it
3315 into the model; otherwise it returns false.
3316
3317 \sa supportedDropActions()
3318*/
3319bool QTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index,
3320 const QMimeData *data, Qt::DropAction action)
3321{
3322 QModelIndex idx;
3323 if (parent) idx = indexFromItem(parent);
3324 return model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx);
3325}
3326
3327/*!
3328 Returns the drop actions supported by this view.
3329
3330 \sa Qt::DropActions
3331*/
3332Qt::DropActions QTreeWidget::supportedDropActions() const
3333{
3334 return model()->QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
3335}
3336
3337/*!
3338 \obsolete
3339 Returns an empty list
3340
3341 \sa mimeData()
3342*/
3343QList<QTreeWidgetItem*> QTreeWidget::items(const QMimeData *data) const
3344{
3345 Q_UNUSED(data);
3346 return QList<QTreeWidgetItem*>();
3347}
3348
3349/*!
3350 Returns the QModelIndex assocated with the given \a item in the given \a column.
3351
3352 \sa itemFromIndex(), topLevelItem()
3353*/
3354QModelIndex QTreeWidget::indexFromItem(QTreeWidgetItem *item, int column) const
3355{
3356 Q_D(const QTreeWidget);
3357 return d->index(item, column);
3358}
3359
3360/*!
3361 Returns a pointer to the QTreeWidgetItem assocated with the given \a index.
3362
3363 \sa indexFromItem()
3364*/
3365QTreeWidgetItem *QTreeWidget::itemFromIndex(const QModelIndex &index) const
3366{
3367 Q_D(const QTreeWidget);
3368 return d->item(index);
3369}
3370
3371#ifndef QT_NO_DRAGANDDROP
3372/*! \reimp */
3373void QTreeWidget::dropEvent(QDropEvent *event) {
3374 Q_D(QTreeWidget);
3375 if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
3376 dragDropMode() == QAbstractItemView::InternalMove)) {
3377 QModelIndex topIndex;
3378 int col = -1;
3379 int row = -1;
3380 if (d->dropOn(event, &row, &col, &topIndex)) {
3381 QList<QModelIndex> idxs = selectedIndexes();
3382 QList<QPersistentModelIndex> indexes;
3383 for (int i = 0; i < idxs.count(); i++)
3384 indexes.append(idxs.at(i));
3385
3386 if (indexes.contains(topIndex))
3387 return;
3388
3389 // When removing items the drop location could shift
3390 QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
3391
3392 // Remove the items
3393 QList<QTreeWidgetItem *> taken;
3394 for (int i = indexes.count() - 1; i >= 0; --i) {
3395 QTreeWidgetItem *parent = itemFromIndex(indexes.at(i));
3396 if (!parent || !parent->parent()) {
3397 taken.append(takeTopLevelItem(indexes.at(i).row()));
3398 } else {
3399 taken.append(parent->parent()->takeChild(indexes.at(i).row()));
3400 }
3401 }
3402
3403 // insert them back in at their new positions
3404 for (int i = 0; i < indexes.count(); ++i) {
3405 // Either at a specific point or appended
3406 if (row == -1) {
3407 if (topIndex.isValid()) {
3408 QTreeWidgetItem *parent = itemFromIndex(topIndex);
3409 parent->insertChild(parent->childCount(), taken.takeFirst());
3410 } else {
3411 insertTopLevelItem(topLevelItemCount(), taken.takeFirst());
3412 }
3413 } else {
3414 int r = dropRow.row() >= 0 ? dropRow.row() : row;
3415 if (topIndex.isValid()) {
3416 QTreeWidgetItem *parent = itemFromIndex(topIndex);
3417 parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst());
3418 } else {
3419 insertTopLevelItem(qMin(r, topLevelItemCount()), taken.takeFirst());
3420 }
3421 }
3422 }
3423
3424 event->accept();
3425 // Don't want QAbstractItemView to delete it because it was "moved" we already did it
3426 event->setDropAction(Qt::CopyAction);
3427 }
3428 }
3429
3430 QTreeView::dropEvent(event);
3431}
3432#endif
3433
3434/*!
3435 \reimp
3436*/
3437
3438void QTreeWidget::setModel(QAbstractItemModel * /*model*/)
3439{
3440 Q_ASSERT(!"QTreeWidget::setModel() - Changing the model of the QTreeWidget is not allowed.");
3441}
3442
3443/*!
3444 \reimp
3445*/
3446bool QTreeWidget::event(QEvent *e)
3447{
3448 Q_D(QTreeWidget);
3449 if (e->type() == QEvent::Polish)
3450 d->treeModel()->executePendingSort();
3451 return QTreeView::event(e);
3452}
3453
3454QT_END_NAMESPACE
3455
3456#include "moc_qtreewidget.cpp"
3457
3458#endif // QT_NO_TREEWIDGET
Note: See TracBrowser for help on using the repository browser.