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 | |
19 | class EnginePrivate; |
20 | |
21 | /** |
22 | * KNSCore::EngineBase for interfacing with QML |
23 | * |
24 | * @see ItemsModel |
25 | */ |
26 | class 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) |
50 | public: |
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(); |
175 | Q_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 | |
216 | private: |
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 | |