File indexing completed on 2024-11-10 12:23:19

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2020 Ahmad Samir <a.samirh78@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "namefinderjob.h"
0009 
0010 #include "../utils_p.h"
0011 #include "kiocoredebug.h"
0012 #include <KFileUtils>
0013 #include <KIO/StatJob>
0014 
0015 #include <QUrl>
0016 
0017 class KIO::NameFinderJobPrivate
0018 {
0019 public:
0020     explicit NameFinderJobPrivate(const QUrl &baseUrl, const QString &name, NameFinderJob *qq)
0021         : m_baseUrl(baseUrl)
0022         , m_name(name)
0023         , m_statJob(nullptr)
0024         , q(qq)
0025     {
0026     }
0027 
0028     QUrl m_baseUrl;
0029     QString m_name;
0030     QUrl m_finalUrl;
0031     KIO::StatJob *m_statJob;
0032     bool m_firstStat = true;
0033 
0034     KIO::NameFinderJob *const q;
0035 
0036     void statUrl();
0037     void slotStatResult();
0038 };
0039 
0040 KIO::NameFinderJob::NameFinderJob(const QUrl &baseUrl, const QString &name, QObject *parent)
0041     : KCompositeJob(parent)
0042     , d(new NameFinderJobPrivate(baseUrl, name, this))
0043 {
0044 }
0045 
0046 KIO::NameFinderJob::~NameFinderJob()
0047 {
0048 }
0049 
0050 void KIO::NameFinderJob::start()
0051 {
0052     if (!d->m_baseUrl.isValid() || d->m_baseUrl.scheme().isEmpty()) {
0053         qCDebug(KIO_CORE) << "Malformed URL" << d->m_baseUrl;
0054         setError(KIO::ERR_MALFORMED_URL);
0055         emitResult();
0056         return;
0057     }
0058 
0059     d->statUrl();
0060 }
0061 
0062 void KIO::NameFinderJobPrivate::statUrl()
0063 {
0064     m_finalUrl = m_baseUrl;
0065     m_finalUrl.setPath(Utils::concatPaths(m_baseUrl.path(), m_name));
0066 
0067     m_statJob = KIO::statDetails(m_finalUrl,
0068                                  KIO::StatJob::DestinationSide,
0069                                  KIO::StatNoDetails, // Just checking if it exists
0070                                  KIO::HideProgressInfo);
0071 
0072     QObject::connect(m_statJob, &KJob::result, q, [this]() {
0073         slotStatResult();
0074     });
0075 }
0076 
0077 void KIO::NameFinderJobPrivate::slotStatResult()
0078 {
0079     // m_statJob will resolve the url to the most local one in the first run
0080     if (m_firstStat) {
0081         m_finalUrl = m_statJob->mostLocalUrl();
0082         m_firstStat = false;
0083     }
0084 
0085     // StripTrailingSlash so that fileName() doesn't return an empty string
0086     m_finalUrl = m_finalUrl.adjusted(QUrl::StripTrailingSlash);
0087     m_baseUrl = m_finalUrl.adjusted(QUrl::RemoveFilename);
0088     m_name = m_finalUrl.fileName();
0089 
0090     if (m_statJob->error()) { // Doesn't exist, we're done
0091         q->emitResult();
0092     } else { // Exists, create a new name, then stat again
0093         m_name = KFileUtils::makeSuggestedName(m_name);
0094         statUrl();
0095     }
0096 }
0097 
0098 QUrl KIO::NameFinderJob::finalUrl() const
0099 {
0100     return d->m_finalUrl;
0101 }
0102 
0103 QUrl KIO::NameFinderJob::baseUrl() const
0104 {
0105     return d->m_baseUrl;
0106 }
0107 
0108 QString KIO::NameFinderJob::finalName() const
0109 {
0110     return d->m_name;
0111 }
0112 
0113 #include "moc_namefinderjob.cpp"