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

akonadi

  • 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 
36 using namespace Akonadi;
37 
38 // @cond PRIVATE
39 
40 AgentInstance AgentManagerPrivate::createInstance( const AgentType &type )
41 {
42  const QString &identifier = mManager->createAgentInstance( type.identifier() );
43  if ( identifier.isEmpty() ) {
44  return AgentInstance();
45  }
46 
47  return fillAgentInstanceLight( identifier );
48 }
49 
50 void AgentManagerPrivate::agentTypeAdded( const QString &identifier )
51 {
52  // Ignore agent types we already know about, for example because we called
53  // readAgentTypes before.
54  if ( mTypes.contains( identifier ) ) {
55  return;
56  }
57 
58  const AgentType type = fillAgentType( identifier );
59  if ( type.isValid() ) {
60  mTypes.insert( identifier, type );
61 
62  // The Akonadi ServerManager assumes that the server is up and running as soon
63  // as it knows about at least one agent type.
64  // If we emit the typeAdded() signal here, it therefore thinks the server is
65  // running. However, the AgentManager does not know about all agent types yet,
66  // as the server might still have pending agentTypeAdded() signals, even though
67  // it internally knows all agent types already.
68  // This can cause situations where the client gets told by the ServerManager that
69  // the server is running, yet the client will encounter an error because the
70  // AgentManager doesn't know all types yet.
71  //
72  // Therefore, we read all agent types from the server here so they are known.
73  readAgentTypes();
74 
75  emit mParent->typeAdded( type );
76  }
77 }
78 
79 void AgentManagerPrivate::agentTypeRemoved( const QString &identifier )
80 {
81  if ( !mTypes.contains( identifier ) ) {
82  return;
83  }
84 
85  const AgentType type = mTypes.take( identifier );
86  emit mParent->typeRemoved( type );
87 }
88 
89 void AgentManagerPrivate::agentInstanceAdded( const QString &identifier )
90 {
91  const AgentInstance instance = fillAgentInstance( identifier );
92  if ( instance.isValid() ) {
93 
94  // It is possible that this function is called when the instance is already
95  // in our list we filled initially in the constructor.
96  // This happens when the constructor is called during Akonadi startup, when
97  // the agent processes are not fully loaded and have no D-Bus interface yet.
98  // The server-side agent manager then emits the instance added signal when
99  // the D-Bus interface for the agent comes up.
100  // In this case, we simply notify that the instance status has changed.
101  const bool newAgentInstance = !mInstances.contains( identifier );
102  if ( newAgentInstance ) {
103  mInstances.insert( identifier, instance );
104  emit mParent->instanceAdded( instance );
105  } else {
106  mInstances.remove( identifier );
107  mInstances.insert( identifier, instance );
108  emit mParent->instanceStatusChanged( instance );
109  }
110  }
111 }
112 
113 void AgentManagerPrivate::agentInstanceRemoved( const QString &identifier )
114 {
115  if ( !mInstances.contains( identifier ) ) {
116  return;
117  }
118 
119  const AgentInstance instance = mInstances.take( identifier );
120  emit mParent->instanceRemoved( instance );
121 }
122 
123 void AgentManagerPrivate::agentInstanceStatusChanged( const QString &identifier, int status, const QString &msg )
124 {
125  if ( !mInstances.contains( identifier ) ) {
126  return;
127  }
128 
129  AgentInstance &instance = mInstances[ identifier ];
130  instance.d->mStatus = status;
131  instance.d->mStatusMessage = msg;
132 
133  emit mParent->instanceStatusChanged( instance );
134 }
135 
136 void AgentManagerPrivate::agentInstanceProgressChanged( const QString &identifier, uint progress, const QString &msg )
137 {
138  if ( !mInstances.contains( identifier ) ) {
139  return;
140  }
141 
142  AgentInstance &instance = mInstances[ identifier ];
143  instance.d->mProgress = progress;
144  if ( !msg.isEmpty() ) {
145  instance.d->mStatusMessage = msg;
146  }
147 
148  emit mParent->instanceProgressChanged( instance );
149 }
150 
151 void AgentManagerPrivate::agentInstanceWarning( const QString &identifier, const QString &msg )
152 {
153  if ( !mInstances.contains( identifier ) ) {
154  return;
155  }
156 
157  AgentInstance &instance = mInstances[ identifier ];
158  emit mParent->instanceWarning( instance, msg );
159 }
160 
161 void AgentManagerPrivate::agentInstanceError( const QString &identifier, const QString &msg )
162 {
163  if ( !mInstances.contains( identifier ) ) {
164  return;
165  }
166 
167  AgentInstance &instance = mInstances[ identifier ];
168  emit mParent->instanceError( instance, msg );
169 }
170 
171 void AgentManagerPrivate::agentInstanceOnlineChanged( const QString &identifier, bool state )
172 {
173  if ( !mInstances.contains( identifier ) ) {
174  return;
175  }
176 
177  AgentInstance &instance = mInstances[ identifier ];
178  instance.d->mIsOnline = state;
179  emit mParent->instanceOnline( instance, state );
180 }
181 
182 void AgentManagerPrivate::agentInstanceNameChanged( const QString &identifier, const QString &name )
183 {
184  if ( !mInstances.contains( identifier ) ) {
185  return;
186  }
187 
188  AgentInstance &instance = mInstances[ identifier ];
189  instance.d->mName = name;
190 
191  emit mParent->instanceNameChanged( instance );
192 }
193 
194 void AgentManagerPrivate::readAgentTypes()
195 {
196  const QDBusReply<QStringList> types = mManager->agentTypes();
197  if ( types.isValid() ) {
198  foreach ( const QString &type, types.value() ) {
199  if ( !mTypes.contains( type ) ) {
200  agentTypeAdded( type );
201  }
202  }
203  }
204 }
205 
206 void AgentManagerPrivate::readAgentInstances()
207 {
208  const QDBusReply<QStringList> instances = mManager->agentInstances();
209  if ( instances.isValid() ) {
210  foreach ( const QString &instance, instances.value() ) {
211  if ( !mInstances.contains( instance ) ) {
212  agentInstanceAdded( instance );
213  }
214  }
215  }
216 }
217 
218 AgentType AgentManagerPrivate::fillAgentType( const QString &identifier ) const
219 {
220  AgentType type;
221  type.d->mIdentifier = identifier;
222  type.d->mName = mManager->agentName( identifier, KGlobal::locale()->language() );
223  type.d->mDescription = mManager->agentComment( identifier, KGlobal::locale()->language() );
224  type.d->mIconName = mManager->agentIcon( identifier );
225  type.d->mMimeTypes = mManager->agentMimeTypes( identifier );
226  type.d->mCapabilities = mManager->agentCapabilities( identifier );
227 
228  return type;
229 }
230 
231 void AgentManagerPrivate::setName( const AgentInstance &instance, const QString &name )
232 {
233  mManager->setAgentInstanceName( instance.identifier(), name );
234 }
235 
236 void AgentManagerPrivate::setOnline( const AgentInstance &instance, bool state )
237 {
238  mManager->setAgentInstanceOnline( instance.identifier(), state );
239 }
240 
241 void AgentManagerPrivate::configure( const AgentInstance &instance, QWidget *parent )
242 {
243  qlonglong winId = 0;
244  if ( parent ) {
245  winId = (qlonglong)( parent->window()->winId() );
246  }
247 
248  mManager->agentInstanceConfigure( instance.identifier(), winId );
249 }
250 
251 void AgentManagerPrivate::synchronize( const AgentInstance &instance )
252 {
253  mManager->agentInstanceSynchronize( instance.identifier() );
254 }
255 
256 void AgentManagerPrivate::synchronizeCollectionTree( const AgentInstance &instance )
257 {
258  mManager->agentInstanceSynchronizeCollectionTree( instance.identifier() );
259 }
260 
261 AgentInstance AgentManagerPrivate::fillAgentInstance( const QString &identifier ) const
262 {
263  AgentInstance instance;
264 
265  const QString agentTypeIdentifier = mManager->agentInstanceType( identifier );
266  if ( !mTypes.contains( agentTypeIdentifier ) ) {
267  return instance;
268  }
269 
270  instance.d->mType = mTypes.value( agentTypeIdentifier );
271  instance.d->mIdentifier = identifier;
272  instance.d->mName = mManager->agentInstanceName( identifier );
273  instance.d->mStatus = mManager->agentInstanceStatus( identifier );
274  instance.d->mStatusMessage = mManager->agentInstanceStatusMessage( identifier );
275  instance.d->mProgress = mManager->agentInstanceProgress( identifier );
276  instance.d->mIsOnline = mManager->agentInstanceOnline( identifier );
277 
278  return instance;
279 }
280 
281 AgentInstance AgentManagerPrivate::fillAgentInstanceLight( const QString &identifier ) const
282 {
283  AgentInstance instance;
284 
285  const QString agentTypeIdentifier = mManager->agentInstanceType( identifier );
286  Q_ASSERT_X( mTypes.contains( agentTypeIdentifier ), "fillAgentInstanceLight", "Requests non-existing agent type" );
287 
288  instance.d->mType = mTypes.value( agentTypeIdentifier );
289  instance.d->mIdentifier = identifier;
290 
291  return instance;
292 }
293 
294 void AgentManagerPrivate::serviceOwnerChanged( const QString&, const QString &oldOwner, const QString& )
295 {
296  if ( oldOwner.isEmpty() ) {
297  readAgentTypes();
298  readAgentInstances();
299  }
300 }
301 
302 void AgentManagerPrivate::createDBusInterface()
303 {
304  mTypes.clear();
305  mInstances.clear();
306  delete mManager;
307 
308  mManager = new org::freedesktop::Akonadi::AgentManager( ServerManager::serviceName( ServerManager::Control ),
309  QLatin1String( "/AgentManager" ),
310  DBusConnectionPool::threadConnection(), mParent );
311 
312  QObject::connect( mManager, SIGNAL(agentTypeAdded(QString)),
313  mParent, SLOT(agentTypeAdded(QString)) );
314  QObject::connect( mManager, SIGNAL(agentTypeRemoved(QString)),
315  mParent, SLOT(agentTypeRemoved(QString)) );
316  QObject::connect( mManager, SIGNAL(agentInstanceAdded(QString)),
317  mParent, SLOT(agentInstanceAdded(QString)) );
318  QObject::connect( mManager, SIGNAL(agentInstanceRemoved(QString)),
319  mParent, SLOT(agentInstanceRemoved(QString)) );
320  QObject::connect( mManager, SIGNAL(agentInstanceStatusChanged(QString,int,QString)),
321  mParent, SLOT(agentInstanceStatusChanged(QString,int,QString)) );
322  QObject::connect( mManager, SIGNAL(agentInstanceProgressChanged(QString,uint,QString)),
323  mParent, SLOT(agentInstanceProgressChanged(QString,uint,QString)) );
324  QObject::connect( mManager, SIGNAL(agentInstanceNameChanged(QString,QString)),
325  mParent, SLOT(agentInstanceNameChanged(QString,QString)) );
326  QObject::connect( mManager, SIGNAL(agentInstanceWarning(QString,QString)),
327  mParent, SLOT(agentInstanceWarning(QString,QString)) );
328  QObject::connect( mManager, SIGNAL(agentInstanceError(QString,QString)),
329  mParent, SLOT(agentInstanceError(QString,QString)) );
330  QObject::connect( mManager, SIGNAL(agentInstanceOnlineChanged(QString,bool)),
331  mParent, SLOT(agentInstanceOnlineChanged(QString,bool)) );
332 
333  if ( mManager->isValid() ) {
334  QDBusReply<QStringList> result = mManager->agentTypes();
335  if ( result.isValid() ) {
336  foreach ( const QString &type, result.value() ) {
337  const AgentType agentType = fillAgentType( type );
338  mTypes.insert( type, agentType );
339  }
340  }
341  result = mManager->agentInstances();
342  if ( result.isValid() ) {
343  foreach ( const QString &instance, result.value() ) {
344  const AgentInstance agentInstance = fillAgentInstance( instance );
345  mInstances.insert( instance, agentInstance );
346  }
347  }
348  } else {
349  kWarning() << "AgentManager failed to get a valid AgentManager DBus interface. Error is:" << mManager->lastError().type() << mManager->lastError().name() << mManager->lastError().message();
350  }
351 }
352 
353 AgentManager* AgentManagerPrivate::mSelf = 0;
354 
355 AgentManager::AgentManager()
356  : QObject( 0 ), d( new AgentManagerPrivate( this ) )
357 {
358  // needed for queued connections on our signals
359  qRegisterMetaType<Akonadi::AgentType>();
360  qRegisterMetaType<Akonadi::AgentInstance>();
361 
362  d->createDBusInterface();
363 
364  QDBusServiceWatcher *watcher = new QDBusServiceWatcher( ServerManager::serviceName( ServerManager::Control ),
365  DBusConnectionPool::threadConnection(),
366  QDBusServiceWatcher::WatchForOwnerChange, this );
367  connect( watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
368  this, SLOT(serviceOwnerChanged(QString,QString,QString)) );
369 }
370 
371 // @endcond
372 
373 AgentManager::~AgentManager()
374 {
375  delete d;
376 }
377 
378 AgentManager* AgentManager::self()
379 {
380  if ( !AgentManagerPrivate::mSelf ) {
381  AgentManagerPrivate::mSelf = new AgentManager();
382  }
383 
384  return AgentManagerPrivate::mSelf;
385 }
386 
387 AgentType::List AgentManager::types() const
388 {
389  return d->mTypes.values();
390 }
391 
392 AgentType AgentManager::type( const QString &identifier ) const
393 {
394  return d->mTypes.value( identifier );
395 }
396 
397 AgentInstance::List AgentManager::instances() const
398 {
399  return d->mInstances.values();
400 }
401 
402 AgentInstance AgentManager::instance( const QString &identifier ) const
403 {
404  return d->mInstances.value( identifier );
405 }
406 
407 void AgentManager::removeInstance( const AgentInstance &instance )
408 {
409  d->mManager->removeAgentInstance( instance.identifier() );
410 }
411 
412 void AgentManager::synchronizeCollection( const Collection & collection )
413 {
414  synchronizeCollection( collection, false );
415 }
416 
417 void AgentManager::synchronizeCollection( const Collection & collection, bool recursive )
418 {
419  const QString resId = collection.resource();
420  Q_ASSERT( !resId.isEmpty() );
421  d->mManager->agentInstanceSynchronizeCollection( resId, collection.id(), recursive );
422 }
423 
424 #include "moc_agentmanager.cpp"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:27:31 by doxygen 1.8.3.1 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.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • 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