From aa599dc4ec09645062b2671ac0482ca051a8a949 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 14 Nov 2011 13:40:03 +1000 Subject: [PATCH] Remove events from the revert list. State change "events" should be removed from the revert list the same way property changes are. Task-number: QTBUG-22583 Change-Id: Ia3f4d16ee8855d163a7f6118a0bc1f8492727940 Reviewed-by: Yunqiao Yin --- src/declarative/util/qdeclarativestate.cpp | 10 ++++- src/declarative/util/qdeclarativestate_p_p.h | 12 +++++- .../qdeclarativestates/data/revertListBug.qml | 47 ++++++++++++++++++++++ .../qdeclarativestates/tst_qdeclarativestates.cpp | 43 ++++++++++++++++++++ 4 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativestates/data/revertListBug.qml diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 2c039f9..1250c0c 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -303,7 +303,10 @@ void QDeclarativeStatePrivate::complete() for (int ii = 0; ii < reverting.count(); ++ii) { for (int jj = 0; jj < revertList.count(); ++jj) { - if (revertList.at(jj).property() == reverting.at(ii)) { + const QDeclarativeRevertAction &revert = reverting.at(ii); + const QDeclarativeSimpleAction &simple = revertList.at(jj); + if ((revert.event && simple.event() == revert.event) || + simple.property() == revert.property) { revertList.removeAt(jj); break; } @@ -685,7 +688,10 @@ void QDeclarativeState::apply(QDeclarativeTransition *trans, QDeclarativeState * a.event->saveCurrentValues(); applyList << a; // Store these special reverts in the reverting list - d->reverting << d->revertList.at(ii).property(); + if (a.event) + d->reverting << a.event; + else + d->reverting << a.property; } } // All the local reverts now become part of the ongoing revertList diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index a9c50f4..55aeecd 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -177,6 +177,16 @@ private: bool m_reverseEvent; }; +class QDeclarativeRevertAction +{ +public: + QDeclarativeRevertAction() : event(0) {} + QDeclarativeRevertAction(const QDeclarativeProperty &prop) : property(prop), event(0) {} + QDeclarativeRevertAction(QDeclarativeActionEvent *e) : event(e) {} + QDeclarativeProperty property; + QDeclarativeActionEvent *event; +}; + class QDeclarativeStateOperationPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QDeclarativeStateOperation) @@ -240,7 +250,7 @@ public: QDeclarativeTransitionManager transitionManager; SimpleActionList revertList; - QList reverting; + QList reverting; QString extends; mutable bool inState; QDeclarativeStateGroup *group; diff --git a/tests/auto/declarative/qdeclarativestates/data/revertListBug.qml b/tests/auto/declarative/qdeclarativestates/data/revertListBug.qml new file mode 100644 index 0000000..fbc4bc5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/revertListBug.qml @@ -0,0 +1,47 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + property Item targetItem: rect1 + + function switchTargetItem() { + if (targetItem === rect1) + targetItem = rect2; + else + targetItem = rect1; + } + + states: State { + name: "reparented" + ParentChange { + target: targetItem + parent: newParent + x: 0; y: 0 + } + } + + Item { + objectName: "originalParent1" + Rectangle { + id: rect1; objectName: "rect1" + width: 50; height: 50 + color: "green" + } + } + + Item { + objectName: "originalParent2" + Rectangle { + id: rect2; objectName: "rect2" + x: 50; y: 50 + width: 50; height: 50 + color: "green" + } + } + + Item { + id: newParent; objectName: "newParent" + x: 200; y: 100 + } +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 5c9760a..efac99c 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -146,6 +146,7 @@ private slots: void editProperties(); void QTBUG_14830(); void avoidFastForward(); + void revertListBug(); }; void tst_qdeclarativestates::initTestCase() @@ -1545,6 +1546,48 @@ void tst_qdeclarativestates::avoidFastForward() QCOMPARE(rect->property("updateCount").toInt(), 1); } +//QTBUG-22583 +void tst_qdeclarativestates::revertListBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("revertListBug.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickRectangle *rect1 = rect->findChild("rect1"); + QQuickRectangle *rect2 = rect->findChild("rect2"); + QQuickItem *origParent1 = rect->findChild("originalParent1"); + QQuickItem *origParent2 = rect->findChild("originalParent2"); + QQuickItem *newParent = rect->findChild("newParent"); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), origParent2); + + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + rectPrivate->setState("reparented"); + + QCOMPARE(rect1->parentItem(), newParent); + QCOMPARE(rect2->parentItem(), origParent2); + + rectPrivate->setState(""); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), origParent2); + + QMetaObject::invokeMethod(rect, "switchTargetItem"); + + rectPrivate->setState("reparented"); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), newParent); + + rectPrivate->setState(""); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), origParent2); //QTBUG-22583 causes rect2's parent item to be origParent1 +} + QTEST_MAIN(tst_qdeclarativestates) #include "tst_qdeclarativestates.moc" -- 2.7.4