aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2020-10-19 11:30:00 +0200
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2020-10-22 17:04:16 +0200
commit03d3d26f6e0cc1698b3a16b0695dcc71420219e8 (patch)
tree093d40ec614de666c83e51a1a687bd650df37a58 /tests
parentd62437be7743bbb5d7697bf2d3bf4b74cc79223e (diff)
TableView: ensure we update content size upon model changes
For tables of non-trivial sizes, we usually don't know what the content size will be unless we load all rows and columns, which we simply cannot do. Because of this, we have up till now chosen a strategy where we normally just calculate a predicted content size up-front, when we table is built, and afterwards just stick to that prediction. This strategy works for big tables that fills more than one size of the viewport, and if the number of rows and column in the model stays around the same. But for tables that start off smaller than the viewport, and later expands to grow out of it, it simply fails. And the failure is such that the tableview can get stuck, with no way way for the user to flick around to see the rest of the contents. An example is TreeView that might only show the root node at start-up, but as you start to expand the tree, it will quickly add more rows than what fits inside the viewport. And in that case, the contentHeight will be totally off, and in turn, make the scrollbar be based on wrong values, and sometimes not work at all (e.g if it has the flag Flickable::StopAtBounds). This patch will change the implementation so that we recalculate the content size whenever it should logially change. That is, if e.g the model add or remove rows and columns, or if you change spacing. This still doesn't mean that contentWidth/Height reports the correct size of the table, but at least it will be a better guestimate for smaller tables, and at the same time, work together with Flickable and ScrollBars. Fixes: QTBUG-87680 Change-Id: Ie2d2e7c1f1519dc7a5d5269a6d25e34cf441b3fe Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit dac2c8aec4917742aed6e311cf542dc37da60809)
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp96
1 files changed, 86 insertions, 10 deletions
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index b876ead301..6339e5a59d 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -178,6 +178,8 @@ private slots:
void delegateWithRequiredProperties();
void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable();
void replaceModel();
+ void checkContentSize_data();
+ void checkContentSize();
};
tst_QQuickTableView::tst_QQuickTableView()
@@ -590,6 +592,12 @@ void tst_QQuickTableView::checkForceLayoutEndUpDoingALayout()
for (auto fxItem : tableViewPrivate->loadedItems)
QCOMPARE(fxItem->item->height(), newDelegateSize);
+
+ // Check that the content height has been updated as well
+ const qreal rowSpacing = tableView->rowSpacing();
+ const qreal colSpacing = tableView->columnSpacing();
+ QCOMPARE(tableView->contentWidth(), (10 * (newDelegateSize + colSpacing)) - colSpacing);
+ QCOMPARE(tableView->contentHeight(), (9 * (newDelegateSize + rowSpacing)) - rowSpacing);
}
void tst_QQuickTableView::checkForceLayoutDuringModelChange()
@@ -1295,10 +1303,10 @@ void tst_QQuickTableView::checkSpacingValues()
tableView->polish();
WAIT_UNTIL_POLISHED;
- const qreal expectedInitialContentWidth = columnCount * (delegateWidth + tableView->columnSpacing()) - tableView->columnSpacing();
- const qreal expectedInitialContentHeight = rowCount * (delegateHeight + tableView->rowSpacing()) - tableView->rowSpacing();
- QCOMPARE(tableView->contentWidth(), expectedInitialContentWidth);
- QCOMPARE(tableView->contentHeight(), expectedInitialContentHeight);
+ qreal expectedContentWidth = columnCount * (delegateWidth + tableView->columnSpacing()) - tableView->columnSpacing();
+ qreal expectedContentHeight = rowCount * (delegateHeight + tableView->rowSpacing()) - tableView->rowSpacing();
+ QCOMPARE(tableView->contentWidth(), expectedContentWidth);
+ QCOMPARE(tableView->contentHeight(), expectedContentHeight);
// Valid spacing assignment
tableView->setRowSpacing(42);
@@ -1309,12 +1317,10 @@ void tst_QQuickTableView::checkSpacingValues()
tableView->polish();
WAIT_UNTIL_POLISHED;
- // Even after changing spacing, TableView will keep the initial guesstimated content size. The
- // reason is that deciding the content size based on the currently visible row/columns/spacing
- // will almost always be at a little bit wrong at best. So instead of pretending that TableView
- // knows what the size of the full table is, it sticks with the first guesstimate.
- QCOMPARE(tableView->contentWidth(), expectedInitialContentWidth);
- QCOMPARE(tableView->contentHeight(), expectedInitialContentHeight);
+ expectedContentWidth = columnCount * (delegateWidth + tableView->columnSpacing()) - tableView->columnSpacing();
+ expectedContentHeight = rowCount * (delegateHeight + tableView->rowSpacing()) - tableView->rowSpacing();
+ QCOMPARE(tableView->contentWidth(), expectedContentWidth);
+ QCOMPARE(tableView->contentHeight(), expectedContentHeight);
// Negative spacing is allowed, and can be used to eliminate double edges
// in the grid if the delegate is a rectangle with a border.
@@ -2775,6 +2781,76 @@ void tst_QQuickTableView::replaceModel()
QCOMPARE(tableView->contentHeight(), 0);
}
+void tst_QQuickTableView::checkContentSize_data()
+{
+ QTest::addColumn<int>("rowCount");
+ QTest::addColumn<int>("colCount");
+
+ QTest::newRow("4x4") << 4 << 4;
+ QTest::newRow("100x100") << 100 << 100;
+ QTest::newRow("0x0") << 0 << 0;
+}
+
+void tst_QQuickTableView::checkContentSize()
+{
+ QFETCH(int, rowCount);
+ QFETCH(int, colCount);
+
+ // Check that the content size is initially correct, and that
+ // it updates when we change e.g the model or spacing (QTBUG-87680)
+ LOAD_TABLEVIEW("plaintableview.qml");
+
+ TestModel model(rowCount, colCount);
+ tableView->setModel(QVariant::fromValue(&model));
+ tableView->setRowSpacing(1);
+ tableView->setColumnSpacing(2);
+
+ WAIT_UNTIL_POLISHED;
+
+ const qreal delegateWidth = 100;
+ const qreal delegateHeight = 50;
+ qreal colSpacing = tableView->columnSpacing();
+ qreal rowSpacing = tableView->rowSpacing();
+
+ // Check that content size has the exepected initial values
+ QCOMPARE(tableView->contentWidth(), colCount == 0 ? 0 : (colCount * (delegateWidth + colSpacing)) - colSpacing);
+ QCOMPARE(tableView->contentHeight(), rowCount == 0 ? 0 : (rowCount * (delegateHeight + rowSpacing)) - rowSpacing);
+
+ // Set no spacing
+ rowSpacing = 0;
+ colSpacing = 0;
+ tableView->setRowSpacing(rowSpacing);
+ tableView->setColumnSpacing(colSpacing);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(tableView->contentWidth(), colCount * delegateWidth);
+ QCOMPARE(tableView->contentHeight(), rowCount * delegateHeight);
+
+ // Set typical spacing values
+ rowSpacing = 2;
+ colSpacing = 3;
+ tableView->setRowSpacing(rowSpacing);
+ tableView->setColumnSpacing(colSpacing);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(tableView->contentWidth(), colCount == 0 ? 0 : (colCount * (delegateWidth + colSpacing)) - colSpacing);
+ QCOMPARE(tableView->contentHeight(), rowCount == 0 ? 0 : (rowCount * (delegateHeight + rowSpacing)) - rowSpacing);
+
+ // Add a row and a column
+ model.insertRow(0);
+ model.insertColumn(0);
+ rowCount = model.rowCount();
+ colCount = model.columnCount();
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(tableView->contentWidth(), (colCount * (delegateWidth + colSpacing)) - colSpacing);
+ QCOMPARE(tableView->contentHeight(), (rowCount * (delegateHeight + rowSpacing)) - rowSpacing);
+
+ // Remove a row (this should also make affect contentWidth if rowCount becomes 0)
+ model.removeRow(0);
+ rowCount = model.rowCount();
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(tableView->contentWidth(), rowCount == 0 ? 0 : (colCount * (delegateWidth + colSpacing)) - colSpacing);
+ QCOMPARE(tableView->contentHeight(), rowCount == 0 ? 0 : (rowCount * (delegateHeight + rowSpacing)) - rowSpacing);
+}
+
QTEST_MAIN(tst_QQuickTableView)
#include "tst_qquicktableview.moc"