aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc3
-rw-r--r--src/qml/qml/qqml.h38
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp4
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h54
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp59
5 files changed, 158 insertions, 0 deletions
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index e06451b2bc..7d4a543089 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -282,6 +282,9 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
template<typename T, int metaObjectRevision>
int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
+
+template<typename T, typename E, int metaObjectRevision>
+int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
\endcode
For example, if \c BaseType is changed and now has a revision 1, you can
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index f0973338ea..ddb4af0b81 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -238,6 +238,44 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+template<typename T, typename E, int metaObjectRevision>
+int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
+{
+ QML_GETTYPENAMES
+
+ QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
+ const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
+ if (!attached) {
+ attached = QQmlPrivate::attachedPropertiesFunc<T>();
+ attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
+ }
+
+ QQmlPrivate::RegisterType type = {
+ 1,
+
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ 0,
+ Q_NULLPTR,
+ reason,
+
+ uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+
+ attached,
+ attachedMetaObject,
+
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
+
+ QQmlPrivate::createParent<E>, &E::staticMetaObject,
+
+ Q_NULLPTR,
+ metaObjectRevision
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
+}
Q_QML_EXPORT int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason);
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index bc8c192a61..bdcdaa8137 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -87,6 +87,10 @@ void registerTypes()
qmlRegisterUncreatableType<MyUncreateableBaseClass,1>("Test", 1, 1, "MyUncreateableBaseClass", "Cannot create MyUncreateableBaseClass");
qmlRegisterType<MyCreateableDerivedClass,1>("Test", 1, 1, "MyCreateableDerivedClass");
+ qmlRegisterExtendedUncreatableType<MyExtendedUncreateableBaseClass, MyExtendedUncreateableBaseClassExtension>("Test", 1, 0, "MyExtendedUncreateableBaseClass", "Cannot create MyExtendedUncreateableBaseClass");
+ qmlRegisterExtendedUncreatableType<MyExtendedUncreateableBaseClass, MyExtendedUncreateableBaseClassExtension, 1>("Test", 1, 1, "MyExtendedUncreateableBaseClass", "Cannot create MyExtendedUncreateableBaseClass");
+ qmlRegisterType<MyExtendedCreateableDerivedClass>("Test", 1, 0, "MyExtendedCreateableDerivedClass");
+
qmlRegisterCustomType<CustomBinding>("Test", 1, 0, "CustomBinding", new CustomBindingParser);
qmlRegisterCustomType<SimpleObjectWithCustomParser>("Test", 1, 0, "SimpleObjectWithCustomParser", new SimpleObjectCustomParser);
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 6c62bcf7b9..7d7a8ac6d3 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -1021,6 +1021,60 @@ public:
}
};
+class MyExtendedUncreateableBaseClass : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool prop1 READ prop1 WRITE setprop1)
+ Q_PROPERTY(bool prop2 READ prop2 WRITE setprop2 REVISION 1)
+ Q_PROPERTY(bool prop3 READ prop3 WRITE setprop3 REVISION 1)
+public:
+ explicit MyExtendedUncreateableBaseClass(QObject *parent = 0)
+ : QObject(parent), _prop1(false), _prop2(false), _prop3(false)
+ {
+ }
+
+ bool _prop1;
+ bool prop1() const { return _prop1; }
+ void setprop1(bool p) { _prop1 = p; }
+ bool _prop2;
+ bool prop2() const { return _prop2; }
+ void setprop2(bool p) { _prop2 = p; }
+ bool _prop3;
+ bool prop3() const { return _prop3; }
+ void setprop3(bool p) { _prop3 = p; }
+};
+
+class MyExtendedUncreateableBaseClassExtension : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool prop4 READ prop4 WRITE setprop4)
+public:
+ explicit MyExtendedUncreateableBaseClassExtension(QObject *parent = 0)
+ : QObject(parent), _prop4(false)
+ {
+ }
+
+ bool _prop4;
+ bool prop4() const { return _prop4; }
+ void setprop4(bool p) { _prop4 = p; }
+};
+
+class MyExtendedCreateableDerivedClass : public MyExtendedUncreateableBaseClass
+{
+ Q_OBJECT
+ Q_PROPERTY(bool prop5 READ prop5 WRITE setprop5)
+
+public:
+ MyExtendedCreateableDerivedClass(QObject *parent = 0)
+ : MyExtendedUncreateableBaseClass(parent), _prop5(false)
+ {
+ }
+
+ bool _prop5;
+ bool prop5() const { return _prop5; }
+ void setprop5(bool p) { _prop5 = p; }
+};
+
class MyVersion2Class : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index c0500afddd..750c32cc3c 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -189,6 +189,9 @@ private slots:
void subclassedUncreateableRevision_data();
void subclassedUncreateableRevision();
+ void subclassedExtendedUncreateableRevision_data();
+ void subclassedExtendedUncreateableRevision();
+
void uncreatableTypesAsProperties();
void propertyInit();
@@ -3228,6 +3231,62 @@ void tst_qqmllanguage::subclassedUncreateableRevision()
delete obj;
}
+void tst_qqmllanguage::subclassedExtendedUncreateableRevision_data()
+{
+ QTest::addColumn<QString>("version");
+ QTest::addColumn<QString>("prop");
+ QTest::addColumn<bool>("shouldWork");
+
+ QTest::newRow("prop1 exists in 1.0") << "1.0" << "prop1" << true;
+ QTest::newRow("prop2 does not exist in 1.0") << "1.0" << "prop2" << false;
+ QTest::newRow("prop3 does not exist in 1.0") << "1.0" << "prop3" << false;
+ QTest::newRow("prop4 exists in 1.0") << "1.0" << "prop4" << true;
+ QTest::newRow("prop5 exists in 1.0") << "1.0" << "prop5" << true;
+
+ QTest::newRow("prop1 exists in 1.1") << "1.1" << "prop1" << true;
+ QTest::newRow("prop2 exists in 1.1") << "1.1" << "prop2" << true;
+ QTest::newRow("prop3 exists in 1.1") << "1.1" << "prop3" << true;
+ QTest::newRow("prop4 exists in 1.1") << "1.1" << "prop4" << true;
+ QTest::newRow("prop5 exists in 1.1") << "1.1" << "prop5" << true;
+}
+
+void tst_qqmllanguage::subclassedExtendedUncreateableRevision()
+{
+ QFETCH(QString, version);
+ QFETCH(QString, prop);
+ QFETCH(bool, shouldWork);
+
+ {
+ QQmlEngine engine;
+ QString qml = QString("import QtQuick 2.0\nimport Test %1\nMyExtendedUncreateableBaseClass {}").arg(version);
+ QQmlComponent c(&engine);
+ QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
+ c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
+ QObject *obj = c.create();
+ QCOMPARE(obj, static_cast<QObject*>(0));
+ QCOMPARE(c.errors().count(), 1);
+ QCOMPARE(c.errors().first().description(), QString("Cannot create MyExtendedUncreateableBaseClass"));
+ }
+
+ QQmlEngine engine;
+ QString qml = QString("import QtQuick 2.0\nimport Test %1\nMyExtendedCreateableDerivedClass {\n%3: true\n}").arg(version).arg(prop);
+ QQmlComponent c(&engine);
+ if (!shouldWork)
+ QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
+ c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
+ QObject *obj = c.create();
+ if (!shouldWork) {
+ QCOMPARE(obj, static_cast<QObject*>(0));
+ return;
+ }
+
+ QVERIFY(obj);
+ MyExtendedUncreateableBaseClass *base = qobject_cast<MyExtendedUncreateableBaseClass*>(obj);
+ QVERIFY(base);
+ QCOMPARE(base->property(prop.toLatin1()).toBool(), true);
+ delete obj;
+}
+
void tst_qqmllanguage::uncreatableTypesAsProperties()
{
QQmlEngine engine;