From 40a6845bcce22aca96e1dee26360bdff3e9520fb Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@theqtcompany.com>
Date: Wed, 22 Oct 2014 16:47:01 +0200
Subject: [PATCH] Fix assignment to QObject pointer properties
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit ammends 59ed8c355b99df0b949003a438ab850274261aa0 to always query
the Qt meta-type registry to retrieve the QMetaObject for a QObject pointer
type.

Change-Id: I70d876a5acfa23967fd1a57c96fcd5ac853eaf49
Task-number: QTBUG-39614
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Reviewed-by: Ulf Hermann <ulf.hermann@digia.com>
---
 src/qml/qml/qqmlproperty.cpp                  |  9 +++---
 .../qml/qqmlproperty/tst_qqmlproperty.cpp     | 28 +++++++++++++++++++
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 09b735ae9e..2a888b7a1e 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1611,15 +1611,14 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
 
 QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engine, int userType)
 {
-    if (engine) {
+    QMetaType metaType(userType);
+    if ((metaType.flags() & QMetaType::PointerToQObject) && metaType.metaObject())
+        return metaType.metaObject();
+    if (engine)
         return engine->rawMetaObjectForType(userType);
-    }
     QQmlType *type = QQmlMetaType::qmlType(userType);
     if (type)
         return QQmlMetaObject(type->baseMetaObject());
-    QMetaType metaType(userType);
-    if ((metaType.flags() & QMetaType::PointerToQObject) && metaType.metaObject())
-        return metaType.metaObject();
     return QQmlMetaObject((QObject*)0);
 }
 
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 6cd1eafafd..62ccec5794 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -1157,6 +1157,17 @@ void tst_qqmlproperty::read()
         QVERIFY(v.canConvert(QMetaType::QObjectStar));
         QVERIFY(qvariant_cast<QObject *>(v) == o.qObject());
     }
+    {
+        QQmlEngine engine;
+        PropertyObject o;
+        QQmlProperty p(&o, "qObject", &engine);
+        QCOMPARE(p.propertyTypeCategory(), QQmlProperty::Object);
+
+        QCOMPARE(p.propertyType(), qMetaTypeId<MyQObject*>());
+        QVariant v = p.read();
+        QVERIFY(v.canConvert(QMetaType::QObjectStar));
+        QVERIFY(qvariant_cast<QObject *>(v) == o.qObject());
+    }
 
     // Object property
     {
@@ -1432,6 +1443,23 @@ void tst_qqmlproperty::write()
         QCOMPARE(newData.value<QObject*>(), newObject);
         QCOMPARE(newData.value<MyQObject*>(), newObject);
     }
+    {
+        QQmlEngine engine;
+        PropertyObject o;
+        QQmlProperty p(&o, QString("qObject"), &engine);
+        QCOMPARE(o.qObject(), (QObject*)0);
+        QObject *newObject = new MyQObject(this);
+        QCOMPARE(p.write(QVariant::fromValue(newObject)), true);
+        QCOMPARE(o.qObject(), newObject);
+        QVariant data = p.read();
+        QCOMPARE(data.value<QObject*>(), newObject);
+        QCOMPARE(data.value<MyQObject*>(), newObject);
+        // Incompatible types can not be written.
+        QCOMPARE(p.write(QVariant::fromValue(new MyQmlObject(this))), false);
+        QVariant newData = p.read();
+        QCOMPARE(newData.value<QObject*>(), newObject);
+        QCOMPARE(newData.value<MyQObject*>(), newObject);
+    }
 }
 
 void tst_qqmlproperty::reset()
-- 
GitLab