KCoreAddons

kjob.cpp
1 /*
2  This file is part of the KDE project
3 
4  SPDX-FileCopyrightText: 2000 Stephan Kulow <[email protected]>
5  SPDX-FileCopyrightText: 2000 David Faure <[email protected]>
6  SPDX-FileCopyrightText: 2006 Kevin Ottens <[email protected]>
7 
8  SPDX-License-Identifier: LGPL-2.0-only
9 */
10 
11 #include "kjob.h"
12 #include "kjob_p.h"
13 
14 #include "kjobuidelegate.h"
15 
16 #include <QEventLoop>
17 #include <QTimer>
18 
19 KJobPrivate::KJobPrivate()
20  : q_ptr(nullptr), uiDelegate(nullptr), error(KJob::NoError),
21  progressUnit(KJob::Bytes), percentage(0),
22  speedTimer(nullptr), eventLoop(nullptr),
23  capabilities(KJob::NoCapabilities),
24  suspended(false), isAutoDelete(true), isFinished(false)
25 {
26 }
27 
28 KJobPrivate::~KJobPrivate()
29 {
30 }
31 
33  : QObject(parent), d_ptr(new KJobPrivate)
34 {
35  d_ptr->q_ptr = this;
36 }
37 
38 KJob::KJob(KJobPrivate &dd, QObject *parent)
39  : QObject(parent), d_ptr(&dd)
40 {
41  d_ptr->q_ptr = this;
42 }
43 
45 {
46  if (!d_ptr->isFinished) {
47  emit finished(this, QPrivateSignal());
48  }
49 
50  delete d_ptr->speedTimer;
51  delete d_ptr->uiDelegate;
52  delete d_ptr;
53 }
54 
56 {
57  Q_D(KJob);
58  if (delegate == nullptr || delegate->setJob(this)) {
59  delete d->uiDelegate;
60  d->uiDelegate = delegate;
61 
62  if (d->uiDelegate) {
63  d->uiDelegate->connectJob(this);
64  }
65  }
66 }
67 
69 {
70  return d_func()->uiDelegate;
71 }
72 
74 {
75  return d_func()->capabilities;
76 }
77 
78 bool KJob::isSuspended() const
79 {
80  return d_func()->suspended;
81 }
82 
83 void KJob::finishJob(bool emitResult)
84 {
85  Q_D(KJob);
86  d->isFinished = true;
87 
88  if (d->eventLoop) {
89  d->eventLoop->quit();
90  }
91 
92  // If we are displaying a progress dialog, remove it first.
93  emit finished(this, QPrivateSignal());
94 
95  if (emitResult) {
96  emit result(this, QPrivateSignal());
97  }
98 
99  if (isAutoDelete()) {
100  deleteLater();
101  }
102 }
103 
104 bool KJob::kill(KillVerbosity verbosity)
105 {
106  if (doKill()) {
107  setError(KilledJobError);
108 
109  finishJob(verbosity != Quietly);
110  return true;
111  } else {
112  return false;
113  }
114 }
115 
117 {
118  Q_D(KJob);
119  if (!d->suspended) {
120  if (doSuspend()) {
121  d->suspended = true;
122  emit suspended(this, QPrivateSignal());
123 
124  return true;
125  }
126  }
127 
128  return false;
129 }
130 
132 {
133  Q_D(KJob);
134  if (d->suspended) {
135  if (doResume()) {
136  d->suspended = false;
137  emit resumed(this, QPrivateSignal());
138 
139  return true;
140  }
141  }
142 
143  return false;
144 }
145 
147 {
148  return false;
149 }
150 
152 {
153  return false;
154 }
155 
157 {
158  return false;
159 }
160 
162 {
163  Q_D(KJob);
164  d->capabilities = capabilities;
165 }
166 
168 {
169  Q_D(KJob);
170  // Usually this job would delete itself, via deleteLater() just after
171  // emitting result() (unless configured otherwise). Since we use an event
172  // loop below, that event loop will process the deletion event and we'll
173  // have been deleted when exec() returns. This crashes, so temporarily
174  // suspend autodeletion and manually do it afterwards.
175  const bool wasAutoDelete = isAutoDelete();
176  setAutoDelete(false);
177 
178  Q_ASSERT(! d->eventLoop);
179 
180  QEventLoop loop(this);
181  d->eventLoop = &loop;
182 
183  start();
184  if (!d->isFinished) {
185  d->eventLoop->exec(QEventLoop::ExcludeUserInputEvents);
186  }
187  d->eventLoop = nullptr;
188 
189  if (wasAutoDelete) {
190  deleteLater();
191  }
192  return (d->error == NoError);
193 }
194 
195 int KJob::error() const
196 {
197  return d_func()->error;
198 }
199 
200 QString KJob::errorText() const
201 {
202  return d_func()->errorText;
203 }
204 
206 {
207  return d_func()->errorText;
208 }
209 
210 qulonglong KJob::processedAmount(Unit unit) const
211 {
212  return d_func()->processedAmount[unit];
213 }
214 
215 qulonglong KJob::totalAmount(Unit unit) const
216 {
217  return d_func()->totalAmount[unit];
218 }
219 
220 unsigned long KJob::percent() const
221 {
222  return d_func()->percentage;
223 }
224 
225 void KJob::setError(int errorCode)
226 {
227  Q_D(KJob);
228  d->error = errorCode;
229 }
230 
232 {
233  Q_D(KJob);
234  d->errorText = errorText;
235 }
236 
237 void KJob::setProcessedAmount(Unit unit, qulonglong amount)
238 {
239  Q_D(KJob);
240  bool should_emit = (d->processedAmount[unit] != amount);
241 
242  d->processedAmount[unit] = amount;
243 
244  if (should_emit) {
245  emit processedAmount(this, unit, amount);
246  if (unit == d->progressUnit) {
247  emit processedSize(this, amount);
248  emitPercent(d->processedAmount[unit], d->totalAmount[unit]);
249  }
250  }
251 }
252 
253 void KJob::setTotalAmount(Unit unit, qulonglong amount)
254 {
255  Q_D(KJob);
256  bool should_emit = (d->totalAmount[unit] != amount);
257 
258  d->totalAmount[unit] = amount;
259 
260  if (should_emit) {
261  emit totalAmount(this, unit, amount);
262  if (unit == d->progressUnit) {
263  emit totalSize(this, amount);
264  emitPercent(d->processedAmount[unit], d->totalAmount[unit]);
265  }
266  }
267 }
268 
269 void KJob::setPercent(unsigned long percentage)
270 {
271  Q_D(KJob);
272  if (d->percentage != percentage) {
273  d->percentage = percentage;
274  emit percent(this, percentage);
275  }
276 }
277 
279 {
280  finishJob(true);
281 }
282 
283 void KJob::emitPercent(qulonglong processedAmount, qulonglong totalAmount)
284 {
285  Q_D(KJob);
286  // calculate percents
287  if (totalAmount) {
288  unsigned long oldPercentage = d->percentage;
289  d->percentage = 100.0 * processedAmount / totalAmount;
290  if (d->percentage != oldPercentage) {
291  emit percent(this, d->percentage);
292  }
293  }
294 }
295 
296 void KJob::emitSpeed(unsigned long value)
297 {
298  Q_D(KJob);
299  if (!d->speedTimer) {
300  d->speedTimer = new QTimer(this);
301  connect(d->speedTimer, SIGNAL(timeout()), SLOT(_k_speedTimeout()));
302  }
303 
304  emit speed(this, value);
305  d->speedTimer->start(5000); // 5 seconds interval should be enough
306 }
307 
308 void KJobPrivate::_k_speedTimeout()
309 {
310  Q_Q(KJob);
311  // send 0 and stop the timer
312  // timer will be restarted only when we receive another speed event
313  emit q->speed(q, 0);
314  speedTimer->stop();
315 }
316 
317 bool KJob::isAutoDelete() const
318 {
319  Q_D(const KJob);
320  return d->isAutoDelete;
321 }
322 
323 void KJob::setAutoDelete(bool autodelete)
324 {
325  Q_D(KJob);
326  d->isAutoDelete = autodelete;
327 }
328 
329 #include "moc_kjob.cpp"
bool kill(KillVerbosity verbosity=Quietly)
Aborts this job.
Definition: kjob.cpp:104
void setCapabilities(Capabilities capabilities)
Sets the capabilities for this job.
Definition: kjob.cpp:161
void emitResult()
Utility function to emit the result signal, and suicide this job.
Definition: kjob.cpp:278
void setUiDelegate(KJobUiDelegate *delegate)
Attach a UI delegate to this job.
Definition: kjob.cpp:55
virtual QString errorString() const
A human-readable error message.
~KJob() override
Destroys a KJob object.
Definition: kjob.cpp:44
void setError(int errorCode)
Sets the error code.
Definition: kjob.cpp:225
bool exec()
Executes the job synchronously.
Definition: kjob.cpp:167
void resumed(KJob *job)
Emitted when the job is resumed.
bool isAutoDelete() const
Returns whether this job automatically deletes itself once the job is finished.
Definition: kjob.cpp:317
void setPercent(unsigned long percentage)
Sets the overall progress of the job.
Definition: kjob.cpp:269
bool suspend()
Suspends this job.
Definition: kjob.cpp:116
void setErrorText(const QString &errorText)
Sets the error text.
Definition: kjob.cpp:231
void speed(KJob *job, unsigned long speed)
Emitted to display information about the speed of this job.
void finished(KJob *job)
Emitted when the job is finished, in any case.
void totalSize(KJob *job, qulonglong size)
Emitted when we know the size of this job (data size in bytes for transfers, number of entries for li...
void setProcessedAmount(Unit unit, qulonglong amount)
Sets the processed size.
Definition: kjob.cpp:237
void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
void deleteLater()
KJobUiDelegate * uiDelegate() const
Retrieves the delegate attached to this job.
Definition: kjob.cpp:68
virtual bool doKill()
Aborts this job quietly.
Definition: kjob.cpp:146
void processedSize(KJob *job, qulonglong size)
Regularly emitted to show the progress of this job (current data size in bytes for transfers...
unsigned long percent() const
Returns the overall progress of this job.
The base class for all KJob UI delegate.
bool resume()
Resumes this job.
Definition: kjob.cpp:131
void emitSpeed(unsigned long speed)
Utility function for inherited jobs.
Definition: kjob.cpp:296
virtual bool setJob(KJob *job)
Attach this UI delegate to a job.
bool isSuspended() const
Returns if the job was suspended with the suspend() call.
Definition: kjob.cpp:78
QObject(QObject *parent)
virtual Q_SCRIPTABLE void start()=0
Starts the job asynchronously.
void setTotalAmount(Unit unit, qulonglong amount)
Sets the total size.
Definition: kjob.cpp:253
void suspended(KJob *job)
Emitted when the job is suspended.
Q_SCRIPTABLE qulonglong totalAmount(Unit unit) const
Returns the total amount of a given unit for this job.
Definition: kjob.cpp:215
KJob(QObject *parent=nullptr)
Creates a new KJob object.
Definition: kjob.cpp:32
void result(KJob *job)
Emitted when the job is finished (except when killed with KJob::Quietly).
void emitPercent(qulonglong processedAmount, qulonglong totalAmount)
Utility function for inherited jobs.
Definition: kjob.cpp:283
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setAutoDelete(bool autodelete)
set the auto-delete property of the job.
Definition: kjob.cpp:323
QObject * parent() const const
Q_SCRIPTABLE qulonglong processedAmount(Unit unit) const
Returns the processed amount of a given unit for this job.
Definition: kjob.cpp:210
virtual bool doResume()
Resumes this job.
Definition: kjob.cpp:156
The base class for all jobs.
Definition: kjob.h:75
virtual bool doSuspend()
Suspends this job.
Definition: kjob.cpp:151
Capabilities capabilities() const
Returns the capabilities of this job.
QString errorText() const
Returns the error text if there has been an error.
int error() const
Returns the error code, if there has been an error.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed May 27 2020 23:06:03 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.