KIO

mkpathjob.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
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
17using namespace KIO;
18
19class KIO::MkpathJobPrivate : public KIO::JobPrivate
20{
21public:
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
99MkpathJob::MkpathJob(MkpathJobPrivate &dd)
100 : Job(dd)
101{
102 Q_D(MkpathJob);
103 QTimer::singleShot(0, this, [d]() {
104 d->slotStart();
105 });
106}
107
108MkpathJob::~MkpathJob()
109{
110}
111
112void 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
131void 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
148MkpathJob *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 slotResult(KJob *job)
The base class for all jobs.
void setParentJob(Job *parentJob)
Set the parent Job.
Definition job.cpp:192
bool removeSubjob(KJob *job) override
Mark a sub job as being done.
Definition job.cpp:80
A KIO job that creates a directory, after creating all parent directories necessary for this.
void directoryCreated(const QUrl &url)
Signals that a directory was created.
virtual void registerJob(KJob *job)
int error() const
void emitPercent(qulonglong processedAmount, qulonglong totalAmount)
void setUiDelegate(KJobUiDelegate *delegate)
A namespace for KIO globals.
KIOCORE_EXPORT MkdirJob * mkdir(const QUrl &url, int permissions=-1)
Creates a single directory.
Definition mkdirjob.cpp:110
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there's one, to create a delegate and return it.
@ HideProgressInfo
Hide progress information dialog, i.e. don't show a GUI.
Definition job_base.h:251
@ NoPrivilegeExecution
When set, notifies the worker that application/job does not want privilege execution.
Definition job_base.h:276
KIOCORE_EXPORT MkpathJob * mkpath(const QUrl &url, const QUrl &baseUrl=QUrl(), JobFlags flags=DefaultFlags)
Creates a directory, creating parent directories as needed.
KIOCORE_EXPORT KJobTrackerInterface * getJobTracker()
Returns the job tracker to be used by all KIO jobs (in which HideProgressInfo is not set)
QString path(const QString &relativePath)
const_reference at(qsizetype i) const const
iterator begin()
const_iterator constBegin() const const
const_iterator constEnd() const const
qsizetype count() const const
iterator erase(const_iterator begin, const_iterator end)
Q_EMITQ_EMIT
SkipEmptyParts
bool isLocalFile() const const
QString path(ComponentFormattingOptions options) const const
void setPath(const QString &path, ParsingMode mode)
QString toLocalFile() const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:58:45 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.