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