File indexing completed on 2024-05-26 05:14:07

0001 /*
0002     SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "agentconfigurationfactorybase.h"
0010 #include "akonadicore_export.h"
0011 
0012 #include <KSharedConfig>
0013 #include <QDialogButtonBox>
0014 #include <QObject>
0015 
0016 #include <memory>
0017 
0018 class KAboutData;
0019 
0020 namespace Akonadi
0021 {
0022 class AgentConfigurationBasePrivate;
0023 
0024 /**
0025  * @brief Base class for configuration UI for Akonadi agents
0026  *
0027  * Each agent that has a graphical configuration should subclass this class
0028  * and create its configuration UI there.
0029  *
0030  * The subclass must reimplement load() and save() virtual methods which
0031  * are called automatically. The load() method is called on start to initialize
0032  * widgets (thus subclasses don't need to call it themselves) or when user
0033  * clicks a "Reset" button. The save() method is called whenever user decides to
0034  * save changes.
0035  *
0036  * Since each Akonadi agent instance has its own configuration file whose
0037  * location and name is opaque to the implementation, config() method can be
0038  * used to get access to the current configuration object.
0039  *
0040  * The widget will not run in the same process as the Akonadi agent, thus all
0041  * communication with the resource (if needed) should be done over DBus. The
0042  * identifier of the instance currently being configured is accessible from the
0043  * identifier() method.
0044  *
0045  * There is no need to signal back to the resource when configuration is changed.
0046  * When save() is called and the dialog is destroyed, Akonadi will automatically
0047  * call AgentBase::reconfigure() in the respective Akonadi agent instance.
0048  *
0049  * It is guaranteed that only a single instance of the configuration dialog for
0050  * given agent will be opened at the same time.
0051  *
0052  * Subclasses of ConfigurationBase must be registered as Akonadi plugins using
0053  * AKONADI_AGENTCONFIG_FACTORY macro.
0054  *
0055  * The metadata JSON file then must contain the following values:
0056  * @code
0057  * {
0058  *     "X-Akonadi-PluginType": "AgentConfig",
0059  *     "X-Akonadi-Library": "exampleresourceconfig",
0060  *     "X-Akonadi-AgentConfig-Type": "akonadi_example_resource"
0061  * }
0062  * @endcode
0063  *
0064  * The @p X-Akonadi-Library value must match the name of the plugin binary without
0065  * the (optional) "lib" prefix and file extension. The @p X-Akonadi-AgentConfig-Type
0066  * value must match the name of the @p X-Akonadi-Identifier value from the agent's
0067  * desktop file.
0068  *
0069  * The plugin binary should be installed into pim<version>/akonadi/config subdirectory in one
0070  * of the paths search by QCoreApplication::libraryPaths().
0071  */
0072 
0073 class AKONADICORE_EXPORT AgentConfigurationBase : public QObject
0074 {
0075     Q_OBJECT
0076 public:
0077     /**
0078      * Creates a new AgentConfigurationBase objects.
0079      *
0080      * The @p parentWidget should be used as a parent widget for the configuration
0081      * widgets.
0082      *
0083      * Subclasses must provide a constructor with this exact signature.
0084      */
0085     explicit AgentConfigurationBase(const KSharedConfigPtr &config, QWidget *parentWidget, const QVariantList &args);
0086 
0087     ~AgentConfigurationBase() override;
0088 
0089     /**
0090      * Reimplement to load settings from the configuration object into widgets.
0091      *
0092      * @warning Always call the base class implementation at the beginning of
0093      * your overridden method!
0094      *
0095      * @see config(), save()
0096      */
0097     virtual void load();
0098 
0099     /**
0100      * Reimplement to save new settings into the configuration object.
0101      *
0102      * Return true if the configuration has been successfully saved and should
0103      * be applied to the agent, return false otherwise.
0104      *
0105      * @warning Always remember call the base class implementation at the end
0106      * of your overridden method!
0107      *
0108      * @see config(), load()
0109      */
0110     virtual bool save() const;
0111 
0112     /**
0113      * Returns about data for the currently configured component.
0114      *
0115      * May return a null pointer.
0116      */
0117     KAboutData *aboutData() const;
0118 
0119     /**
0120      * Reimplement to restore dialog size.
0121      */
0122     virtual QSize restoreDialogSize() const;
0123 
0124     /**
0125      * Reimplement to save dialog size.
0126      */
0127     virtual void saveDialogSize(const QSize &size);
0128 
0129     virtual QDialogButtonBox::StandardButtons standardButtons() const;
0130 
0131 protected:
0132     QWidget *parentWidget() const;
0133 
0134     /**
0135      * Returns KConfig object belonging to the current Akonadi agent instance.
0136      */
0137     KSharedConfigPtr config() const;
0138 
0139     /**
0140      * Returns identifier of the Akonadi agent instance currently being configured.
0141      */
0142     [[nodiscard]] QString identifier() const;
0143 
0144     /**
0145      * When KAboutData is provided the dialog will also contain KHelpMenu with
0146      * access to user help etc.
0147      */
0148     void setKAboutData(const KAboutData &aboutData);
0149 
0150 Q_SIGNALS:
0151     void enableOkButton(bool enabled);
0152 
0153 private:
0154     friend class AgentConfigurationBasePrivate;
0155     std::unique_ptr<AgentConfigurationBasePrivate> const d;
0156 };
0157 
0158 } // namespace