KIO

job.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2000 Stephan Kulow <coolo@kde.org>
4 SPDX-FileCopyrightText: 2000-2009 David Faure <faure@kde.org>
5 SPDX-FileCopyrightText: 2000-2009 Waldo Bastian <bastian@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "job.h"
11#include "job_p.h"
12
13#include <time.h>
14
15#include <KLocalizedString>
16#include <KStringHandler>
17
18#include "worker_p.h"
19#include <kio/jobuidelegateextension.h>
20
21using namespace KIO;
22
23Job::Job()
24 : KCompositeJob(nullptr)
25 , d_ptr(new JobPrivate)
26{
27 d_ptr->q_ptr = this;
28 setCapabilities(KJob::Killable | KJob::Suspendable);
29}
30
31Job::Job(JobPrivate &dd)
32 : KCompositeJob(nullptr)
33 , d_ptr(&dd)
34{
35 d_ptr->q_ptr = this;
36 setCapabilities(KJob::Killable | KJob::Suspendable);
37}
38
39Job::~Job()
40{
41 delete d_ptr;
42}
43
45{
46 Q_D(const Job);
47 return d->m_uiDelegateExtension;
48}
49
51{
52 Q_D(Job);
53 d->m_uiDelegateExtension = extension;
54}
55
56bool Job::addSubjob(KJob *jobBase)
57{
58 // qDebug() << "addSubjob(" << jobBase << ") this=" << this;
59
60 bool ok = KCompositeJob::addSubjob(jobBase);
61 KIO::Job *job = qobject_cast<KIO::Job *>(jobBase);
62 if (ok && job) {
63 // Copy metadata into subjob (e.g. window-id, user-timestamp etc.)
64 Q_D(Job);
65 job->mergeMetaData(d->m_outgoingMetaData);
66
67 // Forward information from that subjob.
68 connect(job, &KJob::speed, this, [this](KJob *job, ulong speed) {
69 Q_UNUSED(job);
71 });
72 job->setProperty("widget", property("widget")); // see KJobWidgets
73 job->setProperty("window", property("window")); // see KJobWidgets
74 job->setProperty("userTimestamp", property("userTimestamp")); // see KJobWidgets
75 job->setUiDelegateExtension(d->m_uiDelegateExtension);
76 }
77 return ok;
78}
79
80bool Job::removeSubjob(KJob *jobBase)
81{
82 // qDebug() << "removeSubjob(" << jobBase << ") this=" << this << "subjobs=" << subjobs().count();
83 return KCompositeJob::removeSubjob(jobBase);
84}
85
86static QString url_description_string(const QUrl &url)
87{
88 return url.scheme() == QLatin1String("data") ? QStringLiteral("data:[...]") : KStringHandler::csqueeze(url.toDisplayString(QUrl::PreferLocalFile), 100);
89}
90
91KIO::JobPrivate::~JobPrivate()
92{
93}
94
95void JobPrivate::emitMoving(KIO::Job *job, const QUrl &src, const QUrl &dest)
96{
97 static const QString s_title = i18nc("@title job", "Moving");
98 static const QString s_source = i18nc("The source of a file operation", "Source");
99 static const QString s_destination = i18nc("The destination of a file operation", "Destination");
100 Q_EMIT job->description(job, s_title, qMakePair(s_source, url_description_string(src)), qMakePair(s_destination, url_description_string(dest)));
101}
102
103void JobPrivate::emitRenaming(KIO::Job *job, const QUrl &src, const QUrl &dest)
104{
105 static const QString s_title = i18nc("@title job", "Renaming");
106 static const QString s_source = i18nc("The source of a file operation", "Source");
107 static const QString s_destination = i18nc("The destination of a file operation", "Destination");
108 Q_EMIT job->description(job, s_title, {s_source, url_description_string(src)}, {s_destination, url_description_string(dest)});
109}
110
111void JobPrivate::emitCopying(KIO::Job *job, const QUrl &src, const QUrl &dest)
112{
113 static const QString s_title = i18nc("@title job", "Copying");
114 static const QString s_source = i18nc("The source of a file operation", "Source");
115 static const QString s_destination = i18nc("The destination of a file operation", "Destination");
116 Q_EMIT job->description(job, s_title, qMakePair(s_source, url_description_string(src)), qMakePair(s_destination, url_description_string(dest)));
117}
118
119void JobPrivate::emitCreatingDir(KIO::Job *job, const QUrl &dir)
120{
121 static const QString s_title = i18nc("@title job", "Creating directory");
122 static const QString s_directory = i18n("Directory");
123 Q_EMIT job->description(job, s_title, qMakePair(s_directory, url_description_string(dir)));
124}
125
126void JobPrivate::emitDeleting(KIO::Job *job, const QUrl &url)
127{
128 static const QString s_title = i18nc("@title job", "Deleting");
129 static const QString s_file = i18n("File");
130 Q_EMIT job->description(job, s_title, qMakePair(s_file, url_description_string(url)));
131}
132
133void JobPrivate::emitStating(KIO::Job *job, const QUrl &url)
134{
135 static const QString s_title = i18nc("@title job", "Examining");
136 static const QString s_file = i18n("File");
137 Q_EMIT job->description(job, s_title, qMakePair(s_file, url_description_string(url)));
138}
139
140void JobPrivate::emitTransferring(KIO::Job *job, const QUrl &url)
141{
142 static const QString s_title = i18nc("@title job", "Transferring");
143 static const QString s_source = i18nc("The source of a file operation", "Source");
144 Q_EMIT job->description(job, s_title, qMakePair(s_source, url_description_string(url)));
145}
146
147void JobPrivate::emitMounting(KIO::Job *job, const QString &dev, const QString &point)
148{
149 Q_EMIT job->description(job, i18nc("@title job", "Mounting"), qMakePair(i18n("Device"), dev), qMakePair(i18n("Mountpoint"), point));
150}
151
152void JobPrivate::emitUnmounting(KIO::Job *job, const QString &point)
153{
154 Q_EMIT job->description(job, i18nc("@title job", "Unmounting"), qMakePair(i18n("Mountpoint"), point));
155}
156
158{
159 // kill all subjobs, without triggering their result slot
160 for (KJob *job : subjobs()) {
161 job->kill(KJob::Quietly);
162 }
163 clearSubjobs();
164
165 return true;
166}
167
169{
170 for (KJob *job : subjobs()) {
171 if (!job->suspend()) {
172 return false;
173 }
174 }
175
176 return true;
177}
178
180{
181 for (KJob *job : subjobs()) {
182 if (!job->resume()) {
183 return false;
184 }
185 }
186
187 return true;
188}
189
190// Job::errorString is implemented in job_error.cpp
191
193{
194 Q_D(Job);
195 Q_ASSERT(d->m_parentJob == nullptr);
196 Q_ASSERT(job);
197 d->m_parentJob = job;
198}
199
201{
202 return d_func()->m_parentJob;
203}
204
206{
207 return d_func()->m_incomingMetaData;
208}
209
211{
212 return d_func()->m_incomingMetaData.value(key, QString());
213}
214
215void Job::setMetaData(const KIO::MetaData &_metaData)
216{
217 Q_D(Job);
218 d->m_outgoingMetaData = _metaData;
219}
220
221void Job::addMetaData(const QString &key, const QString &value)
222{
223 d_func()->m_outgoingMetaData.insert(key, value);
224}
225
227{
228 Q_D(Job);
229 for (auto it = values.cbegin(); it != values.cend(); ++it) {
230 d->m_outgoingMetaData.insert(it.key(), it.value());
231 }
232}
233
235{
236 Q_D(Job);
237 for (auto it = values.cbegin(); it != values.cend(); ++it) {
238 // there's probably a faster way
239 if (!d->m_outgoingMetaData.contains(it.key())) {
240 d->m_outgoingMetaData.insert(it.key(), it.value());
241 }
242 }
243}
244
246{
247 return d_func()->m_outgoingMetaData;
248}
249
250QByteArray JobPrivate::privilegeOperationData()
251{
252 PrivilegeOperationStatus status = OperationNotAllowed;
253
254 if (m_parentJob) {
255 QByteArray jobData = m_parentJob->d_func()->privilegeOperationData();
256 // Copy meta-data from parent job
257 m_incomingMetaData.insert(QStringLiteral("TestData"), m_parentJob->queryMetaData(QStringLiteral("TestData")));
258 return jobData;
259 } else {
260 if (m_privilegeExecutionEnabled) {
261 status = OperationAllowed;
262 switch (m_operationType) {
263 case ChangeAttr:
264 m_title = i18n("Change Attribute");
265 m_message = i18n(
266 "Root privileges are required to change file attributes. "
267 "Do you want to continue?");
268 break;
269 case Copy:
270 m_title = i18n("Copy Files");
271 m_message = i18n(
272 "Root privileges are required to complete the copy operation. "
273 "Do you want to continue?");
274 break;
275 case Delete:
276 m_title = i18n("Delete Files");
277 m_message = i18n(
278 "Root privileges are required to complete the delete operation. "
279 "However, doing so may damage your system. Do you want to continue?");
280 break;
281 case MkDir:
282 m_title = i18n("Create Folder");
283 m_message = i18n(
284 "Root privileges are required to create this folder. "
285 "Do you want to continue?");
286 break;
287 case Move:
288 m_title = i18n("Move Items");
289 m_message = i18n(
290 "Root privileges are required to complete the move operation. "
291 "Do you want to continue?");
292 break;
293 case Rename:
294 m_title = i18n("Rename");
295 m_message = i18n(
296 "Root privileges are required to complete renaming. "
297 "Do you want to continue?");
298 break;
299 case Symlink:
300 m_title = i18n("Create Symlink");
301 m_message = i18n(
302 "Root privileges are required to create a symlink. "
303 "Do you want to continue?");
304 break;
305 case Transfer:
306 m_title = i18n("Transfer data");
307 m_message = i18n(
308 "Root privileges are required to complete transferring data. "
309 "Do you want to continue?");
310 Q_FALLTHROUGH();
311 default:
312 break;
313 }
314
315 if (m_outgoingMetaData.value(QStringLiteral("UnitTesting")) == QLatin1String("true")) {
316 // Set meta-data for the top-level job
317 m_incomingMetaData.insert(QStringLiteral("TestData"), QStringLiteral("PrivilegeOperationAllowed"));
318 }
319 }
320 }
321
322 QByteArray parentJobData;
323 QDataStream ds(&parentJobData, QIODevice::WriteOnly);
324 ds << status << m_title << m_message;
325 return parentJobData;
326}
327
328//////////////////////////
329
330class KIO::DirectCopyJobPrivate : public KIO::SimpleJobPrivate
331{
332public:
333 DirectCopyJobPrivate(const QUrl &url, int command, const QByteArray &packedArgs)
334 : SimpleJobPrivate(url, command, packedArgs)
335 {
336 }
337
338 /**
339 * @internal
340 * Called by the scheduler when a @p worker gets to
341 * work on this job.
342 * @param worker the worker that starts working on this job
343 */
344 void start(Worker *worker) override;
345
346 Q_DECLARE_PUBLIC(DirectCopyJob)
347};
348
349DirectCopyJob::DirectCopyJob(const QUrl &url, const QByteArray &packedArgs)
350 : SimpleJob(*new DirectCopyJobPrivate(url, CMD_COPY, packedArgs))
351{
353}
354
355DirectCopyJob::~DirectCopyJob()
356{
357}
358
359void DirectCopyJobPrivate::start(Worker *worker)
360{
361 Q_Q(DirectCopyJob);
362 q->connect(worker, &WorkerInterface::canResume, q, &DirectCopyJob::slotCanResume);
363 SimpleJobPrivate::start(worker);
364}
365
366void DirectCopyJob::slotCanResume(KIO::filesize_t offset)
367{
368 Q_EMIT canResume(this, offset);
369}
370
371//////////////////////////
372
374{
375 KIO_ARGS << src << qint8(true); // isFile
376 SimpleJob *job = SimpleJobPrivate::newJob(src, CMD_DEL, packedArgs, flags);
377 if (job->uiDelegateExtension()) {
378 job->uiDelegateExtension()->createClipboardUpdater(job, JobUiDelegateExtension::RemoveContent);
379 }
380 return job;
381}
382
383//////////
384////
385
386#include "moc_job_base.cpp"
387#include "moc_job_p.cpp"
virtual bool addSubjob(KJob *job)
const QList< KJob * > & subjobs() const
virtual bool removeSubjob(KJob *job)
void clearSubjobs()
An abstract class defining interaction with users from KIO jobs:
virtual ClipboardUpdater * createClipboardUpdater(Job *job, ClipboardUpdaterMode mode)
Creates a clipboard updater as a child of the given job.
The base class for all jobs.
Definition job_base.h:45
void setMetaData(const KIO::MetaData &metaData)
Set meta data to be sent to the worker, replacing existing meta data.
Definition job.cpp:215
bool doKill() override
Abort this job.
Definition job.cpp:157
void setParentJob(Job *parentJob)
Set the parent Job.
Definition job.cpp:192
Job * parentJob() const
Returns the parent job, if there is one.
Definition job.cpp:200
void mergeMetaData(const QMap< QString, QString > &values)
Add key/value pairs to the meta data that is sent to the worker.
Definition job.cpp:234
JobUiDelegateExtension * uiDelegateExtension() const
Retrieves the UI delegate extension used by this job.
Definition job.cpp:44
void setUiDelegateExtension(JobUiDelegateExtension *extension)
Sets the UI delegate extension to be used by this job.
Definition job.cpp:50
MetaData outgoingMetaData() const
Definition job.cpp:245
QString queryMetaData(const QString &key)
Query meta data received from the worker.
Definition job.cpp:210
bool removeSubjob(KJob *job) override
Mark a sub job as being done.
Definition job.cpp:80
bool doSuspend() override
Suspend this job.
Definition job.cpp:168
bool doResume() override
Resume this job.
Definition job.cpp:179
bool addSubjob(KJob *job) override
Add a job that has to be finished before a result is emitted.
Definition job.cpp:56
MetaData metaData() const
Get meta data received from the worker.
Definition job.cpp:205
void addMetaData(const QString &key, const QString &value)
Add key/value pair to the meta data that is sent to the worker.
Definition job.cpp:221
MetaData is a simple map of key/value strings.
Definition metadata.h:23
A simple job (one url and one command).
Definition simplejob.h:27
bool resume()
void description(KJob *job, const QString &title, const QPair< QString, QString > &field1=QPair< QString, QString >(), const QPair< QString, QString > &field2=QPair< QString, QString >())
bool suspend()
bool kill(KJob::KillVerbosity verbosity=KJob::Quietly)
void setUiDelegate(KJobUiDelegate *delegate)
void emitSpeed(unsigned long speed)
void speed(KJob *job, unsigned long speed)
Q_SCRIPTABLE Q_NOREPLY void start()
Q_SCRIPTABLE CaptureState status()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
A namespace for KIO globals.
KIOCORE_EXPORT SimpleJob * file_delete(const QUrl &src, JobFlags flags=DefaultFlags)
Delete a single file.
Definition job.cpp:373
PrivilegeOperationStatus
Specifies privilege file operation status.
Definition global.h:235
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there's one, to create a delegate and return it.
qulonglong filesize_t
64-bit file size
Definition global.h:35
QByteArray & insert(qsizetype i, QByteArrayView data)
const_iterator cbegin() const const
const_iterator cend() const const
iterator insert(const Key &key, const T &value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QVariant property(const char *name) const const
bool setProperty(const char *name, QVariant &&value)
QString scheme() const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:51 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.