diff options
5 files changed, 127 insertions, 19 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 849c83d466..788d5edb51 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1651,21 +1651,6 @@ QString QQmlEngine::offlineStoragePath() const return d->offlineStoragePath; } -static void voidptr_destructor(void *v) -{ - void **ptr = (void **)v; - delete ptr; -} - -static void *voidptr_constructor(const void *v) -{ - if (!v) { - return new void*; - } else { - return new void*(*(void **)v); - } -} - QQmlPropertyCache *QQmlEnginePrivate::createCache(const QMetaObject *mo) { Q_Q(QQmlEngine); @@ -1878,10 +1863,22 @@ void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data) QByteArray ptr = name + '*'; QByteArray lst = "QQmlListProperty<" + name + '>'; - int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor, - voidptr_constructor); - int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor, - voidptr_constructor); + int ptr_type = QMetaType::registerNormalizedType(ptr, + qMetaTypeDeleteHelper<QObject*>, + qMetaTypeCreateHelper<QObject*>, + qMetaTypeDestructHelper<QObject*>, + qMetaTypeConstructHelper<QObject*>, + sizeof(QObject*), + static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags), + data->root); + int lst_type = QMetaType::registerNormalizedType(lst, + qMetaTypeDeleteHelper<QQmlListProperty<QObject> >, + qMetaTypeCreateHelper<QQmlListProperty<QObject> >, + qMetaTypeDestructHelper<QQmlListProperty<QObject> >, + qMetaTypeConstructHelper<QQmlListProperty<QObject> >, + sizeof(QQmlListProperty<QObject>), + static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags), + static_cast<QMetaObject*>(0)); data->addref(); diff --git a/tests/auto/qml/qqmlproperty/data/SecondComponent.qml b/tests/auto/qml/qqmlproperty/data/SecondComponent.qml new file mode 100644 index 0000000000..45d81c9010 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/SecondComponent.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Item { + property string a: "Hello, World" + property bool b: false +} diff --git a/tests/auto/qml/qqmlproperty/data/componentDir/FirstComponent.qml b/tests/auto/qml/qqmlproperty/data/componentDir/FirstComponent.qml new file mode 100644 index 0000000000..1b7614dc07 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/componentDir/FirstComponent.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + property int a: 10 +} diff --git a/tests/auto/qml/qqmlproperty/data/registeredCompositeTypeProperty.qml b/tests/auto/qml/qqmlproperty/data/registeredCompositeTypeProperty.qml new file mode 100644 index 0000000000..92e1675d11 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/registeredCompositeTypeProperty.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 +import "componentDir" + +Item { + id: root + + property FirstComponent first: FirstComponent { } + property FirstComponent second + property SecondComponent third: SecondComponent { } + + property list<FirstComponent> fclist: [ + FirstComponent { + a: 15 + } + ] + property list<SecondComponent> sclistOne: [ + SecondComponent { + a: "G'day, World" + }, + SecondComponent { }, + SecondComponent { + b: true + } + ] + property list<SecondComponent> sclistTwo + + Component.onCompleted: { + var c1 = Qt.createComponent("./componentDir/FirstComponent.qml"); + var o1 = c1.createObject(root); + second = o1; + } +} diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index a65693bb8f..3957dee062 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -135,6 +135,7 @@ private slots: void noContext(); void assignEmptyVariantMap(); void warnOnInvalidBinding(); + void registeredCompositeTypeProperty(); void copy(); private: @@ -189,6 +190,73 @@ void tst_qqmlproperty::qmlmetaproperty() delete obj; } +void tst_qqmlproperty::registeredCompositeTypeProperty() +{ + // Composite type properties + { + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeProperty.qml")); + QObject *obj = component.create(); + QVERIFY(obj); + + // create property accessors and check types. + QQmlProperty p1(obj, "first"); + QQmlProperty p2(obj, "second"); + QQmlProperty p3(obj, "third"); + QVERIFY(p1.propertyType() == p2.propertyType()); + QVERIFY(p1.propertyType() != p3.propertyType()); + + // check that the values are retrievable from CPP + QVariant first = obj->property("first"); + QVariant second = obj->property("second"); + QVariant third = obj->property("third"); + QVERIFY(first.isValid()); + QVERIFY(second.isValid()); + QVERIFY(third.isValid()); + // ensure that conversion from qobject-derived-ptr to qobject-ptr works. + QVERIFY(first.value<QObject*>()); + QVERIFY(second.value<QObject*>()); + QVERIFY(third.value<QObject*>()); + + // check that the values retrieved via QQmlProperty match. + QCOMPARE(p1.read(), first); + QCOMPARE(p2.read(), second); + QCOMPARE(p3.read(), third); + + delete obj; + } + + // List-of-composite-type type properties + { + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeProperty.qml")); + QObject *obj = component.create(); + QVERIFY(obj); + + // create list property accessors and check types + QQmlProperty lp1(obj, "fclist"); + QQmlProperty lp2(obj, "sclistOne"); + QQmlProperty lp3(obj, "sclistTwo"); + QVERIFY(lp1.propertyType() != lp2.propertyType()); + QVERIFY(lp2.propertyType() == lp3.propertyType()); + + // check that the list values are retrievable from CPP + QVariant firstList = obj->property("fclist"); + QVariant secondList = obj->property("sclistOne"); + QVariant thirdList = obj->property("sclistTwo"); + QVERIFY(firstList.isValid()); + QVERIFY(secondList.isValid()); + QVERIFY(thirdList.isValid()); + + // check that the values retrieved via QQmlProperty match. + QCOMPARE(lp1.read(), firstList); + QCOMPARE(lp2.read(), secondList); + QCOMPARE(lp3.read(), thirdList); + + delete obj; + } +} + class PropertyObject : public QObject { Q_OBJECT |