From bd2eece4a68808c771d39cd53922ef538d0ba54d Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 29 Sep 2011 14:50:27 +1000 Subject: [PATCH] currentIndex not updated correctly if list is initially empty The currentIndex shouldn't be incremented when itemCount == 0 and also it should be default to 0 after the first item is added. Task-number: QTBUG-21643 Change-Id: Ia9418c0cd1cd659410123394c880dfe72557fa16 Reviewed-on: http://codereview.qt-project.org/5768 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- src/declarative/items/qsgitemview.cpp | 7 ++- .../data/fillModelOnComponentCompleted.qml | 36 +++++++++++++++++ .../auto/declarative/qsglistview/data/header1.qml | 33 ---------------- .../declarative/qsglistview/tst_qsglistview.cpp | 41 +++++++++++++++++++- 4 files changed, 81 insertions(+), 36 deletions(-) create mode 100644 tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml delete mode 100644 tests/auto/declarative/qsglistview/data/header1.qml diff --git a/src/declarative/items/qsgitemview.cpp b/src/declarative/items/qsgitemview.cpp index 666b471..1791fb9 100644 --- a/src/declarative/items/qsgitemview.cpp +++ b/src/declarative/items/qsgitemview.cpp @@ -97,18 +97,21 @@ void QSGItemViewChangeSet::applyChanges(const QDeclarativeChangeSet &changeSet) } } foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) { - itemCount += i.count; if (moveId == -1) { - if (newCurrentIndex >= i.index) { + if (itemCount && newCurrentIndex >= i.index) { newCurrentIndex += i.count; currentChanged = true; } else if (newCurrentIndex < 0) { newCurrentIndex = 0; currentChanged = true; + } else if (newCurrentIndex == 0 && !itemCount) { + // this is the first item, set the initial current index + currentChanged = true; } } else if (moveId == i.moveId) { newCurrentIndex = i.index + moveOffset; } + itemCount += i.count; } } diff --git a/tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml b/tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml new file mode 100644 index 0000000..906e6ad --- /dev/null +++ b/tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + + ListModel { id: testModel } + + ListView { + id: list + objectName: "list" + width: parent.width + anchors.top: parent.top + anchors.bottom: parent.bottom + model: testModel + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + } + footer: Rectangle { + width: parent.width + height: 40 + color: "green" + } + header: Text { objectName: "header"; text: "Header" } + } + + Component.onCompleted: { + if (setCurrentToZero == 0) + list.currentIndex = 0 + for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i}) + } +} diff --git a/tests/auto/declarative/qsglistview/data/header1.qml b/tests/auto/declarative/qsglistview/data/header1.qml deleted file mode 100644 index 8ba6e57..0000000 --- a/tests/auto/declarative/qsglistview/data/header1.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - - ListModel { id: testModel } - - ListView { - id: list - objectName: "list" - width: parent.width - anchors.top: parent.top - anchors.bottom: parent.bottom - model: testModel - delegate: Text { - objectName: "wrapper" - font.pointSize: 20 - text: index - } - footer: Rectangle { - width: parent.width - height: 40 - color: "green" - } - header: Text { objectName: "header"; text: "Header" } - } - - Component.onCompleted: { - for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i}) - } -} diff --git a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp index c1be773..101f0fc 100644 --- a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp +++ b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp @@ -94,6 +94,8 @@ private slots: void swapWithFirstItem(); void itemList(); + void currentIndex_delayedItemCreation(); + void currentIndex_delayedItemCreation_data(); void currentIndex(); void noCurrentIndex(); void enforceRange(); @@ -1833,6 +1835,42 @@ void tst_QSGListView::sectionsPositioning() delete canvas; } +void tst_QSGListView::currentIndex_delayedItemCreation() +{ + QFETCH(bool, setCurrentToZero); + + QSGView *canvas = createView(); + + TestModel model; + + // test currentIndexChanged() is emitted even if currentIndex = 0 on start up + // (since the currentItem will have changed and that shares the same index) + canvas->rootContext()->setContextProperty("setCurrentToZero", setCurrentToZero); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/fillModelOnComponentCompleted.qml")); + qApp->processEvents(); + + QSGListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QSGItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QSignalSpy spy(listview, SIGNAL(currentIndexChanged())); + QCOMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(spy.count(), 1); + + delete canvas; +} + +void tst_QSGListView::currentIndex_delayedItemCreation_data() +{ + QTest::addColumn("setCurrentToZero"); + + QTest::newRow("set to 0") << true; + QTest::newRow("don't set to 0") << false; +} + void tst_QSGListView::currentIndex() { TestModel model; @@ -2733,7 +2771,8 @@ void tst_QSGListView::header_delayItemCreation() TestModel model; - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header1.qml")); + canvas->rootContext()->setContextProperty("setCurrentToZero", false); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/fillModelOnComponentCompleted.qml")); qApp->processEvents(); QSGListView *listview = findItem(canvas->rootObject(), "list"); -- 1.7.2.5