KIO

filecopyjob.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2000 Stephan Kulow <[email protected]>
3  2000-2009 David Faure <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "filecopyjob.h"
22 #include "job_p.h"
23 #include <QFile>
24 #include <QTimer>
25 #include "kprotocolmanager.h"
26 #include "scheduler.h"
27 #include "slave.h"
28 #include <KLocalizedString>
29 
30 using namespace KIO;
31 
32 static inline Slave *jobSlave(SimpleJob *job)
33 {
34  return SimpleJobPrivate::get(job)->m_slave;
35 }
36 
38 class KIO::FileCopyJobPrivate: public KIO::JobPrivate
39 {
40 public:
41  FileCopyJobPrivate(const QUrl &src, const QUrl &dest, int permissions,
42  bool move, JobFlags flags)
43  : m_sourceSize(filesize_t(-1)), m_src(src), m_dest(dest), m_moveJob(nullptr), m_copyJob(nullptr), m_delJob(nullptr),
44  m_chmodJob(nullptr), m_getJob(nullptr), m_putJob(nullptr), m_permissions(permissions),
45  m_move(move), m_mustChmod(0), m_bFileCopyInProgress(false), m_flags(flags)
46  {
47  }
48  KIO::filesize_t m_sourceSize;
49  QDateTime m_modificationTime;
50  QUrl m_src;
51  QUrl m_dest;
52  QByteArray m_buffer;
53  SimpleJob *m_moveJob;
54  SimpleJob *m_copyJob;
55  SimpleJob *m_delJob;
56  SimpleJob *m_chmodJob;
57  TransferJob *m_getJob;
58  TransferJob *m_putJob;
59  int m_permissions;
60  bool m_move: 1;
61  bool m_canResume: 1;
62  bool m_resumeAnswerSent: 1;
63  bool m_mustChmod: 1;
64  bool m_bFileCopyInProgress: 1;
65  JobFlags m_flags;
66 
67  void startBestCopyMethod();
68  void startCopyJob();
69  void startCopyJob(const QUrl &slave_url);
70  void startRenameJob(const QUrl &slave_url);
71  void startDataPump();
72  void connectSubjob(SimpleJob *job);
73 
74  void slotStart();
75  void slotData(KIO::Job *, const QByteArray &data);
76  void slotDataReq(KIO::Job *, QByteArray &data);
77  void slotMimetype(KIO::Job *, const QString &type);
83  void slotCanResume(KIO::Job *job, KIO::filesize_t offset);
84 
85  Q_DECLARE_PUBLIC(FileCopyJob)
86 
87  static inline FileCopyJob *newJob(const QUrl &src, const QUrl &dest, int permissions, bool move,
88  JobFlags flags)
89  {
90  //qDebug() << src << "->" << dest;
91  FileCopyJob *job = new FileCopyJob(
92  *new FileCopyJobPrivate(src, dest, permissions, move, flags));
93  job->setProperty("destUrl", dest.toString());
95  if (!(flags & HideProgressInfo)) {
97  }
98  if (!(flags & NoPrivilegeExecution)) {
99  job->d_func()->m_privilegeExecutionEnabled = true;
100  job->d_func()->m_operationType = move ? Move : Copy;
101  }
102  return job;
103  }
104 };
105 
106 /*
107  * The FileCopyJob works according to the famous Bavarian
108  * 'Alternating Bitburger Protocol': we either drink a beer or we
109  * we order a beer, but never both at the same time.
110  * Translated to io-slaves: We alternate between receiving a block of data
111  * and sending it away.
112  */
113 FileCopyJob::FileCopyJob(FileCopyJobPrivate &dd)
114  : Job(dd)
115 {
116  Q_D(FileCopyJob);
117  QTimer::singleShot(0, this, [d]() {
118  d->slotStart();
119  });
120 }
121 
122 void FileCopyJobPrivate::slotStart()
123 {
124  Q_Q(FileCopyJob);
125  if (!m_move) {
126  JobPrivate::emitCopying(q, m_src, m_dest);
127  } else {
128  JobPrivate::emitMoving(q, m_src, m_dest);
129  }
130 
131  if (m_move) {
132  // The if() below must be the same as the one in startBestCopyMethod
133  if ((m_src.scheme() == m_dest.scheme()) &&
134  (m_src.host() == m_dest.host()) &&
135  (m_src.port() == m_dest.port()) &&
136  (m_src.userName() == m_dest.userName()) &&
137  (m_src.password() == m_dest.password())) {
138  startRenameJob(m_src);
139  return;
140  } else if (m_src.isLocalFile() && KProtocolManager::canRenameFromFile(m_dest)) {
141  startRenameJob(m_dest);
142  return;
143  } else if (m_dest.isLocalFile() && KProtocolManager::canRenameToFile(m_src)) {
144  startRenameJob(m_src);
145  return;
146  }
147  // No fast-move available, use copy + del.
148  }
149  startBestCopyMethod();
150 }
151 
152 void FileCopyJobPrivate::startBestCopyMethod()
153 {
154  if ((m_src.scheme() == m_dest.scheme()) &&
155  (m_src.host() == m_dest.host()) &&
156  (m_src.port() == m_dest.port()) &&
157  (m_src.userName() == m_dest.userName()) &&
158  (m_src.password() == m_dest.password())) {
159  startCopyJob();
160  } else if (m_src.isLocalFile() && KProtocolManager::canCopyFromFile(m_dest)) {
161  startCopyJob(m_dest);
162  } else if (m_dest.isLocalFile() && KProtocolManager::canCopyToFile(m_src) &&
164  startCopyJob(m_src);
165  } else {
166  startDataPump();
167  }
168 }
169 
170 FileCopyJob::~FileCopyJob()
171 {
172 }
173 
175 {
176  Q_D(FileCopyJob);
177  d->m_sourceSize = size;
178  if (size != (KIO::filesize_t) - 1) {
180  }
181 }
182 
184 {
185  Q_D(FileCopyJob);
186  d->m_modificationTime = mtime;
187 }
188 
190 {
191  return d_func()->m_src;
192 }
193 
195 {
196  return d_func()->m_dest;
197 }
198 
199 void FileCopyJobPrivate::startCopyJob()
200 {
201  startCopyJob(m_src);
202 }
203 
204 void FileCopyJobPrivate::startCopyJob(const QUrl &slave_url)
205 {
206  Q_Q(FileCopyJob);
207  //qDebug();
208  KIO_ARGS << m_src << m_dest << m_permissions << (qint8)(m_flags & Overwrite);
209  auto job = new DirectCopyJob(slave_url, packedArgs);
210  m_copyJob = job;
211  m_copyJob->setParentJob(q);
212  if (m_modificationTime.isValid()) {
213  m_copyJob->addMetaData(QStringLiteral("modified"), m_modificationTime.toString(Qt::ISODate)); // #55804
214  }
215  q->addSubjob(m_copyJob);
216  connectSubjob(m_copyJob);
217  q->connect(job, &DirectCopyJob::canResume, q, [this](KIO::Job *job, KIO::filesize_t offset) {
218  slotCanResume(job, offset);
219  });
220 }
221 
222 void FileCopyJobPrivate::startRenameJob(const QUrl &slave_url)
223 {
224  Q_Q(FileCopyJob);
225  m_mustChmod = true; // CMD_RENAME by itself doesn't change permissions
226  KIO_ARGS << m_src << m_dest << (qint8)(m_flags & Overwrite);
227  m_moveJob = SimpleJobPrivate::newJobNoUi(slave_url, CMD_RENAME, packedArgs);
228  m_moveJob->setParentJob(q);
229  if (m_modificationTime.isValid()) {
230  m_moveJob->addMetaData(QStringLiteral("modified"), m_modificationTime.toString(Qt::ISODate)); // #55804
231  }
232  q->addSubjob(m_moveJob);
233  connectSubjob(m_moveJob);
234 }
235 
236 void FileCopyJobPrivate::connectSubjob(SimpleJob *job)
237 {
238  Q_Q(FileCopyJob);
239  q->connect(job, &KJob::totalSize, q, [q](KJob *job, qulonglong totalSize) {
240  Q_UNUSED(job);
241  if (totalSize != q->totalAmount(KJob::Bytes)) {
242  q->setTotalAmount(KJob::Bytes, totalSize);
243  }
244  });
245 
246  q->connect(job, &KJob::processedSize, q, [q, this](KJob *job, qulonglong processedSize) {
247  if (job == m_copyJob) {
248  m_bFileCopyInProgress = processedSize > 0;
249  }
250  q->setProcessedAmount(KJob::Bytes, processedSize);
251  });
252 
253  q->connect(job, QOverload<KJob*,ulong>::of(&KJob::percent), q, [q](KJob *job, ulong percent) {
254  Q_UNUSED(job);
255  if (percent > q->percent()) {
256  q->setPercent(percent);
257  }
258  });
259 
260  if (q->isSuspended()) {
261  job->suspend();
262  }
263 }
264 
265 bool FileCopyJob::doSuspend()
266 {
267  Q_D(FileCopyJob);
268  if (d->m_moveJob) {
269  d->m_moveJob->suspend();
270  }
271 
272  if (d->m_copyJob) {
273  d->m_copyJob->suspend();
274  }
275 
276  if (d->m_getJob) {
277  d->m_getJob->suspend();
278  }
279 
280  if (d->m_putJob) {
281  d->m_putJob->suspend();
282  }
283 
284  Job::doSuspend();
285  return true;
286 }
287 
288 bool FileCopyJob::doResume()
289 {
290  Q_D(FileCopyJob);
291  if (d->m_moveJob) {
292  d->m_moveJob->resume();
293  }
294 
295  if (d->m_copyJob) {
296  d->m_copyJob->resume();
297  }
298 
299  if (d->m_getJob) {
300  d->m_getJob->resume();
301  }
302 
303  if (d->m_putJob) {
304  d->m_putJob->resume();
305  }
306 
307  Job::doResume();
308  return true;
309 }
310 
311 void FileCopyJobPrivate::startDataPump()
312 {
313  Q_Q(FileCopyJob);
314  //qDebug();
315 
316  m_canResume = false;
317  m_resumeAnswerSent = false;
318  m_getJob = nullptr; // for now
319  m_putJob = put(m_dest, m_permissions, (m_flags | HideProgressInfo) /* no GUI */);
320  m_putJob->setParentJob(q);
321  //qDebug() << "m_putJob=" << m_putJob << "m_dest=" << m_dest;
322  if (m_modificationTime.isValid()) {
323  m_putJob->setModificationTime(m_modificationTime);
324  }
325 
326  // The first thing the put job will tell us is whether we can
327  // resume or not (this is always emitted)
328  q->connect(m_putJob, &KIO::TransferJob::canResume, q, [this](KIO::Job *job, KIO::filesize_t offset) {
329  slotCanResume(job, offset);
330  });
331  q->connect(m_putJob, &KIO::TransferJob::dataReq, q, [this](KIO::Job *job, QByteArray &data) {
332  slotDataReq(job, data);
333  });
334  q->addSubjob(m_putJob);
335 }
336 
337 void FileCopyJobPrivate::slotCanResume(KIO::Job *job, KIO::filesize_t offset)
338 {
339  Q_Q(FileCopyJob);
340  if (job == m_putJob || job == m_copyJob) {
341  //qDebug() << "'can resume' from PUT job. offset=" << KIO::number(offset);
342  if (offset) {
343  RenameDialog_Result res = Result_Resume;
344 
345  if (!KProtocolManager::autoResume() && !(m_flags & Overwrite) && m_uiDelegateExtension) {
346  QString newPath;
347  KIO::Job *job = (q->parentJob()) ? q->parentJob() : q;
348  // Ask confirmation about resuming previous transfer
349  res = m_uiDelegateExtension->askFileRename(
350  job, i18n("File Already Exists"),
351  m_src,
352  m_dest,
354  m_sourceSize, offset);
355  }
356 
357  if (res == Result_Overwrite || (m_flags & Overwrite)) {
358  offset = 0;
359  } else if (res == Result_Cancel) {
360  if (job == m_putJob) {
361  m_putJob->kill(FileCopyJob::Quietly);
362  q->removeSubjob(m_putJob);
363  m_putJob = nullptr;
364  } else {
365  m_copyJob->kill(FileCopyJob::Quietly);
366  q->removeSubjob(m_copyJob);
367  m_copyJob = nullptr;
368  }
369  q->setError(ERR_USER_CANCELED);
370  q->emitResult();
371  return;
372  }
373  } else {
374  m_resumeAnswerSent = true; // No need for an answer
375  }
376 
377  if (job == m_putJob) {
378  m_getJob = KIO::get(m_src, NoReload, HideProgressInfo /* no GUI */);
379  m_getJob->setParentJob(q);
380  //qDebug() << "m_getJob=" << m_getJob << m_src;
381  m_getJob->addMetaData(QStringLiteral("errorPage"), QStringLiteral("false"));
382  m_getJob->addMetaData(QStringLiteral("AllowCompressedPage"), QStringLiteral("false"));
383  // Set size in subjob. This helps if the slave doesn't emit totalSize.
384  if (m_sourceSize != (KIO::filesize_t) - 1) {
385  m_getJob->setTotalAmount(KJob::Bytes, m_sourceSize);
386  }
387  if (offset) {
388  //qDebug() << "Setting metadata for resume to" << (unsigned long) offset;
389  m_getJob->addMetaData(QStringLiteral("range-start"), KIO::number(offset));
390 
391  // Might or might not get emitted
392  q->connect(m_getJob, &KIO::TransferJob::canResume, q, [this](KIO::Job *job, KIO::filesize_t offset) {
393  slotCanResume(job, offset);
394  });
395  }
396  jobSlave(m_putJob)->setOffset(offset);
397 
398  m_putJob->d_func()->internalSuspend();
399  q->addSubjob(m_getJob);
400  connectSubjob(m_getJob); // Progress info depends on get
401  m_getJob->d_func()->internalResume(); // Order a beer
402 
403  q->connect(m_getJob, &KIO::TransferJob::data, q, [this](KIO::Job *job, const QByteArray &data) {
404  slotData(job, data);
405  });
406  q->connect(m_getJob, QOverload<KIO::Job *, const QString &>::of(&KIO::TransferJob::mimetype), q, [this](KIO::Job *job, const QString &type) {
407  slotMimetype(job, type);
408  });
409  } else { // copyjob
410  jobSlave(m_copyJob)->sendResumeAnswer(offset != 0);
411  }
412  } else if (job == m_getJob) {
413  // Cool, the get job said ok, we can resume
414  m_canResume = true;
415  //qDebug() << "'can resume' from the GET job -> we can resume";
416 
417  jobSlave(m_getJob)->setOffset(jobSlave(m_putJob)->offset());
418  } else {
419  qCWarning(KIO_CORE) << "unknown job=" << job << "m_getJob=" << m_getJob << "m_putJob=" << m_putJob;
420  }
421 }
422 
423 void FileCopyJobPrivate::slotData(KIO::Job *, const QByteArray &data)
424 {
425  //qDebug() << "data size:" << data.size();
426  Q_ASSERT(m_putJob);
427  if (!m_putJob) {
428  return; // Don't crash
429  }
430  m_getJob->d_func()->internalSuspend();
431  m_putJob->d_func()->internalResume(); // Drink the beer
432  m_buffer += data;
433 
434  // On the first set of data incoming, we tell the "put" slave about our
435  // decision about resuming
436  if (!m_resumeAnswerSent) {
437  m_resumeAnswerSent = true;
438  //qDebug() << "(first time) -> send resume answer " << m_canResume;
439  jobSlave(m_putJob)->sendResumeAnswer(m_canResume);
440  }
441 }
442 
443 void FileCopyJobPrivate::slotDataReq(KIO::Job *, QByteArray &data)
444 {
445  Q_Q(FileCopyJob);
446  //qDebug();
447  if (!m_resumeAnswerSent && !m_getJob) {
448  // This can't happen
449  q->setError(ERR_INTERNAL);
450  q->setErrorText(QStringLiteral("'Put' job did not send canResume or 'Get' job did not send data!"));
451  m_putJob->kill(FileCopyJob::Quietly);
452  q->removeSubjob(m_putJob);
453  m_putJob = nullptr;
454  q->emitResult();
455  return;
456  }
457  if (m_getJob) {
458  m_getJob->d_func()->internalResume(); // Order more beer
459  m_putJob->d_func()->internalSuspend();
460  }
461  data = m_buffer;
462  m_buffer = QByteArray();
463 }
464 
465 void FileCopyJobPrivate::slotMimetype(KIO::Job *, const QString &type)
466 {
467  Q_Q(FileCopyJob);
468  emit q->mimetype(q, type);
469 }
470 
472 {
473  Q_D(FileCopyJob);
474  //qDebug() << "this=" << this << "job=" << job;
475  removeSubjob(job);
476 
477  // If result comes from copyjob then we are not writing anymore.
478  if (job == d->m_copyJob) {
479  d->m_bFileCopyInProgress = false;
480  }
481 
482  // Did job have an error ?
483  if (job->error()) {
484  if ((job == d->m_moveJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) {
485  d->m_moveJob = nullptr;
486  d->startBestCopyMethod();
487  return;
488  } else if ((job == d->m_copyJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) {
489  d->m_copyJob = nullptr;
490  d->startDataPump();
491  return;
492  } else if (job == d->m_getJob) {
493  d->m_getJob = nullptr;
494  if (d->m_putJob) {
495  d->m_putJob->kill(Quietly);
496  removeSubjob(d->m_putJob);
497  }
498  } else if (job == d->m_putJob) {
499  d->m_putJob = nullptr;
500  if (d->m_getJob) {
501  d->m_getJob->kill(Quietly);
502  removeSubjob(d->m_getJob);
503  }
504  } else if (job == d->m_chmodJob) {
505  d->m_chmodJob = nullptr;
506  if (d->m_delJob) {
507  d->m_delJob->kill(Quietly);
508  removeSubjob(d->m_delJob);
509  }
510  } else if (job == d->m_delJob) {
511  d->m_delJob = nullptr;
512  if (d->m_chmodJob) {
513  d->m_chmodJob->kill(Quietly);
514  removeSubjob(d->m_chmodJob);
515  }
516  }
517  setError(job->error());
518  setErrorText(job->errorText());
519  emitResult();
520  return;
521  }
522 
523  if (d->m_mustChmod) {
524  // If d->m_permissions == -1, keep the default permissions
525  if (d->m_permissions != -1) {
526  d->m_chmodJob = chmod(d->m_dest, d->m_permissions);
527  addSubjob(d->m_chmodJob);
528  }
529  d->m_mustChmod = false;
530  }
531 
532  if (job == d->m_moveJob) {
533  d->m_moveJob = nullptr; // Finished
534  }
535 
536  if (job == d->m_copyJob) {
537  d->m_copyJob = nullptr;
538  if (d->m_move) {
539  d->m_delJob = file_delete(d->m_src, HideProgressInfo/*no GUI*/); // Delete source
540  addSubjob(d->m_delJob);
541  }
542  }
543 
544  if (job == d->m_getJob) {
545  //qDebug() << "m_getJob finished";
546  d->m_getJob = nullptr; // No action required
547  if (d->m_putJob) {
548  d->m_putJob->d_func()->internalResume();
549  }
550  }
551 
552  if (job == d->m_putJob) {
553  //qDebug() << "m_putJob finished";
554  d->m_putJob = nullptr;
555  if (d->m_getJob) {
556  // The get job is still running, probably after emitting data(QByteArray())
557  // and before we receive its finished().
558  d->m_getJob->d_func()->internalResume();
559  }
560  if (d->m_move) {
561  d->m_delJob = file_delete(d->m_src, HideProgressInfo/*no GUI*/); // Delete source
562  addSubjob(d->m_delJob);
563  }
564  }
565 
566  if (job == d->m_delJob) {
567  d->m_delJob = nullptr; // Finished
568  }
569 
570  if (job == d->m_chmodJob) {
571  d->m_chmodJob = nullptr; // Finished
572  }
573 
574  if (!hasSubjobs()) {
575  emitResult();
576  }
577 }
578 
579 bool FileCopyJob::doKill()
580 {
581 #ifdef Q_OS_WIN
582 //TODO Use SetConsoleCtrlHandler on Windows or similar behaviour.
583 // https://stackoverflow.com/questions/2007516/is-there-a-posix-sigterm-alternative-on-windows-a-gentle-kill-for-console-ap
584 // https://danielkaes.wordpress.com/2009/06/04/how-to-catch-kill-events-with-python/
585 // https://phabricator.kde.org/D25117#566107
586 
587  Q_D(FileCopyJob);
588 
589  // If we are interrupted in the middle of file copying,
590  // we may end up with corrupted file at the destination.
591  // It is better to clean up this file. If a copy is being
592  // made as part of move operation then delete the dest only if
593  // source file is intact (m_delJob == NULL).
594  if (d->m_bFileCopyInProgress && d->m_copyJob && d->m_dest.isLocalFile()) {
595  if (d->m_flags & Overwrite) {
596  QFile::remove(d->m_dest.toLocalFile() + QStringLiteral(".part"));
597  } else {
598  QFile::remove(d->m_dest.toLocalFile());
599  }
600  }
601 #endif
602  return Job::doKill();
603 }
604 
605 FileCopyJob *KIO::file_copy(const QUrl &src, const QUrl &dest, int permissions,
606  JobFlags flags)
607 {
608  return FileCopyJobPrivate::newJob(src, dest, permissions, false, flags);
609 }
610 
611 FileCopyJob *KIO::file_move(const QUrl &src, const QUrl &dest, int permissions,
612  JobFlags flags)
613 {
614  FileCopyJob *job = FileCopyJobPrivate::newJob(src, dest, permissions, true, flags);
615  if (job->uiDelegateExtension()) {
616  job->uiDelegateExtension()->createClipboardUpdater(job, JobUiDelegateExtension::UpdateContent);
617  }
618  return job;
619 }
620 
621 #include "moc_filecopyjob.cpp"
KIOCORE_EXPORT FileCopyJob * file_move(const QUrl &src, const QUrl &dest, int permissions=-1, JobFlags flags=DefaultFlags)
Move a single file.
bool kill(KillVerbosity verbosity=Quietly)
When set, automatically overwrite the destination if it exists already.
Definition: job_base.h:303
QString toString(Qt::DateFormat format) const const
virtual bool addSubjob(KJob *job)
qulonglong filesize_t
64-bit file size
Definition: global.h:51
virtual ClipboardUpdater * createClipboardUpdater(Job *job, ClipboardUpdaterMode mode)
Creates a clipboard updater as a child of the given job.
void addMetaData(const QString &key, const QString &value)
Add key/value pair to the meta data that is sent to the slave.
Definition: job.cpp:243
void emitResult()
QString userName(QUrl::ComponentFormattingOptions options) const const
void setUiDelegate(KJobUiDelegate *delegate)
bool remove()
A namespace for KIO globals.
Definition: authinfo.h:34
Hide progress information dialog, i.e.
Definition: job_base.h:287
Offer a "Resume" button (plus "Resume All" if RenameDialog_MultipleItems).
QString host(QUrl::ComponentFormattingOptions options) const const
void setError(int errorCode)
QUrl destUrl() const
Returns the destination URL.
bool doKill() override
Abort this job.
Definition: job.cpp:179
void setSourceSize(KIO::filesize_t size)
If you know the size of the source file, call this method to inform this job.
KIOCORE_EXPORT FileCopyJob * file_copy(const QUrl &src, const QUrl &dest, int permissions=-1, JobFlags flags=DefaultFlags)
Copy a single file.
int port(int defaultPort) const const
bool addSubjob(KJob *job) override
Add a job that has to be finished before a result is emitted.
Definition: job.cpp:75
static bool canCopyToFile(const QUrl &url)
Returns whether the protocol can copy files/objects directly to the filesystem itself.
bool hasSubjobs() const
void canResume(KIO::Job *job, KIO::filesize_t offset)
Don&#39;t offer a "Rename" button.
bool suspend()
void setErrorText(const QString &errorText)
QFlags< RenameDialog_Option > RenameDialog_Options
Stores a combination of RenameDialog_Option values.
QString mimetype() const
Call this in the slot connected to result, and only after making sure no error happened.
KIOCORE_EXPORT QString number(KIO::filesize_t size)
Converts a size to a string representation Not unlike QString::number(...)
Definition: global.cpp:66
When set, notifies the slave that application/job does not want privilege execution.
Definition: job_base.h:312
JobUiDelegateExtension * uiDelegateExtension() const
Retrieves the UI delegate extension used by this job.
Definition: job.cpp:63
void setModificationTime(const QDateTime &mtime)
Sets the modification time of the file.
void totalSize(KJob *job, qulonglong size)
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there&#39;s one, to create a delegate and return it...
static bool canRenameToFile(const QUrl &url)
Returns whether the protocol can rename (i.e.
KIOCORE_EXPORT KJobTrackerInterface * getJobTracker()
Returns the job tracker to be used by all KIO jobs (in which HideProgressInfo is not set) ...
Definition: jobtracker.cpp:25
Job * parentJob() const
Returns the parent job, if there is one.
Definition: job.cpp:222
KIOCORE_EXPORT TransferJob * put(const QUrl &url, int permissions, JobFlags flags=DefaultFlags)
Put (means: write)
QString scheme() const const
void processedSize(KJob *job, qulonglong size)
unsigned long percent() const
void setModificationTime(const QDateTime &mtime)
Sets the modification time of the file to be created (by KIO::put) Note that some kioslaves might ign...
QUrl srcUrl() const
Returns the source URL.
QString password(QUrl::ComponentFormattingOptions options) const const
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
Get (means: read).
static bool isSlaveOnHoldFor(const QUrl &url)
Returns true if there is a slave on hold for url.
Definition: scheduler.cpp:852
KIOCORE_EXPORT ChmodJob * chmod(const KFileItemList &lstItems, int permissions, int mask, const QString &newOwner, const QString &newGroup, bool recursive, JobFlags flags=DefaultFlags)
Creates a job that changes permissions/ownership on several files or directories, optionally recursiv...
Definition: chmodjob.cpp:285
bool isValid() const const
QString i18n(const char *text, const TYPE &arg...)
void data(KIO::Job *job, const QByteArray &data)
Data from the slave has arrived.
void setParentJob(Job *parentJob)
Set the parent Job.
Definition: job.cpp:214
The FileCopyJob copies data from one place to another.
Definition: filecopyjob.h:38
void dataReq(KIO::Job *job, QByteArray &data)
Request for data.
static bool autoResume()
Returns true if partial downloads should be automatically resumed.
void setTotalAmount(Unit unit, qulonglong amount)
RenameDialog_Result
The result of a rename or skip dialog.
The base class for all jobs.
Definition: job_base.h:57
bool doSuspend() override
Suspend this job.
Definition: job.cpp:190
static bool canRenameFromFile(const QUrl &url)
Returns whether the protocol can rename (i.e.
KIOCORE_EXPORT SimpleJob * file_delete(const QUrl &src, JobFlags flags=DefaultFlags)
Delete a single file.
Definition: job.cpp:388
bool setProperty(const char *name, const QVariant &value)
virtual void registerJob(KJob *job)
KIOCORE_EXPORT CopyJob * move(const QUrl &src, const QUrl &dest, JobFlags flags=DefaultFlags)
Moves a file or directory src to the given destination dest.
Definition: copyjob.cpp:2255
The transfer job pumps data into and/or out of a Slave.
Definition: transferjob.h:38
void slotResult(KJob *job) override
Called whenever a subjob finishes.
bool doResume() override
Resume this job.
Definition: job.cpp:201
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
We have an existing destination, show details about it and offer to overwrite it. ...
QString errorText() const
int error() const
static bool canCopyFromFile(const QUrl &url)
Returns whether the protocol can copy files/objects directly from the filesystem itself.
virtual bool removeSubjob(KJob *job)
A simple job (one url and one command).
Definition: simplejob.h:39
bool isLocalFile() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue Jul 14 2020 23:00:59 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.