|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 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 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
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 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
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 |
|
54 QT_BEGIN_NAMESPACE |
|
55 |
|
56 // workaround for VC++ 6.0 linker bug (?) |
|
57 typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&); |
|
58 |
|
59 class QTreeModelLessThan |
|
60 { |
|
61 public: |
|
62 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const |
|
63 { return *i1 < *i2; } |
|
64 }; |
|
65 |
|
66 class QTreeModelGreaterThan |
|
67 { |
|
68 public: |
|
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 |
|
115 QTreeModel::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 |
|
130 QTreeModel::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 |
|
145 QTreeModel::~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 |
|
159 void 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 |
|
179 void 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 |
|
215 QTreeWidgetItem *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 |
|
229 QModelIndex 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 |
|
260 QModelIndex 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 |
|
287 QModelIndex 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 |
|
308 int 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 |
|
327 int QTreeModel::columnCount(const QModelIndex &index) const |
|
328 { |
|
329 Q_UNUSED(index); |
|
330 if (!headerItem) |
|
331 return 0; |
|
332 return headerItem->columnCount(); |
|
333 } |
|
334 |
|
335 bool 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 |
|
362 QVariant 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 |
|
382 bool 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 |
|
394 QMap<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 */ |
|
423 bool 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 */ |
|
449 bool 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 */ |
|
486 bool 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 |
|
517 QVariant 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 |
|
539 bool 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 |
|
556 Qt::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 |
|
572 void 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 */ |
|
587 void 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 |
|
680 bool 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 |
|
695 bool 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 */ |
|
704 QList<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 |
|
714 QStringList QTreeModel::mimeTypes() const |
|
715 { |
|
716 return view()->mimeTypes(); |
|
717 } |
|
718 |
|
719 QMimeData *QTreeModel::internalMimeData() const |
|
720 { |
|
721 return QAbstractItemModel::mimeData(cachedIndexes); |
|
722 } |
|
723 |
|
724 QMimeData *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 |
|
740 bool 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 |
|
748 Qt::DropActions QTreeModel::supportedDropActions() const |
|
749 { |
|
750 return view()->supportedDropActions(); |
|
751 } |
|
752 |
|
753 void 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 |
|
761 bool 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 |
|
773 void 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 |
|
799 void QTreeModel::beginInsertItems(QTreeWidgetItem *parent, int row, int count) |
|
800 { |
|
801 QModelIndex par = index(parent, 0); |
|
802 beginInsertRows(par, row, row + count - 1); |
|
803 } |
|
804 |
|
805 void QTreeModel::endInsertItems() |
|
806 { |
|
807 endInsertRows(); |
|
808 } |
|
809 |
|
810 void 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 |
|
826 void QTreeModel::endRemoveItems() |
|
827 { |
|
828 endRemoveRows(); |
|
829 } |
|
830 |
|
831 void 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 |
|
870 void 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 */ |
|
1306 QTreeWidgetItem::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 */ |
|
1325 QTreeWidgetItem::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 |
|
1346 QTreeWidgetItem::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 |
|
1371 QTreeWidgetItem::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 */ |
|
1396 QTreeWidgetItem::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 */ |
|
1419 QTreeWidgetItem::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 */ |
|
1437 QTreeWidgetItem::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 */ |
|
1459 QTreeWidgetItem::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 |
|
1477 QTreeWidgetItem::~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 */ |
|
1531 QTreeWidgetItem *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 */ |
|
1574 void 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->viewport()->update( view->d_func()->itemDecorationRect(view->d_func()->index(this))); |
|
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 */ |
|
1592 QTreeWidgetItem::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 */ |
|
1605 void 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 |
|
1639 void 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 */ |
|
1676 Qt::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 */ |
|
1688 void 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 */ |
|
1763 QVariant 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 |
|
1792 bool 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 */ |
|
1807 void 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 */ |
|
1833 void 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 */ |
|
1849 QTreeWidgetItem::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 */ |
|
1865 QTreeWidgetItem &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 */ |
|
1879 void 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 */ |
|
1892 void 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 */ |
|
1935 void 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 */ |
|
1943 QTreeWidgetItem *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 */ |
|
1982 void 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 */ |
|
1994 void 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 */ |
|
2043 QList<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 |
|
2077 void 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 */ |
|
2100 void 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 */ |
|
2123 QVariant 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 */ |
|
2170 void QTreeWidgetItem::emitDataChanged() |
|
2171 { |
|
2172 itemChanged(); |
|
2173 } |
|
2174 |
|
2175 /*! |
|
2176 \internal |
|
2177 */ |
|
2178 void QTreeWidgetItem::itemChanged() |
|
2179 { |
|
2180 if (QTreeModel *model = (view ? qobject_cast<QTreeModel*>(view->model()) : 0)) |
|
2181 model->itemChanged(this); |
|
2182 } |
|
2183 |
|
2184 /*! |
|
2185 \internal |
|
2186 */ |
|
2187 void 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 */ |
|
2204 QDataStream &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 */ |
|
2219 QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item) |
|
2220 { |
|
2221 item.read(in); |
|
2222 return in; |
|
2223 } |
|
2224 #endif // QT_NO_DATASTREAM |
|
2225 |
|
2226 |
|
2227 void QTreeWidgetPrivate::_q_emitItemPressed(const QModelIndex &index) |
|
2228 { |
|
2229 Q_Q(QTreeWidget); |
|
2230 emit q->itemPressed(item(index), index.column()); |
|
2231 } |
|
2232 |
|
2233 void QTreeWidgetPrivate::_q_emitItemClicked(const QModelIndex &index) |
|
2234 { |
|
2235 Q_Q(QTreeWidget); |
|
2236 emit q->itemClicked(item(index), index.column()); |
|
2237 } |
|
2238 |
|
2239 void QTreeWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index) |
|
2240 { |
|
2241 Q_Q(QTreeWidget); |
|
2242 emit q->itemDoubleClicked(item(index), index.column()); |
|
2243 } |
|
2244 |
|
2245 void QTreeWidgetPrivate::_q_emitItemActivated(const QModelIndex &index) |
|
2246 { |
|
2247 Q_Q(QTreeWidget); |
|
2248 emit q->itemActivated(item(index), index.column()); |
|
2249 } |
|
2250 |
|
2251 void QTreeWidgetPrivate::_q_emitItemEntered(const QModelIndex &index) |
|
2252 { |
|
2253 Q_Q(QTreeWidget); |
|
2254 emit q->itemEntered(item(index), index.column()); |
|
2255 } |
|
2256 |
|
2257 void 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 |
|
2265 void QTreeWidgetPrivate::_q_emitItemExpanded(const QModelIndex &index) |
|
2266 { |
|
2267 Q_Q(QTreeWidget); |
|
2268 emit q->itemExpanded(item(index)); |
|
2269 } |
|
2270 |
|
2271 void QTreeWidgetPrivate::_q_emitItemCollapsed(const QModelIndex &index) |
|
2272 { |
|
2273 Q_Q(QTreeWidget); |
|
2274 emit q->itemCollapsed(item(index)); |
|
2275 } |
|
2276 |
|
2277 void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, |
|
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 |
|
2286 void 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 |
|
2295 void 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 |
|
2315 void 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 */ |
|
2503 QTreeWidget::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 |
|
2538 QTreeWidget::~QTreeWidget() |
|
2539 { |
|
2540 } |
|
2541 |
|
2542 /* |
|
2543 Retuns the number of header columns in the view. |
|
2544 |
|
2545 \sa sortColumn(), currentColumn(), topLevelItemCount() |
|
2546 */ |
|
2547 |
|
2548 int 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 |
|
2558 void 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 |
|
2577 QTreeWidgetItem *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 |
|
2590 QTreeWidgetItem *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 |
|
2605 int 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 |
|
2619 void 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 */ |
|
2632 void 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 |
|
2644 QTreeWidgetItem *QTreeWidget::takeTopLevelItem(int index) |
|
2645 { |
|
2646 Q_D(QTreeWidget); |
|
2647 return d->treeModel()->rootItem->takeChild(index); |
|
2648 } |
|
2649 |
|
2650 /*! |
|
2651 \internal |
|
2652 */ |
|
2653 int 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 */ |
|
2666 int 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 */ |
|
2682 void 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 */ |
|
2693 void 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 |
|
2704 QTreeWidgetItem *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 |
|
2719 void 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 */ |
|
2749 void 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 */ |
|
2771 QTreeWidgetItem *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 */ |
|
2783 int 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 */ |
|
2796 void 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 */ |
|
2807 void 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 */ |
|
2820 void 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 */ |
|
2833 QTreeWidgetItem *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 */ |
|
2851 QRect QTreeWidget::visualItemRect(const QTreeWidgetItem *item) const |
|
2852 { |
|
2853 Q_D(const QTreeWidget); |
|
2854 return visualRect(d->index(item)); |
|
2855 } |
|
2856 |
|
2857 /*! |
|
2858 \since 4.1 |
|
2859 |
|
2860 Returns the column used to sort the contents of the widget. |
|
2861 |
|
2862 \sa sortItems() |
|
2863 */ |
|
2864 int QTreeWidget::sortColumn() const |
|
2865 { |
|
2866 Q_D(const QTreeWidget); |
|
2867 return (d->explicitSortColumn != -1 |
|
2868 ? d->explicitSortColumn |
|
2869 : header()->sortIndicatorSection()); |
|
2870 } |
|
2871 |
|
2872 /*! |
|
2873 Sorts the items in the widget in the specified \a order by the values in |
|
2874 the given \a column. |
|
2875 |
|
2876 \sa sortColumn() |
|
2877 */ |
|
2878 |
|
2879 void QTreeWidget::sortItems(int column, Qt::SortOrder order) |
|
2880 { |
|
2881 Q_D(QTreeWidget); |
|
2882 header()->setSortIndicator(column, order); |
|
2883 d->model->sort(column, order); |
|
2884 } |
|
2885 |
|
2886 /*! |
|
2887 \internal |
|
2888 |
|
2889 ### Qt 5: remove |
|
2890 */ |
|
2891 void QTreeWidget::setSortingEnabled(bool enable) |
|
2892 { |
|
2893 QTreeView::setSortingEnabled(enable); |
|
2894 } |
|
2895 |
|
2896 /*! |
|
2897 \internal |
|
2898 |
|
2899 ### Qt 5: remove |
|
2900 */ |
|
2901 bool QTreeWidget::isSortingEnabled() const |
|
2902 { |
|
2903 return QTreeView::isSortingEnabled(); |
|
2904 } |
|
2905 |
|
2906 /*! |
|
2907 Starts editing the \a item in the given \a column if it is editable. |
|
2908 */ |
|
2909 |
|
2910 void QTreeWidget::editItem(QTreeWidgetItem *item, int column) |
|
2911 { |
|
2912 Q_D(QTreeWidget); |
|
2913 edit(d->index(item, column)); |
|
2914 } |
|
2915 |
|
2916 /*! |
|
2917 Opens a persistent editor for the \a item in the given \a column. |
|
2918 |
|
2919 \sa closePersistentEditor() |
|
2920 */ |
|
2921 |
|
2922 void QTreeWidget::openPersistentEditor(QTreeWidgetItem *item, int column) |
|
2923 { |
|
2924 Q_D(QTreeWidget); |
|
2925 QAbstractItemView::openPersistentEditor(d->index(item, column)); |
|
2926 } |
|
2927 |
|
2928 /*! |
|
2929 Closes the persistent editor for the \a item in the given \a column. |
|
2930 |
|
2931 This function has no effect if no persistent editor is open for this |
|
2932 combination of item and column. |
|
2933 |
|
2934 \sa openPersistentEditor() |
|
2935 */ |
|
2936 |
|
2937 void QTreeWidget::closePersistentEditor(QTreeWidgetItem *item, int column) |
|
2938 { |
|
2939 Q_D(QTreeWidget); |
|
2940 QAbstractItemView::closePersistentEditor(d->index(item, column)); |
|
2941 } |
|
2942 |
|
2943 /*! |
|
2944 \since 4.1 |
|
2945 |
|
2946 Returns the widget displayed in the cell specified by \a item and the given \a column. |
|
2947 |
|
2948 \note The tree takes ownership of the widget. |
|
2949 |
|
2950 */ |
|
2951 QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const |
|
2952 { |
|
2953 Q_D(const QTreeWidget); |
|
2954 return QAbstractItemView::indexWidget(d->index(item, column)); |
|
2955 } |
|
2956 |
|
2957 /*! |
|
2958 \since 4.1 |
|
2959 |
|
2960 Sets the given \a widget to be displayed in the cell specified by the given |
|
2961 \a item and \a column. |
|
2962 |
|
2963 The given \a widget's \l {QWidget::}{autoFillBackground} property must be |
|
2964 set to true, otherwise the widget's background will be transparent, showing |
|
2965 both the model data and the tree widget item. |
|
2966 |
|
2967 This function should only be used to display static content in the place of |
|
2968 a tree widget item. If you want to display custom dynamic content or |
|
2969 implement a custom editor widget, use QTreeView and subclass QItemDelegate |
|
2970 instead. |
|
2971 |
|
2972 This function cannot be called before the item hierarchy has been set up, |
|
2973 i.e., the QTreeWidgetItem that will hold \a widget must have been added to |
|
2974 the view before \a widget is set. |
|
2975 |
|
2976 \note The tree takes ownership of the widget. |
|
2977 |
|
2978 \sa {Delegate Classes} |
|
2979 */ |
|
2980 void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget) |
|
2981 { |
|
2982 Q_D(QTreeWidget); |
|
2983 QAbstractItemView::setIndexWidget(d->index(item, column), widget); |
|
2984 } |
|
2985 |
|
2986 /*! |
|
2987 Returns true if the \a item is selected; otherwise returns false. |
|
2988 |
|
2989 \sa itemSelectionChanged() |
|
2990 |
|
2991 \obsolete |
|
2992 |
|
2993 This function is deprecated. Use \l{QTreeWidgetItem::isSelected()} instead. |
|
2994 */ |
|
2995 bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const |
|
2996 { |
|
2997 if (!item) |
|
2998 return false; |
|
2999 return item->d->selected; |
|
3000 } |
|
3001 |
|
3002 /*! |
|
3003 If \a select is true, the given \a item is selected; otherwise it is |
|
3004 deselected. |
|
3005 |
|
3006 \sa itemSelectionChanged() |
|
3007 |
|
3008 \obsolete |
|
3009 |
|
3010 This function is deprecated. Use \l{QTreeWidgetItem::setSelected()} instead. |
|
3011 */ |
|
3012 void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select) |
|
3013 { |
|
3014 Q_D(QTreeWidget); |
|
3015 |
|
3016 if (!item) |
|
3017 return; |
|
3018 |
|
3019 selectionModel()->select(d->index(item), (select ? QItemSelectionModel::Select |
|
3020 : QItemSelectionModel::Deselect) |
|
3021 |QItemSelectionModel::Rows); |
|
3022 item->d->selected = select; |
|
3023 } |
|
3024 |
|
3025 /*! |
|
3026 Returns a list of all selected non-hidden items. |
|
3027 |
|
3028 \sa itemSelectionChanged() |
|
3029 */ |
|
3030 QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const |
|
3031 { |
|
3032 Q_D(const QTreeWidget); |
|
3033 QModelIndexList indexes = selectionModel()->selectedIndexes(); |
|
3034 QList<QTreeWidgetItem*> items; |
|
3035 for (int i = 0; i < indexes.count(); ++i) { |
|
3036 QTreeWidgetItem *item = d->item(indexes.at(i)); |
|
3037 if (isItemHidden(item) || items.contains(item)) // ### slow, optimize later |
|
3038 continue; |
|
3039 items.append(item); |
|
3040 } |
|
3041 return items; |
|
3042 } |
|
3043 |
|
3044 /*! |
|
3045 Returns a list of items that match the given \a text, using the given \a flags, in the given \a column. |
|
3046 */ |
|
3047 QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFlags flags, int column) const |
|
3048 { |
|
3049 Q_D(const QTreeWidget); |
|
3050 QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()), |
|
3051 Qt::DisplayRole, text, -1, flags); |
|
3052 QList<QTreeWidgetItem*> items; |
|
3053 for (int i = 0; i < indexes.size(); ++i) |
|
3054 items.append(d->item(indexes.at(i))); |
|
3055 return items; |
|
3056 } |
|
3057 |
|
3058 /*! |
|
3059 Returns true if the \a item is explicitly hidden, otherwise returns false. |
|
3060 |
|
3061 \obsolete |
|
3062 |
|
3063 This function is deprecated. Use \l{QTreeWidgetItem::isHidden()} instead. |
|
3064 */ |
|
3065 bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const |
|
3066 { |
|
3067 Q_D(const QTreeWidget); |
|
3068 if (item == d->treeModel()->headerItem) |
|
3069 return header()->isHidden(); |
|
3070 if (d->hiddenIndexes.isEmpty()) |
|
3071 return false; |
|
3072 QTreeModel::SkipSorting skipSorting(d->treeModel()); |
|
3073 return d->isRowHidden(d->index(item)); |
|
3074 } |
|
3075 |
|
3076 /*! |
|
3077 Hides the given \a item if \a hide is true; otherwise shows the item. |
|
3078 |
|
3079 \sa itemChanged() |
|
3080 |
|
3081 \obsolete |
|
3082 |
|
3083 This function is deprecated. Use \l{QTreeWidgetItem::setHidden()} instead. |
|
3084 */ |
|
3085 void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide) |
|
3086 { |
|
3087 Q_D(QTreeWidget); |
|
3088 if (item == d->treeModel()->headerItem) { |
|
3089 header()->setHidden(hide); |
|
3090 } else { |
|
3091 const QModelIndex index = d->index(item); |
|
3092 setRowHidden(index.row(), index.parent(), hide); |
|
3093 } |
|
3094 } |
|
3095 |
|
3096 /*! |
|
3097 Returns true if the given \a item is open; otherwise returns false. |
|
3098 |
|
3099 \sa itemExpanded() |
|
3100 |
|
3101 \obsolete |
|
3102 |
|
3103 This function is deprecated. Use \l{QTreeWidgetItem::isExpanded()} instead. |
|
3104 */ |
|
3105 bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const |
|
3106 { |
|
3107 Q_D(const QTreeWidget); |
|
3108 QTreeModel::SkipSorting skipSorting(d->treeModel()); |
|
3109 return isExpanded(d->index(item)); |
|
3110 } |
|
3111 |
|
3112 /*! |
|
3113 Sets the item referred to by \a item to either closed or opened, |
|
3114 depending on the value of \a expand. |
|
3115 |
|
3116 \sa expandItem(), collapseItem(), itemExpanded() |
|
3117 |
|
3118 \obsolete |
|
3119 |
|
3120 This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead. |
|
3121 */ |
|
3122 void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) |
|
3123 { |
|
3124 Q_D(QTreeWidget); |
|
3125 QTreeModel::SkipSorting skipSorting(d->treeModel()); |
|
3126 setExpanded(d->index(item), expand); |
|
3127 } |
|
3128 |
|
3129 /*! |
|
3130 \since 4.3 |
|
3131 |
|
3132 Returns true if the given \a item is set to show only one section over all columns; |
|
3133 otherwise returns false. |
|
3134 |
|
3135 \sa setFirstItemColumnSpanned() |
|
3136 */ |
|
3137 bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const |
|
3138 { |
|
3139 Q_D(const QTreeWidget); |
|
3140 if (item == d->treeModel()->headerItem) |
|
3141 return false; // We can't set the header items to spanning |
|
3142 const QModelIndex index = d->index(item); |
|
3143 return isFirstColumnSpanned(index.row(), index.parent()); |
|
3144 } |
|
3145 |
|
3146 /*! |
|
3147 \since 4.3 |
|
3148 |
|
3149 Sets the given \a item to only show one section for all columns if \a span is true; |
|
3150 otherwise the item will show one section per column. |
|
3151 |
|
3152 \sa isFirstItemColumnSpanned() |
|
3153 */ |
|
3154 void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span) |
|
3155 { |
|
3156 Q_D(QTreeWidget); |
|
3157 if (item == d->treeModel()->headerItem) |
|
3158 return; // We can't set header items to spanning |
|
3159 const QModelIndex index = d->index(item); |
|
3160 setFirstColumnSpanned(index.row(), index.parent(), span); |
|
3161 } |
|
3162 |
|
3163 /*! |
|
3164 \since 4.3 |
|
3165 |
|
3166 Returns the item above the given \a item. |
|
3167 */ |
|
3168 QTreeWidgetItem *QTreeWidget::itemAbove(const QTreeWidgetItem *item) const |
|
3169 { |
|
3170 Q_D(const QTreeWidget); |
|
3171 if (item == d->treeModel()->headerItem) |
|
3172 return 0; |
|
3173 const QModelIndex index = d->index(item); |
|
3174 const QModelIndex above = indexAbove(index); |
|
3175 return d->item(above); |
|
3176 } |
|
3177 |
|
3178 /*! |
|
3179 \since 4.3 |
|
3180 |
|
3181 Returns the item visually below the given \a item. |
|
3182 */ |
|
3183 QTreeWidgetItem *QTreeWidget::itemBelow(const QTreeWidgetItem *item) const |
|
3184 { |
|
3185 Q_D(const QTreeWidget); |
|
3186 if (item == d->treeModel()->headerItem) |
|
3187 return 0; |
|
3188 const QModelIndex index = d->index(item); |
|
3189 const QModelIndex below = indexBelow(index); |
|
3190 return d->item(below); |
|
3191 } |
|
3192 |
|
3193 /*! |
|
3194 \reimp |
|
3195 */ |
|
3196 void QTreeWidget::setSelectionModel(QItemSelectionModel *selectionModel) |
|
3197 { |
|
3198 Q_D(QTreeWidget); |
|
3199 QTreeView::setSelectionModel(selectionModel); |
|
3200 QItemSelection newSelection = selectionModel->selection(); |
|
3201 if (!newSelection.isEmpty()) |
|
3202 d->_q_selectionChanged(newSelection, QItemSelection()); |
|
3203 } |
|
3204 |
|
3205 /*! |
|
3206 Ensures that the \a item is visible, scrolling the view if necessary using |
|
3207 the specified \a hint. |
|
3208 |
|
3209 \sa currentItem(), itemAt(), topLevelItem() |
|
3210 */ |
|
3211 void QTreeWidget::scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint) |
|
3212 { |
|
3213 Q_D(QTreeWidget); |
|
3214 QTreeView::scrollTo(d->index(item), hint); |
|
3215 } |
|
3216 |
|
3217 /*! |
|
3218 Expands the \a item. This causes the tree containing the item's children |
|
3219 to be expanded. |
|
3220 |
|
3221 \sa collapseItem(), currentItem(), itemAt(), topLevelItem(), itemExpanded() |
|
3222 */ |
|
3223 void QTreeWidget::expandItem(const QTreeWidgetItem *item) |
|
3224 { |
|
3225 Q_D(QTreeWidget); |
|
3226 QTreeModel::SkipSorting skipSorting(d->treeModel()); |
|
3227 expand(d->index(item)); |
|
3228 } |
|
3229 |
|
3230 /*! |
|
3231 Closes the \a item. This causes the tree containing the item's children |
|
3232 to be collapsed. |
|
3233 |
|
3234 \sa expandItem(), currentItem(), itemAt(), topLevelItem() |
|
3235 */ |
|
3236 void QTreeWidget::collapseItem(const QTreeWidgetItem *item) |
|
3237 { |
|
3238 Q_D(QTreeWidget); |
|
3239 QTreeModel::SkipSorting skipSorting(d->treeModel()); |
|
3240 collapse(d->index(item)); |
|
3241 } |
|
3242 |
|
3243 /*! |
|
3244 Clears the tree widget by removing all of its items and selections. |
|
3245 |
|
3246 \bold{Note:} Since each item is removed from the tree widget before being |
|
3247 deleted, the return value of QTreeWidgetItem::treeWidget() will be invalid |
|
3248 when called from an item's destructor. |
|
3249 |
|
3250 \sa takeTopLevelItem(), topLevelItemCount(), columnCount() |
|
3251 */ |
|
3252 void QTreeWidget::clear() |
|
3253 { |
|
3254 Q_D(QTreeWidget); |
|
3255 selectionModel()->clear(); |
|
3256 d->treeModel()->clear(); |
|
3257 } |
|
3258 |
|
3259 /*! |
|
3260 Returns a list of MIME types that can be used to describe a list of |
|
3261 treewidget items. |
|
3262 |
|
3263 \sa mimeData() |
|
3264 */ |
|
3265 QStringList QTreeWidget::mimeTypes() const |
|
3266 { |
|
3267 return model()->QAbstractItemModel::mimeTypes(); |
|
3268 } |
|
3269 |
|
3270 /*! |
|
3271 Returns an object that contains a serialized description of the specified |
|
3272 \a items. The format used to describe the items is obtained from the |
|
3273 mimeTypes() function. |
|
3274 |
|
3275 If the list of items is empty, 0 is returned rather than a serialized |
|
3276 empty list. |
|
3277 */ |
|
3278 QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const |
|
3279 { |
|
3280 Q_D(const QTreeWidget); |
|
3281 if (d->treeModel()->cachedIndexes.isEmpty()) { |
|
3282 QList<QModelIndex> indexes; |
|
3283 for (int i = 0; i < items.count(); ++i) { |
|
3284 QTreeWidgetItem *item = items.at(i); |
|
3285 for (int c = 0; c < item->values.count(); ++c) { |
|
3286 indexes << indexFromItem(item, c); |
|
3287 } |
|
3288 } |
|
3289 return d->model->QAbstractItemModel::mimeData(indexes); |
|
3290 } |
|
3291 return d->treeModel()->internalMimeData(); |
|
3292 } |
|
3293 |
|
3294 /*! |
|
3295 Handles the \a data supplied by a drag and drop operation that ended with |
|
3296 the given \a action in the \a index in the given \a parent item. |
|
3297 |
|
3298 The default implementation returns true if the drop was |
|
3299 successfully handled by decoding the mime data and inserting it |
|
3300 into the model; otherwise it returns false. |
|
3301 |
|
3302 \sa supportedDropActions() |
|
3303 */ |
|
3304 bool QTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index, |
|
3305 const QMimeData *data, Qt::DropAction action) |
|
3306 { |
|
3307 QModelIndex idx; |
|
3308 if (parent) idx = indexFromItem(parent); |
|
3309 return model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx); |
|
3310 } |
|
3311 |
|
3312 /*! |
|
3313 Returns the drop actions supported by this view. |
|
3314 |
|
3315 \sa Qt::DropActions |
|
3316 */ |
|
3317 Qt::DropActions QTreeWidget::supportedDropActions() const |
|
3318 { |
|
3319 return model()->QAbstractItemModel::supportedDropActions() | Qt::MoveAction; |
|
3320 } |
|
3321 |
|
3322 /*! |
|
3323 \obsolete |
|
3324 Returns an empty list |
|
3325 |
|
3326 \sa mimeData() |
|
3327 */ |
|
3328 QList<QTreeWidgetItem*> QTreeWidget::items(const QMimeData *data) const |
|
3329 { |
|
3330 Q_UNUSED(data); |
|
3331 return QList<QTreeWidgetItem*>(); |
|
3332 } |
|
3333 |
|
3334 /*! |
|
3335 Returns the QModelIndex assocated with the given \a item in the given \a column. |
|
3336 |
|
3337 \sa itemFromIndex(), topLevelItem() |
|
3338 */ |
|
3339 QModelIndex QTreeWidget::indexFromItem(QTreeWidgetItem *item, int column) const |
|
3340 { |
|
3341 Q_D(const QTreeWidget); |
|
3342 return d->index(item, column); |
|
3343 } |
|
3344 |
|
3345 /*! |
|
3346 Returns a pointer to the QTreeWidgetItem assocated with the given \a index. |
|
3347 |
|
3348 \sa indexFromItem() |
|
3349 */ |
|
3350 QTreeWidgetItem *QTreeWidget::itemFromIndex(const QModelIndex &index) const |
|
3351 { |
|
3352 Q_D(const QTreeWidget); |
|
3353 return d->item(index); |
|
3354 } |
|
3355 |
|
3356 #ifndef QT_NO_DRAGANDDROP |
|
3357 /*! \reimp */ |
|
3358 void QTreeWidget::dropEvent(QDropEvent *event) { |
|
3359 Q_D(QTreeWidget); |
|
3360 if (event->source() == this && (event->dropAction() == Qt::MoveAction || |
|
3361 dragDropMode() == QAbstractItemView::InternalMove)) { |
|
3362 QModelIndex topIndex; |
|
3363 int col = -1; |
|
3364 int row = -1; |
|
3365 if (d->dropOn(event, &row, &col, &topIndex)) { |
|
3366 QList<QModelIndex> idxs = selectedIndexes(); |
|
3367 QList<QPersistentModelIndex> indexes; |
|
3368 for (int i = 0; i < idxs.count(); i++) |
|
3369 indexes.append(idxs.at(i)); |
|
3370 |
|
3371 if (indexes.contains(topIndex)) |
|
3372 return; |
|
3373 |
|
3374 // When removing items the drop location could shift |
|
3375 QPersistentModelIndex dropRow = model()->index(row, col, topIndex); |
|
3376 |
|
3377 // Remove the items |
|
3378 QList<QTreeWidgetItem *> taken; |
|
3379 for (int i = indexes.count() - 1; i >= 0; --i) { |
|
3380 QTreeWidgetItem *parent = itemFromIndex(indexes.at(i)); |
|
3381 if (!parent || !parent->parent()) { |
|
3382 taken.append(takeTopLevelItem(indexes.at(i).row())); |
|
3383 } else { |
|
3384 taken.append(parent->parent()->takeChild(indexes.at(i).row())); |
|
3385 } |
|
3386 } |
|
3387 |
|
3388 // insert them back in at their new positions |
|
3389 for (int i = 0; i < indexes.count(); ++i) { |
|
3390 // Either at a specific point or appended |
|
3391 if (row == -1) { |
|
3392 if (topIndex.isValid()) { |
|
3393 QTreeWidgetItem *parent = itemFromIndex(topIndex); |
|
3394 parent->insertChild(parent->childCount(), taken.takeFirst()); |
|
3395 } else { |
|
3396 insertTopLevelItem(topLevelItemCount(), taken.takeFirst()); |
|
3397 } |
|
3398 } else { |
|
3399 int r = dropRow.row() >= 0 ? dropRow.row() : row; |
|
3400 if (topIndex.isValid()) { |
|
3401 QTreeWidgetItem *parent = itemFromIndex(topIndex); |
|
3402 parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst()); |
|
3403 } else { |
|
3404 insertTopLevelItem(qMin(r, topLevelItemCount()), taken.takeFirst()); |
|
3405 } |
|
3406 } |
|
3407 } |
|
3408 |
|
3409 event->accept(); |
|
3410 // Don't want QAbstractItemView to delete it because it was "moved" we already did it |
|
3411 event->setDropAction(Qt::CopyAction); |
|
3412 } |
|
3413 } |
|
3414 |
|
3415 QTreeView::dropEvent(event); |
|
3416 } |
|
3417 #endif |
|
3418 |
|
3419 /*! |
|
3420 \reimp |
|
3421 */ |
|
3422 |
|
3423 void QTreeWidget::setModel(QAbstractItemModel * /*model*/) |
|
3424 { |
|
3425 Q_ASSERT(!"QTreeWidget::setModel() - Changing the model of the QTreeWidget is not allowed."); |
|
3426 } |
|
3427 |
|
3428 /*! |
|
3429 \reimp |
|
3430 */ |
|
3431 bool QTreeWidget::event(QEvent *e) |
|
3432 { |
|
3433 Q_D(QTreeWidget); |
|
3434 if (e->type() == QEvent::Polish) |
|
3435 d->treeModel()->executePendingSort(); |
|
3436 return QTreeView::event(e); |
|
3437 } |
|
3438 |
|
3439 QT_END_NAMESPACE |
|
3440 |
|
3441 #include "moc_qtreewidget.cpp" |
|
3442 |
|
3443 #endif // QT_NO_TREEWIDGET |