File indexing completed on 2024-06-23 05:06:30
0001 /* 0002 This file is part of akonadiresources. 0003 0004 SPDX-FileCopyrightText: 2006 Till Adam <adam@kde.org> 0005 SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org> 0006 SPDX-FileCopyrightText: 2008 Kevin Krammer <kevin.krammer@gmx.at> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #pragma once 0012 0013 #include "akonadiagentbase_export.h" 0014 // AkonadiCore 0015 #include "akonadi/item.h" 0016 0017 #include <QApplication> 0018 0019 #include <KSharedConfig> 0020 0021 #include <QDBusConnection> 0022 #include <QDBusContext> 0023 0024 #include <memory> 0025 0026 class Akonadi__ControlAdaptor; 0027 class Akonadi__StatusAdaptor; 0028 0029 class KAboutData; 0030 0031 namespace Akonadi 0032 { 0033 class AgentBasePrivate; 0034 class ChangeRecorder; 0035 class Collection; 0036 class Item; 0037 0038 /** 0039 * @short The base class for all Akonadi agents and resources. 0040 * 0041 * This class is a base class for all Akonadi agents, which covers the real 0042 * agent processes and all resources. 0043 * 0044 * It provides: 0045 * - lifetime management 0046 * - change monitoring and recording 0047 * - configuration interface 0048 * - problem reporting 0049 * 0050 * Akonadi Server supports several ways to launch agents and resources: 0051 * - As a separate application (@see AKONADI_AGENT_MAIN) 0052 * - As a thread in the AgentServer 0053 * - As a separate process, using the akonadi_agent_launcher 0054 * 0055 * The idea is this, the agent or resource is written as a plugin instead of an 0056 * executable (@see AgentFactory). In the AgentServer case, the AgentServer 0057 * looks up the plugin and launches the agent in a separate thread. In the 0058 * launcher case, a new akonadi_agent_launcher process is started for each 0059 * agent or resource instance. 0060 * 0061 * When making an Agent or Resource suitable for running in the AgentServer some 0062 * extra caution is needed. Because multiple instances of several kinds of agents 0063 * run in the same process, one cannot blindly use global objects like KGlobal. 0064 * For this reasons several methods where added to avoid problems in this context, 0065 * most notably AgentBase::config(). Additionally, 0066 * one cannot use QDBusConnection::sessionBus() with dbus < 1.4, because of a 0067 * multithreading bug in libdbus. Instead one should use 0068 * QDBusConnection::sessionBus() which works around this problem. 0069 * 0070 * @author Till Adam <adam@kde.org>, Volker Krause <vkrause@kde.org> 0071 */ 0072 class AKONADIAGENTBASE_EXPORT AgentBase : public QObject, protected QDBusContext 0073 { 0074 Q_OBJECT 0075 0076 public: 0077 /** 0078 * @short The interface for reacting on monitored or replayed changes. 0079 * 0080 * The Observer provides an interface to react on monitored or replayed changes. 0081 * 0082 * Since the this base class does only tell the change recorder that the change 0083 * has been processed, an AgentBase subclass which wants to actually process 0084 * the change needs to subclass Observer and reimplement the methods it is 0085 * interested in. 0086 * 0087 * Such an agent specific Observer implementation can either be done 0088 * stand-alone, i.e. as a separate object, or by inheriting both AgentBase 0089 * and AgentBase::Observer. 0090 * 0091 * The observer implementation then has registered with the agent, so it 0092 * can forward the incoming changes to the observer. 0093 * 0094 * @note In the multiple inheritance approach the init() method automatically 0095 * registers itself as the observer. 0096 * 0097 * @note Do not call the base implementation of reimplemented virtual methods! 0098 * The default implementation disconnected themselves from the Akonadi::ChangeRecorder 0099 * to enable internal optimizations for unused notifications. 0100 * 0101 * Example for stand-alone observer: 0102 * @code 0103 * class ExampleAgent : public AgentBase 0104 * { 0105 * public: 0106 * ExampleAgent( const QString &id ); 0107 * 0108 * ~ExampleAgent(); 0109 * 0110 * private: 0111 * AgentBase::Observer *mObserver; 0112 * }; 0113 * 0114 * class ExampleObserver : public AgentBase::Observer 0115 * { 0116 * protected: 0117 * void itemChanged( const Item &item ); 0118 * }; 0119 * 0120 * ExampleAgent::ExampleAgent( const QString &id ) 0121 : AgentBase( id ) 0122 , mObserver( 0 ) 0123 * { 0124 * mObserver = new ExampleObserver(); 0125 * registerObserver( mObserver ); 0126 * } 0127 * 0128 * ExampleAgent::~ExampleAgent() 0129 * { 0130 * delete mObserver; 0131 * } 0132 * 0133 * void ExampleObserver::itemChanged( const Item &item ) 0134 * { 0135 * // do something with item 0136 * qCDebug(AKONADIAGENTBASE_LOG) << "Item id=" << item.id(); 0137 * 0138 * // let base implementation tell the change recorder that we 0139 * // have processed the change 0140 * AgentBase::Observer::itemChanged( item ); 0141 * } 0142 * @endcode 0143 * 0144 * Example for observer through multiple inheritance: 0145 * @code 0146 * class ExampleAgent : public AgentBase, public AgentBase::Observer 0147 * { 0148 * public: 0149 * ExampleAgent( const QString &id ); 0150 * 0151 * protected: 0152 * void itemChanged( const Item &item ); 0153 * }; 0154 * 0155 * ExampleAgent::ExampleAgent( const QString &id ) 0156 : AgentBase( id ) 0157 * { 0158 * // no need to create or register observer since 0159 * // we are the observer and registration happens automatically 0160 * // in init() 0161 * } 0162 * 0163 * void ExampleAgent::itemChanged( const Item &item ) 0164 * { 0165 * // do something with item 0166 * qCDebug(AKONADIAGENTBASE_LOG) << "Item id=" << item.id(); 0167 * 0168 * // let base implementation tell the change recorder that we 0169 * // have processed the change 0170 * AgentBase::Observer::itemChanged( item ); 0171 * } 0172 * @endcode 0173 * 0174 * @author Kevin Krammer <kevin.krammer@gmx.at> 0175 * 0176 * @deprecated Use ObserverV2 instead 0177 */ 0178 class AKONADIAGENTBASE_DEPRECATED AKONADIAGENTBASE_EXPORT Observer // krazy:exclude=dpointer 0179 { 0180 public: 0181 /** 0182 * Creates an observer instance. 0183 */ 0184 Observer(); 0185 0186 /** 0187 * Destroys the observer instance. 0188 */ 0189 virtual ~Observer(); 0190 0191 /** 0192 * Reimplement to handle adding of new items. 0193 * @param item The newly added item. 0194 * @param collection The collection @p item got added to. 0195 */ 0196 virtual void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection); 0197 0198 /** 0199 * Reimplement to handle changes to existing items. 0200 * @param item The changed item. 0201 * @param partIdentifiers The identifiers of the item parts that has been changed. 0202 */ 0203 virtual void itemChanged(const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers); 0204 0205 /** 0206 * Reimplement to handle deletion of items. 0207 * @param item The deleted item. 0208 */ 0209 virtual void itemRemoved(const Akonadi::Item &item); 0210 0211 /** 0212 * Reimplement to handle adding of new collections. 0213 * @param collection The newly added collection. 0214 * @param parent The parent collection. 0215 */ 0216 virtual void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent); 0217 0218 /** 0219 * Reimplement to handle changes to existing collections. 0220 * @param collection The changed collection. 0221 */ 0222 virtual void collectionChanged(const Akonadi::Collection &collection); 0223 0224 /** 0225 * Reimplement to handle deletion of collections. 0226 * @param collection The deleted collection. 0227 */ 0228 virtual void collectionRemoved(const Akonadi::Collection &collection); 0229 }; 0230 0231 /** 0232 * BC extension of Observer with support for monitoring item and collection moves. 0233 * Use this one instead of Observer. 0234 * 0235 * @since 4.4 0236 */ 0237 class AKONADIAGENTBASE_EXPORT ObserverV2 : public Observer // krazy:exclude=dpointer 0238 { 0239 public: 0240 using Observer::collectionChanged; 0241 0242 /** 0243 * Reimplement to handle item moves. 0244 * When using this class in combination with Akonadi::ResourceBase, inter-resource 0245 * moves are handled internally already and the corresponding add or delete method 0246 * is called instead. 0247 * 0248 * @param item The moved item. 0249 * @param collectionSource The collection the item has been moved from. 0250 * @param collectionDestination The collection the item has been moved to. 0251 */ 0252 virtual void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination); 0253 0254 /** 0255 * Reimplement to handle item linking. 0256 * This is only relevant for virtual resources. 0257 * @param item The linked item. 0258 * @param collection The collection the item is linked to. 0259 */ 0260 virtual void itemLinked(const Akonadi::Item &item, const Akonadi::Collection &collection); 0261 0262 /** 0263 * Reimplement to handle item unlinking. 0264 * This is only relevant for virtual resources. 0265 * @param item The unlinked item. 0266 * @param collection The collection the item is unlinked from. 0267 */ 0268 virtual void itemUnlinked(const Akonadi::Item &item, const Akonadi::Collection &collection); 0269 0270 /** 0271 * Reimplement to handle collection moves. 0272 * When using this class in combination with Akonadi::ResourceBase, inter-resource 0273 * moves are handled internally already and the corresponding add or delete method 0274 * is called instead. 0275 * 0276 * @param collection The moved collection. 0277 * @param collectionSource The previous parent collection. 0278 * @param collectionDestination The new parent collection. 0279 */ 0280 virtual void 0281 collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination); 0282 0283 /** 0284 * Reimplement to handle changes to existing collections. 0285 * @param collection The changed collection. 0286 * @param changedAttributes The identifiers of the collection parts/attributes that has been changed. 0287 */ 0288 virtual void collectionChanged(const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes); 0289 }; 0290 0291 /** 0292 * BC extension of ObserverV2 with support for batch operations 0293 * 0294 * @warning When using ObserverV3, you will never get single-item notifications 0295 * from AgentBase::Observer, even when you don't reimplement corresponding batch 0296 * method from ObserverV3. For instance, when you don't reimplement itemsRemoved() 0297 * here, you will not get any notifications about item removal whatsoever! 0298 * 0299 * @since 4.11 0300 */ 0301 class AKONADIAGENTBASE_EXPORT ObserverV3 : public ObserverV2 // krazy:exclude=dpointer 0302 { 0303 public: 0304 /** 0305 * Reimplement to handle changes in flags of existing items 0306 * 0307 * @warning When using ObserverV3, you will never get notifications about 0308 * flag changes via Observer::itemChanged(), even when you don't reimplement 0309 * itemsFlagsChanged()! 0310 * 0311 * @param items The changed items 0312 * @param addedFlags Flags that have been added to the item 0313 * @param removedFlags Flags that have been removed from the item 0314 */ 0315 virtual void itemsFlagsChanged(const Akonadi::Item::List &items, const QSet<QByteArray> &addedFlags, const QSet<QByteArray> &removedFlags); 0316 0317 /** 0318 * Reimplement to handle batch notification about items deletion. 0319 * 0320 * @param items List of deleted items 0321 */ 0322 virtual void itemsRemoved(const Akonadi::Item::List &items); 0323 0324 /** 0325 * Reimplement to handle batch notification about items move 0326 * 0327 * @param items List of moved items 0328 * @param sourceCollection Collection from where the items were moved 0329 * @param destinationCollection Collection to which the items were moved 0330 */ 0331 virtual void 0332 itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &sourceCollection, const Akonadi::Collection &destinationCollection); 0333 0334 /** 0335 * Reimplement to handle batch notifications about items linking. 0336 * 0337 * @param items Linked items 0338 * @param collection Collection to which the items have been linked 0339 */ 0340 virtual void itemsLinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection); 0341 0342 /** 0343 * Reimplement to handle batch notifications about items unlinking. 0344 * 0345 * @param items Unlinked items 0346 * @param collection Collection from which the items have been unlinked 0347 */ 0348 virtual void itemsUnlinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection); 0349 }; 0350 0351 /** 0352 * Observer that adds support for item tagging 0353 * 0354 * @warning ObserverV4 subclasses ObserverV3 which changes behavior of some of the 0355 * virtual methods from Observer and ObserverV2. Please make sure you read 0356 * documentation of ObserverV3 and adapt your agent accordingly. 0357 * 0358 * @since 4.13 0359 */ 0360 class AKONADIAGENTBASE_EXPORT ObserverV4 : public ObserverV3 // krazy:exclude=dpointer 0361 { 0362 public: 0363 /** 0364 * Reimplement to handle tags additions 0365 * 0366 * @param tag Newly added tag 0367 */ 0368 virtual void tagAdded(const Akonadi::Tag &tag); 0369 0370 /** 0371 * Reimplement to handle tags changes 0372 * 0373 * @param tag Tag that has been changed 0374 */ 0375 virtual void tagChanged(const Akonadi::Tag &tag); 0376 0377 /** 0378 * Reimplement to handle tags removal. 0379 * 0380 * @note All items that were tagged by @p tag will get a separate notification 0381 * about untagging via itemsTagsChanged(). It is guaranteed that the itemsTagsChanged() 0382 * notification will be delivered before this one. 0383 * 0384 * @param tag Tag that has been removed. 0385 */ 0386 virtual void tagRemoved(const Akonadi::Tag &tag); 0387 0388 /** 0389 * Reimplement to handle items tagging 0390 * 0391 * @param items Items that were tagged or untagged 0392 * @param addedTags Set of tags that were added to all @p items 0393 * @param removedTags Set of tags that were removed from all @p items 0394 */ 0395 virtual void itemsTagsChanged(const Akonadi::Item::List &items, const QSet<Akonadi::Tag> &addedTags, const QSet<Akonadi::Tag> &removedTags); 0396 0397 /** 0398 * Reimplement to handle relations being added 0399 */ 0400 virtual void relationAdded(const Akonadi::Relation &relation); 0401 0402 /** 0403 * Reimplement to handle relations being removed 0404 */ 0405 virtual void relationRemoved(const Akonadi::Relation &relation); 0406 0407 /** 0408 * Reimplement to handled relations changing on items 0409 * @param items Items that had relations added/removed from them 0410 * @param addedRelations the list of relations that were added to all @p items 0411 * @param removedRelations the list of relations that were removed from all @p items 0412 */ 0413 virtual void 0414 itemsRelationsChanged(const Akonadi::Item::List &items, const Akonadi::Relation::List &addedRelations, const Akonadi::Relation::List &removedRelations); 0415 }; 0416 0417 /** 0418 * This enum describes the different states the 0419 * agent can be in. 0420 */ 0421 enum Status { 0422 Idle = 0, ///< The agent does currently nothing. 0423 Running, ///< The agent is working on something. 0424 Broken, ///< The agent encountered an error state. 0425 NotConfigured ///< The agent is lacking required configuration 0426 }; 0427 0428 /** 0429 * Use this method in the main function of your agent 0430 * application to initialize your agent subclass. 0431 * This method also takes care of creating a KApplication 0432 * object and parsing command line arguments. 0433 * 0434 * @note In case the given class is also derived from AgentBase::Observer 0435 * it gets registered as its own observer (see AgentBase::Observer), e.g. 0436 * <tt>agentInstance->registerObserver( agentInstance );</tt> 0437 * 0438 * @code 0439 * 0440 * class MyAgent : public AgentBase 0441 * { 0442 * ... 0443 * }; 0444 * 0445 * AKONADI_AGENT_MAIN( MyAgent ) 0446 * 0447 * @endcode 0448 * 0449 * @param argc number of arguments 0450 * @param argv arguments for the function 0451 */ 0452 template<typename T> 0453 static int init(int argc, char **argv) 0454 { 0455 // Disable session management 0456 qunsetenv("SESSION_MANAGER"); 0457 0458 QApplication app(argc, argv); 0459 debugAgent(argc, argv); 0460 const QString id = parseArguments(argc, argv); 0461 T r(id); 0462 0463 // check if T also inherits AgentBase::Observer and 0464 // if it does, automatically register it on itself 0465 auto observer = dynamic_cast<Observer *>(&r); 0466 if (observer != nullptr) { 0467 r.registerObserver(observer); 0468 } 0469 return init(r); 0470 } 0471 0472 /** 0473 * This method returns the current status code of the agent. 0474 * 0475 * The following return values are possible: 0476 * 0477 * - 0 - Idle 0478 * - 1 - Running 0479 * - 2 - Broken 0480 * - 3 - NotConfigured 0481 */ 0482 [[nodiscard]] virtual int status() const; 0483 0484 /** 0485 * This method returns an i18n'ed description of the current status code. 0486 */ 0487 [[nodiscard]] virtual QString statusMessage() const; 0488 0489 /** 0490 * This method returns the current progress of the agent in percentage. 0491 */ 0492 [[nodiscard]] virtual int progress() const; 0493 0494 /** 0495 * This method returns an i18n'ed description of the current progress. 0496 */ 0497 [[nodiscard]] virtual QString progressMessage() const; 0498 0499 public Q_SLOTS: 0500 /** 0501 * This method is called whenever the agent shall show its configuration dialog 0502 * to the user. It will be automatically called when the agent is started for 0503 * the first time. 0504 * 0505 * @param windowId The parent window id. 0506 * 0507 * @note If the method is reimplemented it has to emit the configurationDialogAccepted() 0508 * or configurationDialogRejected() signals depending on the users choice. 0509 */ 0510 virtual void configure(WId windowId); 0511 0512 public: 0513 /** 0514 * This method returns the windows id, which should be used for dialogs. 0515 */ 0516 [[nodiscard]] WId winIdForDialogs() const; 0517 0518 #ifdef Q_OS_WIN 0519 /** 0520 * Overload of @ref configure needed because WId cannot be automatically casted 0521 * to qlonglong on Windows. 0522 */ 0523 void configure(qlonglong windowId); 0524 #endif 0525 0526 /** 0527 * Returns the instance identifier of this agent. 0528 */ 0529 [[nodiscard]] QString identifier() const; 0530 0531 /** 0532 * This method is called when the agent is removed from 0533 * the system, so it can do some cleanup stuff. 0534 * 0535 * @note If you reimplement this in a subclass make sure 0536 * to call this base implementation at the end. 0537 */ 0538 virtual void cleanup(); 0539 0540 /** 0541 * Registers the given observer for reacting on monitored or recorded changes. 0542 * 0543 * @param observer The change handler to register. No ownership transfer, i.e. 0544 * the caller stays owner of the pointer and can reset 0545 * the registration by calling this method with @c 0 0546 */ 0547 void registerObserver(Observer *observer); 0548 0549 /** 0550 * This method is used to set the name of the agent. 0551 * 0552 * @since 4.3 0553 * @param name name of the agent 0554 */ 0555 // FIXME_API: make sure location is renamed to this by agentbase 0556 void setAgentName(const QString &name); 0557 0558 /** 0559 * Returns the name of the agent. 0560 * 0561 * @since 4.3 0562 */ 0563 [[nodiscard]] QString agentName() const; 0564 0565 Q_SIGNALS: 0566 /** 0567 * This signal is emitted whenever the name of the agent has changed. 0568 * 0569 * @param name The new name of the agent. 0570 * 0571 * @since 4.3 0572 */ 0573 void agentNameChanged(const QString &name); 0574 0575 /** 0576 * This signal should be emitted whenever the status of the agent has been changed. 0577 * @param status The new Status code. 0578 * @param message A i18n'ed description of the new status. 0579 */ 0580 void status(int status, const QString &message = QString()); 0581 0582 /** 0583 * This signal should be emitted whenever the progress of an action in the agent 0584 * (e.g. data transfer, connection establishment to remote server etc.) has changed. 0585 * 0586 * @param progress The progress of the action in percent. 0587 */ 0588 void percent(int progress); 0589 0590 /** 0591 * This signal shall be used to report warnings. 0592 * 0593 * @param message The i18n'ed warning message. 0594 */ 0595 void warning(const QString &message); 0596 0597 /** 0598 * This signal shall be used to report errors. 0599 * 0600 * @param message The i18n'ed error message. 0601 */ 0602 void error(const QString &message); 0603 0604 /** 0605 * This signal should be emitted whenever the status of the agent has been changed. 0606 * @param status The object that describes the status change. 0607 * 0608 * @since 4.6 0609 */ 0610 void advancedStatus(const QVariantMap &status); 0611 0612 /** 0613 * Emitted when another application has remotely asked the agent to abort 0614 * its current operation. 0615 * Connect to this signal if your agent supports abortion. After aborting 0616 * and cleaning up, agents should return to Idle status. 0617 * 0618 * @since 4.4 0619 */ 0620 void abortRequested(); 0621 0622 /** 0623 * Emitted if another application has changed the agent's configuration remotely 0624 * and called AgentInstance::reconfigure(). 0625 * 0626 * @since 4.2 0627 */ 0628 void reloadConfiguration(); 0629 0630 /** 0631 * Emitted when the online state changed. 0632 * @param online The online state. 0633 * @since 4.2 0634 */ 0635 void onlineChanged(bool online); 0636 0637 /** 0638 * This signal is emitted whenever the user has accepted the configuration dialog. 0639 * 0640 * @note Implementors of agents/resources are responsible to emit this signal if 0641 * the agent/resource reimplements configure(). 0642 * 0643 * @since 4.4 0644 */ 0645 void configurationDialogAccepted(); 0646 0647 /** 0648 * This signal is emitted whenever the user has rejected the configuration dialog. 0649 * 0650 * @note Implementors of agents/resources are responsible to emit this signal if 0651 * the agent/resource reimplements configure(). 0652 * 0653 * @since 4.4 0654 */ 0655 void configurationDialogRejected(); 0656 0657 protected: 0658 /** 0659 * Creates an agent base. 0660 * 0661 * @param id The instance id of the agent. 0662 */ 0663 AgentBase(const QString &id); 0664 0665 /** 0666 * Destroys the agent base. 0667 */ 0668 ~AgentBase() override; 0669 0670 /** 0671 * This method is called whenever the agent application is about to 0672 * quit. 0673 * 0674 * Reimplement this method to do session cleanup (e.g. disconnecting 0675 * from groupware server). 0676 */ 0677 virtual void aboutToQuit(); 0678 0679 /** 0680 * Returns the Akonadi::ChangeRecorder object used for monitoring. 0681 * Use this to configure which parts you want to monitor. 0682 */ 0683 ChangeRecorder *changeRecorder() const; 0684 0685 /** 0686 * Returns the config object for this Agent. 0687 */ 0688 KSharedConfigPtr config(); 0689 0690 /** 0691 * Marks the current change as processes and replays the next change if change 0692 * recording is enabled (noop otherwise). This method is called 0693 * from the default implementation of the change notification slots. While not 0694 * required when not using change recording, it is nevertheless recommended 0695 * to call this method when done with processing a change notification. 0696 */ 0697 void changeProcessed(); 0698 0699 /** 0700 * Returns whether the agent is currently online. 0701 */ 0702 bool isOnline() const; 0703 0704 /** 0705 * Sets whether the agent needs network or not. 0706 * 0707 * @since 4.2 0708 * @todo use this in combination with QNetworkConfiguration to change 0709 * the onLine status of the agent. 0710 * @param needsNetwork @c true if the agents needs network. Defaults to @c false 0711 */ 0712 void setNeedsNetwork(bool needsNetwork); 0713 0714 /** 0715 * Sets whether the agent shall be online or not. 0716 */ 0717 void setOnline(bool state); 0718 0719 protected: 0720 /** 0721 * Sets the agent offline but will make it online again after a given time 0722 * 0723 * Use this method when the agent detects some problem with its backend but it wants 0724 * to retry all pending operations after some time - e.g. a server can not be reached currently 0725 * 0726 * Example usage: 0727 * @code 0728 * void ExampleResource::onItemRemovedFinished(KJob *job) 0729 * { 0730 * if (job->error()) { 0731 * Q_EMIT status(Broken, job->errorString()); 0732 * deferTask(); 0733 * setTemporaryOffline(300); 0734 * return; 0735 * } 0736 * ... 0737 * } 0738 * @endcode 0739 * 0740 * @since 4.13 0741 * @param makeOnlineInSeconds timeout in seconds after which the agent changes to online 0742 */ 0743 void setTemporaryOffline(int makeOnlineInSeconds = 300); 0744 0745 /// @cond PRIVATE 0746 static void debugAgent(int argc, char **argv); 0747 0748 std::unique_ptr<AgentBasePrivate> const d_ptr; 0749 explicit AgentBase(AgentBasePrivate *d, const QString &id); 0750 friend class ObserverV2; 0751 /// @endcond 0752 0753 /** 0754 * This method is called whenever the @p online status has changed. 0755 * Reimplement this method to react on online status changes. 0756 * @param online online status 0757 */ 0758 virtual void doSetOnline(bool online); 0759 0760 virtual KAboutData aboutData() const; 0761 0762 private: 0763 /// @cond PRIVATE 0764 static QString parseArguments(int argc, char **argv); 0765 static int init(AgentBase &r); 0766 void setOnlineInternal(bool state); 0767 0768 // D-Bus interface stuff 0769 void abort(); 0770 void reconfigure(); 0771 void quit(); 0772 0773 // dbus agent interface 0774 friend class ::Akonadi__StatusAdaptor; 0775 friend class ::Akonadi__ControlAdaptor; 0776 0777 Q_DECLARE_PRIVATE(AgentBase) 0778 Q_PRIVATE_SLOT(d_func(), void delayedInit()) 0779 Q_PRIVATE_SLOT(d_func(), void slotStatus(int, const QString &)) 0780 Q_PRIVATE_SLOT(d_func(), void slotPercent(int)) 0781 Q_PRIVATE_SLOT(d_func(), void slotWarning(const QString &)) 0782 Q_PRIVATE_SLOT(d_func(), void slotError(const QString &)) 0783 Q_PRIVATE_SLOT(d_func(), void slotNetworkStatusChange(bool)) 0784 Q_PRIVATE_SLOT(d_func(), void slotResumedFromSuspend()) 0785 Q_PRIVATE_SLOT(d_func(), void slotTemporaryOfflineTimeout()) 0786 0787 /// @endcond 0788 }; 0789 0790 } 0791 0792 #ifndef AKONADI_AGENT_MAIN 0793 /** 0794 * Convenience Macro for the most common main() function for Akonadi agents. 0795 */ 0796 #define AKONADI_AGENT_MAIN(agentClass) \ 0797 int main(int argc, char **argv) \ 0798 { \ 0799 return Akonadi::AgentBase::init<agentClass>(argc, argv); \ 0800 } 0801 #endif