diff options
author | Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com> | 2014-12-02 14:41:07 +0100 |
---|---|---|
committer | Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com> | 2014-12-07 12:38:40 +0100 |
commit | a2d7441b83f96d3ddf57e9bb8532e4e7d52418f8 (patch) | |
tree | b5421fe993ecd682d3a08920d68efba2c2470420 | |
parent | c0a6a1db85e79931f4ac5782a6806d446995e3f0 (diff) |
Fix QMetaProperty::write so it tries to register a property type.
We can not assume that the property type is always registered, because
QVariant argument may contain an instance of a different type.
Change-Id: I4fc9593b826e13c401dbdacec4d60db36edc7102
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 6 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp | 51 |
2 files changed, 55 insertions, 2 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index bf31ef9151..3e2fb46143 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -3027,9 +3027,11 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const else { typeName = rawStringData(mobj, typeInfo & TypeNameIndexMask); t = QMetaType::type(typeName); + if (t == QMetaType::UnknownType) + t = registerPropertyType(); + if (t == QMetaType::UnknownType) + return false; } - if (t == QMetaType::UnknownType) - return false; if (t != QMetaType::QVariant && t != (uint)value.userType() && (t < QMetaType::User && !v.convert((QVariant::Type)t))) return false; } diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index 941abf9039..df76dfc47f 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -52,6 +52,7 @@ private slots: void isConstant(); void isFinal(); void gadget(); + void readAndWriteWithLazyRegistration(); public: enum EnumType { EnumType1 }; @@ -131,6 +132,56 @@ void tst_QMetaProperty::gadget() } } +struct CustomReadObject : QObject +{ + Q_OBJECT +}; + +struct CustomWriteObject : QObject +{ + Q_OBJECT +}; + +struct CustomWriteObjectChild : CustomWriteObject +{ + Q_OBJECT +}; + +struct TypeLazyRegistration : QObject +{ + Q_OBJECT + Q_PROPERTY(CustomReadObject *read MEMBER _read) + Q_PROPERTY(CustomWriteObject *write MEMBER _write) + + CustomReadObject *_read; + CustomWriteObject *_write; + +public: + TypeLazyRegistration() + : _read() + , _write() + {} +}; + +void tst_QMetaProperty::readAndWriteWithLazyRegistration() +{ + QCOMPARE(QMetaType::type("CustomReadObject*"), int(QMetaType::UnknownType)); + QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType)); + + TypeLazyRegistration o; + QVERIFY(o.property("read").isValid()); + QVERIFY(QMetaType::type("CustomReadObject*") != QMetaType::UnknownType); + QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType)); + + CustomWriteObjectChild data; + QVariant value = QVariant::fromValue(&data); // this register CustomWriteObjectChild + // check if base classes are not registered automatically, otherwise this test would be meaningless + QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType)); + QVERIFY(o.setProperty("write", value)); + QVERIFY(QMetaType::type("CustomWriteObject*") != QMetaType::UnknownType); + QCOMPARE(o.property("write").value<CustomWriteObjectChild*>(), &data); +} + QTEST_MAIN(tst_QMetaProperty) #include "tst_qmetaproperty.moc" |