Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/items/qquicktableview_p_p.h |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||
2 | ** | - | ||||||
3 | ** Copyright (C) 2018 The Qt Company Ltd. | - | ||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||
5 | ** | - | ||||||
6 | ** This file is part of the QtQuick module of the Qt Toolkit. | - | ||||||
7 | ** | - | ||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||
9 | ** Commercial License Usage | - | ||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||
16 | ** | - | ||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||
24 | ** | - | ||||||
25 | ** GNU General Public License Usage | - | ||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||
35 | ** | - | ||||||
36 | ** $QT_END_LICENSE$ | - | ||||||
37 | ** | - | ||||||
38 | ****************************************************************************/ | - | ||||||
39 | - | |||||||
40 | // | - | ||||||
41 | // W A R N I N G | - | ||||||
42 | // ------------- | - | ||||||
43 | // | - | ||||||
44 | // This file is not part of the Qt API. It exists purely as an | - | ||||||
45 | // implementation detail. This header file may change from version to | - | ||||||
46 | // version without notice, or even be removed. | - | ||||||
47 | // | - | ||||||
48 | // We mean it. | - | ||||||
49 | // | - | ||||||
50 | - | |||||||
51 | #include "qquicktableview_p.h" | - | ||||||
52 | - | |||||||
53 | #include <QtCore/qtimer.h> | - | ||||||
54 | #include <QtQml/private/qqmldelegatemodel_p.h> | - | ||||||
55 | #include <QtQml/private/qqmlincubator_p.h> | - | ||||||
56 | #include <QtQml/private/qqmlchangeset_p.h> | - | ||||||
57 | #include <QtQml/qqmlinfo.h> | - | ||||||
58 | - | |||||||
59 | #include <QtQuick/private/qquickflickable_p_p.h> | - | ||||||
60 | #include <QtQuick/private/qquickitemviewfxitem_p_p.h> | - | ||||||
61 | - | |||||||
62 | QT_BEGIN_NAMESPACE | - | ||||||
63 | - | |||||||
64 | Q_DECLARE_LOGGING_CATEGORY(lcTableViewDelegateLifecycle) | - | ||||||
65 | - | |||||||
66 | static const int kDefaultCacheBuffer = 300; | - | ||||||
67 | static const qreal kDefaultRowHeight = 50; | - | ||||||
68 | static const qreal kDefaultColumnWidth = 50; | - | ||||||
69 | - | |||||||
70 | class FxTableItem; | - | ||||||
71 | - | |||||||
72 | class Q_QML_AUTOTEST_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate | - | ||||||
73 | { | - | ||||||
74 | Q_DECLARE_PUBLIC(QQuickTableView) | - | ||||||
75 | - | |||||||
76 | public: | - | ||||||
77 | class TableEdgeLoadRequest | - | ||||||
78 | { | - | ||||||
79 | // Whenever we need to load new rows or columns in the | - | ||||||
80 | // table, we fill out a TableEdgeLoadRequest. | - | ||||||
81 | // TableEdgeLoadRequest is just a struct that keeps track | - | ||||||
82 | // of which cells that needs to be loaded, and which cell | - | ||||||
83 | // the table is currently loading. The loading itself is | - | ||||||
84 | // done by QQuickTableView. | - | ||||||
85 | - | |||||||
86 | public: | - | ||||||
87 | void begin(const QPoint &cell, QQmlIncubator::IncubationMode incubationMode) | - | ||||||
88 | { | - | ||||||
89 | Q_ASSERT(!active); | - | ||||||
90 | active = true; | - | ||||||
91 | tableEdge = Qt::Edge(0); | - | ||||||
92 | tableCells = QLine(cell, cell); | - | ||||||
93 | mode = incubationMode; | - | ||||||
94 | cellCount = 1; | - | ||||||
95 | currentIndex = 0; | - | ||||||
96 | qCDebug(lcTableViewDelegateLifecycle()) << "begin top-left:" << toString(); never executed: QMessageLogger(__FILE__, 96, __PRETTY_FUNCTION__, lcTableViewDelegateLifecycle()().categoryName()).debug() << "begin top-left:" << toString();
| 0 | ||||||
97 | } never executed: end of block | 0 | ||||||
98 | - | |||||||
99 | void begin(const QLine cellsToLoad, Qt::Edge edgeToLoad, QQmlIncubator::IncubationMode incubationMode) | - | ||||||
100 | { | - | ||||||
101 | Q_ASSERT(!active); | - | ||||||
102 | active = true; | - | ||||||
103 | tableEdge = edgeToLoad; | - | ||||||
104 | tableCells = cellsToLoad; | - | ||||||
105 | mode = incubationMode; | - | ||||||
106 | cellCount = tableCells.x2() - tableCells.x1() + tableCells.y2() - tableCells.y1() + 1; | - | ||||||
107 | currentIndex = 0; | - | ||||||
108 | qCDebug(lcTableViewDelegateLifecycle()) << "begin:" << toString(); never executed: QMessageLogger(__FILE__, 108, __PRETTY_FUNCTION__, lcTableViewDelegateLifecycle()().categoryName()).debug() << "begin:" << toString();
| 0 | ||||||
109 | } never executed: end of block | 0 | ||||||
110 | - | |||||||
111 | inline void markAsDone() { active = false; } never executed: end of block | 0 | ||||||
112 | inline bool isActive() { return active; } executed 816 times by 1 test: return active; Executed by:
| 816 | ||||||
113 | - | |||||||
114 | inline QPoint firstCell() { return tableCells.p1(); } never executed: return tableCells.p1(); | 0 | ||||||
115 | inline QPoint lastCell() { return tableCells.p2(); } never executed: return tableCells.p2(); | 0 | ||||||
116 | inline QPoint currentCell() { return cellAt(currentIndex); } never executed: return cellAt(currentIndex); | 0 | ||||||
117 | inline QPoint previousCell() { return cellAt(currentIndex - 1); } never executed: return cellAt(currentIndex - 1); | 0 | ||||||
118 | - | |||||||
119 | inline bool atBeginning() { return currentIndex == 0; } never executed: return currentIndex == 0; | 0 | ||||||
120 | inline bool hasCurrentCell() { return currentIndex < cellCount; } never executed: return currentIndex < cellCount; | 0 | ||||||
121 | inline void moveToNextCell() { ++currentIndex; } never executed: end of block | 0 | ||||||
122 | - | |||||||
123 | inline Qt::Edge edge() { return tableEdge; } never executed: return tableEdge; | 0 | ||||||
124 | inline QQmlIncubator::IncubationMode incubationMode() { return mode; } never executed: return mode; | 0 | ||||||
125 | - | |||||||
126 | QString toString() | - | ||||||
127 | { | - | ||||||
128 | QString str; | - | ||||||
129 | QDebug dbg(&str); | - | ||||||
130 | dbg.nospace() << "TableSectionLoadRequest(" << "edge:" | - | ||||||
131 | << tableEdge << " cells:" << tableCells << " incubation:"; | - | ||||||
132 | - | |||||||
133 | switch (mode) { | - | ||||||
134 | case QQmlIncubator::Asynchronous: never executed: case QQmlIncubator::Asynchronous: | 0 | ||||||
135 | dbg << "Asynchronous"; | - | ||||||
136 | break; never executed: break; | 0 | ||||||
137 | case QQmlIncubator::AsynchronousIfNested: never executed: case QQmlIncubator::AsynchronousIfNested: | 0 | ||||||
138 | dbg << "AsynchronousIfNested"; | - | ||||||
139 | break; never executed: break; | 0 | ||||||
140 | case QQmlIncubator::Synchronous: never executed: case QQmlIncubator::Synchronous: | 0 | ||||||
141 | dbg << "Synchronous"; | - | ||||||
142 | break; never executed: break; | 0 | ||||||
143 | } | - | ||||||
144 | - | |||||||
145 | return str; never executed: return str; | 0 | ||||||
146 | } | - | ||||||
147 | - | |||||||
148 | private: | - | ||||||
149 | Qt::Edge tableEdge = Qt::Edge(0); | - | ||||||
150 | QLine tableCells; | - | ||||||
151 | int currentIndex = 0; | - | ||||||
152 | int cellCount = 0; | - | ||||||
153 | bool active = false; | - | ||||||
154 | QQmlIncubator::IncubationMode mode = QQmlIncubator::AsynchronousIfNested; | - | ||||||
155 | - | |||||||
156 | QPoint cellAt(int index) | - | ||||||
157 | { | - | ||||||
158 | int x = tableCells.p1().x() + (tableCells.dx() ? index : 0);
| 0 | ||||||
159 | int y = tableCells.p1().y() + (tableCells.dy() ? index : 0);
| 0 | ||||||
160 | return QPoint(x, y); never executed: return QPoint(x, y); | 0 | ||||||
161 | } | - | ||||||
162 | }; | - | ||||||
163 | - | |||||||
164 | struct ColumnRowSize | - | ||||||
165 | { | - | ||||||
166 | // ColumnRowSize is a helper class for storing row heights | - | ||||||
167 | // and column widths. We calculate the average width of a column | - | ||||||
168 | // the first time it's scrolled into view based on the size of | - | ||||||
169 | // the loaded items in the new column. Since we never load more items | - | ||||||
170 | // that what fits inside the viewport (cachebuffer aside), this calculation | - | ||||||
171 | // would be different depending on which row you were at when the column | - | ||||||
172 | // was scrolling in. To avoid that a column resizes when it's scrolled | - | ||||||
173 | // in and out and in again, we store its width. But to avoid storing | - | ||||||
174 | // the width for all columns, we choose to only store the width if it | - | ||||||
175 | // differs from the column(s) to the left. The same logic applies for row heights. | - | ||||||
176 | // 'index' translates to either 'row' or 'column'. | - | ||||||
177 | int index; | - | ||||||
178 | qreal size; | - | ||||||
179 | - | |||||||
180 | static bool lessThan(const ColumnRowSize& a, const ColumnRowSize& b) | - | ||||||
181 | { | - | ||||||
182 | return a.index < b.index; never executed: return a.index < b.index; | 0 | ||||||
183 | } | - | ||||||
184 | }; | - | ||||||
185 | - | |||||||
186 | public: | - | ||||||
187 | QQuickTableViewPrivate(); | - | ||||||
188 | ~QQuickTableViewPrivate() override; | - | ||||||
189 | - | |||||||
190 | static inline QQuickTableViewPrivate *get(QQuickTableView *q) { return q->d_func(); } never executed: return q->d_func(); | 0 | ||||||
191 | - | |||||||
192 | void updatePolish() override; | - | ||||||
193 | - | |||||||
194 | public: | - | ||||||
195 | QHash<int, FxTableItem *> loadedItems; | - | ||||||
196 | - | |||||||
197 | // model, delegateModel and modelVariant all points to the same model. modelVariant | - | ||||||
198 | // is the model assigned by the user. And delegateModel is the wrapper model we create | - | ||||||
199 | // around it. But if the model is an instance model directly, we cannot wrap it, so | - | ||||||
200 | // we need a pointer for that case as well. | - | ||||||
201 | QQmlInstanceModel* model = nullptr; | - | ||||||
202 | QPointer<QQmlDelegateModel> delegateModel = nullptr; | - | ||||||
203 | QVariant modelVariant; | - | ||||||
204 | - | |||||||
205 | // loadedTable describes the table cells that are currently loaded (from top left | - | ||||||
206 | // row/column to bottom right row/column). loadedTableOuterRect describes the actual | - | ||||||
207 | // pixels that those cells cover, and is matched agains the viewport to determine when | - | ||||||
208 | // we need to fill up with more rows/columns. loadedTableInnerRect describes the pixels | - | ||||||
209 | // that the loaded table covers if you remove one row/column on each side of the table, and | - | ||||||
210 | // is used to determine rows/columns that are no longer visible and can be unloaded. | - | ||||||
211 | QRect loadedTable; | - | ||||||
212 | QRectF loadedTableOuterRect; | - | ||||||
213 | QRectF loadedTableInnerRect; | - | ||||||
214 | - | |||||||
215 | QRectF viewportRect = QRectF(0, 0, -1, -1); | - | ||||||
216 | - | |||||||
217 | QSize tableSize; | - | ||||||
218 | - | |||||||
219 | TableEdgeLoadRequest loadRequest; | - | ||||||
220 | - | |||||||
221 | QPoint contentSizeBenchMarkPoint = QPoint(-1, -1); | - | ||||||
222 | QSizeF cellSpacing; | - | ||||||
223 | QMarginsF tableMargins; | - | ||||||
224 | - | |||||||
225 | int cacheBuffer = kDefaultCacheBuffer; | - | ||||||
226 | QTimer cacheBufferDelayTimer; | - | ||||||
227 | bool hasBufferedItems = false; | - | ||||||
228 | - | |||||||
229 | bool blockItemCreatedCallback = false; | - | ||||||
230 | bool tableInvalid = false; | - | ||||||
231 | bool tableRebuilding = false; | - | ||||||
232 | bool columnRowPositionsInvalid = false; | - | ||||||
233 | - | |||||||
234 | QVector<ColumnRowSize> columnWidths; | - | ||||||
235 | QVector<ColumnRowSize> rowHeights; | - | ||||||
236 | - | |||||||
237 | const static QPoint kLeft; | - | ||||||
238 | const static QPoint kRight; | - | ||||||
239 | const static QPoint kUp; | - | ||||||
240 | const static QPoint kDown; | - | ||||||
241 | - | |||||||
242 | #ifdef QT_DEBUG | - | ||||||
243 | QString forcedIncubationMode = qEnvironmentVariable("QT_TABLEVIEW_INCUBATION_MODE"); | - | ||||||
244 | #endif | - | ||||||
245 | - | |||||||
246 | public: | - | ||||||
247 | QQuickTableViewAttached *getAttachedObject(const QObject *object) const; | - | ||||||
248 | - | |||||||
249 | int modelIndexAtCell(const QPoint &cell) const; | - | ||||||
250 | QPoint cellAtModelIndex(int modelIndex) const; | - | ||||||
251 | - | |||||||
252 | void calculateColumnWidthsAfterRebuilding(); | - | ||||||
253 | void calculateRowHeightsAfterRebuilding(); | - | ||||||
254 | void calculateColumnWidth(int column); | - | ||||||
255 | void calculateRowHeight(int row); | - | ||||||
256 | void calculateEdgeSizeFromLoadRequest(); | - | ||||||
257 | void calculateTableSize(); | - | ||||||
258 | - | |||||||
259 | qreal columnWidth(int column); | - | ||||||
260 | qreal rowHeight(int row); | - | ||||||
261 | - | |||||||
262 | void relayoutTable(); | - | ||||||
263 | void relayoutTableItems(); | - | ||||||
264 | - | |||||||
265 | void layoutVerticalEdge(Qt::Edge tableEdge); | - | ||||||
266 | void layoutHorizontalEdge(Qt::Edge tableEdge); | - | ||||||
267 | void layoutTopLeftItem(); | - | ||||||
268 | void layoutTableEdgeFromLoadRequest(); | - | ||||||
269 | - | |||||||
270 | void updateContentWidth(); | - | ||||||
271 | void updateContentHeight(); | - | ||||||
272 | - | |||||||
273 | void enforceFirstRowColumnAtOrigo(); | - | ||||||
274 | void syncLoadedTableRectFromLoadedTable(); | - | ||||||
275 | void syncLoadedTableFromLoadRequest(); | - | ||||||
276 | - | |||||||
277 | bool canLoadTableEdge(Qt::Edge tableEdge, const QRectF fillRect) const; | - | ||||||
278 | bool canUnloadTableEdge(Qt::Edge tableEdge, const QRectF fillRect) const; | - | ||||||
279 | Qt::Edge nextEdgeToLoad(const QRectF rect); | - | ||||||
280 | Qt::Edge nextEdgeToUnload(const QRectF rect); | - | ||||||
281 | - | |||||||
282 | qreal cellWidth(const QPoint &cell); | - | ||||||
283 | qreal cellHeight(const QPoint &cell); | - | ||||||
284 | - | |||||||
285 | FxTableItem *loadedTableItem(const QPoint &cell) const; | - | ||||||
286 | FxTableItem *itemNextTo(const FxTableItem *fxTableItem, const QPoint &direction) const; | - | ||||||
287 | FxTableItem *createFxTableItem(const QPoint &cell, QQmlIncubator::IncubationMode incubationMode); | - | ||||||
288 | FxTableItem *loadFxTableItem(const QPoint &cell, QQmlIncubator::IncubationMode incubationMode); | - | ||||||
289 | - | |||||||
290 | void releaseItem(FxTableItem *fxTableItem); | - | ||||||
291 | void releaseLoadedItems(); | - | ||||||
292 | void clear(); | - | ||||||
293 | - | |||||||
294 | void unloadItem(const QPoint &cell); | - | ||||||
295 | void unloadItems(const QLine &items); | - | ||||||
296 | - | |||||||
297 | void loadInitialTopLeftItem(); | - | ||||||
298 | void loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMode incubationMode); | - | ||||||
299 | void unloadEdge(Qt::Edge edge); | - | ||||||
300 | void loadAndUnloadVisibleEdges(); | - | ||||||
301 | void cancelLoadRequest(); | - | ||||||
302 | void processLoadRequest(); | - | ||||||
303 | void beginRebuildTable(); | - | ||||||
304 | void endRebuildTable(); | - | ||||||
305 | - | |||||||
306 | void loadBuffer(); | - | ||||||
307 | void unloadBuffer(); | - | ||||||
308 | QRectF bufferRect(); | - | ||||||
309 | - | |||||||
310 | void invalidateTable(); | - | ||||||
311 | void invalidateColumnRowPositions(); | - | ||||||
312 | - | |||||||
313 | void createWrapperModel(); | - | ||||||
314 | - | |||||||
315 | void initItemCallback(int modelIndex, QObject *item); | - | ||||||
316 | void itemCreatedCallback(int modelIndex, QObject *object); | - | ||||||
317 | void modelUpdated(const QQmlChangeSet &changeSet, bool reset); | - | ||||||
318 | - | |||||||
319 | inline QString tableLayoutToString() const; | - | ||||||
320 | void dumpTable() const; | - | ||||||
321 | }; | - | ||||||
322 | - | |||||||
323 | class FxTableItem : public QQuickItemViewFxItem | - | ||||||
324 | { | - | ||||||
325 | public: | - | ||||||
326 | FxTableItem(QQuickItem *item, QQuickTableView *table, bool own) | - | ||||||
327 | : QQuickItemViewFxItem(item, own, QQuickTableViewPrivate::get(table)) | - | ||||||
328 | { | - | ||||||
329 | } never executed: end of block | 0 | ||||||
330 | - | |||||||
331 | qreal position() const override { return 0; } never executed: return 0; | 0 | ||||||
332 | qreal endPosition() const override { return 0; } never executed: return 0; | 0 | ||||||
333 | qreal size() const override { return 0; } never executed: return 0; | 0 | ||||||
334 | qreal sectionSize() const override { return 0; } never executed: return 0; | 0 | ||||||
335 | bool contains(qreal, qreal) const override { return false; } never executed: return false; | 0 | ||||||
336 | - | |||||||
337 | QPoint cell; | - | ||||||
338 | }; | - | ||||||
339 | - | |||||||
340 | Q_DECLARE_TYPEINFO(QQuickTableViewPrivate::ColumnRowSize, Q_PRIMITIVE_TYPE); | - | ||||||
341 | - | |||||||
342 | QT_END_NAMESPACE | - | ||||||
Source code | Switch to Preprocessed file |