diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2021-05-06 11:20:53 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-05-06 18:25:25 +0000 |
commit | 54873d967a22343a36e7b8c02aa32f4061adf1e3 (patch) | |
tree | 04c0f6e19903a52c84913d00af2592078019a5ba /src/quick | |
parent | 6ce50ad548aad6caca815b3058ee1a2be923344f (diff) |
qquicktableview: upon forceLayout(), check for visible rows/columns at the origin
There is a bug in TableView which will stop the user from
scrolling/flicking back to the first column if it has become
visible after first being hidden.
The reason is that this is somewhat of a special case that
happens only if the current left column is already at the
origin of the viewport, since that will fool tableview into
thinking that there can be no more columns in front of it.
This patch add an extra section to the function that checks
for visibility changes, to detect this special case.
Fixes: QTBUG-93264
Change-Id: Ieaad507b45ea11dc231519e9f49cbf182d6443ba
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 546df684e272bbbc5e8b871ae9b224fdb34a4cfa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquicktableview.cpp | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 652050b5ec..7fc6b6572d 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -958,43 +958,61 @@ QQuickTableViewPrivate::RebuildOptions QQuickTableViewPrivate::checkForVisibilit return RebuildOption::None; } - // Go through all columns from first to last, find the columns that used - // to be hidden and not loaded, and check if they should become visible - // (and vice versa). If there is a change, we need to rebuild. RebuildOptions rebuildOptions = RebuildOption::None; - for (int column = leftColumn(); column <= rightColumn(); ++column) { - const bool wasVisibleFromBefore = loadedColumns.contains(column); - const bool isVisibleNow = !qFuzzyIsNull(getColumnWidth(column)); - if (wasVisibleFromBefore == isVisibleNow) - continue; - - // A column changed visibility. This means that it should - // either be loaded or unloaded. So we need a rebuild. - qCDebug(lcTableViewDelegateLifecycle) << "Column" << column << "changed visibility to" << isVisibleNow; + if (loadedTableOuterRect.x() == origin.x() && leftColumn() != 0) { + // Since the left column is at the origin of the viewport, but still not the first + // column in the model, we need to calculate a new left column since there might be + // columns in front of it that used to be hidden, but should now be visible (QTBUG-93264). rebuildOptions.setFlag(RebuildOption::ViewportOnly); - if (column == leftColumn()) { - // The first loaded column should now be hidden. This means that we - // need to calculate which column should now be first instead. - rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn); + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn); + } else { + // Go through all loaded columns from first to last, find the columns that used + // to be hidden and not loaded, and check if they should become visible + // (and vice versa). If there is a change, we need to rebuild. + for (int column = leftColumn(); column <= rightColumn(); ++column) { + const bool wasVisibleFromBefore = loadedColumns.contains(column); + const bool isVisibleNow = !qFuzzyIsNull(getColumnWidth(column)); + if (wasVisibleFromBefore == isVisibleNow) + continue; + + // A column changed visibility. This means that it should + // either be loaded or unloaded. So we need a rebuild. + qCDebug(lcTableViewDelegateLifecycle) << "Column" << column << "changed visibility to" << isVisibleNow; + rebuildOptions.setFlag(RebuildOption::ViewportOnly); + if (column == leftColumn()) { + // The first loaded column should now be hidden. This means that we + // need to calculate which column should now be first instead. + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftColumn); + } + break; } - break; } - // Go through all rows from first to last, and do the same as above - for (int row = topRow(); row <= bottomRow(); ++row) { - const bool wasVisibleFromBefore = loadedRows.contains(row); - const bool isVisibleNow = !qFuzzyIsNull(getRowHeight(row)); - if (wasVisibleFromBefore == isVisibleNow) - continue; - - // A row changed visibility. This means that it should - // either be loaded or unloaded. So we need a rebuild. - qCDebug(lcTableViewDelegateLifecycle) << "Row" << row << "changed visibility to" << isVisibleNow; + if (loadedTableOuterRect.y() == origin.y() && topRow() != 0) { + // Since the top row is at the origin of the viewport, but still not the first + // row in the model, we need to calculate a new top row since there might be + // rows in front of it that used to be hidden, but should now be visible (QTBUG-93264). rebuildOptions.setFlag(RebuildOption::ViewportOnly); - if (row == topRow()) - rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow); - break; + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow); + } else { + // Go through all loaded rows from first to last, find the rows that used + // to be hidden and not loaded, and check if they should become visible + // (and vice versa). If there is a change, we need to rebuild. + for (int row = topRow(); row <= bottomRow(); ++row) { + const bool wasVisibleFromBefore = loadedRows.contains(row); + const bool isVisibleNow = !qFuzzyIsNull(getRowHeight(row)); + if (wasVisibleFromBefore == isVisibleNow) + continue; + + // A row changed visibility. This means that it should + // either be loaded or unloaded. So we need a rebuild. + qCDebug(lcTableViewDelegateLifecycle) << "Row" << row << "changed visibility to" << isVisibleNow; + rebuildOptions.setFlag(RebuildOption::ViewportOnly); + if (row == topRow()) + rebuildOptions.setFlag(RebuildOption::CalculateNewTopLeftRow); + break; + } } return rebuildOptions; |