aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-04-17 12:13:25 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-06-09 08:01:03 +0200
commit9752ad5af7c7ae188250ab5b8b65c74f70d57b41 (patch)
tree19c1b9a8ed6444b626bba339679e1788562e6569
parent1d510acc29dd2cebfb72364b8b933287f54c5579 (diff)
Add methods to programatically insert qmldir import statements
We need this for controls2 to select the style at runtime. Change-Id: I23b6ab962a647b519d5af019eade27f89e1e4e00 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqml.cpp31
-rw-r--r--src/qml/qml/qqml.h3
-rw-r--r--src/qml/qml/qqmlmetatype.cpp35
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmltypeloader.cpp10
-rw-r--r--src/qml/qml/qqmltypemodule.cpp15
-rw-r--r--src/qml/qml/qqmltypemodule_p.h4
-rw-r--r--src/qml/qml/qqmltypemodule_p_p.h2
-rw-r--r--tests/auto/qml/qqmlimport/MyPluginSupported/qmldir1
-rw-r--r--tests/auto/qml/qqmlimport/tst_qqmlimport.cpp22
10 files changed, 122 insertions, 3 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index a57daf78d2..b342690c39 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -72,6 +72,37 @@ void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor)
QQmlMetaType::registerModule(uri, QTypeRevision::fromVersion(versionMajor, versionMinor));
}
+/*!
+ * Registers an implicit import for module \a uri of major version \a majorVersion
+ *
+ * This has the same effect as an \c import statement in a qmldir file: Whenever
+ * \a uri version \a majorVersion is imported, \a import is automatically
+ * imported, too, with the same version.
+ *
+ * \sa qmlUnregisterModuleImport()
+ */
+void qmlRegisterModuleImport(const char *uri, int majorVersion, const char *import)
+{
+ QQmlMetaType::registerModuleImport(
+ QString::fromUtf8(uri), QTypeRevision::fromMajorVersion(majorVersion),
+ QString::fromUtf8(import));
+}
+
+/*!
+ * Removes a module import previously registered with qmlRegisterModuleImport()
+ *
+ * Calling this function makes sure that \a import is not automatically imported
+ * anymore when \a uri of version \a majorVersion is.
+ *
+ * \sa qmlRegisterModuleImport()
+ */
+void qmlUnregisterModuleImport(const char *uri, int majorVersion, const char *import)
+{
+ QQmlMetaType::unregisterModuleImport(
+ QString::fromUtf8(uri), QTypeRevision::fromMajorVersion(majorVersion),
+ QString::fromUtf8(import));
+}
+
//From qqml.h
int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 9c896e6322..ee3afa768a 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -675,6 +675,9 @@ QT_WARNING_POP
Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion);
Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versionMinor);
+Q_QML_EXPORT void qmlRegisterModuleImport(const char *uri, int majorVersion, const char *import);
+Q_QML_EXPORT void qmlUnregisterModuleImport(const char *uri, int majorVersion, const char *import);
+
template<typename T>
QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
{
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index fd307e4575..24a8bcfed3 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -618,6 +618,24 @@ bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version)
return false;
}
+void QQmlMetaType::registerModuleImport(const QString &uri, QTypeRevision version, const QString &import)
+{
+ QQmlMetaTypeDataPtr data;
+
+ QQmlTypeModule *module = getTypeModule(uri, version, data);
+ Q_ASSERT(module);
+ module->addImport(import);
+}
+
+void QQmlMetaType::unregisterModuleImport(const QString &uri, QTypeRevision version, const QString &import)
+{
+ QQmlMetaTypeDataPtr data;
+
+ QQmlTypeModule *module = getTypeModule(uri, version, data);
+ Q_ASSERT(module);
+ module->removeImport(import);
+}
+
void QQmlMetaType::registerModule(const char *uri, QTypeRevision version)
{
QQmlMetaTypeDataPtr data;
@@ -917,7 +935,22 @@ bool QQmlMetaType::isModule(const QString &module, QTypeRevision version)
QQmlTypeModule *QQmlMetaType::typeModule(const QString &uri, QTypeRevision version)
{
QQmlMetaTypeDataPtr data;
- return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, version));
+
+ if (version.hasMajorVersion())
+ return data->uriToModule.value(QQmlMetaTypeData::VersionedUri(uri, version));
+
+ QQmlTypeModule *latestModule = nullptr;
+ for (QQmlMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.cbegin();
+ iter != data->uriToModule.cend(); ++iter) {
+ QQmlTypeModule *module = *iter;
+ if (module->module() != uri)
+ continue;
+
+ if (!latestModule || module->majorVersion() > latestModule->majorVersion())
+ latestModule = module;
+ }
+
+ return latestModule;
}
QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 9ce33ab545..dbc0851ad6 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -97,6 +97,8 @@ public:
static void unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds);
static void registerModule(const char *uri, QTypeRevision version);
static bool protectModule(const QString &uri, QTypeRevision version);
+ static void registerModuleImport(const QString &uri, QTypeRevision version, const QString &import);
+ static void unregisterModuleImport(const QString &uri, QTypeRevision version, const QString &import);
static int typeId(const char *uri, QTypeRevision version, const char *qmlName);
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 49b3d7ad93..1b7993af61 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -712,14 +712,20 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob)
bool QQmlTypeLoader::Blob::loadImportDependencies(PendingImportPtr currentImport, const QString &qmldirUri, QList<QQmlError> *errors)
{
const QQmlTypeLoaderQmldirContent qmldir = typeLoader()->qmldirContent(qmldirUri);
- for (const QString &implicitImports: qmldir.imports()) {
+ const QQmlTypeModule *module = QQmlMetaType::typeModule(currentImport->uri,
+ currentImport->version);
+ const QStringList implicitImports = module ? (module->imports() + qmldir.imports())
+ : qmldir.imports();
+ for (const QString &implicitImport : implicitImports) {
auto dependencyImport = std::make_shared<PendingImport>();
- dependencyImport->uri = implicitImports;
+ dependencyImport->uri = implicitImport;
dependencyImport->qualifier = currentImport->qualifier;
dependencyImport->version = currentImport->version;
if (!addImport(dependencyImport, errors))
return false;
}
+
+
return true;
}
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index e6bf796d74..d6b859bf22 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -175,4 +175,19 @@ void QQmlTypeModule::walkCompositeSingletons(const std::function<void(const QQml
}
}
+QStringList QQmlTypeModule::imports() const
+{
+ return d->imports;
+}
+
+void QQmlTypeModule::addImport(const QString &import)
+{
+ d->imports.append(import);
+}
+
+void QQmlTypeModule::removeImport(const QString &import)
+{
+ d->imports.removeAll(import);
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h
index d3149567a3..a4c319e32e 100644
--- a/src/qml/qml/qqmltypemodule_p.h
+++ b/src/qml/qml/qqmltypemodule_p.h
@@ -94,6 +94,10 @@ public:
void walkCompositeSingletons(const std::function<void(const QQmlType &)> &callback) const;
+ void addImport(const QString &import);
+ void removeImport(const QString &import);
+ QStringList imports() const;
+
private:
QQmlTypeModulePrivate *d;
};
diff --git a/src/qml/qml/qqmltypemodule_p_p.h b/src/qml/qml/qqmltypemodule_p_p.h
index 5d4d2e458a..295a9c744a 100644
--- a/src/qml/qml/qqmltypemodule_p_p.h
+++ b/src/qml/qml/qqmltypemodule_p_p.h
@@ -69,6 +69,8 @@ public:
const QString module;
const quint8 majorVersion = 0;
+ QStringList imports;
+
// Can only ever decrease
QAtomicInt minMinorVersion = std::numeric_limits<quint8>::max();
diff --git a/tests/auto/qml/qqmlimport/MyPluginSupported/qmldir b/tests/auto/qml/qqmlimport/MyPluginSupported/qmldir
index 893e2892da..a58e199228 100644
--- a/tests/auto/qml/qqmlimport/MyPluginSupported/qmldir
+++ b/tests/auto/qml/qqmlimport/MyPluginSupported/qmldir
@@ -1,3 +1,4 @@
module MyPluginSupported
MyItem 1.0 MyItem.qml
+MyItem 2.0 MyItem.qml
designersupported
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index d5d2b061e9..0fdec44cdf 100644
--- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
+++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
@@ -50,6 +50,7 @@ private slots:
void removeDynamicPlugin();
void partialImportVersions_data();
void partialImportVersions();
+ void registerModuleImport();
void cleanup();
};
@@ -337,6 +338,27 @@ void tst_QQmlImport::partialImportVersions()
}
}
+void tst_QQmlImport::registerModuleImport()
+{
+ qmlRegisterModuleImport("MyPluginSupported", 2, "QtQuick");
+ {
+ QQmlEngine engine;
+ engine.addImportPath(directory());
+ QQmlComponent component(&engine);
+ component.setData("import MyPluginSupported; Item {}", QUrl());
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ }
+ qmlUnregisterModuleImport("MyPluginSupported", 2, "QtQuick");
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import MyPluginSupported; Item {}", QUrl());
+ QVERIFY(component.isError());
+ }
+}
+
QTEST_MAIN(tst_QQmlImport)