191 Q_DECLARE_PUBLIC(QQuickTableView)
193 class TableEdgeLoadRequest
203 void begin(
const QPoint &cell,
const QPointF &pos, QQmlIncubator::IncubationMode incubationMode)
207 m_edge = Qt::Edge(0);
208 m_mode = incubationMode;
209 m_edgeIndex = cell.x();
210 m_visibleCellsInEdge.clear();
211 m_visibleCellsInEdge.append(cell.y());
214 qCDebug(lcTableViewDelegateLifecycle()) <<
"begin top-left:" << toString();
217 void begin(Qt::Edge edgeToLoad,
int edgeIndex,
const QList<
int> visibleCellsInEdge, QQmlIncubator::IncubationMode incubationMode)
222 m_edgeIndex = edgeIndex;
223 m_visibleCellsInEdge = visibleCellsInEdge;
224 m_mode = incubationMode;
226 qCDebug(lcTableViewDelegateLifecycle()) <<
"begin:" << toString();
229 inline void markAsDone() { m_active =
false; }
230 inline bool isActive()
const {
return m_active; }
232 inline QPoint currentCell()
const {
return cellAt(m_currentIndex); }
233 inline bool hasCurrentCell()
const {
return m_currentIndex < m_visibleCellsInEdge.size(); }
234 inline void moveToNextCell() { ++m_currentIndex; }
236 inline Qt::Edge edge()
const {
return m_edge; }
237 inline int row()
const {
return cellAt(0).y(); }
238 inline int column()
const {
return cellAt(0).x(); }
239 inline QQmlIncubator::IncubationMode incubationMode()
const {
return m_mode; }
241 inline QPointF startPosition()
const {
return m_startPos; }
243 QString toString()
const
247 dbg.nospace() <<
"TableSectionLoadRequest(" <<
"edge:"
248 << m_edge <<
", edgeIndex:" << m_edgeIndex <<
", incubation:";
251 case QQmlIncubator::Asynchronous:
252 dbg <<
"Asynchronous";
254 case QQmlIncubator::AsynchronousIfNested:
255 dbg <<
"AsynchronousIfNested";
257 case QQmlIncubator::Synchronous:
258 dbg <<
"Synchronous";
266 Qt::Edge m_edge = Qt::Edge(0);
267 QList<
int> m_visibleCellsInEdge;
269 int m_currentIndex = 0;
270 bool m_active =
false;
271 QQmlIncubator::IncubationMode m_mode = QQmlIncubator::AsynchronousIfNested;
274 inline QPoint cellAt(
int index)
const {
275 return !m_edge || (m_edge & (Qt::LeftEdge | Qt::RightEdge))
276 ? QPoint(m_edgeIndex, m_visibleCellsInEdge[index])
277 : QPoint(m_visibleCellsInEdge[index], m_edgeIndex);
284 bool containsIndex(Qt::Edge edge,
int index);
291 enum class RebuildState {
300 MovePreloadedItemsToPool,
304 enum class SectionState {
309 enum class RebuildOption {
314 CalculateNewTopLeftRow = 0x8,
315 CalculateNewTopLeftColumn = 0x10,
316 CalculateNewContentWidth = 0x20,
317 CalculateNewContentHeight = 0x40,
318 PositionViewAtRow = 0x80,
319 PositionViewAtColumn = 0x100,
321 Q_DECLARE_FLAGS(RebuildOptions, RebuildOption)
324 QQuickTableViewPrivate();
325 ~QQuickTableViewPrivate() override;
327 static inline QQuickTableViewPrivate *get(QQuickTableView *q) {
return q->d_func(); }
329 void updatePolish() override;
330 void fixup(AxisData &data, qreal minExtent, qreal maxExtent) override;
333 QHash<
int, FxTableItem *> loadedItems;
339 QQmlInstanceModel* model =
nullptr;
340 QPointer<QQmlTableInstanceModel> tableModel =
nullptr;
344 QVariant assignedModel = QVariant(
int(0));
345 QQmlGuard<QQmlComponent> assignedDelegate;
353 QMinimalFlatSet<
int> loadedColumns;
354 QMinimalFlatSet<
int> loadedRows;
355 QRectF loadedTableOuterRect;
356 QRectF loadedTableInnerRect;
358 QPointF origin = QPointF(0, 0);
359 QSizeF endExtent = QSizeF(0, 0);
361 QRectF viewportRect = QRectF(0, 0, -1, -1);
365 RebuildState rebuildState = RebuildState::Done;
366 RebuildOptions rebuildOptions = RebuildOption::All;
367 RebuildOptions scheduledRebuildOptions = RebuildOption::All;
369 TableEdgeLoadRequest loadRequest;
371 QSizeF cellSpacing = QSizeF(0, 0);
373 QQmlTableInstanceModel::ReusableFlag reusableFlag = QQmlTableInstanceModel::Reusable;
375 bool blockItemCreatedCallback =
false;
376 mutable bool layoutWarningIssued =
false;
377 bool polishing =
false;
378 bool syncVertically =
false;
379 bool syncHorizontally =
false;
380 bool inSetLocalViewportPos =
false;
381 bool inSyncViewportPosRecursive =
false;
382 bool inUpdateContentSize =
false;
384 bool keyNavigationEnabled =
true;
385 bool pointerNavigationEnabled =
true;
386 bool alternatingRows =
true;
387 bool resizableColumns =
false;
388 bool resizableRows =
false;
390 bool m_cursorSet =
false;
395 bool isTransposed =
false;
397 bool warnNoSelectionModel =
true;
399 QQmlDelegateModel::DelegateModelAccess assignedDelegateModelAccess
400 = QQmlDelegateModel::Qt5ReadWrite;
402 bool componentFinalized =
false;
405 void requestSort(
int logicalColumn,
bool clearable);
406 void sortByColumn(
int column, Qt::SortOrder order);
407 void updateSortState(
int column, Qt::SortOrder order);
409 bool sortingEnabled =
false;
411 Qt::SortOrder sortOrder = Qt::AscendingOrder;
413 QJSValue rowHeightProvider;
414 QJSValue columnWidthProvider;
416 mutable EdgeRange cachedNextVisibleEdgeIndex[4];
417 mutable EdgeRange cachedColumnWidth;
418 mutable EdgeRange cachedRowHeight;
429 QQmlNullableValue<qreal> explicitContentWidth;
430 QQmlNullableValue<qreal> explicitContentHeight;
432 QSizeF averageEdgeSize;
434 QPointer<QQuickTableView> assignedSyncView;
435 QPointer<QQuickTableView> syncView;
436 QList<QPointer<QQuickTableView> > syncChildren;
437 Qt::Orientations assignedSyncDirection = Qt::Horizontal | Qt::Vertical;
439 QPointer<QItemSelectionModel> selectionModel;
440 QQuickTableView::SelectionBehavior selectionBehavior = QQuickTableView::SelectCells;
441 QQuickTableView::SelectionMode selectionMode = QQuickTableView::ExtendedSelection;
442 QItemSelectionModel::SelectionFlag selectionFlag = QItemSelectionModel::NoUpdate;
443 std::function<
void(CallBackFlag)> selectableCallbackFunction;
444 bool inSelectionModelUpdate =
false;
445 bool needsModelSynchronization =
false;
447 int assignedPositionViewAtRowAfterRebuild = 0;
448 int assignedPositionViewAtColumnAfterRebuild = 0;
449 int positionViewAtRowAfterRebuild = 0;
450 int positionViewAtColumnAfterRebuild = 0;
451 qreal positionViewAtRowOffset = 0;
452 qreal positionViewAtColumnOffset = 0;
453 QRectF positionViewAtRowSubRect;
454 QRectF positionViewAtColumnSubRect;
455 Qt::Alignment positionViewAtRowAlignment = Qt::AlignTop;
456 Qt::Alignment positionViewAtColumnAlignment = Qt::AlignLeft;
458 QQuickPropertyAnimation positionXAnimation;
459 QQuickPropertyAnimation positionYAnimation;
461 QPoint selectionStartCell = {-1, -1};
462 QPoint selectionEndCell = {-1, -1};
463 QItemSelection existingSelection;
465 QMargins edgesBeforeRebuild;
466 QSize tableSizeBeforeRebuild;
469 int currentColumn = -1;
470#if QT_CONFIG(accessibility)
471 QPointer<QQuickItem> accessibleFocusItem;
474 QHash<
int, qreal> explicitColumnWidths;
475 QHash<
int, qreal> explicitRowHeights;
477 QQuickTableViewHoverHandler *hoverHandler =
nullptr;
478 QQuickTableViewResizeHandler *resizeHandler =
nullptr;
479#if QT_CONFIG(quick_draganddrop)
480 QQuickTableViewSectionDragHandler *sectionDragHandler =
nullptr;
482 QQuickTableViewPointerHandler *activePtrHandler =
nullptr;
484 QQmlTableInstanceModel *editModel =
nullptr;
485 QQuickItem *editItem =
nullptr;
486 QPersistentModelIndex editIndex;
487 QQuickTableView::EditTriggers editTriggers = QQuickTableView::DoubleTapped | QQuickTableView::EditKeyPressed;
490 QString forcedIncubationMode = qEnvironmentVariable(
"QT_TABLEVIEW_INCUBATION_MODE");
498 std::vector<SectionData> horizontalVisualIndices;
499 std::vector<SectionData> verticalVisualIndices;
500 std::vector<SectionData> horizontalLogicalIndices;
501 std::vector<SectionData> verticalLogicalIndices;
503 std::vector<SectionData> &visualIndicesForOrientation(Qt::Orientation orientation)
505 return orientation == Qt::Horizontal ? horizontalVisualIndices : verticalVisualIndices;
507 std::vector<SectionData> &logicalIndicesForOrientation(Qt::Orientation orientation)
509 return orientation == Qt::Horizontal ? horizontalLogicalIndices : verticalLogicalIndices;
512 SectionState m_sectionState = SectionState::Idle;
517 QQuickTableViewAttached *getAttachedObject(
const QObject *object)
const;
519 int modelIndexAtCell(
const QPoint &cell)
const;
520 QPoint cellAtModelIndex(
int modelIndex)
const;
521 int modelIndexToCellIndex(
const QModelIndex &modelIndex,
bool visualIndex =
true)
const;
522 inline bool cellIsValid(
const QPoint &cell)
const {
return cell.x() != -1 && cell.y() != -1; }
524 qreal sizeHintForColumn(
int column)
const;
525 qreal sizeHintForRow(
int row)
const;
526 QSize calculateTableSize();
527 void updateTableSize();
529 inline bool isColumnHidden(
int column)
const;
530 inline bool isRowHidden(
int row)
const;
532 qreal getColumnLayoutWidth(
int column);
533 qreal getRowLayoutHeight(
int row);
534 qreal getColumnWidth(
int column)
const;
535 qreal getRowHeight(
int row)
const;
536 qreal getEffectiveRowY(
int row)
const;
537 qreal getEffectiveRowHeight(
int row)
const;
538 qreal getEffectiveColumnX(
int column)
const;
539 qreal getEffectiveColumnWidth(
int column)
const;
540 qreal getAlignmentContentX(
int column, Qt::Alignment alignment,
const qreal offset,
const QRectF &subRect);
541 qreal getAlignmentContentY(
int row, Qt::Alignment alignment,
const qreal offset,
const QRectF &subRect);
543 int topRow()
const {
return *loadedRows.cbegin(); }
544 int bottomRow()
const {
return *loadedRows.crbegin(); }
545 int leftColumn()
const {
return *loadedColumns.cbegin(); }
546 int rightColumn()
const {
return *loadedColumns.crbegin(); }
548 QQuickTableView *rootSyncView()
const;
550 bool updateTableRecursive();
552 void relayoutTableItems();
554 void layoutVerticalEdge(Qt::Edge tableEdge);
555 void layoutHorizontalEdge(Qt::Edge tableEdge);
556 void layoutTopLeftItem();
557 void layoutTableEdgeFromLoadRequest();
559 void updateContentWidth();
560 void updateContentHeight();
561 void updateAverageColumnWidth();
562 void updateAverageRowHeight();
563 RebuildOptions checkForVisibilityChanges();
564 void forceLayout(
bool immediate);
566 void updateExtents();
567 void syncLoadedTableRectFromLoadedTable();
568 void syncLoadedTableFromLoadRequest();
570 int nextVisibleEdgeIndex(Qt::Edge edge,
int startIndex)
const;
571 int nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge)
const;
572 inline bool atTableEnd(Qt::Edge edge)
const {
return nextVisibleEdgeIndexAroundLoadedTable(edge) == kEdgeIndexAtEnd; }
573 inline bool atTableEnd(Qt::Edge edge,
int startIndex)
const {
return nextVisibleEdgeIndex(edge, startIndex) == kEdgeIndexAtEnd; }
574 inline int edgeToArrayIndex(Qt::Edge edge)
const;
575 void clearEdgeSizeCache();
577 bool canLoadTableEdge(Qt::Edge tableEdge,
const QRectF fillRect)
const;
578 bool canUnloadTableEdge(Qt::Edge tableEdge,
const QRectF fillRect)
const;
579 Qt::Edge nextEdgeToLoad(
const QRectF rect);
580 Qt::Edge nextEdgeToUnload(
const QRectF rect);
582 qreal cellWidth(
const QPoint &cell)
const;
583 qreal cellHeight(
const QPoint &cell)
const;
585 FxTableItem *loadedTableItem(
const QPoint &cell)
const;
586 FxTableItem *createFxTableItem(
const QPoint &cell, QQmlIncubator::IncubationMode incubationMode);
587 FxTableItem *loadFxTableItem(
const QPoint &cell, QQmlIncubator::IncubationMode incubationMode);
589 void releaseItem(FxTableItem *fxTableItem, QQmlTableInstanceModel::ReusableFlag reusableFlag);
590 void releaseLoadedItems(QQmlTableInstanceModel::ReusableFlag reusableFlag);
592 void unloadItem(
const QPoint &cell);
593 void loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMode incubationMode);
594 void unloadEdge(Qt::Edge edge);
595 void loadAndUnloadVisibleEdges(QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested);
596 void drainReusePoolAfterLoadRequest();
597 void processLoadRequest();
599 void processRebuildTable();
600 bool moveToNextRebuildState();
601 void calculateTopLeft(QPoint &topLeft, QPointF &topLeftPos);
602 void loadInitialTable();
604 void layoutAfterLoadingInitialTable();
605 void adjustViewportXAccordingToAlignment();
606 void adjustViewportYAccordingToAlignment();
607 void cancelOvershootAfterLayout();
609 void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options);
614 void updateEditItem();
615 void updateContentSize();
617 QTypeRevision resolveImportVersion();
618 void createWrapperModel();
619 QAbstractItemModel *qaim(QVariant modelAsVariant)
const;
621 virtual void initItemCallback(
int modelIndex, QObject *item);
622 virtual void itemCreatedCallback(
int modelIndex, QObject *object);
623 virtual void itemPooledCallback(
int modelIndex, QObject *object);
624 virtual void itemReusedCallback(
int modelIndex, QObject *object);
625 virtual void modelUpdated(
const QQmlChangeSet &changeSet,
bool reset);
626 virtual void updateItemProperties(
int flatIndex, QObject *object,
bool init);
628 virtual void syncWithPendingChanges();
629 virtual void syncDelegate();
630 virtual void syncDelegateModelAccess();
631 virtual QVariant modelImpl()
const;
632 virtual void setModelImpl(
const QVariant &newModel);
633 virtual void syncModel();
634 virtual void syncSyncView();
635 virtual void syncPositionView();
636 virtual QAbstractItemModel *selectionSourceModel();
637 inline void syncRebuildOptions();
639 void connectToModel();
640 void disconnectFromModel();
642 void rowsMovedCallback(
const QModelIndex &parent,
int start,
int end,
const QModelIndex &destination,
int row);
643 void columnsMovedCallback(
const QModelIndex &parent,
int start,
int end,
const QModelIndex &destination,
int column);
644 void rowsInsertedCallback(
const QModelIndex &parent,
int begin,
int end);
645 void rowsRemovedCallback(
const QModelIndex &parent,
int begin,
int end);
646 void columnsInsertedCallback(
const QModelIndex &parent,
int begin,
int end);
647 void columnsRemovedCallback(
const QModelIndex &parent,
int begin,
int end);
648 void layoutChangedCallback(
const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
649 void modelResetCallback();
650 void dataChangedCallback(
const QModelIndex &topLeft,
const QModelIndex &bottomRight,
const QList<
int> &roles);
651 bool compareModel(
const QVariant& model1,
const QVariant& model2)
const;
653 void positionViewAtRow(
int row, Qt::Alignment alignment, qreal offset,
const QRectF subRect = QRectF());
654 void positionViewAtColumn(
int column, Qt::Alignment alignment, qreal offset,
const QRectF subRect = QRectF());
655 bool scrollToRow(
int row, Qt::Alignment alignment, qreal offset,
const QRectF subRect = QRectF());
656 bool scrollToColumn(
int column, Qt::Alignment alignment, qreal offset,
const QRectF subRect = QRectF());
658 void scheduleRebuildIfFastFlick();
659 void setLocalViewportX(qreal contentX);
660 void setLocalViewportY(qreal contentY);
661 void syncViewportRect();
662 void syncViewportPosRecursive();
664 bool selectedInSelectionModel(
const QPoint &cell)
const;
665 void selectionChangedInSelectionModel(
const QItemSelection &selected,
const QItemSelection &deselected);
666 void updateSelectedOnAllDelegateItems();
667 void setSelectedOnDelegateItem(
const QModelIndex &modelIndex,
bool select);
669 bool currentInSelectionModel(
const QPoint &cell)
const;
670 void currentChangedInSelectionModel(
const QModelIndex ¤t,
const QModelIndex &previous);
671 void setCurrentOnDelegateItem(
const QModelIndex &index,
bool isCurrent);
672 void updateCurrentRowAndColumn();
673#if QT_CONFIG(accessibility)
674 void updateAccessibleFocus();
677 void fetchMoreData();
679 void _q_componentFinalized();
680 void registerCallbackWhenBindingsAreEvaluated();
682 inline QString tableLayoutToString()
const;
683 void dumpTable()
const;
685 void setRequiredProperty(
const char *property,
686 const QVariant &value,
687 int serializedModelIndex,
688 QObject *object,
bool init);
690 void handleTap(
const QQuickHandlerPoint &point);
691 virtual void executeTap(
const QQuickHandlerPoint &point);
692 void setCurrentIndexFromTap(
const QPointF &pos);
693 void setCurrentIndex(
const QPoint &cell);
694 bool setCurrentIndexFromKeyEvent(QKeyEvent *e);
695 bool canEdit(
const QModelIndex tappedIndex,
bool warn);
696 bool editFromKeyEvent(QKeyEvent *e);
697 void closeEditorAndCommit();
698 QObject *installEventFilterOnFocusObjectInsideEditItem();
701 QQuickItem *selectionPointerHandlerTarget()
const override;
702 bool hasSelection()
const override;
703 bool startSelection(
const QPointF &pos, Qt::KeyboardModifiers modifiers) override;
704 void setSelectionStartPos(
const QPointF &pos) override;
705 void setSelectionEndPos(
const QPointF &pos) override;
706 void clearSelection() override;
707 void normalizeSelection() override;
708 QRectF selectionRectangle()
const override;
709 QSizeF scrollTowardsPoint(
const QPointF &pos,
const QSizeF &step) override;
710 void setCallback(std::function<
void(CallBackFlag)> func) override;
711 void cancelSelectionTracking();
713 QPoint clampedCellAtPos(
const QPointF &pos)
const;
714 virtual void updateSelection(
const QRect &oldSelection,
const QRect &newSelection);
715 QRect selection()
const;
719#if QT_CONFIG(quick_draganddrop)
720 void initSectionDragHandler(Qt::Orientation orientation);
721 void destroySectionDragHandler();
723 inline void setActivePointerHandler(QQuickTableViewPointerHandler *handler) { activePtrHandler = handler; }
724 inline QQuickTableViewPointerHandler* activePointerHandler()
const {
return activePtrHandler; }
726 void moveSection(
int source ,
int destination, Qt::Orientation orientation);
727 void initializeIndexMapping();
728 void clearIndexMapping();
729 void clearSection(Qt::Orientation orientation);
730 virtual int logicalRowIndex(
const int visualIndex)
const;
731 virtual int logicalColumnIndex(
const int visualIndex)
const;
732 virtual int visualRowIndex(
const int logicalIndex)
const;
733 virtual int visualColumnIndex(
const int logicalIndex)
const;
734 void setContainsDragOnDelegateItem(
const QModelIndex &modelIndex,
bool overlay);
735 int getEditCellIndex(
const QModelIndex &index)
const;