diff options
Diffstat (limited to 'tests/auto/quick/qquicklistview')
4 files changed, 550 insertions, 22 deletions
diff --git a/tests/auto/quick/qquicklistview/data/displacedTransitions.qml b/tests/auto/quick/qquicklistview/data/displacedTransitions.qml new file mode 100644 index 0000000000..cc7892e930 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/displacedTransitions.qml @@ -0,0 +1,128 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 500 + height: 600 + + property int duration: 10 + property int count: list.count + + Component { + id: myDelegate + Rectangle { + id: wrapper + + property string nameData: name + + objectName: "wrapper" + height: 20 + width: 240 + Text { text: index } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + + onXChanged: checkPos() + onYChanged: checkPos() + + function checkPos() { + if (Qt.point(x, y) == displaced_transitionVia) + model_displaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == addDisplaced_transitionVia) + model_addDisplaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == moveDisplaced_transitionVia) + model_moveDisplaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == removeDisplaced_transitionVia) + model_removeDisplaced_transitionVia.addItem(name, "") + } + } + } + + ListView { + id: list + + property int targetTransitionsDone + property int displaceTransitionsDone + + objectName: "list" + focus: true + anchors.centerIn: parent + width: 240 + height: 320 + model: testModel + delegate: myDelegate + + displaced: useDisplaced ? displaced : null + addDisplaced: useAddDisplaced ? addDisplaced : null + moveDisplaced: useMoveDisplaced ? moveDisplaced : null + removeDisplaced: useRemoveDisplaced ? removeDisplaced : null + + Transition { + id: displaced + enabled: displacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: displaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: displaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: addDisplaced + enabled: addDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: addDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: addDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: moveDisplaced + enabled: moveDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: moveDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: moveDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: removeDisplaced + enabled: removeDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: removeDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: removeDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + } + + Rectangle { + anchors.fill: list + color: "lightsteelblue" + opacity: 0.2 + } +} + diff --git a/tests/auto/quick/qquicklistview/data/multipleTransitions.qml b/tests/auto/quick/qquicklistview/data/multipleTransitions.qml index 50ffbc53c3..8264b42b64 100644 --- a/tests/auto/quick/qquicklistview/data/multipleTransitions.qml +++ b/tests/auto/quick/qquicklistview/data/multipleTransitions.qml @@ -10,7 +10,7 @@ Rectangle { // interrupting transitions will still produce the correct result) property int timeBetweenActions: duration / 2 - property int duration: 100 + property int duration: 300 property int count: list.count @@ -45,6 +45,8 @@ Rectangle { property bool runningAddDisplaced: false property bool runningMoveTargets: false property bool runningMoveDisplaced: false + property bool runningRemoveTargets: false + property bool runningRemoveDisplaced: false objectName: "list" focus: true @@ -70,6 +72,7 @@ Rectangle { id: addDisplaced SequentialAnimation { ScriptAction { script: list.runningAddDisplaced = true } + PauseAnimation { duration: rippleAddDisplaced ? addDisplaced.ViewTransition.index * root.duration/10 : 0 } ParallelAnimation { NumberAnimation { properties: "x"; from: addDisplaced_transitionFrom.x; duration: root.duration } NumberAnimation { properties: "y"; from: addDisplaced_transitionFrom.y; duration: root.duration } @@ -101,6 +104,30 @@ Rectangle { ScriptAction { script: list.runningMoveDisplaced = false } } } + + remove: Transition { + id: removeTargets + SequentialAnimation { + ScriptAction { script: list.runningRemoveTargets = true } + ParallelAnimation { + NumberAnimation { properties: "x"; to: removeTargets_transitionTo.x; duration: root.duration } + NumberAnimation { properties: "y"; to: removeTargets_transitionTo.y; duration: root.duration } + } + ScriptAction { script: list.runningRemoveTargets = false } + } + } + + removeDisplaced: Transition { + id: removeDisplaced + SequentialAnimation { + ScriptAction { script: list.runningRemoveDisplaced = true } + ParallelAnimation { + NumberAnimation { properties: "x"; from: removeDisplaced_transitionFrom.x; duration: root.duration } + NumberAnimation { properties: "y"; from: removeDisplaced_transitionFrom.y; duration: root.duration } + } + ScriptAction { script: list.runningRemoveDisplaced = false } + } + } } Rectangle { diff --git a/tests/auto/quick/qquicklistview/data/sectionpropertychange.qml b/tests/auto/quick/qquicklistview/data/sectionpropertychange.qml new file mode 100644 index 0000000000..f4679b5af0 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/sectionpropertychange.qml @@ -0,0 +1,92 @@ +import QtQuick 2.0 + +Rectangle { + width: 320; height: 480 + + Rectangle { + id: groupButtons + width: 300; height: 30 + color: "yellow" + border.width: 1 + Text { + anchors.centerIn: parent + text: "swap" + } + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + } + MouseArea { + anchors.fill: parent + onClicked: switchGroups() + } + } + + function switchGroups() { + if ("title" === myListView.groupBy) + myListView.groupBy = "genre" + else + myListView.groupBy = "title" + } + + Component.onCompleted: { + myListView.model = generateModel(myListView) + } + + ListView { + id: myListView + objectName: "list" + + clip: true + property string groupBy: "title" + + anchors { + top: groupButtons.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + delegate: Item { + objectName: "wrapper" + height: 50 + width: 320 + Text { id: t; text: model.title } + Text { text: model.author; font.pixelSize: 10; anchors.top: t.bottom } + Text { text: parent.y; anchors.right: parent.right } + } + + onGroupByChanged: { + model.move(0,1,1) + section.property = groupBy + } + + section { + criteria: ViewSection.FullString + delegate: Rectangle { width: 320; height: 25; color: "lightblue" + objectName: "sect" + Text {text: section } + Text { text: parent.y; anchors.right: parent.right } + } + property: "title" + } + } + + function generateModel(theParent) + { + var books = [ + { "author": "Billy Bob", "genre": "Anarchism", "title": "Frogs and Love" }, + { "author": "Lefty Smith", "genre": "Horror", "title": "Chainsaws for Noobs" } + ]; + + var model = Qt.createQmlObject("import QtQuick 2.0; ListModel {}", theParent); + + for (var i = 0; i < books.length; ++i) { + var book = books[i]; + model.append(book); + } + return model; + } + +} + diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index bcac5917d6..9195aab632 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -51,7 +51,6 @@ #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickvisualitemmodel_p.h> #include <QtQml/private/qquicklistmodel_p.h> -#include <QtQuick/private/qquickchangeset_p.h> #include "../../shared/util.h" #include "../shared/viewtestutil.h" #include "../shared/visualtestutil.h" @@ -126,6 +125,7 @@ private slots: void qAbstractItemModel_sections(); void sectionsPositioning(); void sectionsDelegate(); + void sectionPropertyChange(); void cacheBuffer(); void positionViewAtIndex(); void resetModel(); @@ -179,6 +179,8 @@ private slots: void moveTransitions_data(); void removeTransitions(); void removeTransitions_data(); + void displacedTransitions(); + void displacedTransitions_data(); void multipleTransitions(); void multipleTransitions_data(); @@ -491,6 +493,7 @@ void tst_QQuickListView::inserted_more() canvas->setSource(testFileUrl("listviewtest.qml")); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -644,6 +647,7 @@ void tst_QQuickListView::insertBeforeVisible() canvas->setSource(testFileUrl("listviewtest.qml")); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -734,6 +738,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) canvas->setSource(source); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -923,6 +928,7 @@ void tst_QQuickListView::removed_more(const QUrl &source) canvas->setSource(source); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -1144,6 +1150,7 @@ void tst_QQuickListView::moved(const QUrl &source) canvas->setSource(source); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -1370,6 +1377,7 @@ void tst_QQuickListView::multipleChanges() canvas->setSource(testFileUrl("listviewtest.qml")); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -2090,9 +2098,9 @@ void tst_QQuickListView::sectionsPositioning() QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItem(5); QTRY_COMPARE(listview->count(), model.count()); - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem<QQuickItem>(contentItem, - "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); + for (int i = 1; i < 3; ++i) { + QQuickItem *item = findVisibleChild(contentItem, + "sect_" + QString::number(i)); QVERIFY(item); QTRY_COMPARE(item->y(), qreal(i*20*6)); } @@ -2130,6 +2138,52 @@ void tst_QQuickListView::sectionsPositioning() delete canvas; } +void tst_QQuickListView::sectionPropertyChange() +{ + QQuickView *canvas = createView(); + + canvas->setSource(testFileUrl("sectionpropertychange.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + // Confirm items positioned correctly + for (int i = 0; i < 2; ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*75.)); + } + + QMetaObject::invokeMethod(canvas->rootObject(), "switchGroups"); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + // Confirm items positioned correctly + for (int i = 0; i < 2; ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*75.)); + } + + QMetaObject::invokeMethod(canvas->rootObject(), "switchGroups"); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + // Confirm items positioned correctly + for (int i = 0; i < 2; ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*75.)); + } + + delete canvas; +} + void tst_QQuickListView::currentIndex_delayedItemCreation() { QFETCH(bool, setCurrentToZero); @@ -4814,6 +4868,7 @@ void tst_QQuickListView::populateTransitions() canvas->rootContext()->setContextProperty("model_transitionVia", &model_transitionVia); canvas->setSource(testFileUrl("populateTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QVERIFY(listview); @@ -4951,6 +5006,7 @@ void tst_QQuickListView::addTransitions() ctxt->setContextProperty("testObject", testObject); canvas->setSource(testFileUrl("addTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5145,6 +5201,7 @@ void tst_QQuickListView::moveTransitions() ctxt->setContextProperty("testObject", testObject); canvas->setSource(testFileUrl("moveTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5347,6 +5404,7 @@ void tst_QQuickListView::removeTransitions() ctxt->setContextProperty("testObject", testObject); canvas->setSource(testFileUrl("removeTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5508,20 +5566,235 @@ void tst_QQuickListView::removeTransitions_data() << 17 << 3 << ListRange(); } +void tst_QQuickListView::displacedTransitions() +{ + QFETCH(bool, useDisplaced); + QFETCH(bool, displacedEnabled); + QFETCH(bool, useAddDisplaced); + QFETCH(bool, addDisplacedEnabled); + QFETCH(bool, useMoveDisplaced); + QFETCH(bool, moveDisplacedEnabled); + QFETCH(bool, useRemoveDisplaced); + QFETCH(bool, removeDisplacedEnabled); + QFETCH(ListChange, change); + QFETCH(ListRange, expectedDisplacedIndexes); + + QaimModel model; + for (int i = 0; i < 30; i++) + model.addItem("Original item" + QString::number(i), ""); + QaimModel model_displaced_transitionVia; + QaimModel model_addDisplaced_transitionVia; + QaimModel model_moveDisplaced_transitionVia; + QaimModel model_removeDisplaced_transitionVia; + + QPointF displaced_transitionVia(-50, -100); + QPointF addDisplaced_transitionVia(-150, 100); + QPointF moveDisplaced_transitionVia(50, -100); + QPointF removeDisplaced_transitionVia(150, 100); + + QQuickView *canvas = createView(); + QQmlContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject(canvas); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testObject", testObject); + ctxt->setContextProperty("model_displaced_transitionVia", &model_displaced_transitionVia); + ctxt->setContextProperty("model_addDisplaced_transitionVia", &model_addDisplaced_transitionVia); + ctxt->setContextProperty("model_moveDisplaced_transitionVia", &model_moveDisplaced_transitionVia); + ctxt->setContextProperty("model_removeDisplaced_transitionVia", &model_removeDisplaced_transitionVia); + ctxt->setContextProperty("displaced_transitionVia", displaced_transitionVia); + ctxt->setContextProperty("addDisplaced_transitionVia", addDisplaced_transitionVia); + ctxt->setContextProperty("moveDisplaced_transitionVia", moveDisplaced_transitionVia); + ctxt->setContextProperty("removeDisplaced_transitionVia", removeDisplaced_transitionVia); + ctxt->setContextProperty("useDisplaced", useDisplaced); + ctxt->setContextProperty("displacedEnabled", displacedEnabled); + ctxt->setContextProperty("useAddDisplaced", useAddDisplaced); + ctxt->setContextProperty("addDisplacedEnabled", addDisplacedEnabled); + ctxt->setContextProperty("useMoveDisplaced", useMoveDisplaced); + ctxt->setContextProperty("moveDisplacedEnabled", moveDisplacedEnabled); + ctxt->setContextProperty("useRemoveDisplaced", useRemoveDisplaced); + ctxt->setContextProperty("removeDisplacedEnabled", removeDisplacedEnabled); + canvas->setSource(testFileUrl("displacedTransitions.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); + listview->setProperty("displaceTransitionsDone", false); + + switch (change.type) { + case ListChange::Inserted: + { + QList<QPair<QString, QString> > targetItemData; + for (int i=change.index; i<change.index + change.count; ++i) + targetItemData << qMakePair(QString("new item %1").arg(i), QString::number(i)); + model.insertItems(change.index, targetItemData); + QTRY_COMPARE(model.count(), listview->count()); + break; + } + case ListChange::Removed: + model.removeItems(change.index, change.count); + QTRY_COMPARE(model.count(), listview->count()); + break; + case ListChange::Moved: + model.moveItems(change.index, change.to, change.count); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + break; + case ListChange::SetCurrent: + case ListChange::SetContentY: + break; + } + if ((useDisplaced && displacedEnabled) + || (useAddDisplaced && addDisplacedEnabled) + || (useMoveDisplaced && moveDisplacedEnabled) + || (useRemoveDisplaced && removeDisplacedEnabled)) { + QTRY_VERIFY(listview->property("displaceTransitionsDone").toBool()); + } + + if (change.type == ListChange::Inserted && useAddDisplaced && addDisplacedEnabled) + model_addDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with add displaced", "shouldn't have been animated with add displaced"); + else + QCOMPARE(model_addDisplaced_transitionVia.count(), 0); + if (change.type == ListChange::Moved && useMoveDisplaced && moveDisplacedEnabled) + model_moveDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with move displaced", "shouldn't have been animated with move displaced"); + else + QCOMPARE(model_moveDisplaced_transitionVia.count(), 0); + if (change.type == ListChange::Removed && useRemoveDisplaced && removeDisplacedEnabled) + model_removeDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with remove displaced", "shouldn't have been animated with remove displaced"); + else + QCOMPARE(model_removeDisplaced_transitionVia.count(), 0); + + if (useDisplaced && displacedEnabled + && ( (change.type == ListChange::Inserted && (!useAddDisplaced || !addDisplacedEnabled)) + || (change.type == ListChange::Moved && (!useMoveDisplaced || !moveDisplacedEnabled)) + || (change.type == ListChange::Removed && (!useRemoveDisplaced || !removeDisplacedEnabled))) ) { + model_displaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with generic displaced", "shouldn't have been animated with generic displaced"); + } else { + QCOMPARE(model_displaced_transitionVia.count(), 0); + } + + // verify all items moved to the correct final positions + QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); + for (int i=0; i < model.count() && i < items.count(); ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->x(), 0.0); + QCOMPARE(item->y(), i * 20.0); + QQuickText *name = findItem<QQuickText>(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + } + + delete canvas; +} + +void tst_QQuickListView::displacedTransitions_data() +{ + QTest::addColumn<bool>("useDisplaced"); + QTest::addColumn<bool>("displacedEnabled"); + QTest::addColumn<bool>("useAddDisplaced"); + QTest::addColumn<bool>("addDisplacedEnabled"); + QTest::addColumn<bool>("useMoveDisplaced"); + QTest::addColumn<bool>("moveDisplacedEnabled"); + QTest::addColumn<bool>("useRemoveDisplaced"); + QTest::addColumn<bool>("removeDisplacedEnabled"); + QTest::addColumn<ListChange>("change"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("no displaced transitions at all") + << false << false + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("just displaced") + << true << true + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("just displaced (not enabled)") + << true << false + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("displaced + addDisplaced") + << true << true + << true << true + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("displaced + addDisplaced (not enabled)") + << true << true + << true << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("displaced + moveDisplaced") + << true << true + << false << false + << true << true + << false << false + << ListChange::move(0, 10, 1) << ListRange(1, 10); + + QTest::newRow("displaced + moveDisplaced (not enabled)") + << true << true + << false << false + << true << false + << false << false + << ListChange::move(0, 10, 1) << ListRange(1, 10); + + QTest::newRow("displaced + removeDisplaced") + << true << true + << false << false + << false << false + << true << true + << ListChange::remove(0, 1) << ListRange(1, 16); + + QTest::newRow("displaced + removeDisplaced (not enabled)") + << true << true + << false << false + << false << false + << true << false + << ListChange::remove(0, 1) << ListRange(1, 16); + + + QTest::newRow("displaced + add, should use generic displaced for a remove") + << true << true + << true << true + << false << false + << true << false + << ListChange::remove(0, 1) << ListRange(1, 16); +} + void tst_QQuickListView::multipleTransitions() { + QSKIP("QTBUG-24523"); + // Tests that if you interrupt a transition in progress with another action that // cancels the previous transition, the resulting items are still placed correctly. QFETCH(int, initialCount); QFETCH(qreal, contentY); QFETCH(QList<ListChange>, changes); + QFETCH(bool, rippleAddDisplaced); - // add transitions on the left, moves on the right QPointF addTargets_transitionFrom(-50, -50); QPointF addDisplaced_transitionFrom(-50, 50); QPointF moveTargets_transitionFrom(50, -50); QPointF moveDisplaced_transitionFrom(50, 50); + QPointF removeTargets_transitionTo(-100, 300); + QPointF removeDisplaced_transitionFrom(100, 300); QmlListModel model; for (int i = 0; i < initialCount; i++) @@ -5536,8 +5809,12 @@ void tst_QQuickListView::multipleTransitions() ctxt->setContextProperty("addDisplaced_transitionFrom", addDisplaced_transitionFrom); ctxt->setContextProperty("moveTargets_transitionFrom", moveTargets_transitionFrom); ctxt->setContextProperty("moveDisplaced_transitionFrom", moveDisplaced_transitionFrom); + ctxt->setContextProperty("removeTargets_transitionTo", removeTargets_transitionTo); + ctxt->setContextProperty("removeDisplaced_transitionFrom", removeDisplaced_transitionFrom); + ctxt->setContextProperty("rippleAddDisplaced", rippleAddDisplaced); canvas->setSource(testFileUrl("multipleTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5545,6 +5822,11 @@ void tst_QQuickListView::multipleTransitions() QVERIFY(contentItem != 0); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + if (contentY != 0) { + listview->setContentY(contentY); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + } + int timeBetweenActions = canvas->rootObject()->property("timeBetweenActions").toInt(); QList<QPair<QString, QString> > targetItems; @@ -5604,20 +5886,9 @@ void tst_QQuickListView::multipleTransitions() } QCOMPARE(listview->count(), model.count()); - QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); - int firstVisibleIndex = -1; - for (int i=0; i<items.count(); i++) { - if (items[i]->y() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); - break; - } - } - QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); - // verify all items moved to the correct final positions - int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); + for (int i=0; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); QTRY_COMPARE(item->x(), 0.0); @@ -5636,18 +5907,21 @@ void tst_QQuickListView::multipleTransitions_data() QTest::addColumn<int>("initialCount"); QTest::addColumn<qreal>("contentY"); QTest::addColumn<QList<ListChange> >("changes"); + QTest::addColumn<bool>("rippleAddDisplaced"); // the added item and displaced items should move to final dest correctly QTest::newRow("add item, then move it immediately") << 10 << 0.0 << (QList<ListChange>() << ListChange::insert(0, 1) << ListChange::move(0, 3, 1) - ); + ) + << false; // items affected by the add should change from move to add transition QTest::newRow("move, then insert item before the moved item") << 20 << 0.0 << (QList<ListChange>() << ListChange::move(1, 10, 3) << ListChange::insert(0, 1) - ); + ) + << false; // items should be placed correctly if you trigger a transition then refill for that index QTest::newRow("add at 0, flick down, flick back to top and add at 0 again") << 20 << 0.0 << (QList<ListChange>() @@ -5655,7 +5929,14 @@ void tst_QQuickListView::multipleTransitions_data() << ListChange::setContentY(80.0) << ListChange::setContentY(0.0) << ListChange::insert(0, 1) - ); + ) + << false; + + QTest::newRow("insert then remove same index, with ripple effect on add displaced") << 20 << 0.0 << (QList<ListChange>() + << ListChange::insert(1, 1) + << ListChange::remove(1, 1) + ) + << true; } QList<int> tst_QQuickListView::toIntList(const QVariantList &list) |