From f609c2f3b148f0d31167b9feeabe8f2c4bbd03b8 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 1 Aug 2011 12:32:10 +1000 Subject: [PATCH] Fix Binding to correctly restore bindings even when a binding loop is involved. Change-Id: Ie8f9731d9f4834d8b94272ef792dc7ad0235ce78 Reviewed-on: http://codereview.qt.nokia.com/2409 Reviewed-by: Martin Jones --- src/declarative/util/qdeclarativebind.cpp | 6 ++-- .../data/restoreBindingWithLoop.qml | 23 +++++++++++++ .../tst_qdeclarativebinding.cpp | 35 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativebinding/data/restoreBindingWithLoop.qml diff --git a/src/declarative/util/qdeclarativebind.cpp b/src/declarative/util/qdeclarativebind.cpp index 726adf9..fa463eb 100644 --- a/src/declarative/util/qdeclarativebind.cpp +++ b/src/declarative/util/qdeclarativebind.cpp @@ -280,11 +280,11 @@ void QDeclarativeBind::eval() if (!d->when) { //restore any previous binding if (d->prevBind) { - QDeclarativeAbstractBinding *tmp; - tmp = QDeclarativePropertyPrivate::setBinding(d->prop, d->prevBind); + QDeclarativeAbstractBinding *tmp = d->prevBind; + d->prevBind = 0; + tmp = QDeclarativePropertyPrivate::setBinding(d->prop, tmp); if (tmp) //should this ever be true? tmp->destroy(); - d->prevBind = 0; } return; } diff --git a/tests/auto/declarative/qdeclarativebinding/data/restoreBindingWithLoop.qml b/tests/auto/declarative/qdeclarativebinding/data/restoreBindingWithLoop.qml new file mode 100644 index 0000000..ee07104 --- /dev/null +++ b/tests/auto/declarative/qdeclarativebinding/data/restoreBindingWithLoop.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + property bool activateBinding: false + + Rectangle { + id: myItem + objectName: "myItem" + width: 100 + height: 100 + color: "green" + x: myItem.y + 100 + onXChanged: { if (x == 188) y = 90; } //create binding loop + + Binding on x { + when: activateBinding + value: myItem.y + } + } +} diff --git a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp index 7bfd0e0..2e64fed 100644 --- a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp +++ b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp @@ -61,6 +61,7 @@ private slots: void binding(); void whenAfterValue(); void restoreBinding(); + void restoreBindingWithLoop(); private: QDeclarativeEngine engine; @@ -144,6 +145,40 @@ void tst_qdeclarativebinding::restoreBinding() delete rect; } +void tst_qdeclarativebinding::restoreBindingWithLoop() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/restoreBindingWithLoop.qml")); + QSGRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QSGRectangle *myItem = qobject_cast(rect->findChild("myItem")); + QVERIFY(myItem != 0); + + myItem->setY(25); + QCOMPARE(myItem->x(), qreal(25 + 100)); + + myItem->setY(13); + QCOMPARE(myItem->x(), qreal(13 + 100)); + + //Binding takes effect + rect->setProperty("activateBinding", true); + myItem->setY(51); + QCOMPARE(myItem->x(), qreal(51)); + + myItem->setY(88); + QCOMPARE(myItem->x(), qreal(88)); + + //original binding restored + rect->setProperty("activateBinding", false); + QCOMPARE(myItem->x(), qreal(88 + 100)); //if loop handling changes this could be 90 + 100 + + myItem->setY(49); + QCOMPARE(myItem->x(), qreal(49 + 100)); + + delete rect; +} + QTEST_MAIN(tst_qdeclarativebinding) #include "tst_qdeclarativebinding.moc" -- 1.7.2.5