Warning, file /utilities/krusader/app/Synchronizer/synchronizerdirlist.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2006 Csaba Karai <krusader@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2006-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "synchronizerdirlist.h"
0009 
0010 #ifdef HAVE_POSIX_ACL
0011 #include <sys/acl.h>
0012 #ifdef HAVE_NON_POSIX_ACL_EXTENSIONS
0013 #include <acl/libacl.h>
0014 #endif
0015 #endif
0016 
0017 #include <qplatformdefs.h>
0018 // QtCore
0019 #include <QDir>
0020 // QtWidgets
0021 #include <QApplication>
0022 
0023 #include <KI18n/KLocalizedString>
0024 #include <KIO/JobUiDelegate>
0025 #include <KIOCore/KFileItem>
0026 #include <KWidgetsAddons/KMessageBox>
0027 
0028 #include "../FileSystem/filesystem.h"
0029 #include "../FileSystem/krpermhandler.h"
0030 #include "../krservices.h"
0031 
0032 SynchronizerDirList::SynchronizerDirList(QWidget *w, bool hidden)
0033     : fileIterator(nullptr)
0034     , parentWidget(w)
0035     , busy(false)
0036     , result(false)
0037     , ignoreHidden(hidden)
0038     , currentUrl()
0039 {
0040 }
0041 
0042 SynchronizerDirList::~SynchronizerDirList()
0043 {
0044     if (fileIterator)
0045         delete fileIterator;
0046 
0047     QHashIterator<QString, FileItem *> lit(*this);
0048     while (lit.hasNext())
0049         delete lit.next().value();
0050 }
0051 
0052 FileItem *SynchronizerDirList::search(const QString &name, bool ignoreCase)
0053 {
0054     if (!ignoreCase) {
0055         if (!contains(name))
0056             return nullptr;
0057         return (*this)[name];
0058     }
0059 
0060     QHashIterator<QString, FileItem *> iter(*this);
0061     iter.toFront();
0062 
0063     QString file = name.toLower();
0064 
0065     while (iter.hasNext()) {
0066         FileItem *item = iter.next().value();
0067         if (file == item->getName().toLower())
0068             return item;
0069     }
0070     return nullptr;
0071 }
0072 
0073 FileItem *SynchronizerDirList::first()
0074 {
0075     if (fileIterator == nullptr)
0076         fileIterator = new QHashIterator<QString, FileItem *>(*this);
0077 
0078     fileIterator->toFront();
0079     if (fileIterator->hasNext())
0080         return fileIterator->next().value();
0081     return nullptr;
0082 }
0083 
0084 FileItem *SynchronizerDirList::next()
0085 {
0086     if (fileIterator == nullptr)
0087         fileIterator = new QHashIterator<QString, FileItem *>(*this);
0088 
0089     if (fileIterator->hasNext())
0090         return fileIterator->next().value();
0091     return nullptr;
0092 }
0093 
0094 bool SynchronizerDirList::load(const QString &urlIn, bool wait)
0095 {
0096     if (busy)
0097         return false;
0098 
0099     currentUrl = urlIn;
0100     const QUrl url = QUrl::fromUserInput(urlIn, QString(), QUrl::AssumeLocalFile);
0101 
0102     QHashIterator<QString, FileItem *> lit(*this);
0103     while (lit.hasNext())
0104         delete lit.next().value();
0105     clear();
0106     if (fileIterator) {
0107         delete fileIterator;
0108         fileIterator = nullptr;
0109     }
0110 
0111     if (url.isLocalFile()) {
0112         const QString dir = FileSystem::ensureTrailingSlash(url).path();
0113 
0114         QT_DIR *qdir = QT_OPENDIR(dir.toLocal8Bit());
0115         if (!qdir) {
0116             KMessageBox::error(parentWidget, i18n("Cannot open the folder %1.", dir), i18n("Error"));
0117             emit finished(result = false);
0118             return false;
0119         }
0120 
0121         QT_DIRENT *dirEnt;
0122 
0123         while ((dirEnt = QT_READDIR(qdir)) != nullptr) {
0124             const QString name = QString::fromLocal8Bit(dirEnt->d_name);
0125 
0126             if (name == "." || name == "..")
0127                 continue;
0128             if (ignoreHidden && name.startsWith('.'))
0129                 continue;
0130 
0131             FileItem *item = FileSystem::createLocalFileItem(name, dir);
0132 
0133             insert(name, item);
0134         }
0135 
0136         QT_CLOSEDIR(qdir);
0137         emit finished(result = true);
0138         return true;
0139     } else {
0140         KIO::ListJob *job = KIO::listDir(KrServices::escapeFileUrl(url), KIO::HideProgressInfo, true);
0141         connect(job, &KIO::ListJob::entries, this, &SynchronizerDirList::slotEntries);
0142         connect(job, &KIO::ListJob::result, this, &SynchronizerDirList::slotListResult);
0143         busy = true;
0144 
0145         if (!wait)
0146             return true;
0147 
0148         while (busy)
0149             qApp->processEvents();
0150         return result;
0151     }
0152 }
0153 
0154 void SynchronizerDirList::slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries)
0155 {
0156     auto *listJob = dynamic_cast<KIO::ListJob *>(job);
0157     for (const KIO::UDSEntry &entry : entries) {
0158         FileItem *item = FileSystem::createFileItemFromKIO(entry, listJob->url());
0159         if (item) {
0160             insert(item->getName(), item);
0161         }
0162     }
0163 }
0164 
0165 void SynchronizerDirList::slotListResult(KJob *job)
0166 {
0167     busy = false;
0168     if (job && job->error()) {
0169         job->uiDelegate()->showErrorMessage();
0170         emit finished(result = false);
0171         return;
0172     }
0173     emit finished(result = true);
0174 }