aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorOlivier De Cannière <olivier.decanniere@qt.io>2024-01-17 17:41:29 +0100
committerOlivier De Cannière <olivier.decanniere@qt.io>2024-03-21 14:34:32 +0100
commit986b4d155bd39836b1aa3c3da332ef07d2a949fd (patch)
tree02c04716d3d5627ff95b68015f4febac24c0b8ae /src/qml/qml
parent050fa38d65bebe56ab599acdaaa65b8ed12c8a8b (diff)
QQmlEngine: Set translationsDirectory in loadFromModule
In the process, loadFromModule had to be split in two parts. The type resolution has to happen so that the translationDirectory can be set and the translations have to be loaded before loading the actual module. Pick-to: 6.7 6.5 Fixes: QTBUG-116589 Change-Id: Ife7999f418ba35bfb0eed9050198e5a886fa74ae Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp31
-rw-r--r--src/qml/qml/qqmlcomponent.cpp53
-rw-r--r--src/qml/qml/qqmlcomponent_p.h5
3 files changed, 63 insertions, 26 deletions
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 1147748a16..e2d9dceb16 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -7,10 +7,10 @@
#include <QQmlComponent>
#include "qqmlapplicationengine.h"
#include "qqmlapplicationengine_p.h"
+#include <QtQml/private/qqmlcomponent_p.h>
+#include <QtQml/private/qqmldirdata_p.h>
#include <QtQml/private/qqmlfileselector_p.h>
-#include <memory>
-
QT_BEGIN_NAMESPACE
QQmlApplicationEnginePrivate::QQmlApplicationEnginePrivate(QQmlEngine *e)
@@ -109,15 +109,36 @@ void QQmlApplicationEnginePrivate::startLoad(const QUrl &url, const QByteArray &
ensureLoadingFinishes(c);
}
-void QQmlApplicationEnginePrivate::startLoad(QAnyStringView uri, QAnyStringView type)
+void QQmlApplicationEnginePrivate::startLoad(QAnyStringView uri, QAnyStringView typeName)
{
Q_Q(QQmlApplicationEngine);
- _q_loadTranslations(); //Translations must be loaded before the QML file is
QQmlComponent *c = new QQmlComponent(q, q);
ensureInitialized();
- c->loadFromModule(uri, type);
+
+ auto *componentPriv = QQmlComponentPrivate::get(c);
+ const auto [status, type] = componentPriv->prepareLoadFromModule(uri, typeName);
+
+ if (type.sourceUrl().isValid()) {
+ const auto qmlDirData = typeLoader.getQmldir(type.sourceUrl());
+ const QUrl url = qmlDirData->finalUrl();
+ if (url.scheme() == QLatin1String("file") || url.scheme() == QLatin1String("qrc")) {
+ QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(url));
+ translationsDirectory = fi.path() + QLatin1String("/i18n");
+ } else {
+ translationsDirectory.clear();
+ }
+ }
+
+ /* Translations must be loaded before the QML file. They require translationDirectory to
+ * already be resolved. But, in order to resolve the translationDirectory, the type of the
+ * module to load needs to be known. Therefore, loadFromModule is split into resolution and
+ * loading because the translation directory needs to be set in between.
+ */
+ _q_loadTranslations();
+ componentPriv->completeLoadFromModule(uri, typeName, type, status);
+
ensureLoadingFinishes(c);
}
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 73e523fec6..7d691db750 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1335,35 +1335,48 @@ void QQmlComponent::loadFromModule(QAnyStringView uri, QAnyStringView typeName,
QQmlComponent::CompilationMode mode)
{
Q_D(QQmlComponent);
+ auto [status, type] = d->prepareLoadFromModule(uri, typeName);
+ d->completeLoadFromModule(uri, typeName, type, status, mode);
+}
- auto enginePriv = QQmlEnginePrivate::get(d->engine);
+LoadHelper::ResolveTypeResult QQmlComponentPrivate::prepareLoadFromModule(QAnyStringView uri,
+ QAnyStringView typeName)
+{
+ auto enginePriv = QQmlEnginePrivate::get(engine);
// LoadHelper must be on the Heap as it derives from QQmlRefCount
auto loadHelper = QQml::makeRefPointer<LoadHelper>(&enginePriv->typeLoader, uri);
- auto [moduleStatus, type] = loadHelper->resolveType(typeName);
+ return loadHelper->resolveType(typeName);
+}
+
+void QQmlComponentPrivate::completeLoadFromModule(QAnyStringView uri, QAnyStringView typeName, QQmlType type,
+ LoadHelper::ResolveTypeResult::Status moduleStatus,
+ QQmlComponent::CompilationMode mode)
+{
+ Q_Q(QQmlComponent);
+
auto reportError = [&](QString msg) {
QQmlError error;
error.setDescription(msg);
- d->state.errors.push_back(std::move(error));
- emit statusChanged(Error);
+ state.errors.push_back(std::move(error));
+ emit q->statusChanged(q->Error);
};
if (moduleStatus == LoadHelper::ResolveTypeResult::NoSuchModule) {
- reportError(QLatin1String(R"(No module named "%1" found)")
- .arg(uri.toString()));
+ reportError(QLatin1String(R"(No module named "%1" found)").arg(uri.toString()));
} else if (!type.isValid()) {
reportError(QLatin1String(R"(Module "%1" contains no type named "%2")")
.arg(uri.toString(), typeName.toString()));
} else if (type.isCreatable()) {
- d->clear();
+ clear();
// mimic the progressChanged behavior from loadUrl
- if (d->progress != 0) {
- d->progress = 0;
- emit progressChanged(0);
+ if (progress != 0) {
+ progress = 0;
+ emit q->progressChanged(0);
}
- d->loadedType = type;
- d->progress = 1;
- emit progressChanged(1);
- emit statusChanged(status());
+ loadedType = type;
+ progress = 1;
+ emit q->progressChanged(1);
+ emit q->statusChanged(q->status());
} else if (type.isComposite()) {
loadUrl(type.sourceUrl(), mode);
@@ -1371,16 +1384,14 @@ void QQmlComponent::loadFromModule(QAnyStringView uri, QAnyStringView typeName,
auto baseUrl = type.sourceUrl();
baseUrl.setFragment(QString());
loadUrl(baseUrl, mode);
- if (!isError()) {
- d->inlineComponentName = std::make_unique<QString>(type.elementName());
- Q_ASSERT(!d->inlineComponentName->isEmpty());
+ if (!q->isError()) {
+ inlineComponentName = std::make_unique<QString>(type.elementName());
+ Q_ASSERT(!inlineComponentName->isEmpty());
}
} else if (type.isSingleton() || type.isCompositeSingleton()) {
- reportError(QLatin1String(R"(%1 is a singleton, and cannot be loaded)")
- .arg(typeName.toString()));
+ reportError(QLatin1String(R"(%1 is a singleton, and cannot be loaded)").arg(typeName.toString()));
} else {
- reportError(QLatin1String("Could not load %1, as the type is uncreatable")
- .arg(typeName.toString()));
+ reportError(QLatin1String("Could not load %1, as the type is uncreatable").arg(typeName.toString()));
}
}
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 4d01d458a7..21fdee3f7a 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -168,6 +168,11 @@ public:
QQmlContext *context, CreateBehavior behavior = CreateDefault);
bool isBound() const { return compilationUnit && (compilationUnit->componentsAreBound()); }
+ LoadHelper::ResolveTypeResult prepareLoadFromModule(QAnyStringView uri,
+ QAnyStringView typeName);
+ void completeLoadFromModule(QAnyStringView uri, QAnyStringView typeName, QQmlType type,
+ LoadHelper::ResolveTypeResult::Status moduleStatus,
+ QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous);
};
QQmlComponentPrivate::ConstructionState::~ConstructionState()