From db8462b107ad3dbf13c1eed43588fb1d9420f4ad Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 10 Feb 2011 15:31:40 +1000 Subject: PathView items were not correctly updated when rootIndex changed. PathView got confused because it queried the model when removing items due to the rootIndex change. This caused new items to be added since the model->count() was not zero (it was the count for the new rootIndex). Calculate the PathView modelCount similarly to the other views (rather than querying the model) and correctly handle the modelCount being set to zero. Change-Id: I9e4fb27c14aa8c77ad37ff01d95c123f909db20d Task-number: QTBUG-16366 Reviewed-by: Bea Lam --- .../graphicsitems/qdeclarativepathview.cpp | 44 ++++++++++++-------- .../qdeclarativepathview/data/treemodel.qml | 19 +++++++++ .../tst_qdeclarativepathview.cpp | 48 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativepathview/data/treemodel.qml diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 050a9ca..269d3b7 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1455,17 +1455,18 @@ void QDeclarativePathView::itemsInserted(int modelIndex, int count) if (!d->isValid() || !isComponentComplete()) return; - d->itemCache += d->items; - d->items.clear(); - if (modelIndex <= d->currentIndex) { - d->currentIndex += count; - emit currentIndexChanged(); - } else if (d->offset != 0) { - d->offset += count; - d->offsetAdj += count; + if (d->modelCount) { + d->itemCache += d->items; + d->items.clear(); + if (modelIndex <= d->currentIndex) { + d->currentIndex += count; + emit currentIndexChanged(); + } else if (d->offset != 0) { + d->offset += count; + d->offsetAdj += count; + } } - - d->modelCount = d->model->count(); + d->modelCount += count; if (d->flicking || d->moving) { d->regenerate(); d->updateCurrent(); @@ -1502,18 +1503,29 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count) d->itemCache += d->items; d->items.clear(); + bool changedOffset = false; if (modelIndex > d->currentIndex) { if (d->offset >= count) { + changedOffset = true; d->offset -= count; d->offsetAdj -= count; } } - d->modelCount = d->model->count(); - d->regenerate(); - d->updateCurrent(); - if (!d->modelCount) + d->modelCount -= count; + if (!d->modelCount) { + while (d->itemCache.count()) + d->releaseItem(d->itemCache.takeLast()); + d->offset = 0; + changedOffset = true; + d->tl.reset(d->moveOffset); update(); + } else { + d->regenerate(); + d->updateCurrent(); + } + if (changedOffset) + emit offsetChanged(); if (currentChanged) emit currentIndexChanged(); emit countChanged(); @@ -1601,7 +1613,7 @@ void QDeclarativePathView::movementEnding() int QDeclarativePathViewPrivate::calcCurrentIndex() { int current = -1; - if (model && items.count()) { + if (modelCount && model && items.count()) { offset = qmlMod(offset, modelCount); if (offset < 0) offset += modelCount; @@ -1617,7 +1629,7 @@ void QDeclarativePathViewPrivate::updateCurrent() Q_Q(QDeclarativePathView); if (moveReason != Mouse) return; - if (!haveHighlightRange || highlightRangeMode != QDeclarativePathView::StrictlyEnforceRange) + if (!modelCount || !haveHighlightRange || highlightRangeMode != QDeclarativePathView::StrictlyEnforceRange) return; int idx = calcCurrentIndex(); diff --git a/tests/auto/declarative/qdeclarativepathview/data/treemodel.qml b/tests/auto/declarative/qdeclarativepathview/data/treemodel.qml new file mode 100644 index 0000000..56f7ae4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepathview/data/treemodel.qml @@ -0,0 +1,19 @@ +import QtQuick 1.0 + +PathView { + width: 320 + height: 240 + function setRoot(index) { + vdm.rootIndex = vdm.modelIndex(index); + } + model: VisualDataModel { + id: vdm + model: myModel + delegate: Text { objectName: "wrapper"; text: display } + } + + path: Path { + startX: 0; startY: 120 + PathLine { x: 320; y: 120 } + } +} diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index f39e4b9..ebb5f98 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include "../../../shared/util.h" @@ -62,6 +63,25 @@ #define SRCDIR "." #endif +static void initStandardTreeModel(QStandardItemModel *model) +{ + QStandardItem *item; + item = new QStandardItem(QLatin1String("Row 1 Item")); + model->insertRow(0, item); + + item = new QStandardItem(QLatin1String("Row 2 Item")); + item->setCheckable(true); + model->insertRow(1, item); + + QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item")); + item->setChild(0, childItem); + + item = new QStandardItem(QLatin1String("Row 3 Item")); + item->setIcon(QIcon()); + model->insertRow(2, item); +} + + class tst_QDeclarativePathView : public QObject { Q_OBJECT @@ -90,6 +110,7 @@ private slots: void visualDataModel(); void undefinedPath(); void mouseDrag(); + void treeModel(); private: QDeclarativeView *createView(); @@ -900,6 +921,33 @@ void tst_QDeclarativePathView::mouseDrag() delete canvas; } +void tst_QDeclarativePathView::treeModel() +{ + QDeclarativeView *canvas = createView(); + + QStandardItemModel model; + initStandardTreeModel(&model); + canvas->engine()->rootContext()->setContextProperty("myModel", &model); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/treemodel.qml")); + + QDeclarativePathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + QCOMPARE(pathview->count(), 3); + + QDeclarativeText *item = findItem(pathview, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->text(), QLatin1String("Row 1 Item")); + + QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1))); + QCOMPARE(pathview->count(), 1); + + QTRY_VERIFY(item = findItem(pathview, "wrapper", 0)); + QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item")); + + delete canvas; +} + QDeclarativeView *tst_QDeclarativePathView::createView() { QDeclarativeView *canvas = new QDeclarativeView(0); -- cgit v0.12