1 | // Copyright (C) 2018 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 QQUICKTABLEVIEW_P_P_H |
5 | #define QQUICKTABLEVIEW_P_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 "qquicktableview_p.h" |
19 | |
20 | #include <QtCore/qtimer.h> |
21 | #include <QtCore/qitemselectionmodel.h> |
22 | #include <QtQmlModels/private/qqmltableinstancemodel_p.h> |
23 | #include <QtQml/private/qqmlincubator_p.h> |
24 | #include <QtQmlModels/private/qqmlchangeset_p.h> |
25 | #include <QtQml/qqmlinfo.h> |
26 | |
27 | #include <QtQuick/private/qquickflickable_p_p.h> |
28 | #include <QtQuick/private/qquickitemviewfxitem_p_p.h> |
29 | #include <QtQuick/private/qquickanimation_p.h> |
30 | #include <QtQuick/private/qquickselectable_p.h> |
31 | #include <QtQuick/private/qquicksinglepointhandler_p.h> |
32 | #include <QtQuick/private/qquickhoverhandler_p.h> |
33 | #include <QtQuick/private/qquicktaphandler_p.h> |
34 | |
35 | #include <QtCore/private/qminimalflatset_p.h> |
36 | |
37 | #if QT_CONFIG(quick_draganddrop) |
38 | #include <QtGui/qdrag.h> |
39 | #include <QtQuick/private/qquickdroparea_p.h> |
40 | #endif |
41 | |
42 | QT_BEGIN_NAMESPACE |
43 | |
44 | Q_DECLARE_LOGGING_CATEGORY(lcTableViewDelegateLifecycle) |
45 | |
46 | static const qreal kDefaultRowHeight = 50; |
47 | static const qreal kDefaultColumnWidth = 50; |
48 | static const int kEdgeIndexNotSet = -2; |
49 | static const int kEdgeIndexAtEnd = -3; |
50 | |
51 | class FxTableItem; |
52 | class QQuickTableSectionSizeProviderPrivate; |
53 | |
54 | /*! \internal |
55 | * TableView uses QQuickTableViewHoverHandler to track where the pointer is |
56 | * on top of the table, and change the cursor at the places where a drag |
57 | * would start a resize of a row or a column. |
58 | */ |
59 | class QQuickTableViewHoverHandler : public QQuickHoverHandler |
60 | { |
61 | Q_OBJECT |
62 | |
63 | public: |
64 | QQuickTableViewHoverHandler(QQuickTableView *view); |
65 | inline bool isHoveringGrid() const { return m_row != -1 || m_column != -1; }; |
66 | |
67 | int m_row = -1; |
68 | int m_column = -1; |
69 | |
70 | friend class QQuickTableViewPrivate; |
71 | |
72 | protected: |
73 | void handleEventPoint(QPointerEvent *event, QEventPoint &point) override; |
74 | }; |
75 | |
76 | class QQuickTableViewPointerHandler : public QQuickSinglePointHandler |
77 | { |
78 | Q_OBJECT |
79 | |
80 | public: |
81 | enum State { |
82 | Listening, // the pointer is not being pressed between the cells |
83 | Tracking, // the pointer is being pressed between the cells |
84 | DraggingStarted, // dragging started |
85 | Dragging, // a drag is ongoing |
86 | DraggingFinished // dragging was finished |
87 | }; |
88 | |
89 | QQuickTableViewPointerHandler(QQuickTableView *view); |
90 | |
91 | State m_state = Listening; |
92 | State state() { return m_state; } |
93 | |
94 | protected: |
95 | bool wantsEventPoint(const QPointerEvent *event, const QEventPoint &point) override; |
96 | }; |
97 | |
98 | /*! \internal |
99 | * TableView uses QQuickTableViewResizeHandler to enable the user to resize |
100 | * rows and columns. By using a custom pointer handler, we can get away with |
101 | * using a single pointer handler for the whole content item, rather than |
102 | * e.g having to split it up into multiple items with drag handlers placed |
103 | * between the cells. |
104 | */ |
105 | class QQuickTableViewResizeHandler : public QQuickTableViewPointerHandler |
106 | { |
107 | Q_OBJECT |
108 | |
109 | public: |
110 | QQuickTableViewResizeHandler(QQuickTableView *view); |
111 | |
112 | int m_row = -1; |
113 | qreal m_rowStartY = -1; |
114 | qreal m_rowStartHeight = -1; |
115 | |
116 | int m_column = -1; |
117 | qreal m_columnStartX = -1; |
118 | qreal m_columnStartWidth = -1; |
119 | |
120 | void updateState(QEventPoint &point); |
121 | void updateDrag(QPointerEvent *event, QEventPoint &point); |
122 | |
123 | friend class QQuickTableViewPrivate; |
124 | |
125 | protected: |
126 | void handleEventPoint(QPointerEvent *event, QEventPoint &point) override; |
127 | void onGrabChanged(QQuickPointerHandler *grabber, QPointingDevice::GrabTransition transition, |
128 | QPointerEvent *ev, QEventPoint &point) override; |
129 | }; |
130 | |
131 | #if QT_CONFIG(quick_draganddrop) |
132 | class QQuickTableViewSectionDragHandler : public QQuickTableViewPointerHandler |
133 | { |
134 | Q_OBJECT |
135 | |
136 | public: |
137 | QQuickTableViewSectionDragHandler(QQuickTableView *view); |
138 | ~QQuickTableViewSectionDragHandler(); |
139 | |
140 | void grabSection(); |
141 | |
142 | void handleDrag(QQuickDragEvent *event); |
143 | void handleDrop(QQuickDragEvent *event); |
144 | void handleDragDropAction(Qt::DropAction action); |
145 | |
146 | void setSectionOrientation(Qt::Orientation orientation) { m_sectionOrientation = orientation; } |
147 | |
148 | friend class QQuickTableViewPrivate; |
149 | |
150 | protected: |
151 | void handleEventPoint(QPointerEvent *event, QEventPoint &point) override; |
152 | |
153 | private: |
154 | void resetDragData(); |
155 | void resetSectionOverlay(); |
156 | |
157 | QSharedPointer<QQuickItemGrabResult> m_grabResult; |
158 | QPointer<QDrag> m_drag; |
159 | int m_source = -1; |
160 | int m_destination = -1; |
161 | QPointer<QQuickDropArea> m_dropArea; |
162 | Qt::Orientation m_sectionOrientation; |
163 | |
164 | QPointF m_dragPoint; |
165 | QSizeF m_step = QSizeF(1, 1); |
166 | QTimer m_scrollTimer; |
167 | }; |
168 | #endif // quick_draganddrop |
169 | |
170 | /*! \internal |
171 | * QQuickTableViewTapHandler used to handle tap events explicitly for table view |
172 | */ |
173 | class QQuickTableViewTapHandler : public QQuickTapHandler |
174 | { |
175 | Q_OBJECT |
176 | |
177 | public: |
178 | explicit QQuickTableViewTapHandler(QQuickTableView *view); |
179 | bool wantsEventPoint(const QPointerEvent *event, const QEventPoint &point) override; |
180 | |
181 | friend class QQuickTableViewPrivate; |
182 | }; |
183 | |
184 | class Q_QUICK_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate, public QQuickSelectable |
185 | { |
186 | public: |
187 | Q_DECLARE_PUBLIC(QQuickTableView) |
188 | |
189 | class TableEdgeLoadRequest |
190 | { |
191 | // Whenever we need to load new rows or columns in the |
192 | // table, we fill out a TableEdgeLoadRequest. |
193 | // TableEdgeLoadRequest is just a struct that keeps track |
194 | // of which cells that needs to be loaded, and which cell |
195 | // the table is currently loading. The loading itself is |
196 | // done by QQuickTableView. |
197 | |
198 | public: |
199 | void begin(const QPoint &cell, const QPointF &pos, QQmlIncubator::IncubationMode incubationMode) |
200 | { |
201 | Q_ASSERT(!m_active); |
202 | m_active = true; |
203 | m_edge = Qt::Edge(0); |
204 | m_mode = incubationMode; |
205 | m_edgeIndex = cell.x(); |
206 | m_visibleCellsInEdge.clear(); |
207 | m_visibleCellsInEdge.append(t: cell.y()); |
208 | m_currentIndex = 0; |
209 | m_startPos = pos; |
210 | qCDebug(lcTableViewDelegateLifecycle()) << "begin top-left:"<< toString(); |
211 | } |
212 | |
213 | void begin(Qt::Edge edgeToLoad, int edgeIndex, const QVector<int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode) |
214 | { |
215 | Q_ASSERT(!m_active); |
216 | m_active = true; |
217 | m_edge = edgeToLoad; |
218 | m_edgeIndex = edgeIndex; |
219 | m_visibleCellsInEdge = visibleCellsInEdge; |
220 | m_mode = incubationMode; |
221 | m_currentIndex = 0; |
222 | qCDebug(lcTableViewDelegateLifecycle()) << "begin:"<< toString(); |
223 | } |
224 | |
225 | inline void markAsDone() { m_active = false; } |
226 | inline bool isActive() const { return m_active; } |
227 | |
228 | inline QPoint currentCell() const { return cellAt(index: m_currentIndex); } |
229 | inline bool hasCurrentCell() const { return m_currentIndex < m_visibleCellsInEdge.size(); } |
230 | inline void moveToNextCell() { ++m_currentIndex; } |
231 | |
232 | inline Qt::Edge edge() const { return m_edge; } |
233 | inline int row() const { return cellAt(index: 0).y(); } |
234 | inline int column() const { return cellAt(index: 0).x(); } |
235 | inline QQmlIncubator::IncubationMode incubationMode() const { return m_mode; } |
236 | |
237 | inline QPointF startPosition() const { return m_startPos; } |
238 | |
239 | QString toString() const |
240 | { |
241 | QString str; |
242 | QDebug dbg(&str); |
243 | dbg.nospace() << "TableSectionLoadRequest("<< "edge:" |
244 | << m_edge << ", edgeIndex:"<< m_edgeIndex << ", incubation:"; |
245 | |
246 | switch (m_mode) { |
247 | case QQmlIncubator::Asynchronous: |
248 | dbg << "Asynchronous"; |
249 | break; |
250 | case QQmlIncubator::AsynchronousIfNested: |
251 | dbg << "AsynchronousIfNested"; |
252 | break; |
253 | case QQmlIncubator::Synchronous: |
254 | dbg << "Synchronous"; |
255 | break; |
256 | } |
257 | |
258 | return str; |
259 | } |
260 | |
261 | private: |
262 | Qt::Edge m_edge = Qt::Edge(0); |
263 | QVector<int> m_visibleCellsInEdge; |
264 | int m_edgeIndex = 0; |
265 | int m_currentIndex = 0; |
266 | bool m_active = false; |
267 | QQmlIncubator::IncubationMode m_mode = QQmlIncubator::AsynchronousIfNested; |
268 | QPointF m_startPos; |
269 | |
270 | inline QPoint cellAt(int index) const { |
271 | return !m_edge || (m_edge & (Qt::LeftEdge | Qt::RightEdge)) |
272 | ? QPoint(m_edgeIndex, m_visibleCellsInEdge[index]) |
273 | : QPoint(m_visibleCellsInEdge[index], m_edgeIndex); |
274 | } |
275 | }; |
276 | |
277 | class EdgeRange { |
278 | public: |
279 | EdgeRange(); |
280 | bool containsIndex(Qt::Edge edge, int index); |
281 | |
282 | int startIndex; |
283 | int endIndex; |
284 | qreal size; |
285 | }; |
286 | |
287 | enum class RebuildState { |
288 | Begin = 0, |
289 | LoadInitalTable, |
290 | VerifyTable, |
291 | LayoutTable, |
292 | CancelOvershoot, |
293 | UpdateContentSize, |
294 | PreloadColumns, |
295 | PreloadRows, |
296 | MovePreloadedItemsToPool, |
297 | Done |
298 | }; |
299 | |
300 | enum class SectionState { |
301 | Idle = 0, |
302 | Moving |
303 | }; |
304 | |
305 | enum class RebuildOption { |
306 | None = 0, |
307 | All = 0x1, |
308 | LayoutOnly = 0x2, |
309 | ViewportOnly = 0x4, |
310 | CalculateNewTopLeftRow = 0x8, |
311 | CalculateNewTopLeftColumn = 0x10, |
312 | CalculateNewContentWidth = 0x20, |
313 | CalculateNewContentHeight = 0x40, |
314 | PositionViewAtRow = 0x80, |
315 | PositionViewAtColumn = 0x100, |
316 | }; |
317 | Q_DECLARE_FLAGS(RebuildOptions, RebuildOption) |
318 | |
319 | public: |
320 | QQuickTableViewPrivate(); |
321 | ~QQuickTableViewPrivate() override; |
322 | |
323 | static inline QQuickTableViewPrivate *get(QQuickTableView *q) { return q->d_func(); } |
324 | |
325 | void updatePolish() override; |
326 | void fixup(AxisData &data, qreal minExtent, qreal maxExtent) override; |
327 | |
328 | public: |
329 | QHash<int, FxTableItem *> loadedItems; |
330 | |
331 | // model, tableModel and modelVariant all point to the same model. modelVariant |
332 | // is the model assigned by the user. And tableModel is the wrapper model we create |
333 | // around it. But if the model is an instance model directly, we cannot wrap it, so |
334 | // we need a pointer for that case as well. |
335 | QQmlInstanceModel* model = nullptr; |
336 | QPointer<QQmlTableInstanceModel> tableModel = nullptr; |
337 | QVariant modelVariant; |
338 | |
339 | // When the applications assignes a new model or delegate to the view, we keep them |
340 | // around until we're ready to take them into use (syncWithPendingChanges). |
341 | QVariant assignedModel = QVariant(int(0)); |
342 | QQmlGuard<QQmlComponent> assignedDelegate; |
343 | |
344 | // loadedRows/Columns describes the rows and columns that are currently loaded (from top left |
345 | // row/column to bottom right row/column). loadedTableOuterRect describes the actual |
346 | // pixels that all the loaded delegate items cover, and is matched agains the viewport to determine when |
347 | // we need to fill up with more rows/columns. loadedTableInnerRect describes the pixels |
348 | // that the loaded table covers if you remove one row/column on each side of the table, and |
349 | // is used to determine rows/columns that are no longer visible and can be unloaded. |
350 | QMinimalFlatSet<int> loadedColumns; |
351 | QMinimalFlatSet<int> loadedRows; |
352 | QRectF loadedTableOuterRect; |
353 | QRectF loadedTableInnerRect; |
354 | |
355 | QPointF origin = QPointF(0, 0); |
356 | QSizeF endExtent = QSizeF(0, 0); |
357 | |
358 | QRectF viewportRect = QRectF(0, 0, -1, -1); |
359 | |
360 | QSize tableSize; |
361 | |
362 | RebuildState rebuildState = RebuildState::Done; |
363 | RebuildOptions rebuildOptions = RebuildOption::All; |
364 | RebuildOptions scheduledRebuildOptions = RebuildOption::All; |
365 | |
366 | TableEdgeLoadRequest loadRequest; |
367 | |
368 | QSizeF cellSpacing = QSizeF(0, 0); |
369 | |
370 | QQmlTableInstanceModel::ReusableFlag reusableFlag = QQmlTableInstanceModel::Reusable; |
371 | |
372 | bool blockItemCreatedCallback = false; |
373 | mutable bool layoutWarningIssued = false; |
374 | bool polishing = false; |
375 | bool syncVertically = false; |
376 | bool syncHorizontally = false; |
377 | bool inSetLocalViewportPos = false; |
378 | bool inSyncViewportPosRecursive = false; |
379 | bool inUpdateContentSize = false; |
380 | bool animate = true; |
381 | bool keyNavigationEnabled = true; |
382 | bool pointerNavigationEnabled = true; |
383 | bool alternatingRows = true; |
384 | bool resizableColumns = false; |
385 | bool resizableRows = false; |
386 | #if QT_CONFIG(cursor) |
387 | bool m_cursorSet = false; |
388 | #endif |
389 | |
390 | // isTransposed is currently only used by HeaderView. |
391 | // Consider making it public. |
392 | bool isTransposed = false; |
393 | |
394 | bool warnNoSelectionModel = true; |
395 | |
396 | QJSValue rowHeightProvider; |
397 | QJSValue columnWidthProvider; |
398 | |
399 | mutable EdgeRange cachedNextVisibleEdgeIndex[4]; |
400 | mutable EdgeRange cachedColumnWidth; |
401 | mutable EdgeRange cachedRowHeight; |
402 | |
403 | // TableView uses contentWidth/height to report the size of the table (this |
404 | // will e.g make scrollbars written for Flickable work out of the box). This |
405 | // value is continuously calculated, and will change/improve as more columns |
406 | // are loaded into view. At the same time, we want to open up for the |
407 | // possibility that the application can set the content width explicitly, in |
408 | // case it knows what the exact width should be from the start. We therefore |
409 | // override the contentWidth/height properties from QQuickFlickable, to be able |
410 | // to implement this combined behavior. This also lets us lazy build the table |
411 | // if the application needs to know the content size early on. |
412 | QQmlNullableValue<qreal> explicitContentWidth; |
413 | QQmlNullableValue<qreal> explicitContentHeight; |
414 | |
415 | QSizeF averageEdgeSize; |
416 | |
417 | QPointer<QQuickTableView> assignedSyncView; |
418 | QPointer<QQuickTableView> syncView; |
419 | QList<QPointer<QQuickTableView> > syncChildren; |
420 | Qt::Orientations assignedSyncDirection = Qt::Horizontal | Qt::Vertical; |
421 | |
422 | QPointer<QItemSelectionModel> selectionModel; |
423 | QQuickTableView::SelectionBehavior selectionBehavior = QQuickTableView::SelectCells; |
424 | QQuickTableView::SelectionMode selectionMode = QQuickTableView::ExtendedSelection; |
425 | QItemSelectionModel::SelectionFlag selectionFlag = QItemSelectionModel::NoUpdate; |
426 | std::function<void(CallBackFlag)> selectableCallbackFunction; |
427 | bool inSelectionModelUpdate = false; |
428 | |
429 | int assignedPositionViewAtRowAfterRebuild = 0; |
430 | int assignedPositionViewAtColumnAfterRebuild = 0; |
431 | int positionViewAtRowAfterRebuild = 0; |
432 | int positionViewAtColumnAfterRebuild = 0; |
433 | qreal positionViewAtRowOffset = 0; |
434 | qreal positionViewAtColumnOffset = 0; |
435 | QRectF positionViewAtRowSubRect; |
436 | QRectF positionViewAtColumnSubRect; |
437 | Qt::Alignment positionViewAtRowAlignment = Qt::AlignTop; |
438 | Qt::Alignment positionViewAtColumnAlignment = Qt::AlignLeft; |
439 | |
440 | QQuickPropertyAnimation positionXAnimation; |
441 | QQuickPropertyAnimation positionYAnimation; |
442 | |
443 | QPoint selectionStartCell = {-1, -1}; |
444 | QPoint selectionEndCell = {-1, -1}; |
445 | QItemSelection existingSelection; |
446 | |
447 | QMargins edgesBeforeRebuild; |
448 | QSize tableSizeBeforeRebuild; |
449 | |
450 | int currentRow = -1; |
451 | int currentColumn = -1; |
452 | |
453 | QHash<int, qreal> explicitColumnWidths; |
454 | QHash<int, qreal> explicitRowHeights; |
455 | |
456 | QQuickTableViewHoverHandler *hoverHandler = nullptr; |
457 | QQuickTableViewResizeHandler *resizeHandler = nullptr; |
458 | #if QT_CONFIG(quick_draganddrop) |
459 | QQuickTableViewSectionDragHandler *sectionDragHandler = nullptr; |
460 | #endif |
461 | QQuickTableViewPointerHandler *activePtrHandler = nullptr; |
462 | |
463 | QQmlTableInstanceModel *editModel = nullptr; |
464 | QQuickItem *editItem = nullptr; |
465 | QPersistentModelIndex editIndex; |
466 | QQuickTableView::EditTriggers editTriggers = QQuickTableView::DoubleTapped | QQuickTableView::EditKeyPressed; |
467 | |
468 | #ifdef QT_DEBUG |
469 | QString forcedIncubationMode = qEnvironmentVariable(varName: "QT_TABLEVIEW_INCUBATION_MODE"); |
470 | #endif |
471 | |
472 | struct SectionData { |
473 | int index = -1; |
474 | int prevIndex = -1; |
475 | }; |
476 | |
477 | QList<SectionData> visualIndices[Qt::Vertical]; |
478 | QList<SectionData> logicalIndices[Qt::Vertical]; |
479 | |
480 | SectionState m_sectionState = SectionState::Idle; |
481 | |
482 | public: |
483 | void init(); |
484 | |
485 | QQuickTableViewAttached *getAttachedObject(const QObject *object) const; |
486 | |
487 | int modelIndexAtCell(const QPoint &cell) const; |
488 | QPoint cellAtModelIndex(int modelIndex) const; |
489 | int modelIndexToCellIndex(const QModelIndex &modelIndex, bool visualIndex = true) const; |
490 | inline bool cellIsValid(const QPoint &cell) const { return cell.x() != -1 && cell.y() != -1; } |
491 | |
492 | qreal sizeHintForColumn(int column) const; |
493 | qreal sizeHintForRow(int row) const; |
494 | QSize calculateTableSize(); |
495 | void updateTableSize(); |
496 | |
497 | inline bool isColumnHidden(int column) const; |
498 | inline bool isRowHidden(int row) const; |
499 | |
500 | qreal getColumnLayoutWidth(int column); |
501 | qreal getRowLayoutHeight(int row); |
502 | qreal getColumnWidth(int column) const; |
503 | qreal getRowHeight(int row) const; |
504 | qreal getEffectiveRowY(int row) const; |
505 | qreal getEffectiveRowHeight(int row) const; |
506 | qreal getEffectiveColumnX(int column) const; |
507 | qreal getEffectiveColumnWidth(int column) const; |
508 | qreal getAlignmentContentX(int column, Qt::Alignment alignment, const qreal offset, const QRectF &subRect); |
509 | qreal getAlignmentContentY(int row, Qt::Alignment alignment, const qreal offset, const QRectF &subRect); |
510 | |
511 | int topRow() const { return *loadedRows.cbegin(); } |
512 | int bottomRow() const { return *loadedRows.crbegin(); } |
513 | int leftColumn() const { return *loadedColumns.cbegin(); } |
514 | int rightColumn() const { return *loadedColumns.crbegin(); } |
515 | |
516 | QQuickTableView *rootSyncView() const; |
517 | |
518 | bool updateTableRecursive(); |
519 | bool updateTable(); |
520 | void relayoutTableItems(); |
521 | |
522 | void layoutVerticalEdge(Qt::Edge tableEdge); |
523 | void layoutHorizontalEdge(Qt::Edge tableEdge); |
524 | void layoutTopLeftItem(); |
525 | void layoutTableEdgeFromLoadRequest(); |
526 | |
527 | void updateContentWidth(); |
528 | void updateContentHeight(); |
529 | void updateAverageColumnWidth(); |
530 | void updateAverageRowHeight(); |
531 | RebuildOptions checkForVisibilityChanges(); |
532 | void forceLayout(bool immediate); |
533 | |
534 | void updateExtents(); |
535 | void syncLoadedTableRectFromLoadedTable(); |
536 | void syncLoadedTableFromLoadRequest(); |
537 | void shiftLoadedTableRect(const QPointF newPosition); |
538 | |
539 | int nextVisibleEdgeIndex(Qt::Edge edge, int startIndex) const; |
540 | int nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge) const; |
541 | inline bool atTableEnd(Qt::Edge edge) const { return nextVisibleEdgeIndexAroundLoadedTable(edge) == kEdgeIndexAtEnd; } |
542 | inline bool atTableEnd(Qt::Edge edge, int startIndex) const { return nextVisibleEdgeIndex(edge, startIndex) == kEdgeIndexAtEnd; } |
543 | inline int edgeToArrayIndex(Qt::Edge edge) const; |
544 | void clearEdgeSizeCache(); |
545 | |
546 | bool canLoadTableEdge(Qt::Edge tableEdge, const QRectF fillRect) const; |
547 | bool canUnloadTableEdge(Qt::Edge tableEdge, const QRectF fillRect) const; |
548 | Qt::Edge nextEdgeToLoad(const QRectF rect); |
549 | Qt::Edge nextEdgeToUnload(const QRectF rect); |
550 | |
551 | qreal cellWidth(const QPoint &cell) const; |
552 | qreal cellHeight(const QPoint &cell) const; |
553 | |
554 | FxTableItem *loadedTableItem(const QPoint &cell) const; |
555 | FxTableItem *createFxTableItem(const QPoint &cell, QQmlIncubator::IncubationMode incubationMode); |
556 | FxTableItem *loadFxTableItem(const QPoint &cell, QQmlIncubator::IncubationMode incubationMode); |
557 | |
558 | void releaseItem(FxTableItem *fxTableItem, QQmlTableInstanceModel::ReusableFlag reusableFlag); |
559 | void releaseLoadedItems(QQmlTableInstanceModel::ReusableFlag reusableFlag); |
560 | |
561 | void unloadItem(const QPoint &cell); |
562 | void loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMode incubationMode); |
563 | void unloadEdge(Qt::Edge edge); |
564 | void loadAndUnloadVisibleEdges(QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested); |
565 | void drainReusePoolAfterLoadRequest(); |
566 | void processLoadRequest(); |
567 | |
568 | void processRebuildTable(); |
569 | bool moveToNextRebuildState(); |
570 | void calculateTopLeft(QPoint &topLeft, QPointF &topLeftPos); |
571 | void loadInitialTable(); |
572 | |
573 | void layoutAfterLoadingInitialTable(); |
574 | void adjustViewportXAccordingToAlignment(); |
575 | void adjustViewportYAccordingToAlignment(); |
576 | void cancelOvershootAfterLayout(); |
577 | |
578 | void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options); |
579 | |
580 | #if QT_CONFIG(cursor) |
581 | void updateCursor(); |
582 | #endif |
583 | void updateEditItem(); |
584 | void updateContentSize(); |
585 | |
586 | QTypeRevision resolveImportVersion(); |
587 | void createWrapperModel(); |
588 | QAbstractItemModel *qaim(QVariant modelAsVariant) const; |
589 | |
590 | virtual void initItemCallback(int modelIndex, QObject *item); |
591 | virtual void itemCreatedCallback(int modelIndex, QObject *object); |
592 | virtual void itemPooledCallback(int modelIndex, QObject *object); |
593 | virtual void itemReusedCallback(int modelIndex, QObject *object); |
594 | virtual void modelUpdated(const QQmlChangeSet &changeSet, bool reset); |
595 | |
596 | virtual void syncWithPendingChanges(); |
597 | virtual void syncDelegate(); |
598 | virtual QVariant modelImpl() const; |
599 | virtual void setModelImpl(const QVariant &newModel); |
600 | virtual void syncModel(); |
601 | virtual void syncSyncView(); |
602 | virtual void syncPositionView(); |
603 | virtual QAbstractItemModel *selectionSourceModel(); |
604 | inline void syncRebuildOptions(); |
605 | |
606 | void connectToModel(); |
607 | void disconnectFromModel(); |
608 | |
609 | void rowsMovedCallback(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row); |
610 | void columnsMovedCallback(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column); |
611 | void rowsInsertedCallback(const QModelIndex &parent, int begin, int end); |
612 | void rowsRemovedCallback(const QModelIndex &parent, int begin, int end); |
613 | void columnsInsertedCallback(const QModelIndex &parent, int begin, int end); |
614 | void columnsRemovedCallback(const QModelIndex &parent, int begin, int end); |
615 | void layoutChangedCallback(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint); |
616 | void modelResetCallback(); |
617 | bool compareModel(const QVariant& model1, const QVariant& model2) const; |
618 | |
619 | void positionViewAtRow(int row, Qt::Alignment alignment, qreal offset, const QRectF subRect = QRectF()); |
620 | void positionViewAtColumn(int column, Qt::Alignment alignment, qreal offset, const QRectF subRect = QRectF()); |
621 | bool scrollToRow(int row, Qt::Alignment alignment, qreal offset, const QRectF subRect = QRectF()); |
622 | bool scrollToColumn(int column, Qt::Alignment alignment, qreal offset, const QRectF subRect = QRectF()); |
623 | |
624 | void scheduleRebuildIfFastFlick(); |
625 | void setLocalViewportX(qreal contentX); |
626 | void setLocalViewportY(qreal contentY); |
627 | void syncViewportRect(); |
628 | void syncViewportPosRecursive(); |
629 | |
630 | bool selectedInSelectionModel(const QPoint &cell) const; |
631 | void selectionChangedInSelectionModel(const QItemSelection &selected, const QItemSelection &deselected); |
632 | void updateSelectedOnAllDelegateItems(); |
633 | void setSelectedOnDelegateItem(const QModelIndex &modelIndex, bool select); |
634 | |
635 | bool currentInSelectionModel(const QPoint &cell) const; |
636 | void currentChangedInSelectionModel(const QModelIndex ¤t, const QModelIndex &previous); |
637 | void setCurrentOnDelegateItem(const QModelIndex &index, bool isCurrent); |
638 | void updateCurrentRowAndColumn(); |
639 | |
640 | void fetchMoreData(); |
641 | |
642 | void _q_componentFinalized(); |
643 | void registerCallbackWhenBindingsAreEvaluated(); |
644 | |
645 | inline QString tableLayoutToString() const; |
646 | void dumpTable() const; |
647 | |
648 | void setRequiredProperty(const char *property, |
649 | const QVariant &value, |
650 | int serializedModelIndex, |
651 | QObject *object, bool init); |
652 | |
653 | void handleTap(const QQuickHandlerPoint &point); |
654 | void setCurrentIndexFromTap(const QPointF &pos); |
655 | void setCurrentIndex(const QPoint &cell); |
656 | bool setCurrentIndexFromKeyEvent(QKeyEvent *e); |
657 | bool canEdit(const QModelIndex tappedIndex, bool warn); |
658 | bool editFromKeyEvent(QKeyEvent *e); |
659 | |
660 | // QQuickSelectable |
661 | QQuickItem *selectionPointerHandlerTarget() const override; |
662 | bool hasSelection() const override; |
663 | bool startSelection(const QPointF &pos, Qt::KeyboardModifiers modifiers) override; |
664 | void setSelectionStartPos(const QPointF &pos) override; |
665 | void setSelectionEndPos(const QPointF &pos) override; |
666 | void clearSelection() override; |
667 | void normalizeSelection() override; |
668 | QRectF selectionRectangle() const override; |
669 | QSizeF scrollTowardsPoint(const QPointF &pos, const QSizeF &step) override; |
670 | void setCallback(std::function<void(CallBackFlag)> func) override; |
671 | void cancelSelectionTracking(); |
672 | |
673 | QPoint clampedCellAtPos(const QPointF &pos) const; |
674 | virtual void updateSelection(const QRect &oldSelection, const QRect &newSelection); |
675 | QRect selection() const; |
676 | // ---------------- |
677 | |
678 | // Section drag handler |
679 | #if QT_CONFIG(quick_draganddrop) |
680 | void initSectionDragHandler(Qt::Orientation orientation); |
681 | void destroySectionDragHandler(); |
682 | #endif |
683 | inline void setActivePointerHandler(QQuickTableViewPointerHandler *handler) { activePtrHandler = handler; } |
684 | inline QQuickTableViewPointerHandler* activePointerHandler() const { return activePtrHandler; } |
685 | // Row/Column reordering |
686 | void moveSection(int source , int destination, Qt::Orientations orientation); |
687 | void initializeIndexMapping(); |
688 | void clearIndexMapping(); |
689 | void clearSection(Qt::Orientations orientation); |
690 | virtual int logicalRowIndex(const int visualIndex) const; |
691 | virtual int logicalColumnIndex(const int visualIndex) const; |
692 | virtual int visualRowIndex(const int logicalIndex) const; |
693 | virtual int visualColumnIndex(const int logicalIndex) const; |
694 | void setContainsDragOnDelegateItem(const QModelIndex &modelIndex, bool overlay); |
695 | int getEditCellIndex(const QModelIndex &index) const; |
696 | }; |
697 | |
698 | class FxTableItem : public QQuickItemViewFxItem |
699 | { |
700 | public: |
701 | FxTableItem(QQuickItem *item, QQuickTableView *table, bool own) |
702 | : QQuickItemViewFxItem(item, own, QQuickTableViewPrivate::get(q: table)) |
703 | { |
704 | } |
705 | |
706 | qreal position() const override { return 0; } |
707 | qreal endPosition() const override { return 0; } |
708 | qreal size() const override { return 0; } |
709 | qreal sectionSize() const override { return 0; } |
710 | bool contains(qreal, qreal) const override { return false; } |
711 | |
712 | QPoint cell; |
713 | }; |
714 | |
715 | Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickTableViewPrivate::RebuildOptions) |
716 | |
717 | QT_END_NAMESPACE |
718 | |
719 | #endif |
720 |
Definitions
- kDefaultRowHeight
- kDefaultColumnWidth
- kEdgeIndexNotSet
- kEdgeIndexAtEnd
- QQuickTableViewHoverHandler
- isHoveringGrid
- QQuickTableViewPointerHandler
- State
- state
- QQuickTableViewResizeHandler
- QQuickTableViewSectionDragHandler
- setSectionOrientation
- QQuickTableViewTapHandler
- QQuickTableViewPrivate
- TableEdgeLoadRequest
- begin
- begin
- markAsDone
- isActive
- currentCell
- hasCurrentCell
- moveToNextCell
- edge
- row
- column
- incubationMode
- startPosition
- toString
- cellAt
- EdgeRange
- RebuildState
- SectionState
- RebuildOption
- get
- SectionData
- cellIsValid
- topRow
- bottomRow
- leftColumn
- rightColumn
- atTableEnd
- atTableEnd
- setActivePointerHandler
- activePointerHandler
- FxTableItem
- FxTableItem
- position
- endPosition
- size
- sectionSize
Learn Advanced QML with KDAB
Find out more