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