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

Last change on this file since 786 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 96.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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
1477QTreeWidgetItem::~QTreeWidgetItem()
1478{
1479 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
1480 bool wasSkipSort = false;
1481 if (model) {
1482 wasSkipSort = model->skipPendingSort;
1483 model->skipPendingSort = true;
1484 }
1485 if (par) {
1486 int i = par->children.indexOf(this);
1487 if (i >= 0) {
1488 if (model) model->beginRemoveItems(par, i, 1);
1489 // users _could_ do changes when connected to rowsAboutToBeRemoved,
1490 // so we check again to make sure 'i' is valid
1491 if (!par->children.isEmpty() && par->children.at(i) == this)
1492 par->children.takeAt(i);
1493 if (model) model->endRemoveItems();
1494 }
1495 } else if (model) {
1496 if (this == model->headerItem) {
1497 model->headerItem = 0;
1498 } else {
1499 int i = model->rootItem->children.indexOf(this);
1500 if (i >= 0) {
1501 model->beginRemoveItems(0, i, 1);
1502 // users _could_ do changes when connected to rowsAboutToBeRemoved,
1503 // so we check again to make sure 'i' is valid
1504 if (!model->rootItem->children.isEmpty() && model->rootItem->children.at(i) == this)
1505 model->rootItem->children.takeAt(i);
1506 model->endRemoveItems();
1507 }
1508 }
1509 }
1510 // at this point the persistent indexes for the children should also be invalidated
1511 // since we invalidated the parent
1512 for (int i = 0; i < children.count(); ++i) {
1513 QTreeWidgetItem *child = children.at(i);
1514 // make sure the child does not try to remove itself from our children list
1515 child->par = 0;
1516 // make sure the child does not try to remove itself from the top level list
1517 child->view = 0;
1518 delete child;
1519 }
1520
1521 children.clear();
1522 delete d;
1523 if (model) {
1524 model->skipPendingSort = wasSkipSort;
1525 }
1526}
1527
1528/*!
1529 Creates a deep copy of the item and of its children.
1530*/
1531QTreeWidgetItem *QTreeWidgetItem::clone() const
1532{
1533 QTreeWidgetItem *copy = 0;
1534
1535 QStack<const QTreeWidgetItem*> stack;
1536 QStack<QTreeWidgetItem*> parentStack;
1537 stack.push(this);
1538 parentStack.push(0);
1539
1540 QTreeWidgetItem *root = 0;
1541 const QTreeWidgetItem *item = 0;
1542 QTreeWidgetItem *parent = 0;
1543 while (!stack.isEmpty()) {
1544 // get current item, and copied parent
1545 item = stack.pop();
1546 parent = parentStack.pop();
1547
1548 // copy item
1549 copy = new QTreeWidgetItem(*item);
1550 if (!root)
1551 root = copy;
1552
1553 // set parent and add to parents children list
1554 if (parent) {
1555 copy->par = parent;
1556 parent->children.insert(0, copy);
1557 }
1558
1559 for (int i = 0; i < item->childCount(); ++i) {
1560 stack.push(item->child(i));
1561 parentStack.push(copy);
1562 }
1563 }
1564 return root;
1565}
1566
1567/*!
1568 Sets the item indicator \a policy. This policy decides when the
1569 tree branch expand/collapse indicator is shown.
1570 The default value is ShowForChildren.
1571
1572 \sa childIndicatorPolicy()
1573*/
1574void QTreeWidgetItem::setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy)
1575{
1576 if (d->policy == policy)
1577 return;
1578 d->policy = policy;
1579
1580 if (!view)
1581 return;
1582
1583 view->scheduleDelayedItemsLayout();
1584}
1585
1586/*!
1587 Returns the item indicator policy. This policy decides when the
1588 tree branch expand/collapse indicator is shown.
1589
1590 \sa setChildIndicatorPolicy()
1591*/
1592QTreeWidgetItem::ChildIndicatorPolicy QTreeWidgetItem::childIndicatorPolicy() const
1593{
1594 return d->policy;
1595}
1596
1597/*!
1598 \fn void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
1599
1600 Sets the flags for the item to the given \a flags. These determine whether
1601 the item can be selected or modified. This is often used to disable an item.
1602
1603 \sa flags()
1604*/
1605void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
1606{
1607 const bool enable = (flags & Qt::ItemIsEnabled);
1608 const bool changedState = bool(itemFlags & Qt::ItemIsEnabled) != enable;
1609 const bool changedExplicit = d->disabled != !enable;
1610
1611 d->disabled = !enable;
1612
1613 if (enable && par && !(par->itemFlags & Qt::ItemIsEnabled)) // inherit from parent
1614 itemFlags = flags & ~Qt::ItemIsEnabled;
1615 else // this item is explicitly disabled or has no parent
1616 itemFlags = flags;
1617
1618 if (changedState && changedExplicit) { // if the propagate the change to the children
1619 QStack<QTreeWidgetItem*> parents;
1620 parents.push(this);
1621 while (!parents.isEmpty()) {
1622 QTreeWidgetItem *parent = parents.pop();
1623 for (int i = 0; i < parent->children.count(); ++i) {
1624 QTreeWidgetItem *child = parent->children.at(i);
1625 if (!child->d->disabled) { // if not explicitly disabled
1626 parents.push(child);
1627 if (enable)
1628 child->itemFlags = child->itemFlags | Qt::ItemIsEnabled;
1629 else
1630 child->itemFlags = child->itemFlags & ~Qt::ItemIsEnabled;
1631 child->itemChanged(); // ### we may want to optimize this
1632 }
1633 }
1634 }
1635 }
1636 itemChanged();
1637}
1638
1639void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item)
1640{
1641 Q_ASSERT(item);
1642 const bool enable = item->par ? (item->par->itemFlags.testFlag(Qt::ItemIsEnabled)) : true;
1643
1644 QStack<QTreeWidgetItem*> parents;
1645 parents.push(item);
1646 while (!parents.isEmpty()) {
1647 QTreeWidgetItem *parent = parents.pop();
1648 if (!parent->d->disabled) { // if not explicitly disabled
1649 Qt::ItemFlags oldFlags = parent->itemFlags;
1650 if (enable)
1651 parent->itemFlags = parent->itemFlags | Qt::ItemIsEnabled;
1652 else
1653 parent->itemFlags = parent->itemFlags & ~Qt::ItemIsEnabled;
1654 if (parent->itemFlags != oldFlags)
1655 parent->itemChanged();
1656 }
1657
1658 for (int i = 0; i < parent->children.count(); ++i) {
1659 QTreeWidgetItem *child = parent->children.at(i);
1660 parents.push(child);
1661 }
1662 }
1663}
1664/*!
1665 \fn Qt::ItemFlags QTreeWidgetItem::flags() const
1666
1667 Returns the flags used to describe the item. These determine whether
1668 the item can be checked, edited, and selected.
1669
1670 The default value for flags is
1671 Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled.
1672 If the item was constructed with a parent, flags will in addition contain Qt::ItemIsDropEnabled.
1673
1674 \sa setFlags()
1675*/
1676Qt::ItemFlags QTreeWidgetItem::flags() const
1677{
1678 return itemFlags;
1679}
1680
1681/*!
1682 Sets the value for the item's \a column and \a role to the given
1683 \a value.
1684
1685 The \a role describes the type of data specified by \a value, and is defined by
1686 the Qt::ItemDataRole enum.
1687*/
1688void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
1689{
1690 if (column < 0)
1691 return;
1692
1693 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
1694 switch (role) {
1695 case Qt::EditRole:
1696 case Qt::DisplayRole: {
1697 if (values.count() <= column) {
1698 if (model && this == model->headerItem)
1699 model->setColumnCount(column + 1);
1700 else
1701 values.resize(column + 1);
1702 }
1703 if (d->display.count() <= column) {
1704 for (int i = d->display.count() - 1; i < column - 1; ++i)
1705 d->display.append(QVariant());
1706 d->display.append(value);
1707 } else if (d->display[column] != value) {
1708 d->display[column] = value;
1709 } else {
1710 return; // value is unchanged
1711 }
1712 } break;
1713 case Qt::CheckStateRole:
1714 if (itemFlags & Qt::ItemIsTristate) {
1715 for (int i = 0; i < children.count(); ++i) {
1716 QTreeWidgetItem *child = children.at(i);
1717 if (child->data(column, role).isValid()) {// has a CheckState
1718 Qt::ItemFlags f = itemFlags; // a little hack to avoid multiple dataChanged signals
1719 itemFlags &= ~Qt::ItemIsTristate;
1720 child->setData(column, role, value);
1721 itemFlags = f;
1722 }
1723 }
1724 }
1725 // Don't break, but fall through
1726 default:
1727 if (column < values.count()) {
1728 bool found = false;
1729 QVector<QWidgetItemData> column_values = values.at(column);
1730 for (int i = 0; i < column_values.count(); ++i) {
1731 if (column_values.at(i).role == role) {
1732 if (column_values.at(i).value == value)
1733 return; // value is unchanged
1734 values[column][i].value = value;
1735 found = true;
1736 break;
1737 }
1738 }
1739 if (!found)
1740 values[column].append(QWidgetItemData(role, value));
1741 } else {
1742 if (model && this == model->headerItem)
1743 model->setColumnCount(column + 1);
1744 else
1745 values.resize(column + 1);
1746 values[column].append(QWidgetItemData(role, value));
1747 }
1748 }
1749
1750 if (model) {
1751 model->emitDataChanged(this, column);
1752 if (role == Qt::CheckStateRole) {
1753 QTreeWidgetItem *p;
1754 for (p = par; p && (p->itemFlags & Qt::ItemIsTristate); p = p->par)
1755 model->emitDataChanged(p, column);
1756 }
1757 }
1758}
1759
1760/*!
1761 Returns the value for the item's \a column and \a role.
1762*/
1763QVariant QTreeWidgetItem::data(int column, int role) const
1764{
1765 switch (role) {
1766 case Qt::EditRole:
1767 case Qt::DisplayRole:
1768 if (column >= 0 && column < d->display.count())
1769 return d->display.at(column);
1770 break;
1771 case Qt::CheckStateRole:
1772 // special case for check state in tristate
1773 if (children.count() && (itemFlags & Qt::ItemIsTristate))
1774 return childrenCheckState(column);
1775 // fallthrough intended
1776 default:
1777 if (column >= 0 && column < values.size()) {
1778 const QVector<QWidgetItemData> &column_values = values.at(column);
1779 for (int i = 0; i < column_values.count(); ++i)
1780 if (column_values.at(i).role == role)
1781 return column_values.at(i).value;
1782 }
1783 }
1784 return QVariant();
1785}
1786
1787/*!
1788 Returns true if the text in the item is less than the text in the
1789 \a other item, otherwise returns false.
1790*/
1791
1792bool QTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
1793{
1794 int column = view ? view->sortColumn() : 0;
1795 const QVariant v1 = data(column, Qt::DisplayRole);
1796 const QVariant v2 = other.data(column, Qt::DisplayRole);
1797 return QAbstractItemModelPrivate::variantLessThan(v1, v2);
1798}
1799
1800#ifndef QT_NO_DATASTREAM
1801
1802/*!
1803 Reads the item from stream \a in. This only reads data into a single item.
1804
1805 \sa write()
1806*/
1807void QTreeWidgetItem::read(QDataStream &in)
1808{
1809 // convert from streams written before we introduced display (4.2.0)
1810 if (in.version() < QDataStream::Qt_4_2) {
1811 d->display.clear();
1812 in >> values;
1813 // move the display value over to the display string list
1814 for (int column = 0; column < values.count(); ++column) {
1815 d->display << QVariant();
1816 for (int i = 0; i < values.at(column).count(); ++i) {
1817 if (values.at(column).at(i).role == Qt::DisplayRole) {
1818 d->display[column] = values.at(column).at(i).value;
1819 values[column].remove(i--);
1820 }
1821 }
1822 }
1823 } else {
1824 in >> values >> d->display;
1825 }
1826}
1827
1828/*!
1829 Writes the item to stream \a out. This only writes data from one single item.
1830
1831 \sa read()
1832*/
1833void QTreeWidgetItem::write(QDataStream &out) const
1834{
1835 out << values << d->display;
1836}
1837#endif // QT_NO_DATASTREAM
1838
1839/*!
1840 \since 4.1
1841
1842 Constructs a copy of \a other. Note that type() and treeWidget()
1843 are not copied.
1844
1845 This function is useful when reimplementing clone().
1846
1847 \sa data(), flags()
1848*/
1849QTreeWidgetItem::QTreeWidgetItem(const QTreeWidgetItem &other)
1850 : rtti(Type), values(other.values), view(0),
1851 d(new QTreeWidgetItemPrivate(this)), par(0),
1852 itemFlags(other.itemFlags)
1853{
1854 d->display = other.d->display;
1855}
1856
1857/*!
1858 Assigns \a other's data and flags to this item. Note that type()
1859 and treeWidget() are not copied.
1860
1861 This function is useful when reimplementing clone().
1862
1863 \sa data(), flags()
1864*/
1865QTreeWidgetItem &QTreeWidgetItem::operator=(const QTreeWidgetItem &other)
1866{
1867 values = other.values;
1868 d->display = other.d->display;
1869 d->policy = other.d->policy;
1870 itemFlags = other.itemFlags;
1871 return *this;
1872}
1873
1874/*!
1875 Appends the \a child item to the list of children.
1876
1877 \sa insertChild() takeChild()
1878*/
1879void QTreeWidgetItem::addChild(QTreeWidgetItem *child)
1880{
1881 if (child) {
1882 insertChild(children.count(), child);
1883 child->d->rowGuess = children.count() - 1;
1884 }
1885}
1886
1887/*!
1888 Inserts the \a child item at \a index in the list of children.
1889
1890 If the child has already been inserted somewhere else it wont be inserted again.
1891*/
1892void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
1893{
1894 if (index < 0 || index > children.count() || child == 0 || child->view != 0 || child->par != 0)
1895 return;
1896
1897 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0)) {
1898 const bool wasSkipSort = model->skipPendingSort;
1899 model->skipPendingSort = true;
1900 if (model->rootItem == this)
1901 child->par = 0;
1902 else
1903 child->par = this;
1904 if (view->isSortingEnabled()) {
1905 // do a delayed sort instead
1906 if (!model->sortPendingTimer.isActive())
1907 model->sortPendingTimer.start(0, model);
1908 }
1909 model->beginInsertItems(this, index, 1);
1910 int cols = model->columnCount();
1911 QStack<QTreeWidgetItem*> stack;
1912 stack.push(child);
1913 while (!stack.isEmpty()) {
1914 QTreeWidgetItem *i = stack.pop();
1915 i->view = view;
1916 i->values.reserve(cols);
1917 for (int c = 0; c < i->children.count(); ++c)
1918 stack.push(i->children.at(c));
1919 }
1920 children.insert(index, child);
1921 model->endInsertItems();
1922 model->skipPendingSort = wasSkipSort;
1923 } else {
1924 child->par = this;
1925 children.insert(index, child);
1926 }
1927 if (child->par)
1928 d->propagateDisabled(child);
1929}
1930
1931/*!
1932 Removes the given item indicated by \a child.
1933 The removed item will not be deleted.
1934*/
1935void QTreeWidgetItem::removeChild(QTreeWidgetItem *child)
1936{
1937 (void)takeChild(children.indexOf(child));
1938}
1939
1940/*!
1941 Removes the item at \a index and returns it, otherwise return 0.
1942*/
1943QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
1944{
1945 // we move this outside the check of the index to allow executing
1946 // pending sorts from inline functions, using this function (hack)
1947 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
1948 if (model) {
1949 // This will trigger a layoutChanged signal, thus we might want to optimize
1950 // this function by not emitting the rowsRemoved signal etc to the view.
1951 // On the other hand we also need to make sure that the selectionmodel
1952 // is updated in case we take an item that is selected.
1953 model->skipPendingSort = false;
1954 model->executePendingSort();
1955 }
1956 if (index >= 0 && index < children.count()) {
1957 if (model) model->beginRemoveItems(this, index, 1);
1958 QTreeWidgetItem *item = children.takeAt(index);
1959 item->par = 0;
1960 QStack<QTreeWidgetItem*> stack;
1961 stack.push(item);
1962 while (!stack.isEmpty()) {
1963 QTreeWidgetItem *i = stack.pop();
1964 i->view = 0;
1965 for (int c = 0; c < i->children.count(); ++c)
1966 stack.push(i->children.at(c));
1967 }
1968 d->propagateDisabled(item);
1969 if (model) model->endRemoveRows();
1970 return item;
1971 }
1972 return 0;
1973}
1974
1975/*!
1976 \since 4.1
1977
1978 Appends the given list of \a children to the item.
1979
1980 \sa insertChildren() takeChildren()
1981*/
1982void QTreeWidgetItem::addChildren(const QList<QTreeWidgetItem*> &children)
1983{
1984 insertChildren(this->children.count(), children);
1985}
1986
1987/*!
1988 \since 4.1
1989
1990 Inserts the given list of \a children into the list of the item children at \a index .
1991
1992 Children that have already been inserted somewhere else wont be inserted.
1993*/
1994void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &children)
1995{
1996 if (view && view->isSortingEnabled()) {
1997 for (int n = 0; n < children.count(); ++n)
1998 insertChild(index, children.at(n));
1999 return;
2000 }
2001 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
2002 QStack<QTreeWidgetItem*> stack;
2003 QList<QTreeWidgetItem*> itemsToInsert;
2004 for (int n = 0; n < children.count(); ++n) {
2005 QTreeWidgetItem *child = children.at(n);
2006 if (child->view || child->par)
2007 continue;
2008 itemsToInsert.append(child);
2009 if (view && model) {
2010 if (child->childCount() == 0)
2011 child->view = view;
2012 else
2013 stack.push(child);
2014 }
2015 if (model && (model->rootItem == this))
2016 child->par = 0;
2017 else
2018 child->par = this;
2019 }
2020 if (!itemsToInsert.isEmpty()) {
2021 while (!stack.isEmpty()) {
2022 QTreeWidgetItem *i = stack.pop();
2023 i->view = view;
2024 for (int c = 0; c < i->children.count(); ++c)
2025 stack.push(i->children.at(c));
2026 }
2027 if (model) model->beginInsertItems(this, index, itemsToInsert.count());
2028 for (int n = 0; n < itemsToInsert.count(); ++n) {
2029 QTreeWidgetItem *child = itemsToInsert.at(n);
2030 this->children.insert(index + n, child);
2031 if (child->par)
2032 d->propagateDisabled(child);
2033 }
2034 if (model) model->endInsertItems();
2035 }
2036}
2037
2038/*!
2039 \since 4.1
2040
2041 Removes the list of children and returns it, otherwise returns an empty list.
2042*/
2043QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
2044{
2045 QList<QTreeWidgetItem*> removed;
2046 if (children.count() > 0) {
2047 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
2048 if (model) {
2049 // This will trigger a layoutChanged signal, thus we might want to optimize
2050 // this function by not emitting the rowsRemoved signal etc to the view.
2051 // On the other hand we also need to make sure that the selectionmodel
2052 // is updated in case we take an item that is selected.
2053 model->executePendingSort();
2054 }
2055 if (model) model->beginRemoveItems(this, 0, children.count());
2056 for (int n = 0; n < children.count(); ++n) {
2057 QTreeWidgetItem *item = children.at(n);
2058 item->par = 0;
2059 QStack<QTreeWidgetItem*> stack;
2060 stack.push(item);
2061 while (!stack.isEmpty()) {
2062 QTreeWidgetItem *i = stack.pop();
2063 i->view = 0;
2064 for (int c = 0; c < i->children.count(); ++c)
2065 stack.push(i->children.at(c));
2066 }
2067 d->propagateDisabled(item);
2068 }
2069 removed = children;
2070 children.clear(); // detach
2071 if (model) model->endRemoveItems();
2072 }
2073 return removed;
2074}
2075
2076
2077void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool climb)
2078{
2079 QTreeModel *model = (q->view ? qobject_cast<QTreeModel*>(q->view->model()) : 0);
2080 if (!model)
2081 return;
2082 model->sortItems(&q->children, column, order);
2083 if (climb) {
2084 QList<QTreeWidgetItem*>::iterator it = q->children.begin();
2085 for (; it != q->children.end(); ++it) {
2086 //here we call the private object's method to avoid emitting
2087 //the layoutAboutToBeChanged and layoutChanged signals
2088 (*it)->d->sortChildren(column, order, climb);
2089 }
2090 }
2091}
2092
2093/*!
2094 \internal
2095
2096 Sorts the children by the value in the given \a column, in the \a order
2097 specified. If \a climb is true, the items below each of the children will
2098 also be sorted.
2099*/
2100void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order, bool climb)
2101{
2102 QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0);
2103 if (!model)
2104 return;
2105 if (model->isChanging())
2106 return;
2107 int oldSortColumn = view->d_func()->explicitSortColumn;
2108 view->d_func()->explicitSortColumn = column;
2109 emit model->layoutAboutToBeChanged();
2110 d->sortChildren(column, order, climb);
2111 emit model->layoutChanged();
2112 view->d_func()->explicitSortColumn = oldSortColumn;
2113}
2114
2115/*!
2116 \internal
2117
2118 Calculates the checked state of the item based on the checked state
2119 of its children. E.g. if all children checked => this item is also
2120 checked; if some children checked => this item is partially checked;
2121 if no children checked => this item is unchecked.
2122*/
2123QVariant QTreeWidgetItem::childrenCheckState(int column) const
2124{
2125 if (column < 0)
2126 return QVariant();
2127 bool checkedChildren = false;
2128 bool uncheckedChildren = false;
2129 for (int i = 0; i < children.count(); ++i) {
2130 QVariant value = children.at(i)->data(column, Qt::CheckStateRole);
2131 if (!value.isValid())
2132 return QVariant();
2133
2134 switch (static_cast<Qt::CheckState>(value.toInt()))
2135 {
2136 case Qt::Unchecked:
2137 uncheckedChildren = true;
2138 break;
2139 case Qt::Checked:
2140 checkedChildren = true;
2141 break;
2142 case Qt::PartiallyChecked:
2143 default:
2144 return Qt::PartiallyChecked;
2145 }
2146 }
2147
2148 if (uncheckedChildren && checkedChildren)
2149 return Qt::PartiallyChecked;
2150 if (uncheckedChildren)
2151 return Qt::Unchecked;
2152 else if (checkedChildren)
2153 return Qt::Checked;
2154 else
2155 return QVariant(); // value was not defined
2156}
2157
2158/*!
2159 \since 4.5
2160
2161 Causes the model associated with this item to emit a
2162 \l{QAbstractItemModel::dataChanged()}{dataChanged}() signal for this
2163 item.
2164
2165 You normally only need to call this function if you have subclassed
2166 QTreeWidgetItem and reimplemented data() and/or setData().
2167
2168 \sa setData()
2169*/
2170void QTreeWidgetItem::emitDataChanged()
2171{
2172 itemChanged();
2173}
2174
2175/*!
2176 \internal
2177*/
2178void QTreeWidgetItem::itemChanged()
2179{
2180 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0))
2181 model->itemChanged(this);
2182}
2183
2184/*!
2185 \internal
2186*/
2187void QTreeWidgetItem::executePendingSort() const
2188{
2189 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0))
2190 model->executePendingSort();
2191}
2192
2193
2194#ifndef QT_NO_DATASTREAM
2195/*!
2196 \relates QTreeWidgetItem
2197
2198 Writes the tree widget item \a item to stream \a out.
2199
2200 This operator uses QTreeWidgetItem::write().
2201
2202 \sa {Format of the QDataStream Operators}
2203*/
2204QDataStream &operator<<(QDataStream &out, const QTreeWidgetItem &item)
2205{
2206 item.write(out);
2207 return out;
2208}
2209
2210/*!
2211 \relates QTreeWidgetItem
2212
2213 Reads a tree widget item from stream \a in into \a item.
2214
2215 This operator uses QTreeWidgetItem::read().
2216
2217 \sa {Format of the QDataStream Operators}
2218*/
2219QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item)
2220{
2221 item.read(in);
2222 return in;
2223}
2224#endif // QT_NO_DATASTREAM
2225
2226
2227void QTreeWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
2228{
2229 Q_Q(QTreeWidget);
2230 emit q->itemPressed(item(index), index.column());
2231}
2232
2233void QTreeWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
2234{
2235 Q_Q(QTreeWidget);
2236 emit q->itemClicked(item(index), index.column());
2237}
2238
2239void QTreeWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
2240{
2241 Q_Q(QTreeWidget);
2242 emit q->itemDoubleClicked(item(index), index.column());
2243}
2244
2245void QTreeWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
2246{
2247 Q_Q(QTreeWidget);
2248 emit q->itemActivated(item(index), index.column());
2249}
2250
2251void QTreeWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
2252{
2253 Q_Q(QTreeWidget);
2254 emit q->itemEntered(item(index), index.column());
2255}
2256
2257void QTreeWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
2258{
2259 Q_Q(QTreeWidget);
2260 QTreeWidgetItem *indexItem = item(index);
2261 if (indexItem)
2262 emit q->itemChanged(indexItem, index.column());
2263}
2264
2265void QTreeWidgetPrivate::_q_emitItemExpanded(const QModelIndex &index)
2266{
2267 Q_Q(QTreeWidget);
2268 emit q->itemExpanded(item(index));
2269}
2270
2271void QTreeWidgetPrivate::_q_emitItemCollapsed(const QModelIndex &index)
2272{
2273 Q_Q(QTreeWidget);
2274 emit q->itemCollapsed(item(index));
2275}
2276
2277void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
2278 const QModelIndex &previous)
2279{
2280 Q_Q(QTreeWidget);
2281 QTreeWidgetItem *currentItem = item(current);
2282 QTreeWidgetItem *previousItem = item(previous);
2283 emit q->currentItemChanged(currentItem, previousItem);
2284}
2285
2286void QTreeWidgetPrivate::_q_sort()
2287{
2288 if (sortingEnabled) {
2289 int column = header->sortIndicatorSection();
2290 Qt::SortOrder order = header->sortIndicatorOrder();
2291 treeModel()->sort(column, order);
2292 }
2293}
2294
2295void QTreeWidgetPrivate::_q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
2296{
2297 Q_Q(QTreeWidget);
2298 QModelIndexList indices = selected.indexes();
2299 int i;
2300 QTreeModel *m = treeModel();
2301 for (i = 0; i < indices.count(); ++i) {
2302 QTreeWidgetItem *item = m->item(indices.at(i));
2303 item->d->selected = true;
2304 }
2305
2306 indices = deselected.indexes();
2307 for (i = 0; i < indices.count(); ++i) {
2308 QTreeWidgetItem *item = m->item(indices.at(i));
2309 item->d->selected = false;
2310 }
2311
2312 emit q->itemSelectionChanged();
2313}
2314
2315void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
2316 const QModelIndex &bottomRight)
2317{
2318 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
2319 && !treeModel()->sortPendingTimer.isActive()) {
2320 int column = header->sortIndicatorSection();
2321 if (column >= topLeft.column() && column <= bottomRight.column()) {
2322 Qt::SortOrder order = header->sortIndicatorOrder();
2323 treeModel()->ensureSorted(column, order, topLeft.row(),
2324 bottomRight.row(), topLeft.parent());
2325 }
2326 }
2327}
2328
2329/*!
2330 \class QTreeWidget
2331
2332 \brief The QTreeWidget class provides a tree view that uses a predefined
2333 tree model.
2334
2335 \ingroup model-view
2336
2337
2338 The QTreeWidget class is a convenience class that provides a standard
2339 tree widget with a classic item-based interface similar to that used by
2340 the QListView class in Qt 3.
2341 This class is based on Qt's Model/View architecture and uses a default
2342 model to hold items, each of which is a QTreeWidgetItem.
2343
2344 Developers who do not need the flexibility of the Model/View framework
2345 can use this class to create simple hierarchical lists very easily. A more
2346 flexible approach involves combining a QTreeView with a standard item model.
2347 This allows the storage of data to be separated from its representation.
2348
2349 In its simplest form, a tree widget can be constructed in the following way:
2350
2351 \snippet doc/src/snippets/code/src_gui_itemviews_qtreewidget.cpp 0
2352
2353 Before items can be added to the tree widget, the number of columns must
2354 be set with setColumnCount(). This allows each item to have one or more
2355 labels or other decorations. The number of columns in use can be found
2356 with the columnCount() function.
2357
2358 The tree can have a header that contains a section for each column in
2359 the widget. It is easiest to set up the labels for each section by
2360 supplying a list of strings with setHeaderLabels(), but a custom header
2361 can be constructed with a QTreeWidgetItem and inserted into the tree
2362 with the setHeaderItem() function.
2363
2364 The items in the tree can be sorted by column according to a predefined
2365 sort order. If sorting is enabled, the user can sort the items by clicking
2366 on a column header. Sorting can be enabled or disabled by calling
2367 \l{QTreeView::setSortingEnabled()}{setSortingEnabled()}. The
2368 \l{QTreeView::isSortingEnabled()}{isSortingEnabled()} function indicates
2369 whether sorting is enabled.
2370
2371 \table 100%
2372 \row \o \inlineimage windowsxp-treeview.png Screenshot of a Windows XP style tree widget
2373 \o \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree widget
2374 \o \inlineimage plastique-treeview.png Screenshot of a Plastique style tree widget
2375 \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} tree widget.
2376 \o A \l{Macintosh Style Widget Gallery}{Macintosh style} tree widget.
2377 \o A \l{Plastique Style Widget Gallery}{Plastique style} tree widget.
2378 \endtable
2379
2380 \sa QTreeWidgetItem, QTreeWidgetItemIterator, QTreeView,
2381 {Model/View Programming}, {Settings Editor Example}
2382*/
2383
2384/*!
2385 \property QTreeWidget::columnCount
2386 \brief the number of columns displayed in the tree widget
2387
2388 By default, this property has a value of 1.
2389*/
2390
2391/*!
2392 \fn void QTreeWidget::itemActivated(QTreeWidgetItem *item, int column)
2393
2394 This signal is emitted when the user activates an item by single-
2395 or double-clicking (depending on the platform, i.e. on the
2396 QStyle::SH_ItemView_ActivateItemOnSingleClick style hint) or
2397 pressing a special key (e.g., \key Enter).
2398
2399 The specified \a item is the item that was clicked, or 0 if no
2400 item was clicked. The \a column is the item's column that was
2401 clicked, or -1 if no item was clicked.
2402*/
2403
2404/*!
2405 \fn void QTreeWidget::itemPressed(QTreeWidgetItem *item, int column)
2406
2407 This signal is emitted when the user presses a mouse button inside
2408 the widget.
2409
2410 The specified \a item is the item that was clicked, or 0 if no
2411 item was clicked. The \a column is the item's column that was
2412 clicked, or -1 if no item was clicked.
2413*/
2414
2415/*!
2416 \fn void QTreeWidget::itemClicked(QTreeWidgetItem *item, int column)
2417
2418 This signal is emitted when the user clicks inside the widget.
2419
2420 The specified \a item is the item that was clicked. The \a column is the
2421 item's column that was clicked. If no item was clicked, no signal will be
2422 emitted.
2423*/
2424
2425/*!
2426 \fn void QTreeWidget::itemDoubleClicked(QTreeWidgetItem *item, int column)
2427
2428 This signal is emitted when the user double clicks inside the
2429 widget.
2430
2431 The specified \a item is the item that was clicked, or 0 if no
2432 item was clicked. The \a column is the item's column that was
2433 clicked. If no item was double clicked, no signal will be emitted.
2434*/
2435
2436/*!
2437 \fn void QTreeWidget::itemExpanded(QTreeWidgetItem *item)
2438
2439 This signal is emitted when the specified \a item is expanded so that
2440 all of its children are displayed.
2441
2442 \note This signal will not be emitted if an item changes its state when
2443 expandAll() is invoked.
2444
2445 \sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem()
2446*/
2447
2448/*!
2449 \fn void QTreeWidget::itemCollapsed(QTreeWidgetItem *item)
2450
2451 This signal is emitted when the specified \a item is collapsed so that
2452 none of its children are displayed.
2453
2454 \note This signal will not be emitted if an item changes its state when
2455 collapseAll() is invoked.
2456
2457 \sa QTreeWidgetItem::isExpanded(), itemExpanded(), collapseItem()
2458*/
2459
2460/*!
2461 \fn void QTreeWidget::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
2462
2463 This signal is emitted when the current item changes. The current
2464 item is specified by \a current, and this replaces the \a previous
2465 current item.
2466
2467 \sa setCurrentItem()
2468*/
2469
2470/*!
2471 \fn void QTreeWidget::itemSelectionChanged()
2472
2473 This signal is emitted when the selection changes in the tree widget.
2474 The current selection can be found with selectedItems().
2475*/
2476
2477/*!
2478 \fn void QTreeWidget::itemEntered(QTreeWidgetItem *item, int column)
2479
2480 This signal is emitted when the mouse cursor enters an \a item over the
2481 specified \a column.
2482 QTreeWidget mouse tracking needs to be enabled for this feature to work.
2483*/
2484
2485/*!
2486 \fn void QTreeWidget::itemChanged(QTreeWidgetItem *item, int column)
2487
2488 This signal is emitted when the contents of the \a column in the specified
2489 \a item changes.
2490*/
2491
2492/*!
2493 \since 4.3
2494
2495 \fn void QTreeWidget::removeItemWidget(QTreeWidgetItem *item, int column)
2496
2497 Removes the widget set in the given \a item in the given \a column.
2498*/
2499
2500/*!
2501 Constructs a tree widget with the given \a parent.
2502*/
2503QTreeWidget::QTreeWidget(QWidget *parent)
2504 : QTreeView(*new QTreeWidgetPrivate(), parent)
2505{
2506 QTreeView::setModel(new QTreeModel(1, this));
2507 connect(this, SIGNAL(pressed(QModelIndex)),
2508 SLOT(_q_emitItemPressed(QModelIndex)));
2509 connect(this, SIGNAL(clicked(QModelIndex)),
2510 SLOT(_q_emitItemClicked(QModelIndex)));
2511 connect(this, SIGNAL(doubleClicked(QModelIndex)),
2512 SLOT(_q_emitItemDoubleClicked(QModelIndex)));
2513 connect(this, SIGNAL(activated(QModelIndex)),
2514 SLOT(_q_emitItemActivated(QModelIndex)));
2515 connect(this, SIGNAL(entered(QModelIndex)),
2516 SLOT(_q_emitItemEntered(QModelIndex)));
2517 connect(this, SIGNAL(expanded(QModelIndex)),
2518 SLOT(_q_emitItemExpanded(QModelIndex)));
2519 connect(this, SIGNAL(collapsed(QModelIndex)),
2520 SLOT(_q_emitItemCollapsed(QModelIndex)));
2521 connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
2522 this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
2523 connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
2524 this, SLOT(_q_emitItemChanged(QModelIndex)));
2525 connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
2526 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
2527 connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
2528 this, SLOT(_q_sort()));
2529 connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
2530 this, SLOT(_q_selectionChanged(QItemSelection,QItemSelection)));
2531 header()->setClickable(false);
2532}
2533
2534/*!
2535 Destroys the tree widget and all its items.
2536*/
2537
2538QTreeWidget::~QTreeWidget()
2539{
2540}
2541
2542/*
2543 Retuns the number of header columns in the view.
2544
2545 \sa sortColumn(), currentColumn(), topLevelItemCount()
2546*/
2547
2548int QTreeWidget::columnCount() const
2549{
2550 Q_D(const QTreeWidget);
2551 return d->model->columnCount();
2552}
2553
2554/*
2555 Sets the number of header \a columns in the tree widget.
2556*/
2557
2558void QTreeWidget::setColumnCount(int columns)
2559{
2560 Q_D(QTreeWidget);
2561 if (columns < 0)
2562 return;
2563 d->treeModel()->setColumnCount(columns);
2564}
2565
2566/*!
2567 \since 4.2
2568
2569 Returns the tree widget's invisible root item.
2570
2571 The invisible root item provides access to the tree widget's top-level items
2572 through the QTreeWidgetItem API, making it possible to write functions that
2573 can treat top-level items and their children in a uniform way; for example,
2574 recursive functions.
2575*/
2576
2577QTreeWidgetItem *QTreeWidget::invisibleRootItem() const
2578{
2579 Q_D(const QTreeWidget);
2580 return d->treeModel()->rootItem;
2581}
2582
2583/*!
2584 Returns the top level item at the given \a index, or 0 if the item does
2585 not exist.
2586
2587 \sa topLevelItemCount(), insertTopLevelItem()
2588*/
2589
2590QTreeWidgetItem *QTreeWidget::topLevelItem(int index) const
2591{
2592 Q_D(const QTreeWidget);
2593 return d->treeModel()->rootItem->child(index);
2594}
2595
2596/*!
2597 \property QTreeWidget::topLevelItemCount
2598 \brief the number of top-level items
2599
2600 By default, this property has a value of 0.
2601
2602 \sa columnCount(), currentItem()
2603*/
2604
2605int QTreeWidget::topLevelItemCount() const
2606{
2607 Q_D(const QTreeWidget);
2608 return d->treeModel()->rootItem->childCount();
2609}
2610
2611/*!
2612 Inserts the \a item at \a index in the top level in the view.
2613
2614 If the item has already been inserted somewhere else it wont be inserted.
2615
2616 \sa addTopLevelItem(), columnCount()
2617*/
2618
2619void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem *item)
2620{
2621 Q_D(QTreeWidget);
2622 d->treeModel()->rootItem->insertChild(index, item);
2623}
2624
2625/*!
2626 \since 4.1
2627
2628 Appends the \a item as a top-level item in the widget.
2629
2630 \sa insertTopLevelItem()
2631*/
2632void QTreeWidget::addTopLevelItem(QTreeWidgetItem *item)
2633{
2634 insertTopLevelItem(topLevelItemCount(), item);
2635}
2636
2637/*!
2638 Removes the top-level item at the given \a index in the tree and
2639 returns it, otherwise returns 0;
2640
2641 \sa insertTopLevelItem(), topLevelItem(), topLevelItemCount()
2642*/
2643
2644QTreeWidgetItem *QTreeWidget::takeTopLevelItem(int index)
2645{
2646 Q_D(QTreeWidget);
2647 return d->treeModel()->rootItem->takeChild(index);
2648}
2649
2650/*!
2651 \internal
2652*/
2653int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item)
2654{
2655 Q_D(QTreeWidget);
2656 d->treeModel()->executePendingSort();
2657 return d->treeModel()->rootItem->children.indexOf(item);
2658}
2659
2660/*!
2661 Returns the index of the given top-level \a item, or -1 if the item
2662 cannot be found.
2663
2664 \sa sortItems(), topLevelItemCount()
2665 */
2666int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) const
2667{
2668 Q_D(const QTreeWidget);
2669 d->treeModel()->executePendingSort();
2670 return d->treeModel()->rootItem->children.indexOf(item);
2671}
2672
2673/*!
2674 \since 4.1
2675
2676 Inserts the list of \a items at \a index in the top level in the view.
2677
2678 Items that have already been inserted somewhere else wont be inserted.
2679
2680 \sa addTopLevelItems()
2681*/
2682void QTreeWidget::insertTopLevelItems(int index, const QList<QTreeWidgetItem*> &items)
2683{
2684 Q_D(QTreeWidget);
2685 d->treeModel()->rootItem->insertChildren(index, items);
2686}
2687
2688/*!
2689 Appends the list of \a items as a top-level items in the widget.
2690
2691 \sa insertTopLevelItems()
2692*/
2693void QTreeWidget::addTopLevelItems(const QList<QTreeWidgetItem*> &items)
2694{
2695 insertTopLevelItems(topLevelItemCount(), items);
2696}
2697
2698/*!
2699 Returns the item used for the tree widget's header.
2700
2701 \sa setHeaderItem()
2702*/
2703
2704QTreeWidgetItem *QTreeWidget::headerItem() const
2705{
2706 Q_D(const QTreeWidget);
2707 return d->treeModel()->headerItem;
2708}
2709
2710/*!
2711 Sets the header \a item for the tree widget. The label for each column in
2712 the header is supplied by the corresponding label in the item.
2713
2714 The tree widget takes ownership of the item.
2715
2716 \sa headerItem(), setHeaderLabels()
2717*/
2718
2719void QTreeWidget::setHeaderItem(QTreeWidgetItem *item)
2720{
2721 Q_D(QTreeWidget);
2722 if (!item)
2723 return;
2724 item->view = this;
2725
2726 int oldCount = columnCount();
2727 if (oldCount < item->columnCount())
2728 d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount());
2729 else
2730 d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount);
2731 delete d->treeModel()->headerItem;
2732 d->treeModel()->headerItem = item;
2733 if (oldCount < item->columnCount())
2734 d->treeModel()->endInsertColumns();
2735 else
2736 d->treeModel()->endRemoveColumns();
2737 d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount);
2738}
2739
2740
2741/*!
2742 Adds a column in the header for each item in the \a labels list, and sets
2743 the label for each column.
2744
2745 Note that setHeaderLabels() won't remove existing columns.
2746
2747 \sa setHeaderItem(), setHeaderLabel()
2748*/
2749void QTreeWidget::setHeaderLabels(const QStringList &labels)
2750{
2751 Q_D(QTreeWidget);
2752 if (columnCount() < labels.count())
2753 setColumnCount(labels.count());
2754 QTreeWidgetItem *item = d->treeModel()->headerItem;
2755 for (int i = 0; i < labels.count(); ++i)
2756 item->setText(i, labels.at(i));
2757}
2758
2759/*!
2760 \fn void QTreeWidget::setHeaderLabel(const QString &label)
2761 \since 4.2
2762
2763 Same as setHeaderLabels(QStringList(\a label)).
2764*/
2765
2766/*!
2767 Returns the current item in the tree widget.
2768
2769 \sa setCurrentItem(), currentItemChanged()
2770*/
2771QTreeWidgetItem *QTreeWidget::currentItem() const
2772{
2773 Q_D(const QTreeWidget);
2774 return d->item(currentIndex());
2775}
2776
2777/*!
2778 \since 4.1
2779 Returns the current column in the tree widget.
2780
2781 \sa setCurrentItem(), columnCount()
2782*/
2783int QTreeWidget::currentColumn() const
2784{
2785 return currentIndex().column();
2786}
2787
2788/*!
2789 Sets the current \a item in the tree widget.
2790
2791 Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
2792 the item is also be selected.
2793
2794 \sa currentItem(), currentItemChanged()
2795*/
2796void QTreeWidget::setCurrentItem(QTreeWidgetItem *item)
2797{
2798 setCurrentItem(item, 0);
2799}
2800
2801/*!
2802 \since 4.1
2803 Sets the current \a item in the tree widget and the current column to \a column.
2804
2805 \sa currentItem()
2806*/
2807void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column)
2808{
2809 Q_D(QTreeWidget);
2810 setCurrentIndex(d->index(item, column));
2811}
2812
2813/*!
2814 \since 4.4
2815 Sets the current \a item in the tree widget and the current column to \a column,
2816 using the given \a command.
2817
2818 \sa currentItem()
2819*/
2820void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column,
2821 QItemSelectionModel::SelectionFlags command)
2822{
2823 Q_D(QTreeWidget);
2824 d->selectionModel->setCurrentIndex(d->index(item, column), command);
2825}
2826
2827
2828/*!
2829 Returns a pointer to the item at the coordinates \a p.
2830
2831 \sa visualItemRect()
2832*/
2833QTreeWidgetItem *QTreeWidget::itemAt(const QPoint &p) const
2834{
2835 Q_D(const QTreeWidget);
2836 return d->item(indexAt(p));
2837}
2838
2839/*!
2840 \fn QTreeWidgetItem *QTreeWidget::itemAt(int x, int y) const
2841 \overload
2842
2843 Returns a pointer to the item at the coordinates (\a x, \a y).
2844*/
2845
2846/*!
2847 Returns the rectangle on the viewport occupied by the item at \a item.
2848
2849 \sa itemAt()
2850*/
2851QRect QTreeWidget::visualItemRect(const QTreeWidgetItem *item) const
2852{
2853 Q_D(const QTreeWidget);
2854 //the visual rect for an item is across all columns. So we need to determine
2855 //what is the first and last column and get their visual index rects
2856 QModelIndex base = d->index(item);
2857 const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
2858 const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
2859 QModelIndex first = base.sibling(base.row(), header()->logicalIndex(firstVisiblesection));
2860 QModelIndex last = base.sibling(base.row(), header()->logicalIndex(lastVisibleSection));
2861 return visualRect(first) | visualRect(last);
2862}
2863
2864/*!
2865 \since 4.1
2866
2867 Returns the column used to sort the contents of the widget.
2868
2869 \sa sortItems()
2870*/
2871int QTreeWidget::sortColumn() const
2872{
2873 Q_D(const QTreeWidget);
2874 return (d->explicitSortColumn != -1
2875 ? d->explicitSortColumn
2876 : header()->sortIndicatorSection());
2877}
2878
2879/*!
2880 Sorts the items in the widget in the specified \a order by the values in
2881 the given \a column.
2882
2883 \sa sortColumn()
2884*/
2885
2886void QTreeWidget::sortItems(int column, Qt::SortOrder order)
2887{
2888 Q_D(QTreeWidget);
2889 header()->setSortIndicator(column, order);
2890 d->model->sort(column, order);
2891}
2892
2893/*!
2894 \internal
2895
2896 ### Qt 5: remove
2897*/
2898void QTreeWidget::setSortingEnabled(bool enable)
2899{
2900 QTreeView::setSortingEnabled(enable);
2901}
2902
2903/*!
2904 \internal
2905
2906 ### Qt 5: remove
2907*/
2908bool QTreeWidget::isSortingEnabled() const
2909{
2910 return QTreeView::isSortingEnabled();
2911}
2912
2913/*!
2914 Starts editing the \a item in the given \a column if it is editable.
2915*/
2916
2917void QTreeWidget::editItem(QTreeWidgetItem *item, int column)
2918{
2919 Q_D(QTreeWidget);
2920 edit(d->index(item, column));
2921}
2922
2923/*!
2924 Opens a persistent editor for the \a item in the given \a column.
2925
2926 \sa closePersistentEditor()
2927*/
2928
2929void QTreeWidget::openPersistentEditor(QTreeWidgetItem *item, int column)
2930{
2931 Q_D(QTreeWidget);
2932 QAbstractItemView::openPersistentEditor(d->index(item, column));
2933}
2934
2935/*!
2936 Closes the persistent editor for the \a item in the given \a column.
2937
2938 This function has no effect if no persistent editor is open for this
2939 combination of item and column.
2940
2941 \sa openPersistentEditor()
2942*/
2943
2944void QTreeWidget::closePersistentEditor(QTreeWidgetItem *item, int column)
2945{
2946 Q_D(QTreeWidget);
2947 QAbstractItemView::closePersistentEditor(d->index(item, column));
2948}
2949
2950/*!
2951 \since 4.1
2952
2953 Returns the widget displayed in the cell specified by \a item and the given \a column.
2954
2955 \note The tree takes ownership of the widget.
2956
2957*/
2958QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const
2959{
2960 Q_D(const QTreeWidget);
2961 return QAbstractItemView::indexWidget(d->index(item, column));
2962}
2963
2964/*!
2965 \since 4.1
2966
2967 Sets the given \a widget to be displayed in the cell specified by the given
2968 \a item and \a column.
2969
2970 The given \a widget's \l {QWidget::}{autoFillBackground} property must be
2971 set to true, otherwise the widget's background will be transparent, showing
2972 both the model data and the tree widget item.
2973
2974 This function should only be used to display static content in the place of
2975 a tree widget item. If you want to display custom dynamic content or
2976 implement a custom editor widget, use QTreeView and subclass QItemDelegate
2977 instead.
2978
2979 This function cannot be called before the item hierarchy has been set up,
2980 i.e., the QTreeWidgetItem that will hold \a widget must have been added to
2981 the view before \a widget is set.
2982
2983 \note The tree takes ownership of the widget.
2984
2985 \sa {Delegate Classes}
2986*/
2987void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
2988{
2989 Q_D(QTreeWidget);
2990 QAbstractItemView::setIndexWidget(d->index(item, column), widget);
2991}
2992
2993/*!
2994 Returns true if the \a item is selected; otherwise returns false.
2995
2996 \sa itemSelectionChanged()
2997
2998 \obsolete
2999
3000 This function is deprecated. Use \l{QTreeWidgetItem::isSelected()} instead.
3001*/
3002bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const
3003{
3004 if (!item)
3005 return false;
3006 return item->d->selected;
3007}
3008
3009/*!
3010 If \a select is true, the given \a item is selected; otherwise it is
3011 deselected.
3012
3013 \sa itemSelectionChanged()
3014
3015 \obsolete
3016
3017 This function is deprecated. Use \l{QTreeWidgetItem::setSelected()} instead.
3018*/
3019void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select)
3020{
3021 Q_D(QTreeWidget);
3022
3023 if (!item)
3024 return;
3025
3026 selectionModel()->select(d->index(item), (select ? QItemSelectionModel::Select
3027 : QItemSelectionModel::Deselect)
3028 |QItemSelectionModel::Rows);
3029 item->d->selected = select;
3030}
3031
3032/*!
3033 Returns a list of all selected non-hidden items.
3034
3035 \sa itemSelectionChanged()
3036*/
3037QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
3038{
3039 Q_D(const QTreeWidget);
3040 QModelIndexList indexes = selectionModel()->selectedIndexes();
3041 QList<QTreeWidgetItem*> items;
3042 for (int i = 0; i < indexes.count(); ++i) {
3043 QTreeWidgetItem *item = d->item(indexes.at(i));
3044 if (isItemHidden(item) || items.contains(item)) // ### slow, optimize later
3045 continue;
3046 items.append(item);
3047 }
3048 return items;
3049}
3050
3051/*!
3052 Returns a list of items that match the given \a text, using the given \a flags, in the given \a column.
3053*/
3054QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFlags flags, int column) const
3055{
3056 Q_D(const QTreeWidget);
3057 QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()),
3058 Qt::DisplayRole, text, -1, flags);
3059 QList<QTreeWidgetItem*> items;
3060 for (int i = 0; i < indexes.size(); ++i)
3061 items.append(d->item(indexes.at(i)));
3062 return items;
3063}
3064
3065/*!
3066 Returns true if the \a item is explicitly hidden, otherwise returns false.
3067
3068 \obsolete
3069
3070 This function is deprecated. Use \l{QTreeWidgetItem::isHidden()} instead.
3071*/
3072bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
3073{
3074 Q_D(const QTreeWidget);
3075 if (item == d->treeModel()->headerItem)
3076 return header()->isHidden();
3077 if (d->hiddenIndexes.isEmpty())
3078 return false;
3079 QTreeModel::SkipSorting skipSorting(d->treeModel());
3080 return d->isRowHidden(d->index(item));
3081}
3082
3083/*!
3084 Hides the given \a item if \a hide is true; otherwise shows the item.
3085
3086 \sa itemChanged()
3087
3088 \obsolete
3089
3090 This function is deprecated. Use \l{QTreeWidgetItem::setHidden()} instead.
3091*/
3092void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
3093{
3094 Q_D(QTreeWidget);
3095 if (item == d->treeModel()->headerItem) {
3096 header()->setHidden(hide);
3097 } else {
3098 const QModelIndex index = d->index(item);
3099 setRowHidden(index.row(), index.parent(), hide);
3100 }
3101}
3102
3103/*!
3104 Returns true if the given \a item is open; otherwise returns false.
3105
3106 \sa itemExpanded()
3107
3108 \obsolete
3109
3110 This function is deprecated. Use \l{QTreeWidgetItem::isExpanded()} instead.
3111*/
3112bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const
3113{
3114 Q_D(const QTreeWidget);
3115 QTreeModel::SkipSorting skipSorting(d->treeModel());
3116 return isExpanded(d->index(item));
3117}
3118
3119/*!
3120 Sets the item referred to by \a item to either closed or opened,
3121 depending on the value of \a expand.
3122
3123 \sa expandItem(), collapseItem(), itemExpanded()
3124
3125 \obsolete
3126
3127 This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead.
3128*/
3129void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand)
3130{
3131 Q_D(QTreeWidget);
3132 QTreeModel::SkipSorting skipSorting(d->treeModel());
3133 setExpanded(d->index(item), expand);
3134}
3135
3136/*!
3137 \since 4.3
3138
3139 Returns true if the given \a item is set to show only one section over all columns;
3140 otherwise returns false.
3141
3142 \sa setFirstItemColumnSpanned()
3143*/
3144bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const
3145{
3146 Q_D(const QTreeWidget);
3147 if (item == d->treeModel()->headerItem)
3148 return false; // We can't set the header items to spanning
3149 const QModelIndex index = d->index(item);
3150 return isFirstColumnSpanned(index.row(), index.parent());
3151}
3152
3153/*!
3154 \since 4.3
3155
3156 Sets the given \a item to only show one section for all columns if \a span is true;
3157 otherwise the item will show one section per column.
3158
3159 \sa isFirstItemColumnSpanned()
3160*/
3161void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span)
3162{
3163 Q_D(QTreeWidget);
3164 if (item == d->treeModel()->headerItem)
3165 return; // We can't set header items to spanning
3166 const QModelIndex index = d->index(item);
3167 setFirstColumnSpanned(index.row(), index.parent(), span);
3168}
3169
3170/*!
3171 \since 4.3
3172
3173 Returns the item above the given \a item.
3174*/
3175QTreeWidgetItem *QTreeWidget::itemAbove(const QTreeWidgetItem *item) const
3176{
3177 Q_D(const QTreeWidget);
3178 if (item == d->treeModel()->headerItem)
3179 return 0;
3180 const QModelIndex index = d->index(item);
3181 const QModelIndex above = indexAbove(index);
3182 return d->item(above);
3183}
3184
3185/*!
3186 \since 4.3
3187
3188 Returns the item visually below the given \a item.
3189*/
3190QTreeWidgetItem *QTreeWidget::itemBelow(const QTreeWidgetItem *item) const
3191{
3192 Q_D(const QTreeWidget);
3193 if (item == d->treeModel()->headerItem)
3194 return 0;
3195 const QModelIndex index = d->index(item);
3196 const QModelIndex below = indexBelow(index);
3197 return d->item(below);
3198}
3199
3200/*!
3201 \reimp
3202 */
3203void QTreeWidget::setSelectionModel(QItemSelectionModel *selectionModel)
3204{
3205 Q_D(QTreeWidget);
3206 QTreeView::setSelectionModel(selectionModel);
3207 QItemSelection newSelection = selectionModel->selection();
3208 if (!newSelection.isEmpty())
3209 d->_q_selectionChanged(newSelection, QItemSelection());
3210}
3211
3212/*!
3213 Ensures that the \a item is visible, scrolling the view if necessary using
3214 the specified \a hint.
3215
3216 \sa currentItem(), itemAt(), topLevelItem()
3217*/
3218void QTreeWidget::scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint)
3219{
3220 Q_D(QTreeWidget);
3221 QTreeView::scrollTo(d->index(item), hint);
3222}
3223
3224/*!
3225 Expands the \a item. This causes the tree containing the item's children
3226 to be expanded.
3227
3228 \sa collapseItem(), currentItem(), itemAt(), topLevelItem(), itemExpanded()
3229*/
3230void QTreeWidget::expandItem(const QTreeWidgetItem *item)
3231{
3232 Q_D(QTreeWidget);
3233 QTreeModel::SkipSorting skipSorting(d->treeModel());
3234 expand(d->index(item));
3235}
3236
3237/*!
3238 Closes the \a item. This causes the tree containing the item's children
3239 to be collapsed.
3240
3241 \sa expandItem(), currentItem(), itemAt(), topLevelItem()
3242*/
3243void QTreeWidget::collapseItem(const QTreeWidgetItem *item)
3244{
3245 Q_D(QTreeWidget);
3246 QTreeModel::SkipSorting skipSorting(d->treeModel());
3247 collapse(d->index(item));
3248}
3249
3250/*!
3251 Clears the tree widget by removing all of its items and selections.
3252
3253 \bold{Note:} Since each item is removed from the tree widget before being
3254 deleted, the return value of QTreeWidgetItem::treeWidget() will be invalid
3255 when called from an item's destructor.
3256
3257 \sa takeTopLevelItem(), topLevelItemCount(), columnCount()
3258*/
3259void QTreeWidget::clear()
3260{
3261 Q_D(QTreeWidget);
3262 selectionModel()->clear();
3263 d->treeModel()->clear();
3264}
3265
3266/*!
3267 Returns a list of MIME types that can be used to describe a list of
3268 treewidget items.
3269
3270 \sa mimeData()
3271*/
3272QStringList QTreeWidget::mimeTypes() const
3273{
3274 return model()->QAbstractItemModel::mimeTypes();
3275}
3276
3277/*!
3278 Returns an object that contains a serialized description of the specified
3279 \a items. The format used to describe the items is obtained from the
3280 mimeTypes() function.
3281
3282 If the list of items is empty, 0 is returned rather than a serialized
3283 empty list.
3284*/
3285QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const
3286{
3287 Q_D(const QTreeWidget);
3288 if (d->treeModel()->cachedIndexes.isEmpty()) {
3289 QList<QModelIndex> indexes;
3290 for (int i = 0; i < items.count(); ++i) {
3291 QTreeWidgetItem *item = items.at(i);
3292 for (int c = 0; c < item->values.count(); ++c) {
3293 indexes << indexFromItem(item, c);
3294 }
3295 }
3296 return d->model->QAbstractItemModel::mimeData(indexes);
3297 }
3298 return d->treeModel()->internalMimeData();
3299}
3300
3301/*!
3302 Handles the \a data supplied by a drag and drop operation that ended with
3303 the given \a action in the \a index in the given \a parent item.
3304
3305 The default implementation returns true if the drop was
3306 successfully handled by decoding the mime data and inserting it
3307 into the model; otherwise it returns false.
3308
3309 \sa supportedDropActions()
3310*/
3311bool QTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index,
3312 const QMimeData *data, Qt::DropAction action)
3313{
3314 QModelIndex idx;
3315 if (parent) idx = indexFromItem(parent);
3316 return model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx);
3317}
3318
3319/*!
3320 Returns the drop actions supported by this view.
3321
3322 \sa Qt::DropActions
3323*/
3324Qt::DropActions QTreeWidget::supportedDropActions() const
3325{
3326 return model()->QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
3327}
3328
3329/*!
3330 \obsolete
3331 Returns an empty list
3332
3333 \sa mimeData()
3334*/
3335QList<QTreeWidgetItem*> QTreeWidget::items(const QMimeData *data) const
3336{
3337 Q_UNUSED(data);
3338 return QList<QTreeWidgetItem*>();
3339}
3340
3341/*!
3342 Returns the QModelIndex assocated with the given \a item in the given \a column.
3343
3344 \sa itemFromIndex(), topLevelItem()
3345*/
3346QModelIndex QTreeWidget::indexFromItem(QTreeWidgetItem *item, int column) const
3347{
3348 Q_D(const QTreeWidget);
3349 return d->index(item, column);
3350}
3351
3352/*!
3353 Returns a pointer to the QTreeWidgetItem assocated with the given \a index.
3354
3355 \sa indexFromItem()
3356*/
3357QTreeWidgetItem *QTreeWidget::itemFromIndex(const QModelIndex &index) const
3358{
3359 Q_D(const QTreeWidget);
3360 return d->item(index);
3361}
3362
3363#ifndef QT_NO_DRAGANDDROP
3364/*! \reimp */
3365void QTreeWidget::dropEvent(QDropEvent *event) {
3366 Q_D(QTreeWidget);
3367 if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
3368 dragDropMode() == QAbstractItemView::InternalMove)) {
3369 QModelIndex topIndex;
3370 int col = -1;
3371 int row = -1;
3372 if (d->dropOn(event, &row, &col, &topIndex)) {
3373 QList<QModelIndex> idxs = selectedIndexes();
3374 QList<QPersistentModelIndex> indexes;
3375 for (int i = 0; i < idxs.count(); i++)
3376 indexes.append(idxs.at(i));
3377
3378 if (indexes.contains(topIndex))
3379 return;
3380
3381 // When removing items the drop location could shift
3382 QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
3383
3384 // Remove the items
3385 QList<QTreeWidgetItem *> taken;
3386 for (int i = indexes.count() - 1; i >= 0; --i) {
3387 QTreeWidgetItem *parent = itemFromIndex(indexes.at(i));
3388 if (!parent || !parent->parent()) {
3389 taken.append(takeTopLevelItem(indexes.at(i).row()));
3390 } else {
3391 taken.append(parent->parent()->takeChild(indexes.at(i).row()));
3392 }
3393 }
3394
3395 // insert them back in at their new positions
3396 for (int i = 0; i < indexes.count(); ++i) {
3397 // Either at a specific point or appended
3398 if (row == -1) {
3399 if (topIndex.isValid()) {
3400 QTreeWidgetItem *parent = itemFromIndex(topIndex);
3401 parent->insertChild(parent->childCount(), taken.takeFirst());
3402 } else {
3403 insertTopLevelItem(topLevelItemCount(), taken.takeFirst());
3404 }
3405 } else {
3406 int r = dropRow.row() >= 0 ? dropRow.row() : row;
3407 if (topIndex.isValid()) {
3408 QTreeWidgetItem *parent = itemFromIndex(topIndex);
3409 parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst());
3410 } else {
3411 insertTopLevelItem(qMin(r, topLevelItemCount()), taken.takeFirst());
3412 }
3413 }
3414 }
3415
3416 event->accept();
3417 // Don't want QAbstractItemView to delete it because it was "moved" we already did it
3418 event->setDropAction(Qt::CopyAction);
3419 }
3420 }
3421
3422 QTreeView::dropEvent(event);
3423}
3424#endif
3425
3426/*!
3427 \reimp
3428*/
3429
3430void QTreeWidget::setModel(QAbstractItemModel * /*model*/)
3431{
3432 Q_ASSERT(!"QTreeWidget::setModel() - Changing the model of the QTreeWidget is not allowed.");
3433}
3434
3435/*!
3436 \reimp
3437*/
3438bool QTreeWidget::event(QEvent *e)
3439{
3440 Q_D(QTreeWidget);
3441 if (e->type() == QEvent::Polish)
3442 d->treeModel()->executePendingSort();
3443 return QTreeView::event(e);
3444}
3445
3446QT_END_NAMESPACE
3447
3448#include "moc_qtreewidget.cpp"
3449
3450#endif // QT_NO_TREEWIDGET
Note: See TracBrowser for help on using the repository browser.