• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • 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 "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 Mon Apr 30 2012 21:49:14 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

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

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal