1 | /* |
2 | knewstuff3/provider.h |
3 | This file is part of KNewStuff2. |
4 | SPDX-FileCopyrightText: 2009 Jeremy Whiting <jpwhiting@kde.org> |
5 | SPDX-FileCopyrightText: 2009 Frederik Gladhorn <gladhorn@kde.org> |
6 | SPDX-FileCopyrightText: 2021 Dan Leinir Turthra Jensen <admin@leinir.dk> |
7 | |
8 | SPDX-License-Identifier: LGPL-2.1-or-later |
9 | */ |
10 | |
11 | #ifndef KNEWSTUFF3_PROVIDER_P_H |
12 | #define KNEWSTUFF3_PROVIDER_P_H |
13 | |
14 | #include <QDebug> |
15 | #include <QList> |
16 | #include <QString> |
17 | #include <QUrl> |
18 | |
19 | #include <memory> |
20 | |
21 | #include "entry.h" |
22 | #include "errorcode.h" |
23 | |
24 | #include "knewstuffcore_export.h" |
25 | |
26 | namespace KNSCore |
27 | { |
28 | class ProviderPrivate; |
29 | struct ; |
30 | |
31 | /*! |
32 | * \class KNSCore::Provider |
33 | * \inheaderfile KNewStuff/Provider |
34 | * \inmodule KNewStuffCore |
35 | * |
36 | * \brief Base Provider class. |
37 | * |
38 | * This class provides accessors for the provider object. |
39 | * |
40 | * \note This class should not be used directly by the application. |
41 | * This class is the base class and will be instantiated for |
42 | * static website providers. |
43 | * |
44 | * \deprecated[6.9] Use ProviderBase to implement providers (only in-tree supported). Use ProviderCore to manage instances of base. |
45 | */ |
46 | class KNEWSTUFFCORE_EXPORT |
47 | KNEWSTUFFCORE_DEPRECATED_VERSION(6, |
48 | 9, |
49 | "Use ProviderBase to implement providers (only in-tree supported). Use ProviderCore to manage instances of base." ) Provider |
50 | : public QObject |
51 | { |
52 | Q_OBJECT |
53 | |
54 | /*! |
55 | * \qmlproperty string Provider::version |
56 | */ |
57 | /*! |
58 | * \property KNSCore::Provider::version |
59 | */ |
60 | Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY basicsLoaded) |
61 | |
62 | /*! |
63 | * \qmlproperty url Provider::website |
64 | */ |
65 | /*! |
66 | * \property KNSCore::Provider::website |
67 | */ |
68 | Q_PROPERTY(QUrl website READ website WRITE setWebsite NOTIFY basicsLoaded) |
69 | |
70 | /*! |
71 | * \qmlproperty url Provider::host |
72 | */ |
73 | /*! |
74 | * \property KNSCore::Provider::host |
75 | */ |
76 | Q_PROPERTY(QUrl host READ host WRITE setHost NOTIFY basicsLoaded) |
77 | |
78 | /*! |
79 | * \qmlproperty string Provider::contactEmail |
80 | */ |
81 | /*! |
82 | * \property KNSCore::Provider::contactEmail |
83 | */ |
84 | Q_PROPERTY(QString contactEmail READ contactEmail WRITE setContactEmail NOTIFY basicsLoaded) |
85 | |
86 | /*! |
87 | * \qmlproperty bool Provider::supportsSsl |
88 | */ |
89 | /*! |
90 | * \property KNSCore::Provider::supportsSsl |
91 | */ |
92 | Q_PROPERTY(bool supportsSsl READ supportsSsl WRITE setSupportsSsl NOTIFY basicsLoaded) |
93 | public: |
94 | typedef QList<Provider *> List; |
95 | |
96 | /*! |
97 | * \enum KNSCore::Provider::SortMode |
98 | * |
99 | * \value Newest |
100 | * \value Alphabetical |
101 | * \value Rating |
102 | * \value Downloads |
103 | */ |
104 | enum SortMode { |
105 | Newest, |
106 | Alphabetical, |
107 | Rating, |
108 | Downloads, |
109 | }; |
110 | Q_ENUM(SortMode) |
111 | |
112 | /*! |
113 | * KNSCore::Provider::Filter |
114 | * |
115 | * \value None |
116 | * \value Installed |
117 | * \value Updates |
118 | * \value ExactEntryId |
119 | */ |
120 | enum Filter { |
121 | None, |
122 | Installed, |
123 | Updates, |
124 | ExactEntryId, |
125 | }; |
126 | Q_ENUM(Filter) |
127 | |
128 | /*! |
129 | * used to keep track of a search |
130 | * \deprecated[6.9] |
131 | * Use KNSCore::SearchRequest |
132 | */ |
133 | struct KNEWSTUFFCORE_DEPRECATED_VERSION(6, 9, "Use KNSCore::SearchRequest" ) SearchRequest { |
134 | SortMode sortMode; |
135 | Filter filter; |
136 | QString searchTerm; |
137 | QStringList categories; |
138 | int page; |
139 | int pageSize; |
140 | |
141 | SearchRequest(SortMode sortMode_ = Downloads, |
142 | Filter filter_ = None, |
143 | const QString &searchTerm_ = QString(), |
144 | const QStringList &categories_ = QStringList(), |
145 | int page_ = 0, |
146 | int pageSize_ = 20) |
147 | : sortMode(sortMode_) |
148 | , filter(filter_) |
149 | , searchTerm(searchTerm_) |
150 | , categories(categories_) |
151 | , page(page_) |
152 | , pageSize(pageSize_) |
153 | { |
154 | } |
155 | |
156 | QString hashForRequest() const; |
157 | bool operator==(const SearchRequest &other) const |
158 | { |
159 | return sortMode == other.sortMode && filter == other.filter && searchTerm == other.searchTerm && categories == other.categories |
160 | && page == other.page && pageSize == other.pageSize; |
161 | } |
162 | }; |
163 | |
164 | /*! |
165 | * Describes a category: id/name/displayName |
166 | * \deprecated[6.9] |
167 | * \inmodule KNewStuffCore |
168 | * Use KNSCore::CategoryMetadata |
169 | */ |
170 | struct KNEWSTUFFCORE_DEPRECATED_VERSION(6, 9, "Use KNSCore::CategoryMetadata" ) CategoryMetadata { |
171 | /*! |
172 | * |
173 | */ |
174 | QString id; |
175 | |
176 | /*! |
177 | * |
178 | */ |
179 | QString name; |
180 | |
181 | /*! |
182 | * The human-readable name displayed to the user. |
183 | */ |
184 | QString displayName; |
185 | }; |
186 | |
187 | /*! |
188 | * \enum KNSCore::Provider::SearchPresetTypes |
189 | * \brief A helper to identify the kind of label and icon |
190 | * the search preset should have if none are found. |
191 | * \deprecated[6.9] |
192 | * Use KNSCore::SearchPreset::SearchPresetTypes |
193 | * |
194 | * \since 5.83 |
195 | * |
196 | * \value NoPresetType |
197 | * |
198 | * \value GoBack |
199 | * Preset representing the previous search. |
200 | * |
201 | * \value Root |
202 | * Preset indicating a root directory. |
203 | * |
204 | * \value Start |
205 | * Preset indicating the first entry. |
206 | * |
207 | * \value Popular |
208 | * Preset indicating popular items. |
209 | * |
210 | * \value Featured |
211 | * Preset for featured items. |
212 | * |
213 | * \value Recommended |
214 | * Preset for recommended. This may be customized by the server per user. |
215 | * |
216 | * \value Shelf |
217 | * Preset indicating previously acquired items. |
218 | * |
219 | * \value Subscription |
220 | * Preset indicating items that the user is subscribed to. |
221 | * |
222 | * \value New |
223 | * Preset indicating new items. |
224 | * |
225 | * \value FolderUp |
226 | * Preset indicating going up in the search result hierarchy. |
227 | * |
228 | * \value AllEntries |
229 | * Preset indicating all possible entries, such as a crawlable list. Might be intense to load. |
230 | */ |
231 | enum KNEWSTUFFCORE_DEPRECATED_VERSION(6, 9, "Use KNSCore::SearchPreset::SearchPresetTypes" ) SearchPresetTypes { |
232 | NoPresetType = 0, |
233 | GoBack, |
234 | Root, |
235 | Start, |
236 | Popular, |
237 | Featured, |
238 | Recommended, |
239 | Shelf, |
240 | Subscription, |
241 | New, |
242 | FolderUp, |
243 | AllEntries, |
244 | }; |
245 | /*! |
246 | * \class KNSCore::Provider::SearchPreset |
247 | * \inmodule KNewStuffCore |
248 | * \brief Describes a search request that may come from the provider. |
249 | * This is used by the OPDS provider to handle the different urls. |
250 | * \deprecated[6.9] |
251 | * Use KNSCore::SearchPreset |
252 | */ |
253 | struct KNEWSTUFFCORE_DEPRECATED_VERSION(6, 9, "Use KNSCore::SearchPreset" ) SearchPreset { |
254 | SearchRequest request; |
255 | QString displayName; |
256 | QString iconName; |
257 | SearchPresetTypes type; |
258 | QString providerId; // not all providers can handle all search requests. |
259 | }; |
260 | |
261 | /*! |
262 | * Constructor. |
263 | */ |
264 | Provider(); |
265 | |
266 | ~Provider() override; |
267 | |
268 | /*! |
269 | * A unique Id for this provider (the url in most cases) |
270 | */ |
271 | virtual QString id() const = 0; |
272 | |
273 | /*! |
274 | * Sets the provider \a xmldata to initialize the provider. |
275 | * The Provider needs to have it's ID set in this function and cannot change it from there on. |
276 | * |
277 | * Returns true if successful, or false if the XML data is invalid |
278 | */ |
279 | virtual bool setProviderXML(const QDomElement &xmldata) = 0; |
280 | |
281 | /*! |
282 | * |
283 | */ |
284 | virtual bool isInitialized() const = 0; |
285 | |
286 | /*! |
287 | * |
288 | */ |
289 | virtual void setCachedEntries(const KNSCore::Entry::List &cachedEntries) = 0; |
290 | |
291 | /*! |
292 | * Returns the common name of the provider. |
293 | */ |
294 | virtual QString name() const; |
295 | |
296 | /*! |
297 | * Returns the icon URL for this provider. |
298 | */ |
299 | virtual QUrl icon() const; // FIXME use QIcon::fromTheme or pixmap? |
300 | |
301 | /*! |
302 | * Loads the given search and return given page |
303 | * |
304 | * \a request defines the search parameters |
305 | * |
306 | * \note the engine connects to loadingFinished() signal to get the result |
307 | */ |
308 | virtual void loadEntries(const KNSCore::Provider::SearchRequest &request) = 0; |
309 | |
310 | /*! |
311 | * |
312 | */ |
313 | virtual void loadEntryDetails(const KNSCore::Entry &) |
314 | { |
315 | } |
316 | |
317 | /*! |
318 | * |
319 | */ |
320 | virtual void loadPayloadLink(const Entry &entry, int linkId) = 0; |
321 | |
322 | /*! |
323 | * Request a loading of comments from this provider. The engine listens to the |
324 | * commentsLoaded() signal for the result |
325 | * |
326 | * \note Implementation detail: All subclasses should connect to this signal |
327 | * and point it at a slot which does the actual work, if they support comments. |
328 | * |
329 | * \sa commentsLoaded |
330 | * \since 5.63 |
331 | */ |
332 | virtual void (const KNSCore::Entry &, int /*commentsPerPage*/, int /*page*/) |
333 | { |
334 | } |
335 | |
336 | /*! |
337 | * Request loading of the details for a specific person with the given username. |
338 | * The engine listens to the personLoaded() for the result |
339 | * |
340 | * \note Implementation detail: All subclasses should connect to this signal |
341 | * and point it at a slot which does the actual work, if they support comments. |
342 | * |
343 | * \since 5.63 |
344 | */ |
345 | virtual void loadPerson(const QString & /*username*/) |
346 | { |
347 | } |
348 | |
349 | /*! |
350 | * Request loading of the basic information for this provider. The engine listens |
351 | * to the basicsLoaded() signal for the result, which is also the signal the respective |
352 | * properties listen to. |
353 | * |
354 | * This is fired automatically on the first attempt to read one of the properties |
355 | * which contain this basic information, and you will not need to call it as a user |
356 | * of the class (just listen to the properties, which will update when the information |
357 | * has been fetched). |
358 | * |
359 | * \note Implementation detail: All subclasses should connect to this signal |
360 | * and point it at a slot which does the actual work, if they support fetching |
361 | * this basic information (if the information is set during construction, you will |
362 | * not need to worry about this). |
363 | * |
364 | * \sa version() |
365 | * \sa website() |
366 | * \sa host() |
367 | * \sa contactEmail() |
368 | * \sa supportsSsl() |
369 | * \since 5.85 |
370 | */ |
371 | virtual void loadBasics() |
372 | { |
373 | } |
374 | |
375 | /*! |
376 | * \since 5.85 |
377 | */ |
378 | QString version() const; |
379 | |
380 | /*! |
381 | * Sets the \a version. |
382 | * \since 5.85 |
383 | */ |
384 | void setVersion(const QString &version); |
385 | |
386 | /*! |
387 | * \since 5.85 |
388 | */ |
389 | QUrl website() const; |
390 | |
391 | /*! |
392 | * Sets the \a website URL. |
393 | * \since 5.85 |
394 | */ |
395 | void setWebsite(const QUrl &website); |
396 | |
397 | /*! |
398 | * \since 5.85 |
399 | */ |
400 | QUrl host() const; |
401 | |
402 | /*! |
403 | * Sets the host used for this provider to \a host. |
404 | * |
405 | * \since 5.85 |
406 | */ |
407 | void setHost(const QUrl &host); |
408 | |
409 | /*! |
410 | * Returns The general contact email for this provider. |
411 | * \since 5.85 |
412 | */ |
413 | QString contactEmail() const; |
414 | |
415 | /*! |
416 | * Sets the general contact email address for this provider. |
417 | * |
418 | * \a contactEmail The general contact email for this provider |
419 | * |
420 | * \since 5.85 |
421 | */ |
422 | void setContactEmail(const QString &contactEmail); |
423 | |
424 | /*! |
425 | * Returns True if the server supports SSL connections, false if not |
426 | * \since 5.85 |
427 | */ |
428 | bool supportsSsl() const; |
429 | |
430 | /*! |
431 | * Sets whether or not the provider supports SSL connections. |
432 | * |
433 | * \a supportsSsl True if the server supports SSL connections, false if not |
434 | * |
435 | * \since 5.85 |
436 | */ |
437 | void setSupportsSsl(bool supportsSsl); |
438 | |
439 | /*! |
440 | * |
441 | */ |
442 | virtual bool userCanVote() |
443 | { |
444 | return false; |
445 | } |
446 | |
447 | /*! |
448 | * |
449 | */ |
450 | virtual void vote(const Entry & /*entry*/, uint /*rating*/) |
451 | { |
452 | } |
453 | |
454 | /*! |
455 | * |
456 | */ |
457 | virtual bool userCanBecomeFan() |
458 | { |
459 | return false; |
460 | } |
461 | |
462 | /*! |
463 | * |
464 | */ |
465 | virtual void becomeFan(const Entry & /*entry*/) |
466 | { |
467 | } |
468 | |
469 | /*! |
470 | * Sets the tag filter used for entries by this provider. |
471 | * |
472 | * \a tagFilter The new list of filters |
473 | * |
474 | * \sa EngineBase::setTagFilter |
475 | * \since 5.51 |
476 | */ |
477 | void setTagFilter(const QStringList &tagFilter); |
478 | |
479 | /*! |
480 | * Returns the tag filter used for downloads by this provider. |
481 | * \sa EngineBase::setTagFilter |
482 | * \since 5.51 |
483 | */ |
484 | QStringList tagFilter() const; |
485 | |
486 | /*! |
487 | * Sets the tag filter used for download items by this provider |
488 | * |
489 | * \a downloadTagFilter The new list of filters |
490 | * |
491 | * \sa EngineBase::setDownloadTagFilter |
492 | * \since 5.51 |
493 | */ |
494 | void setDownloadTagFilter(const QStringList &downloadTagFilter); |
495 | |
496 | /*! |
497 | * Returns the tag filter used for downloads by this provider. |
498 | * \sa EngineBase::setDownloadTagFilter |
499 | * \since 5.51 |
500 | */ |
501 | QStringList downloadTagFilter() const; |
502 | |
503 | Q_SIGNALS: |
504 | /*! |
505 | * |
506 | */ |
507 | void providerInitialized(KNSCore::Provider *); |
508 | |
509 | /*! |
510 | * |
511 | */ |
512 | void loadingFinished(const KNSCore::Provider::SearchRequest &, const KNSCore::Entry::List &); |
513 | |
514 | /*! |
515 | * |
516 | */ |
517 | void loadingFailed(const KNSCore::Provider::SearchRequest &); |
518 | |
519 | /*! |
520 | * |
521 | */ |
522 | void entryDetailsLoaded(const KNSCore::Entry &); |
523 | |
524 | /*! |
525 | * |
526 | */ |
527 | void payloadLinkLoaded(const KNSCore::Entry &); |
528 | |
529 | /*! |
530 | * Fired when new comments have been loaded |
531 | * |
532 | * \a comments The list of newly loaded comments, in a depth-first order |
533 | * |
534 | * \since 5.63 |
535 | */ |
536 | void (const QList<std::shared_ptr<KNSCore::Comment>> ); |
537 | |
538 | /*! |
539 | * Fired when the details of a person have been loaded |
540 | * |
541 | * \a author The person we've just loaded data for |
542 | * |
543 | * \since 5.63 |
544 | */ |
545 | void personLoaded(const std::shared_ptr<KNSCore::Author> author); |
546 | /*! |
547 | * Fired when the provider's basic information has been fetched and updated |
548 | * \since 5.85 |
549 | */ |
550 | void basicsLoaded(); |
551 | |
552 | /*! |
553 | * Fires when the provider has loaded search \a presets. These represent interesting |
554 | * searches for the user, such as recommendations. |
555 | * \since 5.83 |
556 | */ |
557 | void searchPresetsLoaded(const QList<KNSCore::Provider::SearchPreset> &presets); |
558 | |
559 | /*! |
560 | * |
561 | */ |
562 | void signalInformation(const QString &); |
563 | |
564 | /*! |
565 | * |
566 | */ |
567 | void signalError(const QString &); |
568 | |
569 | /*! |
570 | * |
571 | */ |
572 | void signalErrorCode(KNSCore::ErrorCode::ErrorCode errorCode, const QString &message, const QVariant &metadata); |
573 | |
574 | /*! |
575 | * |
576 | */ |
577 | void categoriesMetadataLoded(const QList<KNSCore::Provider::CategoryMetadata> &categories); |
578 | |
579 | /*! |
580 | * |
581 | */ |
582 | void tagFilterChanged(); |
583 | |
584 | /*! |
585 | * |
586 | */ |
587 | void downloadTagFilterChanged(); |
588 | |
589 | protected: |
590 | /*! |
591 | * |
592 | */ |
593 | void setName(const QString &name); |
594 | /*! |
595 | * |
596 | */ |
597 | void setIcon(const QUrl &icon); |
598 | |
599 | private: |
600 | friend class ProviderBubbleWrap; |
601 | const std::unique_ptr<ProviderPrivate> d; |
602 | Q_DISABLE_COPY(Provider) |
603 | }; |
604 | |
605 | KNEWSTUFFCORE_EXPORT QDebug operator<<(QDebug, const Provider::SearchRequest &); |
606 | } |
607 | |
608 | #endif |
609 | |