summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2021-03-10 17:21:07 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-03-27 08:01:09 +0000
commit032b12cd5074e4618f56668912465a4dca8d72f4 (patch)
tree4baff5960757f5432aaf84c85a04a26b3e7835df
parent0b930884f1a64b2531ef8cbf1a077ed2955bf4ae (diff)
QQuickTableView: always update content size when rebuilding small tables
If you have a TableView with only a couple of rows, and you add a third one, the contentHeight doesn't update. This is fine if not all rows are loaded (some are outside the viewport), but when they are all inside, it should update to reflect the exact height. The same is also the case for the contentWidth. If you add a new row that increases the with of a column (and all columns are visible), the contentWidth should update. This patch adds an extra check when we do a rebuild (which we do when you add a new row), to see if all rows or columns are loaded. And if that is the case, we update contentHeight or contentWidth, respecitively. Fixes: QTBUG-92099 Change-Id: I806bfb7c3606fca97c5d27cbb91856cc40df9fb8 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> (cherry picked from commit d6a5afd120838647e0dd2a420dacf06389f0a48e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/quick/items/qquicktableview.cpp26
-rw-r--r--src/quick/items/qquicktableview_p_p.h2
-rw-r--r--tests/auto/quick/qquicktableview/data/sizefromdelegate.qml74
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp25
4 files changed, 125 insertions, 2 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 9bdf18cd87..63bedb9734 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -777,6 +777,28 @@ int QQuickTableViewPrivate::nextVisibleEdgeIndex(Qt::Edge edge, int startIndex)
return foundIndex;
}
+bool QQuickTableViewPrivate::allColumnsLoaded()
+{
+ // Returns true if all the columns in the model (that are not
+ // hidden by the columnWidthProvider) are currently loaded and visible.
+ const bool firstColumnLoaded = nextVisibleEdgeIndexAroundLoadedTable(Qt::LeftEdge) == kEdgeIndexAtEnd;
+ if (!firstColumnLoaded)
+ return false;
+ bool lastColumnLoaded = nextVisibleEdgeIndexAroundLoadedTable(Qt::RightEdge) == kEdgeIndexAtEnd;
+ return lastColumnLoaded;
+}
+
+bool QQuickTableViewPrivate::allRowsLoaded()
+{
+ // Returns true if all the rows in the model (that are not hidden
+ // by the columnWidthProvider) are currently loaded and visible.
+ const bool firstColumnLoaded = nextVisibleEdgeIndexAroundLoadedTable(Qt::TopEdge) == kEdgeIndexAtEnd;
+ if (!firstColumnLoaded)
+ return false;
+ bool lastColumnLoaded = nextVisibleEdgeIndexAroundLoadedTable(Qt::BottomEdge) == kEdgeIndexAtEnd;
+ return lastColumnLoaded;
+}
+
void QQuickTableViewPrivate::updateContentWidth()
{
// Note that we actually never really know what the content size / size of the full table will
@@ -2136,12 +2158,12 @@ void QQuickTableViewPrivate::layoutAfterLoadingInitialTable()
relayoutTableItems();
syncLoadedTableRectFromLoadedTable();
- if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentWidth)) {
+ if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentWidth) || allColumnsLoaded()) {
updateAverageColumnWidth();
updateContentWidth();
}
- if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentHeight)) {
+ if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentHeight) || allRowsLoaded()) {
updateAverageRowHeight();
updateContentHeight();
}
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index ef408be668..b01fe3cf93 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -385,6 +385,8 @@ public:
int nextVisibleEdgeIndex(Qt::Edge edge, int startIndex);
int nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge);
+ bool allColumnsLoaded();
+ bool allRowsLoaded();
inline int edgeToArrayIndex(Qt::Edge edge);
void clearEdgeSizeCache();
diff --git a/tests/auto/quick/qquicktableview/data/sizefromdelegate.qml b/tests/auto/quick/qquicktableview/data/sizefromdelegate.qml
new file mode 100644
index 0000000000..b4a04c89cb
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/sizefromdelegate.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ anchors.margins: 1
+ delegate: tableViewDelegate
+ columnSpacing: 1
+ rowSpacing: 1
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ color: "lightgray"
+ implicitWidth: text.width
+ implicitHeight: text.height
+
+ Text {
+ id: text
+ anchors.centerIn: parent
+ text: modelData
+ }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 8a85575cca..005aae0639 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -123,6 +123,7 @@ private slots:
void checkForceLayoutDuringModelChange();
void checkForceLayoutWhenAllItemsAreHidden();
void checkContentWidthAndHeight();
+ void checkContentWidthAndHeightForSmallTables();
void checkPageFlicking();
void checkExplicitContentWidthAndHeight();
void checkExtents_origin();
@@ -716,6 +717,30 @@ void tst_QQuickTableView::checkContentWidthAndHeight()
QCOMPARE(tableView->contentHeight(), expectedSizeInit);
}
+void tst_QQuickTableView::checkContentWidthAndHeightForSmallTables()
+{
+ // For tables where all the columns in the model are loaded, we know
+ // the exact table width, and can therefore update the content width
+ // if e.g new rows are added or removed. The same is true for rows.
+ // This test will check that we do so.
+ LOAD_TABLEVIEW("sizefromdelegate.qml");
+
+ TestModel model(3, 3);
+ tableView->setModel(QVariant::fromValue(&model));
+ WAIT_UNTIL_POLISHED;
+
+ const qreal initialContentWidth = tableView->contentWidth();
+ const qreal initialContentHeight = tableView->contentHeight();
+ const QString longText = QStringLiteral("Adding a row with a very long text");
+ model.insertRow(0);
+ model.setModelData(QPoint(0, 0), QSize(1, 1), longText);
+
+ WAIT_UNTIL_POLISHED;
+
+ QVERIFY(tableView->contentWidth() > initialContentWidth);
+ QVERIFY(tableView->contentHeight() > initialContentHeight);
+}
+
void tst_QQuickTableView::checkPageFlicking()
{
// Check that we rebuild the table instead of refilling edges, if the viewport moves