diff --git a/src/core/generation.cpp b/src/core/generation.cpp index a0b465f8..8dbad323 100644 --- a/src/core/generation.cpp +++ b/src/core/generation.cpp @@ -27,8 +27,10 @@ static QHash g_generations; // NOLINT -EngineGeneration::EngineGeneration(QmlScanner scanner) - : scanner(std::move(scanner)) +EngineGeneration::EngineGeneration(const QDir& rootPath, QmlScanner scanner) + : rootPath(rootPath) + , scanner(std::move(scanner)) + , urlInterceptor(this->rootPath) , interceptNetFactory(this->scanner.qmldirIntercepts) , engine(new QQmlEngine()) { g_generations.insert(this->engine, this); diff --git a/src/core/generation.hpp b/src/core/generation.hpp index 3c8f3997..c077c1bf 100644 --- a/src/core/generation.hpp +++ b/src/core/generation.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -19,7 +20,7 @@ class EngineGeneration: public QObject { Q_OBJECT; public: - explicit EngineGeneration(QmlScanner scanner); + explicit EngineGeneration(const QDir& rootPath, QmlScanner scanner); ~EngineGeneration() override; Q_DISABLE_COPY_MOVE(EngineGeneration); @@ -33,6 +34,7 @@ public: static EngineGeneration* findObjectGeneration(QObject* object); RootWrapper* wrapper = nullptr; + QDir rootPath; QmlScanner scanner; QsUrlInterceptor urlInterceptor; QsInterceptNetworkAccessManagerFactory interceptNetFactory; diff --git a/src/core/qsintercept.cpp b/src/core/qsintercept.cpp index 2eaf498e..ba46ab7b 100644 --- a/src/core/qsintercept.cpp +++ b/src/core/qsintercept.cpp @@ -16,7 +16,22 @@ Q_LOGGING_CATEGORY(logQsIntercept, "quickshell.interceptor", QtWarningMsg); -QUrl QsUrlInterceptor::intercept(const QUrl& url, QQmlAbstractUrlInterceptor::DataType type) { +QUrl QsUrlInterceptor::intercept( + const QUrl& originalUrl, + QQmlAbstractUrlInterceptor::DataType type +) { + auto url = originalUrl; + + if (url.scheme() == "root") { + url.setScheme("qsintercept"); + + auto path = url.path(); + if (path.startsWith('/')) path = path.sliced(1); + url.setPath(this->configRoot.filePath(path)); + + qCDebug(logQsIntercept) << "Rewrote root intercept" << originalUrl << "to" << url; + } + // Some types such as Image take into account where they are loading from, and force // asynchronous loading over a network. qsintercept is considered to be over a network. if (type == QQmlAbstractUrlInterceptor::DataType::UrlString && url.scheme() == "qsintercept") { diff --git a/src/core/qsintercept.hpp b/src/core/qsintercept.hpp index d51b78e6..57923568 100644 --- a/src/core/qsintercept.hpp +++ b/src/core/qsintercept.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -13,7 +14,12 @@ Q_DECLARE_LOGGING_CATEGORY(logQsIntercept); class QsUrlInterceptor: public QQmlAbstractUrlInterceptor { public: - QUrl intercept(const QUrl& url, QQmlAbstractUrlInterceptor::DataType type) override; + explicit QsUrlInterceptor(const QDir& configRoot): configRoot(configRoot) {} + + QUrl intercept(const QUrl& originalUrl, QQmlAbstractUrlInterceptor::DataType type) override; + +private: + QDir configRoot; }; class QsInterceptDataReply: public QNetworkReply { diff --git a/src/core/rootwrapper.cpp b/src/core/rootwrapper.cpp index ed2ef4b7..ea2adf18 100644 --- a/src/core/rootwrapper.cpp +++ b/src/core/rootwrapper.cpp @@ -42,10 +42,11 @@ RootWrapper::~RootWrapper() { } void RootWrapper::reloadGraph(bool hard) { - auto scanner = QmlScanner(); + auto rootPath = QFileInfo(this->rootPath).dir(); + auto scanner = QmlScanner(rootPath); scanner.scanQmlFile(this->rootPath); - auto* generation = new EngineGeneration(std::move(scanner)); + auto* generation = new EngineGeneration(rootPath, std::move(scanner)); generation->wrapper = this; // todo: move into EngineGeneration diff --git a/src/core/scan.cpp b/src/core/scan.cpp index f5f078aa..59ec05b6 100644 --- a/src/core/scan.cpp +++ b/src/core/scan.cpp @@ -103,7 +103,15 @@ bool QmlScanner::scanQmlFile(const QString& path) { this->scanDir(currentdir.path()); for (auto& import: imports) { - auto ipath = currentdir.filePath(import); + QString ipath; + if (import.startsWith("root:")) { + auto path = import.sliced(5); + if (path.startsWith('/')) path = path.sliced(1); + ipath = this->rootPath.filePath(path); + } else { + ipath = currentdir.filePath(import); + } + auto cpath = QFileInfo(ipath).canonicalFilePath(); if (cpath.isEmpty()) { diff --git a/src/core/scan.hpp b/src/core/scan.hpp index 32a6166d..e3071a88 100644 --- a/src/core/scan.hpp +++ b/src/core/scan.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -10,6 +11,8 @@ Q_DECLARE_LOGGING_CATEGORY(logQmlScanner); // expects canonical paths class QmlScanner { public: + QmlScanner(const QDir& rootPath): rootPath(rootPath) {} + void scanDir(const QString& path); // returns if the file has a singleton bool scanQmlFile(const QString& path); @@ -17,4 +20,7 @@ public: QVector scannedDirs; QVector scannedFiles; QHash qmldirIntercepts; + +private: + QDir rootPath; };