Akonadi

itemsearchjob.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Tobias Koenig <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "itemsearchjob.h"
8 
9 #include "itemfetchscope.h"
10 #include "tagfetchscope.h"
11 #include "job_p.h"
12 #include "protocolhelper_p.h"
13 #include "searchquery.h"
14 #include "private/protocol_p.h"
15 
16 
17 #include <QCoreApplication>
18 #include <QTimer>
19 #include <QThreadStorage>
20 
21 using namespace Akonadi;
22 
23 class Akonadi::ItemSearchJobPrivate : public JobPrivate
24 {
25 public:
26  ItemSearchJobPrivate(ItemSearchJob *parent, const SearchQuery &query)
27  : JobPrivate(parent)
28  , mQuery(query)
29  {
30  mEmitTimer.setSingleShot(true);
31  mEmitTimer.setInterval(std::chrono::milliseconds{100});
32  }
33 
34  void init()
35  {
36  QObject::connect(&mEmitTimer, &QTimer::timeout, q_ptr, [this]() { timeout(); });
37  }
38 
39  void aboutToFinish() override
40  {
41  timeout();
42  }
43 
44  void timeout()
45  {
47 
48  mEmitTimer.stop(); // in case we are called by result()
49  if (!mPendingItems.isEmpty()) {
50  if (!q->error()) {
51  Q_EMIT q->itemsReceived(mPendingItems);
52  }
53  mPendingItems.clear();
54  }
55  }
56  QString jobDebuggingString() const override
57  {
58  QStringList flags;
59  if (mRecursive) {
60  flags.append(QStringLiteral("recursive"));
61  }
62  if (mRemote) {
63  flags.append(QStringLiteral("remote"));
64  }
65  if (mCollections.isEmpty()) {
66  flags.append(QStringLiteral("all collections"));
67  } else {
68  flags.append(QStringLiteral("%1 collections").arg(mCollections.count()));
69  }
70  return QStringLiteral("%1,json=%2").arg(flags.join(QLatin1Char(',')), QString::fromUtf8(mQuery.toJSON()));
71  }
72 
73  Q_DECLARE_PUBLIC(ItemSearchJob)
74 
75  SearchQuery mQuery;
76  Collection::List mCollections;
77  QStringList mMimeTypes;
78  bool mRecursive = false;
79  bool mRemote = false;
80  ItemFetchScope mItemFetchScope;
81  TagFetchScope mTagFetchScope;
82 
83  Item::List mItems;
84  Item::List mPendingItems; // items pending for emitting itemsReceived()
85 
86  QTimer mEmitTimer;
87 };
88 
89 QThreadStorage<Session *> instances;
90 
91 static void cleanupDefaultSearchSession()
92 {
93  instances.setLocalData(nullptr);
94 }
95 
96 static Session *defaultSearchSession()
97 {
98  if (!instances.hasLocalData()) {
99  const QByteArray sessionName = Session::defaultSession()->sessionId() + "-SearchSession";
100  instances.setLocalData(new Session(sessionName));
101  qAddPostRoutine(cleanupDefaultSearchSession);
102  }
103  return instances.localData();
104 }
105 
106 static QObject *sessionForJob(QObject *parent)
107 {
108  if (qobject_cast<Job *>(parent) || qobject_cast<Session *>(parent)) {
109  return parent;
110  }
111  return defaultSearchSession();
112 }
113 
115  : Job(new ItemSearchJobPrivate(this, SearchQuery()), sessionForJob(parent))
116 {
117  Q_D(ItemSearchJob);
118  d->init();
119 }
120 
122  : Job(new ItemSearchJobPrivate(this, query), sessionForJob(parent))
123 {
124  Q_D(ItemSearchJob);
125  d->init();
126 }
127 
129 
131 {
132  Q_D(ItemSearchJob);
133 
134  d->mQuery = query;
135 }
136 
138 {
139  Q_D(ItemSearchJob);
140 
141  d->mItemFetchScope = fetchScope;
142 }
143 
145 {
146  Q_D(ItemSearchJob);
147 
148  return d->mItemFetchScope;
149 }
150 
152 {
153  Q_D(ItemSearchJob);
154 
155  d->mTagFetchScope = fetchScope;
156 }
157 
159 {
160  Q_D(ItemSearchJob);
161 
162  return d->mTagFetchScope;
163 }
164 
166 {
167  Q_D(ItemSearchJob);
168 
169  d->mCollections = collections;
170 }
171 
173 {
174  return d_func()->mCollections;
175 }
176 
178 {
179  Q_D(ItemSearchJob);
180 
181  d->mMimeTypes = mimeTypes;
182 }
183 
185 {
186  return d_func()->mMimeTypes;
187 }
188 
189 void ItemSearchJob::setRecursive(bool recursive)
190 {
191  Q_D(ItemSearchJob);
192 
193  d->mRecursive = recursive;
194 }
195 
197 {
198  return d_func()->mRecursive;
199 }
200 
202 {
203  Q_D(ItemSearchJob);
204 
205  d->mRemote = enabled;
206 }
207 
209 {
210  return d_func()->mRemote;
211 }
212 
214 {
215  Q_D(ItemSearchJob);
216 
217  auto cmd = Protocol::SearchCommandPtr::create();
218  cmd->setMimeTypes(d->mMimeTypes);
219  if (!d->mCollections.isEmpty()) {
220  QVector<qint64> ids;
221  ids.reserve(d->mCollections.size());
222  for (const Collection &col : qAsConst(d->mCollections)) {
223  ids << col.id();
224  }
225  cmd->setCollections(ids);
226  }
227  cmd->setRecursive(d->mRecursive);
228  cmd->setRemote(d->mRemote);
229  cmd->setQuery(QString::fromUtf8(d->mQuery.toJSON()));
230  cmd->setItemFetchScope(ProtocolHelper::itemFetchScopeToProtocol(d->mItemFetchScope));
231  cmd->setTagFetchScope(ProtocolHelper::tagFetchScopeToProtocol(d->mTagFetchScope));
232 
233  d->sendCommand(cmd);
234 }
235 
236 bool ItemSearchJob::doHandleResponse(qint64 tag, const Protocol::CommandPtr &response)
237 {
238  Q_D(ItemSearchJob);
239 
240  if (response->isResponse() && response->type() == Protocol::Command::FetchItems) {
241  const Item item = ProtocolHelper::parseItemFetchResult(
242  Protocol::cmdCast<Protocol::FetchItemsResponse>(response));
243  if (!item.isValid()) {
244  return false;
245  }
246  d->mItems.append(item);
247  d->mPendingItems.append(item);
248  if (!d->mEmitTimer.isActive()) {
249  d->mEmitTimer.start();
250  }
251 
252  return false;
253  }
254 
255  if (response->isResponse() && response->type() == Protocol::Command::Search) {
256  return true;
257  }
258 
259  return Job::doHandleResponse(tag, response);
260 }
261 
262 Item::List ItemSearchJob::items() const
263 {
264  Q_D(const ItemSearchJob);
265 
266  return d->mItems;
267 }
268 
269 #include "moc_itemsearchjob.cpp"
QStringList mimeTypes() const
Returns list of mime types to search in.
void setRemoteSearchEnabled(bool enabled)
Sets whether resources should be queried too.
virtual bool doHandleResponse(qint64 tag, const Protocol::CommandPtr &response)
This method should be reimplemented in the concrete jobs in case you want to handle incoming data...
Definition: job.cpp:372
Item::List items() const
Returns the items that matched the search query.
void setTagFetchScope(const TagFetchScope &fetchScope)
Sets the tag fetch scope.
Specifies which parts of a tag should be fetched from the Akonadi storage.
Definition: tagfetchscope.h:22
Represents a collection of PIM items.
Definition: collection.h:63
bool isRemoteSearchEnabled() const
Returns whether remote search is enabled.
void setSearchCollections(const Collection::List &collections)
Search only in given collections.
Base class for all actions in the Akonadi storage.
Definition: job.h:80
Collection::List searchCollections() const
Returns list of collections to search.
QString join(const QString &separator) const const
static Session * defaultSession()
Returns the default session for this thread.
void doStart() override
This method must be reimplemented in the concrete jobs.
void setFetchScope(const ItemFetchScope &fetchScope)
Sets the item fetch scope.
QByteArray sessionId() const
Returns the session identifier.
void timeout()
void append(const T &value)
QString fromUtf8(const char *str, int size)
~ItemSearchJob() override
Destroys the item search job.
void setRecursive(bool recursive)
Sets whether the search should recurse into collections.
ItemFetchScope & fetchScope()
Returns the item fetch scope.
A communication session with the Akonadi storage.
Definition: core/session.h:54
void reserve(int size)
A query that can be passed to ItemSearchJob or others.
Definition: searchquery.h:115
Specifies which parts of an item should be fetched from the Akonadi storage.
ItemSearchJob(QObject *parent=nullptr)
Creates an invalid search job.
QCA_EXPORT void init()
bool doHandleResponse(qint64 tag, const Protocol::CommandPtr &response) override
This method should be reimplemented in the concrete jobs in case you want to handle incoming data...
void setQuery(const SearchQuery &query)
Sets the search query.
Helper integration between Akonadi and Qt.
TagFetchScope & tagFetchScope()
Returns the tag fetch scope.
bool isRecursive() const
Returns whether the search is recursive.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setMimeTypes(const QStringList &mimeTypes)
Search only for items of given mime types.
Job that searches for items in the Akonadi storage.
Definition: itemsearchjob.h:56
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Sep 18 2020 23:15:13 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.