1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QTREEVIEW_P_H
5#define QTREEVIEW_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtWidgets/private/qtwidgetsglobal_p.h>
19#include "private/qabstractitemview_p.h"
20#include <QtCore/qabstractitemmodel.h>
21#include <QtCore/qlist.h>
22#if QT_CONFIG(animation)
23#include <QtCore/qvariantanimation.h>
24#endif
25
26QT_REQUIRE_CONFIG(treeview);
27
28QT_BEGIN_NAMESPACE
29
30struct QTreeViewItem
31{
32 QTreeViewItem() : parentItem(-1), expanded(false), spanning(false), hasChildren(false),
33 hasMoreSiblings(false), total(0), level(0), height(0) {}
34 QModelIndex index; // we remove items whenever the indexes are invalidated
35 int parentItem; // parent item index in viewItems
36 uint expanded : 1;
37 uint spanning : 1;
38 uint hasChildren : 1; // if the item has visible children (even if collapsed)
39 uint hasMoreSiblings : 1;
40 uint total : 28; // total number of children visible
41 uint level : 16; // indentation
42 int height : 16; // row height
43};
44
45Q_DECLARE_TYPEINFO(QTreeViewItem, Q_RELOCATABLE_TYPE);
46
47class Q_WIDGETS_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate
48{
49 Q_DECLARE_PUBLIC(QTreeView)
50public:
51
52 QTreeViewPrivate()
53 : QAbstractItemViewPrivate(),
54 header(nullptr), indent(20), lastViewedItem(0), defaultItemHeight(-1),
55 uniformRowHeights(false), rootDecoration(true),
56 itemsExpandable(true), sortingEnabled(false),
57 expandsOnDoubleClick(true),
58 allColumnsShowFocus(false), customIndent(false), current(0), spanning(false),
59 animationsEnabled(false), columnResizeTimerID(0),
60 autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false),
61 treePosition(0) {}
62
63 ~QTreeViewPrivate() {}
64 void initialize();
65 int logicalIndexForTree() const;
66 inline bool isTreePosition(int logicalIndex) const
67 {
68 return logicalIndex == logicalIndexForTree();
69 }
70
71 QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const override;
72 void adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex &current) const override;
73
74#if QT_CONFIG(animation)
75 struct AnimatedOperation : public QVariantAnimation
76 {
77 int item;
78 QPixmap before;
79 QPixmap after;
80 QWidget *viewport;
81 AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); }
82 int top() const { return startValue().toInt(); }
83 QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(pos: top()); return rect; }
84 void updateCurrentValue(const QVariant &) override { viewport->update(rect()); }
85 void updateState(State state, State) override { if (state == Stopped) before = after = QPixmap(); }
86 } animatedOperation;
87 void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
88 void beginAnimatedOperation();
89 void drawAnimatedOperation(QPainter *painter) const;
90 QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
91 void _q_endAnimatedOperation();
92#endif // animation
93
94 void expand(int item, bool emitSignal);
95 void collapse(int item, bool emitSignal);
96
97 void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int) override;
98 void _q_columnsRemoved(const QModelIndex &, int, int) override;
99 void _q_modelAboutToBeReset();
100 void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
101 void _q_modelDestroyed() override;
102 QRect intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const override;
103
104 void layout(int item, bool recusiveExpanding = false, bool afterIsUninitialized = false);
105
106 int pageUp(int item) const;
107 int pageDown(int item) const;
108 int itemForKeyHome() const;
109 int itemForKeyEnd() const;
110
111 int itemHeight(int item) const;
112 int indentationForItem(int item) const;
113 int coordinateForItem(int item) const;
114 int itemAtCoordinate(int coordinate) const;
115
116 int viewIndex(const QModelIndex &index) const;
117 QModelIndex modelIndex(int i, int column = 0) const;
118
119 void insertViewItems(int pos, int count, const QTreeViewItem &viewItem);
120 void removeViewItems(int pos, int count);
121#if 0
122 bool checkViewItems() const;
123#endif
124
125 int firstVisibleItem(int *offset = nullptr) const;
126 int lastVisibleItem(int firstVisual = -1, int offset = -1) const;
127 int columnAt(int x) const;
128 bool hasVisibleChildren( const QModelIndex& parent) const;
129
130 bool expandOrCollapseItemAtPos(const QPoint &pos);
131
132 void updateScrollBars();
133
134 int itemDecorationAt(const QPoint &pos) const;
135 QRect itemDecorationRect(const QModelIndex &index) const;
136
137 QList<QPair<int, int>> columnRanges(const QModelIndex &topIndex,
138 const QModelIndex &bottomIndex) const;
139 void select(const QModelIndex &start, const QModelIndex &stop, QItemSelectionModel::SelectionFlags command);
140
141 QPair<int,int> startAndEndColumns(const QRect &rect) const;
142
143 void updateChildCount(const int parentItem, const int delta);
144
145 void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItem *option, int y, int bottom) const;
146
147 // logicalIndices: vector of currently visibly logical indices
148 // itemPositions: vector of view item positions (beginning/middle/end/onlyone)
149 void calcLogicalIndices(QList<int> *logicalIndices,
150 QList<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left,
151 int right) const;
152 int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const;
153
154 enum RectRule {
155 FullRow,
156 SingleSection,
157 AddRowIndicatorToFirstSection
158 };
159
160 // Base class will get the first visual rect including row indicator
161 QRect visualRect(const QModelIndex &index) const override
162 {
163 return visualRect(index, rule: AddRowIndicatorToFirstSection);
164 }
165
166 QRect visualRect(const QModelIndex &index, RectRule rule) const;
167
168 QHeaderView *header;
169 int indent;
170
171 mutable QList<QTreeViewItem> viewItems;
172 mutable int lastViewedItem;
173 int defaultItemHeight; // this is just a number; contentsHeight() / numItems
174 bool uniformRowHeights; // used when all rows have the same height
175 bool rootDecoration;
176 bool itemsExpandable;
177 bool sortingEnabled;
178 bool expandsOnDoubleClick;
179 bool allColumnsShowFocus;
180 bool customIndent;
181
182 // used for drawing
183 mutable QPair<int,int> leftAndRight;
184 mutable int current;
185 mutable bool spanning;
186
187 // used when expanding and collapsing items
188 QSet<QPersistentModelIndex> expandedIndexes;
189 bool animationsEnabled;
190
191 inline bool storeExpanded(const QPersistentModelIndex &idx) {
192 if (expandedIndexes.contains(value: idx))
193 return false;
194 expandedIndexes.insert(value: idx);
195 return true;
196 }
197
198 inline bool isIndexExpanded(const QModelIndex &idx) const {
199 //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
200 return !(idx.flags() & Qt::ItemNeverHasChildren) && isPersistent(index: idx) && expandedIndexes.contains(value: idx);
201 }
202
203 // used when hiding and showing items
204 QSet<QPersistentModelIndex> hiddenIndexes;
205
206 inline bool isRowHidden(const QModelIndex &idx) const {
207 if (hiddenIndexes.isEmpty())
208 return false;
209 //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
210 return isPersistent(index: idx) && hiddenIndexes.contains(value: idx);
211 }
212
213 inline bool isItemHiddenOrDisabled(int i) const {
214 if (i < 0 || i >= viewItems.size())
215 return false;
216 const QModelIndex index = viewItems.at(i).index;
217 return isRowHidden(idx: index) || !isIndexEnabled(index);
218 }
219
220 inline int above(int item) const
221 { int i = item; while (isItemHiddenOrDisabled(i: --item)){} return item < 0 ? i : item; }
222 inline int below(int item) const
223 { int i = item; while (isItemHiddenOrDisabled(i: ++item)){} return item >= viewItems.size() ? i : item; }
224 inline void invalidateHeightCache(int item) const
225 { viewItems[item].height = 0; }
226
227 inline int accessibleTable2Index(const QModelIndex &index) const {
228 return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column();
229 }
230
231 int accessibleTree2Index(const QModelIndex &index) const;
232
233 void updateIndentationFromStyle();
234
235 // used for spanning rows
236 QSet<QPersistentModelIndex> spanningIndexes;
237
238 // used for updating resized columns
239 int columnResizeTimerID;
240 QList<int> columnsToUpdate;
241
242 // used for the automatic opening of nodes during DND
243 int autoExpandDelay;
244 QBasicTimer openTimer;
245
246 // used for drawing highlighted expand/collapse indicators
247 mutable int hoverBranch;
248
249 // used for blocking recursion when calling setViewportMargins from updateGeometries
250 bool geometryRecursionBlock;
251
252 // If we should clean the set
253 bool hasRemovedItems;
254
255 // tree position
256 int treePosition;
257};
258
259QT_END_NAMESPACE
260
261#endif // QTREEVIEW_P_H
262

source code of qtbase/src/widgets/itemviews/qtreeview_p.h