File indexing completed on 2024-05-05 17:33:20
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 <QObject> 0010 #include <QPair> 0011 #include <QVariantList> 0012 #include <QVector> 0013 0014 #include "AbstractResource.h" 0015 #include "DiscoverAction.h" 0016 #include "Transaction/AddonList.h" 0017 0018 #include "discovercommon_export.h" 0019 0020 class Transaction; 0021 class Category; 0022 class AbstractReviewsBackend; 0023 class AbstractBackendUpdater; 0024 0025 class DISCOVERCOMMON_EXPORT ResultsStream : public QObject 0026 { 0027 Q_OBJECT 0028 public: 0029 ResultsStream(const QString &objectName); 0030 0031 /// assumes all the information is in @p resources 0032 ResultsStream(const QString &objectName, const QVector<AbstractResource *> &resources); 0033 ~ResultsStream() override; 0034 0035 void finish(); 0036 0037 Q_SIGNALS: 0038 void resourcesFound(const QVector<AbstractResource *> &resources); 0039 void fetchMore(); 0040 }; 0041 0042 class DISCOVERCOMMON_EXPORT InlineMessage : public QObject 0043 { 0044 Q_OBJECT 0045 public: 0046 // Keep in sync with Kirigami's in enums.h 0047 enum InlineMessageType { 0048 Information = 0, 0049 Positive, 0050 Warning, 0051 Error, 0052 }; 0053 Q_ENUM(InlineMessageType) 0054 Q_PROPERTY(InlineMessageType type MEMBER type CONSTANT) 0055 Q_PROPERTY(QString iconName MEMBER iconName CONSTANT) 0056 Q_PROPERTY(QString message MEMBER message CONSTANT) 0057 Q_PROPERTY(QVariantList actions MEMBER actions CONSTANT) 0058 0059 InlineMessage(InlineMessageType type, const QString &iconName, const QString &message, DiscoverAction *action = nullptr) 0060 : type(type) 0061 , iconName(iconName) 0062 , message(message) 0063 , actions(action ? QVariantList{QVariant::fromValue<QObject *>(action)} : QVariantList()) 0064 { 0065 } 0066 0067 InlineMessage(InlineMessageType type, const QString &iconName, const QString &message, const QVariantList &actions) 0068 : type(type) 0069 , iconName(iconName) 0070 , message(message) 0071 , actions(actions) 0072 { 0073 } 0074 0075 InlineMessageType type; 0076 const QString iconName; 0077 const QString message; 0078 const QVariantList actions; 0079 }; 0080 0081 /** 0082 * \class AbstractResourcesBackend AbstractResourcesBackend.h "AbstractResourcesBackend.h" 0083 * 0084 * \brief This is the base class of all resource backends. 0085 * 0086 * For writing basic new resource backends, we need to implement two classes: this and the 0087 * AbstractResource one. Basic questions on how to build your plugin with those classes 0088 * can be answered by looking at the dummy plugin. 0089 * 0090 * As this is the base class of a backend, we save all the created resources here and also 0091 * accept calls to install and remove applications or to cancel transactions. 0092 * 0093 * To show resources in Discover, we need to initialize all resources we want to show beforehand, 0094 * we should not create resources in the search function. When we reload the resources 0095 * (e.g. when initializing), the backend needs change the fetching property throughout the 0096 * process. 0097 */ 0098 class DISCOVERCOMMON_EXPORT AbstractResourcesBackend : public QObject 0099 { 0100 Q_OBJECT 0101 Q_PROPERTY(QString name READ name CONSTANT) 0102 Q_PROPERTY(QString displayName READ displayName CONSTANT) 0103 Q_PROPERTY(AbstractReviewsBackend *reviewsBackend READ reviewsBackend CONSTANT) 0104 Q_PROPERTY(int updatesCount READ updatesCount NOTIFY updatesCountChanged) 0105 Q_PROPERTY(int fetchingUpdatesProgress READ fetchingUpdatesProgress NOTIFY fetchingUpdatesProgressChanged) 0106 Q_PROPERTY(bool hasSecurityUpdates READ hasSecurityUpdates NOTIFY updatesCountChanged) 0107 Q_PROPERTY(bool isFetching READ isFetching NOTIFY fetchingChanged) 0108 Q_PROPERTY(bool hasApplications READ hasApplications CONSTANT) 0109 public: 0110 /** 0111 * Constructs an AbstractResourcesBackend 0112 * @param parent the parent of the class (the object will be deleted when the parent gets deleted) 0113 */ 0114 explicit AbstractResourcesBackend(QObject *parent = nullptr); 0115 0116 /** 0117 * @returns true when the backend is in a valid state, which means it is able to work 0118 * You must return true here if you want the backend to be loaded. 0119 */ 0120 virtual bool isValid() const = 0; 0121 0122 struct Filters { 0123 Category *category = nullptr; 0124 AbstractResource::State state = AbstractResource::Broken; 0125 QString mimetype; 0126 QString search; 0127 QString extends; 0128 QUrl resourceUrl; 0129 QString origin; 0130 bool allBackends = false; 0131 bool filterMinimumState = true; 0132 AbstractResourcesBackend *backend = nullptr; 0133 0134 bool isEmpty() const 0135 { 0136 return !category && state == AbstractResource::Broken && mimetype.isEmpty() && search.isEmpty() && extends.isEmpty() && resourceUrl.isEmpty() 0137 && origin.isEmpty(); 0138 } 0139 0140 bool shouldFilter(AbstractResource *res) const; 0141 void filterJustInCase(QVector<AbstractResource *> &input) const; 0142 }; 0143 0144 /** 0145 * @returns a stream that will provide elements that match the search 0146 */ 0147 0148 virtual ResultsStream *search(const Filters &search) = 0; // FIXME: Probably provide a standard implementation?! 0149 0150 /** 0151 * @returns the reviews backend of this AbstractResourcesBackend (which handles all ratings and reviews of resources) 0152 */ 0153 virtual AbstractReviewsBackend *reviewsBackend() const = 0; // FIXME: Have a standard impl which returns 0? 0154 0155 /** 0156 * @returns the class which is used by Discover to update the users system, if you are unsure what to do 0157 * just return the StandardBackendUpdater 0158 */ 0159 virtual AbstractBackendUpdater *backendUpdater() const = 0; // FIXME: Standard impl returning the standard updater? 0160 0161 /** 0162 * @returns the number of resources for which an update is available, it should only count technical packages 0163 */ 0164 virtual int updatesCount() const = 0; // FIXME: Probably provide a standard implementation?! 0165 0166 /** 0167 * @returns whether either of the updates contains a security fix 0168 */ 0169 virtual bool hasSecurityUpdates() const 0170 { 0171 return false; 0172 } 0173 0174 /** 0175 * Tells whether the backend is fetching resources 0176 */ 0177 virtual bool isFetching() const = 0; 0178 0179 /** 0180 * @returns the appstream ids that this backend extends 0181 */ 0182 virtual QStringList extends() const; 0183 0184 /** @returns the plugin's name */ 0185 QString name() const; 0186 0187 /** @internal only to be used by the factory */ 0188 void setName(const QString &name); 0189 0190 virtual QString displayName() const = 0; 0191 0192 /** 0193 * emits a change for all rating properties 0194 */ 0195 void emitRatingsReady(); 0196 0197 /** 0198 * @returns the root category tree 0199 */ 0200 virtual QVector<Category *> category() const 0201 { 0202 return {}; 0203 } 0204 0205 virtual bool hasApplications() const 0206 { 0207 return false; 0208 } 0209 0210 virtual int fetchingUpdatesProgress() const; 0211 0212 public Q_SLOTS: 0213 /** 0214 * This gets called when the backend should install an application. 0215 * The AbstractResourcesBackend should create a Transaction object, is returned and 0216 * will be included in the TransactionModel 0217 * @param app the application to be installed 0218 * @param addons the addons which should be installed with the application 0219 * @returns the Transaction that keeps track of the installation process 0220 */ 0221 virtual Transaction *installApplication(AbstractResource *app, const AddonList &addons) = 0; 0222 0223 /** 0224 * Overloaded function, which simply does the same, except not installing any addons. 0225 */ 0226 virtual Transaction *installApplication(AbstractResource *app); 0227 0228 /** 0229 * This gets called when the backend should remove an application. 0230 * Like in the installApplication() method, we'll return the Transaction 0231 * responsible for the removal. 0232 * 0233 * @see installApplication 0234 * @param app the application to be removed 0235 * @returns the Transaction that keeps track of the removal process 0236 */ 0237 virtual Transaction *removeApplication(AbstractResource *app) = 0; 0238 0239 /** 0240 * Notifies the backend that the user wants the information to be up to date 0241 */ 0242 virtual void checkForUpdates() = 0; 0243 0244 /** 0245 * Provides a guess why a search might not have offered satisfactory results 0246 */ 0247 Q_SCRIPTABLE virtual InlineMessage *explainDysfunction() const; 0248 0249 Q_SIGNALS: 0250 /** 0251 * Notify of a change in the backend 0252 */ 0253 void fetchingChanged(); 0254 0255 /** 0256 * This should be emitted when the number of upgradeable packages changed. 0257 */ 0258 void updatesCountChanged(); 0259 /** 0260 * This should be emitted when all data of the backends resources changed. Internally it will Q_EMIT 0261 * a signal in the model to show the view that all data of a certain backend changed. 0262 */ 0263 void allDataChanged(const QVector<QByteArray> &propertyNames); 0264 0265 /** 0266 * Allows to notify some @p properties in @p resource have changed 0267 */ 0268 void resourcesChanged(AbstractResource *resource, const QVector<QByteArray> &properties); 0269 void resourceRemoved(AbstractResource *resource); 0270 0271 void passiveMessage(const QString &message); 0272 void inlineMessageChanged(const QSharedPointer<InlineMessage> &inlineMessage); 0273 void fetchingUpdatesProgressChanged(); 0274 0275 private: 0276 QString m_name; 0277 }; 0278 0279 DISCOVERCOMMON_EXPORT QDebug operator<<(QDebug dbg, const AbstractResourcesBackend::Filters &filters); 0280 0281 /** 0282 * @internal Workaround because QPluginLoader enforces 1 instance per plugin 0283 */ 0284 class DISCOVERCOMMON_EXPORT AbstractResourcesBackendFactory : public QObject 0285 { 0286 Q_OBJECT 0287 public: 0288 virtual QVector<AbstractResourcesBackend *> newInstance(QObject *parent, const QString &name) const = 0; 0289 }; 0290 0291 #define DISCOVER_BACKEND_PLUGIN(ClassName) \ 0292 class ClassName##Factory : public AbstractResourcesBackendFactory \ 0293 { \ 0294 Q_OBJECT \ 0295 Q_PLUGIN_METADATA(IID "org.kde.muon.AbstractResourcesBackendFactory") \ 0296 Q_INTERFACES(AbstractResourcesBackendFactory) \ 0297 public: \ 0298 QVector<AbstractResourcesBackend *> newInstance(QObject *parent, const QString &name) const override \ 0299 { \ 0300 auto c = new ClassName(parent); \ 0301 c->setName(name); \ 0302 return {c}; \ 0303 } \ 0304 }; 0305 0306 Q_DECLARE_INTERFACE(AbstractResourcesBackendFactory, "org.kde.muon.AbstractResourcesBackendFactory")