diff options
| author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2024-08-30 14:13:23 +0200 |
|---|---|---|
| committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-09-03 19:20:29 +0000 |
| commit | 5688d45261a1d6fc7e1887fe29885a8dc2c4938b (patch) | |
| tree | bd750c0d2559378d66d6443943e9cb52254eaf65 | |
| parent | 5fc1e3f973a20d1a4348227c34be1f6adce213de (diff) | |
QQuickTableView: ensure VerticalHeaderView stays in sync
Bacuse of a copy-paste error in QQuickTableView, TableView
would calulcate the wrong viewport rect for vertically
synced views if the views were not also synced horizontally.
The result of this mistake was that the rows in the two views
would end up with with different heights (and y pos) while
flicking.
This bug has been there for a very long time, but was hidden
becuse of anther bug that was recently fixed (25348bc0e6).
After that fix, this new bug became evident.
This patch will make sure that the offending if-test checks
the correct sync direction, and thereby also calculate the
correctly combined viewport rect.
Fixes: QTBUG-128508
Pick-to: 6.5 6.2
Change-Id: Idf4d93830933c9a28786adaba14e068015564fcc
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 379108f118865f8afc55e46d9a1c217fd30c1c11)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit d8bab4785bf69ccfd0b18987bdfb67a7e9d4a147)
| -rw-r--r-- | src/quick/items/qquicktableview.cpp | 2 | ||||
| -rw-r--r-- | tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | 108 |
2 files changed, 86 insertions, 24 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index a603baa923..34949e0c6c 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -4853,7 +4853,7 @@ void QQuickTableViewPrivate::syncViewportRect() auto syncChild_d = syncChild->d_func(); if (syncChild_d->syncHorizontally) w = qMax(w, syncChild->width()); - if (syncChild_d->syncHorizontally) + if (syncChild_d->syncVertically) h = qMax(h, syncChild->height()); } diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index d92acf779f..3e5a95667d 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -162,7 +162,9 @@ private slots: void checkSyncView_childViews_data(); void checkSyncView_childViews(); void checkSyncView_differentSizedModels(); - void checkSyncView_differentGeometry(); + void checkSyncView_differentGeometry_vertical(); + void checkSyncView_differentGeometry_horizontal(); + void checkSyncView_differentGeometry_both_directions(); void checkSyncView_connect_late_data(); void checkSyncView_connect_late(); void checkSyncView_pageFlicking(); @@ -3074,7 +3076,7 @@ void tst_QQuickTableView::checkSyncView_differentSizedModels() QVERIFY(tableViewHVPrivate->loadedColumns.isEmpty()); } -void tst_QQuickTableView::checkSyncView_differentGeometry() +void tst_QQuickTableView::checkSyncView_differentGeometry_vertical() { // Check that you can have two tables in a syncView relation, where // the sync "child" is larger than the sync view. This means that the @@ -3087,46 +3089,106 @@ void tst_QQuickTableView::checkSyncView_differentGeometry() GET_QML_TABLEVIEW(tableViewV); GET_QML_TABLEVIEW(tableViewHV); - tableView->setWidth(40); - tableView->setHeight(40); + tableView->setHeight(90); + tableViewH->setSyncView(nullptr); + tableViewHV->setSyncView(nullptr); auto tableViewModel = TestModelAsVariant(100, 100); tableView->setModel(tableViewModel); - tableViewH->setModel(tableViewModel); tableViewV->setModel(tableViewModel); - tableViewHV->setModel(tableViewModel); WAIT_UNTIL_POLISHED; - // Check that the column widths are in sync - for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) { - QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); - QCOMPARE(tableViewHV->columnWidth(column), tableView->columnWidth(column)); - } + // Check that the row heights are in sync + for (int row = tableViewV->topRow(); row < tableViewV->bottomRow(); ++row) + QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); + + // Flick in a new row + tableView->setContentY(20); // Check that the row heights are in sync - for (int row = tableViewV->topRow(); row < tableViewV->bottomRow(); ++row) { + for (int row = tableViewV->topRow(); row <= tableViewV->bottomRow(); ++row) QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); - QCOMPARE(tableViewHV->rowHeight(row), tableView->rowHeight(row)); - } +} + +void tst_QQuickTableView::checkSyncView_differentGeometry_horizontal() +{ + // Check that you can have two tables in a syncView relation, where + // the sync "child" is larger than the sync view. This means that the + // child will display more rows and columns than the parent. + // In that case, the sync view will anyway need to load the same rows + // and columns as the child, otherwise the column and row sizes + // cannot be determined for the child. + LOAD_TABLEVIEW("syncviewsimple.qml"); + GET_QML_TABLEVIEW(tableViewH); + GET_QML_TABLEVIEW(tableViewV); + GET_QML_TABLEVIEW(tableViewHV); + + tableView->setWidth(90); + tableViewV->setSyncView(nullptr); + tableViewHV->setSyncView(nullptr); + + auto tableViewModel = TestModelAsVariant(100, 100); + + tableView->setModel(tableViewModel); + tableViewH->setModel(tableViewModel); - // Flick a bit, and do the same test again - tableView->setContentX(200); - tableView->setContentY(200); WAIT_UNTIL_POLISHED; // Check that the column widths are in sync - for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) { + for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); - QCOMPARE(tableViewHV->columnWidth(column), tableView->columnWidth(column)); - } + + // Flick in a new column + tableView->setContentX(20); + + // Check that the column widths are in sync + for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); +} + +void tst_QQuickTableView::checkSyncView_differentGeometry_both_directions() { + // Check that you can have two tables in a syncView relation, where + // the sync "child" is larger than the sync view. This means that the + // child will display more rows and columns than the parent. + // In that case, the sync view will anyway need to load the same rows + // and columns as the child, otherwise the column and row sizes + // cannot be determined for the child. + LOAD_TABLEVIEW("syncviewsimple.qml"); + GET_QML_TABLEVIEW(tableViewH); + GET_QML_TABLEVIEW(tableViewV); + GET_QML_TABLEVIEW(tableViewHV); + + tableView->setWidth(90); + tableView->setHeight(90); + tableViewHV->setSyncView(nullptr); + + auto tableViewModel = TestModelAsVariant(100, 100); + + tableView->setModel(tableViewModel); + tableViewH->setModel(tableViewModel); + tableViewV->setModel(tableViewModel); + + WAIT_UNTIL_POLISHED; // Check that the row heights are in sync - for (int row = tableViewV->topRow(); row < tableViewV->bottomRow(); ++row) { + for (int row = tableViewV->topRow(); row < tableViewV->bottomRow(); ++row) QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); - QCOMPARE(tableViewHV->rowHeight(row), tableView->rowHeight(row)); - } + // Check that the column widths are in sync + for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); + + // Flick in a new row + tableView->setContentX(20); + tableView->setContentY(20); + + // Check that the row heights are in sync + for (int row = tableViewV->topRow(); row <= tableViewV->bottomRow(); ++row) + QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); + // Check that the column widths are in sync + for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); } void tst_QQuickTableView::checkSyncView_connect_late_data() |
