commit 7fa34554e8d0b2222658f02125b0e71959e0e1fc Author: Richard Moe Gustavsen Date: Tue Nov 14 13:19:41 2023 +0100 TableView, 5.15 patch: don't emit rows and columns changed while rebuilding diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 2a8a8ccae0..5334cae55a 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -1025,21 +1025,22 @@ void QQuickTableViewPrivate::forceLayout() const QSize actualTableSize = calculateTableSize(); if (tableSize != actualTableSize) { - // This can happen if the app is calling forceLayout while - // the model is updated, but before we're notified about it. - rebuildOptions = RebuildOption::All; - } else { - // Resizing a column (or row) can result in the table going from being - // e.g completely inside the viewport to go outside. And in the latter - // case, the user needs to be able to scroll the viewport, also if - // flags such as Flickable.StopAtBounds is in use. So we need to - // update contentWidth/Height to support that case. - rebuildOptions = RebuildOption::LayoutOnly - | RebuildOption::CalculateNewContentWidth - | RebuildOption::CalculateNewContentHeight - | checkForVisibilityChanges(); + // The table size will have changed if forceLayout is called after + // the row count in the model has changed, but before we received + // a rowsInsertedCallback about it (and vice versa for columns). + rebuildOptions |= RebuildOption::ViewportOnly; } + // Resizing a column (or row) can result in the table going from being + // e.g completely inside the viewport to go outside. And in the latter + // case, the user needs to be able to scroll the viewport, also if + // flags such as Flickable.StopAtBounds is in use. So we need to + // update contentWidth/Height to support that case. + rebuildOptions |= RebuildOption::LayoutOnly + | RebuildOption::CalculateNewContentWidth + | RebuildOption::CalculateNewContentHeight + | checkForVisibilityChanges(); + scheduleRebuildTable(rebuildOptions); auto rootView = rootSyncView(); @@ -1302,21 +1303,6 @@ qreal QQuickTableViewPrivate::sizeHintForRow(int row) return rowHeight; } -void QQuickTableViewPrivate::updateTableSize() -{ - // tableSize is the same as row and column count, and will always - // be the same as the number of rows and columns in the model. - Q_Q(QQuickTableView); - - const QSize prevTableSize = tableSize; - tableSize = calculateTableSize(); - - if (prevTableSize.width() != tableSize.width()) - emit q->columnsChanged(); - if (prevTableSize.height() != tableSize.height()) - emit q->rowsChanged(); -} - QSize QQuickTableViewPrivate::calculateTableSize() { QSize size(0, 0); @@ -1714,6 +1700,8 @@ void QQuickTableViewPrivate::processRebuildTable() else Q_TABLEVIEW_UNREACHABLE(rebuildOptions); } + + tableSizeBeforeRebuild = tableSize; } moveToNextRebuildState(); @@ -1771,6 +1759,13 @@ void QQuickTableViewPrivate::processRebuildTable() return; } + if (rebuildState == RebuildState::Done) { + if (tableSizeBeforeRebuild.width() != tableSize.width()) + emit q->columnsChanged(); + if (tableSizeBeforeRebuild.height() != tableSize.height()) + emit q->rowsChanged(); + } + Q_TABLEVIEW_ASSERT(rebuildState == RebuildState::Done, int(rebuildState)); qCDebug(lcTableViewDelegateLifecycle()) << "rebuild complete:" << q; } @@ -1892,7 +1887,7 @@ void QQuickTableViewPrivate::calculateTopLeft(QPoint &topLeftCell, QPointF &topL void QQuickTableViewPrivate::beginRebuildTable() { - updateTableSize(); + tableSize = calculateTableSize(); QPoint topLeft; QPointF topLeftPos; diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h index 758c0308b8..52ef3546f1 100644 --- a/src/quick/items/qquicktableview_p_p.h +++ b/src/quick/items/qquicktableview_p_p.h @@ -311,6 +311,8 @@ public: QList > syncChildren; Qt::Orientations assignedSyncDirection = Qt::Horizontal | Qt::Vertical; + QSize tableSizeBeforeRebuild; + const static QPoint kLeft; const static QPoint kRight; const static QPoint kUp; @@ -329,7 +331,6 @@ public: qreal sizeHintForColumn(int column); qreal sizeHintForRow(int row); QSize calculateTableSize(); - void updateTableSize(); inline bool isColumnHidden(int column); inline bool isRowHidden(int row);