From ad91ab8b7db93ee13db18b1284542b9853183092 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 8 Nov 2011 12:09:39 +1000 Subject: [PATCH] Don't emit model reset on completing a VisualDataModel. The views try and retain their current state as much as possible on a reset which prevents the current item being set to a valid item as would happen if the VisualDataModel was completed before the view. Change-Id: I593a850aeeb58846ab500f193487db4033e26399 Reviewed-by: Bea Lam --- src/quick/items/qquickvisualdatamodel.cpp | 1 - .../data/listview-sections-package.qml | 72 ++++++++++ .../qquicklistview/data/listviewtest-package.qml | 145 ++++++++++++++++++++ .../qtquick2/qquicklistview/tst_qquicklistview.cpp | 143 ++++++++++++++----- .../qtquick2/qquickpathview/tst_qquickpathview.cpp | 2 + .../qquickvisualdatamodel/data/packageView.qml | 2 - .../tst_qquickvisualdatamodel.cpp | 5 +- 7 files changed, 330 insertions(+), 40 deletions(-) create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-sections-package.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listviewtest-package.qml diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp index 990353a..efc03e1 100644 --- a/src/quick/items/qquickvisualdatamodel.cpp +++ b/src/quick/items/qquickvisualdatamodel.cpp @@ -557,7 +557,6 @@ void QQuickVisualDataModel::componentComplete() d->connectModel(d->m_adaptorModel); QVector inserts; - d->m_reset = true; d->m_compositor.append( d->m_adaptorModel, 0, diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-sections-package.qml b/tests/auto/qtquick2/qquicklistview/data/listview-sections-package.qml new file mode 100644 index 0000000..8e5a4c4 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-sections-package.qml @@ -0,0 +1,72 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Package { + Item { + id: wrapper + objectName: "wrapper" + height: ListView.previousSection != ListView.section ? 40 : 20; + width: 240 + Package.name: "package" + Rectangle { + y: wrapper.ListView.previousSection != wrapper.ListView.section ? 20 : 0 + height: 20 + width: parent.width + color: wrapper.ListView.isCurrentItem ? "lightsteelblue" : "white" + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 100 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + objectName: "nextSection" + x: 150 + text: wrapper.ListView.nextSection + } + Text { + x: 200 + text: wrapper.y + } + } + Rectangle { + color: "#99bb99" + height: wrapper.ListView.previousSection != wrapper.ListView.section ? 20 : 0 + width: parent.width + visible: wrapper.ListView.previousSection != wrapper.ListView.section ? true : false + Text { text: wrapper.ListView.section } + } + } + } + }, + VisualDataModel { + id: visualModel + model: testModel + delegate: myDelegate + } + + ] + ListView { + id: list + objectName: "list" + width: 240 + height: 320 + model: visualModel.parts.package + section.property: "number" + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listviewtest-package.qml b/tests/auto/qtquick2/qquicklistview/data/listviewtest-package.qml new file mode 100644 index 0000000..54d4dab --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listviewtest-package.qml @@ -0,0 +1,145 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 240 + height: 320 + color: "#ffffff" + + property int count: list.count + property bool showHeader: false + property bool showFooter: false + property real hr: list.visibleArea.heightRatio + function heightRatio() { + return list.visibleArea.heightRatio + } + + function checkProperties() { + testObject.error = false; + if (visualModel.model != testModel) { + console.log("model property incorrect"); + testObject.error = true; + } + if (!testObject.animate && visualModel.delegate != myDelegate) { + console.log("delegate property incorrect - expected myDelegate"); + testObject.error = true; + } + if (testObject.animate && visualModel.delegate != animatedDelegate) { + console.log("delegate property incorrect - expected animatedDelegate"); + testObject.error = true; + } + if (testObject.invalidHighlight && list.highlight != invalidHl) { + console.log("highlight property incorrect - expected invalidHl"); + testObject.error = true; + } + if (!testObject.invalidHighlight && list.highlight != myHighlight) { + console.log("highlight property incorrect - expected myHighlight"); + testObject.error = true; + } + } + resources: [ + Component { + id: myDelegate + Package { + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Package.name: "package" + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + }, + Component { + id: animatedDelegate + Package { + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Package.name: "package" + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + ListView.onRemove: SequentialAnimation { + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } + + } + } + } + }, + Component { + id: myHighlight + Rectangle { color: "green" } + }, + Component { + id: invalidHl + SmoothedAnimation {} + }, + Component { + id: headerFooter + Rectangle { height: 30; width: 240; color: "blue" } + }, + VisualDataModel { + id: visualModel + + model: testModel + delegate: testObject.animate ? animatedDelegate : myDelegate + } + + ] + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + model: visualModel.parts.package + highlight: testObject.invalidHighlight ? invalidHl : myHighlight + highlightMoveSpeed: 1000 + highlightResizeSpeed: 1000 + cacheBuffer: testObject.cacheBuffer + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null + } +} diff --git a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp index ea10523..bd92b91 100644 --- a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp @@ -71,23 +71,29 @@ private slots: void cleanupTestCase(); // Test both QListModelInterface and QAbstractItemModel model types void qListModelInterface_items(); + void qListModelInterface_package_items(); void qAbstractItemModel_items(); void qListModelInterface_changed(); + void qListModelInterface_package_changed(); void qAbstractItemModel_changed(); void qListModelInterface_inserted(); void qListModelInterface_inserted_more(); void qListModelInterface_inserted_more_data(); + void qListModelInterface_package_inserted(); void qAbstractItemModel_inserted(); void qAbstractItemModel_inserted_more(); void qAbstractItemModel_inserted_more_data(); void qListModelInterface_removed(); + void qListModelInterface_package_removed(); void qAbstractItemModel_removed(); void qListModelInterface_moved(); void qListModelInterface_moved_data(); + void qListModelInterface_package_moved(); + void qListModelInterface_package_moved_data(); void qAbstractItemModel_moved(); void qAbstractItemModel_moved_data(); @@ -95,6 +101,7 @@ private slots: void multipleChanges_data(); void qListModelInterface_clear(); + void qListModelInterface_package_clear(); void qAbstractItemModel_clear(); void insertBeforeVisible(); @@ -108,7 +115,9 @@ private slots: void enforceRange(); void enforceRange_withoutHighlight(); void spacing(); - void sections(); + void qListModelInterface_sections(); + void qListModelInterface_package_sections(); + void qAbstractItemModel_sections(); void sectionsPositioning(); void sectionsDelegate(); void cacheBuffer(); @@ -153,13 +162,14 @@ private slots: void asynchronous(); private: - template void items(); - template void changed(); - template void inserted(); + template void items(const QUrl &source, bool forceLayout); + template void changed(const QUrl &source, bool forceLayout); + template void inserted(const QUrl &source); template void inserted_more(); - template void removed(bool animated); - template void moved(); - template void clear(); + template void removed(const QUrl &source, bool animated); + template void moved(const QUrl &source); + template void clear(const QUrl &source); + template void sections(const QUrl &source); QQuickView *createView(); void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName); @@ -458,7 +468,7 @@ tst_QQuickListView::tst_QQuickListView() } template -void tst_QQuickListView::items() +void tst_QQuickListView::items(const QUrl &source, bool forceLayout) { QQuickView *canvas = createView(); @@ -473,7 +483,7 @@ void tst_QQuickListView::items() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->setSource(source); qApp->processEvents(); QQuickListView *listview = findItem(canvas->rootObject(), "list"); @@ -526,6 +536,10 @@ void tst_QQuickListView::items() T model2; ctxt->setContextProperty("testModel", &model2); + // Force a layout, necessary if ListView is completed before VisualDataModel. + if (forceLayout) + QCOMPARE(listview->property("count").toInt(), 0); + int itemCount = findItems(contentItem, "wrapper").count(); QTRY_VERIFY(itemCount == 0); @@ -538,7 +552,7 @@ void tst_QQuickListView::items() template -void tst_QQuickListView::changed() +void tst_QQuickListView::changed(const QUrl &source, bool forceLayout) { QQuickView *canvas = createView(); @@ -553,7 +567,7 @@ void tst_QQuickListView::changed() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->setSource(source); qApp->processEvents(); QQuickFlickable *listview = findItem(canvas->rootObject(), "list"); @@ -562,6 +576,10 @@ void tst_QQuickListView::changed() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + // Force a layout, necessary if ListView is completed before VisualDataModel. + if (forceLayout) + QCOMPARE(listview->property("count").toInt(), model.count()); + model.modifyItem(1, "Will", "9876"); QQuickText *name = findItem(contentItem, "textName", 1); QTRY_VERIFY(name != 0); @@ -575,7 +593,7 @@ void tst_QQuickListView::changed() } template -void tst_QQuickListView::inserted() +void tst_QQuickListView::inserted(const QUrl &source) { QQuickView *canvas = createView(); canvas->show(); @@ -591,7 +609,8 @@ void tst_QQuickListView::inserted() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->setSource(source); + //canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); qApp->processEvents(); QQuickListView *listview = findItem(canvas->rootObject(), "list"); @@ -916,7 +935,7 @@ void tst_QQuickListView::insertBeforeVisible_data() } template -void tst_QQuickListView::removed(bool /* animated */) +void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) { QQuickView *canvas = createView(); @@ -930,7 +949,7 @@ void tst_QQuickListView::removed(bool /* animated */) TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->setSource(source); canvas->show(); qApp->processEvents(); @@ -1094,7 +1113,7 @@ void tst_QQuickListView::removed(bool /* animated */) } template -void tst_QQuickListView::clear() +void tst_QQuickListView::clear(const QUrl &source) { QQuickView *canvas = createView(); @@ -1108,7 +1127,7 @@ void tst_QQuickListView::clear() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->setSource(source); qApp->processEvents(); QQuickListView *listview = findItem(canvas->rootObject(), "list"); @@ -1135,7 +1154,7 @@ void tst_QQuickListView::clear() } template -void tst_QQuickListView::moved() +void tst_QQuickListView::moved(const QUrl &source) { QFETCH(qreal, contentY); QFETCH(int, from); @@ -1158,7 +1177,7 @@ void tst_QQuickListView::moved() TestObject *testObject = new TestObject; ctxt->setContextProperty("testObject", testObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->setSource(source); qApp->processEvents(); QQuickListView *listview = findItem(canvas->rootObject(), "list"); @@ -1767,19 +1786,20 @@ void tst_QQuickListView::spacing() delete testObject; } -void tst_QQuickListView::sections() +template +void tst_QQuickListView::sections(const QUrl &source) { QQuickView *canvas = createView(); canvas->show(); - TestModel model; + T model; for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), QString::number(i/5)); QDeclarativeContext *ctxt = canvas->rootContext(); ctxt->setContextProperty("testModel", &model); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections.qml"))); + canvas->setSource(source); qApp->processEvents(); QQuickListView *listview = findItem(canvas->rootObject(), "list"); @@ -4106,27 +4126,42 @@ void tst_QQuickListView::snapToItem() void tst_QQuickListView::qListModelInterface_items() { - items(); + items(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), false); +} + +void tst_QQuickListView::qListModelInterface_package_items() +{ + items(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml")), true); } void tst_QQuickListView::qAbstractItemModel_items() { - items(); + items(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), false); } void tst_QQuickListView::qListModelInterface_changed() { - changed(); + changed(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), false); +} + +void tst_QQuickListView::qListModelInterface_package_changed() +{ + changed(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml")), true); } void tst_QQuickListView::qAbstractItemModel_changed() { - changed(); + changed(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), false); } void tst_QQuickListView::qListModelInterface_inserted() { - inserted(); + inserted(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); +} + +void tst_QQuickListView::qListModelInterface_package_inserted() +{ + inserted(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml"))); } void tst_QQuickListView::qListModelInterface_inserted_more() @@ -4141,7 +4176,7 @@ void tst_QQuickListView::qListModelInterface_inserted_more_data() void tst_QQuickListView::qAbstractItemModel_inserted() { - inserted(); + inserted(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); } void tst_QQuickListView::qAbstractItemModel_inserted_more() @@ -4156,19 +4191,25 @@ void tst_QQuickListView::qAbstractItemModel_inserted_more_data() void tst_QQuickListView::qListModelInterface_removed() { - removed(false); - removed(true); + removed(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), false); + removed(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), true); +} + +void tst_QQuickListView::qListModelInterface_package_removed() +{ + removed(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml")), false); + removed(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml")), true); } void tst_QQuickListView::qAbstractItemModel_removed() { - removed(false); - removed(true); + removed(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), false); + removed(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")), true); } void tst_QQuickListView::qListModelInterface_moved() { - moved(); + moved(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); } void tst_QQuickListView::qListModelInterface_moved_data() @@ -4176,9 +4217,19 @@ void tst_QQuickListView::qListModelInterface_moved_data() moved_data(); } +void tst_QQuickListView::qListModelInterface_package_moved() +{ + moved(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml"))); +} + +void tst_QQuickListView::qListModelInterface_package_moved_data() +{ + moved_data(); +} + void tst_QQuickListView::qAbstractItemModel_moved() { - moved(); + moved(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); } void tst_QQuickListView::qAbstractItemModel_moved_data() @@ -4188,12 +4239,32 @@ void tst_QQuickListView::qAbstractItemModel_moved_data() void tst_QQuickListView::qListModelInterface_clear() { - clear(); + clear(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); +} + +void tst_QQuickListView::qListModelInterface_package_clear() +{ + clear(QUrl::fromLocalFile(TESTDATA("listviewtest-package.qml"))); } void tst_QQuickListView::qAbstractItemModel_clear() { - clear(); + clear(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); +} + +void tst_QQuickListView::qListModelInterface_sections() +{ + sections(QUrl::fromLocalFile(TESTDATA("listview-sections.qml"))); +} + +void tst_QQuickListView::qListModelInterface_package_sections() +{ + sections(QUrl::fromLocalFile(TESTDATA("listview-sections-package.qml"))); +} + +void tst_QQuickListView::qAbstractItemModel_sections() +{ + sections(QUrl::fromLocalFile(TESTDATA("listview-sections.qml"))); } void tst_QQuickListView::creationContext() diff --git a/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp b/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp index 133769f..0bfa65b 100644 --- a/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp @@ -1208,6 +1208,8 @@ void tst_QQuickPathView::package() QQuickView *canvas = createView(); QVERIFY(canvas); canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview_package.qml"))); + canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickPathView *pathView = canvas->rootObject()->findChild("photoPathView"); QVERIFY(pathView); diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/packageView.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/packageView.qml index e7efcbe..682f383 100644 --- a/tests/auto/qtquick2/qquickvisualdatamodel/data/packageView.qml +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/packageView.qml @@ -49,7 +49,6 @@ Item { right: parent.horizontalCenter; bottom: parent.bottom } model: visualModel.parts.left - currentIndex: 0 } ListView { @@ -60,6 +59,5 @@ Item { right: parent.right; bottom: parent.bottom } model: visualModel.parts.right - currentIndex: 20 } } diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index 1389a53..dfd8c75 100644 --- a/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -692,7 +692,10 @@ void tst_qquickvisualdatamodel::packagesDestroyed() QTRY_VERIFY(rightContent != 0); QCOMPARE(leftview->currentIndex(), 0); - QCOMPARE(rightview->currentIndex(), 20); + QCOMPARE(rightview->currentIndex(), 0); + + rightview->setCurrentIndex(20); + QTRY_COMPARE(rightview->contentY(), 100.0); QDeclarativeGuard left; QDeclarativeGuard right; -- 1.7.2.5