Akonadi

agentbase.h
1 /*
2  This file is part of akonadiresources.
3 
4  SPDX-FileCopyrightText: 2006 Till Adam <[email protected]>
5  SPDX-FileCopyrightText: 2007 Volker Krause <[email protected]>
6  SPDX-FileCopyrightText: 2008 Kevin Krammer <[email protected]>
7 
8  SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10 
11 #pragma once
12 
13 #include "akonadiagentbase_export.h"
14 #include "item.h"
15 
16 #include <QApplication>
17 
18 #include <KSharedConfig>
19 
20 #include <QDBusConnection>
21 #include <QDBusContext>
22 
23 class Akonadi__ControlAdaptor;
24 class Akonadi__StatusAdaptor;
25 
26 class KAboutData;
27 
28 namespace Akonadi
29 {
30 class AgentBasePrivate;
31 class ChangeRecorder;
32 class Collection;
33 class Item;
34 
35 /**
36  * @short The base class for all Akonadi agents and resources.
37  *
38  * This class is a base class for all Akonadi agents, which covers the real
39  * agent processes and all resources.
40  *
41  * It provides:
42  * - lifetime management
43  * - change monitoring and recording
44  * - configuration interface
45  * - problem reporting
46  *
47  * Akonadi Server supports several ways to launch agents and resources:
48  * - As a separate application (@see AKONADI_AGENT_MAIN)
49  * - As a thread in the AgentServer
50  * - As a separate process, using the akonadi_agent_launcher
51  *
52  * The idea is this, the agent or resource is written as a plugin instead of an
53  * executable (@see AgentFactory). In the AgentServer case, the AgentServer
54  * looks up the plugin and launches the agent in a separate thread. In the
55  * launcher case, a new akonadi_agent_launcher process is started for each
56  * agent or resource instance.
57  *
58  * When making an Agent or Resource suitable for running in the AgentServer some
59  * extra caution is needed. Because multiple instances of several kinds of agents
60  * run in the same process, one cannot blindly use global objects like KGlobal.
61  * For this reasons several methods where added to avoid problems in this context,
62  * most notably AgentBase::config(). Additionally,
63  * one cannot use QDBusConnection::sessionBus() with dbus < 1.4, because of a
64  * multithreading bug in libdbus. Instead one should use
65  * QDBusConnection::sessionBus() which works around this problem.
66  *
67  * @author Till Adam <[email protected]>, Volker Krause <[email protected]>
68  */
69 class AKONADIAGENTBASE_EXPORT AgentBase : public QObject, protected QDBusContext
70 {
71  Q_OBJECT
72 
73 public:
74  /**
75  * @short The interface for reacting on monitored or replayed changes.
76  *
77  * The Observer provides an interface to react on monitored or replayed changes.
78  *
79  * Since the this base class does only tell the change recorder that the change
80  * has been processed, an AgentBase subclass which wants to actually process
81  * the change needs to subclass Observer and reimplement the methods it is
82  * interested in.
83  *
84  * Such an agent specific Observer implementation can either be done
85  * stand-alone, i.e. as a separate object, or by inheriting both AgentBase
86  * and AgentBase::Observer.
87  *
88  * The observer implementation then has registered with the agent, so it
89  * can forward the incoming changes to the observer.
90  *
91  * @note In the multiple inheritance approach the init() method automatically
92  * registers itself as the observer.
93  *
94  * @note Do not call the base implementation of reimplemented virtual methods!
95  * The default implementation disconnected themselves from the Akonadi::ChangeRecorder
96  * to enable internal optimizations for unused notifications.
97  *
98  * Example for stand-alone observer:
99  * @code
100  * class ExampleAgent : public AgentBase
101  * {
102  * public:
103  * ExampleAgent( const QString &id );
104  *
105  * ~ExampleAgent();
106  *
107  * private:
108  * AgentBase::Observer *mObserver;
109  * };
110  *
111  * class ExampleObserver : public AgentBase::Observer
112  * {
113  * protected:
114  * void itemChanged( const Item &item );
115  * };
116  *
117  * ExampleAgent::ExampleAgent( const QString &id )
118  : AgentBase( id )
119  , mObserver( 0 )
120  * {
121  * mObserver = new ExampleObserver();
122  * registerObserver( mObserver );
123  * }
124  *
125  * ExampleAgent::~ExampleAgent()
126  * {
127  * delete mObserver;
128  * }
129  *
130  * void ExampleObserver::itemChanged( const Item &item )
131  * {
132  * // do something with item
133  * qCDebug(AKONADIAGENTBASE_LOG) << "Item id=" << item.id();
134  *
135  * // let base implementation tell the change recorder that we
136  * // have processed the change
137  * AgentBase::Observer::itemChanged( item );
138  * }
139  * @endcode
140  *
141  * Example for observer through multiple inheritance:
142  * @code
143  * class ExampleAgent : public AgentBase, public AgentBase::Observer
144  * {
145  * public:
146  * ExampleAgent( const QString &id );
147  *
148  * protected:
149  * void itemChanged( const Item &item );
150  * };
151  *
152  * ExampleAgent::ExampleAgent( const QString &id )
153  : AgentBase( id )
154  * {
155  * // no need to create or register observer since
156  * // we are the observer and registration happens automatically
157  * // in init()
158  * }
159  *
160  * void ExampleAgent::itemChanged( const Item &item )
161  * {
162  * // do something with item
163  * qCDebug(AKONADIAGENTBASE_LOG) << "Item id=" << item.id();
164  *
165  * // let base implementation tell the change recorder that we
166  * // have processed the change
167  * AgentBase::Observer::itemChanged( item );
168  * }
169  * @endcode
170  *
171  * @author Kevin Krammer <[email protected]>
172  *
173  * @deprecated Use ObserverV2 instead
174  */
175  class AKONADIAGENTBASE_DEPRECATED AKONADIAGENTBASE_EXPORT Observer // krazy:exclude=dpointer
176  {
177  public:
178  /**
179  * Creates an observer instance.
180  */
181  Observer();
182 
183  /**
184  * Destroys the observer instance.
185  */
186  virtual ~Observer();
187 
188  /**
189  * Reimplement to handle adding of new items.
190  * @param item The newly added item.
191  * @param collection The collection @p item got added to.
192  */
193  virtual void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection);
194 
195  /**
196  * Reimplement to handle changes to existing items.
197  * @param item The changed item.
198  * @param partIdentifiers The identifiers of the item parts that has been changed.
199  */
200  virtual void itemChanged(const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers);
201 
202  /**
203  * Reimplement to handle deletion of items.
204  * @param item The deleted item.
205  */
206  virtual void itemRemoved(const Akonadi::Item &item);
207 
208  /**
209  * Reimplement to handle adding of new collections.
210  * @param collection The newly added collection.
211  * @param parent The parent collection.
212  */
213  virtual void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent);
214 
215  /**
216  * Reimplement to handle changes to existing collections.
217  * @param collection The changed collection.
218  */
219  virtual void collectionChanged(const Akonadi::Collection &collection);
220 
221  /**
222  * Reimplement to handle deletion of collections.
223  * @param collection The deleted collection.
224  */
225  virtual void collectionRemoved(const Akonadi::Collection &collection);
226  };
227 
228  /**
229  * BC extension of Observer with support for monitoring item and collection moves.
230  * Use this one instead of Observer.
231  *
232  * @since 4.4
233  */
234  class AKONADIAGENTBASE_EXPORT ObserverV2 : public Observer // krazy:exclude=dpointer
235  {
236  public:
237  using Observer::collectionChanged;
238 
239  /**
240  * Reimplement to handle item moves.
241  * When using this class in combination with Akonadi::ResourceBase, inter-resource
242  * moves are handled internally already and the corresponding add or delete method
243  * is called instead.
244  *
245  * @param item The moved item.
246  * @param collectionSource The collection the item has been moved from.
247  * @param collectionDestination The collection the item has been moved to.
248  */
249  virtual void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination);
250 
251  /**
252  * Reimplement to handle item linking.
253  * This is only relevant for virtual resources.
254  * @param item The linked item.
255  * @param collection The collection the item is linked to.
256  */
257  virtual void itemLinked(const Akonadi::Item &item, const Akonadi::Collection &collection);
258 
259  /**
260  * Reimplement to handle item unlinking.
261  * This is only relevant for virtual resources.
262  * @param item The unlinked item.
263  * @param collection The collection the item is unlinked from.
264  */
265  virtual void itemUnlinked(const Akonadi::Item &item, const Akonadi::Collection &collection);
266 
267  /**
268  * Reimplement to handle collection moves.
269  * When using this class in combination with Akonadi::ResourceBase, inter-resource
270  * moves are handled internally already and the corresponding add or delete method
271  * is called instead.
272  *
273  * @param collection The moved collection.
274  * @param collectionSource The previous parent collection.
275  * @param collectionDestination The new parent collection.
276  */
277  virtual void
278  collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination);
279 
280  /**
281  * Reimplement to handle changes to existing collections.
282  * @param collection The changed collection.
283  * @param changedAttributes The identifiers of the collection parts/attributes that has been changed.
284  */
285  virtual void collectionChanged(const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes);
286  };
287 
288  /**
289  * BC extension of ObserverV2 with support for batch operations
290  *
291  * @warning When using ObserverV3, you will never get single-item notifications
292  * from AgentBase::Observer, even when you don't reimplement corresponding batch
293  * method from ObserverV3. For instance, when you don't reimplement itemsRemoved()
294  * here, you will not get any notifications about item removal whatsoever!
295  *
296  * @since 4.11
297  */
298  class AKONADIAGENTBASE_EXPORT ObserverV3 : public ObserverV2 // krazy:exclude=dpointer
299  {
300  public:
301  /**
302  * Reimplement to handle changes in flags of existing items
303  *
304  * @warning When using ObserverV3, you will never get notifications about
305  * flag changes via Observer::itemChanged(), even when you don't reimplement
306  * itemsFlagsChanged()!
307  *
308  * @param items The changed items
309  * @param addedFlags Flags that have been added to the item
310  * @param removedFlags Flags that have been removed from the item
311  */
312  virtual void itemsFlagsChanged(const Akonadi::Item::List &items, const QSet<QByteArray> &addedFlags, const QSet<QByteArray> &removedFlags);
313 
314  /**
315  * Reimplement to handle batch notification about items deletion.
316  *
317  * @param items List of deleted items
318  */
319  virtual void itemsRemoved(const Akonadi::Item::List &items);
320 
321  /**
322  * Reimplement to handle batch notification about items move
323  *
324  * @param items List of moved items
325  * @param sourceCollection Collection from where the items were moved
326  * @param destinationCollection Collection to which the items were moved
327  */
328  virtual void
329  itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &sourceCollection, const Akonadi::Collection &destinationCollection);
330 
331  /**
332  * Reimplement to handle batch notifications about items linking.
333  *
334  * @param items Linked items
335  * @param collection Collection to which the items have been linked
336  */
337  virtual void itemsLinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection);
338 
339  /**
340  * Reimplement to handle batch notifications about items unlinking.
341  *
342  * @param items Unlinked items
343  * @param collection Collection from which the items have been unlinked
344  */
345  virtual void itemsUnlinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection);
346  };
347 
348  /**
349  * Observer that adds support for item tagging
350  *
351  * @warning ObserverV4 subclasses ObserverV3 which changes behavior of some of the
352  * virtual methods from Observer and ObserverV2. Please make sure you read
353  * documentation of ObserverV3 and adapt your agent accordingly.
354  *
355  * @since 4.13
356  */
357  class AKONADIAGENTBASE_EXPORT ObserverV4 : public ObserverV3 // krazy:exclude=dpointer
358  {
359  public:
360  /**
361  * Reimplement to handle tags additions
362  *
363  * @param tag Newly added tag
364  */
365  virtual void tagAdded(const Akonadi::Tag &tag);
366 
367  /**
368  * Reimplement to handle tags changes
369  *
370  * @param tag Tag that has been changed
371  */
372  virtual void tagChanged(const Akonadi::Tag &tag);
373 
374  /**
375  * Reimplement to handle tags removal.
376  *
377  * @note All items that were tagged by @p tag will get a separate notification
378  * about untagging via itemsTagsChanged(). It is guaranteed that the itemsTagsChanged()
379  * notification will be delivered before this one.
380  *
381  * @param tag Tag that has been removed.
382  */
383  virtual void tagRemoved(const Akonadi::Tag &tag);
384 
385  /**
386  * Reimplement to handle items tagging
387  *
388  * @param items Items that were tagged or untagged
389  * @param addedTags Set of tags that were added to all @p items
390  * @param removedTags Set of tags that were removed from all @p items
391  */
392  virtual void itemsTagsChanged(const Akonadi::Item::List &items, const QSet<Akonadi::Tag> &addedTags, const QSet<Akonadi::Tag> &removedTags);
393 
394  /**
395  * Reimplement to handle relations being added
396  */
397  virtual void relationAdded(const Akonadi::Relation &relation);
398 
399  /**
400  * Reimplement to handle relations being removed
401  */
402  virtual void relationRemoved(const Akonadi::Relation &relation);
403 
404  /**
405  * Reimplement to handled relations changing on items
406  * @param items Items that had relations added/removed from them
407  * @param addedRelations the list of relations that were added to all @p items
408  * @param removedRelations the list of relations that were removed from all @p items
409  */
410  virtual void
411  itemsRelationsChanged(const Akonadi::Item::List &items, const Akonadi::Relation::List &addedRelations, const Akonadi::Relation::List &removedRelations);
412  };
413 
414  /**
415  * This enum describes the different states the
416  * agent can be in.
417  */
418  enum Status {
419  Idle = 0, ///< The agent does currently nothing.
420  Running, ///< The agent is working on something.
421  Broken, ///< The agent encountered an error state.
422  NotConfigured ///< The agent is lacking required configuration
423  };
424 
425  /**
426  * Use this method in the main function of your agent
427  * application to initialize your agent subclass.
428  * This method also takes care of creating a KApplication
429  * object and parsing command line arguments.
430  *
431  * @note In case the given class is also derived from AgentBase::Observer
432  * it gets registered as its own observer (see AgentBase::Observer), e.g.
433  * <tt>agentInstance->registerObserver( agentInstance );</tt>
434  *
435  * @code
436  *
437  * class MyAgent : public AgentBase
438  * {
439  * ...
440  * };
441  *
442  * AKONADI_AGENT_MAIN( MyAgent )
443  *
444  * @endcode
445  *
446  * @param argc number of arguments
447  * @param argv arguments for the function
448  */
449  template<typename T> static int init(int argc, char **argv)
450  {
451  // Disable session management
452  qunsetenv("SESSION_MANAGER");
453 
454  QApplication app(argc, argv);
455  debugAgent(argc, argv);
456  const QString id = parseArguments(argc, argv);
457  T r(id);
458 
459  // check if T also inherits AgentBase::Observer and
460  // if it does, automatically register it on itself
461  auto observer = dynamic_cast<Observer *>(&r);
462  if (observer != nullptr) {
463  r.registerObserver(observer);
464  }
465  return init(r);
466  }
467 
468  /**
469  * This method returns the current status code of the agent.
470  *
471  * The following return values are possible:
472  *
473  * - 0 - Idle
474  * - 1 - Running
475  * - 2 - Broken
476  * - 3 - NotConfigured
477  */
478  Q_REQUIRED_RESULT virtual int status() const;
479 
480  /**
481  * This method returns an i18n'ed description of the current status code.
482  */
483  Q_REQUIRED_RESULT virtual QString statusMessage() const;
484 
485  /**
486  * This method returns the current progress of the agent in percentage.
487  */
488  Q_REQUIRED_RESULT virtual int progress() const;
489 
490  /**
491  * This method returns an i18n'ed description of the current progress.
492  */
493  Q_REQUIRED_RESULT virtual QString progressMessage() const;
494 
495 public Q_SLOTS:
496  /**
497  * This method is called whenever the agent shall show its configuration dialog
498  * to the user. It will be automatically called when the agent is started for
499  * the first time.
500  *
501  * @param windowId The parent window id.
502  *
503  * @note If the method is reimplemented it has to emit the configurationDialogAccepted()
504  * or configurationDialogRejected() signals depending on the users choice.
505  */
506  virtual void configure(WId windowId);
507 
508 public:
509  /**
510  * This method returns the windows id, which should be used for dialogs.
511  */
512  Q_REQUIRED_RESULT WId winIdForDialogs() const;
513 
514 #ifdef Q_OS_WIN
515  /**
516  * Overload of @ref configure needed because WId cannot be automatically casted
517  * to qlonglong on Windows.
518  */
519  void configure(qlonglong windowId);
520 #endif
521 
522  /**
523  * Returns the instance identifier of this agent.
524  */
525  Q_REQUIRED_RESULT QString identifier() const;
526 
527  /**
528  * This method is called when the agent is removed from
529  * the system, so it can do some cleanup stuff.
530  *
531  * @note If you reimplement this in a subclass make sure
532  * to call this base implementation at the end.
533  */
534  virtual void cleanup();
535 
536  /**
537  * Registers the given observer for reacting on monitored or recorded changes.
538  *
539  * @param observer The change handler to register. No ownership transfer, i.e.
540  * the caller stays owner of the pointer and can reset
541  * the registration by calling this method with @c 0
542  */
543  void registerObserver(Observer *observer);
544 
545  /**
546  * This method is used to set the name of the agent.
547  *
548  * @since 4.3
549  * @param name name of the agent
550  */
551  // FIXME_API: make sure location is renamed to this by agentbase
552  void setAgentName(const QString &name);
553 
554  /**
555  * Returns the name of the agent.
556  *
557  * @since 4.3
558  */
559  Q_REQUIRED_RESULT QString agentName() const;
560 
561 Q_SIGNALS:
562  /**
563  * This signal is emitted whenever the name of the agent has changed.
564  *
565  * @param name The new name of the agent.
566  *
567  * @since 4.3
568  */
569  void agentNameChanged(const QString &name);
570 
571  /**
572  * This signal should be emitted whenever the status of the agent has been changed.
573  * @param status The new Status code.
574  * @param message A i18n'ed description of the new status.
575  */
576  void status(int status, const QString &message = QString());
577 
578  /**
579  * This signal should be emitted whenever the progress of an action in the agent
580  * (e.g. data transfer, connection establishment to remote server etc.) has changed.
581  *
582  * @param progress The progress of the action in percent.
583  */
584  void percent(int progress);
585 
586  /**
587  * This signal shall be used to report warnings.
588  *
589  * @param message The i18n'ed warning message.
590  */
591  void warning(const QString &message);
592 
593  /**
594  * This signal shall be used to report errors.
595  *
596  * @param message The i18n'ed error message.
597  */
598  void error(const QString &message);
599 
600  /**
601  * This signal should be emitted whenever the status of the agent has been changed.
602  * @param status The object that describes the status change.
603  *
604  * @since 4.6
605  */
606  void advancedStatus(const QVariantMap &status);
607 
608  /**
609  * Emitted when another application has remotely asked the agent to abort
610  * its current operation.
611  * Connect to this signal if your agent supports abortion. After aborting
612  * and cleaning up, agents should return to Idle status.
613  *
614  * @since 4.4
615  */
616  void abortRequested();
617 
618  /**
619  * Emitted if another application has changed the agent's configuration remotely
620  * and called AgentInstance::reconfigure().
621  *
622  * @since 4.2
623  */
624  void reloadConfiguration();
625 
626  /**
627  * Emitted when the online state changed.
628  * @param online The online state.
629  * @since 4.2
630  */
631  void onlineChanged(bool online);
632 
633  /**
634  * This signal is emitted whenever the user has accepted the configuration dialog.
635  *
636  * @note Implementors of agents/resources are responsible to emit this signal if
637  * the agent/resource reimplements configure().
638  *
639  * @since 4.4
640  */
641  void configurationDialogAccepted();
642 
643  /**
644  * This signal is emitted whenever the user has rejected the configuration dialog.
645  *
646  * @note Implementors of agents/resources are responsible to emit this signal if
647  * the agent/resource reimplements configure().
648  *
649  * @since 4.4
650  */
651  void configurationDialogRejected();
652 
653 protected:
654  /**
655  * Creates an agent base.
656  *
657  * @param id The instance id of the agent.
658  */
659  AgentBase(const QString &id);
660 
661  /**
662  * Destroys the agent base.
663  */
664  ~AgentBase();
665 
666  /**
667  * This method is called whenever the agent application is about to
668  * quit.
669  *
670  * Reimplement this method to do session cleanup (e.g. disconnecting
671  * from groupware server).
672  */
673  virtual void aboutToQuit();
674 
675  /**
676  * Returns the Akonadi::ChangeRecorder object used for monitoring.
677  * Use this to configure which parts you want to monitor.
678  */
679  ChangeRecorder *changeRecorder() const;
680 
681  /**
682  * Returns the config object for this Agent.
683  */
684  KSharedConfigPtr config();
685 
686  /**
687  * Marks the current change as processes and replays the next change if change
688  * recording is enabled (noop otherwise). This method is called
689  * from the default implementation of the change notification slots. While not
690  * required when not using change recording, it is nevertheless recommended
691  * to call this method when done with processing a change notification.
692  */
693  void changeProcessed();
694 
695  /**
696  * Returns whether the agent is currently online.
697  */
698  bool isOnline() const;
699 
700  /**
701  * Sets whether the agent needs network or not.
702  *
703  * @since 4.2
704  * @todo use this in combination with QNetworkConfiguration to change
705  * the onLine status of the agent.
706  * @param needsNetwork @c true if the agents needs network. Defaults to @c false
707  */
708  void setNeedsNetwork(bool needsNetwork);
709 
710  /**
711  * Sets whether the agent shall be online or not.
712  */
713  void setOnline(bool state);
714 
715 protected:
716  /**
717  * Sets the agent offline but will make it online again after a given time
718  *
719  * Use this method when the agent detects some problem with its backend but it wants
720  * to retry all pending operations after some time - e.g. a server can not be reached currently
721  *
722  * Example usage:
723  * @code
724  * void ExampleResource::onItemRemovedFinished(KJob *job)
725  * {
726  * if (job->error()) {
727  * Q_EMIT status(Broken, job->errorString());
728  * deferTask();
729  * setTemporaryOffline(300);
730  * return;
731  * }
732  * ...
733  * }
734  * @endcode
735  *
736  * @since 4.13
737  * @param makeOnlineInSeconds timeout in seconds after which the agent changes to online
738  */
739  void setTemporaryOffline(int makeOnlineInSeconds = 300);
740 
741  /// @cond PRIVATE
742  static void debugAgent(int argc, char **argv);
743 
744  AgentBasePrivate *d_ptr;
745  explicit AgentBase(AgentBasePrivate *d, const QString &id);
746  friend class ObserverV2;
747  /// @endcond
748 
749  /**
750  * This method is called whenever the @p online status has changed.
751  * Reimplement this method to react on online status changes.
752  * @param online online status
753  */
754  virtual void doSetOnline(bool online);
755 
756  virtual KAboutData aboutData() const;
757 
758 private:
759  /// @cond PRIVATE
760  static QString parseArguments(int argc, char **argv);
761  static int init(AgentBase &r);
762  void setOnlineInternal(bool state);
763 
764  // D-Bus interface stuff
765  void abort();
766  void reconfigure();
767  void quit();
768 
769  // dbus agent interface
770  friend class ::Akonadi__StatusAdaptor;
771  friend class ::Akonadi__ControlAdaptor;
772 
773  Q_DECLARE_PRIVATE(AgentBase)
774  Q_PRIVATE_SLOT(d_func(), void delayedInit())
775  Q_PRIVATE_SLOT(d_func(), void slotStatus(int, const QString &))
776  Q_PRIVATE_SLOT(d_func(), void slotPercent(int))
777  Q_PRIVATE_SLOT(d_func(), void slotWarning(const QString &))
778  Q_PRIVATE_SLOT(d_func(), void slotError(const QString &))
779  Q_PRIVATE_SLOT(d_func(), void slotNetworkStatusChange(bool))
780  Q_PRIVATE_SLOT(d_func(), void slotResumedFromSuspend())
781  Q_PRIVATE_SLOT(d_func(), void slotTemporaryOfflineTimeout())
782 
783  /// @endcond
784 };
785 
786 }
787 
788 #ifndef AKONADI_AGENT_MAIN
789 /**
790  * Convenience Macro for the most common main() function for Akonadi agents.
791  */
792 #define AKONADI_AGENT_MAIN(agentClass) \
793  int main(int argc, char **argv) \
794  { \
795  return Akonadi::AgentBase::init<agentClass>(argc, argv); \
796  }
797 #endif
798 
An Akonadi Relation.
Definition: relation.h:38
Status
This enum describes the different states the agent can be in.
Definition: agentbase.h:418
Represents a collection of PIM items.
Definition: collection.h:61
static int init(int argc, char **argv)
Use this method in the main function of your agent application to initialize your agent subclass...
Definition: agentbase.h:449
The interface for reacting on monitored or replayed changes.
Definition: agentbase.h:175
The base class for all Akonadi agents and resources.
Definition: agentbase.h:69
BC extension of Observer with support for monitoring item and collection moves.
Definition: agentbase.h:234
BC extension of ObserverV2 with support for batch operations.
Definition: agentbase.h:298
QCA_EXPORT void init()
The agent encountered an error state.
Definition: agentbase.h:421
Helper integration between Akonadi and Qt.
Observer that adds support for item tagging.
Definition: agentbase.h:357
An Akonadi Tag.
Definition: tag.h:25
The agent is working on something.
Definition: agentbase.h:420
Represents a PIM item stored in Akonadi storage.
Definition: item.h:100
Records and replays change notification.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Aug 3 2021 23:17:53 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.