1 | /* |
2 | Copyright (c) 2009 Volker Krause <vkrause@kde.org> |
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 "agentsearchinterface.h" |
21 | #include "agentsearchinterface_p.h" |
22 | #include "collection.h" |
23 | #include "dbusconnectionpool.h" |
24 | #include "searchresultjob_p.h" |
25 | #include "searchadaptor.h" |
26 | #include "collectionfetchjob.h" |
27 | #include "collectionfetchscope.h" |
28 | #include "servermanager.h" |
29 | #include "agentbase.h" |
30 | |
31 | using namespace Akonadi; |
32 | |
33 | AgentSearchInterfacePrivate::AgentSearchInterfacePrivate(AgentSearchInterface *qq) |
34 | : q(qq) |
35 | { |
36 | new Akonadi__SearchAdaptor(this); |
37 | DBusConnectionPool::threadConnection().registerObject(QLatin1String("/Search" ), |
38 | this, QDBusConnection::ExportAdaptors); |
39 | |
40 | QTimer::singleShot(0, this, SLOT(delayedInit())); |
41 | } |
42 | |
43 | void AgentSearchInterfacePrivate::delayedInit() |
44 | { |
45 | QDBusInterface iface(ServerManager::serviceName(ServerManager::Server), |
46 | QLatin1String("/SearchManager" ), |
47 | QLatin1String("org.freedesktop.Akonadi.SearchManager" ), |
48 | QDBusConnection::sessionBus(), this); |
49 | QDBusMessage msg = iface.call(QLatin1String("registerInstance" ), dynamic_cast<AgentBase *>(q)->identifier()); |
50 | } |
51 | |
52 | void AgentSearchInterfacePrivate::addSearch(const QString &query, const QString &queryLanguage, quint64 resultCollectionId) |
53 | { |
54 | q->addSearch(query, queryLanguage, Collection(resultCollectionId)); |
55 | } |
56 | |
57 | void AgentSearchInterfacePrivate::removeSearch(quint64 resultCollectionId) |
58 | { |
59 | q->removeSearch(Collection(resultCollectionId)); |
60 | } |
61 | |
62 | void AgentSearchInterfacePrivate::search(const QByteArray &searchId, |
63 | const QString &query, |
64 | quint64 collectionId) |
65 | { |
66 | mSearchId = searchId; |
67 | mCollectionId = collectionId; |
68 | |
69 | CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection(mCollectionId), CollectionFetchJob::Base, this); |
70 | fetchJob->fetchScope().setAncestorRetrieval(CollectionFetchScope::All); |
71 | fetchJob->setProperty("query" , query); |
72 | connect(fetchJob, SIGNAL(finished(KJob*)), this, SLOT(collectionReceived(KJob*))); |
73 | } |
74 | |
75 | void AgentSearchInterfacePrivate::collectionReceived(KJob *job) |
76 | { |
77 | CollectionFetchJob *fetchJob = qobject_cast<CollectionFetchJob *>(job); |
78 | if (fetchJob->error()) { |
79 | kError() << fetchJob->errorString(); |
80 | new SearchResultJob(fetchJob->property("searchId" ).toByteArray(), Collection(mCollectionId), this); |
81 | return; |
82 | } |
83 | |
84 | if (fetchJob->collections().count() != 1) { |
85 | kDebug() << "Server requested search in invalid collection, or collection was removed in the meanwhile" ; |
86 | // Tell server we are done |
87 | new SearchResultJob(fetchJob->property("searchId" ).toByteArray(), Collection(mCollectionId), this); |
88 | return; |
89 | } |
90 | |
91 | const Collection collection = fetchJob->collections().first(); |
92 | q->search(fetchJob->property("query" ).toString(), |
93 | collection); |
94 | } |
95 | |
96 | AgentSearchInterface::AgentSearchInterface() |
97 | : d(new AgentSearchInterfacePrivate(this)) |
98 | { |
99 | } |
100 | |
101 | AgentSearchInterface::~AgentSearchInterface() |
102 | { |
103 | delete d; |
104 | } |
105 | |
106 | void AgentSearchInterface::searchFinished(const QVector<qint64> result, ResultScope scope) |
107 | { |
108 | if (scope == Akonadi::AgentSearchInterface::Rid) { |
109 | QVector<QByteArray> rids; |
110 | rids.reserve(result.size()); |
111 | Q_FOREACH (qint64 rid, result) { |
112 | rids << QByteArray::number(rid); |
113 | } |
114 | |
115 | searchFinished(rids); |
116 | return; |
117 | } |
118 | |
119 | SearchResultJob *resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d); |
120 | resultJob->setResult(result); |
121 | } |
122 | |
123 | void AgentSearchInterface::searchFinished(const ImapSet &result, ResultScope scope) |
124 | { |
125 | if (scope == Akonadi::AgentSearchInterface::Rid) { |
126 | QVector<QByteArray> rids; |
127 | Q_FOREACH (const ImapInterval &interval, result.intervals()) { |
128 | for (int i = interval.begin(); i <= interval.end(); ++i) { |
129 | rids << QByteArray::number(i); |
130 | } |
131 | } |
132 | |
133 | searchFinished(rids); |
134 | return; |
135 | } |
136 | |
137 | SearchResultJob *resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d); |
138 | resultJob->setResult(result); |
139 | } |
140 | |
141 | void AgentSearchInterface::searchFinished(const QVector<QByteArray> &result) |
142 | { |
143 | SearchResultJob *resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d); |
144 | resultJob->setResult(result); |
145 | } |
146 | |
147 | #include "moc_agentsearchinterface_p.cpp" |
148 | |