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

akonadi

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

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