1/*
2 SPDX-FileCopyrightText: 2016 Dan Leinir Turthra Jensen <admin@leinir.dk>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6
7#ifndef ENGINE_H
8#define ENGINE_H
9
10#include <QObject>
11#include <QQmlListProperty>
12
13#include "enginebase.h"
14#include "entry.h"
15#include "errorcode.h"
16#include "provider.h"
17#include "transaction.h"
18
19class EnginePrivate;
20
21/**
22 * KNSCore::EngineBase for interfacing with QML
23 *
24 * @see ItemsModel
25 */
26class Engine : public KNSCore::EngineBase
27{
28 Q_OBJECT
29 Q_PROPERTY(QString configFile READ configFile WRITE setConfigFile NOTIFY configFileChanged)
30 Q_PROPERTY(bool isLoading READ isLoading NOTIFY busyStateChanged)
31 Q_PROPERTY(bool needsLazyLoadSpinner READ needsLazyLoadSpinner NOTIFY busyStateChanged)
32 Q_PROPERTY(bool hasAdoptionCommand READ hasAdoptionCommand NOTIFY configFileChanged)
33 Q_PROPERTY(QString name READ name NOTIFY configFileChanged)
34 Q_PROPERTY(bool isValid READ isValid NOTIFY configFileChanged)
35
36 Q_PROPERTY(QObject *categories READ categories NOTIFY categoriesChanged)
37 Q_PROPERTY(QStringList categoriesFilter READ categoriesFilter WRITE setCategoriesFilter RESET resetCategoriesFilter NOTIFY categoriesFilterChanged)
38 Q_PROPERTY(KNSCore::Provider::Filter filter READ filter WRITE setFilter NOTIFY filterChanged)
39 Q_PROPERTY(KNSCore::Provider::SortMode sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
40 Q_PROPERTY(QString searchTerm READ searchTerm WRITE setSearchTerm RESET resetSearchTerm NOTIFY searchTermChanged)
41 Q_PROPERTY(QObject *searchPresetModel READ searchPresetModel NOTIFY searchPresetModelChanged)
42
43 /**
44 * Current state of the engine, the state con contain multiple operations
45 * an empty BusyState represents the idle status
46 * @since 5.74
47 */
48 Q_PROPERTY(BusyState busyState READ busyState WRITE setBusyState NOTIFY busyStateChanged)
49 Q_PROPERTY(QString busyMessage READ busyMessage NOTIFY busyStateChanged)
50public:
51 explicit Engine(QObject *parent = nullptr);
52 ~Engine() override;
53
54 enum class BusyOperation {
55 Initializing = 1,
56 LoadingData,
57 LoadingPreview,
58 InstallingEntry,
59 };
60 Q_DECLARE_FLAGS(BusyState, BusyOperation)
61 Q_ENUM(BusyOperation)
62
63 enum EntryEvent { // TODO KF6 remove in favor of using NewStuff.Entry values
64 UnknownEvent = KNSCore::Entry::UnknownEvent,
65 StatusChangedEvent = KNSCore::Entry::StatusChangedEvent,
66 AdoptedEvent = KNSCore::Entry::AdoptedEvent,
67 DetailsLoadedEvent = KNSCore::Entry::DetailsLoadedEvent,
68 };
69 Q_ENUM(EntryEvent)
70
71 QString configFile() const;
72 void setConfigFile(const QString &newFile);
73 Q_SIGNAL void configFileChanged();
74
75 Engine::BusyState busyState() const;
76 QString busyMessage() const;
77 void setBusyState(Engine::BusyState state);
78
79 /**
80 * Signal gets emitted when the busy state changes
81 * @since 5.74
82 */
83 Q_SIGNAL void busyStateChanged();
84
85 /**
86 * Whether or not the engine is performing its initial loading operations
87 * @since 5.65
88 */
89 bool isLoading() const
90 {
91 // When installing entries, we don't want to block the UI
92 return busyState().toInt() != 0 && ((busyState() & BusyOperation::InstallingEntry) != BusyOperation::InstallingEntry);
93 }
94
95 QObject *categories() const;
96 Q_SIGNAL void categoriesChanged();
97
98 QStringList categoriesFilter() const;
99 void setCategoriesFilter(const QStringList &newCategoriesFilter);
100 Q_INVOKABLE void resetCategoriesFilter()
101 {
102 setCategoriesFilter(categoriesFilter());
103 }
104 Q_SIGNAL void categoriesFilterChanged();
105
106 KNSCore::Provider::Filter filter() const;
107 void setFilter(KNSCore::Provider::Filter filter);
108 Q_SIGNAL void filterChanged();
109
110 KNSCore::Provider::SortMode sortOrder() const;
111 void setSortOrder(KNSCore::Provider::SortMode newSortOrder);
112 Q_SIGNAL void sortOrderChanged();
113
114 QString searchTerm() const;
115 void setSearchTerm(const QString &newSearchTerm);
116 Q_INVOKABLE void resetSearchTerm()
117 {
118 setSearchTerm(QString());
119 }
120 Q_SIGNAL void searchTermChanged();
121
122 QObject *searchPresetModel() const;
123 Q_SIGNAL void searchPresetModelChanged();
124
125 Q_INVOKABLE void updateEntryContents(const KNSCore::Entry &entry);
126 Q_INVOKABLE KNSCore::Entry __createEntry(const QString &providerId, const QString &entryId)
127 {
128 KNSCore::Entry e;
129 e.setProviderId(providerId);
130 e.setUniqueId(entryId);
131 return e;
132 }
133
134 bool isValid();
135 void reloadEntries();
136
137 void loadPreview(const KNSCore::Entry &entry, KNSCore::Entry::PreviewType type);
138
139 void addProvider(QSharedPointer<KNSCore::Provider> provider) override;
140
141 /**
142 * Adopt an entry using the adoption command. This will also take care of displaying error messages
143 * @param entry Entry that should be adopted
144 * @see signalErrorCode
145 * @see signalEntryEvent
146 * @since 5.77
147 */
148 Q_INVOKABLE void adoptEntry(const KNSCore::Entry &entry);
149
150 /**
151 * Installs an entry's payload file. This includes verification, if
152 * necessary, as well as decompression and other steps according to the
153 * application's *.knsrc file.
154 *
155 * @param entry Entry to be installed
156 *
157 * @see signalInstallationFinished
158 * @see signalInstallationFailed
159 */
160 Q_INVOKABLE void install(const KNSCore::Entry &entry, int linkId = 1);
161
162 /**
163 * Uninstalls an entry. It reverses the steps which were performed
164 * during the installation.
165 *
166 * @param entry The entry to deinstall
167 */
168 Q_INVOKABLE void uninstall(const KNSCore::Entry &entry);
169
170 void requestMoreData();
171
172 Q_INVOKABLE void revalidateCacheEntries();
173 Q_INVOKABLE void restoreSearch();
174 Q_INVOKABLE void storeSearch();
175Q_SIGNALS:
176 void signalResetView();
177
178 /**
179 * This is fired for events related directly to a single Entry instance
180 * The intermediate states Updating and Installing are not forwarded. In case you
181 * need those you have to listen to the signals of the KNSCore::Engine instance of the engine property.
182 *
183 * As an example, if you need to know when the status of an entry changes, you might write:
184 \code
185 function onEntryEvent(entry, event) {
186 if (event == NewStuff.Engine.StatusChangedEvent) {
187 myModel.ghnsEntryChanged(entry);
188 }
189 }
190 \endcode
191 *
192 * nb: The above example is also how one would port a handler for the old changedEntries signal
193 *
194 * @see Entry::EntryEvent for details on which specific event is being notified
195 */
196 void entryEvent(const KNSCore::Entry &entry, KNSCore::Entry::EntryEvent event);
197
198 /**
199 * Fires in the case of any critical or serious errors, such as network or API problems.
200 * This forwards the signal from KNSCore::Engine::signalErrorCode, but with QML friendly
201 * enumerations.
202 * @param errorCode Represents the specific type of error which has occurred
203 * @param message A human-readable message which can be shown to the end user
204 * @param metadata Any additional data which might be hepful to further work out the details of the error (see KNSCore::Entry::ErrorCode for the
205 * metadata details)
206 * @see KNSCore::Engine::signalErrorCode
207 * @since 5.84
208 */
209 void errorCode(KNSCore::ErrorCode::ErrorCode errorCode, const QString &message, const QVariant &metadata);
210
211 void entryPreviewLoaded(const KNSCore::Entry &, KNSCore::Entry::PreviewType);
212
213 void signalEntriesLoaded(const KNSCore::Entry::List &entries); ///@internal
214 void signalEntryEvent(const KNSCore::Entry &entry, KNSCore::Entry::EntryEvent event); ///@internal
215
216private:
217 bool init(const QString &configfile) override;
218 void updateStatus() override;
219 bool needsLazyLoadSpinner();
220 Q_SIGNAL void signalEntryPreviewLoaded(const KNSCore::Entry &, KNSCore::Entry::PreviewType);
221 void registerTransaction(KNSCore::Transaction *transactions);
222 void doRequest();
223 const std::unique_ptr<EnginePrivate> d;
224};
225
226#endif // ENGINE_H
227

source code of knewstuff/src/qtquick/quickengine.h