qtreeview.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/itemviews/qtreeview.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39#include "qtreeview.h"-
40-
41#ifndef QT_NO_TREEVIEW-
42#include <qheaderview.h>-
43#include <qitemdelegate.h>-
44#include <qapplication.h>-
45#include <qscrollbar.h>-
46#include <qpainter.h>-
47#include <qstack.h>-
48#include <qstyle.h>-
49#include <qstyleoption.h>-
50#include <qevent.h>-
51#include <qpen.h>-
52#include <qdebug.h>-
53#include <QMetaMethod>-
54#include <private/qscrollbar_p.h>-
55#ifndef QT_NO_ACCESSIBILITY-
56#include <qaccessible.h>-
57#endif-
58-
59#include <private/qtreeview_p.h>-
60#include <private/qheaderview_p.h>-
61-
62#include <algorithm>-
63-
64QT_BEGIN_NAMESPACE-
65-
66/*!-
67 \class QTreeView-
68 \brief The QTreeView class provides a default model/view implementation of a tree view.-
69-
70 \ingroup model-view-
71 \ingroup advanced-
72 \inmodule QtWidgets-
73-
74 A QTreeView implements a tree representation of items from a-
75 model. This class is used to provide standard hierarchical lists that-
76 were previously provided by the \c QListView class, but using the more-
77 flexible approach provided by Qt's model/view architecture.-
78-
79 The QTreeView class is one of the \l{Model/View Classes} and is part of-
80 Qt's \l{Model/View Programming}{model/view framework}.-
81-
82 QTreeView implements the interfaces defined by the-
83 QAbstractItemView class to allow it to display data provided by-
84 models derived from the QAbstractItemModel class.-
85-
86 It is simple to construct a tree view displaying data from a-
87 model. In the following example, the contents of a directory are-
88 supplied by a QFileSystemModel and displayed as a tree:-
89-
90 \snippet shareddirmodel/main.cpp 3-
91 \snippet shareddirmodel/main.cpp 6-
92-
93 The model/view architecture ensures that the contents of the tree view-
94 are updated as the model changes.-
95-
96 Items that have children can be in an expanded (children are-
97 visible) or collapsed (children are hidden) state. When this state-
98 changes a collapsed() or expanded() signal is emitted with the-
99 model index of the relevant item.-
100-
101 The amount of indentation used to indicate levels of hierarchy is-
102 controlled by the \l indentation property.-
103-
104 Headers in tree views are constructed using the QHeaderView class and can-
105 be hidden using \c{header()->hide()}. Note that each header is configured-
106 with its \l{QHeaderView::}{stretchLastSection} property set to true,-
107 ensuring that the view does not waste any of the space assigned to it for-
108 its header. If this value is set to true, this property will override the-
109 resize mode set on the last section in the header.-
110-
111 By default, all columns in a tree view are movable except the first. To-
112 disable movement of these columns, use QHeaderView's-
113 \l {QHeaderView::}{setSectionsMovable()} function. For more information-
114 about rearranging sections, see \l {Moving Header Sections}.-
115-
116 \section1 Key Bindings-
117-
118 QTreeView supports a set of key bindings that enable the user to-
119 navigate in the view and interact with the contents of items:-
120-
121 \table-
122 \header \li Key \li Action-
123 \row \li Up \li Moves the cursor to the item in the same column on-
124 the previous row. If the parent of the current item has no more rows to-
125 navigate to, the cursor moves to the relevant item in the last row-
126 of the sibling that precedes the parent.-
127 \row \li Down \li Moves the cursor to the item in the same column on-
128 the next row. If the parent of the current item has no more rows to-
129 navigate to, the cursor moves to the relevant item in the first row-
130 of the sibling that follows the parent.-
131 \row \li Left \li Hides the children of the current item (if present)-
132 by collapsing a branch.-
133 \row \li Minus \li Same as LeftArrow.-
134 \row \li Right \li Reveals the children of the current item (if present)-
135 by expanding a branch.-
136 \row \li Plus \li Same as RightArrow.-
137 \row \li Asterisk \li Expands all children of the current item (if present).-
138 \row \li PageUp \li Moves the cursor up one page.-
139 \row \li PageDown \li Moves the cursor down one page.-
140 \row \li Home \li Moves the cursor to an item in the same column of the first-
141 row of the first top-level item in the model.-
142 \row \li End \li Moves the cursor to an item in the same column of the last-
143 row of the last top-level item in the model.-
144 \row \li F2 \li In editable models, this opens the current item for editing.-
145 The Escape key can be used to cancel the editing process and revert-
146 any changes to the data displayed.-
147 \endtable-
148-
149 \omit-
150 Describe the expanding/collapsing concept if not covered elsewhere.-
151 \endomit-
152-
153 \table 100%-
154 \row \li \inlineimage windowsvista-treeview.png Screenshot of a Windows Vista style tree view-
155 \li \inlineimage macintosh-treeview.png Screenshot of a Macintosh style tree view-
156 \li \inlineimage fusion-treeview.png Screenshot of a Fusion style tree view-
157 \row \li A \l{Windows Vista Style Widget Gallery}{Windows Vista style} tree view.-
158 \li A \l{Macintosh Style Widget Gallery}{Macintosh style} tree view.-
159 \li A \l{Fusion Style Widget Gallery}{Fusion style} tree view.-
160 \endtable-
161-
162 \section1 Improving Performance-
163-
164 It is possible to give the view hints about the data it is handling in order-
165 to improve its performance when displaying large numbers of items. One approach-
166 that can be taken for views that are intended to display items with equal heights-
167 is to set the \l uniformRowHeights property to true.-
168-
169 \sa QListView, QTreeWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,-
170 {Dir View Example}-
171*/-
172-
173-
174/*!-
175 \fn void QTreeView::expanded(const QModelIndex &index)-
176-
177 This signal is emitted when the item specified by \a index is expanded.-
178*/-
179-
180-
181/*!-
182 \fn void QTreeView::collapsed(const QModelIndex &index)-
183-
184 This signal is emitted when the item specified by \a index is collapsed.-
185*/-
186-
187/*!-
188 Constructs a tree view with a \a parent to represent a model's-
189 data. Use setModel() to set the model.-
190-
191 \sa QAbstractItemModel-
192*/-
193QTreeView::QTreeView(QWidget *parent)-
194 : QAbstractItemView(*new QTreeViewPrivate, parent)-
195{-
196 Q_D(QTreeView);-
197 d->initialize();-
198}-
199-
200/*!-
201 \internal-
202*/-
203QTreeView::QTreeView(QTreeViewPrivate &dd, QWidget *parent)-
204 : QAbstractItemView(dd, parent)-
205{-
206 Q_D(QTreeView);-
207 d->initialize();-
208}-
209-
210/*!-
211 Destroys the tree view.-
212*/-
213QTreeView::~QTreeView()-
214{-
215}-
216-
217/*!-
218 \reimp-
219*/-
220void QTreeView::setModel(QAbstractItemModel *model)-
221{-
222 Q_D(QTreeView);-
223 if (model == d->model)-
224 return;-
225 if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {-
226 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),-
227 this, SLOT(rowsRemoved(QModelIndex,int,int)));-
228-
229 disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));-
230 }-
231-
232 if (d->selectionModel) { // support row editing-
233 disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),-
234 d->model, SLOT(submit()));-
235 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),-
236 this, SLOT(rowsRemoved(QModelIndex,int,int)));-
237 disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));-
238 }-
239 d->viewItems.clear();-
240 d->expandedIndexes.clear();-
241 d->hiddenIndexes.clear();-
242 d->header->setModel(model);-
243 QAbstractItemView::setModel(model);-
244-
245 // QAbstractItemView connects to a private slot-
246 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),-
247 this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));-
248 // do header layout after the tree-
249 disconnect(d->model, SIGNAL(layoutChanged()),-
250 d->header, SLOT(_q_layoutChanged()));-
251 // QTreeView has a public slot for this-
252 connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),-
253 this, SLOT(rowsRemoved(QModelIndex,int,int)));-
254-
255 connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));-
256-
257 if (d->sortingEnabled)-
258 d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());-
259}-
260-
261/*!-
262 \reimp-
263*/-
264void QTreeView::setRootIndex(const QModelIndex &index)-
265{-
266 Q_D(QTreeView);-
267 d->header->setRootIndex(index);-
268 QAbstractItemView::setRootIndex(index);-
269}-
270-
271/*!-
272 \reimp-
273*/-
274void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)-
275{-
276 Q_D(QTreeView);-
277 Q_ASSERT(selectionModel);-
278 if (d->selectionModel) {-
279 // support row editing-
280 disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),-
281 d->model, SLOT(submit()));-
282 }-
283-
284 d->header->setSelectionModel(selectionModel);-
285 QAbstractItemView::setSelectionModel(selectionModel);-
286-
287 if (d->selectionModel) {-
288 // support row editing-
289 connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),-
290 d->model, SLOT(submit()));-
291 }-
292}-
293-
294/*!-
295 Returns the header for the tree view.-
296-
297 \sa QAbstractItemModel::headerData()-
298*/-
299QHeaderView *QTreeView::header() const-
300{-
301 Q_D(const QTreeView);-
302 return d->header;-
303}-
304-
305/*!-
306 Sets the header for the tree view, to the given \a header.-
307-
308 The view takes ownership over the given \a header and deletes it-
309 when a new header is set.-
310-
311 \sa QAbstractItemModel::headerData()-
312*/-
313void QTreeView::setHeader(QHeaderView *header)-
314{-
315 Q_D(QTreeView);-
316 if (header == d->header || !header)-
317 return;-
318 if (d->header && d->header->parent() == this)-
319 delete d->header;-
320 d->header = header;-
321 d->header->setParent(this);-
322 d->header->d_func()->setAllowUserMoveOfSection0(false);-
323-
324 if (!d->header->model()) {-
325 d->header->setModel(d->model);-
326 if (d->selectionModel)-
327 d->header->setSelectionModel(d->selectionModel);-
328 }-
329-
330 connect(d->header, SIGNAL(sectionResized(int,int,int)),-
331 this, SLOT(columnResized(int,int,int)));-
332 connect(d->header, SIGNAL(sectionMoved(int,int,int)),-
333 this, SLOT(columnMoved()));-
334 connect(d->header, SIGNAL(sectionCountChanged(int,int)),-
335 this, SLOT(columnCountChanged(int,int)));-
336 connect(d->header, SIGNAL(sectionHandleDoubleClicked(int)),-
337 this, SLOT(resizeColumnToContents(int)));-
338 connect(d->header, SIGNAL(geometriesChanged()),-
339 this, SLOT(updateGeometries()));-
340-
341 setSortingEnabled(d->sortingEnabled);-
342 d->updateGeometry();-
343}-
344-
345/*!-
346 \property QTreeView::autoExpandDelay-
347 \brief The delay time before items in a tree are opened during a drag and drop operation.-
348 \since 4.3-
349-
350 This property holds the amount of time in milliseconds that the user must wait over-
351 a node before that node will automatically open or close. If the time is-
352 set to less then 0 then it will not be activated.-
353-
354 By default, this property has a value of -1, meaning that auto-expansion is disabled.-
355*/-
356int QTreeView::autoExpandDelay() const-
357{-
358 Q_D(const QTreeView);-
359 return d->autoExpandDelay;-
360}-
361-
362void QTreeView::setAutoExpandDelay(int delay)-
363{-
364 Q_D(QTreeView);-
365 d->autoExpandDelay = delay;-
366}-
367-
368/*!-
369 \property QTreeView::indentation-
370 \brief indentation of the items in the tree view.-
371-
372 This property holds the indentation measured in pixels of the items for each-
373 level in the tree view. For top-level items, the indentation specifies the-
374 horizontal distance from the viewport edge to the items in the first column;-
375 for child items, it specifies their indentation from their parent items.-
376-
377 By default, the value of this property is style dependent. Thus, when the style-
378 changes, this property updates from it. Calling setIndentation() stops the updates,-
379 calling resetIndentation() will restore default behavior.-
380*/-
381int QTreeView::indentation() const-
382{-
383 Q_D(const QTreeView);-
384 return d->indent;-
385}-
386-
387void QTreeView::setIndentation(int i)-
388{-
389 Q_D(QTreeView);-
390 if (!d->customIndent || (i != d->indent)) {-
391 d->indent = i;-
392 d->customIndent = true;-
393 d->viewport->update();-
394 }-
395}-
396-
397void QTreeView::resetIndentation()-
398{-
399 Q_D(QTreeView);-
400 if (d->customIndent) {-
401 d->updateIndentationFromStyle();-
402 d->customIndent = false;-
403 }-
404}-
405-
406/*!-
407 \property QTreeView::rootIsDecorated-
408 \brief whether to show controls for expanding and collapsing top-level items-
409-
410 Items with children are typically shown with controls to expand and collapse-
411 them, allowing their children to be shown or hidden. If this property is-
412 false, these controls are not shown for top-level items. This can be used to-
413 make a single level tree structure appear like a simple list of items.-
414-
415 By default, this property is \c true.-
416*/-
417bool QTreeView::rootIsDecorated() const-
418{-
419 Q_D(const QTreeView);-
420 return d->rootDecoration;-
421}-
422-
423void QTreeView::setRootIsDecorated(bool show)-
424{-
425 Q_D(QTreeView);-
426 if (show != d->rootDecoration) {-
427 d->rootDecoration = show;-
428 d->viewport->update();-
429 }-
430}-
431-
432/*!-
433 \property QTreeView::uniformRowHeights-
434 \brief whether all items in the treeview have the same height-
435-
436 This property should only be set to true if it is guaranteed that all items-
437 in the view has the same height. This enables the view to do some-
438 optimizations.-
439-
440 The height is obtained from the first item in the view. It is updated-
441 when the data changes on that item.-
442-
443 \note If the editor size hint is bigger than the cell size hint, then the-
444 size hint of the editor will be used.-
445-
446 By default, this property is \c false.-
447*/-
448bool QTreeView::uniformRowHeights() const-
449{-
450 Q_D(const QTreeView);-
451 return d->uniformRowHeights;-
452}-
453-
454void QTreeView::setUniformRowHeights(bool uniform)-
455{-
456 Q_D(QTreeView);-
457 d->uniformRowHeights = uniform;-
458}-
459-
460/*!-
461 \property QTreeView::itemsExpandable-
462 \brief whether the items are expandable by the user.-
463-
464 This property holds whether the user can expand and collapse items-
465 interactively.-
466-
467 By default, this property is \c true.-
468-
469*/-
470bool QTreeView::itemsExpandable() const-
471{-
472 Q_D(const QTreeView);-
473 return d->itemsExpandable;-
474}-
475-
476void QTreeView::setItemsExpandable(bool enable)-
477{-
478 Q_D(QTreeView);-
479 d->itemsExpandable = enable;-
480}-
481-
482/*!-
483 \property QTreeView::expandsOnDoubleClick-
484 \since 4.4-
485 \brief whether the items can be expanded by double-clicking.-
486-
487 This property holds whether the user can expand and collapse items-
488 by double-clicking. The default value is true.-
489-
490 \sa itemsExpandable-
491*/-
492bool QTreeView::expandsOnDoubleClick() const-
493{-
494 Q_D(const QTreeView);-
495 return d->expandsOnDoubleClick;-
496}-
497-
498void QTreeView::setExpandsOnDoubleClick(bool enable)-
499{-
500 Q_D(QTreeView);-
501 d->expandsOnDoubleClick = enable;-
502}-
503-
504/*!-
505 Returns the horizontal position of the \a column in the viewport.-
506*/-
507int QTreeView::columnViewportPosition(int column) const-
508{-
509 Q_D(const QTreeView);-
510 return d->header->sectionViewportPosition(column);-
511}-
512-
513/*!-
514 Returns the width of the \a column.-
515-
516 \sa resizeColumnToContents(), setColumnWidth()-
517*/-
518int QTreeView::columnWidth(int column) const-
519{-
520 Q_D(const QTreeView);-
521 return d->header->sectionSize(column);-
522}-
523-
524/*!-
525 \since 4.2-
526-
527 Sets the width of the given \a column to the \a width specified.-
528-
529 \sa columnWidth(), resizeColumnToContents()-
530*/-
531void QTreeView::setColumnWidth(int column, int width)-
532{-
533 Q_D(QTreeView);-
534 d->header->resizeSection(column, width);-
535}-
536-
537/*!-
538 Returns the column in the tree view whose header covers the \a x-
539 coordinate given.-
540*/-
541int QTreeView::columnAt(int x) const-
542{-
543 Q_D(const QTreeView);-
544 return d->header->logicalIndexAt(x);-
545}-
546-
547/*!-
548 Returns \c true if the \a column is hidden; otherwise returns \c false.-
549-
550 \sa hideColumn(), isRowHidden()-
551*/-
552bool QTreeView::isColumnHidden(int column) const-
553{-
554 Q_D(const QTreeView);-
555 return d->header->isSectionHidden(column);-
556}-
557-
558/*!-
559 If \a hide is true the \a column is hidden, otherwise the \a column is shown.-
560-
561 \sa hideColumn(), setRowHidden()-
562*/-
563void QTreeView::setColumnHidden(int column, bool hide)-
564{-
565 Q_D(QTreeView);-
566 if (column < 0 || column >= d->header->count())-
567 return;-
568 d->header->setSectionHidden(column, hide);-
569}-
570-
571/*!-
572 \property QTreeView::headerHidden-
573 \brief whether the header is shown or not.-
574 \since 4.4-
575-
576 If this property is \c true, the header is not shown otherwise it is.-
577 The default value is false.-
578-
579 \sa header()-
580*/-
581bool QTreeView::isHeaderHidden() const-
582{-
583 Q_D(const QTreeView);-
584 return d->header->isHidden();-
585}-
586-
587void QTreeView::setHeaderHidden(bool hide)-
588{-
589 Q_D(QTreeView);-
590 d->header->setHidden(hide);-
591}-
592-
593/*!-
594 Returns \c true if the item in the given \a row of the \a parent is hidden;-
595 otherwise returns \c false.-
596-
597 \sa setRowHidden(), isColumnHidden()-
598*/-
599bool QTreeView::isRowHidden(int row, const QModelIndex &parent) const-
600{-
601 Q_D(const QTreeView);-
602 if (!d->model)-
603 return false;-
604 return d->isRowHidden(d->model->index(row, 0, parent));-
605}-
606-
607/*!-
608 If \a hide is true the \a row with the given \a parent is hidden, otherwise the \a row is shown.-
609-
610 \sa isRowHidden(), setColumnHidden()-
611*/-
612void QTreeView::setRowHidden(int row, const QModelIndex &parent, bool hide)-
613{-
614 Q_D(QTreeView);-
615 if (!d->model)-
616 return;-
617 QModelIndex index = d->model->index(row, 0, parent);-
618 if (!index.isValid())-
619 return;-
620-
621 if (hide) {-
622 d->hiddenIndexes.insert(index);-
623 } else if(d->isPersistent(index)) { //if the index is not persistent, it cannot be in the set-
624 d->hiddenIndexes.remove(index);-
625 }-
626-
627 d->doDelayedItemsLayout();-
628}-
629-
630/*!-
631 \since 4.3-
632-
633 Returns \c true if the item in first column in the given \a row-
634 of the \a parent is spanning all the columns; otherwise returns \c false.-
635-
636 \sa setFirstColumnSpanned()-
637*/-
638bool QTreeView::isFirstColumnSpanned(int row, const QModelIndex &parent) const-
639{-
640 Q_D(const QTreeView);-
641 if (d->spanningIndexes.isEmpty() || !d->model)-
642 return false;-
643 QModelIndex index = d->model->index(row, 0, parent);-
644 for (int i = 0; i < d->spanningIndexes.count(); ++i)-
645 if (d->spanningIndexes.at(i) == index)-
646 return true;-
647 return false;-
648}-
649-
650/*!-
651 \since 4.3-
652-
653 If \a span is true the item in the first column in the \a row-
654 with the given \a parent is set to span all columns, otherwise all items-
655 on the \a row are shown.-
656-
657 \sa isFirstColumnSpanned()-
658*/-
659void QTreeView::setFirstColumnSpanned(int row, const QModelIndex &parent, bool span)-
660{-
661 Q_D(QTreeView);-
662 if (!d->model)-
663 return;-
664 QModelIndex index = d->model->index(row, 0, parent);-
665 if (!index.isValid())-
666 return;-
667-
668 if (span) {-
669 QPersistentModelIndex persistent(index);-
670 if (!d->spanningIndexes.contains(persistent))-
671 d->spanningIndexes.append(persistent);-
672 } else {-
673 QPersistentModelIndex persistent(index);-
674 int i = d->spanningIndexes.indexOf(persistent);-
675 if (i >= 0)-
676 d->spanningIndexes.remove(i);-
677 }-
678-
679 d->executePostedLayout();-
680 int i = d->viewIndex(index);-
681 if (i >= 0)-
682 d->viewItems[i].spanning = span;-
683-
684 d->viewport->update();-
685}-
686-
687/*!-
688 \reimp-
689*/-
690void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)-
691{-
692 Q_D(QTreeView);-
693-
694 // if we are going to do a complete relayout anyway, there is no need to update-
695 if (d->delayedPendingLayout)-
696 return;-
697-
698 // refresh the height cache here; we don't really lose anything by getting the size hint,-
699 // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway-
700-
701 bool sizeChanged = false;-
702 int topViewIndex = d->viewIndex(topLeft);-
703 if (topViewIndex == 0) {-
704 int newDefaultItemHeight = indexRowSizeHint(topLeft);-
705 sizeChanged = d->defaultItemHeight != newDefaultItemHeight;-
706 d->defaultItemHeight = newDefaultItemHeight;-
707 }-
708-
709 if (topViewIndex != -1) {-
710 if (topLeft.row() == bottomRight.row()) {-
711 int oldHeight = d->itemHeight(topViewIndex);-
712 d->invalidateHeightCache(topViewIndex);-
713 sizeChanged |= (oldHeight != d->itemHeight(topViewIndex));-
714 if (topLeft.column() == 0)-
715 d->viewItems[topViewIndex].hasChildren = d->hasVisibleChildren(topLeft);-
716 } else {-
717 int bottomViewIndex = d->viewIndex(bottomRight);-
718 for (int i = topViewIndex; i <= bottomViewIndex; ++i) {-
719 int oldHeight = d->itemHeight(i);-
720 d->invalidateHeightCache(i);-
721 sizeChanged |= (oldHeight != d->itemHeight(i));-
722 if (topLeft.column() == 0)-
723 d->viewItems[i].hasChildren = d->hasVisibleChildren(d->viewItems.at(i).index);-
724 }-
725 }-
726 }-
727-
728 if (sizeChanged) {-
729 d->updateScrollBars();-
730 d->viewport->update();-
731 }-
732 QAbstractItemView::dataChanged(topLeft, bottomRight, roles);-
733}-
734-
735/*!-
736 Hides the \a column given.-
737-
738 \note This function should only be called after the model has been-
739 initialized, as the view needs to know the number of columns in order to-
740 hide \a column.-
741-
742 \sa showColumn(), setColumnHidden()-
743*/-
744void QTreeView::hideColumn(int column)-
745{-
746 Q_D(QTreeView);-
747 d->header->hideSection(column);-
748}-
749-
750/*!-
751 Shows the given \a column in the tree view.-
752-
753 \sa hideColumn(), setColumnHidden()-
754*/-
755void QTreeView::showColumn(int column)-
756{-
757 Q_D(QTreeView);-
758 d->header->showSection(column);-
759}-
760-
761/*!-
762 \fn void QTreeView::expand(const QModelIndex &index)-
763-
764 Expands the model item specified by the \a index.-
765-
766 \sa expanded()-
767*/-
768void QTreeView::expand(const QModelIndex &index)-
769{-
770 Q_D(QTreeView);-
771 if (!d->isIndexValid(index))-
772 return;-
773 if (index.flags() & Qt::ItemNeverHasChildren)-
774 return;-
775 if (d->isIndexExpanded(index))-
776 return;-
777 if (d->delayedPendingLayout) {-
778 //A complete relayout is going to be performed, just store the expanded index, no need to layout.-
779 if (d->storeExpanded(index))-
780 emit expanded(index);-
781 return;-
782 }-
783-
784 int i = d->viewIndex(index);-
785 if (i != -1) { // is visible-
786 d->expand(i, true);-
787 if (!d->isAnimating()) {-
788 updateGeometries();-
789 d->viewport->update();-
790 }-
791 } else if (d->storeExpanded(index)) {-
792 emit expanded(index);-
793 }-
794}-
795-
796/*!-
797 \fn void QTreeView::collapse(const QModelIndex &index)-
798-
799 Collapses the model item specified by the \a index.-
800-
801 \sa collapsed()-
802*/-
803void QTreeView::collapse(const QModelIndex &index)-
804{-
805 Q_D(QTreeView);-
806 if (!d->isIndexValid(index))-
807 return;-
808 if (!d->isIndexExpanded(index))-
809 return;-
810 //if the current item is now invisible, the autoscroll will expand the tree to see it, so disable the autoscroll-
811 d->delayedAutoScroll.stop();-
812-
813 if (d->delayedPendingLayout) {-
814 //A complete relayout is going to be performed, just un-store the expanded index, no need to layout.-
815 if (d->isPersistent(index) && d->expandedIndexes.remove(index))-
816 emit collapsed(index);-
817 return;-
818 }-
819 int i = d->viewIndex(index);-
820 if (i != -1) { // is visible-
821 d->collapse(i, true);-
822 if (!d->isAnimating()) {-
823 updateGeometries();-
824 viewport()->update();-
825 }-
826 } else {-
827 if (d->isPersistent(index) && d->expandedIndexes.remove(index))-
828 emit collapsed(index);-
829 }-
830}-
831-
832/*!-
833 \fn bool QTreeView::isExpanded(const QModelIndex &index) const-
834-
835 Returns \c true if the model item \a index is expanded; otherwise returns-
836 false.-
837-
838 \sa expand(), expanded(), setExpanded()-
839*/-
840bool QTreeView::isExpanded(const QModelIndex &index) const-
841{-
842 Q_D(const QTreeView);-
843 return d->isIndexExpanded(index);-
844}-
845-
846/*!-
847 Sets the item referred to by \a index to either collapse or expanded,-
848 depending on the value of \a expanded.-
849-
850 \sa expanded(), expand(), isExpanded()-
851*/-
852void QTreeView::setExpanded(const QModelIndex &index, bool expanded)-
853{-
854 if (expanded)-
855 this->expand(index);-
856 else-
857 this->collapse(index);-
858}-
859-
860/*!-
861 \since 4.2-
862 \property QTreeView::sortingEnabled-
863 \brief whether sorting is enabled-
864-
865 If this property is \c true, sorting is enabled for the tree; if the property-
866 is false, sorting is not enabled. The default value is false.-
867-
868 \note In order to avoid performance issues, it is recommended that-
869 sorting is enabled \e after inserting the items into the tree.-
870 Alternatively, you could also insert the items into a list before inserting-
871 the items into the tree.-
872-
873 \sa sortByColumn()-
874*/-
875-
876void QTreeView::setSortingEnabled(bool enable)-
877{-
878 Q_D(QTreeView);-
879 header()->setSortIndicatorShown(enable);-
880 header()->setSectionsClickable(enable);-
881 if (enable) {-
882 //sortByColumn has to be called before we connect or set the sortingEnabled flag-
883 // because otherwise it will not call sort on the model.-
884 sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());-
885 connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),-
886 this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);-
887 } else {-
888 disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),-
889 this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));-
890 }-
891 d->sortingEnabled = enable;-
892}-
893-
894bool QTreeView::isSortingEnabled() const-
895{-
896 Q_D(const QTreeView);-
897 return d->sortingEnabled;-
898}-
899-
900/*!-
901 \since 4.2-
902 \property QTreeView::animated-
903 \brief whether animations are enabled-
904-
905 If this property is \c true the treeview will animate expansion-
906 and collapsing of branches. If this property is \c false, the treeview-
907 will expand or collapse branches immediately without showing-
908 the animation.-
909-
910 By default, this property is \c false.-
911*/-
912-
913void QTreeView::setAnimated(bool animate)-
914{-
915 Q_D(QTreeView);-
916 d->animationsEnabled = animate;-
917}-
918-
919bool QTreeView::isAnimated() const-
920{-
921 Q_D(const QTreeView);-
922 return d->animationsEnabled;-
923}-
924-
925/*!-
926 \since 4.2-
927 \property QTreeView::allColumnsShowFocus-
928 \brief whether items should show keyboard focus using all columns-
929-
930 If this property is \c true all columns will show focus, otherwise only-
931 one column will show focus.-
932-
933 The default is false.-
934*/-
935-
936void QTreeView::setAllColumnsShowFocus(bool enable)-
937{-
938 Q_D(QTreeView);-
939 if (d->allColumnsShowFocus == enable)-
940 return;-
941 d->allColumnsShowFocus = enable;-
942 d->viewport->update();-
943}-
944-
945bool QTreeView::allColumnsShowFocus() const-
946{-
947 Q_D(const QTreeView);-
948 return d->allColumnsShowFocus;-
949}-
950-
951/*!-
952 \property QTreeView::wordWrap-
953 \brief the item text word-wrapping policy-
954 \since 4.3-
955-
956 If this property is \c true then the item text is wrapped where-
957 necessary at word-breaks; otherwise it is not wrapped at all.-
958 This property is \c false by default.-
959-
960 Note that even if wrapping is enabled, the cell will not be-
961 expanded to fit all text. Ellipsis will be inserted according to-
962 the current \l{QAbstractItemView::}{textElideMode}.-
963*/-
964void QTreeView::setWordWrap(bool on)-
965{-
966 Q_D(QTreeView);-
967 if (d->wrapItemText == on)-
968 return;-
969 d->wrapItemText = on;-
970 d->doDelayedItemsLayout();-
971}-
972-
973bool QTreeView::wordWrap() const-
974{-
975 Q_D(const QTreeView);-
976 return d->wrapItemText;-
977}-
978-
979/*!-
980 \since 5.2-
981-
982 This specifies that the tree structure should be placed at logical index \a index.-
983 If \index is set to -1 then the tree will always follow visual index 0.-
984-
985 \sa treePosition(), QHeaderView::swapSections(), QHeaderView::moveSection()-
986*/-
987-
988void QTreeView::setTreePosition(int index)-
989{-
990 Q_D(QTreeView);-
991 d->treePosition = index;-
992 update();-
993}-
994-
995/*!-
996 \since 5.2-
997-
998 Return the logical index the tree is set on. If the return value is -1 then the-
999 tree is placed on the visual index 0.-
1000-
1001 \sa setTreePosition()-
1002*/-
1003-
1004int QTreeView::treePosition() const-
1005{-
1006 Q_D(const QTreeView);-
1007 return d->treePosition;-
1008}-
1009-
1010/*!-
1011 \reimp-
1012 */-
1013void QTreeView::keyboardSearch(const QString &search)-
1014{-
1015 Q_D(QTreeView);-
1016 if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))-
1017 return;-
1018-
1019 QModelIndex start;-
1020 if (currentIndex().isValid())-
1021 start = currentIndex();-
1022 else-
1023 start = d->model->index(0, 0, d->root);-
1024-
1025 bool skipRow = false;-
1026 bool keyboardTimeWasValid = d->keyboardInputTime.isValid();-
1027 qint64 keyboardInputTimeElapsed;-
1028 if (keyboardTimeWasValid)-
1029 keyboardInputTimeElapsed = d->keyboardInputTime.restart();-
1030 else-
1031 d->keyboardInputTime.start();-
1032 if (search.isEmpty() || !keyboardTimeWasValid-
1033 || keyboardInputTimeElapsed > QApplication::keyboardInputInterval()) {-
1034 d->keyboardInput = search;-
1035 skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)-
1036 } else {-
1037 d->keyboardInput += search;-
1038 }-
1039-
1040 // special case for searches with same key like 'aaaaa'-
1041 bool sameKey = false;-
1042 if (d->keyboardInput.length() > 1) {-
1043 int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));-
1044 sameKey = (c == d->keyboardInput.length());-
1045 if (sameKey)-
1046 skipRow = true;-
1047 }-
1048-
1049 // skip if we are searching for the same key or a new search started-
1050 if (skipRow) {-
1051 if (indexBelow(start).isValid())-
1052 start = indexBelow(start);-
1053 else-
1054 start = d->model->index(0, start.column(), d->root);-
1055 }-
1056-
1057 d->executePostedLayout();-
1058 int startIndex = d->viewIndex(start);-
1059 if (startIndex <= -1)-
1060 return;-
1061-
1062 int previousLevel = -1;-
1063 int bestAbove = -1;-
1064 int bestBelow = -1;-
1065 QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;-
1066 for (int i = 0; i < d->viewItems.count(); ++i) {-
1067 if ((int)d->viewItems.at(i).level > previousLevel) {-
1068 QModelIndex searchFrom = d->viewItems.at(i).index;-
1069 if (start.column() > 0)-
1070 searchFrom = searchFrom.sibling(searchFrom.row(), start.column());-
1071 if (searchFrom.parent() == start.parent())-
1072 searchFrom = start;-
1073 QModelIndexList match = d->model->match(searchFrom, Qt::DisplayRole, searchString);-
1074 if (match.count()) {-
1075 int hitIndex = d->viewIndex(match.at(0));-
1076 if (hitIndex >= 0 && hitIndex < startIndex)-
1077 bestAbove = bestAbove == -1 ? hitIndex : qMin(hitIndex, bestAbove);-
1078 else if (hitIndex >= startIndex)-
1079 bestBelow = bestBelow == -1 ? hitIndex : qMin(hitIndex, bestBelow);-
1080 }-
1081 }-
1082 previousLevel = d->viewItems.at(i).level;-
1083 }-
1084-
1085 QModelIndex index;-
1086 if (bestBelow > -1)-
1087 index = d->viewItems.at(bestBelow).index;-
1088 else if (bestAbove > -1)-
1089 index = d->viewItems.at(bestAbove).index;-
1090-
1091 if (start.column() > 0)-
1092 index = index.sibling(index.row(), start.column());-
1093-
1094 if (index.isValid()) {-
1095 QItemSelectionModel::SelectionFlags flags = (d->selectionMode == SingleSelection-
1096 ? QItemSelectionModel::SelectionFlags(-
1097 QItemSelectionModel::ClearAndSelect-
1098 |d->selectionBehaviorFlags())-
1099 : QItemSelectionModel::SelectionFlags(-
1100 QItemSelectionModel::NoUpdate));-
1101 selectionModel()->setCurrentIndex(index, flags);-
1102 }-
1103}-
1104-
1105/*!-
1106 Returns the rectangle on the viewport occupied by the item at \a index.-
1107 If the index is not visible or explicitly hidden, the returned rectangle is invalid.-
1108*/-
1109QRect QTreeView::visualRect(const QModelIndex &index) const-
1110{-
1111 Q_D(const QTreeView);-
1112-
1113 if (!d->isIndexValid(index) || isIndexHidden(index))-
1114 return QRect();-
1115-
1116 d->executePostedLayout();-
1117-
1118 int vi = d->viewIndex(index);-
1119 if (vi < 0)-
1120 return QRect();-
1121-
1122 bool spanning = d->viewItems.at(vi).spanning;-
1123-
1124 // if we have a spanning item, make the selection stretch from left to right-
1125 int x = (spanning ? 0 : columnViewportPosition(index.column()));-
1126 int w = (spanning ? d->header->length() : columnWidth(index.column()));-
1127 // handle indentation-
1128 if (d->isTreePosition(index.column())) {-
1129 int i = d->indentationForItem(vi);-
1130 w -= i;-
1131 if (!isRightToLeft())-
1132 x += i;-
1133 }-
1134-
1135 int y = d->coordinateForItem(vi);-
1136 int h = d->itemHeight(vi);-
1137-
1138 return QRect(x, y, w, h);-
1139}-
1140-
1141/*!-
1142 Scroll the contents of the tree view until the given model item-
1143 \a index is visible. The \a hint parameter specifies more-
1144 precisely where the item should be located after the-
1145 operation.-
1146 If any of the parents of the model item are collapsed, they will-
1147 be expanded to ensure that the model item is visible.-
1148*/-
1149void QTreeView::scrollTo(const QModelIndex &index, ScrollHint hint)-
1150{-
1151 Q_D(QTreeView);-
1152-
1153 if (!d->isIndexValid(index))-
1154 return;-
1155-
1156 d->executePostedLayout();-
1157 d->updateScrollBars();-
1158-
1159 // Expand all parents if the parent(s) of the node are not expanded.-
1160 QModelIndex parent = index.parent();-
1161 while (parent != d->root && parent.isValid() && state() == NoState && d->itemsExpandable) {-
1162 if (!isExpanded(parent))-
1163 expand(parent);-
1164 parent = d->model->parent(parent);-
1165 }-
1166-
1167 int item = d->viewIndex(index);-
1168 if (item < 0)-
1169 return;-
1170-
1171 QRect area = d->viewport->rect();-
1172-
1173 // vertical-
1174 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {-
1175 int top = verticalScrollBar()->value();-
1176 int bottom = top + verticalScrollBar()->pageStep();-
1177 if (hint == EnsureVisible && item >= top && item < bottom) {-
1178 // nothing to do-
1179 } else if (hint == PositionAtTop || (hint == EnsureVisible && item < top)) {-
1180 verticalScrollBar()->setValue(item);-
1181 } else { // PositionAtBottom or PositionAtCenter-
1182 const int currentItemHeight = d->itemHeight(item);-
1183 int y = (hint == PositionAtCenter-
1184 //we center on the current item with a preference to the top item (ie. -1)-
1185 ? area.height() / 2 + currentItemHeight - 1-
1186 //otherwise we simply take the whole space-
1187 : area.height());-
1188 if (y > currentItemHeight) {-
1189 while (item >= 0) {-
1190 y -= d->itemHeight(item);-
1191 if (y < 0) { //there is no more space left-
1192 item++;-
1193 break;-
1194 }-
1195 item--;-
1196 }-
1197 }-
1198 verticalScrollBar()->setValue(item);-
1199 }-
1200 } else { // ScrollPerPixel-
1201 QRect rect(columnViewportPosition(index.column()),-
1202 d->coordinateForItem(item), // ### slow for items outside the view-
1203 columnWidth(index.column()),-
1204 d->itemHeight(item));-
1205-
1206 if (rect.isEmpty()) {-
1207 // nothing to do-
1208 } else if (hint == EnsureVisible && area.contains(rect)) {-
1209 d->viewport->update(rect);-
1210 // nothing to do-
1211 } else {-
1212 bool above = (hint == EnsureVisible-
1213 && (rect.top() < area.top()-
1214 || area.height() < rect.height()));-
1215 bool below = (hint == EnsureVisible-
1216 && rect.bottom() > area.bottom()-
1217 && rect.height() < area.height());-
1218-
1219 int verticalValue = verticalScrollBar()->value();-
1220 if (hint == PositionAtTop || above)-
1221 verticalValue += rect.top();-
1222 else if (hint == PositionAtBottom || below)-
1223 verticalValue += rect.bottom() - area.height();-
1224 else if (hint == PositionAtCenter)-
1225 verticalValue += rect.top() - ((area.height() - rect.height()) / 2);-
1226 verticalScrollBar()->setValue(verticalValue);-
1227 }-
1228 }-
1229 // horizontal-
1230 int viewportWidth = d->viewport->width();-
1231 int horizontalOffset = d->header->offset();-
1232 int horizontalPosition = d->header->sectionPosition(index.column());-
1233 int cellWidth = d->header->sectionSize(index.column());-
1234-
1235 if (hint == PositionAtCenter) {-
1236 horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));-
1237 } else {-
1238 if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)-
1239 horizontalScrollBar()->setValue(horizontalPosition);-
1240 else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)-
1241 horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);-
1242 }-
1243}-
1244-
1245/*!-
1246 \reimp-
1247*/-
1248void QTreeView::timerEvent(QTimerEvent *event)-
1249{-
1250 Q_D(QTreeView);-
1251 if (event->timerId() == d->columnResizeTimerID) {-
1252 updateGeometries();-
1253 killTimer(d->columnResizeTimerID);-
1254 d->columnResizeTimerID = 0;-
1255 QRect rect;-
1256 int viewportHeight = d->viewport->height();-
1257 int viewportWidth = d->viewport->width();-
1258 for (int i = d->columnsToUpdate.size() - 1; i >= 0; --i) {-
1259 int column = d->columnsToUpdate.at(i);-
1260 int x = columnViewportPosition(column);-
1261 if (isRightToLeft())-
1262 rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);-
1263 else-
1264 rect |= QRect(x, 0, viewportWidth - x, viewportHeight);-
1265 }-
1266 d->viewport->update(rect.normalized());-
1267 d->columnsToUpdate.clear();-
1268 } else if (event->timerId() == d->openTimer.timerId()) {-
1269 QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());-
1270 if (state() == QAbstractItemView::DraggingState-
1271 && d->viewport->rect().contains(pos)) {-
1272 QModelIndex index = indexAt(pos);-
1273 setExpanded(index, !isExpanded(index));-
1274 }-
1275 d->openTimer.stop();-
1276 }-
1277-
1278 QAbstractItemView::timerEvent(event);-
1279}-
1280-
1281/*!-
1282 \reimp-
1283*/-
1284#ifndef QT_NO_DRAGANDDROP-
1285void QTreeView::dragMoveEvent(QDragMoveEvent *event)-
1286{-
1287 Q_D(QTreeView);-
1288 if (d->autoExpandDelay >= 0)-
1289 d->openTimer.start(d->autoExpandDelay, this);-
1290 QAbstractItemView::dragMoveEvent(event);-
1291}-
1292#endif-
1293-
1294/*!-
1295 \reimp-
1296*/-
1297bool QTreeView::viewportEvent(QEvent *event)-
1298{-
1299 Q_D(QTreeView);-
1300 switch (event->type()) {-
1301 case QEvent::HoverEnter:-
1302 case QEvent::HoverLeave:-
1303 case QEvent::HoverMove: {-
1304 QHoverEvent *he = static_cast<QHoverEvent*>(event);-
1305 int oldBranch = d->hoverBranch;-
1306 d->hoverBranch = d->itemDecorationAt(he->pos());-
1307 QModelIndex newIndex = indexAt(he->pos());-
1308 if (d->hover != newIndex || d->hoverBranch != oldBranch) {-
1309 // Update the whole hovered over row. No need to update the old hovered-
1310 // row, that is taken care in superclass hover handling.-
1311 QRect rect = visualRect(newIndex);-
1312 rect.setX(0);-
1313 rect.setWidth(viewport()->width());-
1314 viewport()->update(rect);-
1315 }-
1316 break; }-
1317 default:-
1318 break;-
1319 }-
1320 return QAbstractItemView::viewportEvent(event);-
1321}-
1322-
1323/*!-
1324 \reimp-
1325*/-
1326void QTreeView::paintEvent(QPaintEvent *event)-
1327{-
1328 Q_D(QTreeView);-
1329 d->executePostedLayout();-
1330 QPainter painter(viewport());-
1331#ifndef QT_NO_ANIMATION-
1332 if (d->isAnimating()) {-
1333 drawTree(&painter, event->region() - d->animatedOperation.rect());-
1334 d->drawAnimatedOperation(&painter);-
1335 } else-
1336#endif //QT_NO_ANIMATION-
1337 {-
1338 drawTree(&painter, event->region());-
1339#ifndef QT_NO_DRAGANDDROP-
1340 d->paintDropIndicator(&painter);-
1341#endif-
1342 }-
1343}-
1344-
1345int QTreeViewPrivate::logicalIndexForTree() const-
1346{-
1347 int index = treePosition;-
1348 if (index < 0)-
1349 index = header->logicalIndex(0);-
1350 return index;-
1351}-
1352-
1353void QTreeViewPrivate::paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItem *option, int y, int bottom) const-
1354{-
1355 Q_Q(const QTreeView);-
1356 if (!alternatingColors || !q->style()->styleHint(QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea, option, q))
!alternatingColorsDescription
TRUEnever evaluated
FALSEnever evaluated
!q->style()->s...ea, option, q)Description
TRUEnever evaluated
FALSEnever evaluated
0
1357 return;
never executed: return;
0
1358 int rowHeight = defaultItemHeight;-
1359 if (rowHeight <= 0) {
rowHeight <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1360 rowHeight = itemDelegate->sizeHint(*option, QModelIndex()).height();-
1361 if (rowHeight <= 0)
rowHeight <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1362 return;
never executed: return;
0
1363 }
never executed: end of block
0
1364 while (y <= bottom) {
y <= bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1365 option->rect.setRect(0, y, viewport->width(), rowHeight);-
1366 if (current & 1) {option->features|=.setFlag(QStyleOptionViewItem::Alternate;-
} else {
option->features, current & = ~QStyleOptionViewItem::Alternate;
}1);
1367 ++current;-
1368 q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, option, painter, q);-
1369 y += rowHeight;-
1370 }
never executed: end of block
0
1371}
never executed: end of block
0
1372-
1373bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos)-
1374{-
1375 Q_Q(QTreeView);-
1376 // we want to handle mousePress in EditingState (persistent editors)-
1377 if ((state != QAbstractItemView::NoState-
1378 && state != QAbstractItemView::EditingState)-
1379 || !viewport->rect().contains(pos))-
1380 return true;-
1381-
1382 int i = itemDecorationAt(pos);-
1383 if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) {-
1384 if (viewItems.at(i).expanded)-
1385 collapse(i, true);-
1386 else-
1387 expand(i, true);-
1388 if (!isAnimating()) {-
1389 q->updateGeometries();-
1390 viewport->update();-
1391 }-
1392 return true;-
1393 }-
1394 return false;-
1395}-
1396-
1397void QTreeViewPrivate::_q_modelDestroyed()-
1398{-
1399 //we need to clear the viewItems because it contains QModelIndexes to-
1400 //the model currently being destroyed-
1401 viewItems.clear();-
1402 QAbstractItemViewPrivate::_q_modelDestroyed();-
1403}-
1404-
1405/*!-
1406 \reimp-
1407-
1408 We have a QTreeView way of knowing what elements are on the viewport-
1409*/-
1410QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const-
1411{-
1412 Q_ASSERT(r);-
1413 Q_Q(const QTreeView);-
1414 if (spanningIndexes.isEmpty())-
1415 return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r);-
1416 QModelIndexList list;-
1417 foreach (const QModelIndex &idx, indexes) {-
1418 if (idx.column() > 0 && q->isFirstColumnSpanned(idx.row(), idx.parent()))-
1419 continue;-
1420 list << idx;-
1421 }-
1422 return QAbstractItemViewPrivate::draggablePaintPairs(list, r);-
1423}-
1424-
1425void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex &current) const-
1426{-
1427 const int row = viewIndex(current); // get the index in viewItems[]-
1428 option->state = option->state | (viewItems.at(row).expanded ? QStyle::State_Open : QStyle::State_None)-
1429 | (viewItems.at(row).hasChildren ? QStyle::State_Children : QStyle::State_None)-
1430 | (viewItems.at(row).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);-
1431-
1432 option->showDecorationSelected = (selectionBehavior & QTreeView::SelectRows)-
1433 || option->showDecorationSelected;-
1434-
1435 QVector<int> logicalIndices; // index = visual index of visible columns only. data = logical index.-
1436 QVector<QStyleOptionViewItem::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex, visible columns only.-
1437 const bool spanning = viewItems.at(row).spanning;-
1438 const int left = (spanning ? header->visualIndex(0) : 0);-
1439 const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );-
1440 calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);-
1441-
1442 const int visualIndex = logicalIndices.indexOf(current.column());-
1443 option->viewItemPosition = viewItemPosList.at(visualIndex);-
1444}-
1445-
1446-
1447/*!-
1448 \since 4.2-
1449 Draws the part of the tree intersecting the given \a region using the specified-
1450 \a painter.-
1451-
1452 \sa paintEvent()-
1453*/-
1454void QTreeView::drawTree(QPainter *painter, const QRegion &region) const-
1455{-
1456 Q_D(const QTreeView);-
1457 const QVector<QTreeViewItem> viewItems = d->viewItems;-
1458-
1459 QStyleOptionViewItem option = d->viewOptionsV1();-
1460 const QStyle::State state = option.state;-
1461 d->current = 0;-
1462-
1463 if (viewItems.count() == 0 || d->header->count() == 0 || !d->itemDelegate) {-
1464 d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);-
1465 return;-
1466 }-
1467-
1468 int firstVisibleItemOffset = 0;-
1469 const int firstVisibleItem = d->firstVisibleItem(&firstVisibleItemOffset);-
1470 if (firstVisibleItem < 0) {-
1471 d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);-
1472 return;-
1473 }-
1474-
1475 const int viewportWidth = d->viewport->width();-
1476-
1477 QPoint hoverPos = d->viewport->mapFromGlobal(QCursor::pos());-
1478 d->hoverBranch = d->itemDecorationAt(hoverPos);-
1479-
1480 QVector<QRect> rects = region.rects();-
1481 QVector<int> drawn;-
1482 bool multipleRects = (rects.size() > 1);-
1483 for (int a = 0; a < rects.size(); ++a) {-
1484 const QRect area = (multipleRects-
1485 ? QRect(0, rects.at(a).y(), viewportWidth, rects.at(a).height())-
1486 : rects.at(a));-
1487 d->leftAndRight = d->startAndEndColumns(area);-
1488-
1489 int i = firstVisibleItem; // the first item at the top of the viewport-
1490 int y = firstVisibleItemOffset; // we may only see part of the first item-
1491-
1492 // start at the top of the viewport and iterate down to the update area-
1493 for (; i < viewItems.count(); ++i) {-
1494 const int itemHeight = d->itemHeight(i);-
1495 if (y + itemHeight > area.top())-
1496 break;-
1497 y += itemHeight;-
1498 }-
1499-
1500 // paint the visible rows-
1501 for (; i < viewItems.count() && y <= area.bottom(); ++i) {-
1502 const int itemHeight = d->itemHeight(i);-
1503 option.rect.setRect(0, y, viewportWidth, itemHeight);-
1504 option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)-
1505 | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)-
1506 | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);-
1507 d->current = i;-
1508 d->spanning = viewItems.at(i).spanning;-
1509 if (!multipleRects || !drawn.contains(i)) {-
1510 drawRow(painter, option, viewItems.at(i).index);-
1511 if (multipleRects) // even if the rect only intersects the item,-
1512 drawn.append(i); // the entire item will be painted-
1513 }-
1514 y += itemHeight;-
1515 }-
1516-
1517 if (y <= area.bottom()) {-
1518 d->current = i;-
1519 d->paintAlternatingRowColors(painter, &option, y, area.bottom());-
1520 }-
1521 }-
1522}-
1523-
1524/// ### move to QObject :)-
1525static inline bool ancestorOf(QObject *widget, QObject *other)-
1526{-
1527 for (QObject *parent = other; parent != 0; parent = parent->parent()) {-
1528 if (parent == widget)-
1529 return true;-
1530 }-
1531 return false;-
1532}-
1533-
1534void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left, int right) const-
1535{-
1536 const int columnCount = header->count();-
1537 /* 'left' and 'right' are the left-most and right-most visible visual indices.-
1538 Compute the first visible logical indices before and after the left and right.-
1539 We will use these values to determine the QStyleOptionViewItem::viewItemPosition. */-
1540 int logicalIndexBeforeLeft = -1, logicalIndexAfterRight = -1;-
1541 for (int visualIndex = left - 1; visualIndex >= 0; --visualIndex) {-
1542 int logicalIndex = header->logicalIndex(visualIndex);-
1543 if (!header->isSectionHidden(logicalIndex)) {-
1544 logicalIndexBeforeLeft = logicalIndex;-
1545 break;-
1546 }-
1547 }-
1548-
1549 for (int visualIndex = left; visualIndex < columnCount; ++visualIndex) {-
1550 int logicalIndex = header->logicalIndex(visualIndex);-
1551 if (!header->isSectionHidden(logicalIndex)) {-
1552 if (visualIndex > right) {-
1553 logicalIndexAfterRight = logicalIndex;-
1554 break;-
1555 }-
1556 logicalIndices->append(logicalIndex);-
1557 }-
1558 }-
1559-
1560 itemPositions->resize(logicalIndices->count());-
1561 for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices->count(); ++currentLogicalSection) {-
1562 const int headerSection = logicalIndices->at(currentLogicalSection);-
1563 // determine the viewItemPosition depending on the position of column 0-
1564 int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices->count()-
1565 ? logicalIndexAfterRight-
1566 : logicalIndices->at(currentLogicalSection + 1);-
1567 int prevLogicalSection = currentLogicalSection - 1 < 0-
1568 ? logicalIndexBeforeLeft-
1569 : logicalIndices->at(currentLogicalSection - 1);-
1570 QStyleOptionViewItem::ViewItemPosition pos;-
1571 if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1)-
1572 || (headerSection == 0 && nextLogicalSection == -1) || spanning)-
1573 pos = QStyleOptionViewItem::OnlyOne;-
1574 else if (isTreePosition(headerSection) || (nextLogicalSection != 0 && prevLogicalSection == -1))-
1575 pos = QStyleOptionViewItem::Beginning;-
1576 else if (nextLogicalSection == 0 || nextLogicalSection == -1)-
1577 pos = QStyleOptionViewItem::End;-
1578 else-
1579 pos = QStyleOptionViewItem::Middle;-
1580 (*itemPositions)[currentLogicalSection] = pos;-
1581 }-
1582}-
1583-
1584/*!-
1585 \internal-
1586 Get sizeHint width for single index (providing existing hint and style option) and index in viewIndex i.-
1587*/-
1588int QTreeViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const-
1589{-
1590 QWidget *editor = editorForIndex(index).widget.data();-
1591 if (editor && persistent.contains(editor)) {-
1592 hint = qMax(hint, editor->sizeHint().width());-
1593 int min = editor->minimumSize().width();-
1594 int max = editor->maximumSize().width();-
1595 hint = qBound(min, hint, max);-
1596 }-
1597 int xhint = delegateForIndex(index)->sizeHint(option, index).width();-
1598 hint = qMax(hint, xhint + (isTreePosition(index.column()) ? indentationForItem(i) : 0));-
1599 return hint;-
1600}-
1601-
1602/*!-
1603 Draws the row in the tree view that contains the model item \a index,-
1604 using the \a painter given. The \a option controls how the item is-
1605 displayed.-
1606-
1607 \sa setAlternatingRowColors()-
1608*/-
1609void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,-
1610 const QModelIndex &index) const-
1611{-
1612 Q_D(const QTreeView);-
1613 QStyleOptionViewItem opt = option;-
1614 const QPoint offset = d->scrollDelayOffset;-
1615 const int y = option.rect.y() + offset.y();-
1616 const QModelIndex parent = index.parent();-
1617 const QHeaderView *header = d->header;-
1618 const QModelIndex current = currentIndex();-
1619 const QModelIndex hover = d->hover;-
1620 const bool reverse = isRightToLeft();-
1621 const QStyle::State state = opt.state;-
1622 const bool spanning = d->spanning;-
1623 const int left = (spanning ? header->visualIndex(0) : d->leftAndRight.first);
spanningDescription
TRUEnever evaluated
FALSEnever evaluated
0
1624 const int right = (spanning ? header->visualIndex(0) : d->leftAndRight.second);
spanningDescription
TRUEnever evaluated
FALSEnever evaluated
0
1625 const bool alternate = d->alternatingColors;-
1626 const bool enabled = (state & QStyle::State_Enabled) != 0;-
1627 const bool allColumnsShowFocus = d->allColumnsShowFocus;-
1628-
1629-
1630 // when the row contains an index widget which has focus,-
1631 // we want to paint the entire row as active-
1632 bool indexWidgetHasFocus = false;-
1633 if ((current.row() == index.row()) && !d->editorIndexHash.isEmpty()) {
(current.row() == index.row())Description
TRUEnever evaluated
FALSEnever evaluated
!d->editorIndexHash.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1634 const int r = index.row();-
1635 QWidget *fw = QApplication::focusWidget();-
1636 for (int c = 0; c < header->count(); ++c) {
c < header->count()Description
TRUEnever evaluated
FALSEnever evaluated
0
1637 QModelIndex idx = d->model->index(r, c, parent);-
1638 if (QWidget *editor = indexWidget(idx)) {
QWidget *edito...dexWidget(idx)Description
TRUEnever evaluated
FALSEnever evaluated
0
1639 if (ancestorOf(editor, fw)) {
ancestorOf(editor, fw)Description
TRUEnever evaluated
FALSEnever evaluated
0
1640 indexWidgetHasFocus = true;-
1641 break;
never executed: break;
0
1642 }-
1643 }
never executed: end of block
0
1644 }
never executed: end of block
0
1645 }
never executed: end of block
0
1646-
1647 const bool widgetHasFocus = hasFocus();-
1648 bool currentRowHasFocus = false;-
1649 if (allColumnsShowFocus && widgetHasFocus && current.isValid()) {
allColumnsShowFocusDescription
TRUEnever evaluated
FALSEnever evaluated
widgetHasFocusDescription
TRUEnever evaluated
FALSEnever evaluated
current.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1650 // check if the focus index is before or after the visible columns-
1651 const int r = index.row();-
1652 for (int c = 0; c < left && !currentRowHasFocus; ++c) {
c < leftDescription
TRUEnever evaluated
FALSEnever evaluated
!currentRowHasFocusDescription
TRUEnever evaluated
FALSEnever evaluated
0
1653 QModelIndex idx = d->model->index(r, c, parent);-
1654 currentRowHasFocus = (idx == current);-
1655 }
never executed: end of block
0
1656 QModelIndex parent = d->model->parent(index);-
1657 for (int c = right; c < header->count() && !currentRowHasFocus; ++c) {
c < header->count()Description
TRUEnever evaluated
FALSEnever evaluated
!currentRowHasFocusDescription
TRUEnever evaluated
FALSEnever evaluated
0
1658 currentRowHasFocus = (d->model->index(r, c, parent) == current);-
1659 }
never executed: end of block
0
1660 }
never executed: end of block
0
1661-
1662 // ### special case: treeviews with multiple columns draw-
1663 // the selections differently than with only one column-
1664 opt.showDecorationSelected = (d->selectionBehavior & SelectRows)
(d->selectionB... & SelectRows)Description
TRUEnever evaluated
FALSEnever evaluated
0
1665 || option.showDecorationSelected;
option.showDecorationSelectedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1666-
1667 int width, height = option.rect.height();-
1668 int position;-
1669 QModelIndex modelIndex;-
1670 const bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows
selectionBehav...ew::SelectRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1671 && index.parent() == hover.parent()
index.parent()...hover.parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
1672 && index.row() == hover.row();
index.row() == hover.row()Description
TRUEnever evaluated
FALSEnever evaluated
0
1673-
1674 QVector<int> logicalIndices;-
1675 QVector<QStyleOptionViewItem::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex-
1676 d->calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);-
1677-
1678 for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.count(); ++currentLogicalSection) {
currentLogical...ndices.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
1679 int headerSection = logicalIndices.at(currentLogicalSection);-
1680 position = columnViewportPosition(headerSection) + offset.x();-
1681 width = header->sectionSize(headerSection);-
1682-
1683 if (spanning) {
spanningDescription
TRUEnever evaluated
FALSEnever evaluated
0
1684 int lastSection = header->logicalIndex(header->count() - 1);-
1685 if (!reverse) {
!reverseDescription
TRUEnever evaluated
FALSEnever evaluated
0
1686 width = columnViewportPosition(lastSection) + header->sectionSize(lastSection) - position;-
1687 } else {
never executed: end of block
0
1688 width += position - columnViewportPosition(lastSection);-
1689 position = columnViewportPosition(lastSection);-
1690 }
never executed: end of block
0
1691 }-
1692-
1693 modelIndex = d->model->index(index.row(), headerSection, parent);-
1694 if (!modelIndex.isValid())
!modelIndex.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
1695 continue;
never executed: continue;
0
1696 opt.state = state;-
1697-
1698 opt.viewItemPosition = viewItemPosList.at(currentLogicalSection);-
1699-
1700 // fake activeness when row editor has focus-
1701 if (indexWidgetHasFocus)
indexWidgetHasFocusDescription
TRUEnever evaluated
FALSEnever evaluated
0
1702 opt.state |= QStyle::State_Active;
never executed: opt.state |= QStyle::State_Active;
0
1703-
1704 if (d->selectionModel->isSelected(modelIndex))
d->selectionMo...ed(modelIndex)Description
TRUEnever evaluated
FALSEnever evaluated
0
1705 opt.state |= QStyle::State_Selected;
never executed: opt.state |= QStyle::State_Selected;
0
1706 if (widgetHasFocus && (current == modelIndex)) {
widgetHasFocusDescription
TRUEnever evaluated
FALSEnever evaluated
(current == modelIndex)Description
TRUEnever evaluated
FALSEnever evaluated
0
1707 if (allColumnsShowFocus)
allColumnsShowFocusDescription
TRUEnever evaluated
FALSEnever evaluated
0
1708 currentRowHasFocus = true;
never executed: currentRowHasFocus = true;
0
1709 else-
1710 opt.state |= QStyle::State_HasFocus;
never executed: opt.state |= QStyle::State_HasFocus;
0
1711 }-
1712 if ((opt.state.setFlag(QStyle::State_MouseOver,-
1713 (hoverRow || modelIndex == hover)-
1714 && (option.showDecorationSelected || (d->hoverBranch == -1)))-
opt.state |= QStyle::State_MouseOver;
else
opt.state &= ~QStyle::State_MouseOver;));
1715-
1716 if (enabled) {
enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1717 QPalette::ColorGroup cg;-
1718 if ((d->model->flags(modelIndex) & Qt::ItemIsEnabled) == 0) {
(d->model->fla...sEnabled) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1719 opt.state &= ~QStyle::State_Enabled;-
1720 cg = QPalette::Disabled;-
1721 } else if (opt.state & QStyle::State_Active) {
never executed: end of block
opt.state & QS...::State_ActiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
1722 cg = QPalette::Active;-
1723 } else {
never executed: end of block
0
1724 cg = QPalette::Inactive;-
1725 }
never executed: end of block
0
1726 opt.palette.setCurrentColorGroup(cg);-
1727 }
never executed: end of block
0
1728-
1729 if (alternate) {
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
0
if (d->current & 1
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
) {
alternateDescription
TRUEnever evaluated
FALSEnever evaluated
1730 opt.features|= QStyleOptionViewItem::Alternate;-
} else {
opt.features &= ~setFlag(QStyleOptionViewItem::Alternate;
}, d->current & 1);
1731 }
never executed: end of block
0
1732-
1733 /* Prior to Qt 4.3, the background of the branch (in selected state and-
1734 alternate row color was provided by the view. For backward compatibility,-
1735 this is now delegated to the style using PE_PanelViewItemRow which-
1736 does the appropriate fill */-
1737 if (d->isTreePosition(headerSection)) {
d->isTreePosit...headerSection)Description
TRUEnever evaluated
FALSEnever evaluated
0
1738 const int i = d->indentationForItem(d->current);-
1739 QRect branches(reverse ? position + width - i : position, y, i, height);-
1740 const bool setClipRect = branches.width() > width;-
1741 if (setClipRect) {
setClipRectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1742 painter->save();-
1743 painter->setClipRect(QRect(position, y, width, height));-
1744 }
never executed: end of block
0
1745 // draw background for the branch (selection + alternate row)-
1746 opt.rect = branches;-
1747 style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);-
1748-
1749 // draw background of the item (only alternate row). rest of the background-
1750 // is provided by the delegate-
1751 QStyle::State oldState = opt.state;-
1752 opt.state &= ~QStyle::State_Selected;-
1753 opt.rect.setRect(reverse ? position : i + position, y, width - i, height);-
1754 style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);-
1755 opt.state = oldState;-
1756-
1757 if (d->indent != 0)
d->indent != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1758 drawBranches(painter, branches, index);
never executed: drawBranches(painter, branches, index);
0
1759 if (setClipRect)
setClipRectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1760 painter->restore();
never executed: painter->restore();
0
1761 } else {
never executed: end of block
0
1762 QStyle::State oldState = opt.state;-
1763 opt.state &= ~QStyle::State_Selected;-
1764 opt.rect.setRect(position, y, width, height);-
1765 style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);-
1766 opt.state = oldState;-
1767 }
never executed: end of block
0
1768-
1769 d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);-
1770 }
never executed: end of block
0
1771-
1772 if (currentRowHasFocus) {
currentRowHasFocusDescription
TRUEnever evaluated
FALSEnever evaluated
0
1773 QStyleOptionFocusRect o;-
1774 o.QStyleOption::operator=(option);-
1775 o.state |= QStyle::State_KeyboardFocusChange;-
1776 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
(option.state ...State_Enabled)Description
TRUEnever evaluated
FALSEnever evaluated
0
1777 ? QPalette::Normal : QPalette::Disabled;-
1778 o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)-
1779 ? QPalette::Highlight : QPalette::Background);-
1780 int x = 0;-
1781 if (!option.showDecorationSelected)
!option.showDecorationSelectedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1782 x = header->sectionPosition(0) + d->indentationForItem(d->current);
never executed: x = header->sectionPosition(0) + d->indentationForItem(d->current);
0
1783 QRect focusRect(x - header->offset(), y, header->length() - x, height);-
1784 o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), focusRect);-
1785 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);-
1786 // if we show focus on all columns and the first section is moved,-
1787 // we have to split the focus rect into two rects-
1788 if (allColumnsShowFocus && !option.showDecorationSelected
allColumnsShowFocusDescription
TRUEnever evaluated
FALSEnever evaluated
!option.showDecorationSelectedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1789 && header->sectionsMoved() && (header->visualIndex(0) != 0)) {
header->sectionsMoved()Description
TRUEnever evaluated
FALSEnever evaluated
(header->visualIndex(0) != 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1790 QRect sectionRect(0, y, header->sectionPosition(0), height);-
1791 o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), sectionRect);-
1792 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);-
1793 }
never executed: end of block
0
1794 }
never executed: end of block
0
1795}
never executed: end of block
0
1796-
1797/*!-
1798 Draws the branches in the tree view on the same row as the model item-
1799 \a index, using the \a painter given. The branches are drawn in the-
1800 rectangle specified by \a rect.-
1801*/-
1802void QTreeView::drawBranches(QPainter *painter, const QRect &rect,-
1803 const QModelIndex &index) const-
1804{-
1805 Q_D(const QTreeView);-
1806 const bool reverse = isRightToLeft();-
1807 const int indent = d->indent;-
1808 const int outer = d->rootDecoration ? 0 : 1;
d->rootDecorationDescription
TRUEnever evaluated
FALSEnever evaluated
0
1809 const int item = d->current;-
1810 const QTreeViewItem &viewItem = d->viewItems.at(item);-
1811 int level = viewItem.level;-
1812 QRect primitive(reverse ? rect.left() : rect.right() + 1, rect.top(), indent, rect.height());-
1813-
1814 QModelIndex parent = index.parent();-
1815 QModelIndex current = parent;-
1816 QModelIndex ancestor = current.parent();-
1817-
1818 QStyleOptionViewItem opt = viewOptions();-
1819 QStyle::State extraFlags = QStyle::State_None;-
1820 if (isEnabled())
isEnabled()Description
TRUEnever evaluated
FALSEnever evaluated
0
1821 extraFlags |= QStyle::State_Enabled;
never executed: extraFlags |= QStyle::State_Enabled;
0
1822 if (window()->isActiveWindow())
window()->isActiveWindow()Description
TRUEnever evaluated
FALSEnever evaluated
0
1823 extraFlags |= QStyle::State_Active;
never executed: extraFlags |= QStyle::State_Active;
0
1824 QPoint oldBO = painter->brushOrigin();-
1825 if (verticalScrollMode() == QAbstractItemView::ScrollPerPixel)
verticalScroll...ScrollPerPixelDescription
TRUEnever evaluated
FALSEnever evaluated
0
1826 painter->setBrushOrigin(QPoint(0, verticalOffset()));
never executed: painter->setBrushOrigin(QPoint(0, verticalOffset()));
0
1827-
1828 if (d->alternatingColors) {
d->alternatingColorsDescription
TRUEnever evaluated
FALSEnever evaluated
0
if (d->current & 1
d->alternatingColorsDescription
TRUEnever evaluated
FALSEnever evaluated
) {
d->alternatingColorsDescription
TRUEnever evaluated
FALSEnever evaluated
1829 opt.features|= QStyleOptionViewItem::Alternate;-
} else {
opt.features &= ~setFlag(QStyleOptionViewItem::Alternate;
}, d->current & 1);
1830 }
never executed: end of block
0
1831-
1832 // When hovering over a row, pass State_Hover for painting the branch-
1833 // indicators if it has the decoration (aka branch) selected.-
1834 bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows
selectionBehav...ew::SelectRowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1835 && opt.showDecorationSelected
opt.showDecorationSelectedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1836 && index.parent() == d->hover.parent()
index.parent()...hover.parent()Description
TRUEnever evaluated
FALSEnever evaluated
0
1837 && index.row() == d->hover.row();
index.row() == d->hover.row()Description
TRUEnever evaluated
FALSEnever evaluated
0
1838-
1839 if (d->selectionModel->isSelected(index))
d->selectionMo...elected(index)Description
TRUEnever evaluated
FALSEnever evaluated
0
1840 extraFlags |= QStyle::State_Selected;
never executed: extraFlags |= QStyle::State_Selected;
0
1841-
1842 if (level >= outer) {
level >= outerDescription
TRUEnever evaluated
FALSEnever evaluated
0
1843 // start with the innermost branch-
1844 primitive.moveLeft(reverse ? primitive.left() : primitive.left() - indent);-
1845 opt.rect = primitive;-
1846-
1847 const bool expanded = viewItem.expanded;-
1848 const bool children = viewItem.hasChildren;-
1849 bool moreSiblings = viewItem.hasMoreSiblings;-
1850-
1851 opt.state = QStyle::State_Item | extraFlags-
1852 | (moreSiblings ? QStyle::State_Sibling : QStyle::State_None)-
1853 | (children ? QStyle::State_Children : QStyle::State_None)-
1854 | (expanded ? QStyle::State_Open : QStyle::State_None);-
1855 ifopt.state.setFlag(QStyle::State_MouseOver, hoverRow || item == d->hoverBranch)-
opt.state |= QStyle::State_MouseOver;
else
opt.state &= ~QStyle::State_MouseOver;);
1856-
1857 style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);-
1858 }
never executed: end of block
0
1859 // then go out level by level-
1860 for (--level; level >= outer; --level) { // we have already drawn the innermost branch
level >= outerDescription
TRUEnever evaluated
FALSEnever evaluated
0
1861 primitive.moveLeft(reverse ? primitive.left() + indent : primitive.left() - indent);-
1862 opt.rect = primitive;-
1863 opt.state = extraFlags;-
1864 bool moreSiblings = false;-
1865 if (d->hiddenIndexes.isEmpty()) {
d->hiddenIndexes.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1866 moreSiblings = (d->model->rowCount(ancestor) - 1 > current.row());-
1867 } else {
never executed: end of block
0
1868 int successor = item + viewItem.total + 1;-
1869 while (successor < d->viewItems.size()
successor < d-...ewItems.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1870 && d->viewItems.at(successor).level >= uint(level)) {
d->viewItems.a...>= uint(level)Description
TRUEnever evaluated
FALSEnever evaluated
0
1871 const QTreeViewItem &successorItem = d->viewItems.at(successor);-
1872 if (successorItem.level == uint(level)) {
successorItem....== uint(level)Description
TRUEnever evaluated
FALSEnever evaluated
0
1873 moreSiblings = true;-
1874 break;
never executed: break;
0
1875 }-
1876 successor += successorItem.total + 1;-
1877 }
never executed: end of block
0
1878 }
never executed: end of block
0
1879 if (moreSiblings)
moreSiblingsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1880 opt.state |= QStyle::State_Sibling;
never executed: opt.state |= QStyle::State_Sibling;
0
1881 ifopt.state.setFlag(QStyle::State_MouseOver, hoverRow || item == d->hoverBranch)-
opt.state |= QStyle::State_MouseOver;
else
opt.state &= ~QStyle::State_MouseOver;);
1882-
1883 style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);-
1884 current = ancestor;-
1885 ancestor = current.parent();-
1886 }
never executed: end of block
0
1887 painter->setBrushOrigin(oldBO);-
1888}
never executed: end of block
0
1889-
1890/*!-
1891 \reimp-
1892*/-
1893void QTreeView::mousePressEvent(QMouseEvent *event)-
1894{-
1895 Q_D(QTreeView);-
1896 bool handled = false;-
1897 if (style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, 0, this) == QEvent::MouseButtonPress)-
1898 handled = d->expandOrCollapseItemAtPos(event->pos());-
1899 if (!handled && d->itemDecorationAt(event->pos()) == -1)-
1900 QAbstractItemView::mousePressEvent(event);-
1901}-
1902-
1903/*!-
1904 \reimp-
1905*/-
1906void QTreeView::mouseReleaseEvent(QMouseEvent *event)-
1907{-
1908 Q_D(QTreeView);-
1909 if (d->itemDecorationAt(event->pos()) == -1) {-
1910 QAbstractItemView::mouseReleaseEvent(event);-
1911 } else {-
1912 if (state() == QAbstractItemView::DragSelectingState || state() == QAbstractItemView::DraggingState)-
1913 setState(QAbstractItemView::NoState);-
1914 if (style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, 0, this) == QEvent::MouseButtonRelease)-
1915 d->expandOrCollapseItemAtPos(event->pos());-
1916 }-
1917}-
1918-
1919/*!-
1920 \reimp-
1921*/-
1922void QTreeView::mouseDoubleClickEvent(QMouseEvent *event)-
1923{-
1924 Q_D(QTreeView);-
1925 if (state() != NoState || !d->viewport->rect().contains(event->pos()))-
1926 return;-
1927-
1928 int i = d->itemDecorationAt(event->pos());-
1929 if (i == -1) {-
1930 i = d->itemAtCoordinate(event->y());-
1931 if (i == -1)-
1932 return; // user clicked outside the items-
1933-
1934 const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index;-
1935 const QPersistentModelIndex persistent = indexAt(event->pos());-
1936-
1937 if (d->pressedIndex != persistent) {-
1938 mousePressEvent(event);-
1939 return;-
1940 }-
1941-
1942 // signal handlers may change the model-
1943 emit doubleClicked(persistent);-
1944-
1945 if (!persistent.isValid())-
1946 return;-
1947-
1948 if (edit(persistent, DoubleClicked, event) || state() != NoState)-
1949 return; // the double click triggered editing-
1950-
1951 if (!style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this))-
1952 emit activated(persistent);-
1953-
1954 d->executePostedLayout(); // we need to make sure viewItems is updated-
1955 if (d->itemsExpandable-
1956 && d->expandsOnDoubleClick-
1957 && d->hasVisibleChildren(persistent)) {-
1958 if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) {-
1959 // find the new index of the item-
1960 for (i = 0; i < d->viewItems.count(); ++i) {-
1961 if (d->viewItems.at(i).index == firstColumnIndex)-
1962 break;-
1963 }-
1964 if (i == d->viewItems.count())-
1965 return;-
1966 }-
1967 if (d->viewItems.at(i).expanded)-
1968 d->collapse(i, true);-
1969 else-
1970 d->expand(i, true);-
1971 updateGeometries();-
1972 viewport()->update();-
1973 }-
1974 }-
1975}-
1976-
1977/*!-
1978 \reimp-
1979*/-
1980void QTreeView::mouseMoveEvent(QMouseEvent *event)-
1981{-
1982 Q_D(QTreeView);-
1983 if (d->itemDecorationAt(event->pos()) == -1) // ### what about expanding/collapsing state ?-
1984 QAbstractItemView::mouseMoveEvent(event);-
1985}-
1986-
1987/*!-
1988 \reimp-
1989*/-
1990void QTreeView::keyPressEvent(QKeyEvent *event)-
1991{-
1992 Q_D(QTreeView);-
1993 QModelIndex current = currentIndex();-
1994 //this is the management of the expansion-
1995 if (d->isIndexValid(current) && d->model && d->itemsExpandable) {-
1996 switch (event->key()) {-
1997 case Qt::Key_Asterisk: {-
1998 QStack<QModelIndex> parents;-
1999 parents.push(current);-
2000 while (!parents.isEmpty()) {-
2001 QModelIndex parent = parents.pop();-
2002 for (int row = 0; row < d->model->rowCount(parent); ++row) {-
2003 QModelIndex child = d->model->index(row, 0, parent);-
2004 if (!d->isIndexValid(child))-
2005 break;-
2006 parents.push(child);-
2007 expand(child);-
2008 }-
2009 }-
2010 expand(current);-
2011 break; }-
2012 case Qt::Key_Plus:-
2013 expand(current);-
2014 break;-
2015 case Qt::Key_Minus:-
2016 collapse(current);-
2017 break;-
2018 }-
2019 }-
2020-
2021 QAbstractItemView::keyPressEvent(event);-
2022}-
2023-
2024/*!-
2025 \reimp-
2026*/-
2027QModelIndex QTreeView::indexAt(const QPoint &point) const-
2028{-
2029 Q_D(const QTreeView);-
2030 d->executePostedLayout();-
2031-
2032 int visualIndex = d->itemAtCoordinate(point.y());-
2033 QModelIndex idx = d->modelIndex(visualIndex);-
2034 if (!idx.isValid())-
2035 return QModelIndex();-
2036-
2037 if (d->viewItems.at(visualIndex).spanning)-
2038 return idx;-
2039-
2040 int column = d->columnAt(point.x());-
2041 if (column == idx.column())-
2042 return idx;-
2043 if (column < 0)-
2044 return QModelIndex();-
2045 return idx.sibling(idx.row(), column);-
2046}-
2047-
2048/*!-
2049 Returns the model index of the item above \a index.-
2050*/-
2051QModelIndex QTreeView::indexAbove(const QModelIndex &index) const-
2052{-
2053 Q_D(const QTreeView);-
2054 if (!d->isIndexValid(index))-
2055 return QModelIndex();-
2056 d->executePostedLayout();-
2057 int i = d->viewIndex(index);-
2058 if (--i < 0)-
2059 return QModelIndex();-
2060 const QModelIndex firstColumnIndex = d->viewItems.at(i).index;-
2061 return firstColumnIndex.sibling(firstColumnIndex.row(), index.column());-
2062}-
2063-
2064/*!-
2065 Returns the model index of the item below \a index.-
2066*/-
2067QModelIndex QTreeView::indexBelow(const QModelIndex &index) const-
2068{-
2069 Q_D(const QTreeView);-
2070 if (!d->isIndexValid(index))-
2071 return QModelIndex();-
2072 d->executePostedLayout();-
2073 int i = d->viewIndex(index);-
2074 if (++i >= d->viewItems.count())-
2075 return QModelIndex();-
2076 const QModelIndex firstColumnIndex = d->viewItems.at(i).index;-
2077 return firstColumnIndex.sibling(firstColumnIndex.row(), index.column());-
2078}-
2079-
2080/*!-
2081 \internal-
2082-
2083 Lays out the items in the tree view.-
2084*/-
2085void QTreeView::doItemsLayout()-
2086{-
2087 Q_D(QTreeView);-
2088 if (!d->customIndent) {-
2089 // ### Qt 6: move to event()-
2090 // QAbstractItemView calls this method in case of a style change,-
2091 // so update the indentation here if it wasn't set manually.-
2092 d->updateIndentationFromStyle();-
2093 }-
2094 if (d->hasRemovedItems) {-
2095 //clean the QSet that may contains old (and this invalid) indexes-
2096 d->hasRemovedItems = false;-
2097 QSet<QPersistentModelIndex>::iterator it = d->expandedIndexes.begin();-
2098 while (it != d->expandedIndexes.end()) {-
2099 if (!it->isValid())-
2100 it = d->expandedIndexes.erase(it);-
2101 else-
2102 ++it;-
2103 }-
2104 it = d->hiddenIndexes.begin();-
2105 while (it != d->hiddenIndexes.end()) {-
2106 if (!it->isValid())-
2107 it = d->hiddenIndexes.erase(it);-
2108 else-
2109 ++it;-
2110 }-
2111 }-
2112 d->viewItems.clear(); // prepare for new layout-
2113 QModelIndex parent = d->root;-
2114 if (d->model->hasChildren(parent)) {-
2115 d->layout(-1);-
2116 }-
2117 QAbstractItemView::doItemsLayout();-
2118 d->header->doItemsLayout();-
2119}-
2120-
2121/*!-
2122 \reimp-
2123*/-
2124void QTreeView::reset()-
2125{-
2126 Q_D(QTreeView);-
2127 d->expandedIndexes.clear();-
2128 d->hiddenIndexes.clear();-
2129 d->spanningIndexes.clear();-
2130 d->viewItems.clear();-
2131 QAbstractItemView::reset();-
2132}-
2133-
2134/*!-
2135 Returns the horizontal offset of the items in the treeview.-
2136-
2137 Note that the tree view uses the horizontal header section-
2138 positions to determine the positions of columns in the view.-
2139-
2140 \sa verticalOffset()-
2141*/-
2142int QTreeView::horizontalOffset() const-
2143{-
2144 Q_D(const QTreeView);-
2145 return d->header->offset();-
2146}-
2147-
2148/*!-
2149 Returns the vertical offset of the items in the tree view.-
2150-
2151 \sa horizontalOffset()-
2152*/-
2153int QTreeView::verticalOffset() const-
2154{-
2155 Q_D(const QTreeView);-
2156 if (d->verticalScrollMode == QAbstractItemView::ScrollPerItem) {-
2157 if (d->uniformRowHeights)-
2158 return verticalScrollBar()->value() * d->defaultItemHeight;-
2159 // If we are scrolling per item and have non-uniform row heights,-
2160 // finding the vertical offset in pixels is going to be relatively slow.-
2161 // ### find a faster way to do this-
2162 d->executePostedLayout();-
2163 int offset = 0;-
2164 for (int i = 0; i < d->viewItems.count(); ++i) {-
2165 if (i == verticalScrollBar()->value())-
2166 return offset;-
2167 offset += d->itemHeight(i);-
2168 }-
2169 return 0;-
2170 }-
2171 // scroll per pixel-
2172 return verticalScrollBar()->value();-
2173}-
2174-
2175/*!-
2176 Move the cursor in the way described by \a cursorAction, using the-
2177 information provided by the button \a modifiers.-
2178*/-
2179QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)-
2180{-
2181 Q_D(QTreeView);-
2182 Q_UNUSED(modifiers);-
2183-
2184 d->executePostedLayout();-
2185-
2186 QModelIndex current = currentIndex();-
2187 if (!current.isValid()) {-
2188 int i = d->below(-1);-
2189 int c = 0;-
2190 while (c < d->header->count() && d->header->isSectionHidden(d->header->logicalIndex(c)))-
2191 ++c;-
2192 if (i < d->viewItems.count() && c < d->header->count()) {-
2193 return d->modelIndex(i, d->header->logicalIndex(c));-
2194 }-
2195 return QModelIndex();-
2196 }-
2197 int vi = -1;-
2198#if defined(Q_DEAD_CODE_FROM_QT4_MAC) && !defined(QT_NO_STYLE_MAC)-
2199 // Selection behavior is slightly different on the Mac.-
2200 if (d->selectionMode == QAbstractItemView::ExtendedSelection-
2201 && d->selectionModel-
2202 && d->selectionModel->hasSelection()) {-
2203-
2204 const bool moveUpDown = (cursorAction == MoveUp || cursorAction == MoveDown);-
2205 const bool moveNextPrev = (cursorAction == MoveNext || cursorAction == MovePrevious);-
2206 const bool contiguousSelection = moveUpDown && (modifiers & Qt::ShiftModifier);-
2207-
2208 // Use the outermost index in the selection as the current index-
2209 if (!contiguousSelection && (moveUpDown || moveNextPrev)) {-
2210-
2211 // Find outermost index.-
2212 const bool useTopIndex = (cursorAction == MoveUp || cursorAction == MovePrevious);-
2213 int index = useTopIndex ? INT_MAX : INT_MIN;-
2214 const QItemSelection selection = d->selectionModel->selection();-
2215 for (int i = 0; i < selection.count(); ++i) {-
2216 const QItemSelectionRange &range = selection.at(i);-
2217 int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight());-
2218 if (candidate >= 0)-
2219 index = useTopIndex ? qMin(index, candidate) : qMax(index, candidate);-
2220 }-
2221-
2222 if (index >= 0 && index < INT_MAX)-
2223 vi = index;-
2224 }-
2225 }-
2226#endif-
2227 if (vi < 0)-
2228 vi = qMax(0, d->viewIndex(current));-
2229-
2230 if (isRightToLeft()) {-
2231 if (cursorAction == MoveRight)-
2232 cursorAction = MoveLeft;-
2233 else if (cursorAction == MoveLeft)-
2234 cursorAction = MoveRight;-
2235 }-
2236 switch (cursorAction) {-
2237 case MoveNext:-
2238 case MoveDown:-
2239#ifdef QT_KEYPAD_NAVIGATION-
2240 if (vi == d->viewItems.count()-1 && QApplication::keypadNavigationEnabled())-
2241 return d->model->index(0, current.column(), d->root);-
2242#endif-
2243 return d->modelIndex(d->below(vi), current.column());-
2244 case MovePrevious:-
2245 case MoveUp:-
2246#ifdef QT_KEYPAD_NAVIGATION-
2247 if (vi == 0 && QApplication::keypadNavigationEnabled())-
2248 return d->modelIndex(d->viewItems.count() - 1, current.column());-
2249#endif-
2250 return d->modelIndex(d->above(vi), current.column());-
2251 case MoveLeft: {-
2252 QScrollBar *sb = horizontalScrollBar();-
2253 if (vi < d->viewItems.count() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) {-
2254 d->collapse(vi, true);-
2255 d->moveCursorUpdatedView = true;-
2256 } else {-
2257 bool descend = style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, 0, this);-
2258 if (descend) {-
2259 QModelIndex par = current.parent();-
2260 if (par.isValid() && par != rootIndex())-
2261 return par;-
2262 else-
2263 descend = false;-
2264 }-
2265 if (!descend) {-
2266 if (d->selectionBehavior == SelectItems || d->selectionBehavior == SelectColumns) {-
2267 int visualColumn = d->header->visualIndex(current.column()) - 1;-
2268 while (visualColumn >= 0 && isColumnHidden(d->header->logicalIndex(visualColumn)))-
2269 visualColumn--;-
2270 int newColumn = d->header->logicalIndex(visualColumn);-
2271 QModelIndex next = current.sibling(current.row(), newColumn);-
2272 if (next.isValid())-
2273 return next;-
2274 }-
2275-
2276 int oldValue = sb->value();-
2277 sb->setValue(sb->value() - sb->singleStep());-
2278 if (oldValue != sb->value())-
2279 d->moveCursorUpdatedView = true;-
2280 }-
2281-
2282 }-
2283 updateGeometries();-
2284 viewport()->update();-
2285 break;-
2286 }-
2287 case MoveRight:-
2288 if (vi < d->viewItems.count() && !d->viewItems.at(vi).expanded && d->itemsExpandable-
2289 && d->hasVisibleChildren(d->viewItems.at(vi).index)) {-
2290 d->expand(vi, true);-
2291 d->moveCursorUpdatedView = true;-
2292 } else {-
2293 bool descend = style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, 0, this);-
2294 if (descend) {-
2295 QModelIndex idx = d->modelIndex(d->below(vi));-
2296 if (idx.parent() == current)-
2297 return idx;-
2298 else-
2299 descend = false;-
2300 }-
2301 if (!descend) {-
2302 if (d->selectionBehavior == SelectItems || d->selectionBehavior == SelectColumns) {-
2303 int visualColumn = d->header->visualIndex(current.column()) + 1;-
2304 while (visualColumn < d->model->columnCount(current.parent()) && isColumnHidden(d->header->logicalIndex(visualColumn)))-
2305 visualColumn++;-
2306 const int newColumn = d->header->logicalIndex(visualColumn);-
2307 const QModelIndex next = current.sibling(current.row(), newColumn);-
2308 if (next.isValid())-
2309 return next;-
2310 }-
2311-
2312 //last restort: we change the scrollbar value-
2313 QScrollBar *sb = horizontalScrollBar();-
2314 int oldValue = sb->value();-
2315 sb->setValue(sb->value() + sb->singleStep());-
2316 if (oldValue != sb->value())-
2317 d->moveCursorUpdatedView = true;-
2318 }-
2319 }-
2320 updateGeometries();-
2321 viewport()->update();-
2322 break;-
2323 case MovePageUp:-
2324 return d->modelIndex(d->pageUp(vi), current.column());-
2325 case MovePageDown:-
2326 return d->modelIndex(d->pageDown(vi), current.column());-
2327 case MoveHome:-
2328 return d->model->index(0, current.column(), d->root);-
2329 case MoveEnd:-
2330 return d->modelIndex(d->viewItems.count() - 1, current.column());-
2331 }-
2332 return current;-
2333}-
2334-
2335/*!-
2336 Applies the selection \a command to the items in or touched by the-
2337 rectangle, \a rect.-
2338-
2339 \sa selectionCommand()-
2340*/-
2341void QTreeView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)-
2342{-
2343 Q_D(QTreeView);-
2344 if (!selectionModel() || rect.isNull())
!selectionModel()Description
TRUEnever evaluated
FALSEnever evaluated
rect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
2345 return;
never executed: return;
0
2346-
2347 d->executePostedLayout();-
2348 QPoint tl(isRightToLeft() ? qMax(rect.left(), rect.right())-
2349 : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom()));-
2350 QPoint br(isRightToLeft() ? qMin(rect.left(), rect.right()) :-
2351 qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom()));-
2352 QModelIndex topLeft = indexAt(tl);-
2353 QModelIndex bottomRight = indexAt(br);-
2354 if (!topLeft.isValid() && !bottomRight.isValid()) {
!topLeft.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
!bottomRight.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
2355 if (command & QItemSelectionModel::Clear)
command & QIte...onModel::ClearDescription
TRUEnever evaluated
FALSEnever evaluated
0
2356 selectionModel()->clear();
never executed: selectionModel()->clear();
0
2357 return;
never executed: return;
0
2358 }-
2359 if (!topLeft.isValid() && !d->viewItems.isEmpty())
!topLeft.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
!d->viewItems.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2360 topLeft = d->viewItems.firstconstFirst().index;
never executed: topLeft = d->viewItems.constFirst().index;
0
2361 if (!bottomRight.isValid() && !d->viewItems.isEmpty()) {
!bottomRight.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
!d->viewItems.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2362 const int column = d->header->logicalIndex(d->header->count() - 1);-
2363 const QModelIndex index = d->viewItems.lastconstLast().index;-
2364 bottomRight = index.sibling(index.row(), column);-
2365 }
never executed: end of block
0
2366-
2367 if (!d->isIndexEnabled(topLeft) || !d->isIndexEnabled(bottomRight))
!d->isIndexEnabled(topLeft)Description
TRUEnever evaluated
FALSEnever evaluated
!d->isIndexEna...d(bottomRight)Description
TRUEnever evaluated
FALSEnever evaluated
0
2368 return;
never executed: return;
0
2369-
2370 d->select(topLeft, bottomRight, command);-
2371}
never executed: end of block
0
2372-
2373/*!-
2374 Returns the rectangle from the viewport of the items in the given-
2375 \a selection.-
2376-
2377 Since 4.7, the returned region only contains rectangles intersecting-
2378 (or included in) the viewport.-
2379*/-
2380QRegion QTreeView::visualRegionForSelection(const QItemSelection &selection) const-
2381{-
2382 Q_D(const QTreeView);-
2383 if (selection.isEmpty())
selection.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2384 return QRegion();
never executed: return QRegion();
0
2385-
2386 QRegion selectionRegion;-
2387 const QRect &viewportRect = d->viewport->rect();-
2388 for (int i = 0; i <const auto &range : selection.count(); ++i) {-
2389 QItemSelectionRange range = selection.at(i);if (!range.isValid())
!range.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
2390 continue;
never executed: continue;
0
2391 QModelIndex parent = range.parent();-
2392 QModelIndex leftIndex = range.topLeft();-
2393 int columnCount = d->model->columnCount(parent);-
2394 while (leftIndex.isValid() && isIndexHidden(leftIndex)) {
leftIndex.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
isIndexHidden(leftIndex)Description
TRUEnever evaluated
FALSEnever evaluated
0
2395 if (leftIndex.column() + 1 < columnCount)
leftIndex.colu... < columnCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
2396 leftIndex = d->model->index(leftIndex.row(), leftIndex.column() + 1, parent);
never executed: leftIndex = d->model->index(leftIndex.row(), leftIndex.column() + 1, parent);
0
2397 else-
2398 leftIndex = QModelIndex();
never executed: leftIndex = QModelIndex();
0
2399 }-
2400 if (!leftIndex.isValid())
!leftIndex.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
2401 continue;
never executed: continue;
0
2402 const QRect leftRect = visualRect(leftIndex);-
2403 int top = leftRect.top();-
2404 QModelIndex rightIndex = range.bottomRight();-
2405 while (rightIndex.isValid() && isIndexHidden(rightIndex)) {
rightIndex.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
isIndexHidden(rightIndex)Description
TRUEnever evaluated
FALSEnever evaluated
0
2406 if (rightIndex.column() - 1 >= 0)
rightIndex.column() - 1 >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2407 rightIndex = d->model->index(rightIndex.row(), rightIndex.column() - 1, parent);
never executed: rightIndex = d->model->index(rightIndex.row(), rightIndex.column() - 1, parent);
0
2408 else-
2409 rightIndex = QModelIndex();
never executed: rightIndex = QModelIndex();
0
2410 }-
2411 if (!rightIndex.isValid())
!rightIndex.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
2412 continue;
never executed: continue;
0
2413 const QRect rightRect = visualRect(rightIndex);-
2414 int bottom = rightRect.bottom();-
2415 if (top > bottom)
top > bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
2416 qSwap<int>(top, bottom);
never executed: qSwap<int>(top, bottom);
0
2417 int height = bottom - top + 1;-
2418 if (d->header->sectionsMoved()) {
d->header->sectionsMoved()Description
TRUEnever evaluated
FALSEnever evaluated
0
2419 for (int c = range.left(); c <= range.right(); ++c) {
c <= range.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2420 const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);-
2421 if (viewportRect.intersects(rangeRect))
viewportRect.i...cts(rangeRect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2422 selectionRegion += rangeRect;
never executed: selectionRegion += rangeRect;
0
2423 }
never executed: end of block
0
2424 } else {
never executed: end of block
0
2425 QRect combined = leftRect|rightRect;-
2426 combined.setX(columnViewportPosition(isRightToLeft() ? range.right() : range.left()));-
2427 if (viewportRect.intersects(combined))
viewportRect.i...ects(combined)Description
TRUEnever evaluated
FALSEnever evaluated
0
2428 selectionRegion += combined;
never executed: selectionRegion += combined;
0
2429 }
never executed: end of block
0
2430 }-
2431 return selectionRegion;
never executed: return selectionRegion;
0
2432}-
2433-
2434/*!-
2435 \reimp-
2436*/-
2437QModelIndexList QTreeView::selectedIndexes() const-
2438{-
2439 QModelIndexList viewSelected;-
2440 QModelIndexList modelSelected;-
2441 if (selectionModel())-
2442 modelSelected = selectionModel()->selectedIndexes();-
2443 for (int i = 0; i < modelSelected.count(); ++i) {-
2444 // check that neither the parents nor the index is hidden before we add-
2445 QModelIndex index = modelSelected.at(i);-
2446 while (index.isValid() && !isIndexHidden(index))-
2447 index = index.parent();-
2448 if (index.isValid())-
2449 continue;-
2450 viewSelected.append(modelSelected.at(i));-
2451 }-
2452 return viewSelected;-
2453}-
2454-
2455/*!-
2456 Scrolls the contents of the tree view by (\a dx, \a dy).-
2457*/-
2458void QTreeView::scrollContentsBy(int dx, int dy)-
2459{-
2460 Q_D(QTreeView);-
2461-
2462 d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling-
2463-
2464 dx = isRightToLeft() ? -dx : dx;-
2465 if (dx) {-
2466 int oldOffset = d->header->offset();-
2467 d->header->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode());-
2468 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {-
2469 int newOffset = d->header->offset();-
2470 dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;-
2471 }-
2472 }-
2473-
2474 const int itemHeight = d->defaultItemHeight <= 0 ? sizeHintForRow(0) : d->defaultItemHeight;-
2475 if (d->viewItems.isEmpty() || itemHeight == 0)-
2476 return;-
2477-
2478 // guestimate the number of items in the viewport-
2479 int viewCount = d->viewport->height() / itemHeight;-
2480 int maxDeltaY = qMin(d->viewItems.count(), viewCount);-
2481 // no need to do a lot of work if we are going to redraw the whole thing anyway-
2482 if (qAbs(dy) > qAbs(maxDeltaY) && d->editorIndexHash.isEmpty()) {-
2483 verticalScrollBar()->update();-
2484 d->viewport->update();-
2485 return;-
2486 }-
2487-
2488 if (dy && verticalScrollMode() == QAbstractItemView::ScrollPerItem) {-
2489 int currentScrollbarValue = verticalScrollBar()->value();-
2490 int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy)-
2491 int currentViewIndex = currentScrollbarValue; // the first visible item-
2492 int previousViewIndex = previousScrollbarValue;-
2493 const QVector<QTreeViewItem> viewItems = d->viewItems;-
2494 dy = 0;-
2495 if (previousViewIndex < currentViewIndex) { // scrolling down-
2496 for (int i = previousViewIndex; i < currentViewIndex; ++i) {-
2497 if (i < d->viewItems.count())-
2498 dy -= d->itemHeight(i);-
2499 }-
2500 } else if (previousViewIndex > currentViewIndex) { // scrolling up-
2501 for (int i = previousViewIndex - 1; i >= currentViewIndex; --i) {-
2502 if (i < d->viewItems.count())-
2503 dy += d->itemHeight(i);-
2504 }-
2505 }-
2506 }-
2507-
2508 d->scrollContentsBy(dx, dy);-
2509}-
2510-
2511/*!-
2512 This slot is called whenever a column has been moved.-
2513*/-
2514void QTreeView::columnMoved()-
2515{-
2516 Q_D(QTreeView);-
2517 updateEditorGeometries();-
2518 d->viewport->update();-
2519}-
2520-
2521/*!-
2522 \internal-
2523*/-
2524void QTreeView::reexpand()-
2525{-
2526 // do nothing-
2527}-
2528-
2529/*!-
2530 Informs the view that the rows from the \a start row to the \a end row-
2531 inclusive have been inserted into the \a parent model item.-
2532*/-
2533void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)-
2534{-
2535 Q_D(QTreeView);-
2536 // if we are going to do a complete relayout anyway, there is no need to update-
2537 if (d->delayedPendingLayout) {-
2538 QAbstractItemView::rowsInserted(parent, start, end);-
2539 return;-
2540 }-
2541-
2542 //don't add a hierarchy on a column != 0-
2543 if (parent.column() != 0 && parent.isValid()) {-
2544 QAbstractItemView::rowsInserted(parent, start, end);-
2545 return;-
2546 }-
2547-
2548 const int parentRowCount = d->model->rowCount(parent);-
2549 const int delta = end - start + 1;-
2550 if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) {-
2551 QAbstractItemView::rowsInserted(parent, start, end);-
2552 return;-
2553 }-
2554-
2555 const int parentItem = d->viewIndex(parent);-
2556 if (((parentItem != -1) && d->viewItems.at(parentItem).expanded)-
2557 || (parent == d->root)) {-
2558 d->doDelayedItemsLayout();-
2559 } else if (parentItem != -1 && parentRowCount == delta) {-
2560 // the parent just went from 0 children to more. update to re-paint the decoration-
2561 d->viewItems[parentItem].hasChildren = true;-
2562 viewport()->update();-
2563 }-
2564 QAbstractItemView::rowsInserted(parent, start, end);-
2565}-
2566-
2567/*!-
2568 Informs the view that the rows from the \a start row to the \a end row-
2569 inclusive are about to removed from the given \a parent model item.-
2570*/-
2571void QTreeView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)-
2572{-
2573 Q_D(QTreeView);-
2574 QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);-
2575 d->viewItems.clear();-
2576}-
2577-
2578/*!-
2579 \since 4.1-
2580-
2581 Informs the view that the rows from the \a start row to the \a end row-
2582 inclusive have been removed from the given \a parent model item.-
2583*/-
2584void QTreeView::rowsRemoved(const QModelIndex &parent, int start, int end)-
2585{-
2586 Q_D(QTreeView);-
2587 d->viewItems.clear();-
2588 d->doDelayedItemsLayout();-
2589 d->hasRemovedItems = true;-
2590 d->_q_rowsRemoved(parent, start, end);-
2591}-
2592-
2593/*!-
2594 Informs the tree view that the number of columns in the tree view has-
2595 changed from \a oldCount to \a newCount.-
2596*/-
2597void QTreeView::columnCountChanged(int oldCount, int newCount)-
2598{-
2599 Q_D(QTreeView);-
2600 if (oldCount == 0 && newCount > 0) {-
2601 //if the first column has just been added we need to relayout.-
2602 d->doDelayedItemsLayout();-
2603 }-
2604-
2605 if (isVisible())-
2606 updateGeometries();-
2607 viewport()->update();-
2608}-
2609-
2610/*!-
2611 Resizes the \a column given to the size of its contents.-
2612-
2613 \sa columnWidth(), setColumnWidth(), sizeHintForColumn(), QHeaderView::resizeContentsPrecision()-
2614*/-
2615void QTreeView::resizeColumnToContents(int column)-
2616{-
2617 Q_D(QTreeView);-
2618 d->executePostedLayout();-
2619 if (column < 0 || column >= d->header->count())-
2620 return;-
2621 int contents = sizeHintForColumn(column);-
2622 int header = d->header->isHidden() ? 0 : d->header->sectionSizeHint(column);-
2623 d->header->resizeSection(column, qMax(contents, header));-
2624}-
2625-
2626/*!-
2627 \obsolete-
2628 \overload-
2629-
2630 Sorts the model by the values in the given \a column.-
2631*/-
2632void QTreeView::sortByColumn(int column)-
2633{-
2634 Q_D(QTreeView);-
2635 sortByColumn(column, d->header->sortIndicatorOrder());-
2636}-
2637-
2638/*!-
2639 \since 4.2-
2640-
2641 Sets the model up for sorting by the values in the given \a column and \a order.-
2642-
2643 \a column may be -1, in which case no sort indicator will be shown-
2644 and the model will return to its natural, unsorted order. Note that not-
2645 all models support this and may even crash in this case.-
2646-
2647 \sa sortingEnabled-
2648*/-
2649void QTreeView::sortByColumn(int column, Qt::SortOrder order)-
2650{-
2651 Q_D(QTreeView);-
2652-
2653 //If sorting is enabled will emit a signal connected to _q_sortIndicatorChanged, which then actually sorts-
2654 d->header->setSortIndicator(column, order);-
2655 //If sorting is not enabled, force to sort now.-
2656 if (!d->sortingEnabled)-
2657 d->model->sort(column, order);-
2658}-
2659-
2660/*!-
2661 \reimp-
2662*/-
2663void QTreeView::selectAll()-
2664{-
2665 Q_D(QTreeView);-
2666 if (!selectionModel())
!selectionModel()Description
TRUEnever evaluated
FALSEnever evaluated
0
2667 return;
never executed: return;
0
2668 SelectionMode mode = d->selectionMode;-
2669 d->executePostedLayout(); //make sure we lay out the items-
2670 if (mode != SingleSelection && mode != NoSelection && !d->viewItems.isEmpty()) {
mode != SingleSelectionDescription
TRUEnever evaluated
FALSEnever evaluated
mode != NoSelectionDescription
TRUEnever evaluated
FALSEnever evaluated
!d->viewItems.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2671 const QModelIndex &idx = d->viewItems.lastconstLast().index;-
2672 QModelIndex lastItemIndex = idx.sibling(idx.row(), d->model->columnCount(idx.parent()) - 1);-
2673 d->select(d->viewItems.firstconstFirst().index, lastItemIndex,-
2674 QItemSelectionModel::ClearAndSelect-
2675 |QItemSelectionModel::Rows);-
2676 }
never executed: end of block
0
2677}
never executed: end of block
0
2678-
2679/*!-
2680 \reimp-
2681*/-
2682QSize QTreeView::viewportSizeHint() const-
2683{-
2684 Q_D(const QTreeView);-
2685 d->executePostedLayout(); // Make sure that viewItems are up to date.-
2686-
2687 if (d->viewItems.size() == 0)-
2688 return QAbstractItemView::viewportSizeHint();-
2689-
2690 // Get rect for last item-
2691 const QRect deepestRect = visualRect(d->viewItems.last().index);-
2692-
2693 if (!deepestRect.isValid())-
2694 return QAbstractItemView::viewportSizeHint();-
2695-
2696 QSize result = QSize(d->header->length(), deepestRect.bottom() + 1);-
2697-
2698 // add size for header-
2699 result += QSize(0, d->header->isVisible() ? d->header->height() : 0);-
2700-
2701 // add size for scrollbars-
2702 result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,-
2703 horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);-
2704-
2705 return result;-
2706}-
2707-
2708/*!-
2709 \since 4.2-
2710 Expands all expandable items.-
2711-
2712 Warning: if the model contains a large number of items,-
2713 this function will take some time to execute.-
2714-
2715 \sa collapseAll(), expand(), collapse(), setExpanded()-
2716*/-
2717void QTreeView::expandAll()-
2718{-
2719 Q_D(QTreeView);-
2720 d->viewItems.clear();-
2721 d->interruptDelayedItemsLayout();-
2722 d->layout(-1, true);-
2723 updateGeometries();-
2724 d->viewport->update();-
2725}-
2726-
2727/*!-
2728 \since 4.2-
2729-
2730 Collapses all expanded items.-
2731-
2732 \sa expandAll(), expand(), collapse(), setExpanded()-
2733*/-
2734void QTreeView::collapseAll()-
2735{-
2736 Q_D(QTreeView);-
2737 QSet<QPersistentModelIndex> old_expandedIndexes;-
2738 old_expandedIndexes = d->expandedIndexes;-
2739 d->expandedIndexes.clear();-
2740 if (!signalsBlocked() && isSignalConnected(QMetaMethod::fromSignal(&QTreeView::collapsed))) {-
2741 QSet<QPersistentModelIndex>::const_iterator i = old_expandedIndexes.constBegin();-
2742 for (; i != old_expandedIndexes.constEnd(); ++i) {-
2743 const QPersistentModelIndex &mi = (*i);-
2744 if (mi.isValid() && !(mi.flags() & Qt::ItemNeverHasChildren))-
2745 emit collapsed(mi);-
2746 }-
2747 }-
2748 doItemsLayout();-
2749}-
2750-
2751/*!-
2752 \since 4.3-
2753 Expands all expandable items to the given \a depth.-
2754-
2755 \sa expandAll(), collapseAll(), expand(), collapse(), setExpanded()-
2756*/-
2757void QTreeView::expandToDepth(int depth)-
2758{-
2759 Q_D(QTreeView);-
2760 d->viewItems.clear();-
2761 QSet<QPersistentModelIndex> old_expandedIndexes;-
2762 old_expandedIndexes = d->expandedIndexes;-
2763 d->expandedIndexes.clear();-
2764 d->interruptDelayedItemsLayout();-
2765 d->layout(-1);-
2766 for (int i = 0; i < d->viewItems.count(); ++i) {-
2767 if (d->viewItems.at(i).level <= (uint)depth) {-
2768 d->viewItems[i].expanded = true;-
2769 d->layout(i);-
2770 d->storeExpanded(d->viewItems.at(i).index);-
2771 }-
2772 }-
2773-
2774 bool someSignalEnabled = isSignalConnected(QMetaMethod::fromSignal(&QTreeView::collapsed));-
2775 someSignalEnabled |= isSignalConnected(QMetaMethod::fromSignal(&QTreeView::expanded));-
2776-
2777 if (!signalsBlocked() && someSignalEnabled) {-
2778 // emit signals-
2779 QSet<QPersistentModelIndex> collapsedIndexes = old_expandedIndexes - d->expandedIndexes;-
2780 QSet<QPersistentModelIndex>::const_iterator i = collapsedIndexes.constBegin();-
2781 for (; i != collapsedIndexes.constEnd(); ++i) {-
2782 const QPersistentModelIndex &mi = (*i);-
2783 if (mi.isValid() && !(mi.flags() & Qt::ItemNeverHasChildren))-
2784 emit collapsed(mi);-
2785 }-
2786-
2787 QSet<QPersistentModelIndex> expandedIndexs = d->expandedIndexes - old_expandedIndexes;-
2788 i = expandedIndexs.constBegin();-
2789 for (; i != expandedIndexs.constEnd(); ++i) {-
2790 const QPersistentModelIndex &mi = (*i);-
2791 if (mi.isValid() && !(mi.flags() & Qt::ItemNeverHasChildren))-
2792 emit expanded(mi);-
2793 }-
2794 }-
2795-
2796 updateGeometries();-
2797 d->viewport->update();-
2798}-
2799-
2800/*!-
2801 This function is called whenever \a{column}'s size is changed in-
2802 the header. \a oldSize and \a newSize give the previous size and-
2803 the new size in pixels.-
2804-
2805 \sa setColumnWidth()-
2806*/-
2807void QTreeView::columnResized(int column, int /* oldSize */, int /* newSize */)-
2808{-
2809 Q_D(QTreeView);-
2810 d->columnsToUpdate.append(column);-
2811 if (d->columnResizeTimerID == 0)-
2812 d->columnResizeTimerID = startTimer(0);-
2813}-
2814-
2815/*!-
2816 \reimp-
2817*/-
2818void QTreeView::updateGeometries()-
2819{-
2820 Q_D(QTreeView);-
2821 if (d->header) {-
2822 if (d->geometryRecursionBlock)-
2823 return;-
2824 d->geometryRecursionBlock = true;-
2825 int height = 0;-
2826 if (!d->header->isHidden()) {-
2827 height = qMax(d->header->minimumHeight(), d->header->sizeHint().height());-
2828 height = qMin(height, d->header->maximumHeight());-
2829 }-
2830 setViewportMargins(0, height, 0, 0);-
2831 QRect vg = d->viewport->geometry();-
2832 QRect geometryRect(vg.left(), vg.top() - height, vg.width(), height);-
2833 d->header->setGeometry(geometryRect);-
2834 QMetaObject::invokeMethod(d->header, "updateGeometries");-
2835 d->updateScrollBars();-
2836 d->geometryRecursionBlock = false;-
2837 }-
2838 QAbstractItemView::updateGeometries();-
2839}-
2840-
2841/*!-
2842 Returns the size hint for the \a column's width or -1 if there is no-
2843 model.-
2844-
2845 If you need to set the width of a given column to a fixed value, call-
2846 QHeaderView::resizeSection() on the view's header.-
2847-
2848 If you reimplement this function in a subclass, note that the value you-
2849 return is only used when resizeColumnToContents() is called. In that case,-
2850 if a larger column width is required by either the view's header or-
2851 the item delegate, that width will be used instead.-
2852-
2853 \sa QWidget::sizeHint, header(), QHeaderView::resizeContentsPrecision()-
2854*/-
2855int QTreeView::sizeHintForColumn(int column) const-
2856{-
2857 Q_D(const QTreeView);-
2858 d->executePostedLayout();-
2859 if (d->viewItems.isEmpty())-
2860 return -1;-
2861 ensurePolished();-
2862 int w = 0;-
2863 QStyleOptionViewItem option = d->viewOptionsV1();-
2864 const QVector<QTreeViewItem> viewItems = d->viewItems;-
2865-
2866 const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.-
2867-
2868 int offset = 0;-
2869 int start = d->firstVisibleItem(&offset);-
2870 int end = d->lastVisibleItem(start, offset);-
2871 if (start < 0 || end < 0 || end == viewItems.size() - 1) {-
2872 end = viewItems.size() - 1;-
2873 if (maximumProcessRows < 0) {-
2874 start = 0;-
2875 } else if (maximumProcessRows == 0) {-
2876 start = qMax(0, end - 1);-
2877 int remainingHeight = viewport()->height();-
2878 while (start > 0 && remainingHeight > 0) {-
2879 remainingHeight -= d->itemHeight(start);-
2880 --start;-
2881 }-
2882 } else {-
2883 start = qMax(0, end - maximumProcessRows);-
2884 }-
2885 }-
2886-
2887 int rowsProcessed = 0;-
2888-
2889 for (int i = start; i <= end; ++i) {-
2890 if (viewItems.at(i).spanning)-
2891 continue; // we have no good size hint-
2892 QModelIndex index = viewItems.at(i).index;-
2893 index = index.sibling(index.row(), column);-
2894 w = d->widthHintForIndex(index, w, option, i);-
2895 ++rowsProcessed;-
2896 if (rowsProcessed == maximumProcessRows)-
2897 break;-
2898 }-
2899-
2900 --end;-
2901 int actualBottom = viewItems.size() - 1;-
2902-
2903 if (maximumProcessRows == 0)-
2904 rowsProcessed = 0; // skip the while loop-
2905-
2906 while (rowsProcessed != maximumProcessRows && (start > 0 || end < actualBottom)) {-
2907 int idx = -1;-
2908-
2909 if ((rowsProcessed % 2 && start > 0) || end == actualBottom) {-
2910 while (start > 0) {-
2911 --start;-
2912 if (viewItems.at(start).spanning)-
2913 continue;-
2914 idx = start;-
2915 break;-
2916 }-
2917 } else {-
2918 while (end < actualBottom) {-
2919 ++end;-
2920 if (viewItems.at(end).spanning)-
2921 continue;-
2922 idx = end;-
2923 break;-
2924 }-
2925 }-
2926 if (idx < 0)-
2927 continue;-
2928-
2929 QModelIndex index = viewItems.at(idx).index;-
2930 index = index.sibling(index.row(), column);-
2931 w = d->widthHintForIndex(index, w, option, idx);-
2932 ++rowsProcessed;-
2933 }-
2934 return w;-
2935}-
2936-
2937/*!-
2938 Returns the size hint for the row indicated by \a index.-
2939-
2940 \sa sizeHintForColumn(), uniformRowHeights()-
2941*/-
2942int QTreeView::indexRowSizeHint(const QModelIndex &index) const-
2943{-
2944 Q_D(const QTreeView);-
2945 if (!d->isIndexValid(index) || !d->itemDelegate)-
2946 return 0;-
2947-
2948 int start = -1;-
2949 int end = -1;-
2950 int indexRow = index.row();-
2951 int count = d->header->count();-
2952 bool emptyHeader = (count == 0);-
2953 QModelIndex parent = index.parent();-
2954-
2955 if (count && isVisible()) {-
2956 // If the sections have moved, we end up checking too many or too few-
2957 start = d->header->visualIndexAt(0);-
2958 } else {-
2959 // If the header has not been laid out yet, we use the model directly-
2960 count = d->model->columnCount(parent);-
2961 }-
2962-
2963 if (isRightToLeft()) {-
2964 start = (start == -1 ? count - 1 : start);-
2965 end = 0;-
2966 } else {-
2967 start = (start == -1 ? 0 : start);-
2968 end = count - 1;-
2969 }-
2970-
2971 if (end < start)-
2972 qSwap(end, start);-
2973-
2974 int height = -1;-
2975 QStyleOptionViewItem option = d->viewOptionsV1();-
2976 // ### If we want word wrapping in the items,-
2977 // ### we need to go through all the columns-
2978 // ### and set the width of the column-
2979-
2980 // Hack to speed up the function-
2981 option.rect.setWidth(-1);-
2982-
2983 for (int column = start; column <= end; ++column) {-
2984 int logicalColumn = emptyHeader ? column : d->header->logicalIndex(column);-
2985 if (d->header->isSectionHidden(logicalColumn))-
2986 continue;-
2987 QModelIndex idx = d->model->index(indexRow, logicalColumn, parent);-
2988 if (idx.isValid()) {-
2989 QWidget *editor = d->editorForIndex(idx).widget.data();-
2990 if (editor && d->persistent.contains(editor)) {-
2991 height = qMax(height, editor->sizeHint().height());-
2992 int min = editor->minimumSize().height();-
2993 int max = editor->maximumSize().height();-
2994 height = qBound(min, height, max);-
2995 }-
2996 int hint = d->delegateForIndex(idx)->sizeHint(option, idx).height();-
2997 height = qMax(height, hint);-
2998 }-
2999 }-
3000-
3001 return height;-
3002}-
3003-
3004/*!-
3005 \since 4.3-
3006 Returns the height of the row indicated by the given \a index.-
3007 \sa indexRowSizeHint()-
3008*/-
3009int QTreeView::rowHeight(const QModelIndex &index) const-
3010{-
3011 Q_D(const QTreeView);-
3012 d->executePostedLayout();-
3013 int i = d->viewIndex(index);-
3014 if (i == -1)-
3015 return 0;-
3016 return d->itemHeight(i);-
3017}-
3018-
3019/*!-
3020 \internal-
3021*/-
3022void QTreeView::horizontalScrollbarAction(int action)-
3023{-
3024 QAbstractItemView::horizontalScrollbarAction(action);-
3025}-
3026-
3027/*!-
3028 \reimp-
3029*/-
3030bool QTreeView::isIndexHidden(const QModelIndex &index) const-
3031{-
3032 return (isColumnHidden(index.column()) || isRowHidden(index.row(), index.parent()));-
3033}-
3034-
3035/*-
3036 private implementation-
3037*/-
3038void QTreeViewPrivate::initialize()-
3039{-
3040 Q_Q(QTreeView);-
3041-
3042 updateIndentationFromStyle();-
3043 updateStyledFrameWidths();-
3044 q->setSelectionBehavior(QAbstractItemView::SelectRows);-
3045 q->setSelectionMode(QAbstractItemView::SingleSelection);-
3046 q->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);-
3047 q->setAttribute(Qt::WA_MacShowFocusRect);-
3048-
3049 QHeaderView *header = new QHeaderView(Qt::Horizontal, q);-
3050 header->setSectionsMovable(true);-
3051 header->setStretchLastSection(true);-
3052 header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);-
3053 q->setHeader(header);-
3054#ifndef QT_NO_ANIMATION-
3055 animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animate, 0, q);-
3056 QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));-
3057#endif //QT_NO_ANIMATION-
3058}-
3059-
3060void QTreeViewPrivate::expand(int item, bool emitSignal)-
3061{-
3062 Q_Q(QTreeView);-
3063-
3064 if (item == -1 || viewItems.at(item).expanded)-
3065 return;-
3066 const QModelIndex index = viewItems.at(item).index;-
3067 if (index.flags() & Qt::ItemNeverHasChildren)-
3068 return;-
3069-
3070#ifndef QT_NO_ANIMATION-
3071 if (emitSignal && animationsEnabled)-
3072 prepareAnimatedOperation(item, QVariantAnimation::Forward);-
3073#endif //QT_NO_ANIMATION-
3074 //if already animating, stateBeforeAnimation is set to the correct value-
3075 if (state != QAbstractItemView::AnimatingState)-
3076 stateBeforeAnimation = state;-
3077 q->setState(QAbstractItemView::ExpandingState);-
3078 storeExpanded(index);-
3079 viewItems[item].expanded = true;-
3080 layout(item);-
3081 q->setState(stateBeforeAnimation);-
3082-
3083 if (model->canFetchMore(index))-
3084 model->fetchMore(index);-
3085 if (emitSignal) {-
3086 emit q->expanded(index);-
3087#ifndef QT_NO_ANIMATION-
3088 if (animationsEnabled)-
3089 beginAnimatedOperation();-
3090#endif //QT_NO_ANIMATION-
3091 }-
3092}-
3093-
3094void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)-
3095{-
3096 viewItems.insert(pos, count, viewItem);-
3097 QTreeViewItem *items = viewItems.data();-
3098 for (int i = pos + count; i < viewItems.count(); i++)-
3099 if (items[i].parentItem >= pos)-
3100 items[i].parentItem += count;-
3101}-
3102-
3103void QTreeViewPrivate::removeViewItems(int pos, int count)-
3104{-
3105 viewItems.remove(pos, count);-
3106 QTreeViewItem *items = viewItems.data();-
3107 for (int i = pos; i < viewItems.count(); i++)-
3108 if (items[i].parentItem >= pos)-
3109 items[i].parentItem -= count;-
3110}-
3111-
3112#if 0-
3113bool QTreeViewPrivate::checkViewItems() const-
3114{-
3115 for (int i = 0; i < viewItems.count(); ++i) {-
3116 const QTreeViewItem &vi = viewItems.at(i);-
3117 if (vi.parentItem == -1) {-
3118 Q_ASSERT(!vi.index.parent().isValid() || vi.index.parent() == root);-
3119 } else {-
3120 Q_ASSERT(vi.index.parent() == viewItems.at(vi.parentItem).index);-
3121 }-
3122 }-
3123 return true;-
3124}-
3125#endif-
3126-
3127void QTreeViewPrivate::collapse(int item, bool emitSignal)-
3128{-
3129 Q_Q(QTreeView);-
3130-
3131 if (item == -1 || expandedIndexes.isEmpty())-
3132 return;-
3133-
3134 //if the current item is now invisible, the autoscroll will expand the tree to see it, so disable the autoscroll-
3135 delayedAutoScroll.stop();-
3136-
3137 int total = viewItems.at(item).total;-
3138 const QModelIndex &modelIndex = viewItems.at(item).index;-
3139 if (!isPersistent(modelIndex))-
3140 return; // if the index is not persistent, no chances it is expanded-
3141 QSet<QPersistentModelIndex>::iterator it = expandedIndexes.find(modelIndex);-
3142 if (it == expandedIndexes.end() || viewItems.at(item).expanded == false)-
3143 return; // nothing to do-
3144-
3145#ifndef QT_NO_ANIMATION-
3146 if (emitSignal && animationsEnabled)-
3147 prepareAnimatedOperation(item, QVariantAnimation::Backward);-
3148#endif //QT_NO_ANIMATION-
3149-
3150 //if already animating, stateBeforeAnimation is set to the correct value-
3151 if (state != QAbstractItemView::AnimatingState)-
3152 stateBeforeAnimation = state;-
3153 q->setState(QAbstractItemView::CollapsingState);-
3154 expandedIndexes.erase(it);-
3155 viewItems[item].expanded = false;-
3156 int index = item;-
3157 while (index > -1) {-
3158 viewItems[index].total -= total;-
3159 index = viewItems[index].parentItem;-
3160 }-
3161 removeViewItems(item + 1, total); // collapse-
3162 q->setState(stateBeforeAnimation);-
3163-
3164 if (emitSignal) {-
3165 emit q->collapsed(modelIndex);-
3166#ifndef QT_NO_ANIMATION-
3167 if (animationsEnabled)-
3168 beginAnimatedOperation();-
3169#endif //QT_NO_ANIMATION-
3170 }-
3171}-
3172-
3173#ifndef QT_NO_ANIMATION-
3174void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction)-
3175{-
3176 animatedOperation.item = item;-
3177 animatedOperation.viewport = viewport;-
3178 animatedOperation.setDirection(direction);-
3179-
3180 int top = coordinateForItem(item) + itemHeight(item);-
3181 QRect rect = viewport->rect();-
3182 rect.setTop(top);-
3183 if (direction == QVariantAnimation::Backward) {-
3184 const int limit = rect.height() * 2;-
3185 int h = 0;-
3186 int c = item + viewItems.at(item).total + 1;-
3187 for (int i = item + 1; i < c && h < limit; ++i)-
3188 h += itemHeight(i);-
3189 rect.setHeight(h);-
3190 animatedOperation.setEndValue(top + h);-
3191 }-
3192 animatedOperation.setStartValue(top);-
3193 animatedOperation.before = renderTreeToPixmapForAnimation(rect);-
3194}-
3195-
3196void QTreeViewPrivate::beginAnimatedOperation()-
3197{-
3198 Q_Q(QTreeView);-
3199-
3200 QRect rect = viewport->rect();-
3201 rect.setTop(animatedOperation.top());-
3202 if (animatedOperation.direction() == QVariantAnimation::Forward) {-
3203 const int limit = rect.height() * 2;-
3204 int h = 0;-
3205 int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1;-
3206 for (int i = animatedOperation.item + 1; i < c && h < limit; ++i)-
3207 h += itemHeight(i);-
3208 rect.setHeight(h);-
3209 animatedOperation.setEndValue(animatedOperation.top() + h);-
3210 }-
3211-
3212 if (!rect.isEmpty()) {-
3213 animatedOperation.after = renderTreeToPixmapForAnimation(rect);-
3214-
3215 q->setState(QAbstractItemView::AnimatingState);-
3216 animatedOperation.start(); //let's start the animation-
3217 }-
3218}-
3219-
3220void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const-
3221{-
3222 const int start = animatedOperation.startValue().toInt(),-
3223 end = animatedOperation.endValue().toInt(),-
3224 current = animatedOperation.currentValue().toInt();-
3225 bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward;-
3226 const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after;-
3227 painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height());-
3228 const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before;-
3229 painter->drawPixmap(0, current, bottom);-
3230}-
3231-
3232QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) const-
3233{-
3234 Q_Q(const QTreeView);-
3235 QPixmap pixmap(rect.size() * q->devicePixelRatio());-
3236 pixmap.setDevicePixelRatio(q->devicePixelRatio());-
3237 if (rect.size().isEmpty())-
3238 return pixmap;-
3239 pixmap.fill(Qt::transparent); //the base might not be opaque, and we don't want uninitialized pixels.-
3240 QPainter painter(&pixmap);-
3241 painter.fillRect(QRect(QPoint(0,0), rect.size()), q->palette().base());-
3242 painter.translate(0, -rect.top());-
3243 q->drawTree(&painter, QRegion(rect));-
3244 painter.end();-
3245-
3246 //and now let's render the editors the editors-
3247 QStyleOptionViewItem option = viewOptionsV1();-
3248 for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {-
3249 QWidget *editor = it.key();-
3250 const QModelIndex &index = it.value();-
3251 option.rect = q->visualRect(index);-
3252 if (option.rect.isValid()) {-
3253-
3254 if (QAbstractItemDelegate *delegate = delegateForIndex(index))-
3255 delegate->updateEditorGeometry(editor, option, index);-
3256-
3257 const QPoint pos = editor->pos();-
3258 if (rect.contains(pos)) {-
3259 editor->render(&pixmap, pos - rect.topLeft());-
3260 //the animation uses pixmap to display the treeview's content-
3261 //the editor is rendered on this pixmap and thus can (should) be hidden-
3262 editor->hide();-
3263 }-
3264 }-
3265 }-
3266-
3267-
3268 return pixmap;-
3269}-
3270-
3271void QTreeViewPrivate::_q_endAnimatedOperation()-
3272{-
3273 Q_Q(QTreeView);-
3274 q->setState(stateBeforeAnimation);-
3275 q->updateGeometries();-
3276 viewport->update();-
3277}-
3278#endif //QT_NO_ANIMATION-
3279-
3280void QTreeViewPrivate::_q_modelAboutToBeReset()-
3281{-
3282 viewItems.clear();-
3283}-
3284-
3285void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)-
3286{-
3287 if (start <= 0 && 0 <= end)-
3288 viewItems.clear();-
3289 QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end);-
3290}-
3291-
3292void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end)-
3293{-
3294 if (start <= 0 && 0 <= end)-
3295 doDelayedItemsLayout();-
3296 QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);-
3297}-
3298-
3299/** \internal-
3300 creates and initialize the viewItem structure of the children of the element \li-
3301-
3302 set \a recursiveExpanding if the function has to expand all the children (called from expandAll)-
3303 \a afterIsUninitialized is when we recurse from layout(-1), it means all the items after 'i' are-
3304 not yet initialized and need not to be moved-
3305 */-
3306void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninitialized)-
3307{-
3308 Q_Q(QTreeView);-
3309 QModelIndex current;-
3310 QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i);-
3311-
3312 if (i>=0 && !parent.isValid()) {-
3313 //modelIndex() should never return something invalid for the real items.-
3314 //This can happen if columncount has been set to 0.-
3315 //To avoid infinite loop we stop here.-
3316 return;-
3317 }-
3318-
3319 int count = 0;-
3320 if (model->hasChildren(parent)) {-
3321 if (model->canFetchMore(parent))-
3322 model->fetchMore(parent);-
3323 count = model->rowCount(parent);-
3324 }-
3325-
3326 bool expanding = true;-
3327 if (i == -1) {-
3328 if (uniformRowHeights) {-
3329 QModelIndex index = model->index(0, 0, parent);-
3330 defaultItemHeight = q->indexRowSizeHint(index);-
3331 }-
3332 viewItems.resize(count);-
3333 afterIsUninitialized = true;-
3334 } else if (viewItems[i].total != (uint)count) {-
3335 if (!afterIsUninitialized)-
3336 insertViewItems(i + 1, count, QTreeViewItem()); // expand-
3337 else if (count > 0)-
3338 viewItems.resize(viewItems.count() + count);-
3339 } else {-
3340 expanding = false;-
3341 }-
3342-
3343 int first = i + 1;-
3344 int level = (i >= 0 ? viewItems.at(i).level + 1 : 0);-
3345 int hidden = 0;-
3346 int last = 0;-
3347 int children = 0;-
3348 QTreeViewItem *item = 0;-
3349 for (int j = first; j < first + count; ++j) {-
3350 current = model->index(j - first, 0, parent);-
3351 if (isRowHidden(current)) {-
3352 ++hidden;-
3353 last = j - hidden + children;-
3354 } else {-
3355 last = j - hidden + children;-
3356 if (item)-
3357 item->hasMoreSiblings = true;-
3358 item = &viewItems[last];-
3359 item->index = current;-
3360 item->parentItem = i;-
3361 item->level = level;-
3362 item->height = 0;-
3363 item->spanning = q->isFirstColumnSpanned(current.row(), parent);-
3364 item->expanded = false;-
3365 item->total = 0;-
3366 item->hasMoreSiblings = false;-
3367 if ((recursiveExpanding && !(current.flags() & Qt::ItemNeverHasChildren)) || isIndexExpanded(current)) {-
3368 if (recursiveExpanding && storeExpanded(current) && !q->signalsBlocked())-
3369 emit q->expanded(current);-
3370 item->expanded = true;-
3371 layout(last, recursiveExpanding, afterIsUninitialized);-
3372 item = &viewItems[last];-
3373 children += item->total;-
3374 item->hasChildren = item->total > 0;-
3375 last = j - hidden + children;-
3376 } else {-
3377 item->hasChildren = hasVisibleChildren(current);-
3378 }-
3379 }-
3380 }-
3381-
3382 // remove hidden items-
3383 if (hidden > 0) {-
3384 if (!afterIsUninitialized)-
3385 removeViewItems(last + 1, hidden);-
3386 else-
3387 viewItems.resize(viewItems.size() - hidden);-
3388 }-
3389-
3390 if (!expanding)-
3391 return; // nothing changed-
3392-
3393 while (i > -1) {-
3394 viewItems[i].total += count - hidden;-
3395 i = viewItems[i].parentItem;-
3396 }-
3397}-
3398-
3399int QTreeViewPrivate::pageUp(int i) const-
3400{-
3401 int index = itemAtCoordinate(coordinateForItem(i) - viewport->height());-
3402 while (isItemHiddenOrDisabled(index))-
3403 index--;-
3404 return index == -1 ? 0 : index;-
3405}-
3406-
3407int QTreeViewPrivate::pageDown(int i) const-
3408{-
3409 int index = itemAtCoordinate(coordinateForItem(i) + viewport->height());-
3410 while (isItemHiddenOrDisabled(index))-
3411 index++;-
3412 return index == -1 ? viewItems.count() - 1 : index;-
3413}-
3414-
3415int QTreeViewPrivate::indentationForItem(int item) const-
3416{-
3417 if (item < 0 || item >= viewItems.count())-
3418 return 0;-
3419 int level = viewItems.at(item).level;-
3420 if (rootDecoration)-
3421 ++level;-
3422 return level * indent;-
3423}-
3424-
3425int QTreeViewPrivate::itemHeight(int item) const-
3426{-
3427 if (uniformRowHeights)-
3428 return defaultItemHeight;-
3429 if (viewItems.isEmpty())-
3430 return 0;-
3431 const QModelIndex &index = viewItems.at(item).index;-
3432 if (!index.isValid())-
3433 return 0;-
3434 int height = viewItems.at(item).height;-
3435 if (height <= 0) {-
3436 height = q_func()->indexRowSizeHint(index);-
3437 viewItems[item].height = height;-
3438 }-
3439 return qMax(height, 0);-
3440}-
3441-
3442-
3443/*!-
3444 \internal-
3445 Returns the viewport y coordinate for \a item.-
3446*/-
3447int QTreeViewPrivate::coordinateForItem(int item) const-
3448{-
3449 if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {-
3450 if (uniformRowHeights)-
3451 return (item * defaultItemHeight) - vbar->value();-
3452 // ### optimize (maybe do like QHeaderView by letting items have startposition)-
3453 int y = 0;-
3454 for (int i = 0; i < viewItems.count(); ++i) {-
3455 if (i == item)-
3456 return y - vbar->value();-
3457 y += itemHeight(i);-
3458 }-
3459 } else { // ScrollPerItem-
3460 int topViewItemIndex = vbar->value();-
3461 if (uniformRowHeights)-
3462 return defaultItemHeight * (item - topViewItemIndex);-
3463 if (item >= topViewItemIndex) {-
3464 // search in the visible area first and continue down-
3465 // ### slow if the item is not visible-
3466 int viewItemCoordinate = 0;-
3467 int viewItemIndex = topViewItemIndex;-
3468 while (viewItemIndex < viewItems.count()) {-
3469 if (viewItemIndex == item)-
3470 return viewItemCoordinate;-
3471 viewItemCoordinate += itemHeight(viewItemIndex);-
3472 ++viewItemIndex;-
3473 }-
3474 // below the last item in the view-
3475 Q_ASSERT(false);-
3476 return viewItemCoordinate;-
3477 } else {-
3478 // search the area above the viewport (used for editor widgets)-
3479 int viewItemCoordinate = 0;-
3480 for (int viewItemIndex = topViewItemIndex; viewItemIndex > 0; --viewItemIndex) {-
3481 if (viewItemIndex == item)-
3482 return viewItemCoordinate;-
3483 viewItemCoordinate -= itemHeight(viewItemIndex - 1);-
3484 }-
3485 return viewItemCoordinate;-
3486 }-
3487 }-
3488 return 0;-
3489}-
3490-
3491/*!-
3492 \internal-
3493 Returns the index of the view item at the-
3494 given viewport \a coordinate.-
3495-
3496 \sa modelIndex()-
3497*/-
3498int QTreeViewPrivate::itemAtCoordinate(int coordinate) const-
3499{-
3500 const int itemCount = viewItems.count();-
3501 if (itemCount == 0)-
3502 return -1;-
3503 if (uniformRowHeights && defaultItemHeight <= 0)-
3504 return -1;-
3505 if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) {-
3506 if (uniformRowHeights) {-
3507 const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight;-
3508 return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);-
3509 }-
3510 // ### optimize-
3511 int viewItemCoordinate = 0;-
3512 const int contentsCoordinate = coordinate + vbar->value();-
3513 for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) {-
3514 viewItemCoordinate += itemHeight(viewItemIndex);-
3515 if (viewItemCoordinate >= contentsCoordinate)-
3516 return (viewItemIndex >= itemCount ? -1 : viewItemIndex);-
3517 }-
3518 } else { // ScrollPerItem-
3519 int topViewItemIndex = vbar->value();-
3520 if (uniformRowHeights) {-
3521 if (coordinate < 0)-
3522 coordinate -= defaultItemHeight - 1;-
3523 const int viewItemIndex = topViewItemIndex + (coordinate / defaultItemHeight);-
3524 return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex);-
3525 }-
3526 if (coordinate >= 0) {-
3527 // the coordinate is in or below the viewport-
3528 int viewItemCoordinate = 0;-
3529 for (int viewItemIndex = topViewItemIndex; viewItemIndex < viewItems.count(); ++viewItemIndex) {-
3530 viewItemCoordinate += itemHeight(viewItemIndex);-
3531 if (viewItemCoordinate > coordinate)-
3532 return (viewItemIndex >= itemCount ? -1 : viewItemIndex);-
3533 }-
3534 } else {-
3535 // the coordinate is above the viewport-
3536 int viewItemCoordinate = 0;-
3537 for (int viewItemIndex = topViewItemIndex; viewItemIndex >= 0; --viewItemIndex) {-
3538 if (viewItemCoordinate <= coordinate)-
3539 return (viewItemIndex >= itemCount ? -1 : viewItemIndex);-
3540 viewItemCoordinate -= itemHeight(viewItemIndex);-
3541 }-
3542 }-
3543 }-
3544 return -1;-
3545}-
3546-
3547int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const-
3548{-
3549 if (!_index.isValid() || viewItems.isEmpty())-
3550 return -1;-
3551-
3552 const int totalCount = viewItems.count();-
3553 const QModelIndex index = _index.sibling(_index.row(), 0);-
3554 const int row = index.row();-
3555 const quintptr internalId = index.internalId();-
3556-
3557 // We start nearest to the lastViewedItem-
3558 int localCount = qMin(lastViewedItem - 1, totalCount - lastViewedItem);-
3559 for (int i = 0; i < localCount; ++i) {-
3560 const QModelIndex &idx1 = viewItems.at(lastViewedItem + i).index;-
3561 if (idx1.row() == row && idx1.internalId() == internalId) {-
3562 lastViewedItem = lastViewedItem + i;-
3563 return lastViewedItem;-
3564 }-
3565 const QModelIndex &idx2 = viewItems.at(lastViewedItem - i - 1).index;-
3566 if (idx2.row() == row && idx2.internalId() == internalId) {-
3567 lastViewedItem = lastViewedItem - i - 1;-
3568 return lastViewedItem;-
3569 }-
3570 }-
3571-
3572 for (int j = qMax(0, lastViewedItem + localCount); j < totalCount; ++j) {-
3573 const QModelIndex &idx = viewItems.at(j).index;-
3574 if (idx.row() == row && idx.internalId() == internalId) {-
3575 lastViewedItem = j;-
3576 return j;-
3577 }-
3578 }-
3579 for (int j = qMin(totalCount, lastViewedItem - localCount) - 1; j >= 0; --j) {-
3580 const QModelIndex &idx = viewItems.at(j).index;-
3581 if (idx.row() == row && idx.internalId() == internalId) {-
3582 lastViewedItem = j;-
3583 return j;-
3584 }-
3585 }-
3586-
3587 // nothing found-
3588 return -1;-
3589}-
3590-
3591QModelIndex QTreeViewPrivate::modelIndex(int i, int column) const-
3592{-
3593 if (i < 0 || i >= viewItems.count())-
3594 return QModelIndex();-
3595-
3596 QModelIndex ret = viewItems.at(i).index;-
3597 if (column)-
3598 ret = ret.sibling(ret.row(), column);-
3599 return ret;-
3600}-
3601-
3602int QTreeViewPrivate::firstVisibleItem(int *offset) const-
3603{-
3604 const int value = vbar->value();-
3605 if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {-
3606 if (offset)-
3607 *offset = 0;-
3608 return (value < 0 || value >= viewItems.count()) ? -1 : value;-
3609 }-
3610 // ScrollMode == ScrollPerPixel-
3611 if (uniformRowHeights) {-
3612 if (!defaultItemHeight)-
3613 return -1;-
3614-
3615 if (offset)-
3616 *offset = -(value % defaultItemHeight);-
3617 return value / defaultItemHeight;-
3618 }-
3619 int y = 0; // ### (maybe do like QHeaderView by letting items have startposition)-
3620 for (int i = 0; i < viewItems.count(); ++i) {-
3621 y += itemHeight(i); // the height value is cached-
3622 if (y > value) {-
3623 if (offset)-
3624 *offset = y - value - itemHeight(i);-
3625 return i;-
3626 }-
3627 }-
3628 return -1;-
3629}-
3630-
3631int QTreeViewPrivate::lastVisibleItem(int firstVisual, int offset) const-
3632{-
3633 if (firstVisual < 0 || offset < 0) {-
3634 firstVisual = firstVisibleItem(&offset);-
3635 if (firstVisual < 0)-
3636 return -1;-
3637 }-
3638 int y = - offset;-
3639 int value = viewport->height();-
3640-
3641 for (int i = firstVisual; i < viewItems.count(); ++i) {-
3642 y += itemHeight(i); // the height value is cached-
3643 if (y > value)-
3644 return i;-
3645 }-
3646 return viewItems.size() - 1;-
3647}-
3648-
3649int QTreeViewPrivate::columnAt(int x) const-
3650{-
3651 return header->logicalIndexAt(x);-
3652}-
3653-
3654void QTreeViewPrivate::updateScrollBars()-
3655{-
3656 Q_Q(QTreeView);-
3657 QSize viewportSize = viewport->size();-
3658 if (!viewportSize.isValid())
!viewportSize.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
3659 viewportSize = QSize(0, 0);
never executed: viewportSize = QSize(0, 0);
0
3660-
3661 executePostedLayout();-
3662 if (viewItems.isEmpty()) {
viewItems.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3663 q->doItemsLayout();-
3664 }
never executed: end of block
0
3665-
3666 int itemsInViewport = 0;-
3667 if (uniformRowHeights) {
uniformRowHeightsDescription
TRUEnever evaluated
FALSEnever evaluated
0
3668 if (defaultItemHeight <= 0)
defaultItemHeight <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3669 itemsInViewport = viewItems.count();
never executed: itemsInViewport = viewItems.count();
0
3670 else-
3671 itemsInViewport = viewportSize.height() / defaultItemHeight;
never executed: itemsInViewport = viewportSize.height() / defaultItemHeight;
0
3672 } else {-
3673 const int itemsCount = viewItems.count();-
3674 const int viewportHeight = viewportSize.height();-
3675 for (int height = 0, item = itemsCount - 1; item >= 0; --item) {
item >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3676 height += itemHeight(item);-
3677 if (height > viewportHeight)
height > viewportHeightDescription
TRUEnever evaluated
FALSEnever evaluated
0
3678 break;
never executed: break;
0
3679 ++itemsInViewport;-
3680 }
never executed: end of block
0
3681 }
never executed: end of block
0
3682 if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
verticalScroll...:ScrollPerItemDescription
TRUEnever evaluated
FALSEnever evaluated
0
3683 if (!viewItems.isEmpty())
!viewItems.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3684 itemsInViewport = qMax(1, itemsInViewport);
never executed: itemsInViewport = qMax(1, itemsInViewport);
0
3685 vbar->setRange(0, viewItems.count() - itemsInViewport);-
3686 vbar->setPageStep(itemsInViewport);-
3687 vbar->setSingleStep(1);-
3688 } else { // scroll per pixel
never executed: end of block
0
3689 int contentsHeight = 0;-
3690 if (uniformRowHeights) {
uniformRowHeightsDescription
TRUEnever evaluated
FALSEnever evaluated
0
3691 contentsHeight = defaultItemHeight * viewItems.count();-
3692 } else { // ### (maybe do like QHeaderView by letting items have startposition)
never executed: end of block
0
3693 for (int i = 0; i < viewItems.count(); ++i)
i < viewItems.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
3694 contentsHeight += itemHeight(i);
never executed: contentsHeight += itemHeight(i);
0
3695 }
never executed: end of block
0
3696 vbar->setRange(0, contentsHeight - viewportSize.height());-
3697 vbar->setPageStep(viewportSize.height());-
3698 vbar->setSingleStepd_func()->itemviewChangeSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));-
3699 }
never executed: end of block
0
3700-
3701 const int columnCount = header->count();-
3702 const int viewportWidth = viewportSize.width();-
3703 int columnsInViewport = 0;-
3704 for (int width = 0, column = columnCount - 1; column >= 0; --column) {
column >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3705 int logical = header->logicalIndex(column);-
3706 width += header->sectionSize(logical);-
3707 if (width > viewportWidth)
width > viewportWidthDescription
TRUEnever evaluated
FALSEnever evaluated
0
3708 break;
never executed: break;
0
3709 ++columnsInViewport;-
3710 }
never executed: end of block
0
3711 if (columnCount > 0)
columnCount > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3712 columnsInViewport = qMax(1, columnsInViewport);
never executed: columnsInViewport = qMax(1, columnsInViewport);
0
3713 if (horizontalScrollMode == QAbstractItemView::ScrollPerItem) {
horizontalScro...:ScrollPerItemDescription
TRUEnever evaluated
FALSEnever evaluated
0
3714 hbar->setRange(0, columnCount - columnsInViewport);-
3715 hbar->setPageStep(columnsInViewport);-
3716 hbar->setSingleStep(1);-
3717 } else { // scroll per pixel
never executed: end of block
0
3718 const int horizontalLength = header->length();-
3719 const QSize maxSize = q->maximumViewportSize();-
3720 if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0)
maxSize.width(...rizontalLengthDescription
TRUEnever evaluated
FALSEnever evaluated
vbar->maximum() <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3721 viewportSize = maxSize;
never executed: viewportSize = maxSize;
0
3722 hbar->setPageStep(viewportSize.width());-
3723 hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));-
3724 hbar->setSingleStepd_func()->itemviewChangeSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));-
3725 }
never executed: end of block
0
3726}-
3727-
3728int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const-
3729{-
3730 executePostedLayout();-
3731 int x = pos.x();-
3732 int column = header->logicalIndexAt(x);-
3733 if (!isTreePosition(column))-
3734 return -1; // no logical index at x-
3735-
3736 int viewItemIndex = itemAtCoordinate(pos.y());-
3737 QRect returning = itemDecorationRect(modelIndex(viewItemIndex));-
3738 if (!returning.contains(pos))-
3739 return -1;-
3740-
3741 return viewItemIndex;-
3742}-
3743-
3744QRect QTreeViewPrivate::itemDecorationRect(const QModelIndex &index) const-
3745{-
3746 Q_Q(const QTreeView);-
3747 if (!rootDecoration && index.parent() == root)-
3748 return QRect(); // no decoration at root-
3749-
3750 int viewItemIndex = viewIndex(index);-
3751 if (viewItemIndex < 0 || !hasVisibleChildren(viewItems.at(viewItemIndex).index))-
3752 return QRect();-
3753-
3754 int itemIndentation = indentationForItem(viewItemIndex);-
3755 int position = header->sectionViewportPosition(logicalIndexForTree());-
3756 int size = header->sectionSize(logicalIndexForTree());-
3757-
3758 QRect rect;-
3759 if (q->isRightToLeft())-
3760 rect = QRect(position + size - itemIndentation, coordinateForItem(viewItemIndex),-
3761 indent, itemHeight(viewItemIndex));-
3762 else-
3763 rect = QRect(position + itemIndentation - indent, coordinateForItem(viewItemIndex),-
3764 indent, itemHeight(viewItemIndex));-
3765 QStyleOption opt;-
3766 opt.initFrom(q);-
3767 opt.rect = rect;-
3768 return q->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &opt, q);-
3769}-
3770-
QListQVector<QPair<int, int> > QTreeViewPrivate::columnRanges(const QModelIndex &topIndex,
3772 const QModelIndex &bottomIndex) const-
3773{-
3774 const int topVisual = header->visualIndex(topIndex.column()),-
3775 bottomVisual = header->visualIndex(bottomIndex.column());-
3776-
3777 const int start = qMin(topVisual, bottomVisual);-
3778 const int end = qMax(topVisual, bottomVisual);-
3779-
3780 QList<int> logicalIndexes;-
3781-
3782 //we iterate over the visual indexes to get the logical indexes-
3783 for (int c = start; c <= end; c++) {
c <= endDescription
TRUEnever evaluated
FALSEnever evaluated
0
3784 const int logical = header->logicalIndex(c);-
3785 if (!header->isSectionHidden(logical)) {
!header->isSec...idden(logical)Description
TRUEnever evaluated
FALSEnever evaluated
0
3786 logicalIndexes << logical;-
3787 }
never executed: end of block
0
3788 }
never executed: end of block
0
3789 //let's sort the list-
3790 std::sort(logicalIndexes.begin(), logicalIndexes.end());-
3791-
3792 QListQVector<QPair<int, int> > ret;-
3793 QPair<int, int> current;-
3794 current.first = -2; // -1 is not enough because -1+1 = 0-
3795 current.second = -2;-
3796 for(int i = 0; i < logicalIndexes.count(); ++i) {
i < logicalIndexes.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
3797 const int logicalColumn = logicalIndexes.at(i);-
3798 if (current.second + 1 != logicalColumn) {
current.second... logicalColumnDescription
TRUEnever evaluated
FALSEnever evaluated
0
3799 if (current.first != -2) {
current.first != -2Description
TRUEnever evaluated
FALSEnever evaluated
0
3800 //let's save the current one-
3801 ret += current;-
3802 }
never executed: end of block
0
3803 //let's start a new one-
3804 current.first = current.second = logicalColumn;-
3805 } else {
never executed: end of block
0
3806 current.second++;-
3807 }
never executed: end of block
0
3808 }-
3809-
3810 //let's get the last range-
3811 if (current.first != -2) {
current.first != -2Description
TRUEnever evaluated
FALSEnever evaluated
0
3812 ret += current;-
3813 }
never executed: end of block
0
3814-
3815 return ret;
never executed: return ret;
0
3816}-
3817-
3818void QTreeViewPrivate::select(const QModelIndex &topIndex, const QModelIndex &bottomIndex,-
3819 QItemSelectionModel::SelectionFlags command)-
3820{-
3821 Q_Q(QTreeView);-
3822 QItemSelection selection;-
3823 const int top = viewIndex(topIndex),-
3824 bottom = viewIndex(bottomIndex);-
3825-
3826 const QListQVector<QPair<int, int> > colRanges = columnRanges(topIndex, bottomIndex);-
3827 QListQVector<QPair<int, int> >::const_iterator it;-
3828 for (it = colRanges.begin(); it != colRanges.end(); ++it) {
it != colRanges.end()Description
TRUEnever evaluated
FALSEnever evaluated
0
3829 const int left = (*it).first,-
3830 right = (*it).second;-
3831-
3832 QModelIndex previous;-
3833 QItemSelectionRange currentRange;-
3834 QStack<QItemSelectionRange> rangeStack;-
3835 for (int i = top; i <= bottom; ++i) {
i <= bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
3836 QModelIndex index = modelIndex(i);-
3837 QModelIndex parent = index.parent();-
3838 QModelIndex previousParent = previous.parent();-
3839 if (previous.isValid() && parent == previousParent) {
previous.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
parent == previousParentDescription
TRUEnever evaluated
FALSEnever evaluated
0
3840 // same parent-
3841 if (qAbs(previous.row() - index.row()) > 1) {
qAbs(previous....dex.row()) > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3842 //a hole (hidden index inside a range) has been detected-
3843 if (currentRange.isValid()) {
currentRange.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
3844 selection.append(currentRange);-
3845 }
never executed: end of block
0
3846 //let's start a new range-
3847 currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));-
3848 } else {
never executed: end of block
0
3849 QModelIndex tl = model->index(currentRange.top(), currentRange.left(),-
3850 currentRange.parent());-
3851 currentRange = QItemSelectionRange(tl, index.sibling(index.row(), right));-
3852 }
never executed: end of block
0
3853 } else if (previous.isValid() && parent == model->index(previous.row(), 0, previousParent)) {
previous.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
parent == mode...reviousParent)Description
TRUEnever evaluated
FALSEnever evaluated
0
3854 // item is child of previous-
3855 rangeStack.push(currentRange);-
3856 currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));-
3857 } else {
never executed: end of block
0
3858 if (currentRange.isValid())
currentRange.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
3859 selection.append(currentRange);
never executed: selection.append(currentRange);
0
3860 if (rangeStack.isEmpty()) {
rangeStack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3861 currentRange = QItemSelectionRange(index.sibling(index.row(), left), index.sibling(index.row(), right));-
3862 } else {
never executed: end of block
0
3863 currentRange = rangeStack.pop();-
3864 index = currentRange.bottomRight(); //let's resume the range-
3865 --i; //we process again the current item-
3866 }
never executed: end of block
0
3867 }-
3868 previous = index;-
3869 }
never executed: end of block
0
3870 if (currentRange.isValid())
currentRange.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
3871 selection.append(currentRange);
never executed: selection.append(currentRange);
0
3872 for (int i = 0; i < rangeStack.count(); ++i)
i < rangeStack.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
3873 selection.append(rangeStack.at(i));
never executed: selection.append(rangeStack.at(i));
0
3874 }
never executed: end of block
0
3875 q->selectionModel()->select(selection, command);-
3876}
never executed: end of block
0
3877-
3878QPair<int,int> QTreeViewPrivate::startAndEndColumns(const QRect &rect) const-
3879{-
3880 Q_Q(const QTreeView);-
3881 int start = header->visualIndexAt(rect.left());-
3882 int end = header->visualIndexAt(rect.right());-
3883 if (q->isRightToLeft()) {-
3884 start = (start == -1 ? header->count() - 1 : start);-
3885 end = (end == -1 ? 0 : end);-
3886 } else {-
3887 start = (start == -1 ? 0 : start);-
3888 end = (end == -1 ? header->count() - 1 : end);-
3889 }-
3890 return qMakePair<int,int>(qMin(start, end), qMax(start, end));-
3891}-
3892-
3893bool QTreeViewPrivate::hasVisibleChildren(const QModelIndex& parent) const-
3894{-
3895 Q_Q(const QTreeView);-
3896 if (parent.flags() & Qt::ItemNeverHasChildren)-
3897 return false;-
3898 if (model->hasChildren(parent)) {-
3899 if (hiddenIndexes.isEmpty())-
3900 return true;-
3901 if (q->isIndexHidden(parent))-
3902 return false;-
3903 int rowCount = model->rowCount(parent);-
3904 for (int i = 0; i < rowCount; ++i) {-
3905 if (!q->isRowHidden(i, parent))-
3906 return true;-
3907 }-
3908 if (rowCount == 0)-
3909 return true;-
3910 }-
3911 return false;-
3912}-
3913-
3914void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)-
3915{-
3916 model->sort(column, order);-
3917}-
3918-
3919int QTreeViewPrivate::accessibleTree2Index(const QModelIndex &index) const-
3920{-
3921 Q_Q(const QTreeView);-
3922-
3923 // Note that this will include the header, even if its hidden.-
3924 return (q->visualIndex(index) + (q->header() ? 1 : 0)) * index.model()->columnCount() + index.column();-
3925}-
3926-
3927void QTreeViewPrivate::updateIndentationFromStyle()-
3928{-
3929 Q_Q(const QTreeView);-
3930 indent = q->style()->pixelMetric(QStyle::PM_TreeViewIndentation, 0, q);-
3931}-
3932-
3933/*!-
3934 \reimp-
3935 */-
3936void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)-
3937{-
3938 QAbstractItemView::currentChanged(current, previous);-
3939-
3940 if (allColumnsShowFocus()) {-
3941 if (previous.isValid()) {-
3942 QRect previousRect = visualRect(previous);-
3943 previousRect.setX(0);-
3944 previousRect.setWidth(viewport()->width());-
3945 viewport()->update(previousRect);-
3946 }-
3947 if (current.isValid()) {-
3948 QRect currentRect = visualRect(current);-
3949 currentRect.setX(0);-
3950 currentRect.setWidth(viewport()->width());-
3951 viewport()->update(currentRect);-
3952 }-
3953 }-
3954#ifndef QT_NO_ACCESSIBILITY-
3955 if (QAccessible::isActive() && current.isValid()) {-
3956 Q_D(QTreeView);-
3957-
3958 QAccessibleEvent event(this, QAccessible::Focus);-
3959 event.setChild(d->accessibleTree2Index(current));-
3960 QAccessible::updateAccessibility(&event);-
3961 }-
3962#endif-
3963}-
3964-
3965/*!-
3966 \reimp-
3967 */-
3968void QTreeView::selectionChanged(const QItemSelection &selected,-
3969 const QItemSelection &deselected)-
3970{-
3971 QAbstractItemView::selectionChanged(selected, deselected);-
3972#ifndef QT_NO_ACCESSIBILITY-
3973 if (QAccessible::isActive()) {-
3974 Q_D(QTreeView);-
3975-
3976 // ### does not work properly for selection ranges.-
3977 QModelIndex sel = selected.indexes().value(0);-
3978 if (sel.isValid()) {-
3979 int entry = d->accessibleTree2Index(sel);-
3980 Q_ASSERT(entry >= 0);-
3981 QAccessibleEvent event(this, QAccessible::SelectionAdd);-
3982 event.setChild(entry);-
3983 QAccessible::updateAccessibility(&event);-
3984 }-
3985 QModelIndex desel = deselected.indexes().value(0);-
3986 if (desel.isValid()) {-
3987 int entry = d->accessibleTree2Index(desel);-
3988 Q_ASSERT(entry >= 0);-
3989 QAccessibleEvent event(this, QAccessible::SelectionRemove);-
3990 event.setChild(entry);-
3991 QAccessible::updateAccessibility(&event);-
3992 }-
3993 }-
3994#endif-
3995}-
3996-
3997int QTreeView::visualIndex(const QModelIndex &index) const-
3998{-
3999 Q_D(const QTreeView);-
4000 d->executePostedLayout();-
4001 return d->viewIndex(index);-
4002}-
4003-
4004QT_END_NAMESPACE-
4005-
4006#include "moc_qtreeview.cpp"-
4007-
4008#endif // QT_NO_TREEVIEW-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9