File indexing completed on 2024-05-12 05:29:03
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #pragma once 0008 0009 #include <QSet> 0010 #include <QTimer> 0011 #include <QVector> 0012 0013 #include "AbstractResourcesBackend.h" 0014 #include "discovercommon_export.h" 0015 0016 class DiscoverAction; 0017 0018 class DISCOVERCOMMON_EXPORT AggregatedResultsStream : public ResultsStream 0019 { 0020 Q_OBJECT 0021 public: 0022 AggregatedResultsStream(const QSet<ResultsStream *> &streams); 0023 ~AggregatedResultsStream(); 0024 0025 QSet<QObject *> streams() const 0026 { 0027 return m_streams; 0028 } 0029 0030 Q_SIGNALS: 0031 void finished(); 0032 0033 private: 0034 void addResults(const QVector<StreamResult> &res); 0035 void emitResults(); 0036 void streamDestruction(QObject *obj); 0037 void resourceDestruction(QObject *obj); 0038 void clear(); 0039 0040 QSet<QObject *> m_streams; 0041 QVector<StreamResult> m_results; 0042 QTimer m_delayedEmission; 0043 }; 0044 0045 template<typename T> 0046 class EmitWhenChanged 0047 { 0048 public: 0049 EmitWhenChanged(T initial, const std::function<T()> &get, const std::function<void(T)> &emitChanged) 0050 : m_get(get) 0051 , m_emitChanged(emitChanged) 0052 , m_value(initial) 0053 { 0054 } 0055 0056 void reevaluate() 0057 { 0058 auto newValue = m_get(); 0059 if (newValue != m_value) { 0060 m_value = newValue; 0061 m_emitChanged(m_value); 0062 } 0063 } 0064 0065 std::function<T()> const m_get; 0066 std::function<void(T)> const m_emitChanged; 0067 T m_value; 0068 }; 0069 0070 class DISCOVERCOMMON_EXPORT ResourcesModel : public QObject 0071 { 0072 Q_OBJECT 0073 Q_PROPERTY(int updatesCount READ updatesCount NOTIFY updatesCountChanged) 0074 Q_PROPERTY(bool hasSecurityUpdates READ hasSecurityUpdates NOTIFY updatesCountChanged) 0075 Q_PROPERTY(bool isFetching READ isFetching NOTIFY fetchingChanged) 0076 Q_PROPERTY(bool isInitializing READ isInitializing NOTIFY allInitialized) 0077 Q_PROPERTY(AbstractResourcesBackend *currentApplicationBackend READ currentApplicationBackend WRITE setCurrentApplicationBackend NOTIFY 0078 currentApplicationBackendChanged) 0079 Q_PROPERTY(DiscoverAction *updateAction READ updateAction CONSTANT) 0080 Q_PROPERTY(int fetchingUpdatesProgress READ fetchingUpdatesProgress NOTIFY fetchingUpdatesProgressChanged) 0081 Q_PROPERTY(QString applicationSourceName READ applicationSourceName NOTIFY currentApplicationBackendChanged) 0082 Q_PROPERTY(InlineMessage *inlineMessage READ inlineMessage NOTIFY inlineMessageChanged) 0083 Q_PROPERTY(QString distroName READ distroName CONSTANT) 0084 public: 0085 /** This constructor should be only used by unit tests. 0086 * @p backendName defines what backend will be loaded when the backend is constructed. 0087 */ 0088 explicit ResourcesModel(const QString &backendName, QObject *parent = nullptr); 0089 static ResourcesModel *global(); 0090 ~ResourcesModel() override; 0091 0092 QVector<AbstractResourcesBackend *> backends() const; 0093 int updatesCount() const 0094 { 0095 return m_updatesCount.m_value; 0096 } 0097 bool hasSecurityUpdates() const; 0098 0099 bool isBusy() const; 0100 bool isFetching() const; 0101 bool isInitializing() const; 0102 0103 Q_SCRIPTABLE bool isExtended(const QString &id); 0104 0105 AggregatedResultsStream *search(const AbstractResourcesBackend::Filters &search); 0106 void checkForUpdates(); 0107 0108 QString applicationSourceName() const; 0109 0110 void setCurrentApplicationBackend(AbstractResourcesBackend *backend, bool writeConfig = true); 0111 AbstractResourcesBackend *currentApplicationBackend() const; 0112 0113 DiscoverAction *updateAction() const 0114 { 0115 return m_updateAction; 0116 } 0117 int fetchingUpdatesProgress() const 0118 { 0119 return m_fetchingUpdatesProgress.m_value; 0120 } 0121 0122 QString distroName() const; 0123 Q_INVOKABLE QUrl distroBugReportUrl(); 0124 0125 void setInlineMessage(const QSharedPointer<InlineMessage> &inlineMessage); 0126 InlineMessage *inlineMessage() const 0127 { 0128 return m_inlineMessage.data(); 0129 } 0130 0131 public Q_SLOTS: 0132 void installApplication(AbstractResource *app, const AddonList &addons); 0133 void installApplication(AbstractResource *app); 0134 void removeApplication(AbstractResource *app); 0135 0136 Q_SIGNALS: 0137 void fetchingChanged(bool isFetching); 0138 void allInitialized(); 0139 void backendsChanged(); 0140 void updatesCountChanged(int updatesCount); 0141 void backendDataChanged(AbstractResourcesBackend *backend, const QVector<QByteArray> &properties); 0142 void resourceDataChanged(AbstractResource *resource, const QVector<QByteArray> &properties); 0143 void resourceRemoved(AbstractResource *resource); 0144 void passiveMessage(const QString &message); 0145 void currentApplicationBackendChanged(AbstractResourcesBackend *currentApplicationBackend); 0146 void fetchingUpdatesProgressChanged(int fetchingUpdatesProgress); 0147 void inlineMessageChanged(const QSharedPointer<InlineMessage> &inlineMessage); 0148 void switchToUpdates(); 0149 0150 private Q_SLOTS: 0151 void callerFetchingChanged(); 0152 void updateCaller(const QVector<QByteArray> &properties); 0153 void registerAllBackends(); 0154 0155 private: 0156 ///@p initialize tells if all backends load will be triggered on construction 0157 explicit ResourcesModel(QObject *parent = nullptr); 0158 void init(bool load); 0159 void addResourcesBackend(AbstractResourcesBackend *backend); 0160 void registerBackendByName(const QString &name); 0161 void initApplicationsBackend(); 0162 void slotFetching(); 0163 0164 bool m_isFetching; 0165 bool m_isInitializing = true; 0166 QVector<AbstractResourcesBackend *> m_backends; 0167 int m_initializingBackendsCount; 0168 DiscoverAction *m_updateAction = nullptr; 0169 AbstractResourcesBackend *m_currentApplicationBackend; 0170 QTimer *m_allInitializedEmitter; 0171 0172 EmitWhenChanged<int> m_updatesCount; 0173 EmitWhenChanged<int> m_fetchingUpdatesProgress; 0174 QSharedPointer<InlineMessage> m_inlineMessage; 0175 0176 static ResourcesModel *s_self; 0177 };