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