\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
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)
{
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)
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
void revisions();
void revisionOverloads();
+ void subclassedUncreateableRevision_data();
+ void subclassedUncreateableRevision();
+
void propertyInit();
void remoteLoadCrash();
void signalWithDefaultArg();
}
}
+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();