forked from quickshell/quickshell
core: support root:
and root:/
paths for the config root
This works everywhere urls are accepted and rewrites them from the config root as a qsintercept url.
This commit is contained in:
parent
33fac67798
commit
0519acf1d6
|
@ -27,8 +27,10 @@
|
||||||
|
|
||||||
static QHash<QQmlEngine*, EngineGeneration*> g_generations; // NOLINT
|
static QHash<QQmlEngine*, EngineGeneration*> g_generations; // NOLINT
|
||||||
|
|
||||||
EngineGeneration::EngineGeneration(QmlScanner scanner)
|
EngineGeneration::EngineGeneration(const QDir& rootPath, QmlScanner scanner)
|
||||||
: scanner(std::move(scanner))
|
: rootPath(rootPath)
|
||||||
|
, scanner(std::move(scanner))
|
||||||
|
, urlInterceptor(this->rootPath)
|
||||||
, interceptNetFactory(this->scanner.qmldirIntercepts)
|
, interceptNetFactory(this->scanner.qmldirIntercepts)
|
||||||
, engine(new QQmlEngine()) {
|
, engine(new QQmlEngine()) {
|
||||||
g_generations.insert(this->engine, this);
|
g_generations.insert(this->engine, this);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qcontainerfwd.h>
|
#include <qcontainerfwd.h>
|
||||||
|
#include <qdir.h>
|
||||||
#include <qfilesystemwatcher.h>
|
#include <qfilesystemwatcher.h>
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qpair.h>
|
#include <qpair.h>
|
||||||
|
@ -19,7 +20,7 @@ class EngineGeneration: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EngineGeneration(QmlScanner scanner);
|
explicit EngineGeneration(const QDir& rootPath, QmlScanner scanner);
|
||||||
~EngineGeneration() override;
|
~EngineGeneration() override;
|
||||||
Q_DISABLE_COPY_MOVE(EngineGeneration);
|
Q_DISABLE_COPY_MOVE(EngineGeneration);
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ public:
|
||||||
static EngineGeneration* findObjectGeneration(QObject* object);
|
static EngineGeneration* findObjectGeneration(QObject* object);
|
||||||
|
|
||||||
RootWrapper* wrapper = nullptr;
|
RootWrapper* wrapper = nullptr;
|
||||||
|
QDir rootPath;
|
||||||
QmlScanner scanner;
|
QmlScanner scanner;
|
||||||
QsUrlInterceptor urlInterceptor;
|
QsUrlInterceptor urlInterceptor;
|
||||||
QsInterceptNetworkAccessManagerFactory interceptNetFactory;
|
QsInterceptNetworkAccessManagerFactory interceptNetFactory;
|
||||||
|
|
|
@ -16,7 +16,22 @@
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(logQsIntercept, "quickshell.interceptor", QtWarningMsg);
|
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
|
// 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.
|
// asynchronous loading over a network. qsintercept is considered to be over a network.
|
||||||
if (type == QQmlAbstractUrlInterceptor::DataType::UrlString && url.scheme() == "qsintercept") {
|
if (type == QQmlAbstractUrlInterceptor::DataType::UrlString && url.scheme() == "qsintercept") {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <qdir.h>
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
#include <qloggingcategory.h>
|
#include <qloggingcategory.h>
|
||||||
#include <qnetworkaccessmanager.h>
|
#include <qnetworkaccessmanager.h>
|
||||||
|
@ -13,7 +14,12 @@ Q_DECLARE_LOGGING_CATEGORY(logQsIntercept);
|
||||||
|
|
||||||
class QsUrlInterceptor: public QQmlAbstractUrlInterceptor {
|
class QsUrlInterceptor: public QQmlAbstractUrlInterceptor {
|
||||||
public:
|
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 {
|
class QsInterceptDataReply: public QNetworkReply {
|
||||||
|
|
|
@ -42,10 +42,11 @@ RootWrapper::~RootWrapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootWrapper::reloadGraph(bool hard) {
|
void RootWrapper::reloadGraph(bool hard) {
|
||||||
auto scanner = QmlScanner();
|
auto rootPath = QFileInfo(this->rootPath).dir();
|
||||||
|
auto scanner = QmlScanner(rootPath);
|
||||||
scanner.scanQmlFile(this->rootPath);
|
scanner.scanQmlFile(this->rootPath);
|
||||||
|
|
||||||
auto* generation = new EngineGeneration(std::move(scanner));
|
auto* generation = new EngineGeneration(rootPath, std::move(scanner));
|
||||||
generation->wrapper = this;
|
generation->wrapper = this;
|
||||||
|
|
||||||
// todo: move into EngineGeneration
|
// todo: move into EngineGeneration
|
||||||
|
|
|
@ -103,7 +103,15 @@ bool QmlScanner::scanQmlFile(const QString& path) {
|
||||||
this->scanDir(currentdir.path());
|
this->scanDir(currentdir.path());
|
||||||
|
|
||||||
for (auto& import: imports) {
|
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();
|
auto cpath = QFileInfo(ipath).canonicalFilePath();
|
||||||
|
|
||||||
if (cpath.isEmpty()) {
|
if (cpath.isEmpty()) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qcontainerfwd.h>
|
#include <qcontainerfwd.h>
|
||||||
|
#include <qdir.h>
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
#include <qloggingcategory.h>
|
#include <qloggingcategory.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
@ -10,6 +11,8 @@ Q_DECLARE_LOGGING_CATEGORY(logQmlScanner);
|
||||||
// expects canonical paths
|
// expects canonical paths
|
||||||
class QmlScanner {
|
class QmlScanner {
|
||||||
public:
|
public:
|
||||||
|
QmlScanner(const QDir& rootPath): rootPath(rootPath) {}
|
||||||
|
|
||||||
void scanDir(const QString& path);
|
void scanDir(const QString& path);
|
||||||
// returns if the file has a singleton
|
// returns if the file has a singleton
|
||||||
bool scanQmlFile(const QString& path);
|
bool scanQmlFile(const QString& path);
|
||||||
|
@ -17,4 +20,7 @@ public:
|
||||||
QVector<QString> scannedDirs;
|
QVector<QString> scannedDirs;
|
||||||
QVector<QString> scannedFiles;
|
QVector<QString> scannedFiles;
|
||||||
QHash<QString, QString> qmldirIntercepts;
|
QHash<QString, QString> qmldirIntercepts;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDir rootPath;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue