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 const QString configName = Akonadi::ServerManager::addNamespace(instance.identifier()) + QStringLiteral("rc");
78 KSharedConfigPtr config = KSharedConfig::openConfig(configName);
79 auto layout = new QVBoxLayout(this);
80 layout->setContentsMargins({});
81 d->plugin = d->factory->create(config, this, {instance.identifier()});
82 connect(d->plugin.data(), &AgentConfigurationBase::enableOkButton, this, &AgentConfigurationWidget::enableOkButton);
83 } else {
84 // Hide this dialog and fallback to calling the out-of-process configuration
85 if (auto dlg = qobject_cast<AgentConfigurationDialog *>(parent)) {
86 const_cast<AgentInstance &>(instance).configure(topLevelWidget()->parentWidget());
87 // If we are inside the AgentConfigurationDialog, hide the dialog
88 QTimer::singleShot(0s, this, [dlg]() {
89 dlg->reject();
90 });
91 } else {
92 const_cast<AgentInstance &>(instance).configure();
93 // Otherwise show a message that this is opened externally
94 d->setupErrorWidget(this, i18n("The configuration dialog has been opened in another window"));
95 }
96
97 // TODO: Re-enable once we can kill the fallback code above ^^
98 // d->setupErrorWidget(this, i18n("Failed to load configuration plugin"));
99 }
100 } else if (AgentConfigurationManager::self()->isInstanceRegistered(instance.identifier())) {
101 d->setupErrorWidget(this, i18n("Configuration for %1 is already opened elsewhere.", instance.name()));
102 } else {
103 d->setupErrorWidget(this, i18n("Failed to register %1 configuration dialog.", instance.name()));
104 }
105
106 QTimer::singleShot(0, this, &AgentConfigurationWidget::load);
107}
108
109AgentConfigurationWidget::~AgentConfigurationWidget()
110{
111 AgentConfigurationManager::self()->unregisterInstanceConfiguration(d->agentInstance.identifier());
112}
113
114void AgentConfigurationWidget::load()
115{
116 if (d->plugin) {
117 d->plugin->load();
118 }
119}
120
121void AgentConfigurationWidget::save()
122{
123 qCDebug(AKONADIWIDGETS_LOG) << "Saving configuration for" << d->agentInstance.identifier();
124 if (d->plugin) {
125 if (d->plugin->save()) {
126 d->agentInstance.reconfigure();
127 }
128 }
129}
130
131QSize AgentConfigurationWidget::restoreDialogSize() const
132{
133 if (d->plugin) {
134 return d->plugin->restoreDialogSize();
135 }
136 return {};
137}
138
139void AgentConfigurationWidget::saveDialogSize(QSize size)
140{
141 if (d->plugin) {
142 d->plugin->saveDialogSize(size);
143 }
144}
145
146QDialogButtonBox::StandardButtons AgentConfigurationWidget::standardButtons() const
147{
148 if (d->plugin) {
149 return d->plugin->standardButtons();
150 }
152}
153
154void AgentConfigurationWidget::childEvent(QChildEvent *event)
155{
156 if (event->added()) {
157 if (event->child()->isWidgetType()) {
158 layout()->addWidget(static_cast<QWidget *>(event->child()));
159 }
160 }
161
163}
164
165#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.
Helper integration between Akonadi and Qt.
QString label(StandardShortcut id)
void addWidget(QWidget *w)
virtual void childEvent(QChildEvent *event)
bool isEmpty() const const
AlignCenter
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 Fri Nov 29 2024 11:49:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.