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// Qt-Security score:significant reason:default
4
5#ifndef QHEADERVIEW_P_H
6#define QHEADERVIEW_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtWidgets/private/qtwidgetsglobal_p.h>
20#include "qheaderview.h"
21#include "private/qabstractitemview_p.h"
22
23#include "QtCore/qbitarray.h"
24#include "QtWidgets/qapplication.h"
25#if QT_CONFIG(label)
26#include "QtWidgets/qlabel.h"
27#endif
28
29#include <array>
30
32
33QT_BEGIN_NAMESPACE
34
35// Currently we support huge models with no memory per section if people are not resizing sections and not ordering sections.
36// 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).
37
38enum HeaderMode
39{
40 InitialNoSectionMemoryUsage, // Initial state - we don't use any memory per section until needed (needed on resize, swap, move, hide etc)
41 FlexibleWithSectionMemoryUsage, // user can hide, resize and reorder sections at the cost of memory usage.
42};
43
45{
46 Q_DECLARE_PUBLIC(QHeaderView)
47
48public:
49 enum StateVersion { VersionMarker = 0xff };
50
52 : state(NoState),
53 headerOffset(0),
56 sortIndicatorShown(false),
58 lastPos(-1),
59 firstPos(-1),
60 originalSize(-1),
61 section(-1),
62 target(-1),
63 firstPressed(-1),
64 pressed(-1),
65 hover(-1),
66 length(0),
68 movableSections(false),
69 clickableSections(false),
70 highlightSelected(false),
71 stretchLastSection(false),
72 cascadingResizing(false),
74 allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView
81 lastSectionLogicalIdx(-1), // Only trust when we stretch last section
83#if QT_CONFIG(label)
84 sectionIndicator(nullptr),
85#endif
89 {}
90
91
92 int lastVisibleVisualIndex() const;
94 void setNewLastSection(int visualIndexForLastSection);
96 int sectionHandleAt(int position);
97 void setupSectionIndicator(int section, int position);
98 void updateSectionIndicator(int section, int position);
99 void updateHiddenSections(int logicalFirst, int logicalLast);
100 void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
101 void sectionsRemoved(const QModelIndex &,int,int);
102 void sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart,
103 int logicalEnd, const QModelIndex &destinationParent,
104 int logicalDestination);
105 void sectionsMoved(const QModelIndex &sourceParent, int logicalStart,
106 int logicalEnd, const QModelIndex &destinationParent,
107 int logicalDestination);
108 void sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
109 QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
110 void sectionsChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
111 QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
112
113 bool isSectionSelected(int section) const;
114 bool isFirstVisibleSection(int section) const;
115 bool isLastVisibleSection(int section) const;
116
117 inline bool rowIntersectsSelection(int row) const {
118 return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false);
119 }
120
121 inline bool columnIntersectsSelection(int column) const {
122 return (selectionModel ? selectionModel->columnIntersectsSelection(column, root) : false);
123 }
124
125 inline bool sectionIntersectsSelection(int logical) const {
126 return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical));
127 }
128
129 inline bool isRowSelected(int row) const {
130 return (selectionModel ? selectionModel->isRowSelected(row, root) : false);
131 }
132
133 inline bool isColumnSelected(int column) const {
134 return (selectionModel ? selectionModel->isColumnSelected(column, root) : false);
135 }
136
138 if (!selectionModel || !selectionModel->hasSelection())
139 sectionSelected.clear();
140 else if (sectionSelected.size() != sectionCount() * 2)
141 sectionSelected.fill(false, sectionCount() * 2);
142 else sectionSelected.fill(false);
143 }
144
145 inline int sectionCount() const {
146 return noSectionMemoryUsage() ? countInNoSectionItemsMode : sectionItems.size();
147 }
148
149 inline bool reverse() const {
150 return orientation == Qt::Horizontal && q_func()->isRightToLeft();
151 }
152
153 inline int logicalIndex(int visualIndex) const {
154 return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex);
155 }
156
157 inline int visualIndex(int logicalIndex) const {
158 return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex);
159 }
160
161 inline void setDefaultValues(Qt::Orientation o) {
162 orientation = o;
164 defaultAlignment = (o == Qt::Horizontal
165 ? Qt::Alignment(Qt::AlignCenter)
166 : Qt::AlignLeft|Qt::AlignVCenter);
167 }
168
169 inline bool isVisualIndexHidden(int visual) const {
170 return !noSectionMemoryUsage() && sectionItems.at(visual).isHidden;
171 }
172
173 inline void setVisualIndexHidden(int visual, bool hidden) {
174 sectionItems[visual].isHidden = hidden;
175 }
176
177 inline bool hasAutoResizeSections() const {
179 }
180
181 QStyleOptionHeader getStyleOption() const;
182
183 inline void invalidateCachedSizeHint() const {
184 cachedSizeHint = QSize();
185 }
186
187 inline void initializeIndexMapping() const {
188 if (visualIndices.size() != sectionCount()
189 || logicalIndices.size() != sectionCount()) {
190 visualIndices.resize(sectionCount());
191 logicalIndices.resize(sectionCount());
192 for (int s = 0; s < sectionCount(); ++s) {
193 visualIndices[s] = s;
194 logicalIndices[s] = s;
195 }
196 }
197 }
198
200 firstCascadingSection = sectionItems.size();
202 cascadingSectionSize.clear();
203 }
204
205 inline void saveCascadingSectionSize(int visual, int size) {
206 if (!cascadingSectionSize.contains(visual)) {
207 cascadingSectionSize.insert(visual, size);
210 }
211 }
212
213 inline bool sectionIsCascadable(int visual) const {
214 return headerSectionResizeMode(visual) == QHeaderView::Interactive;
215 }
216
217 inline int modelSectionCount() const {
218 return (orientation == Qt::Horizontal
219 ? model->columnCount(root)
220 : model->rowCount(root));
221 }
222
224 if (!delayedResize.isActive())
225 delayedResize.start(0, q_func());
226 }
227
228 inline void executePostedResize() const {
229 if (delayedResize.isActive() && state == NoState) {
230 const_cast<QHeaderView*>(q_func())->resizeSections();
231 }
232 }
233
234 inline void disconnectModel()
235 {
236 for (const QMetaObject::Connection &connection : modelConnections)
237 QObject::disconnect(connection);
238 }
239
240 void clear();
241 void flipSortIndicator(int section);
242 Qt::SortOrder defaultSortOrderForSection(int section) const;
243 void cascadingResize(int visual, int newSize);
244
246
253
254 mutable QList<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
255 mutable QList<int> logicalIndices; // logicalIndex = row or column in the model
256 mutable QBitArray sectionSelected; // from logical index to bit
257 mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
258 mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
261
264
268 int section; // used for resizing and moving sections
272 int hover;
273
291 int lastSectionLogicalIdx; // Only trust if we stretch LastSection
294#if QT_CONFIG(label)
296#endif
300 // header sections
301
302 struct SectionItem {
303 uint size : 20;
305 uint resizeMode : 5; // (holding QHeaderView::ResizeMode)
307
308 union { // This union is made in order to save space and ensure good vector performance (on remove)
309 mutable int calculated_startpos; // <- this is the primary used member.
310 mutable int tmpLogIdx; // When one of these 'tmp'-members has been used we call
311 int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true
312 }; // to ensure that calculated_startpos will be calculated afterwards.
313
317 inline int sectionSize() const { return size; }
318 inline int calculatedEndPos() const { return calculated_startpos + size; }
319#ifndef QT_NO_DATASTREAM
320 inline void write(QDataStream &out) const
321 { out << static_cast<int>(size); out << 1; out << (int)resizeMode; }
322 inline void read(QDataStream &in)
323 { int m; in >> m; size = m; in >> tmpDataStreamSectionCount; in >> m; resizeMode = m; }
324#endif
325 };
326
328
329 HeaderMode headerMode = HeaderMode::InitialNoSectionMemoryUsage;
331 inline bool noSectionMemoryUsage() const
332 {
333 return (headerMode == HeaderMode::InitialNoSectionMemoryUsage);
334 }
335
337 {
338 setHeaderMode(HeaderMode::FlexibleWithSectionMemoryUsage);
339 }
340
341 void updateCountInNoSectionItemsMode(int newCount);
342 void setHeaderMode(HeaderMode mode);
343
350
351 void createSectionItems(int start, int end, int sectionSize, QHeaderView::ResizeMode mode);
352 void removeSectionsFromSectionItems(int start, int end);
353 void resizeSectionItem(int visualIndex, int oldSize, int newSize);
354 void setDefaultSectionSize(int size);
356 void recalcSectionStartPos() const; // not really const
357
358 inline int headerLength() const { // for debugging
359 int len = 0;
360 for (const auto &section : sectionItems)
361 len += section.size;
362 return len;
363 }
364
366 {
367 QBitArray sectionHidden;
368 if (!hiddenSectionSize.isEmpty()) {
369 sectionHidden.resize(sectionItems.size());
370 for (int u = 0; u < sectionItems.size(); ++u)
371 sectionHidden[u] = sectionItems.at(u).isHidden;
372 }
373 return sectionHidden;
374 }
375
376 void setHiddenSectionsFromBitVector(const QBitArray &sectionHidden) {
377 SectionItem *sectionData = sectionItems.data();
378 for (int i = 0; i < sectionHidden.size(); ++i)
379 sectionData[i].isHidden = sectionHidden.at(i);
380 }
381
382 int headerSectionSize(int visual) const;
383 int headerSectionPosition(int visual) const;
384 int headerVisualIndexAt(int position) const;
385
386 // resize mode
387 void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode);
389 void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode);
390
391 // other
392 int viewSectionSizeHint(int logical) const;
393 int adjustedVisualIndex(int visualIndex) const;
394 void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode);
395 void updateSectionsBeforeAfter(int logical);
396
397#ifndef QT_NO_DATASTREAM
398 void write(QDataStream &out) const;
399 bool read(QDataStream &in);
400#endif
401
402};
405
406QT_END_NAMESPACE
407
408#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)