ListViews loses items if all visible items are removed.
authorMartin Jones <martin.jones@nokia.com>
Fri, 13 May 2011 05:28:30 +0000 (15:28 +1000)
committerMartin Jones <martin.jones@nokia.com>
Mon, 30 May 2011 05:50:32 +0000 (15:50 +1000)
Occurs when at end of list and all visible items are removed in
multiple steps, without entering the event loop.
We were not updating visibleIndex if there were no visible items
when handling itemsRemoved().
Also avoid skipping items in refill if there are no valid visible
items for reference.

Change-Id: I2ff58fb191f6b053f33d5446220d597eb15b66d4
Task-number: QTBUG-19198
Reviewed-by: Bea Lam
(cherry picked from commit 576d577438f1193bbc934e904b809d5b23b8d54e)

src/declarative/graphicsitems/qdeclarativelistview.cpp
tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp

index 27300c4..ef6b032 100644 (file)
@@ -733,6 +733,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
     if (doBuffer && (bufferMode & BufferBefore))
         fillFrom = bufferFrom;
 
+    bool haveValidItems = false;
     int modelIndex = visibleIndex;
     qreal itemEnd = visiblePos-1;
     if (!visibleItems.isEmpty()) {
@@ -741,11 +742,13 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
         int i = visibleItems.count() - 1;
         while (i > 0 && visibleItems.at(i)->index == -1)
             --i;
-        if (visibleItems.at(i)->index != -1)
+        if (visibleItems.at(i)->index != -1) {
+            haveValidItems = true;
             modelIndex = visibleItems.at(i)->index + 1;
+        }
     }
 
-    if (visibleItems.count() && (fillFrom > itemEnd+averageSize+spacing
+    if (haveValidItems && (fillFrom > itemEnd+averageSize+spacing
         || fillTo < visiblePos - averageSize - spacing)) {
         // We've jumped more than a page.  Estimate which items are now
         // visible and fill from there.
@@ -3406,9 +3409,9 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
         }
     }
 
-    if (removedVisible && !haveVisibleIndex) {
+    if (!haveVisibleIndex) {
         d->timeline.clear();
-        if (d->itemCount == 0) {
+        if (removedVisible && d->itemCount == 0) {
             d->visibleIndex = 0;
             d->visiblePos = d->header ? d->header->size() : 0;
             d->setPosition(0);
index ff47165..f7d6dd8 100644 (file)
@@ -717,6 +717,16 @@ void tst_QDeclarativeListView::removed(bool animated)
     QTRY_VERIFY(name = findItem<QDeclarativeText>(contentItem, "textName", model.count()-1));
     QCOMPARE(name->text(), QString("New"));
 
+    // Add some more items so that we don't run out
+    for (int i = 50; i < 100; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    // QTBUG-19198 move to end and remove all visible items one at a time.
+    listview->positionViewAtEnd();
+    for (int i = 0; i < 18; ++i)
+        model.removeItems(model.count() - 1, 1);
+    QTRY_VERIFY(findItems<QDeclarativeItem>(contentItem, "wrapper").count() > 16);
+
     delete canvas;
     delete testObject;
 }