aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-06-22 16:56:27 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-25 04:50:01 +0200
commite76ba402bfe309022a0be29c6bc8223f8f3f94b3 (patch)
tree88f48d90e036f547d1f075feb99934a45d3fe0e7
parentfd754674d04625ebf254ce2a96cbe39b3d7652d8 (diff)
qmlRegisterRevision clashes with qmlRegisterUncreatableType
Add template<typename T, int metaObjectRevision> qmlRegisterUncreatableType() in order to register an uncreatable type for a particular revision. Task-number: QTBUG-23278 Change-Id: Ic165e41c8176916929cf19eb9bf6eef4b5bee1eb Reviewed-by: Lincoln Ramsay <lincoln.ramsay@nokia.com> Reviewed-by: Chris Adams <christopher.adams@nokia.com>
-rw-r--r--src/qml/doc/src/cppintegration/registercpptypes.qdoc3
-rw-r--r--src/qml/qml/qqml.h31
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp6
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h35
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp56
5 files changed, 131 insertions, 0 deletions
diff --git a/src/qml/doc/src/cppintegration/registercpptypes.qdoc b/src/qml/doc/src/cppintegration/registercpptypes.qdoc
index 9ccf428aaf..0e1188310b 100644
--- a/src/qml/doc/src/cppintegration/registercpptypes.qdoc
+++ b/src/qml/doc/src/cppintegration/registercpptypes.qdoc
@@ -265,6 +265,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
\code
template<typename T, int metaObjectRevision>
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)
\endcode
For example, if \c BaseObject is changed and now has a revision 1, you can specify that
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index c7092a6c76..528f8e6416 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -167,6 +167,37 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
}
+template<typename T, int metaObjectRevision>
+int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
+{
+ QML_GETTYPENAMES
+
+ QQmlPrivate::RegisterType type = {
+ 1,
+
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()),
+ qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
+ 0, 0,
+ reason,
+
+ uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+
+ QQmlPrivate::attachedPropertiesFunc<T>(),
+ QQmlPrivate::attachedPropertiesMetaObject<T>(),
+
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
+
+ 0, 0,
+
+ 0,
+ metaObjectRevision
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
+}
+
template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index beb0f596ae..561300decf 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -83,6 +83,12 @@ void registerTypes()
qmlRegisterType<MyEnumDerivedClass>("Test",1,0,"MyEnumDerivedClass");
qmlRegisterType<MyReceiversTestObject>("Test",1,0,"MyReceiversTestObject");
+
+ qmlRegisterUncreatableType<MyUncreateableBaseClass>("Test", 1, 0, "MyUncreateableBaseClass", "Cannot create MyUncreateableBaseClass");
+ qmlRegisterType<MyCreateableDerivedClass>("Test", 1, 0, "MyCreateableDerivedClass");
+
+ qmlRegisterUncreatableType<MyUncreateableBaseClass,1>("Test", 1, 1, "MyUncreateableBaseClass", "Cannot create MyUncreateableBaseClass");
+ qmlRegisterType<MyCreateableDerivedClass,1>("Test", 1, 1, "MyCreateableDerivedClass");
}
QVariant myCustomVariantTypeConverter(const QString &data)
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index f84e42f231..50b6089ffc 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -910,6 +910,41 @@ protected:
qreal m_p5;
};
+class MyUncreateableBaseClass : 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 MyUncreateableBaseClass(bool arg, 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 MyCreateableDerivedClass : public MyUncreateableBaseClass
+{
+ Q_OBJECT
+ Q_PROPERTY(bool prop2 READ prop2 WRITE setprop2 REVISION 1)
+
+public:
+ MyCreateableDerivedClass(QObject *parent = 0)
+ : MyUncreateableBaseClass(true, parent)
+ {
+ }
+};
+
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 6349cd343f..2f2f0a78d4 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -176,6 +176,9 @@ private slots:
void revisions();
void revisionOverloads();
+ void subclassedUncreateableRevision_data();
+ void subclassedUncreateableRevision();
+
void propertyInit();
void remoteLoadCrash();
void signalWithDefaultArg();
@@ -2540,6 +2543,59 @@ void tst_qqmllanguage::revisionOverloads()
}
}
+void tst_qqmllanguage::subclassedUncreateableRevision_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("prop1 exists in 1.1") << "1.1" << "prop1" << true;
+ QTest::newRow("prop2 works because it's re-declared in Derived") << "1.1" << "prop2" << true;
+ QTest::newRow("prop3 only works if the Base REVISION 1 is picked up") << "1.1" << "prop3" << true;
+
+}
+
+void tst_qqmllanguage::subclassedUncreateableRevision()
+{
+ QFETCH(QString, version);
+ QFETCH(QString, prop);
+ QFETCH(bool, shouldWork);
+
+ {
+ QQmlEngine engine;
+ QString qml = QString("import QtQuick 2.0\nimport Test %1\nMyUncreateableBaseClass {}").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 MyUncreateableBaseClass"));
+ }
+
+ QQmlEngine engine;
+ QString qml = QString("import QtQuick 2.0\nimport Test %1\nMyCreateableDerivedClass {\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);
+ MyUncreateableBaseClass *base = qobject_cast<MyUncreateableBaseClass*>(obj);
+ QVERIFY(base);
+ QCOMPARE(base->property(prop.toLatin1()).toBool(), true);
+ delete obj;
+}
+
void tst_qqmllanguage::initTestCase()
{
QString testdataDir = QFileInfo(QFINDTESTDATA("data")).absolutePath();