File indexing completed on 2024-11-10 04:40:30

0001 /*
0002     SPDX-FileCopyrightText: 2006-2007 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "akonadicore_export.h"
0010 #include "item.h"
0011 #include "job.h"
0012 
0013 namespace Akonadi
0014 {
0015 class Collection;
0016 class ItemFetchJobPrivate;
0017 class ItemFetchScope;
0018 
0019 /**
0020  * @short Job that fetches items from the Akonadi storage.
0021  *
0022  * This class is used to fetch items from the Akonadi storage.
0023  * Which parts of the items (e.g. headers only, attachments or all)
0024  * can be specified by the ItemFetchScope.
0025  *
0026  * Note that ItemFetchJob does not refresh the Akonadi storage from the
0027  * backend; this is unnecessary due to the fact that backend updates
0028  * automatically trigger an update to the Akonadi database whenever they occur
0029  * (unless the resource is offline).
0030  *
0031  * Note that items can not be created in the root collection (Collection::root())
0032  * and therefore can not be fetched from there either. That is - an item fetch in
0033  * the root collection will yield an empty list.
0034  *
0035  *
0036  * Example:
0037  *
0038  * @code
0039  *
0040  * // Fetch all items with full payload from a collection
0041  *
0042  * const Collection collection = getCollection();
0043  *
0044  * Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(collection);
0045  * connect(job, SIGNAL(result(KJob*)), SLOT(jobFinished(KJob*)));
0046  * job->fetchScope().fetchFullPayload();
0047  *
0048  * ...
0049  *
0050  * MyClass::jobFinished(KJob *job)
0051  * {
0052  *   if (job->error()) {
0053  *     qDebug() << "Error occurred";
0054  *     return;
0055  *   }
0056  *
0057  *   Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob*>(job);
0058  *
0059  *   const Akonadi::Item::List items = fetchJob->items();
0060  *   for (const Akonadi::Item &item : items) {
0061  *     qDebug() << "Item ID:" << item.id();
0062  *   }
0063  * }
0064  *
0065  * @endcode
0066  *
0067  * @author Volker Krause <vkrause@kde.org>
0068  */
0069 class AKONADICORE_EXPORT ItemFetchJob : public Job
0070 {
0071     Q_OBJECT
0072     Q_FLAGS(DeliveryOptions)
0073 public:
0074     /**
0075      * Creates a new item fetch job that retrieves all items inside the given collection.
0076      *
0077      * @param collection The parent collection to fetch all items from.
0078      * @param parent The parent object.
0079      */
0080     explicit ItemFetchJob(const Collection &collection, QObject *parent = nullptr);
0081 
0082     /**
0083      * Creates a new item fetch job that retrieves the specified item.
0084      * If the item has a uid set, this is used to identify the item on the Akonadi
0085      * server. If only a remote identifier is available, that is used.
0086      * However, as remote identifiers are not necessarily globally unique, you
0087      * need to specify the collection to search in in that case, using
0088      * setCollection().
0089      *
0090      * @internal
0091      * For internal use only when using remote identifiers, the resource search
0092      * context can be set globally by ResourceSelectJob.
0093      * @endinternal
0094      *
0095      * @param item The item to fetch.
0096      * @param parent The parent object.
0097      */
0098     explicit ItemFetchJob(const Item &item, QObject *parent = nullptr);
0099 
0100     /**
0101      * Creates a new item fetch job that retrieves the specified items.
0102      * If the items have a uid set, this is used to identify the item on the Akonadi
0103      * server. If only a remote identifier is available, that is used.
0104      * However, as remote identifiers are not necessarily globally unique, you
0105      * need to specify the collection to search in in that case, using
0106      * setCollection().
0107      *
0108      * @internal
0109      * For internal use only when using remote identifiers, the resource search
0110      * context can be set globally by ResourceSelectJob.
0111      * @endinternal
0112      *
0113      * @param items The items to fetch.
0114      * @param parent The parent object.
0115      * @since 4.4
0116      */
0117     explicit ItemFetchJob(const Item::List &items, QObject *parent = nullptr);
0118 
0119     /**
0120      * Convenience ctor equivalent to ItemFetchJob(const Item::List &items, QObject *parent = nullptr)
0121      * @since 4.8
0122      */
0123     explicit ItemFetchJob(const QList<Item::Id> &items, QObject *parent = nullptr);
0124     /**
0125      * Creates a new item fetch job that retrieves all items tagged with specified @p tag.
0126      *
0127      * @param tag The tag to fetch all items from.
0128      * @param parent The parent object.
0129      *
0130      * @since 4.14
0131      */
0132     explicit ItemFetchJob(const Tag &tag, QObject *parent = nullptr);
0133 
0134     /**
0135      * Destroys the item fetch job.
0136      */
0137     ~ItemFetchJob() override;
0138 
0139     /**
0140      * Returns the fetched items.
0141      *
0142      * This returns an empty list when not using the ItemGetter DeliveryOption.
0143      *
0144      * @note The items are invalid before the result(KJob*)
0145      *       signal has been emitted or if an error occurred.
0146      */
0147     [[nodiscard]] Item::List items() const;
0148 
0149     /**
0150      * Save memory by clearing the fetched items.
0151      * @since 4.12
0152      */
0153     void clearItems();
0154 
0155     /**
0156      * Sets the item fetch scope.
0157      *
0158      * The ItemFetchScope controls how much of an item's data is fetched
0159      * from the server, e.g. whether to fetch the full item payload or
0160      * only meta data.
0161      *
0162      * @param fetchScope The new scope for item fetch operations.
0163      *
0164      * @see fetchScope()
0165      * @since 4.4
0166      */
0167     void setFetchScope(const ItemFetchScope &fetchScope);
0168 
0169     /**
0170      * Returns the item fetch scope.
0171      *
0172      * Since this returns a reference it can be used to conveniently modify the
0173      * current scope in-place, i.e. by calling a method on the returned reference
0174      * without storing it in a local variable. See the ItemFetchScope documentation
0175      * for an example.
0176      *
0177      * @return a reference to the current item fetch scope
0178      *
0179      * @see setFetchScope() for replacing the current item fetch scope
0180      */
0181     ItemFetchScope &fetchScope();
0182 
0183     /**
0184      * Specifies the collection the item is in.
0185      * This is only required when retrieving an item based on its remote id
0186      * which might not be unique globally.
0187      *
0188      * @internal
0189      * @see ResourceSelectJob (for internal use only)
0190      * @endinternal
0191      */
0192     void setCollection(const Collection &collection);
0193 
0194     enum DeliveryOption {
0195         ItemGetter = 0x1, ///< items available through items()
0196         EmitItemsIndividually = 0x2, ///< emitted via signal upon reception
0197         EmitItemsInBatches = 0x4, ///< emitted via signal in bulk (collected and emitted delayed via timer)
0198         Default = ItemGetter | EmitItemsInBatches
0199     };
0200     Q_DECLARE_FLAGS(DeliveryOptions, DeliveryOption)
0201 
0202     /**
0203      * Sets the mechanisms by which the items should be fetched
0204      * @since 4.13
0205      */
0206     void setDeliveryOption(DeliveryOptions options);
0207 
0208     /**
0209      * Returns the delivery options
0210      * @since 4.13
0211      */
0212     DeliveryOptions deliveryOptions() const;
0213 
0214     /**
0215      * Returns the total number of retrieved items.
0216      * This works also without the ItemGetter DeliveryOption.
0217      * @since 4.14
0218      */
0219     int count() const;
0220 
0221     /**
0222      * Sets the limit of fetched items.
0223      *
0224      * @param limit the maximum number of items to retrieve.
0225      * The default value for @p limit is -1, indicating no limit.
0226      * @param start specifies the offset of the first item to retrieve.
0227      * @param order specifies whether items will be fetched
0228      * starting with the highest or lowest ID of the item.
0229      */
0230 
0231     void setLimit(int limit, int start, Qt::SortOrder order = Qt::DescendingOrder);
0232 
0233 Q_SIGNALS:
0234     /**
0235      * This signal is emitted whenever new items have been fetched completely.
0236      *
0237      * @note This is an optimization; instead of waiting for the end of the job
0238      *       and calling items(), you can connect to this signal and get the items
0239      *       incrementally.
0240      *
0241      * @param items The fetched items.
0242      */
0243     void itemsReceived(const Akonadi::Item::List &items);
0244 
0245 protected:
0246     void doStart() override;
0247     bool doHandleResponse(qint64 tag, const Protocol::CommandPtr &response) override;
0248 
0249 private:
0250     Q_DECLARE_PRIVATE(ItemFetchJob)
0251 };
0252 
0253 }
0254 
0255 Q_DECLARE_OPERATORS_FOR_FLAGS(Akonadi::ItemFetchJob::DeliveryOptions)