aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquicktableview.cpp78
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp78
2 files changed, 126 insertions, 30 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 63bedb9734..3f06684f25 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1105,43 +1105,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;
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 005aae0639..60ba28ec08 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -169,6 +169,8 @@ private slots:
void checkTableviewInsideAsyncLoader();
void hideRowsAndColumns_data();
void hideRowsAndColumns();
+ void hideAndShowFirstColumn();
+ void hideAndShowFirstRow();
void checkThatRevisionedPropertiesCannotBeUsedInOldImports();
void checkSyncView_rootView_data();
void checkSyncView_rootView();
@@ -2423,6 +2425,82 @@ void tst_QQuickTableView::hideRowsAndColumns()
QVERIFY(!columnsToHideList.contains(column));
}
+void tst_QQuickTableView::hideAndShowFirstColumn()
+{
+ // Check that if we hide the first column, it will move
+ // the second column to the origin of the viewport. Then check
+ // that if we show the first column again, it will reappear at
+ // the origin of the viewport, and as such, pushing the second
+ // column to the right of it.
+ LOAD_TABLEVIEW("hiderowsandcolumns.qml");
+
+ const int modelSize = 5;
+ auto model = TestModelAsVariant(modelSize, modelSize);
+ tableView->setModel(model);
+
+ // Start by making the first column hidden
+ const auto columnsToHideList = QList<int>() << 0;
+ view->rootObject()->setProperty("columnsToHide", QVariant::fromValue(columnsToHideList));
+
+ WAIT_UNTIL_POLISHED;
+
+ const int expectedColumnCount = modelSize - columnsToHideList.count();
+ QCOMPARE(tableViewPrivate->loadedColumns.count(), expectedColumnCount);
+ QCOMPARE(tableViewPrivate->leftColumn(), 1);
+ QCOMPARE(tableView->contentX(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.x(), 0);
+
+ // Make the first column in the model visible again
+ const auto emptyList = QList<int>();
+ view->rootObject()->setProperty("columnsToHide", QVariant::fromValue(emptyList));
+ tableView->forceLayout();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedColumns.count(), modelSize);
+ QCOMPARE(tableViewPrivate->leftColumn(), 0);
+ QCOMPARE(tableView->contentX(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.x(), 0);
+}
+
+void tst_QQuickTableView::hideAndShowFirstRow()
+{
+ // Check that if we hide the first row, it will move
+ // the second row to the origin of the viewport. Then check
+ // that if we show the first row again, it will reappear at
+ // the origin of the viewport, and as such, pushing the second
+ // row below it.
+ LOAD_TABLEVIEW("hiderowsandcolumns.qml");
+
+ const int modelSize = 5;
+ auto model = TestModelAsVariant(modelSize, modelSize);
+ tableView->setModel(model);
+
+ // Start by making the first row hidden
+ const auto rowsToHideList = QList<int>() << 0;
+ view->rootObject()->setProperty("rowsToHide", QVariant::fromValue(rowsToHideList));
+
+ WAIT_UNTIL_POLISHED;
+
+ const int expectedRowsCount = modelSize - rowsToHideList.count();
+ QCOMPARE(tableViewPrivate->loadedRows.count(), expectedRowsCount);
+ QCOMPARE(tableViewPrivate->topRow(), 1);
+ QCOMPARE(tableView->contentY(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.y(), 0);
+
+ // Make the first row in the model visible again
+ const auto emptyList = QList<int>();
+ view->rootObject()->setProperty("rowsToHide", QVariant::fromValue(emptyList));
+ tableView->forceLayout();
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(tableViewPrivate->loadedRows.count(), modelSize);
+ QCOMPARE(tableViewPrivate->topRow(), 0);
+ QCOMPARE(tableView->contentY(), 0);
+ QCOMPARE(tableViewPrivate->loadedTableOuterRect.y(), 0);
+}
+
void tst_QQuickTableView::checkThatRevisionedPropertiesCannotBeUsedInOldImports()
{
// Check that if you use a QQmlAdaptorModel together with a Repeater, the