Akonadi

agentsearchinterface.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "agentsearchinterface.h"
8#include "agentbase.h"
9#include "agentsearchinterface_p.h"
10#include "akonadiagentbase_debug.h"
11#include "collection.h"
12#include "collectionfetchjob.h"
13#include "collectionfetchscope.h"
14#include "private/imapset_p.h"
15#include "searchadaptor.h"
16#include "searchresultjob_p.h"
17#include "servermanager.h"
18#include <QDBusConnection>
19
20using namespace Akonadi;
21using namespace std::chrono_literals;
22AgentSearchInterfacePrivate::AgentSearchInterfacePrivate(AgentSearchInterface *qq)
23 : q(qq)
24{
25 new Akonadi__SearchAdaptor(this);
27
28 QTimer::singleShot(0s, this, &AgentSearchInterfacePrivate::delayedInit);
29}
30
31void AgentSearchInterfacePrivate::delayedInit()
32{
33 QDBusInterface iface(ServerManager::serviceName(ServerManager::Server),
34 QStringLiteral("/SearchManager"),
35 QStringLiteral("org.freedesktop.Akonadi.SearchManager"),
37 this);
38 QDBusMessage msg = iface.call(QStringLiteral("registerInstance"), dynamic_cast<AgentBase *>(q)->identifier());
39 // TODO ?
40}
41
42void AgentSearchInterfacePrivate::addSearch(const QString &query, const QString &queryLanguage, quint64 resultCollectionId)
43{
44 q->addSearch(query, queryLanguage, Collection(resultCollectionId));
45}
46
47void AgentSearchInterfacePrivate::removeSearch(quint64 resultCollectionId)
48{
49 q->removeSearch(Collection(resultCollectionId));
50}
51
52void AgentSearchInterfacePrivate::search(const QByteArray &searchId, const QString &query, quint64 collectionId)
53{
54 mSearchId = searchId;
55 mCollectionId = collectionId;
56
57 auto fetchJob = new CollectionFetchJob(Collection(mCollectionId), CollectionFetchJob::Base, this);
58 fetchJob->fetchScope().setAncestorRetrieval(CollectionFetchScope::All);
59 fetchJob->setProperty("query", query);
60 connect(fetchJob, &KJob::finished, this, &AgentSearchInterfacePrivate::collectionReceived);
61}
62
63void AgentSearchInterfacePrivate::collectionReceived(KJob *job)
64{
65 auto fetchJob = qobject_cast<CollectionFetchJob *>(job);
66 if (fetchJob->error()) {
67 qCCritical(AKONADIAGENTBASE_LOG) << fetchJob->errorString();
68 new SearchResultJob(fetchJob->property("searchId").toByteArray(), Collection(mCollectionId), this);
69 return;
70 }
71
72 if (fetchJob->collections().count() != 1) {
73 qCDebug(AKONADIAGENTBASE_LOG) << "Server requested search in invalid collection, or collection was removed in the meanwhile";
74 // Tell server we are done
75 new SearchResultJob(fetchJob->property("searchId").toByteArray(), Collection(mCollectionId), this);
76 return;
77 }
78
79 const Collection collection = fetchJob->collections().at(0);
80 q->search(fetchJob->property("query").toString(), collection);
81}
82
84 : d(new AgentSearchInterfacePrivate(this))
85{
86}
87
89
90void AgentSearchInterface::searchFinished(const QList<qint64> &result, ResultScope scope)
91{
92 if (scope == Akonadi::AgentSearchInterface::Rid) {
94 rids.reserve(result.size());
95 for (qint64 rid : result) {
96 rids << QByteArray::number(rid);
97 }
98
99 searchFinished(rids);
100 return;
101 }
102
103 auto resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d.get());
104 resultJob->setResult(result);
105}
106
107void AgentSearchInterface::searchFinished(const ImapSet &result, ResultScope scope)
108{
109 if (scope == Akonadi::AgentSearchInterface::Rid) {
111 const ImapInterval::List lstInterval = result.intervals();
112 for (const ImapInterval &interval : lstInterval) {
113 const int endInterval(interval.end());
114 for (int i = interval.begin(); i <= endInterval; ++i) {
115 rids << QByteArray::number(i);
116 }
117 }
118
119 searchFinished(rids);
120 return;
121 }
122
123 QList<qint64> ids;
124 for (const auto &interval : result.intervals()) {
125 if (!interval.hasDefinedBegin() || !interval.hasDefinedEnd()) {
126 qCWarning(AKONADIAGENTBASE_LOG) << "Search results must not have an open interval! Results will be incomplete.";
127 continue;
128 }
129 for (int i = interval.begin(), end = interval.end(); i <= end; ++i) {
130 ids << i;
131 }
132 }
133
134 auto resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d.get());
135 resultJob->setResult(ids);
136}
137
138void AgentSearchInterface::searchFinished(const QList<QByteArray> &result)
139{
140 auto resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d.get());
141 resultJob->setResult(result);
142}
143
144#include "moc_agentsearchinterface_p.cpp"
The base class for all Akonadi agents and resources.
Definition agentbase.h:73
An interface for agents (or resources) that support searching in their backend.
virtual ~AgentSearchInterface()
Destroys the agent search interface.
AgentSearchInterface()
Creates a new agent search interface.
Job that fetches collections from the Akonadi storage.
@ Base
Only fetch the base collection.
Represents a collection of PIM items.
Definition collection.h:62
void finished(KJob *job)
Helper integration between Akonadi and Qt.
const QList< QKeySequence > & end()
QByteArray number(double n, char format, int precision)
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
void reserve(qsizetype size)
qsizetype size() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.