diff options
-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" |