File indexing completed on 2024-05-12 16:21:31
0001 /** 0002 * SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "storagemovejob.h" 0008 #include "storagemovejoblogging.h" 0009 0010 #include <QDir> 0011 #include <QFile> 0012 #include <QTimer> 0013 0014 #include <KLocalizedString> 0015 0016 0017 StorageMoveJob::StorageMoveJob(const QString &from, const QString &to, QStringList &list, QObject *parent) 0018 : KJob(parent) 0019 , m_from(from) 0020 , m_to(to) 0021 , m_list(list) 0022 { 0023 } 0024 0025 void StorageMoveJob::start() 0026 { 0027 QTimer::singleShot(0, this, &StorageMoveJob::moveFiles); 0028 } 0029 0030 void StorageMoveJob::moveFiles() 0031 { 0032 qCDebug(kastsStorageMoveJob) << "Begin moving" << m_list << "from" << m_from << "to" << m_to; 0033 0034 bool success = true; 0035 0036 QStringList fileList; // this list will contain all files that need to be moved 0037 0038 for (QString item : m_list) { 0039 // make a list of files to be moved; path is relative to m_from 0040 if (QFileInfo(m_from + QStringLiteral("/") + item).isDir()) { 0041 // this item is a dir; now add all files in that subdir 0042 QStringList tempList = QDir(m_from + QStringLiteral("/") + item + QStringLiteral("/")).entryList(QDir::Files); 0043 for (QString file : tempList) { 0044 fileList += item + QStringLiteral("/") + file; 0045 } 0046 0047 // if the item is a subdir, let's try to create it in the new location 0048 // if this fails, then the destination is not writeable, and the move 0049 // should be aborted 0050 success = QFileInfo().absoluteDir().mkpath(m_to + QStringLiteral("/") + item) && success; 0051 } else if (QFileInfo(m_from + QStringLiteral("/") + item).isFile()) { 0052 // this item is a file; simply add it to the list 0053 fileList += item; 0054 } 0055 } 0056 0057 if (!success) { 0058 setError(2); 0059 setErrorText(i18n("Destination path not writable")); 0060 emitResult(); 0061 return; 0062 } 0063 0064 setTotalAmount(Files, fileList.size()); 0065 setProcessedAmount(Files, 0); 0066 0067 for (int i = 0; i < fileList.size(); i++) { 0068 // First check if we need to abort this job 0069 if (m_abort) { 0070 // Remove files that were already copied 0071 for (int j = 0; j < i; j++) { 0072 qCDebug(kastsStorageMoveJob) << "Removing file" << QDir(m_to).absoluteFilePath(fileList[j]); 0073 QFile(QDir(m_to).absoluteFilePath(fileList[j])).remove(); 0074 } 0075 setError(1); 0076 setErrorText(i18n("Operation aborted by user")); 0077 emitResult(); 0078 return; 0079 } 0080 0081 // Now we can start copying 0082 QString fromPath = QDir(m_from).absoluteFilePath(fileList[i]); 0083 QString toPath = QDir(m_to).absoluteFilePath(fileList[i]); 0084 if (QFileInfo::exists(toPath) && (QFileInfo(fromPath).size() == QFileInfo(toPath).size())) { 0085 qCDebug(kastsStorageMoveJob) << "Identical file already exists in destination; skipping" << toPath; 0086 } else { 0087 qCDebug(kastsStorageMoveJob) << "Copy" << fromPath << "to" << toPath; 0088 success = QFile(fromPath).copy(toPath) && success; 0089 } 0090 if (!success) 0091 break; 0092 setProcessedAmount(Files, i + 1); 0093 } 0094 0095 if (m_abort) { 0096 setError(1); 0097 setErrorText(i18n("Operation aborted by user")); 0098 } else if (success) { 0099 // now it's safe to delete all the files from the original location 0100 for (QString file : fileList) { 0101 QFile(QDir(m_from).absoluteFilePath(file)).remove(); 0102 qCDebug(kastsStorageMoveJob) << "Removing file" << QDir(m_from).absoluteFilePath(file); 0103 } 0104 0105 // delete the directories as well 0106 for (const QString &item : m_list) { 0107 if (!item.isEmpty() && QFileInfo(m_from + QStringLiteral("/") + item).isDir()) { 0108 QDir(m_from).rmdir(item); 0109 } 0110 } 0111 } else { 0112 setError(2); 0113 setErrorText(i18n("An error occurred while copying data")); 0114 } 0115 0116 emitResult(); 0117 } 0118 0119 bool StorageMoveJob::doKill() 0120 { 0121 m_abort = true; 0122 return true; 0123 }