File indexing completed on 2024-11-10 04:40:30
0001 /* 0002 SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@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 "collection.h" 0011 #include "item.h" 0012 #include "job.h" 0013 0014 namespace Akonadi 0015 { 0016 class TagFetchScope; 0017 class ItemFetchScope; 0018 class ItemSearchJobPrivate; 0019 class SearchQuery; 0020 0021 /** 0022 * @short Job that searches for items in the Akonadi storage. 0023 * 0024 * This job searches for items that match a given search query and returns 0025 * the list of matching item. 0026 * 0027 * @code 0028 * 0029 * SearchQuery query; 0030 * query.addTerm(SearchTerm("From", "user1@domain.example", SearchTerm::CondEqual)); 0031 * query.addTerm(SearchTerm("Date", QDateTime(QDate( 2014, 01, 27), QTime(00, 00, 00)), SearchTerm::CondGreaterThan); 0032 * 0033 * auto job = new Akonadi::ItemSearchJob(query); 0034 * job->fetchScope().fetchFullPayload(); 0035 * connect(job, &Akonadi::ItemSearchJob::result, this, &MyClass::searchResult)); 0036 * 0037 * ... 0038 * 0039 * MyClass::searchResult(KJob *job) 0040 * { 0041 * auto searchJob = qobject_cast<Akonadi::ItemSearchJob*>(job); 0042 * const Akonadi::Item::List items = searchJob->items(); 0043 * for (const Akonadi::Item &item : items) { 0044 * // extract the payload and do further stuff 0045 * } 0046 * } 0047 * 0048 * @endcode 0049 * 0050 * @author Tobias Koenig <tokoe@kde.org> 0051 * @since 4.4 0052 */ 0053 class AKONADICORE_EXPORT ItemSearchJob : public Job 0054 { 0055 Q_OBJECT 0056 0057 public: 0058 /** 0059 * Creates an invalid search job. 0060 * 0061 * @param parent The parent object. 0062 * @since 5.1 0063 */ 0064 explicit ItemSearchJob(QObject *parent = nullptr); 0065 0066 /** 0067 * Creates an item search job. 0068 * 0069 * @param query The search query. 0070 * @param parent The parent object. 0071 * @since 4.13 0072 */ 0073 explicit ItemSearchJob(const SearchQuery &query, QObject *parent = nullptr); 0074 0075 /** 0076 * Destroys the item search job. 0077 */ 0078 ~ItemSearchJob() override; 0079 0080 /** 0081 * Sets the search @p query. 0082 * 0083 * @since 4.13 0084 */ 0085 void setQuery(const SearchQuery &query); 0086 0087 /** 0088 * Sets the item fetch scope. 0089 * 0090 * The ItemFetchScope controls how much of an matching item's data is fetched 0091 * from the server, e.g. whether to fetch the full item payload or 0092 * only meta data. 0093 * 0094 * @param fetchScope The new scope for item fetch operations. 0095 * 0096 * @see fetchScope() 0097 */ 0098 void setFetchScope(const ItemFetchScope &fetchScope); 0099 0100 /** 0101 * Returns the item fetch scope. 0102 * 0103 * Since this returns a reference it can be used to conveniently modify the 0104 * current scope in-place, i.e. by calling a method on the returned reference 0105 * without storing it in a local variable. See the ItemFetchScope documentation 0106 * for an example. 0107 * 0108 * @return a reference to the current item fetch scope 0109 * 0110 * @see setFetchScope() for replacing the current item fetch scope 0111 */ 0112 ItemFetchScope &fetchScope(); 0113 0114 /** 0115 * Sets the tag fetch scope. 0116 * 0117 * The tag fetch scope affects what scope of tags for each Item will be 0118 * retrieved. 0119 */ 0120 void setTagFetchScope(const TagFetchScope &fetchScope); 0121 0122 /** 0123 * Returns the tag fetch scope. 0124 * 0125 * Since this returns a reference it can be used to conveniently modify 0126 * the current scope in-place. 0127 */ 0128 TagFetchScope &tagFetchScope(); 0129 0130 /** 0131 * Returns the items that matched the search query. 0132 */ 0133 [[nodiscard]] Item::List items() const; 0134 0135 /** 0136 * Search only for items of given mime types. 0137 * 0138 * @since 4.13 0139 */ 0140 void setMimeTypes(const QStringList &mimeTypes); 0141 0142 /** 0143 * Returns list of mime types to search in 0144 * 0145 * @since 4.13 0146 */ 0147 [[nodiscard]] QStringList mimeTypes() const; 0148 0149 /** 0150 * Search only in given collections. 0151 * 0152 * When recursive search is enabled, all child collections of each specified 0153 * collection will be searched too 0154 * 0155 * By default all collections are be searched. 0156 * 0157 * @param collections Collections to search 0158 * @since 4.13 0159 */ 0160 void setSearchCollections(const Collection::List &collections); 0161 0162 /** 0163 * Returns list of collections to search. 0164 * 0165 * This list does not include child collections that will be searched when 0166 * recursive search is enabled 0167 * 0168 * @since 4.13 0169 */ 0170 [[nodiscard]] Collection::List searchCollections() const; 0171 0172 /** 0173 * Sets whether the search should recurse into collections 0174 * 0175 * When set to true, all child collections of the specific collections will 0176 * be search recursively. 0177 * 0178 * @param recursive Whether to search recursively 0179 * @since 4.13 0180 */ 0181 void setRecursive(bool recursive); 0182 0183 /** 0184 * Returns whether the search is recursive 0185 * 0186 * @since 4.13 0187 */ 0188 [[nodiscard]] bool isRecursive() const; 0189 0190 /** 0191 * Sets whether resources should be queried too. 0192 * 0193 * When set to true, Akonadi will search local indexed items and will also 0194 * query resources that support server-side search, to forward the query 0195 * to remote storage (for example using SEARCH feature on IMAP servers) and 0196 * merge their results with results from local index. 0197 * 0198 * This is useful especially when searching resources, that don't fetch full 0199 * payload by default, for example the IMAP resource, which only fetches headers 0200 * by default and the body is fetched on demand, which means that emails that 0201 * were not yet fully fetched cannot be indexed in local index, and thus cannot 0202 * be searched. With remote search, even those emails can be included in search 0203 * results. 0204 * 0205 * This feature is disabled by default. 0206 * 0207 * Results are streamed back to client as they are received from queried sources, 0208 * so this job can take some time to finish, but will deliver initial results 0209 * from local index fairly quickly. 0210 * 0211 * @param enabled Whether remote search is enabled 0212 * @since 4.13 0213 */ 0214 void setRemoteSearchEnabled(bool enabled); 0215 0216 /** 0217 * Returns whether remote search is enabled. 0218 * 0219 * @since 4.13 0220 */ 0221 [[nodiscard]] bool isRemoteSearchEnabled() const; 0222 0223 Q_SIGNALS: 0224 /** 0225 * This signal is emitted whenever new matching items have been fetched completely. 0226 * 0227 * @note This is an optimization, instead of waiting for the end of the job 0228 * and calling items(), you can connect to this signal and get the items 0229 * incrementally. 0230 * 0231 * @param items The matching items. 0232 */ 0233 void itemsReceived(const Akonadi::Item::List &items); 0234 0235 protected: 0236 void doStart() override; 0237 bool doHandleResponse(qint64 tag, const Protocol::CommandPtr &response) override; 0238 0239 private: 0240 /// @cond PRIVATE 0241 Q_DECLARE_PRIVATE(ItemSearchJob) 0242 0243 Q_PRIVATE_SLOT(d_func(), void timeout()) 0244 /// @endcond 0245 }; 0246 0247 }