Akonadi

agentinstancecreatejob.cpp
1 /*
2  Copyright (c) 2008 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "agentinstancecreatejob.h"
21 
22 #include "agentinstance.h"
23 #include "agentmanager.h"
24 #include "agentmanager_p.h"
25 #include "controlinterface.h"
26 #include <QDBusConnection>
27 #include "kjobprivatebase_p.h"
28 #include "servermanager.h"
29 
30 #include <KLocalizedString>
31 
32 #include <QTimer>
33 
34 #ifdef Q_OS_UNIX
35 #include <sys/types.h>
36 #include <signal.h>
37 #endif
38 
39 using namespace Akonadi;
40 
41 static const int safetyTimeout = 10000; // ms
42 
43 namespace Akonadi
44 {
48 class AgentInstanceCreateJobPrivate : public KJobPrivateBase
49 {
50 public:
51  AgentInstanceCreateJobPrivate(AgentInstanceCreateJob *parent)
52  : q(parent)
53  , parentWidget(nullptr)
54  , safetyTimer(new QTimer(parent))
55  , doConfig(false)
56  , tooLate(false)
57  {
59  q, SLOT(agentInstanceAdded(Akonadi::AgentInstance)));
60  QObject::connect(safetyTimer, &QTimer::timeout, q, [this]() {timeout(); });
61  }
62 
63  void agentInstanceAdded(const AgentInstance &instance)
64  {
65  if (agentInstance == instance && !tooLate) {
66  safetyTimer->stop();
67  if (doConfig) {
68  // return from dbus call first before doing the next one
69  QTimer::singleShot(0, q, [this]() { doConfigure(); });
70  } else {
71  q->emitResult();
72  }
73  }
74  }
75 
76  void doConfigure()
77  {
78  org::freedesktop::Akonadi::Agent::Control *agentControlIface =
79  new org::freedesktop::Akonadi::Agent::Control(ServerManager::agentServiceName(ServerManager::Agent, agentInstance.identifier()),
80  QStringLiteral("/"), QDBusConnection::sessionBus(), q);
81  if (!agentControlIface || !agentControlIface->isValid()) {
82  delete agentControlIface;
83 
84  q->setError(KJob::UserDefinedError);
85  q->setErrorText(i18n("Unable to access D-Bus interface of created agent."));
86  q->emitResult();
87  return;
88  }
89 
90  q->connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogAccepted,
91  q, [agentControlIface, this]() {
92  agentControlIface->deleteLater();
93  q->emitResult();
94  });
95  q->connect(agentControlIface, &org::freedesktop::Akonadi::Agent::Control::configurationDialogRejected,
96  q, [agentControlIface, this]() {
97  agentControlIface->deleteLater();
98  AgentManager::self()->removeInstance(agentInstance);
99  q->emitResult();
100  });
101 
102  agentInstance.configure(parentWidget);
103  }
104 
105  void timeout()
106  {
107  tooLate = true;
108  q->setError(KJob::UserDefinedError);
109  q->setErrorText(i18n("Agent instance creation timed out."));
110  q->emitResult();
111  }
112 
113  void doStart() override;
114 
115  AgentInstanceCreateJob * const q;
116  AgentType agentType;
117  QString agentTypeId;
118  AgentInstance agentInstance;
119  QWidget *parentWidget = nullptr;
120  QTimer *safetyTimer = nullptr;
121  bool doConfig;
122  bool tooLate;
123 };
124 
125 }
126 
128  : KJob(parent)
129  , d(new AgentInstanceCreateJobPrivate(this))
130 {
131  d->agentType = agentType;
132 }
133 
135  : KJob(parent)
136  , d(new AgentInstanceCreateJobPrivate(this))
137 {
138  d->agentTypeId = typeId;
139 }
140 
142 {
143  delete d;
144 }
145 
147 {
148  d->parentWidget = parent;
149  d->doConfig = true;
150 }
151 
153 {
154  return d->agentInstance;
155 }
156 
158 {
159  d->start();
160 }
161 
162 void AgentInstanceCreateJobPrivate::doStart()
163 {
164  if (!agentType.isValid() && !agentTypeId.isEmpty()) {
165  agentType = AgentManager::self()->type(agentTypeId);
166  }
167 
168  if (!agentType.isValid()) {
169  q->setError(KJob::UserDefinedError);
170  q->setErrorText(i18n("Unable to obtain agent type '%1'.", agentTypeId));
172  return;
173  }
174 
175  agentInstance = AgentManager::self()->d->createInstance(agentType);
176  if (!agentInstance.isValid()) {
177  q->setError(KJob::UserDefinedError);
178  q->setErrorText(i18n("Unable to create agent instance."));
180  } else {
181  int timeout = safetyTimeout;
182 #ifdef Q_OS_UNIX
183  // Increate the timeout when valgrinding the agent, because that slows down things a log.
184  QString agentValgrind = QString::fromLocal8Bit(qgetenv("AKONADI_VALGRIND"));
185  if (!agentValgrind.isEmpty() && agentType.identifier().contains(agentValgrind)) {
186  timeout *= 15;
187  }
188 #endif
189  // change the timeout when debugging the agent, because we need time to start the debugger
190  const QString agentDebugging = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_WAIT"));
191  if (!agentDebugging.isEmpty()) {
192  // we are debugging
193  const QString agentDebuggingTimeout = QString::fromLocal8Bit(qgetenv("AKONADI_DEBUG_TIMEOUT"));
194  if (agentDebuggingTimeout.isEmpty()) {
195  // use default value of 150 seconds (the same as "valgrinding", this has to be checked)
196  timeout = 15 * safetyTimeout;
197  } else {
198  // use own value
199  timeout = agentDebuggingTimeout.toInt();
200  }
201  }
202  safetyTimer->start(timeout);
203  }
204 }
205 
206 #include "moc_agentinstancecreatejob.cpp"
void emitResult()
QDBusConnection sessionBus()
~AgentInstanceCreateJob() override
Destroys the agent instance create job.
void start() override
Starts the instance creation.
void removeInstance(const AgentInstance &instance)
Removes the given agent instance.
void timeout()
QString fromLocal8Bit(const char *str, int size)
A representation of an agent type.
int toInt(bool *ok, int base) const const
bool isEmpty() const const
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...
AgentInstanceCreateJob(const AgentType &type, QObject *parent=nullptr)
Creates a new agent instance create job.
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
Job for creating new agent instances.
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
static AgentManager * self()
Returns the global instance of the agent manager.
void configure(QWidget *parent=nullptr)
Setup the job to show agent configuration dialog once the agent instance has been successfully starte...
A representation of an agent instance.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue May 26 2020 22:46:17 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.