From 80615c3036e689061588a144339125b7fb8e66e5 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 10 Nov 2011 14:30:08 +1000 Subject: [PATCH] Fix refill where zero-size items are involved 881091b5c0f1d2ead2b70e54f7ac2e4c17680b4e was incorrect since it meant that any items following zero-sized delegates would not be deleted as they scrolled up past the top of the view. refill() should be deleting these items as well as any zero-sized items before them. Task-number: QTBUG-22014 Change-Id: I10cd30bb85a8ec1ddaa2a1cbaa924192536ef6fc Reviewed-by: Martin Jones --- src/declarative/items/qquicklistview.cpp | 32 ++++++++++++++++------ .../qquicklistview/tst_qquicklistview.cpp | 20 +++++++++++++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/declarative/items/qquicklistview.cpp b/src/declarative/items/qquicklistview.cpp index 9dc9130..4fd4e97 100644 --- a/src/declarative/items/qquicklistview.cpp +++ b/src/declarative/items/qquicklistview.cpp @@ -634,18 +634,34 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer FxViewItem *item = 0; bool changed = false; - while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() <= bufferFrom) { + // Remove items from the start of the view. + // Zero-sized items shouldn't be removed unless a non-zero-sized item is also being + // removed, otherwise a zero-sized item is infinitely added and removed over and + // over by refill(). + int index = 0; + while (visibleItems.count() > 1 && index < visibleItems.count() + && (item = visibleItems.at(index)) && item->endPosition() <= bufferFrom) { if (item->attached->delayRemove()) break; - if (item->size() == 0) - break; + if (item->size() > 0) { // qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition(); - if (item->index != -1) - visibleIndex++; - visibleItems.removeFirst(); - releaseItem(item); - changed = true; + + // remove this item and all zero-sized items before it + while (item) { + if (item->index != -1) + visibleIndex++; + visibleItems.removeAt(index); + releaseItem(item); + if (index == 0) + break; + item = visibleItems.at(--index); + } + changed = true; + } else { + index++; + } } + while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) { if (item->attached->delayRemove()) break; diff --git a/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp b/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp index ae37724..36824f8 100644 --- a/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp @@ -3468,7 +3468,7 @@ void tst_QQuickListView::resizeFirstDelegate() // check the content y has not jumped up and down QCOMPARE(listview->contentY(), 0.0); QSignalSpy spy(listview, SIGNAL(contentYChanged())); - QTest::qWait(300); + QTest::qWait(100); QCOMPARE(spy.count(), 0); for (int i = 1; i < model.count(); ++i) { @@ -3477,6 +3477,24 @@ void tst_QQuickListView::resizeFirstDelegate() QTRY_COMPARE(item->y(), (i-1)*20.0); } + + // QTBUG-22014: refill doesn't clear items scrolling off the top of the + // list if they follow a zero-sized delegate + + for (int i = 0; i < 10; i++) + model.addItem("Item" + QString::number(i), ""); + + item = findItem(contentItem, "wrapper", 1); + QVERIFY(item); + item->setHeight(0); + + listview->setCurrentIndex(19); + qApp->processEvents(); + + // items 0-3 should have been deleted + for (int i=0; i<4; i++) + QTRY_VERIFY(!findItem(contentItem, "wrapper", i)); + delete testObject; delete canvas; } -- 2.7.4