File indexing completed on 2025-01-05 04:46:24
0001 /* 0002 SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "agentsearchinterface.h" 0008 #include "agentbase.h" 0009 #include "agentsearchinterface_p.h" 0010 #include "akonadiagentbase_debug.h" 0011 #include "collection.h" 0012 #include "collectionfetchjob.h" 0013 #include "collectionfetchscope.h" 0014 #include "private/imapset_p.h" 0015 #include "searchadaptor.h" 0016 #include "searchresultjob_p.h" 0017 #include "servermanager.h" 0018 #include <QDBusConnection> 0019 0020 using namespace Akonadi; 0021 using namespace std::chrono_literals; 0022 AgentSearchInterfacePrivate::AgentSearchInterfacePrivate(AgentSearchInterface *qq) 0023 : q(qq) 0024 { 0025 new Akonadi__SearchAdaptor(this); 0026 QDBusConnection::sessionBus().registerObject(QStringLiteral("/Search"), this, QDBusConnection::ExportAdaptors); 0027 0028 QTimer::singleShot(0s, this, &AgentSearchInterfacePrivate::delayedInit); 0029 } 0030 0031 void AgentSearchInterfacePrivate::delayedInit() 0032 { 0033 QDBusInterface iface(ServerManager::serviceName(ServerManager::Server), 0034 QStringLiteral("/SearchManager"), 0035 QStringLiteral("org.freedesktop.Akonadi.SearchManager"), 0036 QDBusConnection::sessionBus(), 0037 this); 0038 QDBusMessage msg = iface.call(QStringLiteral("registerInstance"), dynamic_cast<AgentBase *>(q)->identifier()); 0039 // TODO ? 0040 } 0041 0042 void AgentSearchInterfacePrivate::addSearch(const QString &query, const QString &queryLanguage, quint64 resultCollectionId) 0043 { 0044 q->addSearch(query, queryLanguage, Collection(resultCollectionId)); 0045 } 0046 0047 void AgentSearchInterfacePrivate::removeSearch(quint64 resultCollectionId) 0048 { 0049 q->removeSearch(Collection(resultCollectionId)); 0050 } 0051 0052 void AgentSearchInterfacePrivate::search(const QByteArray &searchId, const QString &query, quint64 collectionId) 0053 { 0054 mSearchId = searchId; 0055 mCollectionId = collectionId; 0056 0057 auto fetchJob = new CollectionFetchJob(Collection(mCollectionId), CollectionFetchJob::Base, this); 0058 fetchJob->fetchScope().setAncestorRetrieval(CollectionFetchScope::All); 0059 fetchJob->setProperty("query", query); 0060 connect(fetchJob, &KJob::finished, this, &AgentSearchInterfacePrivate::collectionReceived); 0061 } 0062 0063 void AgentSearchInterfacePrivate::collectionReceived(KJob *job) 0064 { 0065 auto fetchJob = qobject_cast<CollectionFetchJob *>(job); 0066 if (fetchJob->error()) { 0067 qCCritical(AKONADIAGENTBASE_LOG) << fetchJob->errorString(); 0068 new SearchResultJob(fetchJob->property("searchId").toByteArray(), Collection(mCollectionId), this); 0069 return; 0070 } 0071 0072 if (fetchJob->collections().count() != 1) { 0073 qCDebug(AKONADIAGENTBASE_LOG) << "Server requested search in invalid collection, or collection was removed in the meanwhile"; 0074 // Tell server we are done 0075 new SearchResultJob(fetchJob->property("searchId").toByteArray(), Collection(mCollectionId), this); 0076 return; 0077 } 0078 0079 const Collection collection = fetchJob->collections().at(0); 0080 q->search(fetchJob->property("query").toString(), collection); 0081 } 0082 0083 AgentSearchInterface::AgentSearchInterface() 0084 : d(new AgentSearchInterfacePrivate(this)) 0085 { 0086 } 0087 0088 AgentSearchInterface::~AgentSearchInterface() = default; 0089 0090 void AgentSearchInterface::searchFinished(const QList<qint64> &result, ResultScope scope) 0091 { 0092 if (scope == Akonadi::AgentSearchInterface::Rid) { 0093 QList<QByteArray> rids; 0094 rids.reserve(result.size()); 0095 for (qint64 rid : result) { 0096 rids << QByteArray::number(rid); 0097 } 0098 0099 searchFinished(rids); 0100 return; 0101 } 0102 0103 auto resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d.get()); 0104 resultJob->setResult(result); 0105 } 0106 0107 void AgentSearchInterface::searchFinished(const ImapSet &result, ResultScope scope) 0108 { 0109 if (scope == Akonadi::AgentSearchInterface::Rid) { 0110 QList<QByteArray> rids; 0111 const ImapInterval::List lstInterval = result.intervals(); 0112 for (const ImapInterval &interval : lstInterval) { 0113 const int endInterval(interval.end()); 0114 for (int i = interval.begin(); i <= endInterval; ++i) { 0115 rids << QByteArray::number(i); 0116 } 0117 } 0118 0119 searchFinished(rids); 0120 return; 0121 } 0122 0123 auto resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d.get()); 0124 resultJob->setResult(result); 0125 } 0126 0127 void AgentSearchInterface::searchFinished(const QList<QByteArray> &result) 0128 { 0129 auto resultJob = new SearchResultJob(d->mSearchId, Collection(d->mCollectionId), d.get()); 0130 resultJob->setResult(result); 0131 } 0132 0133 #include "moc_agentsearchinterface_p.cpp"