Akonadi

agentinstancecreatejob.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "agentinstancecreatejob.h"
8
9#include "agentinstance.h"
10#include "agentmanager.h"
11#include "agentmanager_p.h"
12#include "controlinterface.h"
13#include "kjobprivatebase_p.h"
14#include <QDBusConnection>
15
16#include <KLocalizedString>
17
18#include <QTimer>
19
20#ifdef Q_OS_UNIX
21#include <signal.h>
22#include <sys/types.h>
23#endif
24
25using namespace Akonadi;
26
27static const int safetyTimeout = 10000; // ms
28
29namespace Akonadi
30{
31/**
32 * @internal
33 */
34class AgentInstanceCreateJobPrivate : public KJobPrivateBase
35{
36 Q_OBJECT
37public:
38 explicit AgentInstanceCreateJobPrivate(AgentInstanceCreateJob *parent)
39 : q(parent)
40 , safetyTimer(new QTimer(parent))
41 {
42 connect(AgentManager::self(), &AgentManager::instanceAdded, this, &AgentInstanceCreateJobPrivate::agentInstanceAdded);
43 connect(safetyTimer, &QTimer::timeout, this, &AgentInstanceCreateJobPrivate::timeout);
44 }
45
46 void agentInstanceAdded(const AgentInstance &instance) const
47 {
48 if (agentInstance == instance && !tooLate) {
49 safetyTimer->stop();
50 if (doConfig) {
51 // return from dbus call first before doing the next one
52 QTimer::singleShot(0, this, &AgentInstanceCreateJobPrivate::doConfigure);
53 } else {
54 q->emitResult();
55 }
56 }
57 }
58
59 void doConfigure()
60 {
61 auto agentControlIface =
62 new org::freedesktop::Akonadi::Agent::Control(ServerManager::agentServiceName(ServerManager::Agent, agentInstance.identifier()),
63 QStringLiteral("/"),
65 q);
66 if (!agentControlIface || !agentControlIface->isValid()) {
67 delete agentControlIface;
68
69 q->setError(KJob::UserDefinedError);
70 q->setErrorText(i18n("Unable to access D-Bus interface of created agent."));
71 q->emitResult();
72 return;
73 }
74
75 connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogAccepted, this, [agentControlIface, this]() {
76 agentControlIface->deleteLater();
77 q->emitResult();
78 });
79 connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogRejected, this, [agentControlIface, this]() {
80 agentControlIface->deleteLater();
81 AgentManager::self()->removeInstance(agentInstance);
82 q->emitResult();
83 });
84
85 agentInstance.configure(parentWidget);
86 }
87
88 void timeout()
89 {
90 tooLate = true;
91 q->setError(KJob::UserDefinedError);
92 q->setErrorText(i18n("Agent instance creation timed out."));
93 q->emitResult();
94 }
95
96 void doStart() override;
97
98 AgentInstanceCreateJob *const q;
99 AgentType agentType;
100 QString agentTypeId;
101 AgentInstance agentInstance;
102 QWidget *parentWidget = nullptr;
103 QTimer *const safetyTimer;
104 bool doConfig = false;
105 bool tooLate = false;
106};
107
108} // namespace Akonadi
109
111 : KJob(parent)
112 , d(new AgentInstanceCreateJobPrivate(this))
113{
114 d->agentType = agentType;
115}
116
118 : KJob(parent)
119 , d(new AgentInstanceCreateJobPrivate(this))
120{
121 d->agentTypeId = typeId;
122}
123
125
127{
128 d->parentWidget = parent;
129 d->doConfig = true;
130}
131
133{
134 return d->agentInstance;
135}
136
138{
139 d->start();
140}
141
142void AgentInstanceCreateJobPrivate::doStart()
143{
144 if (!agentType.isValid() && !agentTypeId.isEmpty()) {
145 agentType = AgentManager::self()->type(agentTypeId);
146 }
147
148 if (!agentType.isValid()) {
149 q->setError(KJob::UserDefinedError);
150 q->setErrorText(i18n("Unable to obtain agent type '%1'.", agentTypeId));
152 return;
153 }
154
155 agentInstance = AgentManager::self()->d->createInstance(agentType);
156 if (!agentInstance.isValid()) {
157 q->setError(KJob::UserDefinedError);
158 q->setErrorText(i18n("Unable to create agent instance."));
160 } else {
161 int timeout = safetyTimeout;
162#ifdef Q_OS_UNIX
163 // Increate the timeout when valgrinding the agent, because that slows down things a log.
164 const QString agentValgrind = QString::fromLocal8Bit(qgetenv("AKONADI_VALGRIND"));
165 if (!agentValgrind.isEmpty() && agentType.identifier().contains(agentValgrind)) {
166 timeout *= 15;
167 }
168#endif
169 // change the timeout when debugging the agent, because we need time to start the debugger
170 const QString agentDebugging = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_WAIT"));
171 if (!agentDebugging.isEmpty()) {
172 // we are debugging
173 const QString agentDebuggingTimeout = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_TIMEOUT"));
174 if (agentDebuggingTimeout.isEmpty()) {
175 // use default value of 150 seconds (the same as "valgrinding", this has to be checked)
176 timeout = 15 * safetyTimeout;
177 } else {
178 // use own value
179 timeout = agentDebuggingTimeout.toInt();
180 }
181 }
182 safetyTimer->start(timeout);
183 }
184}
185
186#include "agentinstancecreatejob.moc"
187
188#include "moc_agentinstancecreatejob.cpp"
void configure(QWidget *parent=nullptr)
Setup the job to show agent configuration dialog once the agent instance has been successfully starte...
~AgentInstanceCreateJob() override
Destroys the agent instance create job.
AgentInstanceCreateJob(const AgentType &type, QObject *parent=nullptr)
Creates a new agent instance create job.
void start() override
Starts the instance creation.
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
A representation of an agent instance.
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
static AgentManager * self()
Returns the global instance of the agent manager.
void removeInstance(const AgentInstance &instance)
Removes the given agent instance.
void instanceAdded(const Akonadi::AgentInstance &instance)
This signal is emitted whenever a new agent instance was created.
A representation of an agent type.
bool isValid() const
Returns whether the agent type is valid.
static QString agentServiceName(ServiceAgentType agentType, const QString &identifier)
Returns the namespaced D-Bus service name for an agent of type agentType with agent identifier identi...
void setErrorText(const QString &errorText)
void emitResult()
void setError(int errorCode)
KJob(QObject *parent=nullptr)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
QDBusConnection sessionBus()
QObject(QObject *parent)
QObject * parent() const const
QString fromLocal8Bit(QByteArrayView str)
bool isEmpty() const const
int toInt(bool *ok, int base) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void timeout()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:49:57 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.