KIO

mkpathjob.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 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include "mkpathjob.h"
10 #include "../utils_p.h"
11 #include "job_p.h"
12 #include "mkdirjob.h"
13 
14 #include <QFileInfo>
15 #include <QTimer>
16 
17 using namespace KIO;
18 
19 class KIO::MkpathJobPrivate : public KIO::JobPrivate
20 {
21 public:
22  MkpathJobPrivate(const QUrl &url, const QUrl &baseUrl, JobFlags flags)
23  : JobPrivate()
24  , m_url(url)
25  , m_pathComponents(url.path().split(QLatin1Char('/'), Qt::SkipEmptyParts))
26  , m_pathIterator()
27  , m_flags(flags)
28  {
29  const QStringList basePathComponents = baseUrl.path().split(QLatin1Char('/'), Qt::SkipEmptyParts);
30 
31 #ifdef Q_OS_WIN
32  const QString startPath;
33 #else
34  const QString startPath = QLatin1String("/");
35 #endif
36  m_url.setPath(startPath);
37  int i = 0;
38  for (; i < basePathComponents.count() && i < m_pathComponents.count(); ++i) {
39  const QString pathComponent = m_pathComponents.at(i);
40  if (pathComponent == basePathComponents.at(i)) {
41  m_url.setPath(Utils::concatPaths(m_url.path(), pathComponent));
42  } else {
43  break;
44  }
45  }
46  if (i > 0) {
47  m_pathComponents.erase(m_pathComponents.begin(), m_pathComponents.begin() + i);
48  }
49 
50  // fast path for local files using QFileInfo::isDir
51  if (m_url.isLocalFile()) {
52  i = 0;
53  for (; i < m_pathComponents.count(); ++i) {
54  const QString localFile = m_url.toLocalFile();
55  QString testDir;
56  if (localFile == startPath) {
57  testDir = localFile + m_pathComponents.at(i);
58  } else {
59  testDir = localFile + QLatin1Char('/') + m_pathComponents.at(i);
60  }
61  if (QFileInfo(testDir).isDir()) {
62  m_url.setPath(testDir);
63  } else {
64  break;
65  }
66  }
67  if (i > 0) {
68  m_pathComponents.erase(m_pathComponents.begin(), m_pathComponents.begin() + i);
69  }
70  }
71 
72  m_pathIterator = m_pathComponents.constBegin();
73  }
74 
75  QUrl m_url;
76  QUrl m_baseUrl;
77  QStringList m_pathComponents;
78  QStringList::const_iterator m_pathIterator;
79  const JobFlags m_flags;
80  Q_DECLARE_PUBLIC(MkpathJob)
81 
82  void slotStart();
83 
84  static inline MkpathJob *newJob(const QUrl &url, const QUrl &baseUrl, JobFlags flags)
85  {
86  MkpathJob *job = new MkpathJob(*new MkpathJobPrivate(url, baseUrl, flags));
88  if (!(flags & HideProgressInfo)) {
90  }
91  if (!(flags & NoPrivilegeExecution)) {
92  job->d_func()->m_privilegeExecutionEnabled = true;
93  job->d_func()->m_operationType = MkDir;
94  }
95  return job;
96  }
97 };
98 
99 MkpathJob::MkpathJob(MkpathJobPrivate &dd)
100  : Job(dd)
101 {
102  Q_D(MkpathJob);
103  QTimer::singleShot(0, this, [d]() {
104  d->slotStart();
105  });
106 }
107 
108 MkpathJob::~MkpathJob()
109 {
110 }
111 
112 void MkpathJobPrivate::slotStart()
113 {
114  Q_Q(MkpathJob);
115 
116  if (m_pathIterator == m_pathComponents.constBegin()) { // first time: emit total
117  q->setTotalAmount(KJob::Directories, m_pathComponents.count());
118  }
119 
120  if (m_pathIterator != m_pathComponents.constEnd()) {
121  m_url.setPath(Utils::concatPaths(m_url.path(), *m_pathIterator));
122  KIO::Job *job = KIO::mkdir(m_url);
123  job->setParentJob(q);
124  q->addSubjob(job);
125  q->setProcessedAmount(KJob::Directories, q->processedAmount(KJob::Directories) + 1);
126  } else {
127  q->emitResult();
128  }
129 }
130 
131 void MkpathJob::slotResult(KJob *job)
132 {
133  Q_D(MkpathJob);
134  if (job->error() && job->error() != KIO::ERR_DIR_ALREADY_EXIST) {
135  KIO::Job::slotResult(job); // will set the error and emit result(this)
136  return;
137  }
138  removeSubjob(job);
139 
140  Q_EMIT directoryCreated(d->m_url);
141 
142  // Move on to next one
143  ++d->m_pathIterator;
144  emitPercent(d->m_pathIterator - d->m_pathComponents.constBegin(), d->m_pathComponents.count());
145  d->slotStart();
146 }
147 
148 MkpathJob *KIO::mkpath(const QUrl &url, const QUrl &baseUrl, KIO::JobFlags flags)
149 {
150  return MkpathJobPrivate::newJob(url, baseUrl, flags);
151 }
152 
153 #include "moc_mkpathjob.cpp"
virtual void registerJob(KJob *job)
Q_EMITQ_EMIT
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
int count(const T &value) const const
@ NoPrivilegeExecution
When set, notifies the worker that application/job does not want privilege execution.
Definition: job_base.h:300
void emitPercent(qulonglong processedAmount, qulonglong totalAmount)
QList::const_iterator constBegin() const const
void setParentJob(Job *parentJob)
Set the parent Job.
Definition: job.cpp:199
KIOCORE_EXPORT KJobTrackerInterface * getJobTracker()
Returns the job tracker to be used by all KIO jobs (in which HideProgressInfo is not set)
Definition: jobtracker.cpp:14
SkipEmptyParts
const T & at(int i) const const
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there's one, to create a delegate and return it.
KIOCORE_EXPORT MkpathJob * mkpath(const QUrl &url, const QUrl &baseUrl=QUrl(), JobFlags flags=DefaultFlags)
Creates a directory, creating parent directories as needed.
Definition: mkpathjob.cpp:148
QList::const_iterator constEnd() const const
QString path(QUrl::ComponentFormattingOptions options) const const
QString path(const QString &relativePath)
void setPath(const QString &path, QUrl::ParsingMode mode)
void setUiDelegate(KJobUiDelegate *delegate)
A namespace for KIO globals.
const QChar at(int position) const const
virtual void slotResult(KJob *job)
@ HideProgressInfo
Hide progress information dialog, i.e. don't show a GUI.
Definition: job_base.h:275
void directoryCreated(const QUrl &url)
Signals that a directory was created.
int error() const
bool removeSubjob(KJob *job) override
Mark a sub job as being done.
Definition: job.cpp:87
Q_D(Todo)
KIOCORE_EXPORT MkdirJob * mkdir(const QUrl &url, int permissions=-1)
Creates a single directory.
Definition: mkdirjob.cpp:110
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Dec 1 2023 03:53:03 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.