diff options
3 files changed, 68 insertions, 7 deletions
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 6e88259..94780c4 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -161,15 +161,22 @@ public: QDeclarativeExpression *rewindExpression; QDeclarativeGuard<QDeclarativeExpression> ownedExpression; + virtual bool changesBindings() { return true; } + virtual void clearBindings() { + ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, 0); + } + virtual void execute(Reason) { - ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, expression); - Q_ASSERT(expression != ownedExpression); + QDeclarativePropertyPrivate::setSignalExpression(property, expression); + if (ownedExpression == expression) + ownedExpression = 0; } virtual bool isReversable() { return true; } virtual void reverse(Reason) { - ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, reverseExpression); - Q_ASSERT(reverseExpression != ownedExpression); + QDeclarativePropertyPrivate::setSignalExpression(property, reverseExpression); + if (ownedExpression == reverseExpression) + ownedExpression = 0; } virtual void saveOriginals() { @@ -177,12 +184,26 @@ public: reverseExpression = rewindExpression; } + virtual void copyOriginals(QDeclarativeActionEvent *other) + { + QDeclarativeReplaceSignalHandler *rsh = static_cast<QDeclarativeReplaceSignalHandler*>(other); + saveCurrentValues(); + if (rsh == this) + return; + reverseExpression = rsh->reverseExpression; + if (rsh->ownedExpression == reverseExpression) { + ownedExpression = rsh->ownedExpression; + rsh->ownedExpression = 0; + } + } + virtual void rewind() { - ownedExpression = QDeclarativePropertyPrivate::setSignalExpression(property, rewindExpression); - Q_ASSERT(rewindExpression != ownedExpression); + QDeclarativePropertyPrivate::setSignalExpression(property, rewindExpression); + if (ownedExpression == rewindExpression) + ownedExpression = 0; } virtual void saveCurrentValues() { - rewindExpression = QDeclarativePropertyPrivate::signalExpression(property); + rewindExpression = QDeclarativePropertyPrivate::signalExpression(property); } virtual bool override(QDeclarativeActionEvent*other) { diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml new file mode 100644 index 0000000..2215ee4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml @@ -0,0 +1,24 @@ +import Qt 4.7 + +Rectangle { + id: myRect + width: 400 + height: 400 + + states: [ + State { + name: "state1" + PropertyChanges { + target: myRect + onHeightChanged: console.log("Hello World") + color: "green" + } + }, + State { + name: "state2"; extend: "state1" + PropertyChanges { + target: myRect + color: "red" + } + }] +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 13992ad..ea074a4 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -87,6 +87,7 @@ private slots: void basicBinding(); void signalOverride(); void signalOverrideCrash(); + void signalOverrideCrash2(); void parentChange(); void parentChangeErrors(); void anchorChanges(); @@ -449,6 +450,21 @@ void tst_qdeclarativestates::signalOverrideCrash() rect->doSomething(); } +void tst_qdeclarativestates::signalOverrideCrash2() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash2.qml"); + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create()); + QVERIFY(rect != 0); + + QDeclarativeItemPrivate::get(rect)->setState("state1"); + QDeclarativeItemPrivate::get(rect)->setState("state2"); + QDeclarativeItemPrivate::get(rect)->setState("state1"); + + delete rect; +} + void tst_qdeclarativestates::parentChange() { QDeclarativeEngine engine; |