• Skip to content
  • Skip to link menu
KDE 4.5 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

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

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal