From 5f0a3cd6dbae87b5944c3cb31fdc294fc0ac1163 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 23 Nov 2009 09:56:08 +1000 Subject: Remove deleted state operations from the state. --- src/declarative/util/qmlstate_p_p.h | 25 ++++++++- tests/auto/declarative/states/data/deleting.qml | 11 ++++ .../auto/declarative/states/data/deletingState.qml | 13 +++++ tests/auto/declarative/states/tst_states.cpp | 65 ++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/states/data/deleting.qml create mode 100644 tests/auto/declarative/states/data/deletingState.qml diff --git a/src/declarative/util/qmlstate_p_p.h b/src/declarative/util/qmlstate_p_p.h index 095a7d2..75eb3fd 100644 --- a/src/declarative/util/qmlstate_p_p.h +++ b/src/declarative/util/qmlstate_p_p.h @@ -102,7 +102,30 @@ public: QString name; QmlBinding *when; - QmlConcreteList operations; + + class OperationList; + struct OperationGuard : public QGuard + { + OperationGuard(QObject *obj, OperationList *l) : list(l) { (QGuard&)*this = obj; } + OperationList *list; + void objectDestroyed(QmlStateOperation *) { + // we assume priv will always be destroyed after objectDestroyed calls + list->removeOne(*this); + } + }; + + typedef QList GuardedOpList; + class OperationList : public GuardedOpList, public QmlList + { + public: + virtual void append(QmlStateOperation* v) { GuardedOpList::append(OperationGuard(v, this)); } + virtual void insert(int i, QmlStateOperation* v) { GuardedOpList::insert(i, OperationGuard(v, this)); } + virtual void clear() { GuardedOpList::clear(); } + virtual QmlStateOperation* at(int i) const { return GuardedOpList::at(i); } + virtual void removeAt(int i) { GuardedOpList::removeAt(i); } + virtual int count() const { return GuardedOpList::count(); } + }; + OperationList operations; QmlTransitionManager transitionManager; diff --git a/tests/auto/declarative/states/data/deleting.qml b/tests/auto/declarative/states/data/deleting.qml new file mode 100644 index 0000000..0c512dd --- /dev/null +++ b/tests/auto/declarative/states/data/deleting.qml @@ -0,0 +1,11 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue"; objectName: "pc1" } + PropertyChanges { target: MyRectangle; radius: 5; objectName: "pc2" } + } +} diff --git a/tests/auto/declarative/states/data/deletingState.qml b/tests/auto/declarative/states/data/deletingState.qml new file mode 100644 index 0000000..9dc46a6 --- /dev/null +++ b/tests/auto/declarative/states/data/deletingState.qml @@ -0,0 +1,13 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + StateGroup { + id: stateGroup + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + } + } +} diff --git a/tests/auto/declarative/states/tst_states.cpp b/tests/auto/declarative/states/tst_states.cpp index a4da1f1..4847535 100644 --- a/tests/auto/declarative/states/tst_states.cpp +++ b/tests/auto/declarative/states/tst_states.cpp @@ -44,6 +44,7 @@ #include #include #include +#include class tst_states : public QObject { @@ -69,6 +70,8 @@ private slots: void explicitChanges(); void propertyErrors(); void incorrectRestoreBug(); + void deletingChange(); + void deletingState(); }; void tst_states::basicChanges() @@ -738,6 +741,68 @@ void tst_states::incorrectRestoreBug() QCOMPARE(rect->color(),QColor("green")); } +void tst_states::deletingChange() +{ + QmlEngine engine; + + QmlComponent rectComponent(&engine, SRCDIR "/data/deleting.qml"); + QmlGraphicsRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->radius(),qreal(5)); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->radius(),qreal(0)); + + QmlPropertyChanges *pc = rect->findChild("pc1"); + QVERIFY(pc != 0); + delete pc; + + QmlState *state = rect->findChild(); + QVERIFY(state != 0); + QCOMPARE(state->changes()->count(), 1); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->radius(),qreal(5)); + + delete rect; +} + +void tst_states::deletingState() +{ + QmlEngine engine; + + QmlComponent rectComponent(&engine, SRCDIR "/data/deletingState.qml"); + QmlGraphicsRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QmlStateGroup *sg = rect->findChild(); + QVERIFY(sg != 0); + QVERIFY(sg->findState("blue") != 0); + + sg->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + sg->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + QmlState *state = rect->findChild(); + QVERIFY(state != 0); + delete state; + + QVERIFY(sg->findState("blue") == 0); + + //### should we warn that state doesn't exist + sg->setState("blue"); + QCOMPARE(rect->color(),QColor("red")); + + delete rect; +} + QTEST_MAIN(tst_states) #include "tst_states.moc" -- cgit v0.12