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

KDE's Doxygen guidelines are available online.