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
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"
Represents one agent instance and takes care of communication with it.
Job for creating new agent instances.
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.
AKONADICORE_DEPRECATED void configure(QWidget *parent=nullptr)
Triggers the agent instance to show its configuration dialog.
bool isValid() const
Returns whether the agent instance object is valid.
QString identifier() const
Returns the unique identifier of the 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.
QString identifier() const
Returns the unique identifier of the agent type.
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)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
QDBusConnection sessionBus()
QObject * parent() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) 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 start()
void stop()
void timeout()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:29 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.