diff --git a/frontends/qt6/CMakeLists.txt b/frontends/qt6/CMakeLists.txt index a2e0eaf74..2c4f25056 100644 --- a/frontends/qt6/CMakeLists.txt +++ b/frontends/qt6/CMakeLists.txt @@ -12,6 +12,7 @@ find_package(cpr CONFIG REQUIRED) qt_add_executable(dbal-qml main.cpp + src/PackageRegistry.cpp ) qt_add_qml_module(dbal-qml diff --git a/frontends/qt6/main.cpp b/frontends/qt6/main.cpp index 0d02c0972..6e029febf 100644 --- a/frontends/qt6/main.cpp +++ b/frontends/qt6/main.cpp @@ -4,6 +4,9 @@ #include #include #include +#include + +#include "src/PackageRegistry.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); @@ -16,6 +19,9 @@ int main(int argc, char *argv[]) { QCoreApplication::exit(-1); } }); + PackageRegistry registry; + registry.loadPackage("frontpage"); + engine.rootContext()->setContextProperty(QStringLiteral("PackageRegistry"), ®istry); engine.load(url); return app.exec(); diff --git a/frontends/qt6/src/PackageRegistry.cpp b/frontends/qt6/src/PackageRegistry.cpp new file mode 100644 index 000000000..f054c08c8 --- /dev/null +++ b/frontends/qt6/src/PackageRegistry.cpp @@ -0,0 +1,103 @@ +#include "PackageRegistry.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace { +QString normalizedPath(const QString &path) { + QDir dir(path); + return dir.absolutePath(); +} + +QString metadataFileName(const QString &packageId) { + return packageId + "/metadata.json"; +} +} + +PackageRegistry::PackageRegistry(QObject *parent) + : QObject(parent) +{ + const auto appDir = QCoreApplication::applicationDirPath(); + m_roots << normalizedPath(appDir + "/packages"); + m_roots << normalizedPath(appDir + "/../packages"); + m_roots << normalizedPath(appDir + "/../frontends/qt6/packages"); + m_roots << normalizedPath(appDir + "/../../frontends/qt6/packages"); +} + +QStringList PackageRegistry::packageIds() const +{ + QSet ids; + for (const auto &root : m_roots) { + QDir dir(root); + if (!dir.exists()) + continue; + + const auto entries = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + for (const auto &entry : entries) { + const auto meta = dir.filePath(metadataFileName(entry)); + if (QFile::exists(meta)) + ids.insert(entry); + } + } + return ids.values(); +} + +QString PackageRegistry::loadedPackage() const +{ + return m_loadedPackage; +} + +QVariantMap PackageRegistry::loadedMetadata() const +{ + return m_loadedMetadata; +} + +QVariantMap PackageRegistry::metadata(const QString &packageId) const +{ + const auto filePath = findMetadataFile(packageId); + if (filePath.isEmpty()) + return {}; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + return {}; + const auto doc = QJsonDocument::fromJson(file.readAll()); + if (!doc.isObject()) + return {}; + return doc.object().toVariantMap(); +} + +bool PackageRegistry::loadPackage(const QString &packageId) +{ + const auto filePath = findMetadataFile(packageId); + if (filePath.isEmpty()) + return false; + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + return false; + + const auto doc = QJsonDocument::fromJson(file.readAll()); + if (!doc.isObject()) + return false; + + m_loadedPackage = packageId; + m_loadedMetadata = doc.object().toVariantMap(); + emit packageLoaded(); + emit metadataChanged(); + return true; +} + +QString PackageRegistry::findMetadataFile(const QString &packageId) const +{ + for (const auto &root : m_roots) { + const auto candidate = QDir(root).filePath(metadataFileName(packageId)); + if (QFile::exists(candidate)) + return candidate; + } + return {}; +}