Akonadi

itemsearchjob.cpp
1 /*
2  Copyright (c) 2009 Tobias Koenig <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "itemsearchjob.h"
21 
22 #include "itemfetchscope.h"
23 #include "tagfetchscope.h"
24 #include "job_p.h"
25 #include "protocolhelper_p.h"
26 #include "searchquery.h"
27 #include "private/protocol_p.h"
28 
29 
30 #include <QCoreApplication>
31 #include <QTimer>
32 #include <QThreadStorage>
33 
34 using namespace Akonadi;
35 
36 class Akonadi::ItemSearchJobPrivate : public JobPrivate
37 {
38 public:
39  ItemSearchJobPrivate(ItemSearchJob *parent, const SearchQuery &query)
40  : JobPrivate(parent)
41  , mQuery(query)
42  {
43  }
44 
45  void init()
46  {
47  Q_Q(ItemSearchJob);
48  mEmitTimer = new QTimer(q);
49  mEmitTimer->setSingleShot(true);
50  mEmitTimer->setInterval(100);
51  q->connect(mEmitTimer, SIGNAL(timeout()), q, SLOT(timeout()));
52  q->connect(q, SIGNAL(result(KJob*)), q, SLOT(timeout()));
53  }
54 
55  void timeout()
56  {
58 
59  mEmitTimer->stop(); // in case we are called by result()
60  if (!mPendingItems.isEmpty()) {
61  if (!q->error()) {
62  Q_EMIT q->itemsReceived(mPendingItems);
63  }
64  mPendingItems.clear();
65  }
66  }
67  QString jobDebuggingString() const override
68  {
69  QStringList flags;
70  if (mRecursive) {
71  flags.append(QStringLiteral("recursive"));
72  }
73  if (mRemote) {
74  flags.append(QStringLiteral("remote"));
75  }
76  if (mCollections.isEmpty()) {
77  flags.append(QStringLiteral("all collections"));
78  } else {
79  flags.append(QStringLiteral("%1 collections").arg(mCollections.count()));
80  }
81  return QStringLiteral("%1,json=%2").arg(flags.join(QLatin1Char(',')), QString::fromUtf8(mQuery.toJSON()));
82  }
83 
84  Q_DECLARE_PUBLIC(ItemSearchJob)
85 
86  SearchQuery mQuery;
87  Collection::List mCollections;
88  QStringList mMimeTypes;
89  bool mRecursive = false;
90  bool mRemote = false;
91  ItemFetchScope mItemFetchScope;
92  TagFetchScope mTagFetchScope;
93 
94  Item::List mItems;
95  Item::List mPendingItems; // items pending for emitting itemsReceived()
96 
97  QTimer *mEmitTimer = nullptr;
98 };
99 
100 QThreadStorage<Session *> instances;
101 
102 static void cleanupDefaultSearchSession()
103 {
104  instances.setLocalData(nullptr);
105 }
106 
107 static Session *defaultSearchSession()
108 {
109  if (!instances.hasLocalData()) {
110  const QByteArray sessionName = Session::defaultSession()->sessionId() + "-SearchSession";
111  instances.setLocalData(new Session(sessionName));
112  qAddPostRoutine(cleanupDefaultSearchSession);
113  }
114  return instances.localData();
115 }
116 
117 static QObject *sessionForJob(QObject *parent)
118 {
119  if (qobject_cast<Job *>(parent) || qobject_cast<Session *>(parent)) {
120  return parent;
121  }
122  return defaultSearchSession();
123 }
124 
126  : Job(new ItemSearchJobPrivate(this, SearchQuery()), sessionForJob(parent))
127 {
128  Q_D(ItemSearchJob);
129 
130  d->init();
131 }
132 
134  : Job(new ItemSearchJobPrivate(this, query), sessionForJob(parent))
135 {
136  Q_D(ItemSearchJob);
137 
138  d->init();
139 }
140 
142 {
143 }
144 
146 {
147  Q_D(ItemSearchJob);
148 
149  d->mQuery = query;
150 }
151 
153 {
154  Q_D(ItemSearchJob);
155 
156  d->mItemFetchScope = fetchScope;
157 }
158 
160 {
161  Q_D(ItemSearchJob);
162 
163  return d->mItemFetchScope;
164 }
165 
167 {
168  Q_D(ItemSearchJob);
169 
170  d->mTagFetchScope = fetchScope;
171 }
172 
174 {
175  Q_D(ItemSearchJob);
176 
177  return d->mTagFetchScope;
178 }
179 
181 {
182  Q_D(ItemSearchJob);
183 
184  d->mCollections = collections;
185 }
186 
188 {
189  return d_func()->mCollections;
190 }
191 
193 {
194  Q_D(ItemSearchJob);
195 
196  d->mMimeTypes = mimeTypes;
197 }
198 
200 {
201  return d_func()->mMimeTypes;
202 }
203 
204 void ItemSearchJob::setRecursive(bool recursive)
205 {
206  Q_D(ItemSearchJob);
207 
208  d->mRecursive = recursive;
209 }
210 
212 {
213  return d_func()->mRecursive;
214 }
215 
217 {
218  Q_D(ItemSearchJob);
219 
220  d->mRemote = enabled;
221 }
222 
224 {
225  return d_func()->mRemote;
226 }
227 
229 {
230  Q_D(ItemSearchJob);
231 
232  auto cmd = Protocol::SearchCommandPtr::create();
233  cmd->setMimeTypes(d->mMimeTypes);
234  if (!d->mCollections.isEmpty()) {
235  QVector<qint64> ids;
236  ids.reserve(d->mCollections.size());
237  for (const Collection &col : qAsConst(d->mCollections)) {
238  ids << col.id();
239  }
240  cmd->setCollections(ids);
241  }
242  cmd->setRecursive(d->mRecursive);
243  cmd->setRemote(d->mRemote);
244  cmd->setQuery(QString::fromUtf8(d->mQuery.toJSON()));
245  cmd->setItemFetchScope(ProtocolHelper::itemFetchScopeToProtocol(d->mItemFetchScope));
246  cmd->setTagFetchScope(ProtocolHelper::tagFetchScopeToProtocol(d->mTagFetchScope));
247 
248  d->sendCommand(cmd);
249 }
250 
251 bool ItemSearchJob::doHandleResponse(qint64 tag, const Protocol::CommandPtr &response)
252 {
253  Q_D(ItemSearchJob);
254 
255  if (response->isResponse() && response->type() == Protocol::Command::FetchItems) {
256  const Item item = ProtocolHelper::parseItemFetchResult(
257  Protocol::cmdCast<Protocol::FetchItemsResponse>(response));
258  if (!item.isValid()) {
259  return false;
260  }
261  d->mItems.append(item);
262  d->mPendingItems.append(item);
263  if (!d->mEmitTimer->isActive()) {
264  d->mEmitTimer->start();
265  }
266 
267  return false;
268  }
269 
270  if (response->isResponse() && response->type() == Protocol::Command::Search) {
271  return true;
272  }
273 
274  return Job::doHandleResponse(tag, response);
275 }
276 
277 Item::List ItemSearchJob::items() const
278 {
279  Q_D(const ItemSearchJob);
280 
281  return d->mItems;
282 }
283 
284 #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:385
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:35
Represents a collection of PIM items.
Definition: collection.h:76
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:93
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.
QUICKADDONS_EXPORT void init()
QByteArray sessionId() const
Returns the session identifier.
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:67
void reserve(int size)
A query that can be passed to ItemSearchJob or others.
Definition: searchquery.h:128
Specifies which parts of an item should be fetched from the Akonadi storage.
ItemSearchJob(QObject *parent=nullptr)
Creates an invalid search job.
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.
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:69
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue May 26 2020 22:46:20 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.