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

Skip menu "kdepimlibs-4.9.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