Akonadi

agentconfigurationwidget.cpp
1/*
2 SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "agentconfigurationwidget.h"
8#include "agentconfigurationdialog.h"
9#include "agentconfigurationwidget_p.h"
10#include "akonadiwidgets_debug.h"
11#include "core/agentconfigurationbase.h"
12#include "core/agentconfigurationfactorybase.h"
13#include "core/agentconfigurationmanager_p.h"
14#include "core/agentmanager.h"
15#include "core/servermanager.h"
16
17#include <QChildEvent>
18#include <QLabel>
19#include <QTimer>
20#include <QVBoxLayout>
21
22#include <KLocalizedString>
23#include <KSharedConfig>
24
25using namespace Akonadi;
26using namespace std::chrono_literals;
27AgentConfigurationWidgetPrivate::AgentConfigurationWidgetPrivate(const AgentInstance &instance)
28 : agentInstance(instance)
29{
30}
31
32AgentConfigurationWidgetPrivate::~AgentConfigurationWidgetPrivate()
33{
34}
35
36void AgentConfigurationWidgetPrivate::setupErrorWidget(QWidget *parent, const QString &text)
37{
38 auto layout = new QVBoxLayout(parent);
39 layout->addStretch(2);
40 auto label = new QLabel(text, parent);
41 label->setAlignment(Qt::AlignCenter);
42 layout->addWidget(label);
43 layout->addStretch(2);
44}
45
46bool AgentConfigurationWidgetPrivate::loadPlugin(const QString &pluginPath)
47{
48 if (pluginPath.isEmpty()) {
49 qCDebug(AKONADIWIDGETS_LOG) << "Haven't found config plugin for" << agentInstance.type().identifier();
50 return false;
51 }
52 loader = decltype(loader)(new QPluginLoader(pluginPath));
53 if (!loader->load()) {
54 qCWarning(AKONADIWIDGETS_LOG) << "Failed to load config plugin" << pluginPath << ":" << loader->errorString();
55 loader.reset();
56 return false;
57 }
58 factory = qobject_cast<AgentConfigurationFactoryBase *>(loader->instance());
59 if (!factory) {
60 // will unload the QPluginLoader and thus delete the factory as well
61 qCWarning(AKONADIWIDGETS_LOG) << "Config plugin" << pluginPath << "does not contain AgentConfigurationFactory!";
62 loader.reset();
63 return false;
64 }
65
66 qCDebug(AKONADIWIDGETS_LOG) << "Loaded agent configuration plugin" << pluginPath;
67 return true;
68}
69
70AgentConfigurationWidget::AgentConfigurationWidget(const AgentInstance &instance, QWidget *parent)
71 : QWidget(parent)
72 , d(new AgentConfigurationWidgetPrivate(instance))
73{
74 if (AgentConfigurationManager::self()->registerInstanceConfiguration(instance.identifier())) {
75 const auto pluginPath = AgentConfigurationManager::self()->findConfigPlugin(instance.type().identifier());
76 if (d->loadPlugin(pluginPath)) {
77 QString configName = instance.identifier() + QStringLiteral("rc");
78 configName = Akonadi::ServerManager::addNamespace(configName);
79 KSharedConfigPtr config = KSharedConfig::openConfig(configName);
80 auto layout = new QVBoxLayout(this);
81 layout->setContentsMargins({});
82 d->plugin = d->factory->create(config, this, {instance.identifier()});
83 connect(d->plugin.data(), &AgentConfigurationBase::enableOkButton, this, &AgentConfigurationWidget::enableOkButton);
84 } else {
85 // Hide this dialog and fallback to calling the out-of-process configuration
86 if (auto dlg = qobject_cast<AgentConfigurationDialog *>(parent)) {
87 const_cast<AgentInstance &>(instance).configure(topLevelWidget()->parentWidget());
88 // If we are inside the AgentConfigurationDialog, hide the dialog
89 QTimer::singleShot(0s, this, [dlg]() {
90 dlg->reject();
91 });
92 } else {
93 const_cast<AgentInstance &>(instance).configure();
94 // Otherwise show a message that this is opened externally
95 d->setupErrorWidget(this, i18n("The configuration dialog has been opened in another window"));
96 }
97
98 // TODO: Re-enable once we can kill the fallback code above ^^
99 // d->setupErrorWidget(this, i18n("Failed to load configuration plugin"));
100 }
101 } else if (AgentConfigurationManager::self()->isInstanceRegistered(instance.identifier())) {
102 d->setupErrorWidget(this, i18n("Configuration for %1 is already opened elsewhere.", instance.name()));
103 } else {
104 d->setupErrorWidget(this, i18n("Failed to register %1 configuration dialog.", instance.name()));
105 }
106
107 QTimer::singleShot(0, this, &AgentConfigurationWidget::load);
108}
109
110AgentConfigurationWidget::~AgentConfigurationWidget()
111{
112 AgentConfigurationManager::self()->unregisterInstanceConfiguration(d->agentInstance.identifier());
113}
114
115void AgentConfigurationWidget::load()
116{
117 if (d->plugin) {
118 d->plugin->load();
119 }
120}
121
122void AgentConfigurationWidget::save()
123{
124 qCDebug(AKONADIWIDGETS_LOG) << "Saving configuration for" << d->agentInstance.identifier();
125 if (d->plugin) {
126 if (d->plugin->save()) {
127 d->agentInstance.reconfigure();
128 }
129 }
130}
131
132QSize AgentConfigurationWidget::restoreDialogSize() const
133{
134 if (d->plugin) {
135 return d->plugin->restoreDialogSize();
136 }
137 return {};
138}
139
140void AgentConfigurationWidget::saveDialogSize(QSize size)
141{
142 if (d->plugin) {
143 d->plugin->saveDialogSize(size);
144 }
145}
146
147QDialogButtonBox::StandardButtons AgentConfigurationWidget::standardButtons() const
148{
149 if (d->plugin) {
150 return d->plugin->standardButtons();
151 }
153}
154
155void AgentConfigurationWidget::childEvent(QChildEvent *event)
156{
157 if (event->added()) {
158 if (event->child()->isWidgetType()) {
159 layout()->addWidget(static_cast<QWidget *>(event->child()));
160 }
161 }
162
164}
165
166#include "moc_agentconfigurationwidget.cpp"
Represents one agent instance and takes care of communication with it.
QString identifier() const
Set/get the unique identifier of this AgentInstance.
static QString addNamespace(const QString &string)
Adds the multi-instance namespace to string if required (with '_' as separator).
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
KGuiItem configure()
QString label(StandardShortcut id)
typedef StandardButtons
void addWidget(QWidget *w)
virtual void childEvent(QChildEvent *event)
T qobject_cast(QObject *object)
bool isEmpty() const const
AlignCenter
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
virtual bool event(QEvent *event) override
QLayout * layout() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.