KIO

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

KDE's Doxygen guidelines are available online.