summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-04-30 08:09:09 (GMT)
committerEskil Abrahamsen Blomfeldt <eblomfel@trolltech.com>2009-04-30 08:09:09 (GMT)
commit18e848faad9289f6052249ef4fe6a20f0654b786 (patch)
tree760a3ce914e202182ccc33e447c302eb4b3daf75
parent9e6311a7fd23a9fb7bb3a8a8edc78cddddc3f807 (diff)
downloadQt-18e848faad9289f6052249ef4fe6a20f0654b786.zip
Qt-18e848faad9289f6052249ef4fe6a20f0654b786.tar.gz
Qt-18e848faad9289f6052249ef4fe6a20f0654b786.tar.bz2
When restoring properties in descendants of a state which assigns it a value,
the property should be restored to the value assigned by the ancestor state. When restoreProperties is on, assigning a value in a state means it will have that value as long as the state is active, unless an active state deeper in the hierarchy assigns it a different value. This is basically a stack of "initial" values, but implemented using the parent hierarchy of the state instead.
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp7
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp64
2 files changed, 69 insertions, 2 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 81d65d5..0ebc993 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -658,13 +658,16 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
}
// Remove pending restorables for all parent states to avoid restoring properties
- // before the state that assigned them is exited.
+ // before the state that assigned them is exited. If state does not explicitly
+ // assign a property which is assigned by the parent, it inherits the parent's assignment.
QState *parentState = s;
while (parentState = parentState->parentState()) {
assignments = QStatePrivate::get(parentState)->propertyAssignments;
for (int j=0; j<assignments.size(); ++j) {
const QPropertyAssignment &assn = assignments.at(j);
- pendingRestorables.remove(RestorableId(assn.object, assn.propertyName));
+ int c = pendingRestorables.remove(RestorableId(assn.object, assn.propertyName));
+ if (c > 0)
+ propertyAssignmentsForState[s].append(assn);
}
}
}
diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp
index fa4c233..80bf674 100644
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp
@@ -141,6 +141,7 @@ private slots:
void parallelStateTransition();
void parallelStateAssignmentsDone();
void nestedRestoreProperties();
+ void nestedRestoreProperties2();
void simpleAnimation();
void twoAnimations();
@@ -3162,6 +3163,69 @@ void tst_QStateMachine::nestedRestoreProperties()
QCOMPARE(propertyHolder->property("bar").toInt(), 5);
}
+void tst_QStateMachine::nestedRestoreProperties2()
+{
+ QStateMachine machine;
+ machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties);
+
+ QObject *propertyHolder = new QObject(&machine);
+ propertyHolder->setProperty("foo", 1);
+ propertyHolder->setProperty("bar", 2);
+
+ QState *s1 = new QState(machine.rootState());
+ machine.setInitialState(s1);
+
+ QState *s2 = new QState(machine.rootState());
+ s2->assignProperty(propertyHolder, "foo", 3);
+
+ QState *s21 = new QState(s2);
+ s21->assignProperty(propertyHolder, "bar", 4);
+ s2->setInitialState(s21);
+
+ QState *s22 = new QState(s2);
+ s22->assignProperty(propertyHolder, "foo", 6);
+ s22->assignProperty(propertyHolder, "bar", 5);
+
+ s1->addTransition(new EventTransition(QEvent::User, s2));
+ s21->addTransition(new EventTransition(QEvent::User, s22));
+ s22->addTransition(new EventTransition(QEvent::User, s21));
+
+ machine.start();
+ QCoreApplication::processEvents();
+
+ QCOMPARE(machine.configuration().size(), 1);
+ QVERIFY(machine.configuration().contains(s1));
+ QCOMPARE(propertyHolder->property("foo").toInt(), 1);
+ QCOMPARE(propertyHolder->property("bar").toInt(), 2);
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCoreApplication::processEvents();
+
+ QCOMPARE(machine.configuration().size(), 2);
+ QVERIFY(machine.configuration().contains(s2));
+ QVERIFY(machine.configuration().contains(s21));
+ QCOMPARE(propertyHolder->property("foo").toInt(), 3);
+ QCOMPARE(propertyHolder->property("bar").toInt(), 4);
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCoreApplication::processEvents();
+
+ QCOMPARE(machine.configuration().size(), 2);
+ QVERIFY(machine.configuration().contains(s2));
+ QVERIFY(machine.configuration().contains(s22));
+ QCOMPARE(propertyHolder->property("foo").toInt(), 6);
+ QCOMPARE(propertyHolder->property("bar").toInt(), 5);
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCoreApplication::processEvents();
+
+ QCOMPARE(machine.configuration().size(), 2);
+ QVERIFY(machine.configuration().contains(s2));
+ QVERIFY(machine.configuration().contains(s21));
+ QCOMPARE(propertyHolder->property("foo").toInt(), 3);
+ QCOMPARE(propertyHolder->property("bar").toInt(), 4);
+
+}
QTEST_MAIN(tst_QStateMachine)