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