X-Git-Url: https://www.flypig.org.uk/git/?p=openvpnui.git;a=blobdiff_plain;f=src%2Ffilebrowse%2Ffileworker.cpp;fp=src%2Ffilebrowse%2Ffileworker.cpp;h=46378628aa64b092bca5d7e6d030c3390efcce00;hp=0000000000000000000000000000000000000000;hb=e24363e314aca32e7bee952f02f517a04a8dc5f2;hpb=ee3968ffa08d4e0fcbad87765efa3aeb32ff0554 diff --git a/src/filebrowse/fileworker.cpp b/src/filebrowse/fileworker.cpp new file mode 100644 index 0000000..4637862 --- /dev/null +++ b/src/filebrowse/fileworker.cpp @@ -0,0 +1,266 @@ +#include "fileworker.h" +#include +#include "globals.h" + +FileWorker::FileWorker(QObject *parent) : + QThread(parent), + m_mode(DeleteMode), + m_cancelled(KeepRunning), + m_progress(0) +{ +} + +FileWorker::~FileWorker() +{ +} + +void FileWorker::startDeleteFiles(QStringList filenames) +{ + if (isRunning()) { + emit errorOccurred(tr("File operation already in progress"), ""); + return; + } + + // basic validity check + foreach (QString filename, filenames) { + if (filename.isEmpty()) { + emit errorOccurred(tr("Empty filename"), ""); + return; + } + } + + m_mode = DeleteMode; + m_filenames = filenames; + m_cancelled.storeRelease(KeepRunning); + start(); +} + +void FileWorker::startCopyFiles(QStringList filenames, QString destDirectory) +{ + if (isRunning()) { + emit errorOccurred(tr("File operation already in progress"), ""); + return; + } + + // basic validity check + foreach (QString filename, filenames) { + if (filename.isEmpty()) { + emit errorOccurred(tr("Empty filename"), ""); + return; + } + } + + m_mode = CopyMode; + m_filenames = filenames; + m_destDirectory = destDirectory; + m_cancelled.storeRelease(KeepRunning); + start(); +} + +void FileWorker::startMoveFiles(QStringList filenames, QString destDirectory) +{ + if (isRunning()) { + emit errorOccurred(tr("File operation already in progress"), ""); + return; + } + + // basic validity check + foreach (QString filename, filenames) { + if (filename.isEmpty()) { + emit errorOccurred(tr("Empty filename"), ""); + return; + } + } + + m_mode = MoveMode; + m_filenames = filenames; + m_destDirectory = destDirectory; + m_cancelled.storeRelease(KeepRunning); + start(); +} + +void FileWorker::cancel() +{ + m_cancelled.storeRelease(Cancelled); +} + +void FileWorker::run() Q_DECL_OVERRIDE +{ + switch (m_mode) { + case DeleteMode: + deleteFiles(); + break; + + case MoveMode: + case CopyMode: + copyOrMoveFiles(); + break; + } +} + +QString FileWorker::deleteFile(QString filename) +{ + QFileInfo info(filename); + if (!info.exists()) + return tr("File not found"); + + if (info.isDir()) { + // this should be custom function to get better error reporting + bool ok = QDir(info.absoluteFilePath()).removeRecursively(); + if (!ok) + return tr("Folder delete failed"); + + } else { + QFile file(info.absoluteFilePath()); + bool ok = file.remove(); + if (!ok) + return file.errorString(); + } + return QString(); +} + +void FileWorker::deleteFiles() +{ + int fileIndex = 0; + int fileCount = m_filenames.count(); + + foreach (QString filename, m_filenames) { + m_progress = 100 * fileIndex / fileCount; + emit progressChanged(m_progress, filename); + + // stop if cancelled + if (m_cancelled.loadAcquire() == Cancelled) { + emit errorOccurred(tr("Cancelled"), filename); + return; + } + + // delete file and stop if errors + QString errMsg = deleteFile(filename); + if (!errMsg.isEmpty()) { + emit errorOccurred(errMsg, filename); + return; + } + emit fileDeleted(filename); + + fileIndex++; + } + + m_progress = 100; + emit progressChanged(m_progress, ""); + emit done(); +} + +void FileWorker::copyOrMoveFiles() +{ + int fileIndex = 0; + int fileCount = m_filenames.count(); + + QDir dest(m_destDirectory); + foreach (QString filename, m_filenames) { + m_progress = 100 * fileIndex / fileCount; + emit progressChanged(m_progress, filename); + + // stop if cancelled + if (m_cancelled.loadAcquire() == Cancelled) { + emit errorOccurred(tr("Cancelled"), filename); + return; + } + + // check destination does not exists, otherwise copy/move fails + QFileInfo fileInfo(filename); + QString newname = dest.absoluteFilePath(fileInfo.fileName()); + + // move or copy and stop if errors + QFile file(filename); + if (m_mode == MoveMode) { + if (!file.rename(newname)) { + emit errorOccurred(file.errorString(), filename); + return; + } + } else { + if (fileInfo.isDir()) { + QString errmsg = copyDirRecursively(filename, newname); + if (!errmsg.isEmpty()) { + emit errorOccurred(errmsg, filename); + return; + } + } else { + QString errmsg = copyOverwrite(filename, newname); + if (!errmsg.isEmpty()) { + emit errorOccurred(errmsg, filename); + return; + } + } + } + + fileIndex++; + } + + m_progress = 100; + emit progressChanged(m_progress, ""); + emit done(); +} + +QString FileWorker::copyDirRecursively(QString srcDirectory, QString destDirectory) +{ + QDir srcDir(srcDirectory); + if (!srcDir.exists()) + return tr("Source folder doesn't exist"); + + QDir destDir(destDirectory); + if (!destDir.exists()) { + QDir d(destDir); + d.cdUp(); + if (!d.mkdir(destDir.dirName())) + return tr("Can't create target folder %1").arg(destDirectory); + } + + // copy files + QStringList names = srcDir.entryList(QDir::Files); + for (int i = 0 ; i < names.count() ; ++i) { + // stop if cancelled + if (m_cancelled.loadAcquire() == Cancelled) + return tr("Cancelled"); + + QString filename = names.at(i); + emit progressChanged(m_progress, filename); + QString spath = srcDir.absoluteFilePath(filename); + QString dpath = destDir.absoluteFilePath(filename); + QString errmsg = copyOverwrite(spath, dpath); + if (!errmsg.isEmpty()) + return errmsg; + } + + // copy dirs + names = srcDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs); + for (int i = 0 ; i < names.count() ; ++i) { + // stop if cancelled + if (m_cancelled.loadAcquire() == Cancelled) + return tr("Cancelled"); + + QString filename = names.at(i); + emit progressChanged(m_progress, filename); + QString spath = srcDir.absoluteFilePath(filename); + QString dpath = destDir.absoluteFilePath(filename); + QString errmsg = copyDirRecursively(spath, dpath); + if (!errmsg.isEmpty()) + return errmsg; + } + + return QString(); +} + +QString FileWorker::copyOverwrite(QString src, QString dest) +{ + QFile dfile(dest); + if (dfile.exists()) { + if (!dfile.remove()) + return dfile.errorString(); + } + + QFile sfile(src); + if (!sfile.copy(dest)) + return sfile.errorString(); + + return QString(); +}