KIO

deletejob.cpp
1 /* This file is part of the KDE libraries
2  Copyright 2000 Stephan Kulow <[email protected]>
3  Copyright 2000-2009 David Faure <[email protected]>
4  Copyright 2000 Waldo Bastian <[email protected]>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "deletejob.h"
23 
24 #include "global.h"
25 #include "job.h" // buildErrorString
26 #include "statjob.h"
27 #include "listjob.h"
28 #include "kcoredirlister.h"
29 #include "scheduler.h"
30 #include <KDirWatch>
31 #include "kprotocolmanager.h"
32 #include <kdirnotify.h>
33 #include "../pathhelpers_p.h"
34 
35 #include <KLocalizedString>
36 #include <kio/jobuidelegatefactory.h>
37 
38 #include <QTimer>
39 #include <QFile>
40 #include <QFileInfo>
41 #include <QDir>
42 #include <QPointer>
43 #include <QThread>
44 #include <QMetaObject>
45 
46 #include "job_p.h"
47 
48 extern bool kio_resolve_local_urls; // from copyjob.cpp, abused here to save a symbol.
49 
50 static bool isHttpProtocol(const QString &protocol)
51 {
52  return (protocol.startsWith(QLatin1String("webdav"), Qt::CaseInsensitive) ||
53  protocol.startsWith(QLatin1String("http"), Qt::CaseInsensitive));
54 }
55 
56 namespace KIO
57 {
58 enum DeleteJobState {
59  DELETEJOB_STATE_STATING,
60  DELETEJOB_STATE_DELETING_FILES,
61  DELETEJOB_STATE_DELETING_DIRS
62 };
63 
64 class DeleteJobIOWorker : public QObject {
65  Q_OBJECT
66 
67 Q_SIGNALS:
68  void rmfileResult(bool succeeded, bool isLink);
69  void rmddirResult(bool succeeded);
70 
71 public Q_SLOTS:
72 
77  void rmfile(const QUrl& url, bool isLink) {
78  emit rmfileResult(QFile::remove(url.toLocalFile()), isLink);
79  }
80 
85  void rmdir(const QUrl& url) {
86  emit rmddirResult(QDir().rmdir(url.toLocalFile()));
87  }
88 };
89 
90 class DeleteJobPrivate: public KIO::JobPrivate
91 {
92 public:
93  explicit DeleteJobPrivate(const QList<QUrl> &src)
94  : state(DELETEJOB_STATE_STATING)
95  , m_processedFiles(0)
96  , m_processedDirs(0)
97  , m_totalFilesDirs(0)
98  , m_srcList(src)
99  , m_currentStat(m_srcList.begin())
100  , m_reportTimer(nullptr)
101  {
102  }
103  DeleteJobState state;
104  int m_processedFiles;
105  int m_processedDirs;
106  int m_totalFilesDirs;
107  QUrl m_currentURL;
108  QList<QUrl> files;
109  QList<QUrl> symlinks;
111  QList<QUrl> m_srcList;
112  QList<QUrl>::iterator m_currentStat;
113  QSet<QString> m_parentDirs;
114  QTimer *m_reportTimer;
115  DeleteJobIOWorker *m_ioworker = nullptr;
116  QThread *m_thread = nullptr;
117 
118  void statNextSrc();
119  DeleteJobIOWorker* worker();
120  void currentSourceStated(bool isDir, bool isLink);
121  void finishedStatPhase();
122  void deleteNextFile();
123  void deleteNextDir();
124  void restoreDirWatch() const;
125  void slotReport();
126  void slotStart();
127  void slotEntries(KIO::Job *, const KIO::UDSEntryList &list);
128 
129 
131  void rmFileResult(bool result, bool isLink);
133  void rmdirResult(bool result);
134  void deleteFileUsingJob(const QUrl& url, bool isLink);
135  void deleteDirUsingJob(const QUrl& url);
136 
137  ~DeleteJobPrivate();
138 
139  Q_DECLARE_PUBLIC(DeleteJob)
140 
141  static inline DeleteJob *newJob(const QList<QUrl> &src, JobFlags flags)
142  {
143  DeleteJob *job = new DeleteJob(*new DeleteJobPrivate(src));
145  if (!(flags & HideProgressInfo)) {
147  }
148  if (!(flags & NoPrivilegeExecution)) {
149  job->d_func()->m_privilegeExecutionEnabled = true;
150  job->d_func()->m_operationType = Delete;
151  }
152  return job;
153  }
154 };
155 
156 } // namespace KIO
157 
158 using namespace KIO;
159 
160 DeleteJob::DeleteJob(DeleteJobPrivate &dd)
161  : Job(dd)
162 {
163  d_func()->m_reportTimer = new QTimer(this);
164  connect(d_func()->m_reportTimer, SIGNAL(timeout()), this, SLOT(slotReport()));
165  //this will update the report dialog with 5 Hz, I think this is fast enough, aleXXX
166  d_func()->m_reportTimer->start(200);
167 
168  QTimer::singleShot(0, this, SLOT(slotStart()));
169 }
170 
171 DeleteJob::~DeleteJob()
172 {
173 }
174 
175 DeleteJobPrivate::~DeleteJobPrivate()
176 {
177  if (m_thread) {
178  m_thread->quit();
179  m_thread->wait();
180  }
181 }
182 
184 {
185  return d_func()->m_srcList;
186 }
187 
188 void DeleteJobPrivate::slotStart()
189 {
190  statNextSrc();
191 }
192 
193 DeleteJobIOWorker* DeleteJobPrivate::worker()
194 {
195  Q_Q(DeleteJob);
196 
197  if (!m_ioworker) {
198  m_thread = new QThread();
199 
200  m_ioworker = new DeleteJobIOWorker;
201  m_ioworker->moveToThread(m_thread);
202  QObject::connect(m_thread, &QThread::finished, m_ioworker, &QObject::deleteLater);
203  QObject::connect(m_ioworker, &DeleteJobIOWorker::rmfileResult, q, [=](bool result, bool isLink){
204  this->rmFileResult(result, isLink);
205  });
206  QObject::connect(m_ioworker, &DeleteJobIOWorker::rmddirResult, q, [=](bool result){
207  this->rmdirResult(result);
208  });
209  m_thread->start();
210  }
211 
212  return m_ioworker;
213 }
214 
215 void DeleteJobPrivate::slotReport()
216 {
217  Q_Q(DeleteJob);
218  emit q->deleting(q, m_currentURL);
219 
220  // TODO: maybe we could skip everything else when (flags & HideProgressInfo) ?
221  JobPrivate::emitDeleting(q, m_currentURL);
222 
223  switch (state) {
224  case DELETEJOB_STATE_STATING:
225  q->setTotalAmount(KJob::Files, files.count());
226  q->setTotalAmount(KJob::Directories, dirs.count());
227  break;
228  case DELETEJOB_STATE_DELETING_DIRS:
229  q->setProcessedAmount(KJob::Directories, m_processedDirs);
230  q->emitPercent(m_processedFiles + m_processedDirs, m_totalFilesDirs);
231  break;
232  case DELETEJOB_STATE_DELETING_FILES:
233  q->setProcessedAmount(KJob::Files, m_processedFiles);
234  q->emitPercent(m_processedFiles, m_totalFilesDirs);
235  break;
236  }
237 }
238 
239 void DeleteJobPrivate::slotEntries(KIO::Job *job, const UDSEntryList &list)
240 {
242  const UDSEntryList::ConstIterator end = list.end();
243  for (; it != end; ++it) {
244  const UDSEntry &entry = *it;
245  const QString displayName = entry.stringValue(KIO::UDSEntry::UDS_NAME);
246 
247  Q_ASSERT(!displayName.isEmpty());
248  if (displayName != QLatin1String("..") && displayName != QLatin1String(".")) {
249  QUrl url;
250  const QString urlStr = entry.stringValue(KIO::UDSEntry::UDS_URL);
251  if (!urlStr.isEmpty()) {
252  url = QUrl(urlStr);
253  } else {
254  url = static_cast<SimpleJob *>(job)->url(); // assumed to be a dir
255  url.setPath(concatPaths(url.path(), displayName));
256  }
257 
258  //qDebug() << displayName << "(" << url << ")";
259  if (entry.isLink()) {
260  symlinks.append(url);
261  } else if (entry.isDir()) {
262  dirs.append(url);
263  } else {
264  files.append(url);
265  }
266  }
267  }
268 }
269 
270 void DeleteJobPrivate::statNextSrc()
271 {
272  Q_Q(DeleteJob);
273  //qDebug();
274  if (m_currentStat != m_srcList.end()) {
275  m_currentURL = (*m_currentStat);
276 
277  // if the file system doesn't support deleting, we do not even stat
278  if (!KProtocolManager::supportsDeleting(m_currentURL)) {
279  QPointer<DeleteJob> that = q;
280  ++m_currentStat;
281  emit q->warning(q, buildErrorString(ERR_CANNOT_DELETE, m_currentURL.toDisplayString()));
282  if (that) {
283  statNextSrc();
284  }
285  return;
286  }
287  // Stat it
288  state = DELETEJOB_STATE_STATING;
289 
290  // Fast path for KFileItems in directory views
291  while (m_currentStat != m_srcList.end()) {
292  m_currentURL = (*m_currentStat);
293  const KFileItem cachedItem = KCoreDirLister::cachedItemForUrl(m_currentURL);
294  if (cachedItem.isNull()) {
295  break;
296  }
297  //qDebug() << "Found cached info about" << m_currentURL << "isDir=" << cachedItem.isDir() << "isLink=" << cachedItem.isLink();
298  currentSourceStated(cachedItem.isDir(), cachedItem.isLink());
299  ++m_currentStat;
300  }
301 
302  // Hook for unit test to disable the fast path.
303  if (!kio_resolve_local_urls) {
304 
305  // Fast path for local files
306  // (using a loop, instead of a huge recursion)
307  while (m_currentStat != m_srcList.end() && (*m_currentStat).isLocalFile()) {
308  m_currentURL = (*m_currentStat);
309  QFileInfo fileInfo(m_currentURL.toLocalFile());
310  currentSourceStated(fileInfo.isDir(), fileInfo.isSymLink());
311  ++m_currentStat;
312  }
313  }
314  if (m_currentStat == m_srcList.end()) {
315  // Done, jump to the last else of this method
316  statNextSrc();
317  } else {
318  KIO::SimpleJob *job = KIO::statDetails(m_currentURL, StatJob::SourceSide, KIO::StatBasic, KIO::HideProgressInfo);
320  //qDebug() << "stat'ing" << m_currentURL;
321  q->addSubjob(job);
322  }
323  } else {
324  if (!q->hasSubjobs()) { // don't go there yet if we're still listing some subdirs
325  finishedStatPhase();
326  }
327  }
328 }
329 
330 void DeleteJobPrivate::finishedStatPhase()
331 {
332  m_totalFilesDirs = files.count() + symlinks.count() + dirs.count();
333  slotReport();
334  // Now we know which dirs hold the files we're going to delete.
335  // To speed things up and prevent double-notification, we disable KDirWatch
336  // on those dirs temporarily (using KDirWatch::self, that's the instance
337  // used by e.g. kdirlister).
338  const QSet<QString>::const_iterator itEnd = m_parentDirs.constEnd();
339  for (QSet<QString>::const_iterator it = m_parentDirs.constBegin(); it != itEnd; ++it) {
341  }
342  state = DELETEJOB_STATE_DELETING_FILES;
343  deleteNextFile();
344 }
345 
346 
347 void DeleteJobPrivate::rmFileResult(bool result, bool isLink)
348 {
349  if (result) {
350  m_processedFiles++;
351 
352  if (isLink) {
353  symlinks.removeFirst();
354  } else {
355  files.removeFirst();
356  }
357 
358  deleteNextFile();
359  } else {
360  // fallback if QFile::remove() failed (we'll use the job's error handling in that case)
361  deleteFileUsingJob(m_currentURL, isLink);
362  }
363 }
364 
365 void DeleteJobPrivate::deleteFileUsingJob(const QUrl &url, bool isLink)
366 {
367  Q_Q(DeleteJob);
368 
369  SimpleJob *job;
370  if (isHttpProtocol(url.scheme())) {
372  } else {
374  job->setParentJob(q);
375  }
377 
378  if (isLink) {
379  symlinks.removeFirst();
380  } else {
381  files.removeFirst();
382  }
383 
384  q->addSubjob(job);
385 }
386 
387 void DeleteJobPrivate::deleteNextFile()
388 {
389  //qDebug();
390 
391  // if there is something else to delete
392  // the loop is run using callbacks slotResult and rmFileResult
393  if (!files.isEmpty() || !symlinks.isEmpty()) {
394 
395  // Take first file to delete out of list
396  QList<QUrl>::iterator it = files.begin();
397  const bool isLink = (it == files.end()); // No more files
398  if (isLink) {
399  it = symlinks.begin(); // Pick up a symlink to delete
400  }
401  m_currentURL = (*it);
402 
403  // If local file, try do it directly
404  if (m_currentURL.isLocalFile()) {
405  // separate thread will do the work
407  Q_ARG(const QUrl&, m_currentURL),
408  Q_ARG(bool, isLink));
409  } else {
410  // if remote, use a job
411  deleteFileUsingJob(m_currentURL, isLink);
412  }
413  return;
414  }
415 
416  state = DELETEJOB_STATE_DELETING_DIRS;
417  deleteNextDir();
418 }
419 
420 void DeleteJobPrivate::rmdirResult(bool result)
421 {
422  if (result) {
423  m_processedDirs++;
424  dirs.removeLast();
425  deleteNextDir();
426  } else {
427  // fallback
428  deleteDirUsingJob(m_currentURL);
429  }
430 }
431 
432 void DeleteJobPrivate::deleteDirUsingJob(const QUrl &url)
433 {
434  Q_Q(DeleteJob);
435 
436  // Call rmdir - works for kioslaves with canDeleteRecursive too,
437  // CMD_DEL will trigger the recursive deletion in the slave.
438  SimpleJob *job = KIO::rmdir(url);
439  job->setParentJob(q);
440  job->addMetaData(QStringLiteral("recurse"), QStringLiteral("true"));
442  dirs.removeLast();
443  q->addSubjob(job);
444 }
445 
446 void DeleteJobPrivate::deleteNextDir()
447 {
448  Q_Q(DeleteJob);
449 
450  if (!dirs.isEmpty()) { // some dirs to delete ?
451 
452  // the loop is run using callbacks slotResult and rmdirResult
453  // Take first dir to delete out of list - last ones first !
454  QList<QUrl>::iterator it = --dirs.end();
455  m_currentURL = (*it);
456  // If local dir, try to rmdir it directly
457  if (m_currentURL.isLocalFile()) {
458  // delete it on separate worker thread
460  Q_ARG(const QUrl&, m_currentURL));
461  } else {
462  deleteDirUsingJob(m_currentURL);
463  }
464  return;
465  }
466 
467  // Re-enable watching on the dirs that held the deleted files
468  restoreDirWatch();
469 
470  // Finished - tell the world
471  if (!m_srcList.isEmpty()) {
472  //qDebug() << "KDirNotify'ing FilesRemoved" << m_srcList;
473  org::kde::KDirNotify::emitFilesRemoved(m_srcList);
474  }
475  if (m_reportTimer != nullptr) {
476  m_reportTimer->stop();
477  }
478  // display final numbers
479  q->setProcessedAmount(KJob::Directories, m_processedDirs);
480  q->setProcessedAmount(KJob::Files, m_processedFiles);
481  q->emitPercent(m_processedFiles + m_processedDirs, m_totalFilesDirs);
482 
483  q->emitResult();
484 }
485 
486 void DeleteJobPrivate::restoreDirWatch() const
487 {
488  const auto itEnd = m_parentDirs.constEnd();
489  for (auto it = m_parentDirs.constBegin(); it != itEnd; ++it) {
491  }
492 }
493 
494 void DeleteJobPrivate::currentSourceStated(bool isDir, bool isLink)
495 {
496  Q_Q(DeleteJob);
497  const QUrl url = (*m_currentStat);
498  if (isDir && !isLink) {
499  // Add toplevel dir in list of dirs
500  dirs.append(url);
501  if (url.isLocalFile()) {
502  // We are about to delete this dir, no need to watch it
503  // Maybe we should ask kdirwatch to remove all watches recursively?
504  // But then there would be no feedback (things disappearing progressively) during huge deletions
506  }
508  //qDebug() << url << "is a directory, let's list it";
510 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 69)
511  // TODO KF6: remove legacy details code path
512  newjob->addMetaData(QStringLiteral("details"), QStringLiteral("0"));
513 #endif
514  newjob->addMetaData(QStringLiteral("statDetails"), QString::number(KIO::StatBasic));
515  newjob->setUnrestricted(true); // No KIOSK restrictions
516  Scheduler::setJobPriority(newjob, 1);
517  QObject::connect(newjob, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
518  q, SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList)));
519  q->addSubjob(newjob);
520  // Note that this listing job will happen in parallel with other stat jobs.
521  }
522  } else {
523  if (isLink) {
524  //qDebug() << "Target is a symlink";
525  symlinks.append(url);
526  } else {
527  //qDebug() << "Target is a file";
528  files.append(url);
529  }
530  }
531  if (url.isLocalFile()) {
533  m_parentDirs.insert(parentDir);
534  }
535 }
536 
537 void DeleteJob::slotResult(KJob *job)
538 {
539  Q_D(DeleteJob);
540  switch (d->state) {
541  case DELETEJOB_STATE_STATING:
542  removeSubjob(job);
543 
544  // Was this a stat job or a list job? We do both in parallel.
545  if (StatJob *statJob = qobject_cast<StatJob *>(job)) {
546  // Was there an error while stating ?
547  if (job->error()) {
548  // Probably : doesn't exist
549  Job::slotResult(job); // will set the error and emit result(this)
550  d->restoreDirWatch();
551  return;
552  }
553 
554  const UDSEntry &entry = statJob->statResult();
555  // Is it a file or a dir ?
556  const bool isLink = entry.isLink();
557  const bool isDir = entry.isDir();
558  d->currentSourceStated(isDir, isLink);
559 
560  ++d->m_currentStat;
561  d->statNextSrc();
562  } else {
563  if (job->error()) {
564  // Try deleting nonetheless, it may be empty (and non-listable)
565  }
566  if (!hasSubjobs()) {
567  d->finishedStatPhase();
568  }
569  }
570  break;
571  case DELETEJOB_STATE_DELETING_FILES:
572  // Propagate the subjob's metadata (a SimpleJob) to the real DeleteJob
573  // FIXME: setMetaData() in the KIO API only allows access to outgoing metadata,
574  // but we need to alter the incoming one
575  d->m_incomingMetaData = dynamic_cast<KIO::Job *>(job)->metaData();
576 
577  if (job->error()) {
578  Job::slotResult(job); // will set the error and emit result(this)
579  d->restoreDirWatch();
580  return;
581  }
582  removeSubjob(job);
583  Q_ASSERT(!hasSubjobs());
584  d->m_processedFiles++;
585 
586  d->deleteNextFile();
587  break;
588  case DELETEJOB_STATE_DELETING_DIRS:
589  if (job->error()) {
590  Job::slotResult(job); // will set the error and emit result(this)
591  d->restoreDirWatch();
592  return;
593  }
594  removeSubjob(job);
595  Q_ASSERT(!hasSubjobs());
596  d->m_processedDirs++;
597  //emit processedAmount( this, KJob::Directories, d->m_processedDirs );
598  //emitPercent( d->m_processedFiles + d->m_processedDirs, d->m_totalFilesDirs );
599 
600  d->deleteNextDir();
601  break;
602  default:
603  Q_ASSERT(0);
604  }
605 }
606 
607 DeleteJob *KIO::del(const QUrl &src, JobFlags flags)
608 {
609  QList<QUrl> srcList;
610  srcList.append(src);
611  DeleteJob *job = DeleteJobPrivate::newJob(srcList, flags);
612  if (job->uiDelegateExtension()) {
613  job->uiDelegateExtension()->createClipboardUpdater(job, JobUiDelegateExtension::RemoveContent);
614  }
615  return job;
616 }
617 
619 {
620  DeleteJob *job = DeleteJobPrivate::newJob(src, flags);
621  if (job->uiDelegateExtension()) {
622  job->uiDelegateExtension()->createClipboardUpdater(job, JobUiDelegateExtension::RemoveContent);
623  }
624  return job;
625 }
626 
627 #include "deletejob.moc"
628 #include "moc_deletejob.cpp"
An alternative URL (If different from the caption).
Definition: udsentry.h:288
StripTrailingSlash
static KDirWatch * self()
QString toDisplayString(QUrl::FormattingOptions options) const const
bool isLink() const
Definition: udsentry.cpp:380
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
bool isDir() const
Returns true if this item represents a directory.
Definition: kfileitem.cpp:1241
void setUiDelegate(KJobUiDelegate *delegate)
const QUrl & url() const
Returns the SimpleJob&#39;s URL.
Definition: simplejob.cpp:82
Universal Directory Service.
Definition: udsentry.h:88
static void setJobPriority(SimpleJob *job, int priority)
Changes the priority of job; jobs of the same priority run in the order in which they were created...
Definition: scheduler.cpp:822
bool remove()
A namespace for KIO globals.
Definition: authinfo.h:34
A ListJob is allows you to get the get the content of a directory.
Definition: listjob.h:40
bool isNull() const
Return true if default-constructed.
Definition: kfileitem.cpp:1639
void removeFirst()
Hide progress information dialog, i.e.
Definition: job_base.h:287
bool isDir() const
Definition: udsentry.cpp:375
KIOCORE_EXPORT DeleteJob * del(const QUrl &src, JobFlags flags=DefaultFlags)
Delete a file or directory.
Definition: deletejob.cpp:607
A KIO job that retrieves information about a file or directory.
Definition: statjob.h:38
QSet::iterator insert(const T &value)
Q_SIGNALSQ_SIGNALS
const QList< QKeySequence > & begin()
bool hasSubjobs() const
void setUnrestricted(bool unrestricted)
Do not apply any KIOSK restrictions to this job.
Definition: listjob.cpp:268
bool stopDirScan(const QString &path)
void start(QThread::Priority priority)
void setPath(const QString &path, QUrl::ParsingMode mode)
QString number(int n, int base)
KIOCORE_EXPORT ListJob * listRecursive(const QUrl &url, JobFlags flags=DefaultFlags, bool includeHidden=true)
The same as the previous method, but recurses subdirectories.
Definition: listjob.cpp:263
int count(const T &value) const const
void append(const T &value)
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
static bool supportsDeleting(const QUrl &url)
Returns whether the protocol can delete files/objects.
Q_OBJECTQ_OBJECT
CaseInsensitive
A more complex Job to delete files and directories.
Definition: deletejob.h:46
Filename, access, type, size, linkdest.
Definition: global.h:325
bool isEmpty() const const
virtual void slotResult(KJob *job)
bool isEmpty() const const
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there&#39;s one, to create a delegate and return it...
static bool canDeleteRecursive(const QUrl &url)
Returns whether the protocol can recursively delete directories by itself.
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
KIOCORE_EXPORT QString buildErrorString(int errorCode, const QString &errorText)
Returns a translated error message for errorCode using the additional error information provided by e...
Definition: job_error.cpp:38
static KFileItem cachedItemForUrl(const QUrl &url)
Return the KFileItem for the given URL, if we listed it recently and it&#39;s still in the cache - which ...
QString stringValue(uint field) const
Definition: udsentry.cpp:365
QString path(QUrl::ComponentFormattingOptions options) const const
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
QSet::const_iterator constEnd() const const
MetaData metaData() const
Get meta data received from the slave.
Definition: job.cpp:227
void deleteLater()
KIOCORE_EXPORT TransferJob * http_delete(const QUrl &url, JobFlags flags=DefaultFlags)
HTTP DELETE.
QList< QUrl > urls() const
Returns the list of URLs.
Definition: deletejob.cpp:183
QString scheme() const const
QString toLocalFile() const const
QList::iterator end()
bool isLink() const
Returns true if this item represents a link in the UNIX sense of a link.
Definition: kfileitem.cpp:1525
void stop()
QSet::const_iterator constBegin() const const
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9)
void setParentJob(Job *parentJob)
Set the parent Job.
Definition: job.cpp:214
bool wait(QDeadlineTimer deadline)
QUrl adjusted(QUrl::FormattingOptions options) const const
Filename - as displayed in directory listings etc.
Definition: udsentry.h:261
The base class for all jobs.
Definition: job_base.h:57
bool removeSubjob(KJob *job) override
Mark a sub job as being done.
Definition: job.cpp:98
void removeLast()
KIOCORE_EXPORT SimpleJob * file_delete(const QUrl &src, JobFlags flags=DefaultFlags)
Delete a single file.
Definition: job.cpp:388
void result(KJob *job)
virtual void registerJob(KJob *job)
void quit()
Q_SLOTSQ_SLOTS
QueuedConnection
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool restartDirScan(const QString &path)
QList::iterator begin()
KIOCORE_EXPORT StatJob * statDetails(const QUrl &url, KIO::StatJob::StatSide side, KIO::StatDetails details=KIO::StatDefaultDetails, JobFlags flags=DefaultFlags)
Find all details for one file or directory.
Definition: statjob.cpp:237
A KFileItem is a generic class to handle a file, local or remote.
Definition: kfileitem.h:47
void finished()
KIOCORE_EXPORT SimpleJob * rmdir(const QUrl &url)
Removes a single directory.
Definition: simplejob.cpp:345
int error() const
KStandardDirs * dirs()
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 Sat Jul 11 2020 23:00:25 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.