diff options
| author | Kaj Grönholm <[email protected]> | 2024-04-11 12:06:13 +0300 |
|---|---|---|
| committer | Qt Cherry-pick Bot <[email protected]> | 2024-04-16 06:39:12 +0000 |
| commit | 61247583dc0273d954370d6f585de44c6f73fff1 (patch) | |
| tree | 0bf80f42ccad5c6fd24ff75af100209f18ff8f76 | |
| parent | 81b88576d6917479dcba90ead043b97b5f5bc3c0 (diff) | |
Make sure PathView index isn't negative when filling the model
Pick-to: 6.5
Fixes: QTBUG-46487
Change-Id: Iba2a875756f0c06b86bb0a0aaf66eac329b2382b
Reviewed-by: Santhosh Kumar <[email protected]>
(cherry picked from commit b31bfde4bd840a94cdd4b2223e8f7c345850bd66)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
| -rw-r--r-- | src/quick/items/qquickpathview.cpp | 1 | ||||
| -rw-r--r-- | tests/auto/quick/qquickpathview/data/qtbug46487.qml | 28 | ||||
| -rw-r--r-- | tests/auto/quick/qquickpathview/tst_qquickpathview.cpp | 63 |
3 files changed, 92 insertions, 0 deletions
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 3b1f953208..ce61543f42 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -2025,6 +2025,7 @@ void QQuickPathView::refill() startPos = d->highlightRangeStart; // With no items, then "end" is just off the top so we populate via append endIdx = (qRound(d->modelCount - d->offset) - 1) % d->modelCount; + endIdx = qMax(-1, endIdx); // endIdx shouldn't be smaller than -1 endPos = d->positionOfIndex(endIdx); } //Append diff --git a/tests/auto/quick/qquickpathview/data/qtbug46487.qml b/tests/auto/quick/qquickpathview/data/qtbug46487.qml new file mode 100644 index 0000000000..840d77ffe4 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug46487.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +PathView { + id: view + property int delegatesCreated: 0 + property int delegatesDestroyed: 0 + + width: 400 + height: 400 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + pathItemCount: 5 + currentIndex: 1 + model: customModel + delegate: Text { + text: "item: " + index + " of: " + view.count + Component.onCompleted: view.delegatesCreated++; + Component.onDestruction: view.delegatesDestroyed++; + } + path: Path { + startX: 50 + startY: 0 + PathLine { + x: 50 + y: 400 + } + } +} diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index e2edf87708..1b06e0047b 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -134,6 +134,7 @@ private slots: void mousePressAfterFlick(); void qtbug90479(); void overCached(); + void qtbug46487(); private: QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); @@ -2935,6 +2936,68 @@ void tst_QQuickPathView::overCached() QVERIFY(pathview->property("delegatesDestroyed").toInt() <= 1); } +class CustomModel : public QAbstractListModel +{ +public: + CustomModel(QObject *parent = 0) : QAbstractListModel(parent) { + m_values << 0 << 1 << 2 << 3 << 4; + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const { + Q_UNUSED(parent); + return m_values.count(); + } + QVariant data(const QModelIndex &index, int role) const { + if (index.row() < 0 || m_values.count() <= index.row()) + return QVariant(); + + return m_values[index.row()]; + } + + Q_INVOKABLE void shrink() { + beginResetModel(); + m_values.takeLast(); + m_values.takeLast(); + endResetModel(); + } + +private: + QList<int> m_values; +}; + +void tst_QQuickPathView::qtbug46487() +{ + QScopedPointer<QQuickView> window(createView()); + + CustomModel* model = new CustomModel; + QQmlContext *ctxt = window->rootContext(); + ctxt->setContextProperty("customModel", model); + + window->setSource(testFileUrl("qtbug46487.qml")); + window->show(); + qApp->processEvents(); + + QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); + QVERIFY(pathview); + + QTest::qWait(500); + + // Should create just pathItemCount amount and not destroy any + QCOMPARE(pathview->count(), 5); + QCOMPARE(pathview->property("delegatesCreated").toInt(), 5); + QCOMPARE(pathview->property("delegatesDestroyed").toInt(), 0); + + // Resets the model and removes 2 items. + model->shrink(); + QTest::qWait(500); + + // Should destroy previous items (begin/endResetModel) and + // (re)create 3 new items. + QCOMPARE(pathview->count(), 3); + QCOMPARE(pathview->property("delegatesCreated").toInt(), 5 + 3); + QCOMPARE(pathview->property("delegatesDestroyed").toInt(), 5); +} + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc" |
