akonadi
agentmanager.cpp
00001 /* 00002 Copyright (c) 2006-2008 Tobias Koenig <tokoe@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "agentmanager.h" 00021 #include "agentmanager_p.h" 00022 00023 #include "agenttype_p.h" 00024 #include "agentinstance_p.h" 00025 #include "dbusconnectionpool.h" 00026 00027 #include <akonadi/private/protocol_p.h> 00028 00029 #include "collection.h" 00030 00031 #include <QtDBus/QDBusServiceWatcher> 00032 #include <QtGui/QWidget> 00033 00034 #include <KGlobal> 00035 #include <KLocale> 00036 00037 using namespace Akonadi; 00038 00039 // @cond PRIVATE 00040 00041 AgentInstance AgentManagerPrivate::createInstance( const AgentType &type ) 00042 { 00043 const QString &identifier = mManager->createAgentInstance( type.identifier() ); 00044 if ( identifier.isEmpty() ) 00045 return AgentInstance(); 00046 00047 return fillAgentInstanceLight( identifier ); 00048 } 00049 00050 void AgentManagerPrivate::agentTypeAdded( const QString &identifier ) 00051 { 00052 // Ignore agent types we already know about, for example because we called 00053 // readAgentTypes before. 00054 if ( mTypes.contains( identifier ) ) 00055 return; 00056 00057 const AgentType type = fillAgentType( identifier ); 00058 if ( type.isValid() ) { 00059 mTypes.insert( identifier, type ); 00060 00061 // The Akonadi ServerManager assumes that the server is up and running as soon 00062 // as it knows about at least one agent type. 00063 // If we emit the typeAdded() signal here, it therefore thinks the server is 00064 // running. However, the AgentManager does not know about all agent types yet, 00065 // as the server might still have pending agentTypeAdded() signals, even though 00066 // it internally knows all agent types already. 00067 // This can cause situations where the client gets told by the ServerManager that 00068 // the server is running, yet the client will encounter an error because the 00069 // AgentManager doesn't know all types yet. 00070 // 00071 // Therefore, we read all agent types from the server here so they are known. 00072 readAgentTypes(); 00073 00074 emit mParent->typeAdded( type ); 00075 } 00076 } 00077 00078 void AgentManagerPrivate::agentTypeRemoved( const QString &identifier ) 00079 { 00080 if ( !mTypes.contains( identifier ) ) 00081 return; 00082 00083 const AgentType type = mTypes.take( identifier ); 00084 emit mParent->typeRemoved( type ); 00085 } 00086 00087 void AgentManagerPrivate::agentInstanceAdded( const QString &identifier ) 00088 { 00089 const AgentInstance instance = fillAgentInstance( identifier ); 00090 if ( instance.isValid() ) { 00091 00092 // It is possible that this function is called when the instance is already 00093 // in our list we filled initially in the constructor. 00094 // This happens when the constructor is called during Akonadi startup, when 00095 // the agent processes are not fully loaded and have no D-Bus interface yet. 00096 // The server-side agent manager then emits the instance added signal when 00097 // the D-Bus interface for the agent comes up. 00098 // In this case, we simply notify that the instance status has changed. 00099 const bool newAgentInstance = !mInstances.contains( identifier ); 00100 if ( newAgentInstance ) { 00101 mInstances.insert( identifier, instance ); 00102 emit mParent->instanceAdded( instance ); 00103 } else { 00104 mInstances.remove( identifier ); 00105 mInstances.insert( identifier, instance ); 00106 emit mParent->instanceStatusChanged( instance ); 00107 } 00108 } 00109 } 00110 00111 void AgentManagerPrivate::agentInstanceRemoved( const QString &identifier ) 00112 { 00113 if ( !mInstances.contains( identifier ) ) 00114 return; 00115 00116 const AgentInstance instance = mInstances.take( identifier ); 00117 emit mParent->instanceRemoved( instance ); 00118 } 00119 00120 void AgentManagerPrivate::agentInstanceStatusChanged( const QString &identifier, int status, const QString &msg ) 00121 { 00122 if ( !mInstances.contains( identifier ) ) 00123 return; 00124 00125 AgentInstance &instance = mInstances[ identifier ]; 00126 instance.d->mStatus = status; 00127 instance.d->mStatusMessage = msg; 00128 00129 emit mParent->instanceStatusChanged( instance ); 00130 } 00131 00132 void AgentManagerPrivate::agentInstanceProgressChanged( const QString &identifier, uint progress, const QString &msg ) 00133 { 00134 if ( !mInstances.contains( identifier ) ) 00135 return; 00136 00137 AgentInstance &instance = mInstances[ identifier ]; 00138 instance.d->mProgress = progress; 00139 if ( !msg.isEmpty() ) 00140 instance.d->mStatusMessage = msg; 00141 00142 emit mParent->instanceProgressChanged( instance ); 00143 } 00144 00145 void AgentManagerPrivate::agentInstanceWarning( const QString &identifier, const QString &msg ) 00146 { 00147 if ( !mInstances.contains( identifier ) ) 00148 return; 00149 00150 AgentInstance &instance = mInstances[ identifier ]; 00151 emit mParent->instanceWarning( instance, msg ); 00152 } 00153 00154 void AgentManagerPrivate::agentInstanceError( const QString &identifier, const QString &msg ) 00155 { 00156 if ( !mInstances.contains( identifier ) ) 00157 return; 00158 00159 AgentInstance &instance = mInstances[ identifier ]; 00160 emit mParent->instanceError( instance, msg ); 00161 } 00162 00163 void AgentManagerPrivate::agentInstanceOnlineChanged( const QString &identifier, bool state ) 00164 { 00165 if ( !mInstances.contains( identifier ) ) 00166 return; 00167 00168 AgentInstance &instance = mInstances[ identifier ]; 00169 instance.d->mIsOnline = state; 00170 emit mParent->instanceOnline( instance, state ); 00171 } 00172 00173 void AgentManagerPrivate::agentInstanceNameChanged( const QString &identifier, const QString &name ) 00174 { 00175 if ( !mInstances.contains( identifier ) ) 00176 return; 00177 00178 AgentInstance &instance = mInstances[ identifier ]; 00179 instance.d->mName = name; 00180 00181 emit mParent->instanceNameChanged( instance ); 00182 } 00183 00184 void AgentManagerPrivate::readAgentTypes() 00185 { 00186 const QDBusReply<QStringList> types = mManager->agentTypes(); 00187 if ( types.isValid() ) { 00188 foreach ( const QString &type, types.value() ) { 00189 if ( !mTypes.contains( type ) ) 00190 agentTypeAdded( type ); 00191 } 00192 } 00193 } 00194 00195 void AgentManagerPrivate::readAgentInstances() 00196 { 00197 const QDBusReply<QStringList> instances = mManager->agentInstances(); 00198 if ( instances.isValid() ) { 00199 foreach ( const QString &instance, instances.value() ) { 00200 if ( !mInstances.contains( instance ) ) { 00201 agentInstanceAdded( instance ); 00202 } 00203 } 00204 } 00205 } 00206 00207 AgentType AgentManagerPrivate::fillAgentType( const QString &identifier ) const 00208 { 00209 AgentType type; 00210 type.d->mIdentifier = identifier; 00211 type.d->mName = mManager->agentName( identifier, KGlobal::locale()->language() ); 00212 type.d->mDescription = mManager->agentComment( identifier, KGlobal::locale()->language() ); 00213 type.d->mIconName = mManager->agentIcon( identifier ); 00214 type.d->mMimeTypes = mManager->agentMimeTypes( identifier ); 00215 type.d->mCapabilities = mManager->agentCapabilities( identifier ); 00216 00217 return type; 00218 } 00219 00220 void AgentManagerPrivate::setName( const AgentInstance &instance, const QString &name ) 00221 { 00222 mManager->setAgentInstanceName( instance.identifier(), name ); 00223 } 00224 00225 void AgentManagerPrivate::setOnline( const AgentInstance &instance, bool state ) 00226 { 00227 mManager->setAgentInstanceOnline( instance.identifier(), state ); 00228 } 00229 00230 void AgentManagerPrivate::configure( const AgentInstance &instance, QWidget *parent ) 00231 { 00232 qlonglong winId = 0; 00233 if ( parent ) 00234 winId = (qlonglong)( parent->window()->winId() ); 00235 00236 mManager->agentInstanceConfigure( instance.identifier(), winId ); 00237 } 00238 00239 void AgentManagerPrivate::synchronize( const AgentInstance &instance ) 00240 { 00241 mManager->agentInstanceSynchronize( instance.identifier() ); 00242 } 00243 00244 void AgentManagerPrivate::synchronizeCollectionTree( const AgentInstance &instance ) 00245 { 00246 mManager->agentInstanceSynchronizeCollectionTree( instance.identifier() ); 00247 } 00248 00249 AgentInstance AgentManagerPrivate::fillAgentInstance( const QString &identifier ) const 00250 { 00251 AgentInstance instance; 00252 00253 const QString agentTypeIdentifier = mManager->agentInstanceType( identifier ); 00254 if ( !mTypes.contains( agentTypeIdentifier ) ) 00255 return instance; 00256 00257 instance.d->mType = mTypes.value( agentTypeIdentifier ); 00258 instance.d->mIdentifier = identifier; 00259 instance.d->mName = mManager->agentInstanceName( identifier ); 00260 instance.d->mStatus = mManager->agentInstanceStatus( identifier ); 00261 instance.d->mStatusMessage = mManager->agentInstanceStatusMessage( identifier ); 00262 instance.d->mProgress = mManager->agentInstanceProgress( identifier ); 00263 instance.d->mIsOnline = mManager->agentInstanceOnline( identifier ); 00264 00265 return instance; 00266 } 00267 00268 AgentInstance AgentManagerPrivate::fillAgentInstanceLight( const QString &identifier ) const 00269 { 00270 AgentInstance instance; 00271 00272 const QString agentTypeIdentifier = mManager->agentInstanceType( identifier ); 00273 Q_ASSERT_X( mTypes.contains( agentTypeIdentifier ), "fillAgentInstanceLight", "Requests non-existing agent type" ); 00274 00275 instance.d->mType = mTypes.value( agentTypeIdentifier ); 00276 instance.d->mIdentifier = identifier; 00277 00278 return instance; 00279 } 00280 00281 void AgentManagerPrivate::serviceOwnerChanged( const QString&, const QString &oldOwner, const QString& ) 00282 { 00283 if ( oldOwner.isEmpty() ) { 00284 readAgentTypes(); 00285 readAgentInstances(); 00286 } 00287 } 00288 00289 void AgentManagerPrivate::createDBusInterface() 00290 { 00291 mTypes.clear(); 00292 mInstances.clear(); 00293 delete mManager; 00294 00295 mManager = new org::freedesktop::Akonadi::AgentManager( QLatin1String( AKONADI_DBUS_CONTROL_SERVICE ), 00296 QLatin1String( "/AgentManager" ), 00297 DBusConnectionPool::threadConnection(), mParent ); 00298 00299 QObject::connect( mManager, SIGNAL(agentTypeAdded(QString)), 00300 mParent, SLOT(agentTypeAdded(QString)) ); 00301 QObject::connect( mManager, SIGNAL(agentTypeRemoved(QString)), 00302 mParent, SLOT(agentTypeRemoved(QString)) ); 00303 QObject::connect( mManager, SIGNAL(agentInstanceAdded(QString)), 00304 mParent, SLOT(agentInstanceAdded(QString)) ); 00305 QObject::connect( mManager, SIGNAL(agentInstanceRemoved(QString)), 00306 mParent, SLOT(agentInstanceRemoved(QString)) ); 00307 QObject::connect( mManager, SIGNAL(agentInstanceStatusChanged(QString,int,QString)), 00308 mParent, SLOT(agentInstanceStatusChanged(QString,int,QString)) ); 00309 QObject::connect( mManager, SIGNAL(agentInstanceProgressChanged(QString,uint,QString)), 00310 mParent, SLOT(agentInstanceProgressChanged(QString,uint,QString)) ); 00311 QObject::connect( mManager, SIGNAL(agentInstanceNameChanged(QString,QString)), 00312 mParent, SLOT(agentInstanceNameChanged(QString,QString)) ); 00313 QObject::connect( mManager, SIGNAL(agentInstanceWarning(QString,QString)), 00314 mParent, SLOT(agentInstanceWarning(QString,QString)) ); 00315 QObject::connect( mManager, SIGNAL(agentInstanceError(QString,QString)), 00316 mParent, SLOT(agentInstanceError(QString,QString)) ); 00317 QObject::connect( mManager, SIGNAL(agentInstanceOnlineChanged(QString,bool)), 00318 mParent, SLOT(agentInstanceOnlineChanged(QString,bool)) ); 00319 00320 if ( mManager->isValid() ) { 00321 QDBusReply<QStringList> result = mManager->agentTypes(); 00322 if ( result.isValid() ) { 00323 foreach ( const QString &type, result.value() ) { 00324 const AgentType agentType = fillAgentType( type ); 00325 mTypes.insert( type, agentType ); 00326 } 00327 } 00328 result = mManager->agentInstances(); 00329 if ( result.isValid() ) { 00330 foreach ( const QString &instance, result.value() ) { 00331 const AgentInstance agentInstance = fillAgentInstance( instance ); 00332 mInstances.insert( instance, agentInstance ); 00333 } 00334 } 00335 } else { 00336 kWarning() << "AgentManager failed to get a valid AgentManager DBus interface. Error is:" << mManager->lastError().type() << mManager->lastError().name() << mManager->lastError().message(); 00337 } 00338 } 00339 00340 AgentManager* AgentManagerPrivate::mSelf = 0; 00341 00342 AgentManager::AgentManager() 00343 : QObject( 0 ), d( new AgentManagerPrivate( this ) ) 00344 { 00345 // needed for queued connections on our signals 00346 qRegisterMetaType<Akonadi::AgentType>(); 00347 qRegisterMetaType<Akonadi::AgentInstance>(); 00348 00349 d->createDBusInterface(); 00350 00351 QDBusServiceWatcher *watcher = new QDBusServiceWatcher( QLatin1String( AKONADI_DBUS_CONTROL_SERVICE ), 00352 DBusConnectionPool::threadConnection(), 00353 QDBusServiceWatcher::WatchForOwnerChange, this ); 00354 connect( watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), 00355 this, SLOT(serviceOwnerChanged(QString,QString,QString)) ); 00356 } 00357 00358 // @endcond 00359 00360 AgentManager::~AgentManager() 00361 { 00362 delete d; 00363 } 00364 00365 AgentManager* AgentManager::self() 00366 { 00367 if ( !AgentManagerPrivate::mSelf ) 00368 AgentManagerPrivate::mSelf = new AgentManager(); 00369 00370 return AgentManagerPrivate::mSelf; 00371 } 00372 00373 AgentType::List AgentManager::types() const 00374 { 00375 return d->mTypes.values(); 00376 } 00377 00378 AgentType AgentManager::type( const QString &identifier ) const 00379 { 00380 return d->mTypes.value( identifier ); 00381 } 00382 00383 AgentInstance::List AgentManager::instances() const 00384 { 00385 return d->mInstances.values(); 00386 } 00387 00388 AgentInstance AgentManager::instance( const QString &identifier ) const 00389 { 00390 return d->mInstances.value( identifier ); 00391 } 00392 00393 void AgentManager::removeInstance( const AgentInstance &instance ) 00394 { 00395 d->mManager->removeAgentInstance( instance.identifier() ); 00396 } 00397 00398 void AgentManager::synchronizeCollection( const Collection & collection ) 00399 { 00400 synchronizeCollection( collection, false ); 00401 } 00402 00403 void AgentManager::synchronizeCollection( const Collection & collection, bool recursive ) 00404 { 00405 const QString resId = collection.resource(); 00406 Q_ASSERT( !resId.isEmpty() ); 00407 d->mManager->agentInstanceSynchronizeCollection( resId, collection.id(), recursive ); 00408 } 00409 00410 #include "agentmanager.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:18:29 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:18:29 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.