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 QHEADERVIEW_P_H |
5 | #define |
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 | |
21 | #include "QtCore/qbitarray.h" |
22 | #include "QtWidgets/qapplication.h" |
23 | #if QT_CONFIG(label) |
24 | #include "QtWidgets/qlabel.h" |
25 | #endif |
26 | |
27 | QT_REQUIRE_CONFIG(itemviews); |
28 | |
29 | QT_BEGIN_NAMESPACE |
30 | |
31 | class : public QAbstractItemViewPrivate |
32 | { |
33 | Q_DECLARE_PUBLIC(QHeaderView) |
34 | |
35 | public: |
36 | enum { = 0xff }; |
37 | |
38 | () |
39 | : state(NoState), |
40 | offset(0), |
41 | sortIndicatorOrder(Qt::DescendingOrder), |
42 | sortIndicatorSection(0), |
43 | sortIndicatorShown(false), |
44 | sortIndicatorClearable(false), |
45 | lastPos(-1), |
46 | firstPos(-1), |
47 | originalSize(-1), |
48 | section(-1), |
49 | target(-1), |
50 | firstPressed(-1), |
51 | pressed(-1), |
52 | hover(-1), |
53 | length(0), |
54 | preventCursorChangeInSetOffset(false), |
55 | movableSections(false), |
56 | clickableSections(false), |
57 | highlightSelected(false), |
58 | stretchLastSection(false), |
59 | cascadingResizing(false), |
60 | resizeRecursionBlock(false), |
61 | allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView |
62 | customDefaultSectionSize(false), |
63 | stretchSections(0), |
64 | contentsSections(0), |
65 | minimumSectionSize(-1), |
66 | maximumSectionSize(-1), |
67 | lastSectionSize(0), |
68 | lastSectionLogicalIdx(-1), // Only trust when we stretch last section |
69 | sectionIndicatorOffset(0), |
70 | #if QT_CONFIG(label) |
71 | sectionIndicator(nullptr), |
72 | #endif |
73 | globalResizeMode(QHeaderView::Interactive), |
74 | sectionStartposRecalc(true), |
75 | resizeContentsPrecision(1000) |
76 | {} |
77 | |
78 | |
79 | int () const; |
80 | void (); |
81 | void (int visualIndexForLastSection); |
82 | void maybeRestorePrevLastSectionAndStretchLast(); |
83 | int sectionHandleAt(int position); |
84 | void (int section, int position); |
85 | void (int section, int position); |
86 | void (int logicalFirst, int logicalLast); |
87 | void (QHeaderView::ResizeMode globalMode, bool useGlobalMode = false); |
88 | void (const QModelIndex &,int,int); |
89 | void (const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination); |
90 | void (const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination); |
91 | void (const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(), |
92 | QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); |
93 | void (const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(), |
94 | QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); |
95 | |
96 | bool (int section) const; |
97 | bool (int section) const; |
98 | bool (int section) const; |
99 | |
100 | inline bool (int row) const { |
101 | return (selectionModel ? selectionModel->rowIntersectsSelection(row, parent: root) : false); |
102 | } |
103 | |
104 | inline bool columnIntersectsSelection(int column) const { |
105 | return (selectionModel ? selectionModel->columnIntersectsSelection(column, parent: root) : false); |
106 | } |
107 | |
108 | inline bool (int logical) const { |
109 | return (orientation == Qt::Horizontal ? columnIntersectsSelection(column: logical) : rowIntersectsSelection(row: logical)); |
110 | } |
111 | |
112 | inline bool (int row) const { |
113 | return (selectionModel ? selectionModel->isRowSelected(row, parent: root) : false); |
114 | } |
115 | |
116 | inline bool isColumnSelected(int column) const { |
117 | return (selectionModel ? selectionModel->isColumnSelected(column, parent: root) : false); |
118 | } |
119 | |
120 | inline void () { |
121 | if (!selectionModel || !selectionModel->hasSelection()) |
122 | sectionSelected.clear(); |
123 | else if (sectionSelected.size() != sectionCount() * 2) |
124 | sectionSelected.fill(aval: false, asize: sectionCount() * 2); |
125 | else sectionSelected.fill(aval: false); |
126 | } |
127 | |
128 | inline int () const {return sectionItems.size();} |
129 | |
130 | inline bool () const { |
131 | return orientation == Qt::Horizontal && q_func()->isRightToLeft(); |
132 | } |
133 | |
134 | inline int (int visualIndex) const { |
135 | return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(i: visualIndex); |
136 | } |
137 | |
138 | inline int (int logicalIndex) const { |
139 | return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(i: logicalIndex); |
140 | } |
141 | |
142 | inline void (Qt::Orientation o) { |
143 | orientation = o; |
144 | updateDefaultSectionSizeFromStyle(); |
145 | defaultAlignment = (o == Qt::Horizontal |
146 | ? Qt::Alignment(Qt::AlignCenter) |
147 | : Qt::AlignLeft|Qt::AlignVCenter); |
148 | } |
149 | |
150 | inline bool (int visual) const { |
151 | return sectionItems.at(i: visual).isHidden; |
152 | } |
153 | |
154 | inline void (int visual, bool hidden) { |
155 | sectionItems[visual].isHidden = hidden; |
156 | } |
157 | |
158 | inline bool () const { |
159 | return stretchSections || stretchLastSection || contentsSections; |
160 | } |
161 | |
162 | QStyleOptionHeader () const; |
163 | |
164 | inline void () const { |
165 | cachedSizeHint = QSize(); |
166 | } |
167 | |
168 | inline void () const { |
169 | if (visualIndices.size() != sectionCount() |
170 | || logicalIndices.size() != sectionCount()) { |
171 | visualIndices.resize(size: sectionCount()); |
172 | logicalIndices.resize(size: sectionCount()); |
173 | for (int s = 0; s < sectionCount(); ++s) { |
174 | visualIndices[s] = s; |
175 | logicalIndices[s] = s; |
176 | } |
177 | } |
178 | } |
179 | |
180 | inline void () { |
181 | firstCascadingSection = sectionItems.size(); |
182 | lastCascadingSection = 0; |
183 | cascadingSectionSize.clear(); |
184 | } |
185 | |
186 | inline void (int visual, int size) { |
187 | if (!cascadingSectionSize.contains(key: visual)) { |
188 | cascadingSectionSize.insert(key: visual, value: size); |
189 | firstCascadingSection = qMin(a: firstCascadingSection, b: visual); |
190 | lastCascadingSection = qMax(a: lastCascadingSection, b: visual); |
191 | } |
192 | } |
193 | |
194 | inline bool (int visual) const { |
195 | return headerSectionResizeMode(visual) == QHeaderView::Interactive; |
196 | } |
197 | |
198 | inline int () const { |
199 | return (orientation == Qt::Horizontal |
200 | ? model->columnCount(parent: root) |
201 | : model->rowCount(parent: root)); |
202 | } |
203 | |
204 | inline void () { |
205 | if (!delayedResize.isActive()) |
206 | delayedResize.start(msec: 0, obj: q_func()); |
207 | } |
208 | |
209 | inline void () const { |
210 | if (delayedResize.isActive() && state == NoState) { |
211 | const_cast<QHeaderView*>(q_func())->resizeSections(); |
212 | } |
213 | } |
214 | |
215 | void (); |
216 | void (int section); |
217 | Qt::SortOrder (int section) const; |
218 | void (int visual, int newSize); |
219 | |
220 | enum { , , , , } ; |
221 | |
222 | int ; |
223 | Qt::Orientation ; |
224 | Qt::SortOrder ; |
225 | int ; |
226 | bool ; |
227 | bool ; |
228 | |
229 | mutable QList<int> ; // visualIndex = visualIndices.at(logicalIndex) |
230 | mutable QList<int> ; // logicalIndex = row or column in the model |
231 | mutable QBitArray ; // from logical index to bit |
232 | mutable QHash<int, int> ; // from logical index to section size |
233 | mutable QHash<int, int> ; // from visual index to section size |
234 | mutable QSize ; |
235 | mutable QBasicTimer ; |
236 | |
237 | int ; |
238 | int ; |
239 | |
240 | int ; |
241 | int ; |
242 | int ; |
243 | int ; // used for resizing and moving sections |
244 | int ; |
245 | int ; |
246 | int ; |
247 | int ; |
248 | |
249 | int ; |
250 | bool ; |
251 | bool ; |
252 | bool ; |
253 | bool ; |
254 | bool ; |
255 | bool ; |
256 | bool ; |
257 | bool ; |
258 | bool ; |
259 | int ; |
260 | int ; |
261 | int ; |
262 | int ; |
263 | int ; |
264 | int ; |
265 | int ; // Only trust if we stretch LastSection |
266 | int ; |
267 | Qt::Alignment ; |
268 | #if QT_CONFIG(label) |
269 | QLabel *; |
270 | #endif |
271 | QHeaderView::ResizeMode ; |
272 | mutable bool ; |
273 | int ; |
274 | // header sections |
275 | |
276 | struct { |
277 | uint : 20; |
278 | uint : 1; |
279 | uint : 5; // (holding QHeaderView::ResizeMode) |
280 | uint : 6; |
281 | |
282 | union { // This union is made in order to save space and ensure good vector performance (on remove) |
283 | mutable int ; // <- this is the primary used member. |
284 | mutable int ; // When one of these 'tmp'-members has been used we call |
285 | int ; // recalcSectionStartPos() or set sectionStartposRecalc to true |
286 | }; // to ensure that calculated_startpos will be calculated afterwards. |
287 | |
288 | inline () : size(0), isHidden(0), resizeMode(QHeaderView::Interactive) {} |
289 | inline (int length, QHeaderView::ResizeMode mode) |
290 | : size(length), isHidden(0), resizeMode(mode), calculated_startpos(-1) {} |
291 | inline int () const { return size; } |
292 | inline int () const { return calculated_startpos + size; } |
293 | #ifndef QT_NO_DATASTREAM |
294 | inline void (QDataStream &out) const |
295 | { out << static_cast<int>(size); out << 1; out << (int)resizeMode; } |
296 | inline void (QDataStream &in) |
297 | { int m; in >> m; size = m; in >> tmpDataStreamSectionCount; in >> m; resizeMode = m; } |
298 | #endif |
299 | }; |
300 | |
301 | QList<SectionItem> ; |
302 | struct { |
303 | QPersistentModelIndex ; |
304 | SectionItem ; |
305 | }; |
306 | QList<LayoutChangeItem> ; |
307 | |
308 | void (int start, int end, int sectionSize, QHeaderView::ResizeMode mode); |
309 | void (int start, int end); |
310 | void (int visualIndex, int oldSize, int newSize); |
311 | void (int size); |
312 | void (); |
313 | void () const; // not really const |
314 | |
315 | inline int () const { // for debugging |
316 | int len = 0; |
317 | for (const auto §ion : sectionItems) |
318 | len += section.size; |
319 | return len; |
320 | } |
321 | |
322 | QBitArray () const |
323 | { |
324 | QBitArray sectionHidden; |
325 | if (!hiddenSectionSize.isEmpty()) { |
326 | sectionHidden.resize(size: sectionItems.size()); |
327 | for (int u = 0; u < sectionItems.size(); ++u) |
328 | sectionHidden[u] = sectionItems.at(i: u).isHidden; |
329 | } |
330 | return sectionHidden; |
331 | } |
332 | |
333 | void (const QBitArray §ionHidden) { |
334 | SectionItem *sectionData = sectionItems.data(); |
335 | for (int i = 0; i < sectionHidden.size(); ++i) |
336 | sectionData[i].isHidden = sectionHidden.at(i); |
337 | } |
338 | |
339 | int (int visual) const; |
340 | int (int visual) const; |
341 | int (int position) const; |
342 | |
343 | // resize mode |
344 | void (int visual, QHeaderView::ResizeMode mode); |
345 | QHeaderView::ResizeMode (int visual) const; |
346 | void (QHeaderView::ResizeMode mode); |
347 | |
348 | // other |
349 | int (int logical) const; |
350 | int (int visualIndex) const; |
351 | void (const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode); |
352 | void (int logical); |
353 | |
354 | #ifndef QT_NO_DATASTREAM |
355 | void (QDataStream &out) const; |
356 | bool (QDataStream &in); |
357 | #endif |
358 | |
359 | }; |
360 | Q_DECLARE_TYPEINFO(QHeaderViewPrivate::SectionItem, Q_PRIMITIVE_TYPE); |
361 | Q_DECLARE_TYPEINFO(QHeaderViewPrivate::LayoutChangeItem, Q_RELOCATABLE_TYPE); |
362 | |
363 | QT_END_NAMESPACE |
364 | |
365 | #endif // QHEADERVIEW_P_H |
366 | |