From: Alan Alpert Date: Thu, 24 Jan 2013 20:13:57 +0000 (-0800) Subject: Add qmlRegisterType for Composite Types X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=99ad368cf810723643ae76bba6a1adba3321b18f;p=konrad%2Fqtdeclarative.git Add qmlRegisterType for Composite Types This is equivalent functionality to registering a composite type in a qmldir file, a type name in a versioned module is associated with a given file. This function now allows that to be done easily from C++. Change-Id: I1cf44b92c3ad7fee593f4f84773c35b56253e628 Reviewed-by: Shawn Rutledge --- diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index da62dda..81b8fd5 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -380,3 +380,20 @@ \endcode */ + +/*! + \fn int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName); + \relates QQmlEngine + + This function registers a type in the QML system with the name \a qmlName, in the library imported from \a uri having the + version number composed from \a versionMajor and \a versionMinor. The type is defined by the QML file located at \a url. The + url must be an absolute URL, i.e. url.isRelative() == false. + + Normally QML files can be loaded as types directly from other QML files, or using a qmldir file. This function allows + registration of files to types from a C++ module, such as when the type mapping needs to be procedurally determined at startup. + + #include to use this function. + + Returns non-zero if the registration was sucessful. +*/ + diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 877e6c1..7e6e0d1 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -49,6 +49,7 @@ #include #include +#include #define QML_VERSION 0x020000 #define QML_VERSION_STR "2.0" @@ -463,6 +464,26 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } + +inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName) +{ + if (url.isRelative()) { + // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types + qWarning() << "qmlRegisterType requires absolute URLs."; + return 0; + } + + QQmlPrivate::RegisterCompositeType type = { + url, + uri, + versionMajor, + versionMinor, + qmlName + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type); +} + QT_END_NAMESPACE QML_DECLARE_TYPE(QObject) diff --git a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt new file mode 100644 index 0000000..7a75447 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.errors.txt @@ -0,0 +1,2 @@ +3:1:Type RegisteredCompositeType2 unavailable +-1:-1:File not found diff --git a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.qml b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.qml new file mode 100644 index 0000000..915a613 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.1.qml @@ -0,0 +1,3 @@ +import Test 1.0 + +RegisteredCompositeType2 {} diff --git a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.2.errors.txt b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.2.errors.txt new file mode 100644 index 0000000..0272619 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.2.errors.txt @@ -0,0 +1,2 @@ +3:1:Type RegisteredCompositeType3 unavailable +1:1:Expected a qualified name id diff --git a/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.2.qml b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.2.qml new file mode 100644 index 0000000..43d7f3e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/badCompositeRegistration.2.qml @@ -0,0 +1,3 @@ +import Test 1.0 + +RegisteredCompositeType3 {} diff --git a/tests/auto/qml/qqmllanguage/data/registeredCompositeType.qml b/tests/auto/qml/qqmllanguage/data/registeredCompositeType.qml new file mode 100644 index 0000000..f633a14 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/registeredCompositeType.qml @@ -0,0 +1,3 @@ +import Test 1.0 + +RegisteredCompositeType {} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 222548d..3121d10 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -139,6 +139,7 @@ private slots: void registrationOrder(); void readonly(); void receivers(); + void registeredCompositeType(); void basicRemote_data(); void basicRemote(); @@ -467,6 +468,9 @@ void tst_qqmllanguage::errors_data() QTest::newRow("invalidTypeName.4") << "invalidTypeName.4.qml" << "invalidTypeName.4.errors.txt" << false; QTest::newRow("Major version isolation") << "majorVersionIsolation.qml" << "majorVersionIsolation.errors.txt" << false; + + QTest::newRow("badCompositeRegistration.1") << "badCompositeRegistration.1.qml" << "badCompositeRegistration.1.errors.txt" << false; + QTest::newRow("badCompositeRegistration.2") << "badCompositeRegistration.2.qml" << "badCompositeRegistration.2.errors.txt" << false; } @@ -2771,6 +2775,10 @@ void tst_qqmllanguage::initTestCase() QQmlMetaType::registerCustomStringConverter(qMetaTypeId(), myCustomVariantTypeConverter); registerTypes(); + // Registered here because it uses testFileUrl + qmlRegisterType(testFileUrl("CompositeType.qml"), "Test", 1, 0, "RegisteredCompositeType"); + qmlRegisterType(testFileUrl("CompositeType.DoesNotExist.qml"), "Test", 1, 0, "RegisteredCompositeType2"); + qmlRegisterType(testFileUrl("invalidRoot.1.qml"), "Test", 1, 0, "RegisteredCompositeType3"); // Registering the TestType class in other modules should have no adverse effects qmlRegisterType("org.qtproject.TestPre", 1, 0, "Test"); @@ -2915,6 +2923,17 @@ void tst_qqmllanguage::receivers() delete o; } +void tst_qqmllanguage::registeredCompositeType() +{ + QQmlComponent component(&engine, testFileUrl("registeredCompositeType.qml")); + + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o != 0); + + delete o; +} + // QTBUG-18268 void tst_qqmllanguage::remoteLoadCrash() { diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 03d2f0b..9002322 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -129,11 +129,7 @@ void tst_qqmlmetatype::initTestCase() qmlRegisterType("Test", 1, 0, "ValueInterceptorTestType"); QUrl testTypeUrl(testFileUrl("CompositeType.qml")); - //TODO: Replace this with public API version when added - QQmlPrivate::RegisterCompositeType regStruct = { - testTypeUrl,"Test", 1, 0, "TestTypeComposite" - }; - QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, ®Struct); + qmlRegisterType(testTypeUrl, "Test", 1, 0, "TestTypeComposite"); } void tst_qqmlmetatype::qmlParserStatusCast()