• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
agentmanager.cpp
1 /*
2  Copyright (c) 2006-2008 Tobias Koenig <tokoe@kde.org>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "agentmanager.h"
21 #include "agentmanager_p.h"
22 
23 #include "agenttype_p.h"
24 #include "agentinstance_p.h"
25 #include "dbusconnectionpool.h"
26 #include "servermanager.h"
27 
28 #include "collection.h"
29 
30 #include <QtDBus/QDBusServiceWatcher>
31 #include <QWidget>
32 
33 #include <KGlobal>
34 #include <KLocale>
35 #include <KLocalizedString>
36 
37 using namespace Akonadi;
38 
39 // @cond PRIVATE
40 
41 AgentInstance AgentManagerPrivate::createInstance( const AgentType &type )
42 {
43  const QString &identifier = mManager->createAgentInstance( type.identifier() );
44  if ( identifier.isEmpty() ) {
45  return AgentInstance();
46  }
47 
48  return fillAgentInstanceLight( identifier );
49 }
50 
51 void AgentManagerPrivate::agentTypeAdded( const QString &identifier )
52 {
53  // Ignore agent types we already know about, for example because we called
54  // readAgentTypes before.
55  if ( mTypes.contains( identifier ) ) {
56  return;
57  }
58 
59  const AgentType type = fillAgentType( identifier );
60  if ( type.isValid() ) {
61  mTypes.insert( identifier, type );
62 
63  // The Akonadi ServerManager assumes that the server is up and running as soon
64  // as it knows about at least one agent type.
65  // If we emit the typeAdded() signal here, it therefore thinks the server is
66  // running. However, the AgentManager does not know about all agent types yet,
67  // as the server might still have pending agentTypeAdded() signals, even though
68  // it internally knows all agent types already.
69  // This can cause situations where the client gets told by the ServerManager that
70  // the server is running, yet the client will encounter an error because the
71  // AgentManager doesn't know all types yet.
72  //
73  // Therefore, we read all agent types from the server here so they are known.
74  readAgentTypes();
75 
76  emit mParent->typeAdded( type );
77  }
78 }
79 
80 void AgentManagerPrivate::agentTypeRemoved( const QString &identifier )
81 {
82  if ( !mTypes.contains( identifier ) ) {
83  return;
84  }
85 
86  const AgentType type = mTypes.take( identifier );
87  emit mParent->typeRemoved( type );
88 }
89 
90 void AgentManagerPrivate::agentInstanceAdded( const QString &identifier )
91 {
92  const AgentInstance instance = fillAgentInstance( identifier );
93  if ( instance.isValid() ) {
94 
95  // It is possible that this function is called when the instance is already
96  // in our list we filled initially in the constructor.
97  // This happens when the constructor is called during Akonadi startup, when
98  // the agent processes are not fully loaded and have no D-Bus interface yet.
99  // The server-side agent manager then emits the instance added signal when
100  // the D-Bus interface for the agent comes up.
101  // In this case, we simply notify that the instance status has changed.
102  const bool newAgentInstance = !mInstances.contains( identifier );
103  if ( newAgentInstance ) {
104  mInstances.insert( identifier, instance );
105  emit mParent->instanceAdded( instance );
106  } else {
107  mInstances.remove( identifier );
108  mInstances.insert( identifier, instance );
109  emit mParent->instanceStatusChanged( instance );
110  }
111  }
112 }
113 
114 void AgentManagerPrivate::agentInstanceRemoved( const QString &identifier )
115 {
116  if ( !mInstances.contains( identifier ) ) {
117  return;
118  }
119 
120  const AgentInstance instance = mInstances.take( identifier );
121  emit mParent->instanceRemoved( instance );
122 }
123 
124 void AgentManagerPrivate::agentInstanceStatusChanged( const QString &identifier, int status, const QString &msg )
125 {
126  if ( !mInstances.contains( identifier ) ) {
127  return;
128  }
129 
130  AgentInstance &instance = mInstances[ identifier ];
131  instance.d->mStatus = status;
132  instance.d->mStatusMessage = msg;
133 
134  emit mParent->instanceStatusChanged( instance );
135 }
136 
137 void AgentManagerPrivate::agentInstanceProgressChanged( const QString &identifier, uint progress, const QString &msg )
138 {
139  if ( !mInstances.contains( identifier ) ) {
140  return;
141  }
142 
143  AgentInstance &instance = mInstances[ identifier ];
144  instance.d->mProgress = progress;
145  if ( !msg.isEmpty() ) {
146  instance.d->mStatusMessage = msg;
147  }
148 
149  emit mParent->instanceProgressChanged( instance );
150 }
151 
152 void AgentManagerPrivate::agentInstanceWarning( const QString &identifier, const QString &msg )
153 {
154  if ( !mInstances.contains( identifier ) ) {
155  return;
156  }
157 
158  AgentInstance &instance = mInstances[ identifier ];
159  emit mParent->instanceWarning( instance, msg );
160 }
161 
162 void AgentManagerPrivate::agentInstanceError( const QString &identifier, const QString &msg )
163 {
164  if ( !mInstances.contains( identifier ) ) {
165  return;
166  }
167 
168  AgentInstance &instance = mInstances[ identifier ];
169  emit mParent->instanceError( instance, msg );
170 }
171 
172 void AgentManagerPrivate::agentInstanceOnlineChanged( const QString &identifier, bool state )
173 {
174  if ( !mInstances.contains( identifier ) ) {
175  return;
176  }
177 
178  AgentInstance &instance = mInstances[ identifier ];
179  instance.d->mIsOnline = state;
180  emit mParent->instanceOnline( instance, state );
181 }
182 
183 void AgentManagerPrivate::agentInstanceNameChanged( const QString &identifier, const QString &name )
184 {
185  if ( !mInstances.contains( identifier ) ) {
186  return;
187  }
188 
189  AgentInstance &instance = mInstances[ identifier ];
190  instance.d->mName = name;
191 
192  emit mParent->instanceNameChanged( instance );
193 }
194 
195 void AgentManagerPrivate::readAgentTypes()
196 {
197  const QDBusReply<QStringList> types = mManager->agentTypes();
198  if ( types.isValid() ) {
199  foreach ( const QString &type, types.value() ) {
200  if ( !mTypes.contains( type ) ) {
201  agentTypeAdded( type );
202  }
203  }
204  }
205 }
206 
207 void AgentManagerPrivate::readAgentInstances()
208 {
209  const QDBusReply<QStringList> instances = mManager->agentInstances();
210  if ( instances.isValid() ) {
211  foreach ( const QString &instance, instances.value() ) {
212  if ( !mInstances.contains( instance ) ) {
213  agentInstanceAdded( instance );
214  }
215  }
216  }
217 }
218 
219 AgentType AgentManagerPrivate::fillAgentType( const QString &identifier ) const
220 {
221  AgentType type;
222  type.d->mIdentifier = identifier;
223  type.d->mName = mManager->agentName( identifier, KGlobal::locale()->language() );
224  type.d->mDescription = mManager->agentComment( identifier, KGlobal::locale()->language() );
225  type.d->mIconName = mManager->agentIcon( identifier );
226  type.d->mMimeTypes = mManager->agentMimeTypes( identifier );
227  type.d->mCapabilities = mManager->agentCapabilities( identifier );
228  type.d->mCustomProperties = mManager->agentCustomProperties( identifier );
229 
230  return type;
231 }
232 
233 void AgentManagerPrivate::setName( const AgentInstance &instance, const QString &name )
234 {
235  mManager->setAgentInstanceName( instance.identifier(), name );
236 }
237 
238 void AgentManagerPrivate::setOnline( const AgentInstance &instance, bool state )
239 {
240  mManager->setAgentInstanceOnline( instance.identifier(), state );
241 }
242 
243 void AgentManagerPrivate::configure( const AgentInstance &instance, QWidget *parent )
244 {
245  qlonglong winId = 0;
246  if ( parent ) {
247  winId = (qlonglong)( parent->window()->winId() );
248  }
249 
250  mManager->agentInstanceConfigure( instance.identifier(), winId );
251 }
252 
253 void AgentManagerPrivate::synchronize( const AgentInstance &instance )
254 {
255  mManager->agentInstanceSynchronize( instance.identifier() );
256 }
257 
258 void AgentManagerPrivate::synchronizeCollectionTree( const AgentInstance &instance )
259 {
260  mManager->agentInstanceSynchronizeCollectionTree( instance.identifier() );
261 }
262 
263 AgentInstance AgentManagerPrivate::fillAgentInstance( const QString &identifier ) const
264 {
265  AgentInstance instance;
266 
267  const QString agentTypeIdentifier = mManager->agentInstanceType( identifier );
268  if ( !mTypes.contains( agentTypeIdentifier ) ) {
269  return instance;
270  }
271 
272  instance.d->mType = mTypes.value( agentTypeIdentifier );
273  instance.d->mIdentifier = identifier;
274  instance.d->mName = mManager->agentInstanceName( identifier );
275  instance.d->mStatus = mManager->agentInstanceStatus( identifier );
276  instance.d->mStatusMessage = mManager->agentInstanceStatusMessage( identifier );
277  instance.d->mProgress = mManager->agentInstanceProgress( identifier );
278  instance.d->mIsOnline = mManager->agentInstanceOnline( identifier );
279 
280  return instance;
281 }
282 
283 AgentInstance AgentManagerPrivate::fillAgentInstanceLight( const QString &identifier ) const
284 {
285  AgentInstance instance;
286 
287  const QString agentTypeIdentifier = mManager->agentInstanceType( identifier );
288  Q_ASSERT_X( mTypes.contains( agentTypeIdentifier ), "fillAgentInstanceLight", "Requests non-existing agent type" );
289 
290  instance.d->mType = mTypes.value( agentTypeIdentifier );
291  instance.d->mIdentifier = identifier;
292 
293  return instance;
294 }
295 
296 void AgentManagerPrivate::serviceOwnerChanged( const QString&, const QString &oldOwner, const QString& )
297 {
298  if ( oldOwner.isEmpty() ) {
299  readAgentTypes();
300  readAgentInstances();
301  }
302 }
303 
304 void AgentManagerPrivate::createDBusInterface()
305 {
306  mTypes.clear();
307  mInstances.clear();
308  delete mManager;
309 
310  mManager = new org::freedesktop::Akonadi::AgentManager( ServerManager::serviceName( ServerManager::Control ),
311  QLatin1String( "/AgentManager" ),
312  DBusConnectionPool::threadConnection(), mParent );
313 
314  QObject::connect( mManager, SIGNAL(agentTypeAdded(QString)),
315  mParent, SLOT(agentTypeAdded(QString)) );
316  QObject::connect( mManager, SIGNAL(agentTypeRemoved(QString)),
317  mParent, SLOT(agentTypeRemoved(QString)) );
318  QObject::connect( mManager, SIGNAL(agentInstanceAdded(QString)),
319  mParent, SLOT(agentInstanceAdded(QString)) );
320  QObject::connect( mManager, SIGNAL(agentInstanceRemoved(QString)),
321  mParent, SLOT(agentInstanceRemoved(QString)) );
322  QObject::connect( mManager, SIGNAL(agentInstanceStatusChanged(QString,int,QString)),
323  mParent, SLOT(agentInstanceStatusChanged(QString,int,QString)) );
324  QObject::connect( mManager, SIGNAL(agentInstanceProgressChanged(QString,uint,QString)),
325  mParent, SLOT(agentInstanceProgressChanged(QString,uint,QString)) );
326  QObject::connect( mManager, SIGNAL(agentInstanceNameChanged(QString,QString)),
327  mParent, SLOT(agentInstanceNameChanged(QString,QString)) );
328  QObject::connect( mManager, SIGNAL(agentInstanceWarning(QString,QString)),
329  mParent, SLOT(agentInstanceWarning(QString,QString)) );
330  QObject::connect( mManager, SIGNAL(agentInstanceError(QString,QString)),
331  mParent, SLOT(agentInstanceError(QString,QString)) );
332  QObject::connect( mManager, SIGNAL(agentInstanceOnlineChanged(QString,bool)),
333  mParent, SLOT(agentInstanceOnlineChanged(QString,bool)) );
334 
335  if ( mManager->isValid() ) {
336  QDBusReply<QStringList> result = mManager->agentTypes();
337  if ( result.isValid() ) {
338  foreach ( const QString &type, result.value() ) {
339  const AgentType agentType = fillAgentType( type );
340  mTypes.insert( type, agentType );
341  }
342  }
343  result = mManager->agentInstances();
344  if ( result.isValid() ) {
345  foreach ( const QString &instance, result.value() ) {
346  const AgentInstance agentInstance = fillAgentInstance( instance );
347  mInstances.insert( instance, agentInstance );
348  }
349  }
350  } else {
351  kWarning() << "AgentManager failed to get a valid AgentManager DBus interface. Error is:" << mManager->lastError().type() << mManager->lastError().name() << mManager->lastError().message();
352  }
353 }
354 
355 AgentManager* AgentManagerPrivate::mSelf = 0;
356 
357 AgentManager::AgentManager()
358  : QObject( 0 ), d( new AgentManagerPrivate( this ) )
359 {
360  // needed for queued connections on our signals
361  qRegisterMetaType<Akonadi::AgentType>();
362  qRegisterMetaType<Akonadi::AgentInstance>();
363 
364  d->createDBusInterface();
365 
366  QDBusServiceWatcher *watcher = new QDBusServiceWatcher( ServerManager::serviceName( ServerManager::Control ),
367  DBusConnectionPool::threadConnection(),
368  QDBusServiceWatcher::WatchForOwnerChange, this );
369  connect( watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
370  this, SLOT(serviceOwnerChanged(QString,QString,QString)) );
371 }
372 
373 // @endcond
374 
375 AgentManager::~AgentManager()
376 {
377  delete d;
378 }
379 
380 AgentManager* AgentManager::self()
381 {
382  if ( !AgentManagerPrivate::mSelf ) {
383  AgentManagerPrivate::mSelf = new AgentManager();
384  }
385 
386  return AgentManagerPrivate::mSelf;
387 }
388 
389 AgentType::List AgentManager::types() const
390 {
391  return d->mTypes.values();
392 }
393 
394 AgentType AgentManager::type( const QString &identifier ) const
395 {
396  return d->mTypes.value( identifier );
397 }
398 
399 AgentInstance::List AgentManager::instances() const
400 {
401  return d->mInstances.values();
402 }
403 
404 AgentInstance AgentManager::instance( const QString &identifier ) const
405 {
406  return d->mInstances.value( identifier );
407 }
408 
409 void AgentManager::removeInstance( const AgentInstance &instance )
410 {
411  d->mManager->removeAgentInstance( instance.identifier() );
412 }
413 
414 void AgentManager::synchronizeCollection( const Collection & collection )
415 {
416  synchronizeCollection( collection, false );
417 }
418 
419 void AgentManager::synchronizeCollection( const Collection & collection, bool recursive )
420 {
421  const QString resId = collection.resource();
422  Q_ASSERT( !resId.isEmpty() );
423  d->mManager->agentInstanceSynchronizeCollection( resId, collection.id(), recursive );
424 }
425 
426 #include "moc_agentmanager.cpp"
Akonadi::AgentManager::instanceStatusChanged
void instanceStatusChanged(const Akonadi::AgentInstance &instance)
This signal is emitted whenever the status of an agent instance has changed.
Akonadi::AgentManager::synchronizeCollection
void synchronizeCollection(const Collection &collection)
Trigger a synchronization of the given collection by its owning resource agent.
Definition: agentmanager.cpp:414
Akonadi::AgentInstance::List
QList< AgentInstance > List
Describes a list of agent instances.
Definition: agentinstance.h:71
Akonadi::AgentManager::instanceRemoved
void instanceRemoved(const Akonadi::AgentInstance &instance)
This signal is emitted whenever an agent instance was removed.
Akonadi::AgentManager::instances
AgentInstance::List instances() const
Returns the list of all available agent instances.
Definition: agentmanager.cpp:399
Akonadi::AgentManager
Provides an interface to retrieve agent types and manage agent instances.
Definition: agentmanager.h:55
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::AgentManagerPrivate::readAgentInstances
void readAgentInstances()
Reads the information about all known agent instances from the server.
Akonadi::AgentManager::instanceError
void instanceError(const Akonadi::AgentInstance &instance, const QString &message)
This signal is emitted whenever the agent instance raised an error.
Akonadi::AgentManager::instanceProgressChanged
void instanceProgressChanged(const Akonadi::AgentInstance &instance)
This signal is emitted whenever the progress of an agent instance has changed.
Akonadi::AgentType::isValid
bool isValid() const
Returns whether the agent type is valid.
Definition: agenttype.cpp:41
Akonadi::AgentManager::instanceNameChanged
void instanceNameChanged(const Akonadi::AgentInstance &instance)
This signal is emitted whenever the name of the agent instance has changed.
Akonadi::AgentInstance::identifier
QString identifier() const
Returns the unique identifier of the agent instance.
Definition: agentinstance.cpp:55
Akonadi::ServerManager::serviceName
static QString serviceName(ServiceType serviceType)
Returns the namespaced D-Bus service name for serviceType.
Definition: servermanager.cpp:298
Akonadi::AgentType::identifier
QString identifier() const
Returns the unique identifier of the agent type.
Definition: agenttype.cpp:46
Akonadi::AgentManager::removeInstance
void removeInstance(const AgentInstance &instance)
Removes the given agent instance.
Definition: agentmanager.cpp:409
Akonadi::AgentManagerPrivate::readAgentTypes
void readAgentTypes()
Reads the information about all known agent types from the serverside agent manager and updates mType...
Akonadi::AgentManager::instanceAdded
void instanceAdded(const Akonadi::AgentInstance &instance)
This signal is emitted whenever a new agent instance was created.
Akonadi::AgentManager::typeRemoved
void typeRemoved(const Akonadi::AgentType &type)
This signal is emitted whenever an agent type was removed from the system.
Akonadi::AgentType
A representation of an agent type.
Definition: agenttype.h:58
Akonadi::AgentManager::instance
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
Definition: agentmanager.cpp:404
Akonadi::AgentInstance::isValid
bool isValid() const
Returns whether the agent instance object is valid.
Definition: agentinstance.cpp:45
Akonadi::AgentType::List
QList< AgentType > List
Describes a list of agent types.
Definition: agenttype.h:67
Akonadi::Entity::id
Id id() const
Returns the unique identifier of the entity.
Definition: entity.cpp:72
Akonadi::AgentManagerPrivate
Definition: agentmanager_p.h:37
Akonadi::AgentManager::instanceOnline
void instanceOnline(const Akonadi::AgentInstance &instance, bool online)
This signal is emitted whenever the online state of an agent changed.
Akonadi::AgentManager::type
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
Definition: agentmanager.cpp:394
Akonadi::AgentManager::instanceWarning
void instanceWarning(const Akonadi::AgentInstance &instance, const QString &message)
This signal is emitted whenever the agent instance raised a warning.
Akonadi::AgentManager::~AgentManager
~AgentManager()
Destroys the agent manager.
Definition: agentmanager.cpp:375
Akonadi::AgentManager::types
AgentType::List types() const
Returns the list of all available agent types.
Definition: agentmanager.cpp:389
Akonadi::AgentManager::self
static AgentManager * self()
Returns the global instance of the agent manager.
Definition: agentmanager.cpp:380
Akonadi::AgentInstance
A representation of an agent instance.
Definition: agentinstance.h:62
Akonadi::Collection::resource
QString resource() const
Returns the identifier of the resource owning the collection.
Definition: collection.cpp:207
Akonadi::AgentManager::typeAdded
void typeAdded(const Akonadi::AgentType &type)
This signal is emitted whenever a new agent type was installed on the system.
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:26 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



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