add more spacing
[personal-kdebase.git] / runtime / nepomuk / kioslaves / search / queryserviceclient.cpp
blob95bc9b0d756ee21b76be1ce0de30a3679c636fa5
1 /*
2 Copyright (c) 2008 Sebastian Trueg <trueg@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "queryserviceclient.h"
20 #include "dbusoperators.h"
21 #include "result.h"
22 #include "query.h"
23 #include "queryserviceinterface.h"
24 #include "queryinterface.h"
26 #include <QtDBus/QDBusInterface>
27 #include <QtDBus/QDBusConnection>
28 #include <QtDBus/QDBusConnectionInterface>
29 #include <QtDBus/QDBusReply>
31 #include <QtCore/QEventLoop>
32 #include <QtCore/QTimer>
34 #include <KDebug>
35 #include <KGlobal>
38 namespace {
39 /**
40 * Each thread needs its own QDBusConnection. We do it the very easy
41 * way and just create a new connection for each client
42 * Why does Qt not handle this automatically?
44 class QDBusConnectionPerThreadHelper
46 public:
47 QDBusConnectionPerThreadHelper()
48 : m_counter( 0 ) {
51 QDBusConnection newConnection() {
52 QMutexLocker lock( &m_mutex );
53 return QDBusConnection::connectToBus( QDBusConnection::SessionBus,
54 QString("NepomukQueryServiceConnection%1").arg(++m_counter) );
57 private:
58 int m_counter;
59 QMutex m_mutex;
62 K_GLOBAL_STATIC( QDBusConnectionPerThreadHelper, s_globalDBusConnectionPerThreadHelper )
66 class Nepomuk::Search::QueryServiceClient::Private
68 public:
69 Private()
70 : queryServiceInterface( 0 ),
71 queryInterface( 0 ),
72 dbusConnection( s_globalDBusConnectionPerThreadHelper->newConnection() ),
73 loop( 0 ) {
76 void _k_entriesRemoved( const QStringList& );
77 void _k_finishedListing();
78 bool handleQueryReply( QDBusReply<QDBusObjectPath> reply );
80 org::kde::nepomuk::QueryService* queryServiceInterface;
81 org::kde::nepomuk::Query* queryInterface;
83 QueryServiceClient* q;
85 QDBusConnection dbusConnection;
87 QEventLoop* loop;
91 void Nepomuk::Search::QueryServiceClient::Private::_k_entriesRemoved( const QStringList& uris )
93 QList<QUrl> ul;
94 foreach( const QString& s, uris ) {
95 ul.append( QUrl( s ) );
97 emit q->entriesRemoved( ul );
101 void Nepomuk::Search::QueryServiceClient::Private::_k_finishedListing()
103 emit q->finishedListing();
104 if( loop ) {
105 q->close();
110 bool Nepomuk::Search::QueryServiceClient::Private::handleQueryReply( QDBusReply<QDBusObjectPath> r )
112 if ( r.isValid() ) {
113 queryInterface = new org::kde::nepomuk::Query( queryServiceInterface->service(),
114 r.value().path(),
115 dbusConnection );
116 connect( queryInterface, SIGNAL( newEntries( QList<Nepomuk::Search::Result> ) ),
117 q, SIGNAL( newEntries( QList<Nepomuk::Search::Result> ) ) );
118 connect( queryInterface, SIGNAL( entriesRemoved( QStringList ) ),
119 q, SLOT( _k_entriesRemoved( QStringList ) ) );
120 connect( queryInterface, SIGNAL( finishedListing() ),
121 q, SLOT( _k_finishedListing() ) );
122 // run the listing async in case the event loop below is the only one we have
123 // and we need it to handle the signals and list returns results immediately
124 QTimer::singleShot( 0, queryInterface, SLOT(list()) );
125 return true;
127 else {
128 kDebug() << "Query failed:" << r.error().message();
129 return false;
134 Nepomuk::Search::QueryServiceClient::QueryServiceClient( QObject* parent )
135 : QObject( parent ),
136 d( new Private() )
138 d->q = this;
140 Nepomuk::Search::registerDBusTypes();
142 // we use our own connection to be thread-safe
143 d->queryServiceInterface = new org::kde::nepomuk::QueryService( "org.kde.nepomuk.services.nepomukqueryservice",
144 "/nepomukqueryservice",
145 d->dbusConnection );
149 Nepomuk::Search::QueryServiceClient::~QueryServiceClient()
151 close();
152 delete d;
156 bool Nepomuk::Search::QueryServiceClient::query( const QString& query )
158 close();
160 if ( d->queryServiceInterface->isValid() ) {
161 return d->handleQueryReply( d->queryServiceInterface->query( query, QStringList() ) );
163 else {
164 kDebug() << "Could not contact query service.";
165 return false;
170 bool Nepomuk::Search::QueryServiceClient::query( const Query& query )
172 close();
174 if ( d->queryServiceInterface->isValid() ) {
175 return d->handleQueryReply( d->queryServiceInterface->query( query ) );
177 else {
178 kDebug() << "Could not contact query service.";
179 return false;
184 bool Nepomuk::Search::QueryServiceClient::blockingQuery( const QString& q )
186 if( query( q ) ) {
187 QEventLoop loop;
188 d->loop = &loop;
189 loop.exec();
190 d->loop = 0;
191 return true;
193 else {
194 return false;
199 bool Nepomuk::Search::QueryServiceClient::blockingQuery( const Query& q )
201 if( query( q ) ) {
202 QEventLoop loop;
203 d->loop = &loop;
204 loop.exec();
205 d->loop = 0;
206 return true;
208 else {
209 return false;
214 void Nepomuk::Search::QueryServiceClient::close()
216 if ( d->queryInterface ) {
217 kDebug();
218 d->queryInterface->close();
219 delete d->queryInterface;
220 d->queryInterface = 0;
221 if( d->loop )
222 d->loop->exit();
227 bool Nepomuk::Search::QueryServiceClient::serviceAvailable()
229 return QDBusConnection::sessionBus().interface()->isServiceRegistered( "org.kde.nepomuk.services.nepomukqueryservice" );
232 #include "queryserviceclient.moc"