/* * SPDX-FileCopyrightText: 2024 ivan tkachenko * SPDX-FileCopyrightText: 2024 Harald Sitter * * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL */ #pragma once #include #include #include #include class PackageKitFetchDependenciesJob; // Minimal info about a package class PackageKitDependency { Q_GADGET Q_PROPERTY(PackageKit::Transaction::Info info MEMBER m_info CONSTANT FINAL) Q_PROPERTY(QString infoString MEMBER m_infoString CONSTANT FINAL) Q_PROPERTY(QString packageId MEMBER m_packageId CONSTANT FINAL) Q_PROPERTY(QString packageName READ packageName CONSTANT FINAL) Q_PROPERTY(QString summary MEMBER m_summary CONSTANT FINAL) public: explicit PackageKitDependency() = default; // for the sake of QVariant explicit PackageKitDependency(PackageKit::Transaction::Info info, const QString &packageId, const QString &summary); bool operator==(const PackageKitDependency &other) const; PackageKit::Transaction::Info info() const; QString infoString() const; QString packageId() const; QString packageName() const; QString summary() const; private: PackageKit::Transaction::Info m_info; QString m_infoString; QString m_packageId; QString m_summary; }; // Lazy job runner. Guards against starting two jobs at once. Resets itself when package ID changes. class PackageKitDependencies : public QObject { Q_OBJECT Q_PROPERTY(QString packageId READ packageId WRITE setPackageId NOTIFY packageIdChanged) Q_PROPERTY(QList dependencies READ dependencies NOTIFY dependenciesChanged) public: explicit PackageKitDependencies(QObject *parent = nullptr); ~PackageKitDependencies() override; Q_DISABLE_COPY_MOVE(PackageKitDependencies) QString packageId() const; void setPackageId(const QString &packageId); [[nodiscard]] bool hasFetchedDependencies(); [[nodiscard]] QList dependencies(); void setDirty(); void refresh(); Q_SIGNALS: void packageIdChanged(); void dependenciesChanged(); private Q_SLOTS: void onJobFinished(QList dependencies); private: using Job = QPointer; using Data = QList; void start(); void cancel(bool notify); QString m_packageId; // tri-state: // - no work done or even started yet: nullopt; // - job is currently running, no need to start another one: optional(Job); // - data is available: optional(Data). std::optional> m_state; }; // Wrapper which hides some complexity of PackageKit::Transaction management. // Self-destructs and emiting finished() signal or being cancelled. class PackageKitFetchDependenciesJob : public QObject { Q_OBJECT public: explicit PackageKitFetchDependenciesJob(const QString &packageId); ~PackageKitFetchDependenciesJob() override; Q_DISABLE_COPY_MOVE(PackageKitFetchDependenciesJob) void cancel(); Q_SIGNALS: void finished(QList dependencies); private Q_SLOTS: void onTransactionErrorCode(PackageKit::Transaction::Error error, const QString &details); void onTransactionPackage(PackageKit::Transaction::Info info, const QString &packageId, const QString &summary); void onTransactionFinished(); private: QPointer m_transaction; QList m_dependencies; };