From 67e8acf859b57e473a0a9988f9d094121e72bcd9 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Tue, 27 Jun 2023 14:26:06 +0200 Subject: [PATCH] Fix crash while positioning zero sized table view TableView expects view size to be specified for loading model items within it. If not specified, it doesn't load any items (change made after patch set ebefb583c886dba86aa51012fb377762235f2379). If user positions the view through positionViewAtCell or positionViewAtColumn or positionViewAtRow without specifying view size, then the TableView crashes and its an unexpected behavior. This patch set adds validation in the TableView to check for loaded columns or rows during positioning. The document also been updated to show the expected behavior of TableView when size not specified. Fixes: QTBUG-113738 Change-Id: Ibd72caada5bfeb290ab5eff3b9ead1e07b3a7176 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Paul Wicking (cherry picked from commit 4bd3738a4ee0b2124793ddb45367ff6e459f4b55) Reviewed-by: Qt Cherry-pick Bot --- src/quick/items/qquicktableview.cpp | 10 ++++++++-- .../quick/qquicktableview/data/zerosizedtableview.qml | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 42bc7309e0..ec8713a228 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -44,6 +44,12 @@ using the \l HorizontalHeaderView and \l VerticalHeaderView from Qt Quick Controls. + \note TableView will only \l {isRowLoaded()}{load} as many delegate items as + needed to fill up the view. There is no guarantee that items outside the view + will be loaded, although TableView will sometimes pre-load items for + optimization reasons. Hence, a TableView with zero width or height might not + load any delegate items at all. + \section1 Example Usage \section2 C++ Models @@ -5640,7 +5646,7 @@ int QQuickTableView::currentColumn() const void QQuickTableView::positionViewAtRow(int row, PositionMode mode, qreal offset, const QRectF &subRect) { Q_D(QQuickTableView); - if (row < 0 || row >= rows()) + if (row < 0 || row >= rows() || d->loadedRows.isEmpty()) return; // Note: PositionMode::Contain is from here on translated to (Qt::AlignTop | Qt::AlignBottom). @@ -5706,7 +5712,7 @@ void QQuickTableView::positionViewAtRow(int row, PositionMode mode, qreal offset void QQuickTableView::positionViewAtColumn(int column, PositionMode mode, qreal offset, const QRectF &subRect) { Q_D(QQuickTableView); - if (column < 0 || column >= columns()) + if (column < 0 || column >= columns() || d->loadedColumns.isEmpty()) return; // Note: PositionMode::Contain is from here on translated to (Qt::AlignLeft | Qt::AlignRight). diff --git a/tests/auto/quick/qquicktableview/data/zerosizedtableview.qml b/tests/auto/quick/qquicktableview/data/zerosizedtableview.qml index c8d6168b81..5b43553f22 100644 --- a/tests/auto/quick/qquicktableview/data/zerosizedtableview.qml +++ b/tests/auto/quick/qquicktableview/data/zerosizedtableview.qml @@ -15,6 +15,14 @@ Item { width: 0 height: 0 delegate: tableViewDelegate + + Component.onCompleted: { + positionViewAtCell( + Qt.point(0,0), + TableView.AlignHCenter, + Qt.point(-5,-5) + ); + } } Component {