Fix QDeclarativeListProperty assignment
authorChris Adams <christopher.adams@nokia.com>
Thu, 8 Sep 2011 05:13:42 +0000 (15:13 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 19 Sep 2011 05:31:00 +0000 (07:31 +0200)
This commit ensures that a QDeclarativeListReference can be
assigned to another QDeclarativeListProperty, by retrieving
each element in the list reference and converting to the appropriate
type before appending to the target list property.

Task-number: QTBUG-16316
Change-Id: Id8858058f052a53bf43eadc085fd278654478d77
Reviewed-on: http://codereview.qt-project.org/4388
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
src/declarative/qml/qdeclarativeproperty.cpp
tests/auto/declarative/qdeclarativeecmascript/data/listAssignment.qml [new file with mode: 0644]
tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp

index 60e7855..acc2cfb 100644 (file)
@@ -1215,7 +1215,16 @@ bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePrope
 
         prop.clear(&prop);
 
-        if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
+        if (value.userType() == qMetaTypeId<QDeclarativeListReference>()) {
+            QDeclarativeListReference qdlr = value.value<QDeclarativeListReference>();
+
+            for (int ii = 0; ii < qdlr.count(); ++ii) {
+                QObject *o = qdlr.at(ii);
+                if (o && !canConvert(o->metaObject(), listType))
+                    o = 0;
+                prop.append(&prop, (void *)o);
+            }
+        } else if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
             const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);
 
             for (int ii = 0; ii < list.count(); ++ii) {
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/listAssignment.qml b/tests/auto/declarative/qdeclarativeecmascript/data/listAssignment.qml
new file mode 100644 (file)
index 0000000..6e60397
--- /dev/null
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+    id: root
+    width: 640
+    height: 480
+
+    property int list1length: list1.length
+
+    property list<MyQmlObject> list1
+    property list<MyQmlObject> list2: [
+        MyQmlObject { id: one; value: 100 },
+        MyQmlObject { id: two; value: 300 }
+    ]
+
+    Component.onCompleted: {
+        root.list1 = root.list2;
+    }
+}
index b732cd8..dc3f053 100644 (file)
@@ -131,6 +131,7 @@ private slots:
     void jsObject();
     void undefinedResetsProperty();
     void listToVariant();
+    void listAssignment();
     void multiEngineObject();
     void deletedObject();
     void attachedPropertyScope();
@@ -2233,6 +2234,21 @@ void tst_qdeclarativeecmascript::listToVariant()
     delete object;
 }
 
+// QTBUG-16316
+Q_DECLARE_METATYPE(QDeclarativeListProperty<MyQmlObject>)
+void tst_qdeclarativeecmascript::listAssignment()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("listAssignment.qml"));
+    QObject *obj = component.create();
+    QCOMPARE(obj->property("list1length").toInt(), 2);
+    QDeclarativeListProperty<MyQmlObject> list1 = obj->property("list1").value<QDeclarativeListProperty<MyQmlObject> >();
+    QDeclarativeListProperty<MyQmlObject> list2 = obj->property("list2").value<QDeclarativeListProperty<MyQmlObject> >();
+    QCOMPARE(list1.count(&list1), list2.count(&list2));
+    QCOMPARE(list1.at(&list1, 0), list2.at(&list2, 0));
+    QCOMPARE(list1.at(&list1, 1), list2.at(&list2, 1));
+    delete obj;
+}
+
 // QTBUG-7957
 void tst_qdeclarativeecmascript::multiEngineObject()
 {