mirror of
https://github.com/logos-co/logos-app-poc.git
synced 2026-08-27 09:51:17 +00:00
Measured on the built artefact: main_ui.dylib DEFINES zero and IMPORTS zero of
TokenManager, StoreRegistry, LogosAPI, LogosAPIClient and logos_core_*, out of
3410 symbols read. It links Qt and nothing else from this workspace, which
nix/symbol-gate.nix enforces across the in-process image set.
Getting there needed the last non-Qt types off the boundary: the model
properties cross as QAbstractItemModel*, catalogInstallStageChanged carries an
int rather than InstallStage::Value, and the two prebuilt AppsFilterProxy
instances are declared in QML instead of owned by MainUIBackend. That last one
removes a real inversion -- PackageCoordinator called setRequiredPackages() on
a proxy the host held a pointer to; it now emits requiredPackagesResolved() and
QML binds to the republished property.
Window resolves the plugin, qobject_casts it to IShellView, checks
hostAbiVersion() against IShellHost_abi, and calls createShell(IShellHost*).
No error-label fallback widget: that degraded to something that looked like a
working app with an empty window.
Filter proxies read role constants off host-side models and InstallEnums is
used by nine host files, so app/interfaces/ gains the contract headers both
sides compile against -- the models inherit the role structs, leaving every
AppsModel::NameRole call site unchanged. The plugin's include path is
app/interfaces only, so including a host header does not compile.
Four things only running it finds:
* Logos::DesignSystem may be linked by exactly ONE image -- both linked it
and the app aborted with "Cannot add multiple registrations for
Logos.Icons"; QML module registration is process-global
* qmltyperegistrar emits no #include for a SOURCES header given as an
absolute path outside the project
* each qt_add_qml_module is its own target and inherits no include dirs
* AUTOMOC pairs header<->cpp by same-basename-same-DIRECTORY, which the
split breaks
tst_AppManagerView.qml grows five tests for the QML binding, checked with a
negative control: breaking one assertion fails qml-tests, so they run.
128 lines
4.1 KiB
C++
128 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "BasecampModelRoles.h"
|
|
#include "InstallEnums.h"
|
|
|
|
#include <QAbstractListModel>
|
|
#include <QHash>
|
|
#include <QPointer>
|
|
#include <QString>
|
|
#include <QVariantList>
|
|
#include <QVariantMap>
|
|
|
|
class InstallRegistry;
|
|
|
|
// AppsModel — the single source of truth for every package the App Manager
|
|
// (and Modules tab) cares about.
|
|
class AppsModel : public QAbstractListModel, public AppsModelRoles {
|
|
Q_OBJECT
|
|
Q_PROPERTY(QStringList categories READ categories NOTIFY categoriesChanged)
|
|
public:
|
|
Q_ENUM(Roles)
|
|
|
|
explicit AppsModel(QObject* parent = nullptr);
|
|
|
|
// ── QAbstractListModel
|
|
int rowCount(const QModelIndex& parent = {}) const override;
|
|
QVariant data(const QModelIndex& index, int role) const override;
|
|
QHash<int, QByteArray> roleNames() const override;
|
|
|
|
QStringList categories() const;
|
|
|
|
signals:
|
|
void categoriesChanged();
|
|
|
|
public:
|
|
|
|
// True once the manifest guarantees a conforming icon (>= 0.4.0). Static
|
|
// and public so UIPluginManager's sidebar path uses the SAME rule — this
|
|
// comparison must exist once. Mirrors Manifest::requiresIconContract().
|
|
static bool supportsFullBleedIcon(const QString& manifestVersion);
|
|
|
|
|
|
void replaceCatalog(const QVariantList& catalogRows);
|
|
|
|
// Append synthetic rows for installed packages that have no catalog row.
|
|
// Marked by empty repositoryUrl
|
|
void mergeLocalOnlyInstalled(const QVariantList& installedPackages);
|
|
|
|
void markInstalled(const QString& name,
|
|
const QString& installedVersion,
|
|
const QString& installedHash = {});
|
|
void replaceInstalledSet(const QHash<QString, QString>& versionByName,
|
|
const QHash<QString, QString>& hashByName);
|
|
|
|
void setInstallType(const QString& name, const QString& installType);
|
|
void setIconUrl(const QString& name, const QString& iconUrl);
|
|
void setMissingDeps(const QString& name, const QStringList& missing);
|
|
void setInstallRegistry(InstallRegistry* installRegistry);
|
|
|
|
void beginBulkInstalledUpdate();
|
|
void endBulkInstalledUpdate();
|
|
|
|
struct ResolverRow {
|
|
QString name;
|
|
QString repositoryUrl;
|
|
QString action;
|
|
QString toVersion;
|
|
bool isTopLevel = false;
|
|
QString resolverError;
|
|
};
|
|
void setResolverOverlay(const QList<ResolverRow>& rows);
|
|
void clearResolverOverlay();
|
|
|
|
QVariantMap rowDataByName(const QString& name,
|
|
const QString& repositoryUrl = {}) const;
|
|
|
|
private:
|
|
int rowOf(const QString& name,
|
|
const QString& repositoryUrl = {}) const;
|
|
QVariantMap rowData(int row) const;
|
|
|
|
struct Row {
|
|
// Identity
|
|
QString name;
|
|
QString repositoryUrl;
|
|
|
|
// Catalog metadata
|
|
QString displayName;
|
|
QString description;
|
|
QString category;
|
|
QString type;
|
|
QString iconUrl;
|
|
bool supportsFullBleedIcon = false;
|
|
QVariantList versions;
|
|
QString latestVersion; // computed from versions[0].version
|
|
QVariantList dependencies;
|
|
|
|
// On-disk state
|
|
QString installedVersion;
|
|
QString installedHash;
|
|
QString installType;
|
|
QStringList missingDeps;
|
|
InstallStatus::Value installStatus = InstallStatus::NotInstalled;
|
|
|
|
// Resolver overlay (per dialog session). Live install state lives
|
|
// on m_installRegistry — see setInstallRegistry. Per-row InstallStageRole /
|
|
// InstallErrorRole / ActionRole derive from there at read time.
|
|
QString action;
|
|
QString toVersion;
|
|
bool isTopLevel = false;
|
|
QString resolverError;
|
|
};
|
|
|
|
static QString key(const QString& repo, const QString& name);
|
|
|
|
|
|
void recomputeVersionDerivedFields(Row& r);
|
|
void recomputeInstallStatus(Row& r);
|
|
|
|
QList<Row> m_rows;
|
|
QHash<QString, int> m_indexByKey; // (repo + "\n" + name) → row index
|
|
QMultiHash<QString, int> m_indicesByName;
|
|
bool m_inBulkInstalledUpdate = false;
|
|
|
|
// Source of truth for in-flight install state
|
|
QPointer<InstallRegistry> m_installRegistry;
|
|
};
|