Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qheaderview_p.h
Go to the documentation of this file.
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 QHEADERVIEW_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 "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
31
32QT_BEGIN_NAMESPACE
33
34// Currently we support huge models with no memory per section if people are not resizing sections and not ordering sections.
35// This enum is unlikely to be public later on. (Either we go for a huge model bool or another ("subset") enum not containing the initial mode).
36
37enum HeaderMode
38{
39 InitialNoSectionMemoryUsage, // Initial state - we don't use any memory per section until needed (needed on resize, swap, move, hide etc)
40 FlexibleWithSectionMemoryUsage, // user can hide, resize and reorder sections at the cost of memory usage.
41};
42
44{
45 Q_DECLARE_PUBLIC(QHeaderView)
46
47public:
48 enum StateVersion { VersionMarker = 0xff };
49
51 : state(NoState),
52 headerOffset(0),
55 sortIndicatorShown(false),
57 lastPos(-1),
58 firstPos(-1),
59 originalSize(-1),
60 section(-1),
61 target(-1),
62 firstPressed(-1),
63 pressed(-1),
64 hover(-1),
65 length(0),
67 movableSections(false),
68 clickableSections(false),
69 highlightSelected(false),
70 stretchLastSection(false),
71 cascadingResizing(false),
73 allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView
80 lastSectionLogicalIdx(-1), // Only trust when we stretch last section
82#if QT_CONFIG(label)
83 sectionIndicator(nullptr),
84#endif
88 {}
89
90
91 int lastVisibleVisualIndex() const;
93 void setNewLastSection(int visualIndexForLastSection);
95 int sectionHandleAt(int position);
96 void setupSectionIndicator(int section, int position);
97 void updateSectionIndicator(int section, int position);
98 void updateHiddenSections(int logicalFirst, int logicalLast);
99 void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
100 void sectionsRemoved(const QModelIndex &,int,int);
101 void sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart,
102 int logicalEnd, const QModelIndex &destinationParent,
103 int logicalDestination);
104 void sectionsMoved(const QModelIndex &sourceParent, int logicalStart,
105 int logicalEnd, const QModelIndex &destinationParent,
106 int logicalDestination);
107 void sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
108 QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
109 void sectionsChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
110 QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
111
112 bool isSectionSelected(int section) const;
113 bool isFirstVisibleSection(int section) const;
114 bool isLastVisibleSection(int section) const;
115
116 inline bool rowIntersectsSelection(int row) const {
117 return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false);
118 }
119
120 inline bool columnIntersectsSelection(int column) const {
121 return (selectionModel ? selectionModel->columnIntersectsSelection(column, root) : false);
122 }
123
124 inline bool sectionIntersectsSelection(int logical) const {
125 return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical));
126 }
127
128 inline bool isRowSelected(int row) const {
129 return (selectionModel ? selectionModel->isRowSelected(row, root) : false);
130 }
131
132 inline bool isColumnSelected(int column) const {
133 return (selectionModel ? selectionModel->isColumnSelected(column, root) : false);
134 }
135
137 if (!selectionModel || !selectionModel->hasSelection())
138 sectionSelected.clear();
139 else if (sectionSelected.size() != sectionCount() * 2)
140 sectionSelected.fill(false, sectionCount() * 2);
141 else sectionSelected.fill(false);
142 }
143
144 inline int sectionCount() const {
145 return noSectionMemoryUsage() ? countInNoSectionItemsMode : sectionItems.size();
146 }
147
148 inline bool reverse() const {
149 return orientation == Qt::Horizontal && q_func()->isRightToLeft();
150 }
151
152 inline int logicalIndex(int visualIndex) const {
153 return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex);
154 }
155
156 inline int visualIndex(int logicalIndex) const {
157 return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex);
158 }
159
160 inline void setDefaultValues(Qt::Orientation o) {
161 orientation = o;
163 defaultAlignment = (o == Qt::Horizontal
164 ? Qt::Alignment(Qt::AlignCenter)
165 : Qt::AlignLeft|Qt::AlignVCenter);
166 }
167
168 inline bool isVisualIndexHidden(int visual) const {
169 return !noSectionMemoryUsage() && sectionItems.at(visual).isHidden;
170 }
171
172 inline void setVisualIndexHidden(int visual, bool hidden) {
173 sectionItems[visual].isHidden = hidden;
174 }
175
176 inline bool hasAutoResizeSections() const {
178 }
179
180 QStyleOptionHeader getStyleOption() const;
181
182 inline void invalidateCachedSizeHint() const {
183 cachedSizeHint = QSize();
184 }
185
186 inline void initializeIndexMapping() const {
187 if (visualIndices.size() != sectionCount()
188 || logicalIndices.size() != sectionCount()) {
189 visualIndices.resize(sectionCount());
190 logicalIndices.resize(sectionCount());
191 for (int s = 0; s < sectionCount(); ++s) {
192 visualIndices[s] = s;
193 logicalIndices[s] = s;
194 }
195 }
196 }
197
199 firstCascadingSection = sectionItems.size();
201 cascadingSectionSize.clear();
202 }
203
204 inline void saveCascadingSectionSize(int visual, int size) {
205 if (!cascadingSectionSize.contains(visual)) {
206 cascadingSectionSize.insert(visual, size);
209 }
210 }
211
212 inline bool sectionIsCascadable(int visual) const {
213 return headerSectionResizeMode(visual) == QHeaderView::Interactive;
214 }
215
216 inline int modelSectionCount() const {
217 return (orientation == Qt::Horizontal
218 ? model->columnCount(root)
219 : model->rowCount(root));
220 }
221
223 if (!delayedResize.isActive())
224 delayedResize.start(0, q_func());
225 }
226
227 inline void executePostedResize() const {
228 if (delayedResize.isActive() && state == NoState) {
229 const_cast<QHeaderView*>(q_func())->resizeSections();
230 }
231 }
232
233 inline void disconnectModel()
234 {
235 for (const QMetaObject::Connection &connection : modelConnections)
236 QObject::disconnect(connection);
237 }
238
239 void clear();
240 void flipSortIndicator(int section);
241 Qt::SortOrder defaultSortOrderForSection(int section) const;
242 void cascadingResize(int visual, int newSize);
243
245
252
253 mutable QList<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
254 mutable QList<int> logicalIndices; // logicalIndex = row or column in the model
255 mutable QBitArray sectionSelected; // from logical index to bit
256 mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
257 mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
260
263
267 int section; // used for resizing and moving sections
271 int hover;
272
290 int lastSectionLogicalIdx; // Only trust if we stretch LastSection
293#if QT_CONFIG(label)
295#endif
299 // header sections
300
301 struct SectionItem {
302 uint size : 20;
304 uint resizeMode : 5; // (holding QHeaderView::ResizeMode)
306
307 union { // This union is made in order to save space and ensure good vector performance (on remove)
308 mutable int calculated_startpos; // <- this is the primary used member.
309 mutable int tmpLogIdx; // When one of these 'tmp'-members has been used we call
310 int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true
311 }; // to ensure that calculated_startpos will be calculated afterwards.
312
316 inline int sectionSize() const { return size; }
317 inline int calculatedEndPos() const { return calculated_startpos + size; }
318#ifndef QT_NO_DATASTREAM
319 inline void write(QDataStream &out) const
320 { out << static_cast<int>(size); out << 1; out << (int)resizeMode; }
321 inline void read(QDataStream &in)
322 { int m; in >> m; size = m; in >> tmpDataStreamSectionCount; in >> m; resizeMode = m; }
323#endif
324 };
325
327
328 HeaderMode headerMode = HeaderMode::InitialNoSectionMemoryUsage;
330 inline bool noSectionMemoryUsage() const
331 {
332 return (headerMode == HeaderMode::InitialNoSectionMemoryUsage);
333 }
334
336 {
337 setHeaderMode(HeaderMode::FlexibleWithSectionMemoryUsage);
338 }
339
340 void updateCountInNoSectionItemsMode(int newCount);
341 void setHeaderMode(HeaderMode mode);
342
349
350 void createSectionItems(int start, int end, int sectionSize, QHeaderView::ResizeMode mode);
351 void removeSectionsFromSectionItems(int start, int end);
352 void resizeSectionItem(int visualIndex, int oldSize, int newSize);
353 void setDefaultSectionSize(int size);
355 void recalcSectionStartPos() const; // not really const
356
357 inline int headerLength() const { // for debugging
358 int len = 0;
359 for (const auto &section : sectionItems)
360 len += section.size;
361 return len;
362 }
363
365 {
366 QBitArray sectionHidden;
367 if (!hiddenSectionSize.isEmpty()) {
368 sectionHidden.resize(sectionItems.size());
369 for (int u = 0; u < sectionItems.size(); ++u)
370 sectionHidden[u] = sectionItems.at(u).isHidden;
371 }
372 return sectionHidden;
373 }
374
375 void setHiddenSectionsFromBitVector(const QBitArray &sectionHidden) {
376 SectionItem *sectionData = sectionItems.data();
377 for (int i = 0; i < sectionHidden.size(); ++i)
378 sectionData[i].isHidden = sectionHidden.at(i);
379 }
380
381 int headerSectionSize(int visual) const;
382 int headerSectionPosition(int visual) const;
383 int headerVisualIndexAt(int position) const;
384
385 // resize mode
386 void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode);
388 void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode);
389
390 // other
391 int viewSectionSizeHint(int logical) const;
392 int adjustedVisualIndex(int visualIndex) const;
393 void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode);
394 void updateSectionsBeforeAfter(int logical);
395
396#ifndef QT_NO_DATASTREAM
397 void write(QDataStream &out) const;
398 bool read(QDataStream &in);
399#endif
400
401};
404
405QT_END_NAMESPACE
406
407#endif // QHEADERVIEW_P_H
int headerSectionSize(int visual) const
void updateDefaultSectionSizeFromStyle()
void sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination)
int headerLength() const
int headerVisualIndexAt(int position) const
void cascadingResize(int visual, int newSize)
Qt::SortOrder defaultSortOrderForSection(int section) const
void saveCascadingSectionSize(int visual, int size)
void setupSectionIndicator(int section, int position)
Qt::Alignment defaultAlignment
void setDefaultValues(Qt::Orientation o)
int logicalIndex(int visualIndex) const
void recalcSectionStartPos() const
void setNewLastSection(int visualIndexForLastSection)
void sectionsRemoved(const QModelIndex &, int, int)
void initializeIndexMapping() const
void sectionsAboutToBeChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
void updateHiddenSections(int logicalFirst, int logicalLast)
void invalidateCachedSizeHint() const
bool rowIntersectsSelection(int row) const
void removeSectionsFromSectionItems(int start, int end)
Qt::Orientation orientation
QBitArray sectionSelected
void updateSectionIndicator(int section, int position)
int sectionCount() const
bool noSectionMemoryUsage() const
void setHeaderMode(HeaderMode mode)
int lastVisibleVisualIndex() const
void createSectionItems(int start, int end, int sectionSize, QHeaderView::ResizeMode mode)
QHash< int, int > cascadingSectionSize
std::array< QMetaObject::Connection, 8 > modelConnections
bool sectionIsCascadable(int visual) const
int modelSectionCount() const
bool read(QDataStream &in)
bool isFirstVisibleSection(int section) const
bool isSectionSelected(int section) const
void restoreSizeOnPrevLastSection()
void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode)
void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode=false)
bool reverse() const
int headerSectionPosition(int visual) const
void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode)
void flipSortIndicator(int section)
bool isColumnSelected(int column) const
void write(QDataStream &out) const
bool preventCursorChangeInSetOffset
void executePostedResize() const
void setHiddenSectionsFromBitVector(const QBitArray &sectionHidden)
void sectionsMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination)
void switchToFlexibleModeWithSectionMemoryUsage()
int adjustedVisualIndex(int visualIndex) const
bool isRowSelected(int row) const
int visualIndex(int logicalIndex) const
bool isVisualIndexHidden(int visual) const
QStyleOptionHeader getStyleOption() const
QList< int > logicalIndices
void resizeSectionItem(int visualIndex, int oldSize, int newSize)
bool isLastVisibleSection(int section) const
int sectionHandleAt(int position)
qsizetype countInNoSectionItemsMode
void setVisualIndexHidden(int visual, bool hidden)
void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode)
QBasicTimer delayedResize
QList< LayoutChangeItem > layoutChangePersistentSections
bool columnIntersectsSelection(int column) const
QHash< int, int > hiddenSectionSize
Qt::SortOrder sortIndicatorOrder
bool sectionIntersectsSelection(int logical) const
void setDefaultSectionSize(int size)
void maybeRestorePrevLastSectionAndStretchLast()
QBitArray sectionsHiddenToBitVector() const
void updateCountInNoSectionItemsMode(int newCount)
void updateSectionsBeforeAfter(int logical)
void sectionsChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
QList< int > visualIndices
int viewSectionSizeHint(int logical) const
bool hasAutoResizeSections() const
QList< SectionItem > sectionItems
QT_REQUIRE_CONFIG(itemviews)
Q_DECLARE_TYPEINFO(QHeaderViewPrivate::LayoutChangeItem, Q_RELOCATABLE_TYPE)
Q_DECLARE_TYPEINFO(QHeaderViewPrivate::SectionItem, Q_PRIMITIVE_TYPE)
void write(QDataStream &out) const
SectionItem(int length, QHeaderView::ResizeMode mode)