Fix Binding to correctly restore bindings even when a binding loop is involved.
authorMichael Brasser <michael.brasser@nokia.com>
Mon, 1 Aug 2011 02:32:10 +0000 (12:32 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 1 Aug 2011 02:49:54 +0000 (04:49 +0200)
Change-Id: Ie8f9731d9f4834d8b94272ef792dc7ad0235ce78
Reviewed-on: http://codereview.qt.nokia.com/2409
Reviewed-by: Martin Jones <martin.jones@nokia.com>

src/declarative/util/qdeclarativebind.cpp
tests/auto/declarative/qdeclarativebinding/data/restoreBindingWithLoop.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp

index 726adf9..fa463eb 100644 (file)
@@ -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 (file)
index 0000000..ee07104
--- /dev/null
@@ -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
+        }
+    }
+}
index 7bfd0e0..2e64fed 100644 (file)
@@ -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<QSGRectangle*>(c.create());
+    QVERIFY(rect != 0);
+
+    QSGRectangle *myItem = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("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"