currentIndex not updated correctly if list is initially empty
authorBea Lam <bea.lam@nokia.com>
Thu, 29 Sep 2011 04:50:27 +0000 (14:50 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 3 Oct 2011 07:04:13 +0000 (09:04 +0200)
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>

src/declarative/items/qsgitemview.cpp
tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml [moved from tests/auto/declarative/qsglistview/data/header1.qml with 91% similarity]
tests/auto/declarative/qsglistview/tst_qsglistview.cpp

index 666b471..1791fb9 100644 (file)
@@ -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;
     }
 }
 
@@ -14,6 +14,7 @@ Rectangle {
         anchors.top: parent.top
         anchors.bottom: parent.bottom
         model: testModel
+
         delegate: Text {
             objectName: "wrapper"
             font.pointSize: 20
@@ -28,6 +29,8 @@ Rectangle {
     }
 
     Component.onCompleted: {
+        if (setCurrentToZero == 0)
+            list.currentIndex = 0
         for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i})
     }
 }
index c1be773..101f0fc 100644 (file)
@@ -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<QSGListView>(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<bool>("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<QSGListView>(canvas->rootObject(), "list");