From 3bb4880d63e0ebc972d500d3c7538127cd709a5d Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 26 Jun 2012 13:13:11 +1000 Subject: [PATCH] Fix section delegates not updating when changed. Delete all allocated section items before doing an update when the section delegate is changed. Task-number: QTBUG-24899 Change-Id: I09dc7a1c602a49ad7bb37512a7e5116392259457 Reviewed-by: Martin Jones --- src/quick/items/qquicklistview.cpp | 21 +++++++ .../qquicklistview/data/sectiondelegatechange.qml | 61 ++++++++++++++++++++ .../quick/qquicklistview/tst_qquicklistview.cpp | 41 +++++++++++++ 3 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 tests/auto/quick/qquicklistview/data/sectiondelegatechange.qml diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 062cd58..d67e02e 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -113,6 +113,7 @@ public: virtual void updateSections(); QQuickItem *getSectionItem(const QString §ion); void releaseSectionItem(QQuickItem *item); + void releaseSectionItems(); void updateInlineSection(FxListItemSG *); void updateCurrentSection(); void updateStickySections(); @@ -209,6 +210,8 @@ void QQuickViewSection::setCriteria(QQuickViewSection::SectionCriteria criteria) void QQuickViewSection::setDelegate(QQmlComponent *delegate) { if (delegate != m_delegate) { + if (m_delegate) + m_view->releaseSectionItems(); m_delegate = delegate; emit delegateChanged(); m_view->updateSections(); @@ -980,6 +983,24 @@ void QQuickListViewPrivate::releaseSectionItem(QQuickItem *item) delete item; } + +void QQuickListViewPrivate::releaseSectionItems() +{ + for (int i = 0; i < visibleItems.count(); ++i) { + FxListItemSG *listItem = static_cast(visibleItems.at(i)); + if (listItem->section()) { + qreal pos = listItem->position(); + releaseSectionItem(listItem->section()); + listItem->setSection(0); + listItem->setPosition(pos); + } + } + for (int i = 0; i < sectionCacheSize; ++i) { + delete sectionCache[i]; + sectionCache[i] = 0; + } +} + void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem) { if (!sectionCriteria || !sectionCriteria->delegate()) diff --git a/tests/auto/quick/qquicklistview/data/sectiondelegatechange.qml b/tests/auto/quick/qquicklistview/data/sectiondelegatechange.qml new file mode 100644 index 0000000..eee15ed --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/sectiondelegatechange.qml @@ -0,0 +1,61 @@ +import QtQuick 2.0 + +ListView { + width: 240 + height: 320 + + function switchDelegates() { + section.delegate = section.delegate === delegate1 + ? delegate2 + : delegate1 + } + + Component { + id: delegate1 + + Rectangle { + objectName: "section1" + color: "lightsteelblue" + border.width: 1; + width: 240 + height: 25 + + Text { + anchors.centerIn: parent + text: section + } + } + } + Component { + id: delegate2 + + Rectangle { + objectName: "section2" + color: "yellow" + border.width: 1; + width: 240 + height: 50 + + Text { + anchors.centerIn: parent + text: section + } + } + } + + section.property: "modelData" + section.delegate: delegate1 + + model: 20 + delegate: Rectangle { + objectName: "item" + border.width: 1 + width: 240 + height: 25 + + Text { + anchors.centerIn: parent + text: modelData + } + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index c6a7230..848ffb1 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -146,6 +146,7 @@ private slots: void sectionsDragOutsideBounds(); void sectionsDelegate_headerVisibility(); void sectionPropertyChange(); + void sectionDelegateChange(); void cacheBuffer(); void positionViewAtIndex(); void resetModel(); @@ -2431,6 +2432,46 @@ void tst_QQuickListView::sectionPropertyChange() delete canvas; } +void tst_QQuickListView::sectionDelegateChange() +{ + QQuickView *canvas = createView(); + + canvas->setSource(testFileUrl("sectiondelegatechange.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQUICK_VERIFY_POLISH(listview); + + QVERIFY(findItems(contentItem, "section1").count() > 0); + QCOMPARE(findItems(contentItem, "section2").count(), 0); + + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, "item", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*50.)); + } + + QMetaObject::invokeMethod(canvas->rootObject(), "switchDelegates"); + QQUICK_VERIFY_POLISH(listview); + + QCOMPARE(findItems(contentItem, "section1").count(), 0); + QVERIFY(findItems(contentItem, "section2").count() > 0); + + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, "item", i); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(50. + i*75.)); + } + + delete canvas; +} + void tst_QQuickListView::currentIndex_delayedItemCreation() { QFETCH(bool, setCurrentToZero); -- 1.7.2.5