From 679642fcfaac25bf56613df0bf25afa11ed0d01b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 29 Mar 2019 15:33:58 +0100 Subject: QQuickTableView: implement recursive updateTable() Now that a TableView can be inside a syncView hierarchy, we cannot update a table in isolation, but need to coordinate this with the other views. It's especially important that we update a parent syncView before a child syncView, to ensure that the parent has calculated all the necessary columns width and row heights. For that reason, we always update the table views starting from the top. Change-Id: Iba8ae7d28fa0bb2fbbad9f8fc7aa198e15b91872 Reviewed-by: Mitch Curtis --- src/quick/items/qquicktableview.cpp | 44 +++++++++++++++++++++++++++++++++++ src/quick/items/qquicktableview_p_p.h | 4 ++++ 2 files changed, 48 insertions(+) (limited to 'src/quick/items') diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 82702b1a8f..8c64c11bb1 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -1768,7 +1768,51 @@ void QQuickTableViewPrivate::scheduleRebuildTable(RebuildOptions options) { q_func()->polish(); } +QQuickTableView *QQuickTableViewPrivate::rootSyncView() const +{ + QQuickTableView *root = const_cast(q_func()); + while (QQuickTableView *view = root->d_func()->syncView) + root = view; + return root; +} + void QQuickTableViewPrivate::updatePolish() +{ + // We always start updating from the top of the syncView tree, since + // the layout of a syncView child will depend on the layout of the syncView. + // E.g when a new column is flicked in, the syncView should load and layout + // the column first, before any syncChildren gets a chance to do the same. + Q_TABLEVIEW_ASSERT(!polishing, "recursive updatePolish() calls are not allowed!"); + rootSyncView()->d_func()->updateTableRecursive(); +} + +bool QQuickTableViewPrivate::updateTableRecursive() +{ + if (polishing) { + // We're already updating the Table in this view, so + // we cannot continue. Signal this back by returning false. + // The caller can then choose to call "polish()" instead, to + // do the update later. + return false; + } + + updateTable(); + + for (auto syncChild : qAsConst(syncChildren)) { + auto syncChild_d = syncChild->d_func(); + syncChild_d->scheduledRebuildOptions |= rebuildOptions; + + const bool updated = syncChild_d->updateTableRecursive(); + if (!updated) + return false; + } + + rebuildOptions = RebuildOption::None; + + return true; +} + +void QQuickTableViewPrivate::updateTable() { // Whenever something changes, e.g viewport moves, spacing is set to a // new value, model changes etc, this function will end up being called. Here diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h index c018356efa..13c69d0b43 100644 --- a/src/quick/items/qquicktableview_p_p.h +++ b/src/quick/items/qquicktableview_p_p.h @@ -310,6 +310,10 @@ public: inline int leftColumn() const { return loadedColumns.firstKey(); } inline int rightColumn() const { return loadedColumns.lastKey(); } + QQuickTableView *rootSyncView() const; + + bool updateTableRecursive(); + void updateTable(); void relayoutTable(); void relayoutTableItems(); -- cgit v1.2.3