From 3958fa914c8a524ed4b6a5b035b794e12708fa1d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 1 Mar 2018 22:42:01 +0000 Subject: Import ultracopier_1.4.0.4.orig.tar.xz [dgit import orig ultracopier_1.4.0.4.orig.tar.xz] --- plugins/CopyEngine/Ultracopier/AvancedQFile.cpp | 208 ++ plugins/CopyEngine/Ultracopier/AvancedQFile.h | 45 + plugins/CopyEngine/Ultracopier/CompilerInfo.h | 1 + .../Ultracopier/CopyEngine-collision-and-error.cpp | 568 +++++ plugins/CopyEngine/Ultracopier/CopyEngine.cpp | 1253 ++++++++++ plugins/CopyEngine/Ultracopier/CopyEngine.h | 382 ++++ plugins/CopyEngine/Ultracopier/CopyEngine.pro | 106 + .../CopyEngine/Ultracopier/CopyEngineFactory.cpp | 700 ++++++ plugins/CopyEngine/Ultracopier/CopyEngineFactory.h | 133 ++ plugins/CopyEngine/Ultracopier/DebugDialog.cpp | 54 + plugins/CopyEngine/Ultracopier/DebugDialog.h | 39 + plugins/CopyEngine/Ultracopier/DebugEngineMacro.h | 28 + plugins/CopyEngine/Ultracopier/DiskSpace.cpp | 53 + plugins/CopyEngine/Ultracopier/DiskSpace.h | 29 + plugins/CopyEngine/Ultracopier/DiskSpace.ui | 68 + plugins/CopyEngine/Ultracopier/DriveManagement.cpp | 105 + plugins/CopyEngine/Ultracopier/DriveManagement.h | 34 + plugins/CopyEngine/Ultracopier/Environment.h | 11 + plugins/CopyEngine/Ultracopier/FileErrorDialog.cpp | 163 ++ plugins/CopyEngine/Ultracopier/FileErrorDialog.h | 51 + .../CopyEngine/Ultracopier/FileExistsDialog.cpp | 244 ++ plugins/CopyEngine/Ultracopier/FileExistsDialog.h | 60 + .../CopyEngine/Ultracopier/FileIsSameDialog.cpp | 194 ++ plugins/CopyEngine/Ultracopier/FileIsSameDialog.h | 57 + plugins/CopyEngine/Ultracopier/FilterRules.cpp | 193 ++ plugins/CopyEngine/Ultracopier/FilterRules.h | 46 + plugins/CopyEngine/Ultracopier/FilterRules.ui | 162 ++ plugins/CopyEngine/Ultracopier/Filters.cpp | 460 ++++ plugins/CopyEngine/Ultracopier/Filters.h | 45 + plugins/CopyEngine/Ultracopier/Filters.ui | 194 ++ .../CopyEngine/Ultracopier/FolderExistsDialog.cpp | 205 ++ .../CopyEngine/Ultracopier/FolderExistsDialog.h | 57 + .../Ultracopier/Languages/ar/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/de/translation.ts | 1290 +++++++++++ .../Ultracopier/Languages/el/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/en/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/es/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/fr/translation.ts | 1294 +++++++++++ .../Ultracopier/Languages/hi/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/hu/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/id/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/it/translation.ts | 1299 +++++++++++ .../Ultracopier/Languages/ja/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/ko/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/nl/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/no/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/pl/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/pt/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/ru/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/th/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/tr/translation.ts | 1289 +++++++++++ .../Ultracopier/Languages/zh/translation.ts | 1289 +++++++++++ plugins/CopyEngine/Ultracopier/ListThread.cpp | 2399 ++++++++++++++++++++ plugins/CopyEngine/Ultracopier/ListThread.h | 432 ++++ .../Ultracopier/ListThread_InodeAction.cpp | 64 + plugins/CopyEngine/Ultracopier/MkPath.cpp | 517 +++++ plugins/CopyEngine/Ultracopier/MkPath.h | 106 + plugins/CopyEngine/Ultracopier/ReadThread.cpp | 687 ++++++ plugins/CopyEngine/Ultracopier/ReadThread.h | 147 ++ plugins/CopyEngine/Ultracopier/RenamingRules.cpp | 85 + plugins/CopyEngine/Ultracopier/RenamingRules.h | 34 + plugins/CopyEngine/Ultracopier/RenamingRules.ui | 129 ++ .../CopyEngine/Ultracopier/ScanFileOrFolder.cpp | 688 ++++++ plugins/CopyEngine/Ultracopier/ScanFileOrFolder.h | 108 + .../CopyEngine/Ultracopier/StructEnumDefinition.h | 1 + .../Ultracopier/StructEnumDefinition_CopyEngine.h | 124 + plugins/CopyEngine/Ultracopier/TransferThread.cpp | 2091 +++++++++++++++++ plugins/CopyEngine/Ultracopier/TransferThread.h | 288 +++ plugins/CopyEngine/Ultracopier/Variable.h | 43 + plugins/CopyEngine/Ultracopier/WriteThread.cpp | 968 ++++++++ plugins/CopyEngine/Ultracopier/WriteThread.h | 160 ++ .../CopyEngine/Ultracopier/copyEngineOptions.ui | 762 +++++++ .../CopyEngine/Ultracopier/copyEngineResources.qrc | 8 + plugins/CopyEngine/Ultracopier/debugDialog.ui | 98 + plugins/CopyEngine/Ultracopier/documentation.dox | 39 + plugins/CopyEngine/Ultracopier/fileErrorDialog.ui | 264 +++ plugins/CopyEngine/Ultracopier/fileExistsDialog.ui | 412 ++++ plugins/CopyEngine/Ultracopier/fileIsSameDialog.ui | 214 ++ .../CopyEngine/Ultracopier/folderExistsDialog.ui | 309 +++ .../CopyEngine/Ultracopier/informations-rsync.xml | 26 + plugins/CopyEngine/Ultracopier/informations.xml | 26 + plugins/CopyEngine/Ultracopier/plugin.json | 1 + plugins/CopyEngine/Ultracopier/resources/add.png | Bin 0 -> 552 bytes plugins/CopyEngine/Ultracopier/resources/edit.png | Bin 0 -> 623 bytes .../CopyEngine/Ultracopier/resources/filter.png | Bin 0 -> 685 bytes .../CopyEngine/Ultracopier/resources/remove.png | Bin 0 -> 683 bytes 86 files changed, 42974 insertions(+) create mode 100644 plugins/CopyEngine/Ultracopier/AvancedQFile.cpp create mode 100644 plugins/CopyEngine/Ultracopier/AvancedQFile.h create mode 100644 plugins/CopyEngine/Ultracopier/CompilerInfo.h create mode 100644 plugins/CopyEngine/Ultracopier/CopyEngine-collision-and-error.cpp create mode 100644 plugins/CopyEngine/Ultracopier/CopyEngine.cpp create mode 100644 plugins/CopyEngine/Ultracopier/CopyEngine.h create mode 100644 plugins/CopyEngine/Ultracopier/CopyEngine.pro create mode 100644 plugins/CopyEngine/Ultracopier/CopyEngineFactory.cpp create mode 100644 plugins/CopyEngine/Ultracopier/CopyEngineFactory.h create mode 100644 plugins/CopyEngine/Ultracopier/DebugDialog.cpp create mode 100644 plugins/CopyEngine/Ultracopier/DebugDialog.h create mode 100644 plugins/CopyEngine/Ultracopier/DebugEngineMacro.h create mode 100644 plugins/CopyEngine/Ultracopier/DiskSpace.cpp create mode 100644 plugins/CopyEngine/Ultracopier/DiskSpace.h create mode 100644 plugins/CopyEngine/Ultracopier/DiskSpace.ui create mode 100644 plugins/CopyEngine/Ultracopier/DriveManagement.cpp create mode 100644 plugins/CopyEngine/Ultracopier/DriveManagement.h create mode 100644 plugins/CopyEngine/Ultracopier/Environment.h create mode 100644 plugins/CopyEngine/Ultracopier/FileErrorDialog.cpp create mode 100644 plugins/CopyEngine/Ultracopier/FileErrorDialog.h create mode 100644 plugins/CopyEngine/Ultracopier/FileExistsDialog.cpp create mode 100644 plugins/CopyEngine/Ultracopier/FileExistsDialog.h create mode 100644 plugins/CopyEngine/Ultracopier/FileIsSameDialog.cpp create mode 100644 plugins/CopyEngine/Ultracopier/FileIsSameDialog.h create mode 100644 plugins/CopyEngine/Ultracopier/FilterRules.cpp create mode 100644 plugins/CopyEngine/Ultracopier/FilterRules.h create mode 100644 plugins/CopyEngine/Ultracopier/FilterRules.ui create mode 100644 plugins/CopyEngine/Ultracopier/Filters.cpp create mode 100644 plugins/CopyEngine/Ultracopier/Filters.h create mode 100644 plugins/CopyEngine/Ultracopier/Filters.ui create mode 100644 plugins/CopyEngine/Ultracopier/FolderExistsDialog.cpp create mode 100644 plugins/CopyEngine/Ultracopier/FolderExistsDialog.h create mode 100644 plugins/CopyEngine/Ultracopier/Languages/ar/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/de/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/el/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/en/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/es/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/fr/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/hi/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/hu/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/id/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/it/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/ja/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/ko/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/nl/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/no/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/pl/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/pt/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/ru/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/th/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/tr/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/Languages/zh/translation.ts create mode 100644 plugins/CopyEngine/Ultracopier/ListThread.cpp create mode 100644 plugins/CopyEngine/Ultracopier/ListThread.h create mode 100644 plugins/CopyEngine/Ultracopier/ListThread_InodeAction.cpp create mode 100644 plugins/CopyEngine/Ultracopier/MkPath.cpp create mode 100644 plugins/CopyEngine/Ultracopier/MkPath.h create mode 100644 plugins/CopyEngine/Ultracopier/ReadThread.cpp create mode 100644 plugins/CopyEngine/Ultracopier/ReadThread.h create mode 100644 plugins/CopyEngine/Ultracopier/RenamingRules.cpp create mode 100644 plugins/CopyEngine/Ultracopier/RenamingRules.h create mode 100644 plugins/CopyEngine/Ultracopier/RenamingRules.ui create mode 100644 plugins/CopyEngine/Ultracopier/ScanFileOrFolder.cpp create mode 100644 plugins/CopyEngine/Ultracopier/ScanFileOrFolder.h create mode 100644 plugins/CopyEngine/Ultracopier/StructEnumDefinition.h create mode 100644 plugins/CopyEngine/Ultracopier/StructEnumDefinition_CopyEngine.h create mode 100644 plugins/CopyEngine/Ultracopier/TransferThread.cpp create mode 100644 plugins/CopyEngine/Ultracopier/TransferThread.h create mode 100644 plugins/CopyEngine/Ultracopier/Variable.h create mode 100644 plugins/CopyEngine/Ultracopier/WriteThread.cpp create mode 100644 plugins/CopyEngine/Ultracopier/WriteThread.h create mode 100644 plugins/CopyEngine/Ultracopier/copyEngineOptions.ui create mode 100644 plugins/CopyEngine/Ultracopier/copyEngineResources.qrc create mode 100644 plugins/CopyEngine/Ultracopier/debugDialog.ui create mode 100644 plugins/CopyEngine/Ultracopier/documentation.dox create mode 100644 plugins/CopyEngine/Ultracopier/fileErrorDialog.ui create mode 100644 plugins/CopyEngine/Ultracopier/fileExistsDialog.ui create mode 100644 plugins/CopyEngine/Ultracopier/fileIsSameDialog.ui create mode 100644 plugins/CopyEngine/Ultracopier/folderExistsDialog.ui create mode 100644 plugins/CopyEngine/Ultracopier/informations-rsync.xml create mode 100644 plugins/CopyEngine/Ultracopier/informations.xml create mode 100644 plugins/CopyEngine/Ultracopier/plugin.json create mode 100644 plugins/CopyEngine/Ultracopier/resources/add.png create mode 100644 plugins/CopyEngine/Ultracopier/resources/edit.png create mode 100644 plugins/CopyEngine/Ultracopier/resources/filter.png create mode 100644 plugins/CopyEngine/Ultracopier/resources/remove.png (limited to 'plugins/CopyEngine/Ultracopier') diff --git a/plugins/CopyEngine/Ultracopier/AvancedQFile.cpp b/plugins/CopyEngine/Ultracopier/AvancedQFile.cpp new file mode 100644 index 0000000..3d867fb --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/AvancedQFile.cpp @@ -0,0 +1,208 @@ +/** \file AvancedQFile.cpp +\brief Define the QFile herited class to set file date/time +\author alpha_one_x86 */ + +#include "AvancedQFile.h" + +#ifdef Q_CC_GNU +//this next header is needed to change file time/date under gcc +#include +#include +#endif + +//source +//hSrc=CreateFile(pData->pfiSrcFile->GetFullFilePath(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffer ? FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH : 0), NULL); +//destination +//hDst=CreateFile(pData->strDstFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffer ? FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH : 0), NULL); + +bool AvancedQFile::setCreated(const QDateTime &time) +{ + time_t ctime=time.toTime_t(); + #ifdef Q_CC_GNU + //creation time not exists into unix world + Q_UNUSED(ctime) + return true; + #else + setErrorString(tr("Not supported on this platform")); + return false; + #endif +} + +bool AvancedQFile::setLastModified(const QDateTime &time) +{ + time_t actime=QFileInfo(*this).lastRead().toTime_t(); + //protect to wrong actime + if(actime<0) + actime=0; + time_t modtime=time.toTime_t(); + if(modtime<0) + { + setErrorString(tr("Last modified date is wrong")); + return false; + } + #ifdef Q_CC_GNU + //this function avalaible on unix and mingw + utimbuf butime; + butime.actime=actime; + butime.modtime=modtime; + int returnVal=utime(this->fileName().toLocal8Bit().data(),&butime); + if(returnVal==0) + return true; + else + { + setErrorString(strerror(errno)); + return false; + } + #else + setErrorString(tr("Not supported on this platform")); + return false; + #endif +} + +bool AvancedQFile::setLastRead(const QDateTime &time) +{ + time_t modtime=QFileInfo(*this).lastModified().toTime_t(); + //protect to wrong actime + if(modtime<0) + modtime=0; + time_t actime=time.toTime_t(); + if(actime<0) + { + setErrorString(tr("Last access date is wrong")); + return false; + } + #ifdef Q_CC_GNU + //this function avalaible on unix and mingw + utimbuf butime; + butime.actime=actime; + butime.modtime=modtime; + int returnVal=utime(this->fileName().toLocal8Bit().data(),&butime); + if(returnVal==0) + return true; + else + { + setErrorString(strerror(errno)); + return false; + } + #else + setErrorString(tr("Not supported on this platform")); + return false; + #endif +} + +#ifdef ULTRACOPIER_OVERLAPPED_FILE +AvancedQFile::avancedQFile() +{ + handle=INVALID_HANDLE_VALUE; + fileError=QFileDevice::NoError; + fileErrorString.clear(); +} + +AvancedQFile::~avancedQFile() +{ + close(); +} + +QString AvancedQFile::getLastWindowsError() +{ + WCHAR ErrorStringW[65535]; + DWORD dw = GetLastError(); + + int size=FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + ErrorStringW, + 0, NULL ); + if(size<0) + tr("Unknown error: %1").arg(dw); + return QString::fromWCharArray(ErrorStringW,size); +} + +bool AvancedQFile::open(OpenMode mode) +{ + fileError=QFileDevice::NoError; + fileErrorString.clear(); + WCHAR fileNameW[fileName().size()+1]; + if(QDir::toNativeSeparators("\\\\?\\"+fileName()).toWCharArray(fileNameW)!=fileName().size()) + { + fileError=QFileDevice::OpenError; + fileErrorString=tr("Path conversion error"); + return false; + } + fileNameW[fileName().size()]='\0'; + + DWORD dwDesiredAccess=0; + if(mode & QIODevice::ReadOnly) + dwDesiredAccess|=GENERIC_READ; + if(mode & QIODevice::WriteOnly) + dwDesiredAccess|=GENERIC_Write; + + DWORD dwCreationDisposition; + if(mode & QIODevice::WriteOnly) + dwCreationDisposition=CREATE_ALWAYS; + else + dwCreationDisposition=OPEN_EXISTING; + + handle=CreateFile( + fileNameW, + dwDesiredAccess, + 0, + 0, + dwCreationDisposition, + FILE_FLAG_WRITE_THROUGH | FILE_FLAG_SEQUENTIAL_SCAN, + 0 + ); + if(handle==INVALID_HANDLE_VALUE) + { + fileError=QFileDevice::OpenError; + fileErrorString=getLastWindowsError(); + } + return (handle!=INVALID_HANDLE_VALUE); +} + +void AvancedQFile::close() +{ + if(handle==INVALID_HANDLE_VALUE) + return; + CloseHandle(handle); +} + +bool AvancedQFile::seek(qint64 pos) +{ + toto +} + +bool AvancedQFile::resize(qint64 size) +{ + toto +} + +QString AvancedQFile::errorString() const +{ + if(fileErrorString.isEmpty()) + return tr("Unknown error"); + return fileErrorString; +} + +bool AvancedQFile::isOpen() const +{ + return (handle!=INVALID_HANDLE_VALUE); +} + +qint64 AvancedQFile::write(const QByteArray &data) +{ +} + +QByteArray AvancedQFile::read(qint64 maxlen) +{ +} + +QFileDevice::FileError AvancedQFile::error() const +{ + return fileError; +} +#endif diff --git a/plugins/CopyEngine/Ultracopier/AvancedQFile.h b/plugins/CopyEngine/Ultracopier/AvancedQFile.h new file mode 100644 index 0000000..8c3dc4a --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/AvancedQFile.h @@ -0,0 +1,45 @@ +/** \file AvancedQFile.h +\brief Define the QFile herited class to set file date/time +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef AVANCEDQFILE_H +#define AVANCEDQFILE_H + +#include +#include +#include + +/// \brief devired class from QFile to set time/date on file +class AvancedQFile : public QFile +{ + Q_OBJECT +public: + /// \brief set created date, not exists in unix world + bool setCreated(const QDateTime &time); + /// \brief set last modification date + bool setLastModified(const QDateTime &time); + /// \brief set last read date + bool setLastRead(const QDateTime &time); + + #ifdef ULTRACOPIER_OVERLAPPED_FILE + explicit AvancedQFile(); + ~AvancedQFile(); + bool open(OpenMode mode); + void close(); + bool seek(qint64 pos); + bool resize(qint64 size); + QString errorString() const; + bool isOpen() const; + qint64 write(const QByteArray &data); + QByteArray read(qint64 maxlen); + FileError error() const; + QString getLastWindowsError(); +private: + HANDLE handle; + FileError fileError; + QString fileErrorString; + #endif +}; + +#endif // AVANCEDQFILE_H diff --git a/plugins/CopyEngine/Ultracopier/CompilerInfo.h b/plugins/CopyEngine/Ultracopier/CompilerInfo.h new file mode 100644 index 0000000..84625b9 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CompilerInfo.h @@ -0,0 +1 @@ +#include "../../../CompilerInfo.h" diff --git a/plugins/CopyEngine/Ultracopier/CopyEngine-collision-and-error.cpp b/plugins/CopyEngine/Ultracopier/CopyEngine-collision-and-error.cpp new file mode 100644 index 0000000..16c36ae --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CopyEngine-collision-and-error.cpp @@ -0,0 +1,568 @@ +/** \file copyEngine.cpp +\brief Define the copy engine +\author alpha_one_x86 */ + +#include "CopyEngine.h" +#include "FolderExistsDialog.h" +#include "DiskSpace.h" + +//dialog message +/// \note Can be call without queue because all call will be serialized +void CopyEngine::fileAlreadyExistsSlot(QFileInfo source,QFileInfo destination,bool isSame,TransferThread * thread) +{ + fileAlreadyExists(source,destination,isSame,thread); +} + +/// \note Can be call without queue because all call will be serialized +void CopyEngine::errorOnFileSlot(QFileInfo fileInfo,std::string errorString,TransferThread * thread,const ErrorType &errorType) +{ + errorOnFile(fileInfo,errorString,thread,errorType); +} + +/// \note Can be call without queue because all call will be serialized +void CopyEngine::folderAlreadyExistsSlot(QFileInfo source,QFileInfo destination,bool isSame,ScanFileOrFolder * thread) +{ + folderAlreadyExists(source,destination,isSame,thread); +} + +/// \note Can be call without queue because all call will be serialized +void CopyEngine::errorOnFolderSlot(QFileInfo fileInfo,std::string errorString,ScanFileOrFolder * thread,ErrorType errorType) +{ + errorOnFolder(fileInfo,errorString,thread,errorType); +} + +//mkpath event +void CopyEngine::mkPathErrorOnFolderSlot(QFileInfo folder,std::string error,ErrorType errorType) +{ + mkPathErrorOnFolder(folder,error,errorType); +} + +/// \note Can be call without queue because all call will be serialized +void CopyEngine::fileAlreadyExists(QFileInfo source,QFileInfo destination,bool isSame,TransferThread * thread,bool isCalledByShowOneNewDialog) +{ + if(stopIt) + return; + if(thread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to locate the thread"); + return; + } + //load the action + if(isSame) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"file is same: "+source.absoluteFilePath().toStdString()); + FileExistsAction tempFileExistsAction=alwaysDoThisActionForFileExists; + if(tempFileExistsAction==FileExists_Overwrite || tempFileExistsAction==FileExists_OverwriteIfNewer || tempFileExistsAction==FileExists_OverwriteIfNotSame || tempFileExistsAction==FileExists_OverwriteIfOlder) + tempFileExistsAction=FileExists_NotSet; + switch(tempFileExistsAction) + { + case FileExists_Skip: + case FileExists_Rename: + thread->setFileExistsAction(tempFileExistsAction); + break; + default: + if(dialogIsOpen) + { + alreadyExistsQueueItem newItem; + newItem.source=source; + newItem.destination=destination; + newItem.isSame=isSame; + newItem.transfer=thread; + newItem.scan=NULL; + alreadyExistsQueue.push_back(newItem); + return; + } + dialogIsOpen=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + FileIsSameDialog dialog(interface,source,firstRenamingRule,otherRenamingRule); + emit isInPause(true); + dialog.exec();/// \bug crash when external close + FileExistsAction newAction=dialog.getAction(); + emit isInPause(false); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"close dialog: "+std::to_string(newAction)); + if(newAction==FileExists_Cancel) + { + emit cancelAll(); + return; + } + if(dialog.getAlways() && newAction!=alwaysDoThisActionForFileExists) + { + alwaysDoThisActionForFileExists=newAction; + listThread->setAlwaysFileExistsAction(alwaysDoThisActionForFileExists); + if(uiIsInstalled) + switch(newAction) + { + default: + case FileExists_Skip: + ui->comboBoxFileCollision->setCurrentIndex(1); + break; + case FileExists_Rename: + ui->comboBoxFileCollision->setCurrentIndex(6); + break; + } + } + if(dialog.getAlways() || newAction!=FileExists_Rename) + thread->setFileExistsAction(newAction); + else + thread->setFileRename(dialog.getNewName()); + dialogIsOpen=false; + if(!isCalledByShowOneNewDialog) + emit queryOneNewDialog(); + return; + break; + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"file already exists: "+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()); + FileExistsAction tempFileExistsAction=alwaysDoThisActionForFileExists; + switch(tempFileExistsAction) + { + case FileExists_Skip: + case FileExists_Rename: + case FileExists_Overwrite: + case FileExists_OverwriteIfNewer: + case FileExists_OverwriteIfOlder: + case FileExists_OverwriteIfNotSame: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"always do this action: "+std::to_string(tempFileExistsAction)); + thread->setFileExistsAction(tempFileExistsAction); + break; + default: + if(dialogIsOpen) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("dialog open, put in queue: %1 %2") + .arg(source.absoluteFilePath()) + .arg(destination.absoluteFilePath()) + .toStdString() + ); + alreadyExistsQueueItem newItem; + newItem.source=source; + newItem.destination=destination; + newItem.isSame=isSame; + newItem.transfer=thread; + newItem.scan=NULL; + alreadyExistsQueue.push_back(newItem); + return; + } + dialogIsOpen=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + FileExistsDialog dialog(interface,source,destination,firstRenamingRule,otherRenamingRule); + emit isInPause(true); + dialog.exec();/// \bug crash when external close + FileExistsAction newAction=dialog.getAction(); + emit isInPause(false); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"close dialog: "+std::to_string(newAction)); + if(newAction==FileExists_Cancel) + { + emit cancelAll(); + return; + } + if(dialog.getAlways() && newAction!=alwaysDoThisActionForFileExists) + { + alwaysDoThisActionForFileExists=newAction; + listThread->setAlwaysFileExistsAction(alwaysDoThisActionForFileExists); + if(uiIsInstalled) + switch(newAction) + { + default: + case FileExists_Skip: + ui->comboBoxFileCollision->setCurrentIndex(1); + break; + case FileExists_Rename: + ui->comboBoxFileCollision->setCurrentIndex(6); + break; + case FileExists_Overwrite: + ui->comboBoxFileCollision->setCurrentIndex(2); + break; + case FileExists_OverwriteIfNotSame: + ui->comboBoxFileCollision->setCurrentIndex(3); + break; + case FileExists_OverwriteIfNewer: + ui->comboBoxFileCollision->setCurrentIndex(4); + break; + case FileExists_OverwriteIfOlder: + ui->comboBoxFileCollision->setCurrentIndex(5); + break; + } + } + if(dialog.getAlways() || newAction!=FileExists_Rename) + thread->setFileExistsAction(newAction); + else + thread->setFileRename(dialog.getNewName()); + dialogIsOpen=false; + if(!isCalledByShowOneNewDialog) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"emit queryOneNewDialog()"); + emit queryOneNewDialog(); + } + return; + break; + } + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop"); +} + +void CopyEngine::haveNeedPutAtBottom(bool needPutAtBottom, const QFileInfo &fileInfo, const std::string &errorString,TransferThread *thread,const ErrorType &errorType) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + if(!needPutAtBottom) + { + alwaysDoThisActionForFileError=FileError_NotSet; + if(uiIsInstalled) + ui->comboBoxFileError->setCurrentIndex(0); + errorQueueItem newItem; + newItem.errorString=errorString; + newItem.inode=fileInfo; + newItem.mkPath=false; + newItem.rmPath=false; + newItem.scan=NULL; + newItem.transfer=thread; + newItem.errorType=errorType; + errorQueue.push_back(newItem); + showOneNewDialog(); + } +} + +void CopyEngine::missingDiskSpace(std::vector list) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + DiskSpace dialog(facilityEngine,list,interface); + emit isInPause(true); + dialog.exec();/// \bug crash when external close + bool ok=dialog.getAction(); + emit isInPause(false); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"cancel: "+std::to_string(ok)); + if(!ok) + emit cancelAll(); + else + listThread->autoStartIfNeeded(); +} + +/// \note Can be call without queue because all call will be serialized +void CopyEngine::errorOnFile(QFileInfo fileInfo,std::string errorString,TransferThread * thread,const ErrorType &errorType,bool isCalledByShowOneNewDialog) +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"file have error: "+fileInfo.absoluteFilePath().toStdString()+", error: "+errorString); + if(thread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to locate the thread"); + return; + } + //load the action + FileErrorAction tempFileErrorAction=alwaysDoThisActionForFileError; + switch(tempFileErrorAction) + { + case FileError_Skip: + thread->skip(); + return; + case FileError_Retry: + thread->retryAfterError(); + return; + case FileError_PutToEndOfTheList: + emit getNeedPutAtBottom(fileInfo,errorString,thread,errorType); + return; + case FileError_Cancel: + return; + default: + if(dialogIsOpen) + { + errorQueueItem newItem; + newItem.errorString=errorString; + newItem.inode=fileInfo; + newItem.mkPath=false; + newItem.rmPath=false; + newItem.scan=NULL; + newItem.transfer=thread; + newItem.errorType=errorType; + errorQueue.push_back(newItem); + return; + } + dialogIsOpen=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + emit error(fileInfo.absoluteFilePath().toStdString(),fileInfo.size(),fileInfo.lastModified().toMSecsSinceEpoch()/1000,errorString); + FileErrorDialog dialog(interface,fileInfo,errorString,errorType); + emit isInPause(true); + dialog.exec();/// \bug crash when external close + FileErrorAction newAction=dialog.getAction(); + emit isInPause(false); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"close dialog: "+std::to_string(newAction)); + if(newAction==FileError_Cancel) + { + emit cancelAll(); + return; + } + if(dialog.getAlways() && newAction!=alwaysDoThisActionForFileError) + { + alwaysDoThisActionForFileError=newAction; + if(uiIsInstalled) + switch(newAction) + { + default: + case FileError_Skip: + ui->comboBoxFileError->setCurrentIndex(1); + break; + case FileError_PutToEndOfTheList: + ui->comboBoxFileError->setCurrentIndex(2); + break; + } + } + switch(newAction) + { + case FileError_Skip: + thread->skip(); + break; + case FileError_Retry: + thread->retryAfterError(); + break; + case FileError_PutToEndOfTheList: + thread->putAtBottom(); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"file error action wrong"); + break; + } + dialogIsOpen=false; + if(!isCalledByShowOneNewDialog) + emit queryOneNewDialog(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"isCalledByShowOneNewDialog==true then not show other dial"); + return; + break; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop"); +} + +/// \note Can be call without queue because all call will be serialized +void CopyEngine::folderAlreadyExists(QFileInfo source,QFileInfo destination,bool isSame,ScanFileOrFolder * thread,bool isCalledByShowOneNewDialog) +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"folder already exists: "+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()); + if(thread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to locate the thread"); + return; + } + //load the always action + FolderExistsAction tempFolderExistsAction=alwaysDoThisActionForFolderExists; + switch(tempFolderExistsAction) + { + case FolderExists_Skip: + case FolderExists_Rename: + case FolderExists_Merge: + thread->setFolderExistsAction(tempFolderExistsAction); + break; + default: + if(dialogIsOpen) + { + alreadyExistsQueueItem newItem; + newItem.source=source; + newItem.destination=destination; + newItem.isSame=isSame; + newItem.transfer=NULL; + newItem.scan=thread; + alreadyExistsQueue.push_back(newItem); + return; + } + dialogIsOpen=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + FolderExistsDialog dialog(interface,source,isSame,destination,firstRenamingRule,otherRenamingRule); + dialog.exec();/// \bug crash when external close + FolderExistsAction newAction=dialog.getAction(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"close dialog: "+std::to_string(newAction)); + if(newAction==FolderExists_Cancel) + { + emit cancelAll(); + return; + } + if(dialog.getAlways() && newAction!=alwaysDoThisActionForFolderExists) + setComboBoxFolderCollision(newAction); + if(!dialog.getAlways() && newAction==FolderExists_Rename) + thread->setFolderExistsAction(newAction,dialog.getNewName()); + else + thread->setFolderExistsAction(newAction); + dialogIsOpen=false; + if(!isCalledByShowOneNewDialog) + emit queryOneNewDialog(); + return; + break; + } +} + +/// \note Can be call without queue because all call will be serialized +/// \todo all this part +void CopyEngine::errorOnFolder(QFileInfo fileInfo, std::string errorString, ScanFileOrFolder * thread, ErrorType errorType, bool isCalledByShowOneNewDialog) +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"file have error: "+fileInfo.absoluteFilePath().toStdString()+", error: "+errorString); + if(thread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to locate the thread"); + return; + } + //load the always action + FileErrorAction tempFileErrorAction=alwaysDoThisActionForFolderError; + switch(tempFileErrorAction) + { + case FileError_Skip: + case FileError_Retry: + case FileError_PutToEndOfTheList: + thread->setFolderErrorAction(tempFileErrorAction); + break; + default: + if(dialogIsOpen) + { + errorQueueItem newItem; + newItem.errorString=errorString; + newItem.inode=fileInfo; + newItem.mkPath=false; + newItem.rmPath=false; + newItem.scan=thread; + newItem.transfer=NULL; + newItem.errorType=errorType; + errorQueue.push_back(newItem); + return; + } + dialogIsOpen=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + emit error(fileInfo.absoluteFilePath().toStdString(),fileInfo.size(),fileInfo.lastModified().toMSecsSinceEpoch()/1000,errorString); + FileErrorDialog dialog(interface,fileInfo,errorString,errorType); + dialog.exec();/// \bug crash when external close + FileErrorAction newAction=dialog.getAction(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"close dialog: "+std::to_string(newAction)); + if(newAction==FileError_Cancel) + { + emit cancelAll(); + return; + } + if(dialog.getAlways() && newAction!=alwaysDoThisActionForFileError) + { + setComboBoxFolderError(newAction); + alwaysDoThisActionForFolderError=newAction; + } + dialogIsOpen=false; + thread->setFolderErrorAction(newAction); + if(!isCalledByShowOneNewDialog) + emit queryOneNewDialog(); + return; + break; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop"); +} + +// ----------------------------------------------------- + +//mkpath event +void CopyEngine::mkPathErrorOnFolder(QFileInfo folder,std::string errorString,const ErrorType &errorType,bool isCalledByShowOneNewDialog) +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"file have error: "+folder.absoluteFilePath().toStdString()+", error: "+errorString); + //load the always action + FileErrorAction tempFileErrorAction=alwaysDoThisActionForFolderError; + switch(tempFileErrorAction) + { + case FileError_Skip: + listThread->mkPathQueue.skip(); + return; + case FileError_Retry: + listThread->mkPathQueue.retry(); + return; + default: + if(dialogIsOpen) + { + errorQueueItem newItem; + newItem.errorString=errorString; + newItem.inode=folder; + newItem.mkPath=true; + newItem.rmPath=false; + newItem.scan=NULL; + newItem.transfer=NULL; + newItem.errorType=errorType; + errorQueue.push_back(newItem); + return; + } + dialogIsOpen=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"show dialog"); + emit error(folder.absoluteFilePath().toStdString(),folder.size(),folder.lastModified().toMSecsSinceEpoch()/1000,errorString); + FileErrorDialog dialog(interface,folder,errorString,errorType); + dialog.exec();/// \bug crash when external close + FileErrorAction newAction=dialog.getAction(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"close dialog: "+std::to_string(newAction)); + if(newAction==FileError_Cancel) + { + emit cancelAll(); + return; + } + if(dialog.getAlways() && newAction!=alwaysDoThisActionForFileError) + { + setComboBoxFolderError(newAction); + alwaysDoThisActionForFolderError=newAction; + } + dialogIsOpen=false; + switch(newAction) + { + case FileError_Skip: + listThread->mkPathQueue.skip(); + break; + case FileError_Retry: + listThread->mkPathQueue.retry(); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unknow switch case: "+std::to_string(newAction)); + break; + } + if(!isCalledByShowOneNewDialog) + emit queryOneNewDialog(); + return; + break; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop"); +} + +//show one new dialog if needed +void CopyEngine::showOneNewDialog() +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"alreadyExistsQueue.size(): "+std::to_string(alreadyExistsQueue.size())); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"errorQueue.size(): "+std::to_string(errorQueue.size())); + int loop_size=alreadyExistsQueue.size(); + while(loop_size>0) + { + if(alreadyExistsQueue.front().transfer!=NULL) + { + fileAlreadyExists(alreadyExistsQueue.front().source, + alreadyExistsQueue.front().destination, + alreadyExistsQueue.front().isSame, + alreadyExistsQueue.front().transfer, + true); + } + else if(alreadyExistsQueue.front().scan!=NULL) + folderAlreadyExists(alreadyExistsQueue.front().source, + alreadyExistsQueue.front().destination, + alreadyExistsQueue.front().isSame, + alreadyExistsQueue.front().scan, + true); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"bug, no thread actived"); + alreadyExistsQueue.erase(alreadyExistsQueue.cbegin()); + loop_size--; + } + loop_size=errorQueue.size(); + while(errorQueue.size()>0 && loop_size>0) + { + if(errorQueue.front().transfer!=NULL) + errorOnFile(errorQueue.front().inode,errorQueue.front().errorString,errorQueue.front().transfer,errorQueue.front().errorType,true); + else if(errorQueue.front().scan!=NULL) + errorOnFolder(errorQueue.front().inode,errorQueue.front().errorString,errorQueue.front().scan,errorQueue.front().errorType,true); + else if(errorQueue.front().mkPath) + mkPathErrorOnFolder(errorQueue.front().inode,errorQueue.front().errorString,errorQueue.front().errorType,true); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"bug, no thread actived"); + errorQueue.erase(errorQueue.cbegin()); + loop_size--; + } +} diff --git a/plugins/CopyEngine/Ultracopier/CopyEngine.cpp b/plugins/CopyEngine/Ultracopier/CopyEngine.cpp new file mode 100644 index 0000000..f3d6e04 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CopyEngine.cpp @@ -0,0 +1,1253 @@ +/** \file copyEngine.cpp +\brief Define the copy engine +\author alpha_one_x86 */ + +#include +#include +#include + +#include "CopyEngine.h" +#include "FolderExistsDialog.h" +#include "../../../interface/PluginInterface_CopyEngine.h" + +// The cmath header from MSVC does not contain round() +#if (defined(_WIN64) || defined(_WIN32)) && defined(_MSC_VER) +inline double round(double d) { + return floor( d + 0.5 ); +} +#endif + +CopyEngine::CopyEngine(FacilityInterface * facilityEngine) : + ui(new Ui::copyEngineOptions()) +{ + listThread=new ListThread(facilityEngine); + this->facilityEngine = facilityEngine; + filters = NULL; + renamingRules = NULL; + + blockSize = ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE; + sequentialBuffer = ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*ULTRACOPIER_PLUGIN_DEFAULT_SEQUENTIAL_NUMBER_OF_BLOCK; + parallelBuffer = ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*ULTRACOPIER_PLUGIN_DEFAULT_PARALLEL_NUMBER_OF_BLOCK; + interface = NULL; + tempWidget = NULL; + uiIsInstalled = false; + dialogIsOpen = false; + renameTheOriginalDestination = false; + maxSpeed = 0; + alwaysDoThisActionForFileExists = FileExists_NotSet; + alwaysDoThisActionForFileError = FileError_NotSet; + checkDestinationFolderExists = false; + stopIt = false; + size_for_speed = 0; + putAtBottom = 0; + forcedMode = false; + followTheStrictOrder = false; + deletePartiallyTransferredFiles = true; + inodeThreads = 16; + moveTheWholeFolder = true; + + //implement the SingleShot in this class + //timerActionDone.setSingleShot(true); + timerActionDone.setInterval(ULTRACOPIER_PLUGIN_TIME_UPDATE_TRASNFER_LIST); + //timerProgression.setSingleShot(true); + timerProgression.setInterval(ULTRACOPIER_PLUGIN_TIME_UPDATE_PROGRESSION); + + timerUpdateMount.setInterval(ULTRACOPIER_PLUGIN_TIME_UPDATE_MOUNT_MS); +} + +CopyEngine::~CopyEngine() +{ + /*if(filters!=NULL) + delete filters; + if(renamingRules!=NULL) + delete renamingRules; + destroyed by the widget parent, here the interface + */ + stopIt=true; + delete listThread; + delete ui; +} + +void CopyEngine::connectTheSignalsSlots() +{ + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + debugDialogWindow.show(); + #endif + if(!connect(listThread,&ListThread::actionInProgess, this,&CopyEngine::actionInProgess, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect actionInProgess()"); + if(!connect(listThread,&ListThread::actionInProgess, this,&CopyEngine::newActionInProgess, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect actionInProgess() to slot"); + if(!connect(listThread,&ListThread::newFolderListing, this,&CopyEngine::newFolderListing, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect newFolderListing()"); + if(!connect(listThread,&ListThread::isInPause, this,&CopyEngine::isInPause, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect isInPause()"); + if(!connect(listThread,&ListThread::error, this,&CopyEngine::error, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect error()"); + if(!connect(listThread,&ListThread::rmPath, this,&CopyEngine::rmPath, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect rmPath()"); + if(!connect(listThread,&ListThread::mkPath, this,&CopyEngine::mkPath, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect mkPath()"); + if(!connect(listThread,&ListThread::newActionOnList, this,&CopyEngine::newActionOnList, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect newActionOnList()"); + if(!connect(listThread,&ListThread::doneTime, this,&CopyEngine::doneTime, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect doneTime()"); + if(!connect(listThread,&ListThread::pushFileProgression, this,&CopyEngine::pushFileProgression, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect pushFileProgression()"); + if(!connect(listThread,&ListThread::pushGeneralProgression, this,&CopyEngine::pushGeneralProgression, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect pushGeneralProgression()"); + if(!connect(listThread,&ListThread::syncReady, this,&CopyEngine::syncReady, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect syncReady()"); + if(!connect(listThread,&ListThread::canBeDeleted, this,&CopyEngine::canBeDeleted, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect canBeDeleted()"); + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + if(!connect(listThread,&ListThread::debugInformation, this,&CopyEngine::debugInformation, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect debugInformation()"); + #endif + + if(!connect(listThread,&ListThread::send_fileAlreadyExists, this,&CopyEngine::fileAlreadyExistsSlot, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_fileAlreadyExists()"); + if(!connect(listThread,&ListThread::send_errorOnFile, this,&CopyEngine::errorOnFileSlot, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_errorOnFile()"); + if(!connect(listThread,&ListThread::send_folderAlreadyExists, this,&CopyEngine::folderAlreadyExistsSlot, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_folderAlreadyExists()"); + if(!connect(listThread,&ListThread::send_errorOnFolder, this,&CopyEngine::errorOnFolderSlot, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_errorOnFolder()"); + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + if(!connect(listThread,&ListThread::updateTheDebugInfo, this,&CopyEngine::updateTheDebugInfo, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect updateTheDebugInfo()"); + #endif + if(!connect(listThread,&ListThread::errorTransferList, this,&CopyEngine::errorTransferList, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect errorTransferList()"); + if(!connect(listThread,&ListThread::warningTransferList, this,&CopyEngine::warningTransferList, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect warningTransferList()"); + if(!connect(listThread,&ListThread::mkPathErrorOnFolder, this,&CopyEngine::mkPathErrorOnFolderSlot, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect mkPathErrorOnFolder()"); + if(!connect(listThread,&ListThread::send_realBytesTransfered, this,&CopyEngine::get_realBytesTransfered, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_realBytesTransfered()"); + + if(!connect(this,&CopyEngine::tryCancel, listThread,&ListThread::cancel, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect tryCancel()"); + if(!connect(this,&CopyEngine::getNeedPutAtBottom, listThread,&ListThread::getNeedPutAtBottom, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect getNeedPutAtBottom()"); + if(!connect(listThread,&ListThread::haveNeedPutAtBottom, this,&CopyEngine::haveNeedPutAtBottom, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect haveNeedPutAtBottom()"); + + + if(!connect(this,&CopyEngine::signal_pause, listThread,&ListThread::pause, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_pause()"); + if(!connect(this,&CopyEngine::signal_exportErrorIntoTransferList,listThread,&ListThread::exportErrorIntoTransferList, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_exportErrorIntoTransferList()"); + if(!connect(this,&CopyEngine::signal_resume, listThread,&ListThread::resume, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_resume()"); + if(!connect(this,&CopyEngine::signal_skip, listThread,&ListThread::skip, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_skip()"); + if(!connect(this,&CopyEngine::signal_setCollisionAction, listThread,&ListThread::setAlwaysFileExistsAction, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_setCollisionAction()"); + if(!connect(this,&CopyEngine::signal_setTransferAlgorithm, listThread,&ListThread::setTransferAlgorithm, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_setCollisionAction()"); + if(!connect(this,&CopyEngine::signal_setFolderCollision, listThread,&ListThread::setFolderCollision, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_setFolderCollision()"); + if(!connect(this,&CopyEngine::signal_removeItems, listThread,&ListThread::removeItems, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_removeItems()"); + if(!connect(this,&CopyEngine::signal_moveItemsOnTop, listThread,&ListThread::moveItemsOnTop, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_moveItemsOnTop()"); + if(!connect(this,&CopyEngine::signal_moveItemsUp, listThread,&ListThread::moveItemsUp, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_moveItemsUp()"); + if(!connect(this,&CopyEngine::signal_moveItemsDown, listThread,&ListThread::moveItemsDown, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_moveItemsDown()"); + if(!connect(this,&CopyEngine::signal_moveItemsOnBottom, listThread,&ListThread::moveItemsOnBottom, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_moveItemsOnBottom()"); + if(!connect(this,&CopyEngine::signal_exportTransferList, listThread,&ListThread::exportTransferList, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_exportTransferList()"); + if(!connect(this,&CopyEngine::signal_importTransferList, listThread,&ListThread::importTransferList, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_importTransferList()"); + if(!connect(this,&CopyEngine::signal_forceMode, listThread,&ListThread::forceMode, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect signal_forceMode()"); + if(!connect(this,&CopyEngine::send_osBufferLimit, listThread,&ListThread::set_osBufferLimit, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_osBufferLimit()"); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + if(!connect(this,&CopyEngine::send_speedLimitation, listThread,&ListThread::setSpeedLimitation, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_speedLimitation()"); + #endif + if(!connect(this,&CopyEngine::send_blockSize, listThread,&ListThread::setBlockSize, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_blockSize()"); + if(!connect(this,&CopyEngine::send_parallelBuffer, listThread,&ListThread::setParallelBuffer, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect setParallelBuffer()"); + if(!connect(this,&CopyEngine::send_sequentialBuffer, listThread,&ListThread::setSequentialBuffer, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect setSequentialBuffer()"); + if(!connect(this,&CopyEngine::send_parallelizeIfSmallerThan, listThread,&ListThread::setParallelizeIfSmallerThan, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect setParallelizeIfSmallerThan()"); + if(!connect(this,&CopyEngine::send_moveTheWholeFolder, listThread,&ListThread::setMoveTheWholeFolder, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect moveTheWholeFolder()"); + if(!connect(this,&CopyEngine::send_deletePartiallyTransferredFiles, listThread,&ListThread::setDeletePartiallyTransferredFiles, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect deletePartiallyTransferredFiles()"); + if(!connect(this,&CopyEngine::send_setRenameTheOriginalDestination, listThread,&ListThread::setRenameTheOriginalDestination, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect setRenameTheOriginalDestination()"); + if(!connect(this,&CopyEngine::send_setInodeThreads, listThread,&ListThread::setInodeThreads, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect setInodeThreads()"); + if(!connect(this,&CopyEngine::send_followTheStrictOrder, listThread,&ListThread::setFollowTheStrictOrder, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect followTheStrictOrder()"); + if(!connect(this,&CopyEngine::send_setFilters,listThread,&ListThread::set_setFilters, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_setFilters()"); + if(!connect(this,&CopyEngine::send_sendNewRenamingRules,listThread,&ListThread::set_sendNewRenamingRules, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect send_sendNewRenamingRules()"); + if(!connect(&timerActionDone,&QTimer::timeout, listThread,&ListThread::sendActionDone)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect timerActionDone"); + if(!connect(&timerProgression,&QTimer::timeout, listThread,&ListThread::sendProgression)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect timerProgression"); + if(!connect(listThread,&ListThread::missingDiskSpace, this,&CopyEngine::missingDiskSpace,Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect timerProgression"); + + if(!connect(this,&CopyEngine::queryOneNewDialog,this,&CopyEngine::showOneNewDialog,Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect queryOneNewDialog()"); + if(!connect(listThread,&ListThread::errorToRetry,this,&CopyEngine::errorToRetry,Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect errorToRetry()"); + + if(!connect(&timerUpdateMount,&QTimer::timeout,listThread,&ListThread::set_updateMount, Qt::QueuedConnection)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect set_updateMount()"); +} + +#ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW +void CopyEngine::updateTheDebugInfo(const std::vector &newList, const std::vector &newList2, const int &numberOfInodeOperation) +{ + debugDialogWindow.setTransferThreadList(newList); + debugDialogWindow.setTransferList(newList2); + debugDialogWindow.setInodeUsage(numberOfInodeOperation); +} +#endif + +//to send the options panel +bool CopyEngine::getOptionsEngine(QWidget * tempWidget) +{ + this->tempWidget=tempWidget; + ui->setupUi(tempWidget); + ui->toolBox->setCurrentIndex(0); + ui->blockSize->setMaximum(ULTRACOPIER_PLUGIN_MAX_BLOCK_SIZE); + connect(tempWidget, &QWidget::destroyed, this, &CopyEngine::resetTempWidget); + //conect the ui widget + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + if(!setSpeedLimitation(maxSpeed)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the speed limitation"); + #endif + + //here else, the default settings can't be loaded + uiIsInstalled=true; + + setBlockSize(blockSize); + setSequentialBuffer(sequentialBuffer); + setParallelBuffer(parallelBuffer); + setAutoStart(autoStart); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + setRsync(rsync); + #else + ui->label_rsync->setVisible(false); + ui->rsync->setVisible(false); + #endif + setCheckDestinationFolderExists(checkDestinationFolderExists); + set_doChecksum(doChecksum); + set_checksumIgnoreIfImpossible(checksumIgnoreIfImpossible); + set_checksumOnlyOnError(checksumOnlyOnError); + set_osBuffer(osBuffer); + set_osBufferLimited(osBufferLimited); + set_osBufferLimit(osBufferLimit); + setRightTransfer(doRightTransfer); + setKeepDate(keepDate); + setParallelizeIfSmallerThan(parallelizeIfSmallerThan); + setFollowTheStrictOrder(followTheStrictOrder); + setDeletePartiallyTransferredFiles(deletePartiallyTransferredFiles); + setInodeThreads(inodeThreads); + setRenameTheOriginalDestination(renameTheOriginalDestination); + setMoveTheWholeFolder(moveTheWholeFolder); + setCheckDiskSpace(checkDiskSpace); + setDefaultDestinationFolder(defaultDestinationFolder); + + switch(alwaysDoThisActionForFileExists) + { + case FileExists_NotSet: + ui->comboBoxFileCollision->setCurrentIndex(0); + break; + case FileExists_Skip: + ui->comboBoxFileCollision->setCurrentIndex(1); + break; + case FileExists_Overwrite: + ui->comboBoxFileCollision->setCurrentIndex(2); + break; + case FileExists_OverwriteIfNotSame: + ui->comboBoxFileCollision->setCurrentIndex(3); + break; + case FileExists_OverwriteIfNewer: + ui->comboBoxFileCollision->setCurrentIndex(4); + break; + case FileExists_OverwriteIfOlder: + ui->comboBoxFileCollision->setCurrentIndex(5); + break; + case FileExists_Rename: + ui->comboBoxFileCollision->setCurrentIndex(6); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + ui->comboBoxFileCollision->setCurrentIndex(0); + break; + } + switch(alwaysDoThisActionForFileError) + { + case FileError_NotSet: + ui->comboBoxFileError->setCurrentIndex(0); + break; + case FileError_Skip: + ui->comboBoxFileError->setCurrentIndex(1); + break; + case FileError_PutToEndOfTheList: + ui->comboBoxFileError->setCurrentIndex(2); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + ui->comboBoxFileError->setCurrentIndex(0); + break; + } + switch(alwaysDoThisActionForFolderExists) + { + case FolderExists_NotSet: + ui->comboBoxFolderCollision->setCurrentIndex(0); + break; + case FolderExists_Merge: + ui->comboBoxFolderCollision->setCurrentIndex(1); + break; + case FolderExists_Skip: + ui->comboBoxFolderCollision->setCurrentIndex(2); + break; + case FolderExists_Rename: + ui->comboBoxFolderCollision->setCurrentIndex(3); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + ui->comboBoxFolderCollision->setCurrentIndex(0); + break; + } + switch(alwaysDoThisActionForFolderError) + { + case FileError_NotSet: + ui->comboBoxFolderError->setCurrentIndex(0); + break; + case FileError_Skip: + ui->comboBoxFolderError->setCurrentIndex(1); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored: "+std::to_string(alwaysDoThisActionForFolderError)); + ui->comboBoxFolderError->setCurrentIndex(0); + break; + } + switch(transferAlgorithm) + { + case TransferAlgorithm_Automatic: + ui->transferAlgorithm->setCurrentIndex(0); + break; + case TransferAlgorithm_Sequential: + ui->transferAlgorithm->setCurrentIndex(1); + break; + case TransferAlgorithm_Parallel: + ui->transferAlgorithm->setCurrentIndex(2); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + ui->transferAlgorithm->setCurrentIndex(0); + break; + } + return true; +} + +//to have interface widget to do modal dialog +void CopyEngine::setInterfacePointer(QWidget * interface) +{ + this->interface=interface; + filters=new Filters(tempWidget); + renamingRules=new RenamingRules(tempWidget); + + if(uiIsInstalled) + { + connect(ui->doRightTransfer, &QCheckBox::toggled, this,&CopyEngine::setRightTransfer); + connect(ui->keepDate, &QCheckBox::toggled, this,&CopyEngine::setKeepDate); + connect(ui->blockSize, static_cast(&QSpinBox::valueChanged), this,&CopyEngine::setBlockSize); + connect(ui->autoStart, &QCheckBox::toggled, this,&CopyEngine::setAutoStart); + connect(ui->doChecksum, &QCheckBox::toggled, this,&CopyEngine::doChecksum_toggled); + connect(ui->checksumIgnoreIfImpossible, &QCheckBox::toggled, this,&CopyEngine::checksumIgnoreIfImpossible_toggled); + connect(ui->checksumOnlyOnError, &QCheckBox::toggled, this,&CopyEngine::checksumOnlyOnError_toggled); + connect(ui->osBuffer, &QCheckBox::toggled, this,&CopyEngine::osBuffer_toggled); + connect(ui->osBufferLimited, &QCheckBox::toggled, this,&CopyEngine::osBufferLimited_toggled); + connect(ui->osBufferLimit, &QSpinBox::editingFinished, this,&CopyEngine::osBufferLimit_editingFinished); + connect(ui->moveTheWholeFolder, &QCheckBox::toggled, this,&CopyEngine::setMoveTheWholeFolder); + connect(ui->deletePartiallyTransferredFiles, &QCheckBox::toggled, this,&CopyEngine::setDeletePartiallyTransferredFiles); + connect(ui->followTheStrictOrder, &QCheckBox::toggled, this,&CopyEngine::setFollowTheStrictOrder); + connect(ui->checkBoxDestinationFolderExists, &QCheckBox::toggled, this,&CopyEngine::setCheckDestinationFolderExists); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + connect(ui->rsync, &QCheckBox::toggled, this,&CopyEngine::setRsync); + #endif + connect(ui->renameTheOriginalDestination, &QCheckBox::toggled, this,&CopyEngine::setRenameTheOriginalDestination); + connect(filters, &Filters::haveNewFilters, this,&CopyEngine::sendNewFilters); + connect(ui->filters, &QPushButton::clicked, this,&CopyEngine::showFilterDialog); + connect(ui->inodeThreads, &QSpinBox::editingFinished, this,&CopyEngine::inodeThreadsFinished); + connect(ui->inodeThreads, static_cast(&QSpinBox::valueChanged), this,&CopyEngine::setInodeThreads); + connect(ui->defaultDestinationFolderBrowse, &QPushButton::clicked, this,&CopyEngine::defaultDestinationFolderBrowse); + + connect(ui->sequentialBuffer, static_cast(&QSpinBox::valueChanged), this,&CopyEngine::setSequentialBuffer); + connect(ui->parallelBuffer, static_cast(&QSpinBox::valueChanged), this,&CopyEngine::setParallelBuffer); + connect(ui->parallelizeIfSmallerThan, static_cast(&QSpinBox::valueChanged), this,&CopyEngine::setParallelizeIfSmallerThan); + connect(ui->comboBoxFolderError, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngine::setFolderError); + connect(ui->comboBoxFolderCollision, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngine::setFolderCollision); + connect(ui->comboBoxFileError, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngine::setFileError); + connect(ui->comboBoxFileCollision, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngine::setFileCollision); + connect(ui->transferAlgorithm, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngine::setTransferAlgorithm); + + if(!connect(renamingRules,&RenamingRules::sendNewRenamingRules,this,&CopyEngine::sendNewRenamingRules)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect sendNewRenamingRules()"); + if(!connect(ui->renamingRules,&QPushButton::clicked,this,&CopyEngine::showRenamingRules)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"unable to connect renamingRules.clicked()"); + } + + filters->setFilters(includeStrings,includeOptions,excludeStrings,excludeOptions); + set_setFilters(includeStrings,includeOptions,excludeStrings,excludeOptions); + + renamingRules->setRenamingRules(firstRenamingRule,otherRenamingRule); + emit send_sendNewRenamingRules(firstRenamingRule,otherRenamingRule); +} + +bool CopyEngine::haveSameSource(const std::vector &sources) +{ + return listThread->haveSameSource(sources); +} + +bool CopyEngine::haveSameDestination(const std::string &destination) +{ + return listThread->haveSameDestination(destination); +} + +bool CopyEngine::newCopy(const std::vector &sources) +{ + if(forcedMode && mode!=Ultracopier::Copy) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The engine is forced to move, you can't copy with it"); + QMessageBox::critical(NULL,QString::fromStdString(facilityEngine->translateText("Internal error")),tr("The engine is forced to move, you can't copy with it")); + return false; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + std::string destination; + if(!defaultDestinationFolder.empty() && QDir(QString::fromStdString(defaultDestinationFolder)).exists()) + destination = defaultDestinationFolder; + else + destination = askDestination(); + if(destination.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Canceled by the user"); + return false; + } + return listThread->newCopy(sources,destination); +} + +bool CopyEngine::newCopy(const std::vector &sources,const std::string &destination) +{ + if(forcedMode && mode!=Ultracopier::Copy) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The engine is forced to move, you can't copy with it"); + QMessageBox::critical(NULL,QString::fromStdString(facilityEngine->translateText("Internal error")),tr("The engine is forced to move, you can't copy with it")); + return false; + } + return listThread->newCopy(sources,destination); +} + +bool CopyEngine::newMove(const std::vector &sources) +{ + if(forcedMode && mode!=Ultracopier::Move) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The engine is forced to copy, you can't move with it"); + QMessageBox::critical(NULL,QString::fromStdString(facilityEngine->translateText("Internal error")),tr("The engine is forced to copy, you can't move with it")); + return false; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + std::string destination; + if(!ui->defaultDestinationFolder->text().isEmpty() && QDir(ui->defaultDestinationFolder->text()).exists()) + destination = ui->defaultDestinationFolder->text().toStdString(); + else + destination = askDestination(); + if(destination.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Canceled by the user"); + return false; + } + return listThread->newMove(sources,destination); +} + +bool CopyEngine::newMove(const std::vector &sources,const std::string &destination) +{ + if(forcedMode && mode!=Ultracopier::Move) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The engine is forced to copy, you can't move with it"); + QMessageBox::critical(NULL,QString::fromStdString(facilityEngine->translateText("Internal error")),tr("The engine is forced to copy, you can't move with it")); + return false; + } + return listThread->newMove(sources,destination); +} + +void CopyEngine::defaultDestinationFolderBrowse() +{ + std::string destination = askDestination(); + if(destination.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Canceled by the user"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(uiIsInstalled) + ui->defaultDestinationFolder->setText(QString::fromStdString(destination)); +} + +std::string CopyEngine::askDestination() +{ + std::string destination = listThread->getUniqueDestinationFolder(); + if(!destination.empty()) + { + QMessageBox::StandardButton button=QMessageBox::question(interface,tr("Destination"),tr("Use the actual destination \"%1\"?") + .arg(QString::fromStdString(destination)), + QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes); + if(button==QMessageBox::Yes) + return destination; + } + destination=QFileDialog::getExistingDirectory(interface,QString::fromStdString(facilityEngine->translateText("Select destination directory")),QStringLiteral(""),QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks).toStdString(); + return destination; +} + +void CopyEngine::newTransferList(const std::string &file) +{ + emit signal_importTransferList(file); +} + +//because direct access to list thread into the main thread can't be do +uint64_t CopyEngine::realByteTransfered() +{ + return size_for_speed; +} + +//speed limitation +bool CopyEngine::supportSpeedLimitation() const +{ + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + return true; + #else + return false; + #endif +} + +/** \brief to sync the transfer list + * Used when the interface is changed, useful to minimize the memory size */ +void CopyEngine::syncTransferList() +{ + listThread->syncTransferList(); +} + +void CopyEngine::set_doChecksum(bool doChecksum) +{ + listThread->set_doChecksum(doChecksum); + if(uiIsInstalled) + { + ui->doChecksum->setChecked(doChecksum); + ui->checksumOnlyOnError->setEnabled(ui->doChecksum->isChecked()); + ui->checksumIgnoreIfImpossible->setEnabled(ui->doChecksum->isChecked()); + } + this->doChecksum=doChecksum; +} + +void CopyEngine::set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible) +{ + listThread->set_checksumIgnoreIfImpossible(checksumIgnoreIfImpossible); + if(uiIsInstalled) + ui->checksumIgnoreIfImpossible->setChecked(checksumIgnoreIfImpossible); + this->checksumIgnoreIfImpossible=checksumIgnoreIfImpossible; +} + +void CopyEngine::set_checksumOnlyOnError(bool checksumOnlyOnError) +{ + listThread->set_checksumOnlyOnError(checksumOnlyOnError); + if(uiIsInstalled) + ui->checksumOnlyOnError->setChecked(checksumOnlyOnError); + this->checksumOnlyOnError=checksumOnlyOnError; +} + +void CopyEngine::set_osBuffer(bool osBuffer) +{ + listThread->set_osBuffer(osBuffer); + if(uiIsInstalled) + { + ui->osBuffer->setChecked(osBuffer); + updateBufferCheckbox(); + } + this->osBuffer=osBuffer; +} + +void CopyEngine::set_osBufferLimited(bool osBufferLimited) +{ + listThread->set_osBufferLimited(osBufferLimited); + if(uiIsInstalled) + { + ui->osBufferLimited->setChecked(osBufferLimited); + updateBufferCheckbox(); + } + this->osBufferLimited=osBufferLimited; +} + +void CopyEngine::set_osBufferLimit(unsigned int osBufferLimit) +{ + emit send_osBufferLimit(osBufferLimit); + if(uiIsInstalled) + ui->osBufferLimit->setValue(osBufferLimit); + this->osBufferLimit=osBufferLimit; +} + +void CopyEngine::updateBufferCheckbox() +{ + ui->osBufferLimited->setEnabled(ui->osBuffer->isChecked()); + ui->osBufferLimit->setEnabled(ui->osBuffer->isChecked() && ui->osBufferLimited->isChecked()); +} + +void CopyEngine::set_setFilters(std::vector includeStrings,std::vector includeOptions,std::vector excludeStrings,std::vector excludeOptions) +{ + if(filters!=NULL) + { + filters->setFilters(includeStrings,includeOptions,excludeStrings,excludeOptions); + emit send_setFilters(filters->getInclude(),filters->getExclude()); + } + this->includeStrings=includeStrings; + this->includeOptions=includeOptions; + this->excludeStrings=excludeStrings; + this->excludeOptions=excludeOptions; +} + +void CopyEngine::setRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule) +{ + sendNewRenamingRules(firstRenamingRule,otherRenamingRule); +} + +bool CopyEngine::userAddFolder(const Ultracopier::CopyMode &mode) +{ + std::string source = QFileDialog::getExistingDirectory(interface,QString::fromStdString(facilityEngine->translateText("Select source directory")), + QStringLiteral(""), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks).toStdString(); + if(source.empty() || source=="") + return false; + std::vector sources; + sources.push_back(source); + if(mode==Ultracopier::Copy) + return newCopy(sources); + else + return newMove(sources); +} + +bool CopyEngine::userAddFile(const Ultracopier::CopyMode &mode) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + QStringList sources = QFileDialog::getOpenFileNames( + interface, + QString::fromStdString(facilityEngine->translateText("Select one or more files to open")), + QStringLiteral(""), + QString::fromStdString(facilityEngine->translateText("All files"))+QStringLiteral(" (*)")); + + std::vector sourcesstd; + unsigned int index=0; + while(index<(unsigned int)sources.size()) + { + sourcesstd.push_back(sources.at(index).toStdString()); + index++; + } + + if(sourcesstd.empty()) + return false; + if(mode==Ultracopier::Copy) + return newCopy(sourcesstd); + else + return newMove(sourcesstd); +} + +void CopyEngine::pause() +{ + emit signal_pause(); +} + +void CopyEngine::resume() +{ + emit signal_resume(); +} + +void CopyEngine::skip(const uint64_t &id) +{ + emit signal_skip(id); +} + +void CopyEngine::cancel() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + stopIt=true; + timerProgression.stop(); + timerActionDone.stop(); + emit tryCancel(); +} + +void CopyEngine::removeItems(const std::vector &ids) +{ + emit signal_removeItems(ids); +} + +void CopyEngine::moveItemsOnTop(const std::vector &ids) +{ + emit signal_moveItemsOnTop(ids); +} + +void CopyEngine::moveItemsUp(const std::vector &ids) +{ + emit signal_moveItemsUp(ids); +} + +void CopyEngine::moveItemsDown(const std::vector &ids) +{ + emit signal_moveItemsDown(ids); +} + +void CopyEngine::moveItemsOnBottom(const std::vector &ids) +{ + emit signal_moveItemsOnBottom(ids); +} + +/** \brief give the forced mode, to export/import transfer list */ +void CopyEngine::forceMode(const Ultracopier::CopyMode &mode) +{ + #ifdef ULTRACOPIER_PLUGIN_RSYNC + if(mode==Ultracopier::Move) + { + listThread->setRsync(false); + rsync=false; + } + if(uiIsInstalled) + ui->rsync->setEnabled(mode==Ultracopier::Copy); + #endif + if(forcedMode) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Mode forced previously"); + QMessageBox::critical(NULL,QString::fromStdString(facilityEngine->translateText("Internal error")),tr("The mode has been forced previously. This is an internal error, please report it")); + return; + } + #ifdef ULTRACOPIER_PLUGIN_RSYNC + if(mode==Ultracopier::Move) + rsync=false; + #endif + if(mode==Ultracopier::Copy) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Force mode to copy"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Force mode to move"); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + if(uiIsInstalled) + ui->rsync->setEnabled(mode==Ultracopier::Copy); + #endif + this->mode=mode; + forcedMode=true; + emit signal_forceMode(mode); +} + +void CopyEngine::exportTransferList() +{ + std::string fileName = QFileDialog::getSaveFileName(interface,QString::fromStdString(facilityEngine->translateText("Save transfer list")),QStringLiteral("transfer-list.lst"),QString::fromStdString(facilityEngine->translateText("Transfer list"))+QStringLiteral(" (*.lst)")).toStdString(); + if(fileName.empty()) + return; + emit signal_exportTransferList(fileName); +} + +void CopyEngine::importTransferList() +{ + std::string fileName = QFileDialog::getOpenFileName(interface,QString::fromStdString(facilityEngine->translateText("Open transfer list")),QStringLiteral("transfer-list.lst"),QString::fromStdString(facilityEngine->translateText("Transfer list"))+QStringLiteral(" (*.lst)")).toStdString(); + if(fileName.empty()) + return; + emit signal_importTransferList(fileName); +} + +void CopyEngine::warningTransferList(const std::string &warning) +{ + QMessageBox::warning(interface,QString::fromStdString(facilityEngine->translateText("Error")),QString::fromStdString(warning)); +} + +void CopyEngine::errorTransferList(const std::string &error) +{ + QMessageBox::critical(interface,QString::fromStdString(facilityEngine->translateText("Error")),QString::fromStdString(error)); +} + +bool CopyEngine::setSpeedLimitation(const int64_t &speedLimitation) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"maxSpeed: "+std::to_string(speedLimitation)); + maxSpeed=speedLimitation; + emit send_speedLimitation(speedLimitation); + return true; +} + +void CopyEngine::setFileCollision(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"action index: "+std::to_string(index)); + if(uiIsInstalled) + if(index!=ui->comboBoxFileCollision->currentIndex()) + ui->comboBoxFileCollision->setCurrentIndex(index); + switch(index) + { + case 0: + alwaysDoThisActionForFileExists=FileExists_NotSet; + break; + case 1: + alwaysDoThisActionForFileExists=FileExists_Skip; + break; + case 2: + alwaysDoThisActionForFileExists=FileExists_Overwrite; + break; + case 3: + alwaysDoThisActionForFileExists=FileExists_OverwriteIfNotSame; + break; + case 4: + alwaysDoThisActionForFileExists=FileExists_OverwriteIfNewer; + break; + case 5: + alwaysDoThisActionForFileExists=FileExists_OverwriteIfOlder; + break; + case 6: + alwaysDoThisActionForFileExists=FileExists_Rename; + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + alwaysDoThisActionForFileExists=FileExists_NotSet; + break; + } + emit signal_setCollisionAction(alwaysDoThisActionForFileExists); +} + +void CopyEngine::setFileError(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"action index: "+std::to_string(index)); + if(uiIsInstalled) + if(index!=ui->comboBoxFileError->currentIndex()) + ui->comboBoxFileError->setCurrentIndex(index); + switch(index) + { + case 0: + alwaysDoThisActionForFileError=FileError_NotSet; + break; + case 1: + alwaysDoThisActionForFileError=FileError_Skip; + break; + case 2: + alwaysDoThisActionForFileError=FileError_PutToEndOfTheList; + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + alwaysDoThisActionForFileError=FileError_NotSet; + break; + } + emit signal_setCollisionAction(alwaysDoThisActionForFileExists); +} + +void CopyEngine::setTransferAlgorithm(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"action index: "+std::to_string(index)); + if(uiIsInstalled) + if(index!=ui->transferAlgorithm->currentIndex()) + ui->transferAlgorithm->setCurrentIndex(index); + switch(index) + { + case 0: + transferAlgorithm=TransferAlgorithm_Automatic; + break; + case 1: + transferAlgorithm=TransferAlgorithm_Sequential; + break; + case 2: + transferAlgorithm=TransferAlgorithm_Parallel; + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + transferAlgorithm=TransferAlgorithm_Automatic; + break; + } + if(transferAlgorithm==TransferAlgorithm_Sequential) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"transferAlgorithm==TransferAlgorithm_Sequential"); + else if(transferAlgorithm==TransferAlgorithm_Automatic) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"transferAlgorithm==TransferAlgorithm_Automatic"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"transferAlgorithm==TransferAlgorithm_Parallel"); + emit signal_setTransferAlgorithm(transferAlgorithm); +} + +void CopyEngine::setRightTransfer(const bool doRightTransfer) +{ + this->doRightTransfer=doRightTransfer; + if(uiIsInstalled) + ui->doRightTransfer->setChecked(doRightTransfer); + listThread->setRightTransfer(doRightTransfer); +} + +//set keep date +void CopyEngine::setKeepDate(const bool keepDate) +{ + this->keepDate=keepDate; + if(uiIsInstalled) + ui->keepDate->setChecked(keepDate); + listThread->setKeepDate(keepDate); +} + +//set block size in KB +void CopyEngine::setBlockSize(const int blockSize) +{ + this->blockSize=blockSize; + if(uiIsInstalled) + { + ui->blockSize->setValue(blockSize); + ui->sequentialBuffer->setSingleStep(blockSize); + ui->parallelBuffer->setSingleStep(blockSize); + } + emit send_blockSize(blockSize); + updatedBlockSize(); +} + +void CopyEngine::setParallelBuffer(int parallelBuffer) +{ + parallelBuffer=round((float)parallelBuffer/(float)blockSize)*blockSize; + this->parallelBuffer=parallelBuffer; + if(uiIsInstalled) + ui->parallelBuffer->setValue(parallelBuffer); + emit send_parallelBuffer(parallelBuffer/blockSize); +} + +void CopyEngine::setSequentialBuffer(int sequentialBuffer) +{ + sequentialBuffer=round((float)sequentialBuffer/(float)blockSize)*blockSize; + this->sequentialBuffer=sequentialBuffer; + if(uiIsInstalled) + ui->sequentialBuffer->setValue(sequentialBuffer); + emit send_sequentialBuffer(sequentialBuffer/blockSize); +} + +void CopyEngine::setParallelizeIfSmallerThan(int parallelizeIfSmallerThan) +{ + this->parallelizeIfSmallerThan=parallelizeIfSmallerThan; + if(uiIsInstalled) + ui->parallelizeIfSmallerThan->setValue(parallelizeIfSmallerThan); + emit send_parallelizeIfSmallerThan(parallelizeIfSmallerThan*1024); +} + +void CopyEngine::setMoveTheWholeFolder(const bool &moveTheWholeFolder) +{ + this->moveTheWholeFolder=moveTheWholeFolder; + if(uiIsInstalled) + ui->moveTheWholeFolder->setChecked(moveTheWholeFolder); + emit send_moveTheWholeFolder(moveTheWholeFolder); +} + +void CopyEngine::setFollowTheStrictOrder(const bool &followTheStrictOrder) +{ + this->followTheStrictOrder=followTheStrictOrder; + if(uiIsInstalled) + ui->followTheStrictOrder->setChecked(followTheStrictOrder); + emit send_followTheStrictOrder(followTheStrictOrder); +} + +void CopyEngine::setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles) +{ + this->deletePartiallyTransferredFiles=deletePartiallyTransferredFiles; + if(uiIsInstalled) + ui->deletePartiallyTransferredFiles->setChecked(deletePartiallyTransferredFiles); + emit send_deletePartiallyTransferredFiles(deletePartiallyTransferredFiles); +} + +void CopyEngine::setInodeThreads(const int &inodeThreads) +{ + this->inodeThreads=inodeThreads; + if(uiIsInstalled) + ui->inodeThreads->setValue(inodeThreads); + emit send_setInodeThreads(inodeThreads); +} + +void CopyEngine::setRenameTheOriginalDestination(const bool &renameTheOriginalDestination) +{ + this->renameTheOriginalDestination=renameTheOriginalDestination; + if(uiIsInstalled) + ui->renameTheOriginalDestination->setChecked(renameTheOriginalDestination); + emit send_setRenameTheOriginalDestination(renameTheOriginalDestination); +} + +void CopyEngine::inodeThreadsFinished() +{ + this->inodeThreads=ui->inodeThreads->value(); + emit send_setInodeThreads(inodeThreads); +} + +//set auto start +void CopyEngine::setAutoStart(const bool autoStart) +{ + this->autoStart=autoStart; + if(uiIsInstalled) + ui->autoStart->setChecked(autoStart); + listThread->setAutoStart(autoStart); +} + +#ifdef ULTRACOPIER_PLUGIN_RSYNC +/// \brief set rsync +void CopyEngine::setRsync(const bool rsync) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"set rsync: "+std::to_string(rsync)); + this->rsync=rsync; + if(uiIsInstalled) + { + ui->rsync->setChecked(rsync); + ui->rsync->setEnabled(forcedMode && mode==Ultracopier::Copy); + ui->label_rsync->setEnabled(forcedMode && mode==Ultracopier::Copy); + } + listThread->setRsync(rsync); +} +#endif + +//set check destination folder +void CopyEngine::setCheckDestinationFolderExists(const bool checkDestinationFolderExists) +{ + this->checkDestinationFolderExists=checkDestinationFolderExists; + if(uiIsInstalled) + ui->checkBoxDestinationFolderExists->setChecked(checkDestinationFolderExists); + listThread->setCheckDestinationFolderExists(checkDestinationFolderExists); +} + +//reset widget +void CopyEngine::resetTempWidget() +{ + uiIsInstalled=false; + tempWidget=NULL; +} + +void CopyEngine::setFolderCollision(int index) +{ + switch(index) + { + case 0: + setComboBoxFolderCollision(FolderExists_NotSet,false); + break; + case 1: + setComboBoxFolderCollision(FolderExists_Merge,false); + break; + case 2: + setComboBoxFolderCollision(FolderExists_Skip,false); + break; + case 3: + setComboBoxFolderCollision(FolderExists_Rename,false); + break; + } +} + +void CopyEngine::setFolderError(int index) +{ + switch(index) + { + case 0: + setComboBoxFolderError(FileError_NotSet,false); + break; + case 1: + setComboBoxFolderError(FileError_Skip,false); + break; + } +} + +//set the translate +void CopyEngine::newLanguageLoaded() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, retranslate the widget options"); + if(tempWidget!=NULL) + { + ui->retranslateUi(tempWidget); + ui->comboBoxFolderError->setItemText(0,tr("Ask")); + ui->comboBoxFolderError->setItemText(1,tr("Skip")); + + ui->comboBoxFolderCollision->setItemText(0,tr("Ask")); + ui->comboBoxFolderCollision->setItemText(1,tr("Merge")); + ui->comboBoxFolderCollision->setItemText(2,tr("Skip")); + ui->comboBoxFolderCollision->setItemText(3,tr("Rename")); + + ui->comboBoxFileError->setItemText(0,tr("Ask")); + ui->comboBoxFileError->setItemText(1,tr("Skip")); + ui->comboBoxFileError->setItemText(2,tr("Put at the end")); + + ui->comboBoxFileCollision->setItemText(0,tr("Ask")); + ui->comboBoxFileCollision->setItemText(1,tr("Skip")); + ui->comboBoxFileCollision->setItemText(2,tr("Overwrite")); + ui->comboBoxFileCollision->setItemText(3,tr("Overwrite if different")); + ui->comboBoxFileCollision->setItemText(4,tr("Overwrite if newer")); + ui->comboBoxFileCollision->setItemText(5,tr("Overwrite if older")); + ui->comboBoxFileCollision->setItemText(6,tr("Rename")); + + ui->transferAlgorithm->setItemText(0,tr("Automatic")); + ui->transferAlgorithm->setItemText(1,tr("Sequential")); + ui->transferAlgorithm->setItemText(2,tr("Parallel")); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"ui not loaded!"); +} + +void CopyEngine::setComboBoxFolderCollision(FolderExistsAction action,bool changeComboBox) +{ + alwaysDoThisActionForFolderExists=action; + emit signal_setFolderCollision(alwaysDoThisActionForFolderExists); + if(!changeComboBox || !uiIsInstalled) + return; + switch(action) + { + case FolderExists_Merge: + ui->comboBoxFolderCollision->setCurrentIndex(1); + break; + case FolderExists_Skip: + ui->comboBoxFolderCollision->setCurrentIndex(2); + break; + case FolderExists_Rename: + ui->comboBoxFolderCollision->setCurrentIndex(3); + break; + default: + ui->comboBoxFolderCollision->setCurrentIndex(0); + break; + } +} + +void CopyEngine::setComboBoxFolderError(FileErrorAction action,bool changeComboBox) +{ + alwaysDoThisActionForFileError=action; + if(!changeComboBox || !uiIsInstalled) + return; + switch(action) + { + case FileError_Skip: + ui->comboBoxFolderError->setCurrentIndex(1); + break; + default: + ui->comboBoxFolderError->setCurrentIndex(0); + break; + } +} + +void CopyEngine::doChecksum_toggled(bool doChecksum) +{ + listThread->set_doChecksum(doChecksum); +} + +void CopyEngine::checksumOnlyOnError_toggled(bool checksumOnlyOnError) +{ + listThread->set_checksumOnlyOnError(checksumOnlyOnError); +} + +void CopyEngine::checksumIgnoreIfImpossible_toggled(bool checksumIgnoreIfImpossible) +{ + listThread->set_checksumIgnoreIfImpossible(checksumIgnoreIfImpossible); +} + +void CopyEngine::osBuffer_toggled(bool osBuffer) +{ + listThread->set_osBuffer(osBuffer); + updateBufferCheckbox(); +} + +void CopyEngine::osBufferLimited_toggled(bool osBufferLimited) +{ + listThread->set_osBufferLimited(osBufferLimited); + updateBufferCheckbox(); +} + +void CopyEngine::osBufferLimit_editingFinished() +{ + emit send_osBufferLimit(ui->osBufferLimit->value()); +} + +void CopyEngine::showFilterDialog() +{ + if(filters!=NULL) + filters->exec(); +} + +void CopyEngine::sendNewFilters() +{ + if(filters!=NULL) + emit send_setFilters(filters->getInclude(),filters->getExclude()); +} + +void CopyEngine::sendNewRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"new filter"); + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + emit send_sendNewRenamingRules(firstRenamingRule,otherRenamingRule); +} + +void CopyEngine::showRenamingRules() +{ + if(renamingRules==NULL) + { + QMessageBox::critical(NULL,tr("Options error"),tr("Options engine is not loaded. Unable to access the filters")); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"options not loaded"); + return; + } + renamingRules->exec(); +} + +void CopyEngine::get_realBytesTransfered(quint64 realBytesTransfered) +{ + size_for_speed=realBytesTransfered; +} + +void CopyEngine::newActionInProgess(Ultracopier::EngineActionInProgress action) +{ + if(action==Ultracopier::Idle) + { + timerProgression.stop(); + timerActionDone.stop(); + } + else + { + timerProgression.start(); + timerActionDone.start(); + } +} + +void CopyEngine::updatedBlockSize() +{ + if(uiIsInstalled) + { + ui->sequentialBuffer->setMinimum(ui->blockSize->value()); + ui->sequentialBuffer->setSingleStep(ui->blockSize->value()); + ui->sequentialBuffer->setMaximum(ui->blockSize->value()*ULTRACOPIER_PLUGIN_MAX_SEQUENTIAL_NUMBER_OF_BLOCK); + ui->parallelBuffer->setMinimum(ui->blockSize->value()); + ui->parallelBuffer->setSingleStep(ui->blockSize->value()); + ui->parallelBuffer->setMaximum(ui->blockSize->value()*ULTRACOPIER_PLUGIN_MAX_PARALLEL_NUMBER_OF_BLOCK); + } + setParallelBuffer(parallelBuffer); + setSequentialBuffer(sequentialBuffer); +} + +void CopyEngine::setCheckDiskSpace(const bool &checkDiskSpace) +{ + this->checkDiskSpace=checkDiskSpace; + if(uiIsInstalled) + ui->checkDiskSpace->setChecked(checkDiskSpace); + listThread->setCheckDiskSpace(checkDiskSpace); +} + +void CopyEngine::setDefaultDestinationFolder(const std::string &defaultDestinationFolder) +{ + this->defaultDestinationFolder=defaultDestinationFolder; + if(uiIsInstalled) + ui->defaultDestinationFolder->setText(QString::fromStdString(defaultDestinationFolder)); +} + +void CopyEngine::setCopyListOrder(const bool &order) +{ + listThread->setCopyListOrder(order); +} + +void CopyEngine::exportErrorIntoTransferList() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"exportErrorIntoTransferList"); + std::string fileName = QFileDialog::getSaveFileName(interface,QString::fromStdString(facilityEngine->translateText("Save transfer list")),QStringLiteral("transfer-list.lst"),QString::fromStdString(facilityEngine->translateText("Transfer list"))+QStringLiteral(" (*.lst)")).toStdString(); + if(fileName.empty()) + return; + emit signal_exportErrorIntoTransferList(fileName); +} diff --git a/plugins/CopyEngine/Ultracopier/CopyEngine.h b/plugins/CopyEngine/Ultracopier/CopyEngine.h new file mode 100644 index 0000000..e5311d8 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CopyEngine.h @@ -0,0 +1,382 @@ +/** \file copyEngine.h +\brief Define the copy engine +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../../interface/PluginInterface_CopyEngine.h" +#include "FileErrorDialog.h" +#include "FileExistsDialog.h" +#include "FolderExistsDialog.h" +#include "FileIsSameDialog.h" +#include "ui_copyEngineOptions.h" +#include "Environment.h" +#include "ListThread.h" +#include "Filters.h" +#include "RenamingRules.h" + +#ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW +#include "DebugDialog.h" +#include +#endif + +#ifndef COPY_ENGINE_H +#define COPY_ENGINE_H + +namespace Ui { + class copyEngineOptions; +} + +/// \brief the implementation of copy engine plugin, manage directly few stuff, else pass to ListThread class. +class CopyEngine : public PluginInterface_CopyEngine +{ + Q_OBJECT +public: + CopyEngine(FacilityInterface * facilityEngine); + ~CopyEngine(); + void connectTheSignalsSlots(); +private: + ListThread * listThread; + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + DebugDialog debugDialogWindow; + #endif + QWidget * tempWidget; + Ui::copyEngineOptions * ui; + bool uiIsInstalled; + QWidget * interface; + Filters * filters; + RenamingRules * renamingRules; + FacilityInterface * facilityEngine; + uint32_t maxSpeed; + bool doRightTransfer; + bool keepDate; + int blockSize; + int parallelBuffer; + int sequentialBuffer; + int parallelizeIfSmallerThan; + bool followTheStrictOrder; + bool deletePartiallyTransferredFiles; + int inodeThreads; + bool renameTheOriginalDestination; + bool moveTheWholeFolder; + bool autoStart; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + bool rsync; + #endif + bool checkDestinationFolderExists; + FileExistsAction alwaysDoThisActionForFileExists; + FileErrorAction alwaysDoThisActionForFileError; + FileErrorAction alwaysDoThisActionForFolderError; + FolderExistsAction alwaysDoThisActionForFolderExists; + TransferAlgorithm transferAlgorithm; + bool dialogIsOpen; + volatile bool stopIt; + std::string defaultDestinationFolder; + /// \brief error queue + struct errorQueueItem + { + TransferThread * transfer; ///< NULL if send by scan thread + ScanFileOrFolder * scan; ///< NULL if send by transfer thread + bool mkPath; + bool rmPath; + QFileInfo inode; + std::string errorString; + ErrorType errorType; + }; + std::vector errorQueue; + /// \brief already exists queue + struct alreadyExistsQueueItem + { + TransferThread * transfer; ///< NULL if send by scan thread + ScanFileOrFolder * scan; ///< NULL if send by transfer thread + QFileInfo source; + QFileInfo destination; + bool isSame; + }; + std::vector alreadyExistsQueue; + uint64_t size_for_speed;//because direct access to list thread into the main thread can't be do + Ultracopier::CopyMode mode; + bool forcedMode; + + bool doChecksum; + bool checksumIgnoreIfImpossible; + bool checksumOnlyOnError; + bool osBuffer; + bool osBufferLimited; + bool checkDiskSpace; + unsigned int osBufferLimit; + std::vector includeStrings,includeOptions,excludeStrings,excludeOptions; + std::string firstRenamingRule; + std::string otherRenamingRule; + + //send action done timer + QTimer timerActionDone; + //send progression timer + QTimer timerProgression; + + QTimer timerUpdateMount; + int putAtBottom;//to keep how many automatic put at bottom have been used +private slots: + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + void updateTheDebugInfo(const std::vector &newList, const std::vector &newList2, const int &numberOfInodeOperation); + #endif + + /************* External call ********************/ + //dialog message + /// \note Can be call without queue because all call will be serialized + void fileAlreadyExistsSlot(QFileInfo source,QFileInfo destination,bool isSame,TransferThread * thread); + /// \note Can be call without queue because all call will be serialized + void errorOnFileSlot(QFileInfo fileInfo, std::string errorString, TransferThread * thread, const ErrorType &errorType); + /// \note Can be call without queue because all call will be serialized + void folderAlreadyExistsSlot(QFileInfo source,QFileInfo destination,bool isSame,ScanFileOrFolder * thread); + /// \note Can be call without queue because all call will be serialized + void errorOnFolderSlot(QFileInfo fileInfo, std::string errorString, ScanFileOrFolder * thread, ErrorType errorType); + //mkpath event + void mkPathErrorOnFolderSlot(QFileInfo, std::string, ErrorType errorType); + + //dialog message + /// \note Can be call without queue because all call will be serialized + void fileAlreadyExists(QFileInfo source,QFileInfo destination,bool isSame,TransferThread * thread,bool isCalledByShowOneNewDialog=false); + /// \note Can be call without queue because all call will be serialized + void errorOnFile(QFileInfo fileInfo, std::string errorString, TransferThread * thread, const ErrorType &errorType, bool isCalledByShowOneNewDialog=false); + /// \note Can be call without queue because all call will be serialized + void folderAlreadyExists(QFileInfo source,QFileInfo destination,bool isSame,ScanFileOrFolder * thread,bool isCalledByShowOneNewDialog=false); + /// \note Can be call without queue because all call will be serialized + void errorOnFolder(QFileInfo fileInfo, std::string errorString, ScanFileOrFolder * thread, ErrorType errorType, bool isCalledByShowOneNewDialog=false); + //mkpath event + void mkPathErrorOnFolder(QFileInfo, std::string, const ErrorType &errorType, bool isCalledByShowOneNewDialog=false); + + //show one new dialog if needed + void showOneNewDialog(); + void sendNewFilters(); + + void doChecksum_toggled(bool); + void checksumOnlyOnError_toggled(bool); + void checksumIgnoreIfImpossible_toggled(bool); + void osBuffer_toggled(bool); + void osBufferLimited_toggled(bool); + void osBufferLimit_editingFinished(); + void showFilterDialog(); + void sendNewRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule); + void showRenamingRules(); + void get_realBytesTransfered(quint64 realBytesTransfered); + void newActionInProgess(Ultracopier::EngineActionInProgress); + void updatedBlockSize(); + void updateBufferCheckbox(); + void haveNeedPutAtBottom(bool needPutAtBottom, const QFileInfo &fileInfo, const std::string &errorString, TransferThread *thread, const ErrorType &errorType); + void missingDiskSpace(std::vector list); + void exportErrorIntoTransferList(); +public: + /** \brief to send the options panel + * \return return false if have not the options + * \param tempWidget the widget to generate on it the options */ + bool getOptionsEngine(QWidget * tempWidget); + /** \brief to have interface widget to do modal dialog + * \param interface to have the widget of the interface, useful for modal dialog */ + void setInterfacePointer(QWidget * interface); + //return empty if multiple + /** \brief compare the current sources of the copy, with the passed arguments + * \param sources the sources list to compares with the current sources list + * \return true if have same sources, else false (or empty) */ + bool haveSameSource(const std::vector &sources); + /** \brief compare the current destination of the copy, with the passed arguments + * \param destination the destination to compares with the current destination + * \return true if have same destination, else false (or empty) */ + bool haveSameDestination(const std::string &destination); + //external soft like file browser have send copy/move list to do + /** \brief send copy without destination, ask the destination + * \param sources the sources list to copy + * \return true if the copy have been accepted */ + bool newCopy(const std::vector &sources); + /** \brief send copy with destination + * \param sources the sources list to copy + * \param destination the destination to copy + * \return true if the copy have been accepted */ + bool newCopy(const std::vector &sources,const std::string &destination); + /** \brief send move without destination, ask the destination + * \param sources the sources list to move + * \return true if the move have been accepted */ + bool newMove(const std::vector &sources); + /** \brief send move without destination, ask the destination + * \param sources the sources list to move + * \param destination the destination to move + * \return true if the move have been accepted */ + bool newMove(const std::vector &sources,const std::string &destination); + /** \brief send the new transfer list + * \param file the transfer list */ + void newTransferList(const std::string &file); + + /** \brief to get byte read, use by Ultracopier for the speed calculation + * real size transfered to right speed calculation */ + uint64_t realByteTransfered(); + /** \brief support speed limitation */ + bool supportSpeedLimitation() const; + + /** \brief to set drives detected + * specific to this copy engine */ + + /** \brief to sync the transfer list + * Used when the interface is changed, useful to minimize the memory size */ + void syncTransferList(); + + void set_doChecksum(bool doChecksum); + void set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible); + void set_checksumOnlyOnError(bool checksumOnlyOnError); + void set_osBuffer(bool osBuffer); + void set_osBufferLimited(bool osBufferLimited); + void set_osBufferLimit(unsigned int osBufferLimit); + void set_setFilters(std::vector includeStrings,std::vector includeOptions,std::vector excludeStrings,std::vector excludeOptions); + void setRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + void setRsync(const bool rsync); + #endif + void setCheckDiskSpace(const bool &checkDiskSpace); + void setDefaultDestinationFolder(const std::string &defaultDestinationFolder); + void setCopyListOrder(const bool &order); + void defaultDestinationFolderBrowse(); + std::string askDestination(); +public slots: + //user ask ask to add folder (add it with interface ask source/destination) + /** \brief add folder called on the interface + * Used by manual adding */ + bool userAddFolder(const Ultracopier::CopyMode &mode); + /** \brief add file called on the interface + * Used by manual adding */ + bool userAddFile(const Ultracopier::CopyMode &mode); + //action on the copy + /// \brief put the transfer in pause + void pause(); + /// \brief resume the transfer + void resume(); + /** \brief skip one transfer entry + * \param id id of the file to remove */ + void skip(const uint64_t &id); + /// \brief cancel all the transfer + void cancel(); + //edit the transfer list + /** \brief remove the selected item + * \param ids ids is the id list of the selected items */ + void removeItems(const std::vector &ids); + /** \brief move on top of the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsOnTop(const std::vector &ids); + /** \brief move up the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsUp(const std::vector &ids); + /** \brief move down the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsDown(const std::vector &ids); + /** \brief move on bottom of the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsOnBottom(const std::vector &ids); + + /** \brief give the forced mode, to export/import transfer list */ + void forceMode(const Ultracopier::CopyMode &mode); + /// \brief export the transfer list into a file + void exportTransferList(); + /// \brief import the transfer list into a file + void importTransferList(); + + /** \brief to set the speed limitation + * -1 if not able, 0 if disabled */ + bool setSpeedLimitation(const int64_t &speedLimitation); + + // specific to this copy engine + + /// \brief set if the rights shoul be keep + void setRightTransfer(const bool doRightTransfer); + /// \brief set keep date + void setKeepDate(const bool keepDate); + /// \brief set block size in KB + void setBlockSize(const int blockSize); + + void setParallelBuffer(int parallelBuffer); + void setSequentialBuffer(int sequentialBuffer); + void setParallelizeIfSmallerThan(int parallelizeIfSmallerThan); + void setMoveTheWholeFolder(const bool &moveTheWholeFolder); + void setFollowTheStrictOrder(const bool &followTheStrictOrder); + void setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles); + void setInodeThreads(const int &inodeThreads); + void setRenameTheOriginalDestination(const bool &renameTheOriginalDestination); + void inodeThreadsFinished(); + + /// \brief set auto start + void setAutoStart(const bool autoStart); + /// \brief set if need check if the destination folder exists + void setCheckDestinationFolderExists(const bool checkDestinationFolderExists); + /// \brief reset widget + void resetTempWidget(); + //autoconnect + void setFolderCollision(int index); + void setFolderError(int index); + void setFileCollision(int index); + void setFileError(int index); + void setTransferAlgorithm(int index); + /// \brief need retranslate the insterface + void newLanguageLoaded(); +private slots: + void setComboBoxFolderCollision(FolderExistsAction action,bool changeComboBox=true); + void setComboBoxFolderError(FileErrorAction action,bool changeComboBox=true); + void warningTransferList(const std::string &warning); + void errorTransferList(const std::string &error); +signals: + //action on the copy + void signal_pause() const; + void signal_resume() const; + void signal_skip(const uint64_t &id) const; + + //edit the transfer list + void signal_removeItems(const std::vector &ids) const; + void signal_moveItemsOnTop(const std::vector &ids) const; + void signal_moveItemsUp(const std::vector &ids) const; + void signal_moveItemsDown(const std::vector &ids) const; + void signal_moveItemsOnBottom(const std::vector &ids) const; + + void signal_forceMode(const Ultracopier::CopyMode &mode) const; + void signal_exportTransferList(const std::string &fileName) const; + void signal_importTransferList(const std::string &fileName) const; + void signal_exportErrorIntoTransferList(const std::string &fileName) const; + + //action + void signal_setTransferAlgorithm(TransferAlgorithm transferAlgorithm) const; + void signal_setCollisionAction(FileExistsAction alwaysDoThisActionForFileExists) const; + void signal_setComboBoxFolderCollision(FolderExistsAction action) const; + void signal_setFolderCollision(FolderExistsAction action) const; + + //internal cancel + void tryCancel() const; + void getNeedPutAtBottom(const QFileInfo &fileInfo,const std::string &errorString,TransferThread * thread,const ErrorType &errorType) const; + + #ifdef ULTRACOPIER_PLUGIN_DEBUG + /// \brief To debug source + void debugInformation(const Ultracopier::DebugLevel &level,std::string fonction,std::string text,std::string file,int ligne) const; + #endif + + //other signals + void queryOneNewDialog() const; + + void send_speedLimitation(const uint64_t &speedLimitation) const; + void send_blockSize(const int &blockSize) const; + void send_osBufferLimit(const unsigned int &osBufferLimit) const; + void send_setFilters(const std::vector &include,const std::vector &exclude) const; + void send_sendNewRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule) const; + void send_parallelBuffer(const int ¶llelBuffer) const; + void send_sequentialBuffer(const int &sequentialBuffer) const; + void send_parallelizeIfSmallerThan(const int ¶llelizeIfSmallerThan) const; + void send_followTheStrictOrder(const bool &followTheStrictOrder) const; + void send_deletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles) const; + void send_setInodeThreads(const int &inodeThreads) const; + void send_moveTheWholeFolder(const bool &moveTheWholeFolder) const; + void send_setRenameTheOriginalDestination(const bool &renameTheOriginalDestination) const; +}; + +#endif // COPY_ENGINE_H diff --git a/plugins/CopyEngine/Ultracopier/CopyEngine.pro b/plugins/CopyEngine/Ultracopier/CopyEngine.pro new file mode 100644 index 0000000..112e999 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CopyEngine.pro @@ -0,0 +1,106 @@ +CONFIG += c++11 +QMAKE_CXXFLAGS+="-std=c++0x -Wall -Wextra" +mac:QMAKE_CXXFLAGS+="-stdlib=libc++" + +QT += widgets xml +DEFINES += UNICODE _UNICODE +TEMPLATE = lib +CONFIG += plugin +win32 { + LIBS += -ladvapi32 +} + +HEADERS = \ + $$PWD/StructEnumDefinition.h \ + $$PWD/StructEnumDefinition_CopyEngine.h \ + $$PWD/DebugEngineMacro.h \ + $$PWD/Variable.h \ + $$PWD/TransferThread.h \ + $$PWD/ReadThread.h \ + $$PWD/WriteThread.h \ + $$PWD/MkPath.h \ + $$PWD/AvancedQFile.h \ + $$PWD/ListThread.h \ + $$PWD/../../../interface/PluginInterface_CopyEngine.h \ + $$PWD/../../../interface/OptionInterface.h \ + $$PWD/../../../interface/FacilityInterface.h \ + $$PWD/../../../cpp11addition.h \ + $$PWD/Filters.h \ + $$PWD/FilterRules.h \ + $$PWD/RenamingRules.h \ + $$PWD/DriveManagement.h \ + $$PWD/CopyEngine.h \ + $$PWD/DebugDialog.h \ + $$PWD/CopyEngineFactory.h \ + $$PWD/FileErrorDialog.h \ + $$PWD/FileExistsDialog.h \ + $$PWD/FileIsSameDialog.h \ + $$PWD/FolderExistsDialog.h \ + $$PWD/ScanFileOrFolder.h \ + $$PWD/DiskSpace.h +SOURCES = \ + $$PWD/TransferThread.cpp \ + $$PWD/ReadThread.cpp \ + $$PWD/WriteThread.cpp \ + $$PWD/MkPath.cpp \ + $$PWD/AvancedQFile.cpp \ + $$PWD/ListThread.cpp \ + $$PWD/../../../cpp11addition.cpp \ + $$PWD/../../../cpp11additionstringtointcpp.cpp \ + $$PWD/Filters.cpp \ + $$PWD/FilterRules.cpp \ + $$PWD/RenamingRules.cpp \ + $$PWD/ListThread_InodeAction.cpp \ + $$PWD/DriveManagement.cpp \ + $$PWD/CopyEngine-collision-and-error.cpp \ + $$PWD/CopyEngine.cpp \ + $$PWD/DebugDialog.cpp \ + $$PWD/CopyEngineFactory.cpp \ + $$PWD/FileErrorDialog.cpp \ + $$PWD/FileExistsDialog.cpp \ + $$PWD/FileIsSameDialog.cpp \ + $$PWD/FolderExistsDialog.cpp \ + $$PWD/ScanFileOrFolder.cpp \ + $$PWD/DiskSpace.cpp +TARGET = $$qtLibraryTarget(copyEngine) +TRANSLATIONS += \ + $$PWD/Languages/ar/translation.ts \ + $$PWD/Languages/de/translation.ts \ + $$PWD/Languages/el/translation.ts \ + $$PWD/Languages/en/translation.ts \ + $$PWD/Languages/es/translation.ts \ + $$PWD/Languages/fr/translation.ts \ + $$PWD/Languages/hi/translation.ts \ + $$PWD/Languages/hu/translation.ts \ + $$PWD/Languages/id/translation.ts \ + $$PWD/Languages/it/translation.ts \ + $$PWD/Languages/ja/translation.ts \ + $$PWD/Languages/ko/translation.ts \ + $$PWD/Languages/nl/translation.ts \ + $$PWD/Languages/no/translation.ts \ + $$PWD/Languages/pl/translation.ts \ + $$PWD/Languages/pt/translation.ts \ + $$PWD/Languages/ru/translation.ts \ + $$PWD/Languages/th/translation.ts \ + $$PWD/Languages/tr/translation.ts \ + $$PWD/Languages/zh/translation.ts + +FORMS += \ + $$PWD/fileErrorDialog.ui \ + $$PWD/fileExistsDialog.ui \ + $$PWD/fileIsSameDialog.ui \ + $$PWD/debugDialog.ui \ + $$PWD/folderExistsDialog.ui \ + $$PWD/Filters.ui \ + $$PWD/FilterRules.ui \ + $$PWD/RenamingRules.ui \ + $$PWD/copyEngineOptions.ui \ + $$PWD/DiskSpace.ui + +OTHER_FILES += \ + $$PWD/informations.xml + +!CONFIG(static) { +RESOURCES += \ + $$PWD/copyEngineResources.qrc +} diff --git a/plugins/CopyEngine/Ultracopier/CopyEngineFactory.cpp b/plugins/CopyEngine/Ultracopier/CopyEngineFactory.cpp new file mode 100644 index 0000000..6507ce2 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CopyEngineFactory.cpp @@ -0,0 +1,700 @@ +/** \file factory.cpp +\brief Define the factory to create new instance +\author alpha_one_x86 */ + +#include +#include +#include +#include +#include + +#include "../../../cpp11addition.h" +#include "CopyEngineFactory.h" + +// The cmath header from MSVC does not contain round() +#if (defined(_WIN64) || defined(_WIN32)) && defined(_MSC_VER) +inline double round(double d) { + return floor( d + 0.5 ); +} +#endif + +CopyEngineFactory::CopyEngineFactory() : + ui(new Ui::copyEngineOptions()) +{ + qRegisterMetaType("FolderExistsAction"); + qRegisterMetaType("FileExistsAction"); + qRegisterMetaType >("QList"); + qRegisterMetaType("TransferStat"); + qRegisterMetaType >("QList"); + qRegisterMetaType("TransferAlgorithm"); + qRegisterMetaType("ActionType"); + qRegisterMetaType("ErrorType"); + qRegisterMetaType("Diskspace"); + qRegisterMetaType >("QList"); + qRegisterMetaType("QFileInfo"); + qRegisterMetaType("Ultracopier::CopyMode"); + qRegisterMetaType >("std::vector"); + + tempWidget=new QWidget(); + ui->setupUi(tempWidget); + ui->toolBox->setCurrentIndex(0); + ui->blockSize->setMaximum(ULTRACOPIER_PLUGIN_MAX_BLOCK_SIZE); + errorFound=false; + optionsEngine=NULL; + filters=new Filters(tempWidget); + renamingRules=new RenamingRules(tempWidget); + + connect(ui->doRightTransfer, &QCheckBox::toggled, this,&CopyEngineFactory::setDoRightTransfer); + connect(ui->keepDate, &QCheckBox::toggled, this,&CopyEngineFactory::setKeepDate); + connect(ui->blockSize, static_cast(&QSpinBox::valueChanged), this,&CopyEngineFactory::setBlockSize); + connect(ui->sequentialBuffer, static_cast(&QSpinBox::valueChanged), this,&CopyEngineFactory::setSequentialBuffer); + connect(ui->parallelBuffer, static_cast(&QSpinBox::valueChanged), this,&CopyEngineFactory::setParallelBuffer); + connect(ui->parallelizeIfSmallerThan, static_cast(&QSpinBox::valueChanged), this,&CopyEngineFactory::setParallelizeIfSmallerThan); + connect(ui->inodeThreads, static_cast(&QSpinBox::valueChanged), this,&CopyEngineFactory::on_inodeThreads_editingFinished); + connect(ui->autoStart, &QCheckBox::toggled, this,&CopyEngineFactory::setAutoStart); + connect(ui->doChecksum, &QCheckBox::toggled, this,&CopyEngineFactory::doChecksum_toggled); + connect(ui->comboBoxFolderError, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngineFactory::setFolderError); + connect(ui->comboBoxFolderCollision, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngineFactory::setFolderCollision); + connect(ui->comboBoxFileError, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngineFactory::setFileError); + connect(ui->comboBoxFileCollision, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngineFactory::setFileCollision); + connect(ui->transferAlgorithm, static_cast(&QComboBox::currentIndexChanged), this,&CopyEngineFactory::setTransferAlgorithm); + connect(ui->checkBoxDestinationFolderExists, &QCheckBox::toggled, this,&CopyEngineFactory::setCheckDestinationFolder); + connect(ui->checksumIgnoreIfImpossible, &QCheckBox::toggled, this,&CopyEngineFactory::checksumIgnoreIfImpossible_toggled); + connect(ui->checksumOnlyOnError, &QCheckBox::toggled, this,&CopyEngineFactory::checksumOnlyOnError_toggled); + connect(ui->osBuffer, &QCheckBox::toggled, this,&CopyEngineFactory::osBuffer_toggled); + connect(ui->osBufferLimited, &QCheckBox::toggled, this,&CopyEngineFactory::osBufferLimited_toggled); + connect(ui->osBufferLimit, &QSpinBox::editingFinished, this,&CopyEngineFactory::osBufferLimit_editingFinished); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + connect(ui->rsync, &QCheckBox::toggled, this,&CopyEngineFactory::setRsync); + #endif + connect(ui->inodeThreads, &QSpinBox::editingFinished, this,&CopyEngineFactory::on_inodeThreads_editingFinished); + connect(ui->osBufferLimited, &QAbstractButton::toggled, this,&CopyEngineFactory::updateBufferCheckbox); + connect(ui->osBuffer, &QAbstractButton::toggled, this,&CopyEngineFactory::updateBufferCheckbox); + connect(ui->moveTheWholeFolder, &QCheckBox::toggled, this,&CopyEngineFactory::moveTheWholeFolder); + connect(ui->followTheStrictOrder, &QCheckBox::toggled, this,&CopyEngineFactory::followTheStrictOrder); + connect(ui->deletePartiallyTransferredFiles,&QCheckBox::toggled, this,&CopyEngineFactory::deletePartiallyTransferredFiles); + connect(ui->renameTheOriginalDestination,&QCheckBox::toggled, this,&CopyEngineFactory::renameTheOriginalDestination); + connect(ui->checkDiskSpace, &QCheckBox::toggled, this,&CopyEngineFactory::checkDiskSpace); + connect(ui->defaultDestinationFolderBrowse,&QPushButton::clicked, this,&CopyEngineFactory::defaultDestinationFolderBrowse); + connect(ui->defaultDestinationFolder,&QLineEdit::editingFinished, this,&CopyEngineFactory::defaultDestinationFolder); + connect(ui->copyListOrder, &QCheckBox::toggled, this,&CopyEngineFactory::copyListOrder); + + connect(filters,&Filters::sendNewFilters,this,&CopyEngineFactory::sendNewFilters); + connect(ui->filters,&QPushButton::clicked,this,&CopyEngineFactory::showFilterDialog); + connect(renamingRules,&RenamingRules::sendNewRenamingRules,this,&CopyEngineFactory::sendNewRenamingRules); + connect(ui->renamingRules,&QPushButton::clicked,this,&CopyEngineFactory::showRenamingRules); + + lunchInitFunction.setInterval(0); + lunchInitFunction.setSingleShot(true); + connect(&lunchInitFunction,&QTimer::timeout,this,&CopyEngineFactory::init,Qt::QueuedConnection); + lunchInitFunction.start(); +} + +CopyEngineFactory::~CopyEngineFactory() +{ + delete renamingRules; + delete filters; + delete ui; +} + +void CopyEngineFactory::init() +{ +} + +PluginInterface_CopyEngine * CopyEngineFactory::getInstance() +{ + CopyEngine *realObject=new CopyEngine(facilityEngine); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + connect(realObject,&CopyEngine::debugInformation,this,&CopyEngineFactory::debugInformation); + #endif + realObject->connectTheSignalsSlots(); + PluginInterface_CopyEngine * newTransferEngine=realObject; + connect(this,&CopyEngineFactory::reloadLanguage,realObject,&CopyEngine::newLanguageLoaded); + realObject->setRightTransfer(ui->doRightTransfer->isChecked()); + realObject->setKeepDate(ui->keepDate->isChecked()); + realObject->setBlockSize(ui->blockSize->value()); + realObject->setAutoStart(ui->autoStart->isChecked()); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + realObject->setRsync(ui->rsync->isChecked()); + #endif + realObject->setFolderCollision(ui->comboBoxFolderCollision->currentIndex()); + realObject->setFolderError(ui->comboBoxFolderError->currentIndex()); + realObject->setFileCollision(ui->comboBoxFileCollision->currentIndex()); + realObject->setFileError(ui->comboBoxFileError->currentIndex()); + realObject->setTransferAlgorithm(ui->transferAlgorithm->currentIndex()); + realObject->setCheckDestinationFolderExists(ui->checkBoxDestinationFolderExists->isChecked()); + realObject->set_doChecksum(ui->doChecksum->isChecked()); + realObject->set_checksumIgnoreIfImpossible(ui->checksumIgnoreIfImpossible->isChecked()); + realObject->set_checksumOnlyOnError(ui->checksumOnlyOnError->isChecked()); + realObject->set_osBuffer(ui->osBuffer->isChecked()); + realObject->set_osBufferLimited(ui->osBufferLimited->isChecked()); + realObject->set_osBufferLimit(ui->osBufferLimit->value()); + realObject->set_setFilters(includeStrings,includeOptions,excludeStrings,excludeOptions); + realObject->setRenamingRules(firstRenamingRule,otherRenamingRule); + realObject->setSequentialBuffer(ui->sequentialBuffer->value()); + realObject->setParallelBuffer(ui->parallelBuffer->value()); + realObject->setParallelizeIfSmallerThan(ui->parallelizeIfSmallerThan->value()); + realObject->setMoveTheWholeFolder(ui->moveTheWholeFolder->isChecked()); + realObject->setFollowTheStrictOrder(ui->followTheStrictOrder->isChecked()); + realObject->setDeletePartiallyTransferredFiles(ui->deletePartiallyTransferredFiles->isChecked()); + realObject->setInodeThreads(ui->inodeThreads->value()); + realObject->setRenameTheOriginalDestination(ui->renameTheOriginalDestination->isChecked()); + realObject->setCheckDiskSpace(ui->checkDiskSpace->isChecked()); + realObject->setDefaultDestinationFolder(ui->defaultDestinationFolder->text().toStdString()); + realObject->setCopyListOrder(ui->copyListOrder->isChecked()); + return newTransferEngine; +} + +void CopyEngineFactory::setResources(OptionInterface * options,const std::string &writePath,const std::string &pluginPath,FacilityInterface * facilityInterface,const bool &portableVersion) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, writePath: "+writePath+", pluginPath:"+pluginPath); + this->facilityEngine=facilityInterface; + Q_UNUSED(portableVersion); + #ifndef ULTRACOPIER_PLUGIN_DEBUG + Q_UNUSED(writePath); + Q_UNUSED(pluginPath); + #endif + #if ! defined (Q_CC_GNU) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("Unable to change date time of files, only gcc is supported")); + #endif + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,COMPILERINFO); + #if defined (ULTRACOPIER_PLUGIN_CHECKLISTTYPE) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"CHECK LIST TYPE set"); + #else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"CHECK LIST TYPE not set"); + #endif + if(options!=NULL) + { + //load the options + std::vector > KeysList; + KeysList.push_back(std::pair("doRightTransfer","true")); + #ifndef Q_OS_LINUX + KeysList.push_back(std::pair("keepDate","false")); + #else + KeysList.push_back(std::pair("keepDate","true")); + #endif + KeysList.push_back(std::pair("blockSize",std::to_string(ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE))); + uint32_t sequentialBuffer=ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*ULTRACOPIER_PLUGIN_DEFAULT_SEQUENTIAL_NUMBER_OF_BLOCK; + uint32_t parallelBuffer=ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*ULTRACOPIER_PLUGIN_DEFAULT_PARALLEL_NUMBER_OF_BLOCK; + //to prevent swap and other bad effect, only under windows and unix for now + #if defined(Q_OS_WIN32) or (defined(Q_OS_LINUX) and defined(_SC_PHYS_PAGES)) + size_t max_memory=getTotalSystemMemory()/1024; + if(max_memory>0) + { + if(sequentialBuffer>(max_memory/10)) + sequentialBuffer=max_memory/10; + if(parallelBuffer>(max_memory/100)) + parallelBuffer=max_memory/100; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("detected memory: %1MB").arg(max_memory/1024).toStdString()); + #endif + KeysList.push_back(std::pair("sequentialBuffer",std::to_string(sequentialBuffer))); + KeysList.push_back(std::pair("parallelBuffer",std::to_string(parallelBuffer))); + KeysList.push_back(std::pair("parallelizeIfSmallerThan",std::to_string(128)));//128KB, better for modern hardware: Multiple queue en linux, SSD, ... + KeysList.push_back(std::pair("autoStart","true")); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + KeysList.push_back(std::pair("rsync","true")); + #endif + KeysList.push_back(std::pair("folderError",std::to_string(0))); + KeysList.push_back(std::pair("folderCollision",std::to_string(0))); + KeysList.push_back(std::pair("fileError",std::to_string(2))); + KeysList.push_back(std::pair("fileCollision",std::to_string(0))); + KeysList.push_back(std::pair("transferAlgorithm",std::to_string(0))); + KeysList.push_back(std::pair("checkDestinationFolder","true")); + KeysList.push_back(std::pair("includeStrings","")); + KeysList.push_back(std::pair("includeOptions","")); + KeysList.push_back(std::pair("excludeStrings","")); + KeysList.push_back(std::pair("excludeOptions","")); + KeysList.push_back(std::pair("doChecksum","false")); + KeysList.push_back(std::pair("checksumIgnoreIfImpossible","true")); + KeysList.push_back(std::pair("checksumOnlyOnError","true")); + KeysList.push_back(std::pair("osBuffer","false")); + KeysList.push_back(std::pair("firstRenamingRule","")); + KeysList.push_back(std::pair("otherRenamingRule","")); + KeysList.push_back(std::pair("osBufferLimited","false")); + KeysList.push_back(std::pair("osBufferLimit",std::to_string(512))); + KeysList.push_back(std::pair("deletePartiallyTransferredFiles","true")); + KeysList.push_back(std::pair("moveTheWholeFolder","true")); + KeysList.push_back(std::pair("followTheStrictOrder","false")); + KeysList.push_back(std::pair("renameTheOriginalDestination","false")); + KeysList.push_back(std::pair("checkDiskSpace","true")); + KeysList.push_back(std::pair("defaultDestinationFolder","")); + KeysList.push_back(std::pair("inodeThreads",std::to_string(1))); + KeysList.push_back(std::pair("copyListOrder","false")); + options->addOptionGroup(KeysList); + #if ! defined (Q_CC_GNU) + ui->keepDate->setEnabled(false); + ui->keepDate->setToolTip(QStringLiteral("Not supported with this compiler")); + #endif + ui->doRightTransfer->setChecked(stringtobool(options->getOptionValue("doRightTransfer"))); + ui->keepDate->setChecked(stringtobool(options->getOptionValue("keepDate"))); + ui->blockSize->setValue(stringtouint32(options->getOptionValue("blockSize")));//keep before sequentialBuffer and parallelBuffer + ui->autoStart->setChecked(stringtobool(options->getOptionValue("autoStart"))); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + ui->rsync->setChecked(stringtobool(options->getOptionValue("rsync"))); + #else + ui->label_rsync->setVisible(false); + ui->rsync->setVisible(false); + #endif + ui->comboBoxFolderError->setCurrentIndex(stringtouint32(options->getOptionValue("folderError"))); + ui->comboBoxFolderCollision->setCurrentIndex(stringtouint32(options->getOptionValue("folderCollision"))); + ui->comboBoxFileError->setCurrentIndex(stringtouint32(options->getOptionValue("fileError"))); + ui->comboBoxFileCollision->setCurrentIndex(stringtouint32(options->getOptionValue("fileCollision"))); + ui->transferAlgorithm->setCurrentIndex(stringtouint32(options->getOptionValue("transferAlgorithm"))); + ui->checkBoxDestinationFolderExists->setChecked(stringtobool(options->getOptionValue("checkDestinationFolder"))); + ui->parallelizeIfSmallerThan->setValue(stringtouint32(options->getOptionValue("parallelizeIfSmallerThan"))); + ui->sequentialBuffer->setValue(stringtouint32(options->getOptionValue("sequentialBuffer"))); + ui->parallelBuffer->setValue(stringtouint32(options->getOptionValue("parallelBuffer"))); + ui->sequentialBuffer->setSingleStep(ui->blockSize->value()); + ui->parallelBuffer->setSingleStep(ui->blockSize->value()); + ui->deletePartiallyTransferredFiles->setChecked(stringtobool(options->getOptionValue("deletePartiallyTransferredFiles"))); + ui->moveTheWholeFolder->setChecked(stringtobool(options->getOptionValue("moveTheWholeFolder"))); + ui->followTheStrictOrder->setChecked(stringtobool(options->getOptionValue("followTheStrictOrder"))); + ui->inodeThreads->setValue(stringtouint32(options->getOptionValue("inodeThreads"))); + ui->renameTheOriginalDestination->setChecked(stringtobool(options->getOptionValue("renameTheOriginalDestination"))); + ui->checkDiskSpace->setChecked(stringtobool(options->getOptionValue("checkDiskSpace"))); + ui->defaultDestinationFolder->setText(QString::fromStdString(options->getOptionValue("defaultDestinationFolder"))); + + ui->doChecksum->setChecked(stringtobool(options->getOptionValue("doChecksum"))); + ui->checksumIgnoreIfImpossible->setChecked(stringtobool(options->getOptionValue("checksumIgnoreIfImpossible"))); + ui->checksumOnlyOnError->setChecked(stringtobool(options->getOptionValue("checksumOnlyOnError"))); + + ui->osBuffer->setChecked(stringtobool(options->getOptionValue("osBuffer"))); + ui->osBufferLimited->setChecked(stringtobool(options->getOptionValue("osBufferLimited"))); + ui->osBufferLimit->setValue(stringtouint32(options->getOptionValue("osBufferLimit"))); + //ui->autoStart->setChecked(options->getOptionValue("autoStart").toBool());//moved from options(), wrong previous place + includeStrings=stringtostringlist(options->getOptionValue("includeStrings")); + includeOptions=stringtostringlist(options->getOptionValue("includeOptions")); + excludeStrings=stringtostringlist(options->getOptionValue("excludeStrings")); + excludeOptions=stringtostringlist(options->getOptionValue("excludeOptions")); + filters->setFilters(includeStrings,includeOptions,excludeStrings,excludeOptions); + firstRenamingRule=options->getOptionValue("firstRenamingRule"); + otherRenamingRule=options->getOptionValue("otherRenamingRule"); + renamingRules->setRenamingRules(firstRenamingRule,otherRenamingRule); + + ui->checksumOnlyOnError->setEnabled(ui->doChecksum->isChecked()); + ui->checksumIgnoreIfImpossible->setEnabled(ui->doChecksum->isChecked()); + ui->copyListOrder->setChecked(stringtobool(options->getOptionValue("copyListOrder"))); + + updateBufferCheckbox(); + optionsEngine=options; + + updatedBlockSize(); + } +} + +std::vector CopyEngineFactory::supportedProtocolsForTheSource() const +{ + std::vector l; + l.push_back("file"); + return l; +} + +std::vector CopyEngineFactory::supportedProtocolsForTheDestination() const +{ + std::vector l; + l.push_back("file"); + return l; +} + +Ultracopier::CopyType CopyEngineFactory::getCopyType() +{ + return Ultracopier::FileAndFolder; +} + +Ultracopier::TransferListOperation CopyEngineFactory::getTransferListOperation() +{ + return Ultracopier::TransferListOperation_ImportExport; +} + +bool CopyEngineFactory::canDoOnlyCopy() const +{ + return false; +} + +void CopyEngineFactory::resetOptions() +{ +} + +QWidget * CopyEngineFactory::options() +{ + return tempWidget; +} + +void CopyEngineFactory::setDoRightTransfer(bool doRightTransfer) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("doRightTransfer",booltostring(doRightTransfer)); +} + +void CopyEngineFactory::setKeepDate(bool keepDate) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("keepDate",booltostring(keepDate)); +} + +void CopyEngineFactory::setBlockSize(int blockSize) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("blockSize",std::to_string(blockSize)); + updatedBlockSize(); +} + +void CopyEngineFactory::setParallelBuffer(int parallelBuffer) +{ + if(optionsEngine!=NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + parallelBuffer=round((float)parallelBuffer/(float)ui->blockSize->value())*ui->blockSize->value(); + ui->parallelBuffer->setValue(parallelBuffer); + optionsEngine->setOptionValue("parallelBuffer",std::to_string(parallelBuffer)); + } +} + +void CopyEngineFactory::setSequentialBuffer(int sequentialBuffer) +{ + if(optionsEngine!=NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + sequentialBuffer=round((float)sequentialBuffer/(float)ui->blockSize->value())*ui->blockSize->value(); + ui->sequentialBuffer->setValue(sequentialBuffer); + optionsEngine->setOptionValue("sequentialBuffer",std::to_string(sequentialBuffer)); + } +} + +void CopyEngineFactory::setParallelizeIfSmallerThan(int parallelizeIfSmallerThan) +{ + if(optionsEngine!=NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + optionsEngine->setOptionValue("parallelizeIfSmallerThan",std::to_string(parallelizeIfSmallerThan)); + } +} + +void CopyEngineFactory::setAutoStart(bool autoStart) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("autoStart",booltostring(autoStart)); +} + +void CopyEngineFactory::setFolderCollision(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("folderCollision",std::to_string(index)); +} + +void CopyEngineFactory::setFolderError(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("folderError",std::to_string(index)); +} + +void CopyEngineFactory::setTransferAlgorithm(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("transferAlgorithm",std::to_string(index)); +} + +void CopyEngineFactory::setCheckDestinationFolder() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("checkDestinationFolder",booltostring(ui->checkBoxDestinationFolderExists->isChecked())); +} + +void CopyEngineFactory::newLanguageLoaded() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, retranslate the widget options"); + OptionInterface * optionsEngine=this->optionsEngine; + this->optionsEngine=NULL; + ui->retranslateUi(tempWidget); + ui->comboBoxFolderError->setItemText(0,tr("Ask")); + ui->comboBoxFolderError->setItemText(1,tr("Skip")); + + ui->comboBoxFolderCollision->setItemText(0,tr("Ask")); + ui->comboBoxFolderCollision->setItemText(1,tr("Merge")); + ui->comboBoxFolderCollision->setItemText(2,tr("Skip")); + ui->comboBoxFolderCollision->setItemText(3,tr("Rename")); + + ui->comboBoxFileError->setItemText(0,tr("Ask")); + ui->comboBoxFileError->setItemText(1,tr("Skip")); + ui->comboBoxFileError->setItemText(2,tr("Put at the end")); + + ui->comboBoxFileCollision->setItemText(0,tr("Ask")); + ui->comboBoxFileCollision->setItemText(1,tr("Skip")); + ui->comboBoxFileCollision->setItemText(2,tr("Overwrite")); + ui->comboBoxFileCollision->setItemText(3,tr("Overwrite if different")); + ui->comboBoxFileCollision->setItemText(4,tr("Overwrite if newer")); + ui->comboBoxFileCollision->setItemText(5,tr("Overwrite if older")); + ui->comboBoxFileCollision->setItemText(6,tr("Rename")); + + ui->transferAlgorithm->setItemText(0,tr("Automatic")); + ui->transferAlgorithm->setItemText(1,tr("Sequential")); + ui->transferAlgorithm->setItemText(2,tr("Parallel")); + if(optionsEngine!=NULL) + { + filters->newLanguageLoaded(); + renamingRules->newLanguageLoaded(); + } + emit reloadLanguage(); + this->optionsEngine=optionsEngine; +} + +void CopyEngineFactory::doChecksum_toggled(bool doChecksum) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("doChecksum",booltostring(doChecksum)); +} + +void CopyEngineFactory::checksumOnlyOnError_toggled(bool checksumOnlyOnError) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("checksumOnlyOnError",booltostring(checksumOnlyOnError)); +} + +void CopyEngineFactory::osBuffer_toggled(bool osBuffer) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("osBuffer",booltostring(osBuffer)); + ui->osBufferLimit->setEnabled(ui->osBuffer->isChecked() && ui->osBufferLimited->isChecked()); +} + +void CopyEngineFactory::osBufferLimited_toggled(bool osBufferLimited) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("osBufferLimited",booltostring(osBufferLimited)); + ui->osBufferLimit->setEnabled(ui->osBuffer->isChecked() && ui->osBufferLimited->isChecked()); +} + +void CopyEngineFactory::osBufferLimit_editingFinished() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the spinbox have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("osBufferLimit",std::to_string(ui->osBufferLimit->value())); +} + +void CopyEngineFactory::showFilterDialog() +{ + if(optionsEngine==NULL) + { + QMessageBox::critical(NULL,tr("Options error"),tr("Options engine is not loaded. Unable to access the filters")); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"options not loaded"); + return; + } + filters->exec(); +} + +void CopyEngineFactory::sendNewFilters(const std::vector &includeStrings,const std::vector &includeOptions,const std::vector &excludeStrings,const std::vector &excludeOptions) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"new filter"); + this->includeStrings=includeStrings; + this->includeOptions=includeOptions; + this->excludeStrings=excludeStrings; + this->excludeOptions=excludeOptions; + if(optionsEngine!=NULL) + { + optionsEngine->setOptionValue("includeStrings",stringlisttostring(includeStrings)); + optionsEngine->setOptionValue("includeOptions",stringlisttostring(includeOptions)); + optionsEngine->setOptionValue("excludeStrings",stringlisttostring(excludeStrings)); + optionsEngine->setOptionValue("excludeOptions",stringlisttostring(excludeOptions)); + } +} + +void CopyEngineFactory::sendNewRenamingRules(const std::string &firstRenamingRule,const std::string &otherRenamingRule) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"new filter"); + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + if(optionsEngine!=NULL) + { + optionsEngine->setOptionValue("firstRenamingRule",firstRenamingRule); + optionsEngine->setOptionValue("otherRenamingRule",otherRenamingRule); + } +} + +void CopyEngineFactory::showRenamingRules() +{ + if(optionsEngine==NULL) + { + QMessageBox::critical(NULL,tr("Options error"),tr("Options engine is not loaded, can't access to the filters")); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"options not loaded"); + return; + } + renamingRules->exec(); +} + +void CopyEngineFactory::updateBufferCheckbox() +{ + ui->osBufferLimited->setEnabled(ui->osBuffer->isChecked()); + ui->osBufferLimit->setEnabled(ui->osBuffer->isChecked() && ui->osBufferLimited->isChecked()); +} + +void CopyEngineFactory::checksumIgnoreIfImpossible_toggled(bool checksumIgnoreIfImpossible) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("checksumIgnoreIfImpossible",booltostring(checksumIgnoreIfImpossible)); +} + +void CopyEngineFactory::setFileCollision(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"action index: "+std::to_string(index)); + if(optionsEngine==NULL) + return; + switch(index) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + optionsEngine->setOptionValue("fileCollision",std::to_string(index)); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + break; + } +} + +void CopyEngineFactory::setFileError(int index) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"action index: "+std::to_string(index)); + if(optionsEngine==NULL) + return; + switch(index) + { + case 0: + case 1: + case 2: + optionsEngine->setOptionValue("fileError",std::to_string(index)); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error, unknow index, ignored"); + break; + } +} + +void CopyEngineFactory::updatedBlockSize() +{ + ui->sequentialBuffer->setMinimum(ui->blockSize->value()); + ui->sequentialBuffer->setSingleStep(ui->blockSize->value()); + ui->sequentialBuffer->setMaximum(ui->blockSize->value()*ULTRACOPIER_PLUGIN_MAX_SEQUENTIAL_NUMBER_OF_BLOCK); + ui->parallelBuffer->setMinimum(ui->blockSize->value()); + ui->parallelBuffer->setSingleStep(ui->blockSize->value()); + ui->parallelBuffer->setMaximum(ui->blockSize->value()*ULTRACOPIER_PLUGIN_MAX_PARALLEL_NUMBER_OF_BLOCK); + setParallelBuffer(ui->parallelBuffer->value()); + setSequentialBuffer(ui->sequentialBuffer->value()); +} + +void CopyEngineFactory::deletePartiallyTransferredFiles(bool checked) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("deletePartiallyTransferredFiles",booltostring(checked)); +} + +void CopyEngineFactory::renameTheOriginalDestination(bool checked) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("renameTheOriginalDestination",booltostring(checked)); +} + +void CopyEngineFactory::checkDiskSpace(bool checked) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("checkDiskSpace",booltostring(checked)); +} + +void CopyEngineFactory::defaultDestinationFolderBrowse() +{ + QString destination = QFileDialog::getExistingDirectory(ui->defaultDestinationFolder, + QString::fromStdString(facilityEngine->translateText("Select destination directory")), + "",QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + if(destination.isEmpty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Canceled by the user"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + ui->defaultDestinationFolder->setText(destination); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("defaultDestinationFolder",destination.toStdString()); +} + +void CopyEngineFactory::defaultDestinationFolder() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("defaultDestinationFolder",ui->defaultDestinationFolder->text().toStdString()); +} + +void CopyEngineFactory::followTheStrictOrder(bool checked) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("followTheStrictOrder",booltostring(checked)); +} + +void CopyEngineFactory::moveTheWholeFolder(bool checked) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("moveTheWholeFolder",booltostring(checked)); +} + +void CopyEngineFactory::on_inodeThreads_editingFinished() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the spinbox have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("inodeThreads",std::to_string(ui->inodeThreads->value())); +} + +#ifdef Q_OS_WIN32 +size_t CopyEngineFactory::getTotalSystemMemory() +{ + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + GlobalMemoryStatusEx(&status); + return status.ullTotalPhys; +} +#endif + +#ifdef Q_OS_LINUX +size_t CopyEngineFactory::getTotalSystemMemory() +{ + long pages = sysconf(_SC_PHYS_PAGES); + long page_size = sysconf(_SC_PAGE_SIZE); + return pages * page_size; +} +#endif + +#ifdef ULTRACOPIER_PLUGIN_RSYNC +void CopyEngineFactory::setRsync(bool rsync) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("rsync",std::to_string(rsync)); +} +#endif + +void CopyEngineFactory::copyListOrder(bool checked) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the value have changed"); + if(optionsEngine!=NULL) + optionsEngine->setOptionValue("copyListOrder",booltostring(checked)); +} diff --git a/plugins/CopyEngine/Ultracopier/CopyEngineFactory.h b/plugins/CopyEngine/Ultracopier/CopyEngineFactory.h new file mode 100644 index 0000000..59c4208 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/CopyEngineFactory.h @@ -0,0 +1,133 @@ +/** \file factory.h +\brief Define the factory to create new instance +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include "StructEnumDefinition_CopyEngine.h" + +#include +#include +#include +#include +#include +#include + +#include "../../../interface/PluginInterface_CopyEngine.h" +#include "qstorageinfo.h" +#include "StructEnumDefinition.h" +#include "ui_copyEngineOptions.h" +#include "CopyEngine.h" +#include "Environment.h" +#include "Filters.h" +#include "RenamingRules.h" + +#ifdef Q_OS_WIN32 + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include +#endif +#ifdef Q_OS_LINUX + #include +#endif + +#ifndef FACTORY_H +#define FACTORY_H + +namespace Ui { + class copyEngineOptions; +} + +/** \brief to generate copy engine instance */ +class CopyEngineFactory : public PluginInterface_CopyEngineFactory +{ + Q_OBJECT + #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT + Q_PLUGIN_METADATA(IID "first-world.info.ultracopier.PluginInterface.CopyEngineFactory/1.0.0.0" FILE "plugin.json") + Q_INTERFACES(PluginInterface_CopyEngineFactory) + #endif +public: + CopyEngineFactory(); + ~CopyEngineFactory(); + /// \brief to return the instance of the copy engine + PluginInterface_CopyEngine * getInstance(); + /// \brief set the resources, to store options, to have facilityInterface + void setResources(OptionInterface * options,const std::string &writePath,const std::string &pluginPath,FacilityInterface * facilityInterface,const bool &portableVersion); + //get mode allowed + /// \brief define if can copy file, folder or both + Ultracopier::CopyType getCopyType(); + /// \brief to return which kind of transfer list operation is supported + Ultracopier::TransferListOperation getTransferListOperation(); + /// \brief define if can only copy, or copy and move + bool canDoOnlyCopy() const; + /// \brief to get the supported protocols for the source + std::vector supportedProtocolsForTheSource() const; + /// \brief to get the supported protocols for the destination + std::vector supportedProtocolsForTheDestination() const; + /// \brief to get the options of the copy engine + QWidget * options(); + +private: + Ui::copyEngineOptions *ui; + QWidget* tempWidget; + OptionInterface * optionsEngine; + bool errorFound; + FacilityInterface * facilityEngine; + Filters *filters; + RenamingRules *renamingRules; + QStorageInfo storageInfo; + QTimer lunchInitFunction; + std::vector includeStrings,includeOptions,excludeStrings,excludeOptions; + std::string firstRenamingRule,otherRenamingRule; + +#if defined(Q_OS_WIN32) || (defined(Q_OS_LINUX) && defined(_SC_PHYS_PAGES)) + static size_t getTotalSystemMemory(); +#endif +private slots: + void init(); + void setDoRightTransfer(bool doRightTransfer); + void setKeepDate(bool keepDate); + void setBlockSize(int blockSize); + void setParallelBuffer(int parallelBuffer); + void setSequentialBuffer(int sequentialBuffer); + void setParallelizeIfSmallerThan(int parallelizeIfSmallerThan); + void setAutoStart(bool autoStart); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + void setRsync(bool rsync); + #endif + void setFolderCollision(int index); + void setFolderError(int index); + void setTransferAlgorithm(int index); + void setCheckDestinationFolder(); + void showFilterDialog(); + void sendNewFilters(const std::vector &includeStrings,const std::vector &includeOptions, + const std::vector &excludeStrings,const std::vector &excludeOptions); + void doChecksum_toggled(bool); + void checksumOnlyOnError_toggled(bool); + void osBuffer_toggled(bool); + void osBufferLimited_toggled(bool); + void osBufferLimit_editingFinished(); + void checksumIgnoreIfImpossible_toggled(bool); + void sendNewRenamingRules(const std::string &firstRenamingRule, const std::string &otherRenamingRule); + void showRenamingRules(); + void updateBufferCheckbox(); + void setFileCollision(int index); + void setFileError(int index); + void updatedBlockSize(); + void deletePartiallyTransferredFiles(bool checked); + void renameTheOriginalDestination(bool checked); + void checkDiskSpace(bool checked); + void defaultDestinationFolderBrowse(); + void defaultDestinationFolder(); + void followTheStrictOrder(bool checked); + void moveTheWholeFolder(bool checked); + void on_inodeThreads_editingFinished(); + void copyListOrder(bool checked); +public slots: + void resetOptions(); + void newLanguageLoaded(); +signals: + void reloadLanguage() const; +}; + +#endif // FACTORY_H diff --git a/plugins/CopyEngine/Ultracopier/DebugDialog.cpp b/plugins/CopyEngine/Ultracopier/DebugDialog.cpp new file mode 100644 index 0000000..0b3fec4 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DebugDialog.cpp @@ -0,0 +1,54 @@ +/** \file debugDialog.cpp +\brief Define the dialog to have debug information +\author alpha_one_x86 */ + +#include "DebugDialog.h" +#include "ui_debugDialog.h" + +#ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + +DebugDialog::DebugDialog(QWidget *parent) : + QWidget(parent), + ui(new Ui::debugDialog) +{ + ui->setupUi(this); +} + +DebugDialog::~DebugDialog() +{ + delete ui; +} + +void DebugDialog::setTransferList(const std::vector &list) +{ + ui->tranferList->clear(); + unsigned int index=0; + while(indextranferList->addItem(QString::fromStdString(list.at(index))); + index++; + } +} + +void DebugDialog::setActiveTransfer(const int &activeTransfer) +{ + ui->spinBoxActiveTransfer->setValue(activeTransfer); +} + +void DebugDialog::setInodeUsage(const int &inodeUsage) +{ + ui->spinBoxNumberOfInode->setValue(inodeUsage); +} + +void DebugDialog::setTransferThreadList(const std::vector &list) +{ + ui->transferThreadList->clear(); + unsigned int index=0; + while(indextransferThreadList->addItem(QString::fromStdString(list.at(index))); + index++; + } +} + +#endif diff --git a/plugins/CopyEngine/Ultracopier/DebugDialog.h b/plugins/CopyEngine/Ultracopier/DebugDialog.h new file mode 100644 index 0000000..c84cfaa --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DebugDialog.h @@ -0,0 +1,39 @@ +/** \file debugDialog.h +\brief Define the dialog to have debug information +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef DEBUGDAILOG_H +#define DEBUGDAILOG_H + +#include "Environment.h" + +#ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW +#include + +namespace Ui { + class debugDialog; +} + +/// \brief class to the dialog to have debug information +class DebugDialog : public QWidget +{ + Q_OBJECT +public: + explicit DebugDialog(QWidget *parent = 0); + ~DebugDialog(); + /// \brief to set the transfer list, limited in result to not slow down the application + void setTransferList(const std::vector &list); + /// \brief show the transfer thread, it show be a thread pool in normal time + void setTransferThreadList(const std::vector &list); + /// \brief show how many transfer is active + void setActiveTransfer(const int &activeTransfer); + /// \brief show many many inode is manipulated + void setInodeUsage(const int &inodeUsage); +private: + Ui::debugDialog *ui; +}; + +#endif // ULTRACOPIER_PLUGIN_DEBUG_WINDOW + +#endif // DEBUGDAILOG_H diff --git a/plugins/CopyEngine/Ultracopier/DebugEngineMacro.h b/plugins/CopyEngine/Ultracopier/DebugEngineMacro.h new file mode 100644 index 0000000..f9b5349 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DebugEngineMacro.h @@ -0,0 +1,28 @@ +/** \file DebugEngineMacro.h +\brief Define the macro for the debug +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef DEBUGENGINEMACRO_H +#define DEBUGENGINEMACRO_H + +#ifdef WIN32 +# define __func__ __FUNCTION__ +#endif + +/// \brief Macro for the debug log +#ifdef ULTRACOPIER_PLUGIN_DEBUG + #if defined (__FILE__) && defined (__LINE__) + #define ULTRACOPIER_DEBUGCONSOLE(a,b) emit debugInformation(a,__func__,b,__FILE__,__LINE__) + #else + #define ULTRACOPIER_DEBUGCONSOLE(a,b) emit debugInformation(a,__func__,b) + #endif +#else // ULTRACOPIER_PLUGIN_DEBUG + #define ULTRACOPIER_DEBUGCONSOLE(a,b) void() +#endif // ULTRACOPIER_PLUGIN_DEBUG + +#endif // DEBUGENGINEMACRO_H + + + + diff --git a/plugins/CopyEngine/Ultracopier/DiskSpace.cpp b/plugins/CopyEngine/Ultracopier/DiskSpace.cpp new file mode 100644 index 0000000..e9b996d --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DiskSpace.cpp @@ -0,0 +1,53 @@ +#include "DiskSpace.h" +#include "ui_DiskSpace.h" +#include "StructEnumDefinition_CopyEngine.h" + +DiskSpace::DiskSpace(FacilityInterface * facilityEngine,std::vector list,QWidget *parent) : + QDialog(parent), + ui(new Ui::DiskSpace) +{ + Qt::WindowFlags flags = windowFlags(); + #ifdef Q_OS_LINUX + flags=flags & ~Qt::X11BypassWindowManagerHint; + #endif + flags=flags | Qt::WindowStaysOnTopHint; + setWindowFlags(flags); + + ui->setupUi(this); + ok=false; + int index=0; + int size=list.size(); + QString drives; + while(indexsizeToString(list.at(index).freeSpace))) + .arg(QString::fromStdString(facilityEngine->sizeToString(list.at(index).requiredSpace))); + drives+=QStringLiteral("
"); + index++; + } + ui->drives->setText(drives); +} + +DiskSpace::~DiskSpace() +{ + delete ui; +} + +void DiskSpace::on_ok_clicked() +{ + ok=true; + close(); +} + +void DiskSpace::on_cancel_clicked() +{ + ok=false; + close(); +} + +bool DiskSpace::getAction() const +{ + return ok; +} diff --git a/plugins/CopyEngine/Ultracopier/DiskSpace.h b/plugins/CopyEngine/Ultracopier/DiskSpace.h new file mode 100644 index 0000000..5a923ab --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DiskSpace.h @@ -0,0 +1,29 @@ +#ifndef DISKSPACE_H +#define DISKSPACE_H + +#include +#include +#include "../../../interface/PluginInterface_CopyEngine.h" +#include "StructEnumDefinition_CopyEngine.h" + +namespace Ui { +class DiskSpace; +} + +class DiskSpace : public QDialog +{ + Q_OBJECT + +public: + explicit DiskSpace(FacilityInterface * facilityEngine,std::vector list,QWidget *parent = 0); + ~DiskSpace(); + bool getAction() const; +private slots: + void on_ok_clicked(); + void on_cancel_clicked(); +private: + Ui::DiskSpace *ui; + bool ok; +}; + +#endif // DISKSPACE_H diff --git a/plugins/CopyEngine/Ultracopier/DiskSpace.ui b/plugins/CopyEngine/Ultracopier/DiskSpace.ui new file mode 100644 index 0000000..10b5c69 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DiskSpace.ui @@ -0,0 +1,68 @@ + + + DiskSpace + + + + 0 + 0 + 367 + 146 + + + + Disk space + + + + :/CopyEngine/Ultracopier/resources/remove.png:/CopyEngine/Ultracopier/resources/remove.png + + + + + + You need more space on this drive to finish this transfer + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Continue + + + + + + + Cancel + + + + + + + + + + + + diff --git a/plugins/CopyEngine/Ultracopier/DriveManagement.cpp b/plugins/CopyEngine/Ultracopier/DriveManagement.cpp new file mode 100644 index 0000000..f25836f --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/DriveManagement.cpp @@ -0,0 +1,105 @@ +#include "DriveManagement.h" + +#include +#include +#include + +#include "../../../cpp11addition.h" + +DriveManagement::DriveManagement() +{ + tryUpdate(); + #ifdef Q_OS_WIN32 + reg1=std::regex("^(\\\\\\\\|//)[^\\\\\\\\/]+(\\\\|/)[^\\\\\\\\/]+"); + reg2=std::regex("^((\\\\\\\\|//)[^\\\\\\\\/]+(\\\\|/)[^\\\\\\\\/]+).*$"); + reg3=std::regex("^[a-zA-Z]:[\\\\/]"); + reg4=std::regex("^([a-zA-Z]:[\\\\/]).*$"); + #endif + /// \warn ULTRACOPIER_DEBUGCONSOLE() don't work here because the sinal slot is not connected! +} + +//get drive of an file or folder +/// \todo do network drive support for windows +std::string DriveManagement::getDrive(const std::string &fileOrFolder) const +{ + const std::string &inode=QDir::toNativeSeparators(QString::fromStdString(fileOrFolder)).toStdString(); + int size=mountSysPoint.size(); + for (int i = 0; i < size; ++i) { + if(stringStartWith(inode,mountSysPoint.at(i))) + return QDir::toNativeSeparators(QString::fromStdString(mountSysPoint.at(i))).toStdString(); + } + #ifdef Q_OS_WIN32 + if(std::regex_match(fileOrFolder,reg1)) + { + std::string returnString=fileOrFolder; + std::regex_replace(returnString,reg2,"$1"); + return returnString; + } + //due to lack of WMI support into mingw, the new drive event is never called, this is a workaround + if(std::regex_match(fileOrFolder,reg3)) + { + std::string returnString=fileOrFolder; + std::regex_replace(returnString,reg4,"$1"); + return QDir::toNativeSeparators(QString::fromStdString(returnString)).toUpper().toStdString(); + } + #endif + //if unable to locate the right mount point + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"unable to locate the right mount point for: "+fileOrFolder+", mount point: "+stringimplode(mountSysPoint,";")); + return std::string(); +} + +QByteArray DriveManagement::getDriveType(const std::string &drive) const +{ + int index=vectorindexOf(mountSysPoint,drive); + if(index!=-1) + return driveType.at(index); + return QByteArray(); +} + +bool DriveManagement::isSameDrive(const std::string &file1,const std::string &file2) const +{ + if(mountSysPoint.size()==0) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"no mount point found"); + return false; + } + const std::string &drive1=getDrive(file1); + if(drive1.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"drive for the file1 not found: "+file1); + return false; + } + const std::string &drive2=getDrive(file2); + if(drive2.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"drive for the file2 not found: "+file2); + return false; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,drive1+" is egal to "+drive2); + if(drive1==drive2) + return true; + else + return false; +} + +void DriveManagement::tryUpdate() +{ + mountSysPoint.clear(); + driveType.clear(); + const QList mountedVolumesList=QStorageInfo::mountedVolumes(); + int index=0; + while(index +#include +#include +#include +#include +#include + +#include "Environment.h" + +class DriveManagement : public QObject +{ + Q_OBJECT +public: + explicit DriveManagement(); + bool isSameDrive(const std::string &file1, const std::string &file2) const; + /// \brief get drive of an file or folder + std::string getDrive(const std::string &fileOrFolder) const; + QByteArray getDriveType(const std::string &drive) const; + void tryUpdate(); +protected: + std::vector mountSysPoint; + std::vector driveType; + #ifdef Q_OS_WIN32 + std::regex reg1,reg2,reg3,reg4; + #endif +signals: + /// \brief To debug source + void debugInformation(const Ultracopier::DebugLevel &level,const std::string &fonction,const std::string &text,const std::string &file,const int &ligne) const; +}; + +#endif // DRIVEMANAGEMENT_H diff --git a/plugins/CopyEngine/Ultracopier/Environment.h b/plugins/CopyEngine/Ultracopier/Environment.h new file mode 100644 index 0000000..34db2a2 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Environment.h @@ -0,0 +1,11 @@ +/** \file Environment.h +\brief Define the environment variable and global function +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include "Variable.h" +/// \brief The global include +#include "StructEnumDefinition.h" +#include "StructEnumDefinition_CopyEngine.h" +#include "DebugEngineMacro.h" +#include "CompilerInfo.h" diff --git a/plugins/CopyEngine/Ultracopier/FileErrorDialog.cpp b/plugins/CopyEngine/Ultracopier/FileErrorDialog.cpp new file mode 100644 index 0000000..d88fb90 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FileErrorDialog.cpp @@ -0,0 +1,163 @@ +#include "FileErrorDialog.h" +#include "ui_fileErrorDialog.h" +#include "TransferThread.h" + +#include + +bool FileErrorDialog::isInAdmin=false; + +FileErrorDialog::FileErrorDialog(QWidget *parent, QFileInfo fileInfo, std::string errorString, const ErrorType &errorType) : + QDialog(parent), + ui(new Ui::fileErrorDialog) +{ + Qt::WindowFlags flags = windowFlags(); + #ifdef Q_OS_LINUX + flags=flags & ~Qt::X11BypassWindowManagerHint; + #endif + flags=flags | Qt::WindowStaysOnTopHint; + setWindowFlags(flags); + + ui->setupUi(this); + action=FileError_Cancel; + ui->label_error->setText(QString::fromStdString(errorString)); + if(fileInfo.exists()) + { + ui->label_content_file_name->setText(QString::fromStdString(TransferThread::resolvedName(fileInfo))); + if(ui->label_content_file_name->text().isEmpty()) + { + ui->label_content_file_name->setText(fileInfo.absoluteFilePath()); + ui->label_folder->setVisible(false); + ui->label_content_folder->setVisible(false); + } + else + { + QString folder=fileInfo.absolutePath(); + if(folder.size()>80) + folder=folder.mid(0,38)+"..."+folder.mid(folder.size()-38); + ui->label_content_folder->setText(fileInfo.absolutePath()); + } + ui->label_content_size->setText(QString::number(fileInfo.size())); + QDateTime maxTime(QDate(ULTRACOPIER_PLUGIN_MINIMALYEAR,1,1)); + if(maxTimelabel_modified->setVisible(true); + ui->label_content_modified->setVisible(true); + ui->label_content_modified->setText(fileInfo.lastModified().toString()); + } + else + { + ui->label_modified->setVisible(false); + ui->label_content_modified->setVisible(false); + } + if(fileInfo.isDir()) + { + this->setWindowTitle(tr("Error on folder")); + ui->label_size->hide(); + ui->label_content_size->hide(); + ui->label_file_name->setText(tr("Folder name")); + } + ui->label_file_destination->setVisible(fileInfo.isSymLink()); + ui->label_content_file_destination->setVisible(fileInfo.isSymLink()); + if(fileInfo.isSymLink()) + ui->label_content_file_destination->setText(fileInfo.symLinkTarget()); + } + else + { + ui->label_content_file_name->setText(QString::fromStdString(TransferThread::resolvedName(fileInfo))); + if(ui->label_content_file_name->text().isEmpty()) + { + ui->label_content_file_name->setText(fileInfo.absoluteFilePath()); + ui->label_folder->setVisible(false); + ui->label_content_folder->setVisible(false); + } + else + ui->label_content_folder->setText(fileInfo.absolutePath()); + + ui->label_file_destination->hide(); + ui->label_content_file_destination->hide(); + ui->label_size->hide(); + ui->label_content_size->hide(); + ui->label_modified->hide(); + ui->label_content_modified->hide(); + } + if(errorType==ErrorType_Folder || errorType==ErrorType_FolderWithRety) + ui->PutToBottom->hide(); + if(errorType==ErrorType_Folder) + ui->Retry->hide(); + + ui->Rights->hide(); + #ifdef ULTRACOPIER_PLUGIN_RIGHTS + if(isInAdmin) + ui->Rights->hide(); + #ifdef Q_OS_WIN32 + if(errorType!=ErrorType_Rights) + ui->Rights->hide(); + #else + ui->Rights->hide(); + #endif + #else + ui->Rights->hide(); + #endif +} + +FileErrorDialog::~FileErrorDialog() +{ + delete ui; +} + +void FileErrorDialog::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void FileErrorDialog::on_PutToBottom_clicked() +{ + action=FileError_PutToEndOfTheList; + this->close(); +} + +void FileErrorDialog::on_Retry_clicked() +{ + action=FileError_Retry; + this->close(); +} + +void FileErrorDialog::on_Skip_clicked() +{ + action=FileError_Skip; + this->close(); +} + +void FileErrorDialog::on_Cancel_clicked() +{ + action=FileError_Cancel; + this->close(); +} + +bool FileErrorDialog::getAlways() +{ + return ui->checkBoxAlways->isChecked(); +} + +FileErrorAction FileErrorDialog::getAction() +{ + return action; +} + +void FileErrorDialog::on_checkBoxAlways_clicked() +{ + ui->Rights->setEnabled(!ui->checkBoxAlways->isChecked()); +} + +#ifdef ULTRACOPIER_PLUGIN_RIGHTS +void FileErrorDialog::on_Rights_clicked() +{ +} +#endif diff --git a/plugins/CopyEngine/Ultracopier/FileErrorDialog.h b/plugins/CopyEngine/Ultracopier/FileErrorDialog.h new file mode 100644 index 0000000..133a8b0 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FileErrorDialog.h @@ -0,0 +1,51 @@ +/** \file fileErrorDialog.h +\brief Define the dialog error on the file +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include +#include +#include +#include +#include +#include "Environment.h" + +#ifndef FILEERRORDIALOG_H +#define FILEERRORDIALOG_H + + + +namespace Ui { + class fileErrorDialog; +} + +/// \brief to show error dialog, and ask what do +class FileErrorDialog : public QDialog +{ + Q_OBJECT +public: + /// \brief create the object and pass all the informations to it + explicit FileErrorDialog(QWidget *parent,QFileInfo fileInfo,std::string errorString,const ErrorType &errorType); + ~FileErrorDialog(); + /// \brief return the the always checkbox is checked + bool getAlways(); + /// \brief return the action clicked + FileErrorAction getAction(); +protected: + void changeEvent(QEvent *e); + static bool isInAdmin; +private slots: + void on_PutToBottom_clicked(); + void on_Retry_clicked(); + void on_Skip_clicked(); + void on_Cancel_clicked(); + void on_checkBoxAlways_clicked(); + #ifdef ULTRACOPIER_PLUGIN_RIGHTS + void on_Rights_clicked(); + #endif +private: + Ui::fileErrorDialog *ui; + FileErrorAction action; +}; + +#endif // FILEERRORDIALOG_H diff --git a/plugins/CopyEngine/Ultracopier/FileExistsDialog.cpp b/plugins/CopyEngine/Ultracopier/FileExistsDialog.cpp new file mode 100644 index 0000000..91df1f8 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FileExistsDialog.cpp @@ -0,0 +1,244 @@ +#include "FileExistsDialog.h" +#include "ui_fileExistsDialog.h" +#include "TransferThread.h" + +#ifdef Q_OS_WIN32 +#define CURRENTSEPARATOR "\\" +#else +#define CURRENTSEPARATOR "/" +#endif + +#include +#include +#include + +FileExistsDialog::FileExistsDialog(QWidget *parent, QFileInfo source, QFileInfo destination, std::string firstRenamingRule, std::string otherRenamingRule) : + QDialog(parent), + ui(new Ui::fileExistsDialog) +{ + Qt::WindowFlags flags = windowFlags(); + #ifdef Q_OS_LINUX + flags=flags & ~Qt::X11BypassWindowManagerHint; + #endif + flags=flags | Qt::WindowStaysOnTopHint; + setWindowFlags(flags); + + ui->setupUi(this); + action=FileExists_Cancel; + destinationInfo=destination; + oldName=TransferThread::resolvedName(destination); + ui->lineEditNewName->setText(QString::fromStdString(oldName)); + ui->lineEditNewName->setPlaceholderText(QString::fromStdString(oldName)); + ui->Overwrite->addAction(ui->actionOverwrite_if_newer); + ui->Overwrite->addAction(ui->actionOverwrite_if_not_same_modification_date); + ui->label_content_source_size->setText(QString::number(source.size())); + ui->label_content_source_modified->setText(source.lastModified().toString()); + ui->label_content_source_file_name->setText(QString::fromStdString(TransferThread::resolvedName(source))); + QString folder=source.absolutePath(); + if(folder.size()>80) + folder=folder.mid(0,38)+"..."+folder.mid(folder.size()-38); + ui->label_content_source_folder->setText(folder); + ui->label_content_destination_size->setText(QString::number(destination.size())); + ui->label_content_destination_modified->setText(destination.lastModified().toString()); + ui->label_content_destination_file_name->setText(QString::fromStdString(TransferThread::resolvedName(destination))); + folder=destination.absolutePath(); + if(folder.size()>80) + folder=folder.mid(0,38)+"..."+folder.mid(folder.size()-38); + ui->label_content_destination_folder->setText(folder); + QDateTime maxTime(QDate(ULTRACOPIER_PLUGIN_MINIMALYEAR,1,1)); + if(maxTimelabel_source_modified->setVisible(true); + ui->label_content_source_modified->setVisible(true); + ui->label_content_source_modified->setText(source.lastModified().toString()); + } + else + { + ui->label_source_modified->setVisible(false); + ui->label_content_source_modified->setVisible(false); + } + if(maxTimelabel_destination_modified->setVisible(true); + ui->label_content_destination_modified->setVisible(true); + ui->label_content_destination_modified->setText(destination.lastModified().toString()); + } + else + { + ui->label_destination_modified->setVisible(false); + ui->label_content_destination_modified->setVisible(false); + } + if(!source.exists()) + { + ui->label_content_source_size->setVisible(false); + ui->label_source_size->setVisible(false); + ui->label_source_modified->setVisible(false); + ui->label_content_source_modified->setVisible(false); + } + if(!destination.exists()) + { + ui->label_content_destination_size->setVisible(false); + ui->label_destination_size->setVisible(false); + ui->label_destination_modified->setVisible(false); + ui->label_content_destination_modified->setVisible(false); + } + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + on_SuggestNewName_clicked(); +} + +FileExistsDialog::~FileExistsDialog() +{ + delete ui; +} + +void FileExistsDialog::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +std::string FileExistsDialog::getNewName() +{ + if(oldName==ui->lineEditNewName->text().toStdString() || ui->checkBoxAlways->isChecked()) + return oldName; + else + return ui->lineEditNewName->text().toStdString(); +} + +void FileExistsDialog::on_SuggestNewName_clicked() +{ + QFileInfo destinationInfo=this->destinationInfo; + QString absolutePath=destinationInfo.absolutePath(); + QString fileName=QString::fromStdString(TransferThread::resolvedName(destinationInfo)); + QString suffix=""; + QString destination; + QString newFileName; + //resolv the suffix + if(fileName.contains(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")))) + { + suffix=fileName; + suffix.replace(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")),QStringLiteral("\\2")); + fileName.replace(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")),QStringLiteral("\\1")); + } + //resolv the new name + int num=1; + do + { + if(num==1) + { + if(firstRenamingRule.empty()) + newFileName=tr("%1 - copy").arg(fileName); + else + { + newFileName=QString::fromStdString(firstRenamingRule); + newFileName.replace("%name%",fileName); + } + } + else + { + if(otherRenamingRule.empty()) + newFileName=tr("%1 - copy (%2)").arg(fileName).arg(num); + else + { + newFileName=QString::fromStdString(otherRenamingRule); + newFileName.replace(QStringLiteral("%name%"),fileName); + newFileName.replace(QStringLiteral("%number%"),QString::number(num)); + } + } + destination=absolutePath+CURRENTSEPARATOR+newFileName+suffix; + destinationInfo.setFile(destination); + num++; + } + while(destinationInfo.exists()); + ui->lineEditNewName->setText(newFileName+suffix); +} + +void FileExistsDialog::on_Rename_clicked() +{ + action=FileExists_Rename; + this->close(); +} + +void FileExistsDialog::on_Overwrite_clicked() +{ + action=FileExists_Overwrite; + this->close(); +} + +void FileExistsDialog::on_Skip_clicked() +{ + action=FileExists_Skip; + this->close(); +} + +void FileExistsDialog::on_Cancel_clicked() +{ + action=FileExists_Cancel; + this->close(); +} + +void FileExistsDialog::on_actionOverwrite_if_newer_triggered() +{ + action=FileExists_OverwriteIfNewer; + this->close(); +} + +void FileExistsDialog::on_actionOverwrite_if_not_same_modification_date_triggered() +{ + action=FileExists_OverwriteIfNotSame; + this->close(); +} + +FileExistsAction FileExistsDialog::getAction() +{ + return action; +} + +bool FileExistsDialog::getAlways() +{ + return ui->checkBoxAlways->isChecked(); +} + +void FileExistsDialog::updateRenameButton() +{ + ui->Rename->setEnabled(ui->checkBoxAlways->isChecked() || (!ui->lineEditNewName->text().contains(QRegularExpression("[/\\\\\\*]")) && oldName!=ui->lineEditNewName->text().toStdString() && !ui->lineEditNewName->text().isEmpty())); +} + +void FileExistsDialog::on_checkBoxAlways_toggled(bool checked) +{ + Q_UNUSED(checked); + updateRenameButton(); +} + +void FileExistsDialog::on_lineEditNewName_textChanged(const QString &arg1) +{ + Q_UNUSED(arg1); + updateRenameButton(); +} + +void FileExistsDialog::on_lineEditNewName_returnPressed() +{ + updateRenameButton(); + if(ui->Rename->isEnabled()) + on_Rename_clicked(); + else + QMessageBox::warning(this,tr("Error"),tr("Try rename with using special characters")); +} + +void FileExistsDialog::on_actionOverwrite_if_older_triggered() +{ + action=FileExists_OverwriteIfOlder; + this->close(); +} + +void FileExistsDialog::on_lineEditNewName_editingFinished() +{ + updateRenameButton(); +} diff --git a/plugins/CopyEngine/Ultracopier/FileExistsDialog.h b/plugins/CopyEngine/Ultracopier/FileExistsDialog.h new file mode 100644 index 0000000..05ff7e0 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FileExistsDialog.h @@ -0,0 +1,60 @@ +/** \file fileExistsDialog.h +\brief Define the dialog when file already exists +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include +#include +#include +#include +#include +#include +#include "Environment.h" + +#ifndef FILEEXISTSDIALOG_H +#define FILEEXISTSDIALOG_H + +namespace Ui { + class fileExistsDialog; +} + +/// \brief to show file exists dialog, and ask what do +class FileExistsDialog : public QDialog +{ + Q_OBJECT +public: + /// \brief create the object and pass all the informations to it + explicit FileExistsDialog(QWidget *parent,QFileInfo source,QFileInfo destination,std::string firstRenamingRule,std::string otherRenamingRule); + ~FileExistsDialog(); + /// \brief return the the always checkbox is checked + bool getAlways(); + /// \brief return the action clicked + FileExistsAction getAction(); + /// \brief return the new rename is case in manual renaming + std::string getNewName(); +protected: + void changeEvent(QEvent *e); +private slots: + void on_SuggestNewName_clicked(); + void on_Rename_clicked(); + void on_Overwrite_clicked(); + void on_Skip_clicked(); + void on_Cancel_clicked(); + void on_actionOverwrite_if_newer_triggered(); + void on_actionOverwrite_if_not_same_modification_date_triggered(); + void updateRenameButton(); + void on_checkBoxAlways_toggled(bool checked); + void on_lineEditNewName_textChanged(const QString &arg1); + void on_lineEditNewName_returnPressed(); + void on_actionOverwrite_if_older_triggered(); + void on_lineEditNewName_editingFinished(); +private: + Ui::fileExistsDialog *ui; + FileExistsAction action; + std::string oldName; + QFileInfo destinationInfo; + std::string firstRenamingRule; + std::string otherRenamingRule; +}; + +#endif // FILEEXISTSDIALOG_H diff --git a/plugins/CopyEngine/Ultracopier/FileIsSameDialog.cpp b/plugins/CopyEngine/Ultracopier/FileIsSameDialog.cpp new file mode 100644 index 0000000..3bee3ae --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FileIsSameDialog.cpp @@ -0,0 +1,194 @@ +#include "FileIsSameDialog.h" +#include "ui_fileIsSameDialog.h" +#include "TransferThread.h" + +#ifdef Q_OS_WIN32 +#define CURRENTSEPARATOR "\\" +#else +#define CURRENTSEPARATOR "/" +#endif + +#include +#include +#include + +FileIsSameDialog::FileIsSameDialog(QWidget *parent, QFileInfo fileInfo, std::string firstRenamingRule, std::string otherRenamingRule) : + QDialog(parent), + ui(new Ui::fileIsSameDialog) +{ + Qt::WindowFlags flags = windowFlags(); + #ifdef Q_OS_LINUX + flags=flags & ~Qt::X11BypassWindowManagerHint; + #endif + flags=flags | Qt::WindowStaysOnTopHint; + setWindowFlags(flags); + + ui->setupUi(this); + action=FileExists_Cancel; + oldName=TransferThread::resolvedName(fileInfo); + destinationInfo=fileInfo; + ui->lineEditNewName->setText(QString::fromStdString(oldName)); + ui->lineEditNewName->setPlaceholderText(QString::fromStdString(oldName)); + ui->label_content_size->setText(QString::number(fileInfo.size())); + ui->label_content_modified->setText(fileInfo.lastModified().toString()); + ui->label_content_file_name->setText(QString::fromStdString(TransferThread::resolvedName(fileInfo))); + QString folder=fileInfo.absolutePath(); + if(folder.size()>80) + folder=folder.mid(0,38)+"..."+folder.mid(folder.size()-38); + ui->label_content_folder->setText(folder); + updateRenameButton(); + QDateTime maxTime(QDate(ULTRACOPIER_PLUGIN_MINIMALYEAR,1,1)); + if(maxTimelabel_modified->setVisible(true); + ui->label_content_modified->setVisible(true); + ui->label_content_modified->setText(fileInfo.lastModified().toString()); + } + else + { + ui->label_modified->setVisible(false); + ui->label_content_modified->setVisible(false); + } + if(!fileInfo.exists()) + { + ui->label_content_size->setVisible(false); + ui->label_size->setVisible(false); + ui->label_modified->setVisible(false); + ui->label_content_modified->setVisible(false); + } + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + on_SuggestNewName_clicked(); +} + +FileIsSameDialog::~FileIsSameDialog() +{ + delete ui; +} + +void FileIsSameDialog::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +std::string FileIsSameDialog::getNewName() +{ + if(oldName==ui->lineEditNewName->text().toStdString() || ui->checkBoxAlways->isChecked()) + return oldName; + else + return ui->lineEditNewName->text().toStdString(); +} + +void FileIsSameDialog::on_SuggestNewName_clicked() +{ + QFileInfo destinationInfo=this->destinationInfo; + QString absolutePath=destinationInfo.absolutePath(); + QString fileName=QString::fromStdString(TransferThread::resolvedName(destinationInfo)); + QString suffix=""; + QString destination; + QString newFileName; + //resolv the suffix + if(fileName.contains(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")))) + { + suffix=fileName; + suffix.replace(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")),QStringLiteral("\\2")); + fileName.replace(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")),QStringLiteral("\\1")); + } + //resolv the new name + int num=1; + do + { + if(num==1) + { + if(firstRenamingRule.empty()) + newFileName=tr("%1 - copy").arg(fileName); + else + { + newFileName=QString::fromStdString(firstRenamingRule); + newFileName.replace(QStringLiteral("%name%"),fileName); + } + } + else + { + if(otherRenamingRule.empty()) + newFileName=tr("%1 - copy (%2)").arg(fileName).arg(num); + else + { + newFileName=QString::fromStdString(otherRenamingRule); + newFileName.replace(QStringLiteral("%name%"),fileName); + newFileName.replace(QStringLiteral("%number%"),QString::number(num)); + } + } + destination=absolutePath+CURRENTSEPARATOR+newFileName+suffix; + destinationInfo.setFile(destination); + num++; + } + while(destinationInfo.exists()); + ui->lineEditNewName->setText(newFileName+suffix); +} + +void FileIsSameDialog::on_Rename_clicked() +{ + action=FileExists_Rename; + this->close(); +} + +void FileIsSameDialog::on_Skip_clicked() +{ + action=FileExists_Skip; + this->close(); +} + +void FileIsSameDialog::on_Cancel_clicked() +{ + action=FileExists_Cancel; + this->close(); +} + +FileExistsAction FileIsSameDialog::getAction() +{ + return action; +} + +bool FileIsSameDialog::getAlways() +{ + return ui->checkBoxAlways->isChecked(); +} + +void FileIsSameDialog::updateRenameButton() +{ + ui->Rename->setEnabled(ui->checkBoxAlways->isChecked() || (!ui->lineEditNewName->text().contains(QRegularExpression("[/\\\\\\*]")) && oldName!=ui->lineEditNewName->text().toStdString() && !ui->lineEditNewName->text().isEmpty())); +} + +void FileIsSameDialog::on_lineEditNewName_textChanged(const QString &arg1) +{ + Q_UNUSED(arg1); + updateRenameButton(); +} + +void FileIsSameDialog::on_checkBoxAlways_toggled(bool checked) +{ + Q_UNUSED(checked); + updateRenameButton(); +} + +void FileIsSameDialog::on_lineEditNewName_returnPressed() +{ + updateRenameButton(); + if(ui->Rename->isEnabled()) + on_Rename_clicked(); + else + QMessageBox::warning(this,tr("Error"),tr("Try rename with using special characters")); +} + +void FileIsSameDialog::on_lineEditNewName_editingFinished() +{ + updateRenameButton(); +} diff --git a/plugins/CopyEngine/Ultracopier/FileIsSameDialog.h b/plugins/CopyEngine/Ultracopier/FileIsSameDialog.h new file mode 100644 index 0000000..5dc0067 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FileIsSameDialog.h @@ -0,0 +1,57 @@ +/** \file fileIsSameDialog.h +\brief Define the dialog when file is same +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include +#include +#include +#include +#include +#include +#include "Environment.h" + +#ifndef FILEISSAMEDIALOG_H +#define FILEISSAMEDIALOG_H + +namespace Ui { + class fileIsSameDialog; +} + +/// \brief to show file is same dialog, and ask what do +class FileIsSameDialog : public QDialog +{ + Q_OBJECT +public: + /// \brief create the object and pass all the informations to it + explicit FileIsSameDialog(QWidget *parent,QFileInfo fileInfo,std::string firstRenamingRule,std::string otherRenamingRule); + ~FileIsSameDialog(); + /// \brief return the the always checkbox is checked + bool getAlways(); + /// \brief return the action clicked + FileExistsAction getAction(); + /// \brief return the new rename is case in manual renaming + std::string getNewName(); +protected: + void changeEvent(QEvent *e); +private slots: + void on_SuggestNewName_clicked(); + void on_Rename_clicked(); + void on_Skip_clicked(); + void on_Cancel_clicked(); + void updateRenameButton(); + void on_lineEditNewName_textChanged(const QString &arg1); + void on_checkBoxAlways_toggled(bool checked); + void on_lineEditNewName_returnPressed(); + void on_lineEditNewName_editingFinished(); +private: + Ui::fileIsSameDialog *ui; + FileExistsAction action; + std::string oldName; + QFileInfo destinationInfo; + std::string firstRenamingRule; + std::string otherRenamingRule; + +}; + +#endif // FILEISSAMEDIALOG_H diff --git a/plugins/CopyEngine/Ultracopier/FilterRules.cpp b/plugins/CopyEngine/Ultracopier/FilterRules.cpp new file mode 100644 index 0000000..0f6bf2c --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FilterRules.cpp @@ -0,0 +1,193 @@ +#include "FilterRules.h" +#include "ui_FilterRules.h" + +#include + +FilterRules::FilterRules(QWidget *parent) : + QDialog(parent), + ui(new Ui::FilterRules) +{ + ui->setupUi(this); + updateChecking(); + haveBeenValided=false; +} + +FilterRules::~FilterRules() +{ + delete ui; +} + +bool FilterRules::getIsValid() +{ + return isValid && haveBeenValided; +} + +std::string FilterRules::get_search_text() +{ + return ui->search->text().toStdString(); +} + +SearchType FilterRules::get_search_type() +{ + switch(ui->search_type->currentIndex()) + { + case 0: + return SearchType_rawText; + case 1: + return SearchType_simpleRegex; + case 2: + return SearchType_perlRegex; + } + return SearchType_simpleRegex; +} + +ApplyOn FilterRules::get_apply_on() +{ + switch(ui->apply_on->currentIndex()) + { + case 0: + return ApplyOn_file; + case 1: + return ApplyOn_fileAndFolder; + case 2: + return ApplyOn_folder; + } + return ApplyOn_fileAndFolder; +} + +bool FilterRules::get_need_match_all() +{ + return ui->need_match_all->isChecked(); +} + +void FilterRules::set_search_text(std::string search_text) +{ + ui->search->setText(QString::fromStdString(search_text)); +} + +void FilterRules::set_search_type(SearchType search_type) +{ + switch(search_type) + { + case SearchType_rawText: + ui->search_type->setCurrentIndex(0); + break; + case SearchType_simpleRegex: + ui->search_type->setCurrentIndex(1); + break; + case SearchType_perlRegex: + ui->search_type->setCurrentIndex(2); + break; + } +} + +void FilterRules::set_apply_on(ApplyOn apply_on) +{ + switch(apply_on) + { + case ApplyOn_file: + ui->apply_on->setCurrentIndex(0); + break; + case ApplyOn_fileAndFolder: + ui->apply_on->setCurrentIndex(1); + break; + case ApplyOn_folder: + ui->apply_on->setCurrentIndex(2); + break; + } +} + +void FilterRules::set_need_match_all(bool need_match_all) +{ + ui->need_match_all->setChecked(need_match_all); +} + +void FilterRules::on_search_textChanged(const std::string &arg1) +{ + Q_UNUSED(arg1); + updateChecking(); +} + +void FilterRules::updateChecking() +{ + QRegularExpression regex; + isValid=!ui->search->text().isEmpty(); + if(isValid) + { + QString tempString; + if(ui->search_type->currentIndex()==0) + { + tempString=QRegularExpression::escape(ui->search->text()); + if(tempString.contains('/') || tempString.contains('\\')) + isValid=false; + } + else if(ui->search_type->currentIndex()==1) + { + tempString=QRegularExpression::escape(ui->search->text()); + tempString.replace(QStringLiteral("\\*"),QStringLiteral("[^\\\\/]*")); + } + else if(ui->search_type->currentIndex()==2) + { + tempString=ui->search->text(); + if(tempString.startsWith('^') && tempString.endsWith('$')) + { + ui->need_match_all->setChecked(true); + tempString.remove(QRegularExpression(QStringLiteral("^\\^"))); + tempString.remove(QRegularExpression(QStringLiteral("\\$$"))); + ui->search->setText(tempString); + } + } + if(isValid) + { + if(ui->need_match_all->isChecked()) + tempString=QStringLiteral("^")+tempString+QStringLiteral("$"); + regex=QRegularExpression(tempString); + isValid=regex.isValid(); + } + } + + ui->isValid->setChecked(isValid); + ui->testString->setEnabled(isValid); + ui->label_test_string->setEnabled(isValid); + ui->matched->setEnabled(isValid); + ui->matched->setChecked(isValid && ui->testString->text().contains(regex)); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid); +} + +void FilterRules::on_isValid_clicked() +{ + updateChecking(); +} + +void FilterRules::on_testString_textChanged(const std::string &arg1) +{ + Q_UNUSED(arg1); + updateChecking(); +} + +void FilterRules::on_matched_clicked() +{ + updateChecking(); +} + +void FilterRules::on_search_type_currentIndexChanged(int index) +{ + Q_UNUSED(index); + updateChecking(); +} + +void FilterRules::on_need_match_all_clicked() +{ + updateChecking(); +} + +void FilterRules::on_buttonBox_clicked(QAbstractButton *button) +{ + if(ui->buttonBox->buttonRole(button)==QDialogButtonBox::RejectRole) + reject(); + else + { + haveBeenValided=true; + accept(); + } +} diff --git a/plugins/CopyEngine/Ultracopier/FilterRules.h b/plugins/CopyEngine/Ultracopier/FilterRules.h new file mode 100644 index 0000000..0838792 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FilterRules.h @@ -0,0 +1,46 @@ +#ifndef FILTERRULES_H +#define FILTERRULES_H + +#include +#include +#include + +#include "StructEnumDefinition_CopyEngine.h" + +namespace Ui { +class FilterRules; +} + +/** All the filter rules to include/exclude some file during the listing */ +class FilterRules : public QDialog +{ + Q_OBJECT + +public: + explicit FilterRules(QWidget *parent = 0); + ~FilterRules(); + bool getIsValid(); + std::string get_search_text(); + SearchType get_search_type(); + ApplyOn get_apply_on(); + bool get_need_match_all(); + void set_search_text(std::string search_text); + void set_search_type(SearchType search_type); + void set_apply_on(ApplyOn apply_on); + void set_need_match_all(bool need_match_all); +private slots: + void on_search_textChanged(const std::string &arg1); + void on_isValid_clicked(); + void on_testString_textChanged(const std::string &arg1); + void on_matched_clicked(); + void on_search_type_currentIndexChanged(int index); + void on_need_match_all_clicked(); + void on_buttonBox_clicked(QAbstractButton *button); +private: + Ui::FilterRules *ui; + void updateChecking(); + bool isValid; + bool haveBeenValided; +}; + +#endif // FILTERRULES_H diff --git a/plugins/CopyEngine/Ultracopier/FilterRules.ui b/plugins/CopyEngine/Ultracopier/FilterRules.ui new file mode 100644 index 0000000..a4006fe --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FilterRules.ui @@ -0,0 +1,162 @@ + + + FilterRules + + + Qt::WindowModal + + + + 0 + 0 + 289 + 231 + + + + Filters dialog + + + + :/CopyEngine/resources/resources/filter.png:/CopyEngine/resources/resources/filter.png + + + + 1 + + + 1 + + + + + Search: + + + + + + + + + + Search type: + + + + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + + + + Apply on: + + + + + + + + File + + + + + Folder + + + + + File and folder + + + + + + + + Whole string must match + + + + + + + Checking + + + + + + The regex is valid + + + + + + + Test string: + + + + + + + + + + The test string matches with the regex + + + + + + + + + + + + Qt::Horizontal + + + + 68 + 20 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + diff --git a/plugins/CopyEngine/Ultracopier/Filters.cpp b/plugins/CopyEngine/Ultracopier/Filters.cpp new file mode 100644 index 0000000..c7b1526 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Filters.cpp @@ -0,0 +1,460 @@ +#include "Filters.h" +#include "ui_Filters.h" +#include "../../../cpp11addition.h" + +#include + +Filters::Filters(QWidget *parent) : + QDialog(parent), + ui(new Ui::Filters) +{ + ui->setupUi(this); +} + +Filters::~Filters() +{ + delete ui; +} + +void Filters::setFilters(std::vector includeStrings,std::vector includeOptions,std::vector excludeStrings,std::vector excludeOptions) +{ + if(includeStrings.size()!=includeOptions.size() || excludeStrings.size()!=excludeOptions.size()) + return; + Filters_rules new_item; + + include.clear(); + unsigned int index=0; + while(index<(unsigned int)includeStrings.size()) + { + new_item.search_text=includeStrings.at(index); + std::vector options=stringsplit(includeOptions.at(index),';'); + new_item.need_match_all=false; + new_item.search_type=SearchType_rawText; + new_item.apply_on=ApplyOn_fileAndFolder; + + if(vectorcontainsAtLeastOne(options,std::string("SearchType_simpleRegex"))) + new_item.search_type=SearchType_simpleRegex; + if(vectorcontainsAtLeastOne(options,std::string("SearchType_perlRegex"))) + new_item.search_type=SearchType_perlRegex; + if(vectorcontainsAtLeastOne(options,std::string("ApplyOn_file"))) + new_item.apply_on=ApplyOn_file; + if(vectorcontainsAtLeastOne(options,std::string("ApplyOn_folder"))) + new_item.apply_on=ApplyOn_folder; + if(vectorcontainsAtLeastOne(options,std::string("need_match_all"))) + new_item.need_match_all=true; + + if(convertToRegex(new_item)) + include.push_back(new_item); + + index++; + } + + exclude.clear(); + index=0; + while(index options=stringsplit(excludeOptions.at(index),';'); + new_item.need_match_all=false; + new_item.search_type=SearchType_rawText; + new_item.apply_on=ApplyOn_fileAndFolder; + + if(vectorcontainsAtLeastOne(options,std::string("SearchType_simpleRegex"))) + new_item.search_type=SearchType_simpleRegex; + if(vectorcontainsAtLeastOne(options,std::string("SearchType_perlRegex"))) + new_item.search_type=SearchType_perlRegex; + if(vectorcontainsAtLeastOne(options,std::string("ApplyOn_file"))) + new_item.apply_on=ApplyOn_file; + if(vectorcontainsAtLeastOne(options,std::string("ApplyOn_folder"))) + new_item.apply_on=ApplyOn_folder; + if(vectorcontainsAtLeastOne(options,std::string("need_match_all"))) + new_item.need_match_all=true; + + if(convertToRegex(new_item)) + exclude.push_back(new_item); + + index++; + } + + reShowAll(); +} + +void Filters::reShowAll() +{ + ui->inclusion->clear(); + unsigned int index=0; + while(index<(unsigned int)include.size()) + { + std::string entryShow=include.at(index).search_text+" ("; + std::vector optionsToShow; + switch(include.at(index).search_type) + { + case SearchType_rawText: + optionsToShow.push_back(tr("Raw text").toStdString()); + break; + case SearchType_simpleRegex: + optionsToShow.push_back(tr("Simplified regex").toStdString()); + break; + case SearchType_perlRegex: + optionsToShow.push_back(tr("Perl's regex").toStdString()); + break; + default: + break; + } + switch(include.at(index).apply_on) + { + case ApplyOn_file: + optionsToShow.push_back(tr("Only on file").toStdString()); + break; + case ApplyOn_folder: + optionsToShow.push_back(tr("Only on folder").toStdString()); + break; + default: + break; + } + if(include.at(index).need_match_all) + optionsToShow.push_back(tr("Full match").toStdString()); + entryShow+=stringimplode(optionsToShow,","); + entryShow+=")"; + ui->inclusion->addItem(new QListWidgetItem(QString::fromStdString(entryShow))); + index++; + } + ui->exclusion->clear(); + index=0; + while(index<(unsigned int)exclude.size()) + { + std::string entryShow=exclude.at(index).search_text+" ("; + std::vector optionsToShow; + switch(exclude.at(index).search_type) + { + case SearchType_rawText: + optionsToShow.push_back(tr("Raw text").toStdString()); + break; + case SearchType_simpleRegex: + optionsToShow.push_back(tr("Simplified regex").toStdString()); + break; + case SearchType_perlRegex: + optionsToShow.push_back(tr("Perl's regex").toStdString()); + break; + default: + break; + } + switch(exclude.at(index).apply_on) + { + case ApplyOn_file: + optionsToShow.push_back(tr("Only on file").toStdString()); + break; + case ApplyOn_folder: + optionsToShow.push_back(tr("Only on folder").toStdString()); + break; + default: + break; + } + if(exclude.at(index).need_match_all) + optionsToShow.push_back(tr("Full match").toStdString()); + entryShow+=stringimplode(optionsToShow,","); + entryShow+=")"; + ui->exclusion->addItem(new QListWidgetItem(QString::fromStdString(entryShow))); + index++; + } +} + +std::vector Filters::getInclude() const +{ + return include; +} + +std::vector Filters::getExclude() const +{ + return exclude; +} + +void Filters::newLanguageLoaded() +{ + ui->retranslateUi(this); + reShowAll(); +} + +void Filters::updateFilters() +{ + std::vector includeStrings,includeOptions,excludeStrings,excludeOptions; + unsigned int index=0; + while(index<(unsigned int)include.size()) + { + includeStrings.push_back(include.at(index).search_text); + std::vector optionsToShow; + + switch(include.at(index).search_type) + { + case SearchType_rawText: + optionsToShow.push_back("SearchType_rawText"); + break; + case SearchType_simpleRegex: + optionsToShow.push_back("SearchType_simpleRegex"); + break; + case SearchType_perlRegex: + optionsToShow.push_back("SearchType_perlRegex"); + break; + default: + break; + } + switch(include.at(index).apply_on) + { + case ApplyOn_file: + optionsToShow.push_back("ApplyOn_file"); + break; + case ApplyOn_fileAndFolder: + optionsToShow.push_back("ApplyOn_fileAndFolder"); + break; + case ApplyOn_folder: + optionsToShow.push_back("ApplyOn_folder"); + break; + default: + break; + } + if(include.at(index).need_match_all) + optionsToShow.push_back(tr("Full match").toStdString()); + includeOptions.push_back(stringimplode(optionsToShow,";")); + index++; + } + index=0; + while(index<(unsigned int)exclude.size()) + { + excludeStrings.push_back(exclude.at(index).search_text); + std::vector optionsToShow; + + switch(exclude.at(index).search_type) + { + case SearchType_rawText: + optionsToShow.push_back("SearchType_rawText"); + break; + case SearchType_simpleRegex: + optionsToShow.push_back("SearchType_simpleRegex"); + break; + case SearchType_perlRegex: + optionsToShow.push_back("SearchType_perlRegex"); + break; + default: + break; + } + switch(exclude.at(index).apply_on) + { + case ApplyOn_file: + optionsToShow.push_back("ApplyOn_file"); + break; + case ApplyOn_fileAndFolder: + optionsToShow.push_back("ApplyOn_fileAndFolder"); + break; + case ApplyOn_folder: + optionsToShow.push_back("ApplyOn_folder"); + break; + default: + break; + } + if(exclude.at(index).need_match_all) + optionsToShow.push_back(tr("Full match").toStdString()); + excludeOptions.push_back(stringimplode(optionsToShow,";")); + index++; + } + emit sendNewFilters(includeStrings,includeOptions,excludeStrings,excludeOptions); + emit haveNewFilters(); +} + +bool Filters::convertToRegex(Filters_rules &item) +{ + bool isValid=!item.search_text.empty(); + if(isValid) + { + std::regex regex; + std::string tempString; + if(item.search_type==SearchType_rawText) + { + tempString=QRegularExpression::escape(QString::fromStdString(item.search_text)).toStdString(); + if(tempString.find('/') != std::string::npos || tempString.find('\\') != std::string::npos) + isValid=false; + } + else if(item.search_type==SearchType_simpleRegex) + { + tempString=QRegularExpression::escape(QString::fromStdString(item.search_text)).toStdString(); + stringreplaceAll(tempString,"\\*","[^\\\\/]*"); + } + else if(item.search_type==SearchType_perlRegex) + { + tempString=item.search_text; + if(stringStartWith(tempString,'^') && stringEndsWith(tempString,'$')) + { + item.need_match_all=true; + if(stringStartWith(tempString,'^')) + tempString=tempString.substr(1,tempString.size()-1); + if(stringEndsWith(tempString,'$')) + tempString=tempString.substr(0,tempString.size()-1); + item.search_text=tempString; + } + } + if(isValid) + { + if(item.need_match_all==true) + tempString="^"+tempString+"$"; + regex=std::regex(tempString); + //isValid=regex.isValid(); + item.regex=regex; + return true; + } + else + return false; + } + return false; +} + +void Filters::on_remove_exclusion_clicked() +{ + bool removedEntry=false; + int index=0; + while(indexexclusion->count()) + { + if(ui->exclusion->item(index)->isSelected()) + { + delete ui->exclusion->item(index); + exclude.erase(exclude.cbegin()+index); + removedEntry=true; + } + else + index++; + } + if(removedEntry) + { + reShowAll(); + updateFilters(); + } +} + +void Filters::on_remove_inclusion_clicked() +{ + bool removedEntry=false; + int index=0; + while(indexinclusion->count()) + { + if(ui->inclusion->item(index)->isSelected()) + { + delete ui->inclusion->item(index); + include.erase(include.cbegin()+index); + removedEntry=true; + } + else + index++; + } + if(removedEntry) + { + reShowAll(); + updateFilters(); + } +} + +void Filters::on_add_exclusion_clicked() +{ + FilterRules dialog(this); + dialog.exec(); + if(dialog.getIsValid()) + { + Filters_rules new_item; + new_item.apply_on=dialog.get_apply_on(); + new_item.need_match_all=dialog.get_need_match_all(); + new_item.search_text=dialog.get_search_text(); + new_item.search_type=dialog.get_search_type(); + exclude.push_back(new_item); + reShowAll(); + updateFilters(); + } +} + +void Filters::on_buttonBox_clicked(QAbstractButton *button) +{ + if(ui->buttonBox->buttonRole(button)==QDialogButtonBox::RejectRole) + reject(); +} + +void Filters::on_add_inclusion_clicked() +{ + FilterRules dialog(this); + dialog.exec(); + if(dialog.getIsValid()) + { + Filters_rules new_item; + new_item.apply_on=dialog.get_apply_on(); + new_item.need_match_all=dialog.get_need_match_all(); + new_item.search_text=dialog.get_search_text(); + new_item.search_type=dialog.get_search_type(); + if(convertToRegex(new_item)) + include.push_back(new_item); + reShowAll(); + updateFilters(); + } +} + +void Filters::on_edit_exclusion_clicked() +{ + bool editedEntry=false; + int index=0; + while(indexexclusion->count()) + { + if(ui->exclusion->item(index)->isSelected()) + { + FilterRules dialog(this); + dialog.set_apply_on(exclude.at(index).apply_on); + dialog.set_need_match_all(exclude.at(index).need_match_all); + dialog.set_search_text(exclude.at(index).search_text); + dialog.set_search_type(exclude.at(index).search_type); + dialog.exec(); + if(dialog.getIsValid()) + { + exclude[index].apply_on=dialog.get_apply_on(); + exclude[index].need_match_all=dialog.get_need_match_all(); + exclude[index].search_text=dialog.get_search_text(); + exclude[index].search_type=dialog.get_search_type(); + if(!convertToRegex(exclude[index])) + exclude.erase(exclude.cbegin()+index); + editedEntry=true; + } + } + index++; + } + if(editedEntry) + { + reShowAll(); + updateFilters(); + } +} + +void Filters::on_edit_inclusion_clicked() +{ + bool editedEntry=false; + int index=0; + while(indexinclusion->count()) + { + if(ui->inclusion->item(index)->isSelected()) + { + FilterRules dialog(this); + dialog.set_apply_on(exclude.at(index).apply_on); + dialog.set_need_match_all(exclude.at(index).need_match_all); + dialog.set_search_text(exclude.at(index).search_text); + dialog.set_search_type(exclude.at(index).search_type); + dialog.exec(); + if(dialog.getIsValid()) + { + exclude[index].apply_on=dialog.get_apply_on(); + exclude[index].need_match_all=dialog.get_need_match_all(); + exclude[index].search_text=dialog.get_search_text(); + exclude[index].search_type=dialog.get_search_type(); + if(!convertToRegex(exclude[index])) + exclude.erase(exclude.cbegin()+index); + editedEntry=true; + } + } + index++; + } + if(editedEntry) + { + reShowAll(); + updateFilters(); + } +} diff --git a/plugins/CopyEngine/Ultracopier/Filters.h b/plugins/CopyEngine/Ultracopier/Filters.h new file mode 100644 index 0000000..6645afc --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Filters.h @@ -0,0 +1,45 @@ +#ifndef FILTERS_H +#define FILTERS_H + +#include +#include + +#include "FilterRules.h" +#include "StructEnumDefinition_CopyEngine.h" + +namespace Ui { +class Filters; +} + +/** To add/edit one filter rules */ +class Filters : public QDialog +{ + Q_OBJECT +public: + explicit Filters(QWidget *parent = 0); + ~Filters(); + void setFilters(std::vector includeStrings, std::vector includeOptions, std::vector excludeStrings, std::vector excludeOptions); + void reShowAll(); + std::vector getInclude() const; + std::vector getExclude() const; + void newLanguageLoaded(); +private: + Ui::Filters *ui; + std::vector include; + std::vector exclude; + void updateFilters(); + bool convertToRegex(Filters_rules &item); +signals: + void sendNewFilters(const std::vector &includeStrings,const std::vector &includeOptions,const std::vector &excludeStrings,const std::vector &excludeOptions) const; + void haveNewFilters() const; +private slots: + void on_remove_exclusion_clicked(); + void on_remove_inclusion_clicked(); + void on_add_exclusion_clicked(); + void on_buttonBox_clicked(QAbstractButton *button); + void on_add_inclusion_clicked(); + void on_edit_exclusion_clicked(); + void on_edit_inclusion_clicked(); +}; + +#endif // FILTERS_H diff --git a/plugins/CopyEngine/Ultracopier/Filters.ui b/plugins/CopyEngine/Ultracopier/Filters.ui new file mode 100644 index 0000000..33822af --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Filters.ui @@ -0,0 +1,194 @@ + + + Filters + + + + 0 + 0 + 507 + 502 + + + + Filters + + + + :/CopyEngine/Ultracopier/resources/filter.png:/CopyEngine/Ultracopier/resources/filter.png + + + + 1 + + + 1 + + + + + Exclusion filters + + + + 1 + + + 2 + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + :/CopyEngine/Ultracopier/resources/add.png:/CopyEngine/Ultracopier/resources/add.png + + + + + + + + :/CopyEngine/Ultracopier/resources/edit.png:/CopyEngine/Ultracopier/resources/edit.png + + + + + + + + :/CopyEngine/Ultracopier/resources/remove.png:/CopyEngine/Ultracopier/resources/remove.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Inclusion filters + + + + 1 + + + 2 + + + + + None = Include all + + + + + + + + + QAbstractItemView::MultiSelection + + + + + + + + + + :/CopyEngine/Ultracopier/resources/add.png:/CopyEngine/Ultracopier/resources/add.png + + + + + + + + :/CopyEngine/Ultracopier/resources/edit.png:/CopyEngine/Ultracopier/resources/edit.png + + + + + + + + :/CopyEngine/Ultracopier/resources/remove.png:/CopyEngine/Ultracopier/resources/remove.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Cancel + + + + + + + + + + + + diff --git a/plugins/CopyEngine/Ultracopier/FolderExistsDialog.cpp b/plugins/CopyEngine/Ultracopier/FolderExistsDialog.cpp new file mode 100644 index 0000000..d05a715 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FolderExistsDialog.cpp @@ -0,0 +1,205 @@ +#include "FolderExistsDialog.h" +#include "ui_folderExistsDialog.h" +#include "TransferThread.h" + +#ifdef Q_OS_WIN32 +#define CURRENTSEPARATOR "\\" +#else +#define CURRENTSEPARATOR "/" +#endif + +#include +#include +#include + +FolderExistsDialog::FolderExistsDialog(QWidget *parent, QFileInfo source, bool isSame, QFileInfo destination, std::string firstRenamingRule, std::string otherRenamingRule) : + QDialog(parent), + ui(new Ui::folderExistsDialog) +{ + Qt::WindowFlags flags = windowFlags(); + #ifdef Q_OS_LINUX + flags=flags & ~Qt::X11BypassWindowManagerHint; + #endif + flags=flags | Qt::WindowStaysOnTopHint; + setWindowFlags(flags); + + ui->setupUi(this); + action=FolderExists_Cancel; + oldName=TransferThread::resolvedName(destination); + ui->lineEditNewName->setText(QString::fromStdString(oldName)); + ui->lineEditNewName->setPlaceholderText(QString::fromStdString(oldName)); + ui->label_content_source_modified->setText(source.lastModified().toString()); + ui->label_content_source_folder_name->setText(source.fileName()); + QString folder=source.absolutePath(); + if(folder.size()>80) + folder=folder.mid(0,38)+"..."+folder.mid(folder.size()-38); + ui->label_content_source_folder->setText(folder); + if(ui->label_content_source_folder_name->text().isEmpty()) + { + ui->label_source_folder_name->hide(); + ui->label_content_source_folder_name->hide(); + } + if(isSame) + { + this->destinationInfo=source; + ui->label_source->hide(); + ui->label_destination->hide(); + ui->label_destination_modified->hide(); + ui->label_destination_folder_name->hide(); + ui->label_destination_folder->hide(); + ui->label_content_destination_modified->hide(); + ui->label_content_destination_folder_name->hide(); + ui->label_content_destination_folder->hide(); + } + else + { + this->destinationInfo=destination; + this->setWindowTitle(tr("Folder already exists")); + ui->label_content_destination_modified->setText(destination.lastModified().toString()); + ui->label_content_destination_folder_name->setText(destination.fileName()); + QString folder=destination.absolutePath(); + if(folder.size()>80) + folder=folder.mid(0,38)+"..."+folder.mid(folder.size()-38); + ui->label_content_destination_folder->setText(folder); + if(ui->label_content_destination_folder_name->text().isEmpty()) + { + ui->label_destination_folder_name->hide(); + ui->label_content_destination_folder_name->hide(); + } + } + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + on_SuggestNewName_clicked(); +} + +FolderExistsDialog::~FolderExistsDialog() +{ + delete ui; +} + +void FolderExistsDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +std::string FolderExistsDialog::getNewName() +{ + if(oldName==ui->lineEditNewName->text().toStdString() || ui->checkBoxAlways->isChecked()) + return ""; + else + return ui->lineEditNewName->text().toStdString(); +} + +void FolderExistsDialog::on_SuggestNewName_clicked() +{ + QFileInfo destinationInfo=this->destinationInfo; + QString absolutePath=destinationInfo.absolutePath(); + QString fileName=QString::fromStdString(TransferThread::resolvedName(destinationInfo)); + QString suffix; + QString destination; + QString newFileName; + //resolv the suffix + if(fileName.contains(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")))) + { + suffix=fileName; + suffix.replace(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")),QStringLiteral("\\2")); + fileName.replace(QRegularExpression(QStringLiteral("^(.*)(\\.[a-z0-9]+)$")),QStringLiteral("\\1")); + } + //resolv the new name + int num=1; + do + { + if(num==1) + { + if(firstRenamingRule.empty()) + newFileName=tr("%1 - copy").arg(fileName); + else + { + newFileName=QString::fromStdString(firstRenamingRule); + newFileName.replace(QStringLiteral("%name%"),fileName); + } + } + else + { + if(otherRenamingRule.empty()) + newFileName=tr("%1 - copy (%2)").arg(fileName).arg(num); + else + { + newFileName=QString::fromStdString(otherRenamingRule); + newFileName.replace(QStringLiteral("%name%"),fileName); + newFileName.replace(QStringLiteral("%number%"),QString::number(num)); + } + } + destination=absolutePath+CURRENTSEPARATOR+newFileName+suffix; + destinationInfo.setFile(destination); + num++; + } + while(destinationInfo.exists()); + ui->lineEditNewName->setText(newFileName+suffix); +} + +void FolderExistsDialog::on_Rename_clicked() +{ + action=FolderExists_Rename; + this->close(); +} + +void FolderExistsDialog::on_Skip_clicked() +{ + action=FolderExists_Skip; + this->close(); +} + +void FolderExistsDialog::on_Cancel_clicked() +{ + action=FolderExists_Cancel; + this->close(); +} + +FolderExistsAction FolderExistsDialog::getAction() +{ + return action; +} + +bool FolderExistsDialog::getAlways() +{ + return ui->checkBoxAlways->isChecked(); +} + +void FolderExistsDialog::on_Merge_clicked() +{ + action=FolderExists_Merge; + this->close(); +} + +void FolderExistsDialog::on_lineEditNewName_editingFinished() +{ + updateRenameButton(); +} + +void FolderExistsDialog::on_lineEditNewName_returnPressed() +{ + updateRenameButton(); + if(ui->Rename->isEnabled()) + on_Rename_clicked(); + else + QMessageBox::warning(this,tr("Error"),tr("Try rename with using special characters")); +} + +void FolderExistsDialog::on_lineEditNewName_textChanged(const std::string &arg1) +{ + Q_UNUSED(arg1); + updateRenameButton(); +} + +void FolderExistsDialog::updateRenameButton() +{ + ui->Rename->setEnabled(ui->checkBoxAlways->isChecked() || (!ui->lineEditNewName->text().contains(QRegularExpression("[/\\\\\\*]")) && oldName!=ui->lineEditNewName->text().toStdString() && !ui->lineEditNewName->text().isEmpty())); +} diff --git a/plugins/CopyEngine/Ultracopier/FolderExistsDialog.h b/plugins/CopyEngine/Ultracopier/FolderExistsDialog.h new file mode 100644 index 0000000..a3bcf67 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/FolderExistsDialog.h @@ -0,0 +1,57 @@ +/** \file folderExistsDialog.h +\brief Define the dialog when file exists +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef FOLDERISSAMEDIALOG_H +#define FOLDERISSAMEDIALOG_H + +#include +#include +#include +#include +#include + +#include "Environment.h" + +namespace Ui { + class folderExistsDialog; +} + +/// \brief to show file exists dialog, and ask what do +class FolderExistsDialog : public QDialog +{ + Q_OBJECT + +public: + /// \brief create the object and pass all the informations to it + explicit FolderExistsDialog(QWidget *parent,QFileInfo source,bool isSame,QFileInfo destination,std::string firstRenamingRule,std::string otherRenamingRule); + ~FolderExistsDialog(); + /// \brief return the the always checkbox is checked + bool getAlways(); + /// \brief return the action clicked + FolderExistsAction getAction(); + /// \brief return the new rename is case in manual renaming + std::string getNewName(); +protected: + void changeEvent(QEvent *e); +private slots: + void updateRenameButton(); + void on_SuggestNewName_clicked(); + void on_Rename_clicked(); + void on_Skip_clicked(); + void on_Cancel_clicked(); + void on_Merge_clicked(); + void on_lineEditNewName_editingFinished(); + void on_lineEditNewName_returnPressed(); + void on_lineEditNewName_textChanged(const std::string &arg1); +private: + Ui::folderExistsDialog *ui; + FolderExistsAction action; + std::string oldName; + std::string firstRenamingRule; + std::string otherRenamingRule; + QFileInfo destinationInfo; +}; + +#endif // FOLDERISSAMEDIALOG_H diff --git a/plugins/CopyEngine/Ultracopier/Languages/ar/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/ar/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/ar/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/de/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/de/translation.ts new file mode 100644 index 0000000..cad2890 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/de/translation.ts @@ -0,0 +1,1290 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + Auf dieser Plattform nicht unterstĆ¼tzt + + + + Last modified date is wrong + Datum der letzten Ƅnderung ist falsch + + + + Last access date is wrong + + Datum des letzten Zugriffs ist falsch + + + + Unknown error: %1 + Unbekannter Fehler: %1 + + + + Unknown error + Unbekannter Fehler + + + + Path conversion error + Pfad Konvertierungsfehler + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + Verschiebemodus - Sie kƶnnen nicht kopieren + + + + + The engine is forced to copy, you can't move with it + Kopiermodus - Sie kƶnnen nicht verschieben + + + + Destination + Ziel + + + + Use the actual destination "%1"? + Aktuelles Ziel: "%1" benutzen? + + + + The mode has been forced previously. This is an internal error, please report it + Der Modus wurde vorher erzwungen. Interner Fehler - Bitte bei mir melden! + + + + + + + Ask + Fragen + + + + + + + Skip + Ɯberspringen + + + + Merge + Fusionieren + + + + + Rename + Umbenennen + + + + Put at the end + Ans Ende verschieben + + + + Overwrite + Ɯberschreiben + + + + Overwrite if different + Ɯberschreiben, falls verschieden + + + + Overwrite if newer + Ɯberschreiben, falls neuer + + + + Overwrite if older + Ɯberschreiben, falls Ƥlter + + + + Automatic + Automatisch + + + + Sequential + Sequentiell + + + + Parallel + Parallel + + + + Options error + Fehlerhafte Optionen + + + + Options engine is not loaded. Unable to access the filters + Optionen nicht geladen - Kein Zugriff auf Filter + + + + CopyEngineFactory + + + + + + Ask + Fragen + + + + + + + Skip + Ɯberspringen + + + + Merge + Fusionieren + + + + + Rename + Umbenennen + + + + Put at the end + Ans Ende verschieben + + + + Overwrite + Ɯberschreiben + + + + Overwrite if different + Ɯberschreiben, falls verschieden + + + + Overwrite if newer + Ɯberschreiben, falls neuer + + + + Overwrite if older + Ɯberschreiben, falls Ƥlter + + + + Automatic + Automatisch + + + + Sequential + Sequentiell + + + + Parallel + Parallel + + + + + Options error + Fehlerhafte Optionen + + + + Options engine is not loaded. Unable to access the filters + Option nicht geladen - Kein Zugriff auf Filter + + + + Options engine is not loaded, can't access to the filters + Option nicht geladen - Kann nicht auf Filter zugreifen + + + + DiskSpace + + + Disk space + Speicherplatz + + + + You need more space on this drive to finish this transfer + Zu wenig Speicherplatz auf diesem Laufwerk + + + + Continue + Fortsetzen + + + + Cancel + Abbrechen + + + + Drives %1 have %2 available but need %3 + Laufwerk %1: %2 verfĆ¼gbar %3 benƶtigt + + + + FileErrorDialog + + + Error on folder + Ordnerfehler + + + + Folder name + Ordnername + + + + FileExistsDialog + + + %1 - copy + %1 - Kopie + + + + %1 - copy (%2) + %1 - Kopie (%2) + + + + Error + Fehler + + + + Try rename with using special characters + Versuche Umbenennung mit Sonderzeichen + + + + FileIsSameDialog + + + %1 - copy + %1 - kopieren + + + + %1 - copy (%2) + %1 - kopieren (%2) + + + + Error + Fehler + + + + Try rename with using special characters + Versuche Umbenennung mit Sonderzeichen + + + + FilterRules + + + Search: + Suche: + + + + Search type: + Suche (Typ): + + + + Raw text + Roh-Text + + + + Simplified regex + Vereinfachte RegEx + + + + Perl's regex + Perls RegEx + + + + Apply on: + Anwenden auf: + + + + File + Datei + + + + Folder + Ordner + + + + File and folder + Datei und Ordner + + + + The test string matches with the regex + Die Test-Zeichenfolge stimmt mit RegEx Ć¼berein + + + + Checking + ƜberprĆ¼fen + + + + Test string: + Test-Zeichenfolge: + + + + Filters dialog + Filter-Dialog + + + + Whole string must match + Ganze Zeichenfolge muss Ć¼bereinstimmen + + + + The regex is valid + Die RegEx ist gĆ¼ltig + + + + Filters + + + Filters + Filter + + + + Exclusion filters + AusschlieƟungs-Filter + + + + Inclusion filters + EinschlieƟungs-Filter + + + + None = Include all + Keiner = Alle einschlieƟen + + + + + Raw text + Roh-Text + + + + + Simplified regex + Vereinfachte RegEx + + + + + Perl's regex + Perls RegEx + + + + + Only on file + Nur auf Datei + + + + + Only on folder + Nur auf Ordner + + + + + + + Full match + Volle Ɯbereinstimmung + + + + FolderExistsDialog + + + Folder already exists + Ordner existiert bereits + + + + %1 - copy + %1 - Kopie + + + + %1 - copy (%2) + %1 - Kopie (%2) + + + + Error + Fehler + + + + Try rename with using special characters + Versuche Umbenennung mit Sonderzeichen + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + Falscher Modus: %1 - Kann Element nicht verschieben oder kopieren + + + + + Unable to save the transfer list: %1 + Konnte die Transferliste: %1 nicht speichern + + + + Problem reading file, or file-size is 0 + Lesefehler, oder DateigrĆ¶ĆŸe=0 + + + + Wrong header: "%1" + Falscher Header: "%1" + + + + The transfer list is in mixed mode, but this instance is not in this mode + Die Transferliste ist im gemischten Modus, aber diese Instanz ist nicht im selben Modus + + + + The transfer list is in copy mode, but this instance is not in this mode + Die Transferliste ist im Kopiermodus, aber diese Instanz ist nicht im selben Modus + + + + The transfer list is in move mode, but this instance is not in this mode + Die Transferliste ist im Verschiebe-Modus, aber diese Instanz ist nicht im selben Modus + + + + Some errors have been found during the line parsing + Bei der Zeilenanalyse sind Fehler aufgetreten + + + + Unable to open the transfer list: %1 + Transferliste: %1 kann nicht geƶffnet werden + + + + MkPath + + + Unable to create the folder + Der Ordner kann nicht erstellt werden + + + + The source folder don't exists + Quell-Ordner existiert nicht + + + + Unable to temporary rename the folder + Kann den Ordner nicht temporƤr umbenennen + + + + Unable to do the final real move the folder + Kann den Ordner nicht endgĆ¼ltig verschieben + + + + Unable to move the folder + Kann den Ordner nicht verschieben + + + + + Unable to remove + Kann nicht lƶschen + + + + ReadThread + + + Internal error, please report it! + Interner Fehler - Bitte bei mir melden! + + + + Internal error reading the source file:block size out of range + Interner Fehler beim Lesen der Quelldatei: BlockgrĆ¶ĆŸe auƟerhalb des zulƤssigen Bereichs + + + + + Unable to read the source file: + Die Quelldatei kann nicht gelesen werden: + + + + + File truncated during the read, possible data change + Datei wƤhrend des Lesevorgangs abgeschnitten, Daten wurden mƶglicherweise verƤndert + + + + RenamingRules + + + First renaming + Erste Umbenennung + + + + %name% - copy + %name% should not be translated + %name% - Kopie + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + <html><head/><body><p>Variablen: <span style=" font-weight:600;">%name%</span> fĆ¼r den ursprĆ¼nglichen Dateinamen</p></body></html> + + + + Second renaming + Zweite Umbenennung + + + + %name% - copy (%number%) + %name%, %number% should not be translated + %name% - Kopie (%number%) + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + <html><head/><body><p>Variablen: <span style=" font-weight:600;">%name%</span> fĆ¼r den ursprĆ¼nglichen Dateinamen</p><p><span style=" font-weight:600;">%number%</span> fĆ¼r die zusƤtzliche Zahl</p></body></html> + + + + + %1 - copy + %1 - Kopie + + + + + %1 - copy (%2) + %1 - Kopie (%2) + + + + Renaming rules + Umbennungsregeln + + + + ScanFileOrFolder + + + Blacklisted folder + Ordner der schwarzen Liste + + + + + %1 - copy + %1 - Kopie + + + + + %1 - copy (%2) + %1 - Kopie (%2) + + + + This is not a folder + Dies ist kein Ordner + + + + The folder does exists + Ordner existiert bereits + + + + The folder is not readable + Der Ordner kann nicht gelesen werden + + + + Problem with name encoding + Problem mit der Namen-Encodierung + + + + TransferThread + + + + + + File not found + Datei nicht gefunden + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + Interner Fehler: Bereits geƶffnet + + + + Drive %1 + Laufwerk %1 + + + + Unknown folder + Unbekannter Ordner + + + + root + Stammverzeichnis + + + + %1 - copy + %1 - Kopie + + + + %1 - copy (%2) + %1 - Kopie (%2) + + + + The source doesn't exist + Quelle existiert nicht + + + + + + Unable to change the date + + + + + + The source file doesn't exist + Quelldatei existiert nicht + + + + The checksums do not match + PrĆ¼fsummen sind verschieden + + + + Internal error: The size transfered doesn't match + Interner Fehler: Ubertragene GrĆ¶ĆŸe ungleich + + + + + Unable to do the folder + Ordner kann nicht erstellt werden + + + + Try rename with using special characters + Versuche Umbenennung mit Sonderzeichen + + + + Another file exists at same place + Andere Datei befindet sich am selben Ort + + + + Internal error: The destination is not closed + Interner Fehler: Ziel ist nicht geschlossen + + + + Internal error: The buffer is not empty + Interner Fehler: Puffer ist nicht leer + + + + WriteThread + + + Path resolution error (Empty path) + Pfad-Auflƶsungsfehler (leerer Pfad) + + + + Internal error, please report it! + Interner Fehler - Bitte bei mir melden! + + + + Unable to read the source file: + Quelldatei kann nicht gelesen werden: + + + + File truncated during read, possible data change + Datenabbruch beim Lesen, Daten wurden mƶglicherweise verƤndert + + + + copyEngineOptions + + + Transfer + Ɯbertragung + + + + Move the whole folder + Verschiebe den ganzen Ordner + + + + Transfer the file rights + Ɯbertrage die Dateirechte + + + + Keep the file date + Datum der Dateien beibehalten + + + + Autostart the transfer + Ɯbertragung automatisch starten + + + + + Less performance if checked + Leistung drosseln + + + + Follow the strict order + Genau nach Reihenfolge + + + + Error and collision + Fehler und Kollision + + + + When folder error + Bei Ordnerfehlern: + + + + When file error + Bei Dateifehlern: + + + + When file collision + Bei Dateikollisionen: + + + + When folder collision + Bei Ordnerkollisionen: + + + + Check if destination folder exists + PrĆ¼fen ob Zielordner vorhanden ist + + + + Renaming rules + Umbennungsregeln + + + + Delete partially transferred files + UnvollstƤndig Ć¼bertragene Dateien lƶschen + + + + Rename the original destination + Original-Ziel umbenennen + + + + Control + ƜberprĆ¼fung + + + + Checksum + PrĆ¼fsumme + + + + Only after error + Nur nach einem Fehler + + + + Ignore if impossible + Ignorieren falls unmƶglich + + + + Verify checksums + PrĆ¼fsummen vergleichen + + + + Performance + Leistung + + + + Parallel buffer + Paralleler Puffer + + + + + + + + KB + KB + + + + Block size + BlockgrĆ¶ĆŸe + + + + Sequential buffer + Sequentieller Puffer + + + + Enable OS buffer + OS-Puffer aktivieren + + + + OS buffer only if smaller than + OS-Puffer nur verwenden, wenn kleiner als + + + + Transfer algorithm + Ɯbertragungs-Algorithmus + + + + Parallelize if smaller than + Parallelisieren wenn kleiner als + + + + Inode threads + Inode Threads + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + Verschiedenes + + + + Check the disk space + Auf freien Speicherplatz Ć¼berprĆ¼fen + + + + Use this folder when destination is not set + + + + + Browse + WƤhlen + + + + Filters + Filter + + + + fileErrorDialog + + + Error with file + Dateifehler + + + + Error + Fehler + + + + Size + GrĆ¶ĆŸe + + + + Modified + GeƤndert + + + + File name + Dateiname + + + + Destination + Ziel + + + + Folder + Ordner + + + + &Always perform this action + &Aktion immer ausfĆ¼hren + + + + Try in with elevated privileges + Mit erweiterten Rechten versuchen + + + + Put to bottom + Ans Ende verschieben + + + + Retry + Wiederholen + + + + &Skip + Ɯber&springen + + + + &Cancel + Abbrechen (&C) + + + + fileExistsDialog + + + The file exists + Die Datei existiert + + + + Source + Quelle + + + + Destination + Ziel + + + + + Size + GrĆ¶ĆŸe + + + + + Modified + GeƤndert + + + + + File name + Dateiname + + + + + Folder + Ordner + + + + Suggest new &name + Neuen &Namen vorschlagen + + + + &Always perform this action + &Aktion immer ausfĆ¼hren + + + + + Overwrite if modification date differs + Ɯberschreiben, falls Ƅnderungsdatum verschieden + + + + &Rename + Umbenennen (&R) + + + + &Overwrite + Ɯberschreiben (&O) + + + + &Skip + Ɯber&springen + + + + &Cancel + Abbrechen (&C) + + + + Overwrite if newer + Ɯberschreiben, falls neuer + + + + + Overwrite if older + Ɯberschreiben, falls Ƥlter + + + + fileIsSameDialog + + + Size + GrĆ¶ĆŸe + + + + Modified + GeƤndert + + + + File name + Dateiname + + + + The source and destination are same + Quelle und Ziel sind gleich + + + + Folder + Ordner + + + + Suggest new &name + Neuen &Namen vorschlagen + + + + &Always perform this action + &Aktion immer ausfĆ¼hren + + + + &Rename + Umbenennen (&R) + + + + &Skip + Ɯber&springen + + + + &Cancel + Abbrechen (&C) + + + + folderExistsDialog + + + Source + Quelle + + + + Destination + Ziel + + + + The source and destination is identical + Quelle und Ziel sind identisch + + + + + Modified + GeƤndert + + + + + Folder name + Ordnername + + + + + Folder + Ordner + + + + Suggest new &name + Neuen &Namen vorschlagen + + + + &Always perform this action + &Aktion immer ausfĆ¼hren + + + + &Rename + Umbenennen (&R) + + + + Merge + Fusionieren + + + + Skip + Ɯberspringen + + + + &Cancel + Abbrechen (&C) + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/el/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/el/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/el/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/en/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/en/translation.ts new file mode 100644 index 0000000..2c9ce27 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/en/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Filters dialog + + + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + Whole string must match + + + + + The test string matches with the regex + + + + + Checking + + + + + The regex is valid + + + + + Test string: + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + Renaming rules + + + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/es/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/es/translation.ts new file mode 100644 index 0000000..9cb6abe --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/es/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + No es compatible con esta plataforma + + + + Last modified date is wrong + Fecha de Ćŗltima modificaciĆ³n es incorrecto + + + + Last access date is wrong + Fecha de Ćŗltimo acceso es incorrecto + + + + Unknown error: %1 + Error desconocido: %1 + + + + Unknown error + Error desconocido + + + + Path conversion error + Error de conversiĆ³n de Sendero + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + El motor se ve obligado a moverse, no se puede copiar con ella + + + + + The engine is forced to copy, you can't move with it + El motor se ve obligado a copiar, no te puedes mover con Ć©l + + + + Destination + Destino + + + + Use the actual destination "%1"? + Utilice el destino "%1" actual? + + + + The mode has been forced previously. This is an internal error, please report it + El modo se ha visto obligado previamente. Este es un error interno, por favor repĆ³rtelo + + + + + + + Ask + Pedir + + + + + + + Skip + Omitir + + + + Merge + Unir + + + + + Rename + Cambiar el nombre + + + + Put at the end + Ponga al final + + + + Overwrite + Sobrescribir + + + + Overwrite if different + Sobrescribir si es diferente + + + + Overwrite if newer + Sobrescribir si nuevo + + + + Overwrite if older + Sobrescribir si es mayor + + + + Automatic + AutomĆ”tico + + + + Sequential + Secuencial + + + + Parallel + Paralelo + + + + Options error + error Opciones + + + + Options engine is not loaded. Unable to access the filters + Opciones del motor no estĆ” cargado. No es posible acceder a los filtros + + + + CopyEngineFactory + + + + + + Ask + Pedir + + + + + + + Skip + Omitir + + + + Merge + Unir + + + + + Rename + Cambiar el nombre + + + + Put at the end + Ponga al final + + + + Overwrite + Sobrescribir + + + + Overwrite if different + Sobrescribir si es diferente + + + + Overwrite if newer + Sobrescribir si nuevo + + + + Overwrite if older + Sobrescribir si es mayor + + + + Automatic + AutomĆ”tico + + + + Sequential + Secuencial + + + + Parallel + Paralelo + + + + + Options error + error Opciones + + + + Options engine is not loaded. Unable to access the filters + Opciones del motor no estĆ” cargado. No es posible acceder a los filtros + + + + Options engine is not loaded, can't access to the filters + Opciones del motor no estĆ” cargado, no se puede acceder a los filtros + + + + DiskSpace + + + Disk space + Espacio en disco + + + + You need more space on this drive to finish this transfer + Necesita mĆ”s espacio en esta unidad para terminar esta transferencia + + + + Continue + Continuar + + + + Cancel + Cancelar + + + + Drives %1 have %2 available but need %3 + Drives %1 tienen %2 disponible, pero necesitan %3 + + + + FileErrorDialog + + + Error on folder + Error en la carpeta + + + + Folder name + Nombre de la carpeta + + + + FileExistsDialog + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Error + Error + + + + Try rename with using special characters + Trate de cambiar el nombre con el uso de caracteres especiales + + + + FileIsSameDialog + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Error + Error + + + + Try rename with using special characters + Trate de cambiar el nombre con el uso de caracteres especiales + + + + FilterRules + + + Search: + Buscar: + + + + Search type: + Tipo de bĆŗsqueda: + + + + Raw text + texto Fuente + + + + Simplified regex + Regex simplificado + + + + Perl's regex + Perl's regex + + + + Apply on: + Aplicar sobre: + + + + File + Archivos + + + + Folder + Carpeta + + + + File and folder + Archivos y carpeta + + + + The test string matches with the regex + La cadena de prueba coincide con la expresiĆ³n regular + + + + Checking + Verification + + + + Test string: + Prueba de la cuerda: + + + + Filters dialog + Filtros de diĆ”logo + + + + Whole string must match + Todo cadena debe coincidir + + + + The regex is valid + La expresiĆ³n regular es vĆ”lido + + + + Filters + + + Filters + Filtros + + + + Exclusion filters + Filtros de exclusiĆ³n + + + + Inclusion filters + Filtros de inclusiĆ³n + + + + None = Include all + Ninguno = Incluya todos los + + + + + Raw text + texto Fuente + + + + + Simplified regex + Simplificado regex + + + + + Perl's regex + Perl's regex + + + + + Only on file + SĆ³lo en el archivo + + + + + Only on folder + SĆ³lo en la carpeta + + + + + + + Full match + Partido completo + + + + FolderExistsDialog + + + Folder already exists + Carpeta ya existe + + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Error + Error + + + + Try rename with using special characters + Trate de cambiar el nombre con el uso de caracteres especiales + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + No se puede hacer para mover o copiar elemento en modo incorrecto obligado: %1 + + + + + Unable to save the transfer list: %1 + No se puede guardar la lista de transferencias: %1 + + + + Problem reading file, or file-size is 0 + Problema al leer el archivo o archivos de tamaƱo es 0 + + + + Wrong header: "%1" + Encabezado incorrecto: "%1" + + + + The transfer list is in mixed mode, but this instance is not in this mode + La lista de transferencia estĆ” en modo mixto, pero este caso no es de este modo + + + + The transfer list is in copy mode, but this instance is not in this mode + La lista de transferencia estĆ” en el modo de copia, pero esta instancia no estĆ” en este modo + + + + The transfer list is in move mode, but this instance is not in this mode + La lista de transferencia es el modo de desplazamiento, pero esta instancia no estĆ” en este modo + + + + Some errors have been found during the line parsing + Algunos errores han sido encontrados durante el anĆ”lisis de lĆ­nea + + + + Unable to open the transfer list: %1 + No se puede abrir la lista de transferencias: %1 + + + + MkPath + + + Unable to create the folder + No se puede crear la carpeta + + + + The source folder don't exists + La carpeta de origen no existe + + + + Unable to temporary rename the folder + No es posible cambiar el nombre de la carpeta temporal + + + + Unable to do the final real move the folder + No se puede hacer el movimiento final real de la carpeta + + + + Unable to move the folder + No se puede mover la carpeta + + + + + Unable to remove + No se puede eliminar + + + + ReadThread + + + Internal error, please report it! + Error interno, por favor informe de ello! + + + + Internal error reading the source file:block size out of range + Error interno de leer el archivo de origen: tamaƱo de bloque fuera de rango + + + + + Unable to read the source file: + No se puede leer el archivo de origen: + + + + + File truncated during the read, possible data change + Archivo truncada durante el cambio de lectura, los datos posibles + + + + RenamingRules + + + First renaming + En primer lugar el cambio de nombre + + + + %name% - copy + %name% should not be translated + %name% - copia + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> para el nombre del archivo original</p></body></html> + + + + Second renaming + En segundo lugar el cambio de nombre + + + + %name% - copy (%number%) + %name%, %number% should not be translated + %name% - copia (%number%) + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> para el nombre del archivo original</p><p><span style=" font-weight:600;">%number%</span> para el nĆŗmero adicional</p></body></html> + + + + + %1 - copy + %1 - copia + + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Renaming rules + Reglas de Cambio de nombre + + + + ScanFileOrFolder + + + Blacklisted folder + Carpeta de la lista negra + + + + + %1 - copy + %1 - copia + + + + + %1 - copy (%2) + %1 - copia (%2) + + + + This is not a folder + Esto no es una carpeta + + + + The folder does exists + La carpeta no existe + + + + The folder is not readable + La carpeta no se puede leer + + + + Problem with name encoding + Problema con codificaciĆ³n de nombres + + + + TransferThread + + + + + + File not found + Archivo no encontrado + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + Error interno: Ya la apertura + + + + Drive %1 + Drive %1 + + + + Unknown folder + Desconocido carpeta + + + + root + raĆ­z + + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + The source doesn't exist + La fuente no existe + + + + + + Unable to change the date + + + + + + The source file doesn't exist + El archivo de origen no existe + + + + The checksums do not match + Las sumas de comprobaciĆ³n no coinciden + + + + Internal error: The size transfered doesn't match + Error interno: El tamaƱo transferido no coincide + + + + + Unable to do the folder + Incapaz de hacer la carpeta + + + + Try rename with using special characters + Trate de cambiar el nombre con el uso de caracteres especiales + + + + Another file exists at same place + Otro archivo existe en el mismo lugar + + + + Internal error: The destination is not closed + Error interno: El destino no estĆ” cerrado + + + + Internal error: The buffer is not empty + Error interno: El buffer no estĆ” vacĆ­o + + + + WriteThread + + + Path resolution error (Empty path) + Error de resoluciĆ³n de ruta (camino vacĆ­o) + + + + Internal error, please report it! + Error interno, por favor informe de ello! + + + + Unable to read the source file: + No se puede leer el archivo de origen: + + + + File truncated during read, possible data change + Archivo truncado durante lectura, posible cambio de datos + + + + copyEngineOptions + + + Transfer + Transferencia + + + + Move the whole folder + Mueva la carpeta completa + + + + Transfer the file rights + Transferencia de los derechos de archivo + + + + Keep the file date + Mantener la fecha de archivo + + + + Autostart the transfer + Inicio automĆ”tico de la transferencia + + + + + Less performance if checked + Si comprueba Menos rendimiento + + + + Follow the strict order + Siga el orden estricto + + + + Error and collision + Error y de la colisiĆ³n + + + + When folder error + Cuando el error carpeta + + + + When file error + Cuando archivo error + + + + When file collision + Cuando archivo colisiĆ³n + + + + When folder collision + Cuando la colisiĆ³n carpeta + + + + Check if destination folder exists + Compruebe si existe la carpeta de destino + + + + Renaming rules + Reglas de Cambio de nombre + + + + Delete partially transferred files + Eliminar archivos parcialmente transferidos + + + + Rename the original destination + Cambie el nombre del destino original + + + + Control + Controlar + + + + Checksum + Suma de comprobaciĆ³n + + + + Only after error + SĆ³lo despuĆ©s de un error + + + + Ignore if impossible + No haga caso si no es posible + + + + Verify checksums + Verifique checksums + + + + Performance + Rendimiento + + + + Parallel buffer + BĆŗfer paralelo + + + + + + + + KB + KB + + + + Block size + TamaƱo del bloque + + + + Sequential buffer + TampĆ³n secuencial + + + + Enable OS buffer + Habilitar el OS de amortiguaciĆ³n + + + + OS buffer only if smaller than + OS de amortiguaciĆ³n sĆ³lo si menor que + + + + Transfer algorithm + Algoritmo de transferencia + + + + Parallelize if smaller than + Paralelice si mĆ”s pequeƱo que + + + + Inode threads + Temas inodo + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + Misc + + + + Check the disk space + Compruebe el espacio en disco + + + + Use this folder when destination is not set + + + + + Browse + Busque + + + + Filters + Filtros + + + + fileErrorDialog + + + Error with file + Error con el archivo + + + + Error + Error + + + + Size + TamaƱo + + + + Modified + Modificado + + + + File name + Nombre de archivo + + + + Destination + Destino + + + + Folder + Carpeta + + + + &Always perform this action + &Siempre realice esta acciĆ³n + + + + Try in with elevated privileges + Pruebe con privilegios elevados + + + + Put to bottom + Ponga a abajo + + + + Retry + Reintentar + + + + &Skip + &Omitir + + + + &Cancel + Cancelar + + + + fileExistsDialog + + + The file exists + El archivo ya existe + + + + Source + Fuente + + + + Destination + Destino + + + + + Size + TamaƱo + + + + + Modified + Modificado + + + + + File name + Nombre de archivo + + + + + Folder + Carpeta + + + + Suggest new &name + Sugerir nuevo &nombre + + + + &Always perform this action + &Siempre realice esta acciĆ³n + + + + + Overwrite if modification date differs + Sobrescribir si la fecha de modificaciĆ³n difiere + + + + &Rename + &Cambiar el nombre + + + + &Overwrite + &Sobrescribir + + + + &Skip + &Omitir + + + + &Cancel + Ca&ncelar + + + + Overwrite if newer + Sobrescribir si nuevo + + + + + Overwrite if older + Sobrescribir si es mayor + + + + fileIsSameDialog + + + Size + TamaƱo + + + + Modified + Modificado + + + + File name + Nombre de archivo + + + + The source and destination are same + El origen y el destino son los mismos + + + + Folder + Carpeta + + + + Suggest new &name + Sugerir nuevo nombre + + + + &Always perform this action + &Siempre realice esta acciĆ³n + + + + &Rename + Cambiar el nombre + + + + &Skip + Omitir + + + + &Cancel + Cancelar + + + + folderExistsDialog + + + Source + Fuente + + + + Destination + Destino + + + + The source and destination is identical + La fuente y el destino es idĆ©ntica + + + + + Modified + Modificado + + + + + Folder name + Nombre de la carpeta + + + + + Folder + Carpeta + + + + Suggest new &name + Sugerir nuevo nombre + + + + &Always perform this action + &Siempre realice esta acciĆ³n + + + + &Rename + Cambiar el nombre + + + + Merge + Unir + + + + Skip + Omitir + + + + &Cancel + Cancelar + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/fr/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/fr/translation.ts new file mode 100644 index 0000000..13ac433 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/fr/translation.ts @@ -0,0 +1,1294 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + Non supportĆ© sur cette plateforme + + + + Last modified date is wrong + Date de derniĆØre modification du fichier incorrecte + + + + Last access date is wrong + Date du dernier accĆØs au fichier incorrecte + + + + Unknown error: %1 + Erreur inconnue: %1 + + + + Unknown error + Erreur inconnue + + + + Path conversion error + Erreur de conversion de chemain + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + Le moteur est forcĆ© en dĆ©placement, vous ne pouvez pas copier avec + + + + + The engine is forced to copy, you can't move with it + Le moteur est forcĆ© en copie, vous ne pouvez pas dĆ©placer avec + + + + Destination + Destination + + + + Use the actual destination "%1"? + Utiliser la destination actuelle "%1"? + + + + The mode has been forced previously. This is an internal error, please report it + Le mode a Ć©tĆ© forcĆ©. C'est une erreur interne, merci de la repporter + + + + + + + Ask + Demander + + + + + + + Skip + Passer + + + + Merge + Fusionner + + + + + Rename + Renommer + + + + Put at the end + Mettre Ć  la fin + + + + Overwrite + Ɖcraser + + + + Overwrite if different + Ɖcraser si diffĆ©rent + + + + Overwrite if newer + Ɖcraser si plus rĆ©cent + + + + Overwrite if older + Ɖcraser si plus vieux + + + + Automatic + Automatique + + + + Sequential + SĆ©quentiel + + + + Parallel + ParallĆØle + + + + Options error + Erreur d'options + + + + Options engine is not loaded. Unable to access the filters + Le moteur d'options n'est pas chargĆ©. Impossible d'accĆ©dĆ© aux filtres + + + + CopyEngineFactory + + + + + + Ask + Demander + + + + + + + Skip + Passer + + + + Merge + Fusionner + + + + + Rename + Renommer + + + + Put at the end + Mettre Ć  la fin + + + + Overwrite + Ɖcraser + + + + Overwrite if different + Ɖcraser si diffĆ©rent + + + + Overwrite if newer + Ɖcraser si plus rĆ©cent + + + + Overwrite if older + Ɖcraser si plus vieux + + + + Automatic + Automatique + + + + Sequential + SĆ©quentiel + + + + Parallel + ParallĆØle + + + + + Options error + Erreur d'options + + + + Options engine is not loaded. Unable to access the filters + Le moteur d'options n'est pas chargĆ©. Impossible d'accĆ©dĆ© aux filtres + + + + Options engine is not loaded, can't access to the filters + Moteur d'options non chargĆ©, impossible d'accĆ©der aux filtres + + + + DiskSpace + + + Disk space + Espace disque + + + + You need more space on this drive to finish this transfer + Vous avez besoin de plus d'espace pour finir ce transfert + + + + Continue + Continuer + + + + Cancel + Annuler + + + + Drives %1 have %2 available but need %3 + Lecteur %1 as %2 disponible mais Ć  besoin de %3 + + + + FileErrorDialog + + + Error on folder + Erreur sur un dossier + + + + Folder name + Nom de rĆ©pertoire + + + + FileExistsDialog + + + %1 - copy + %1 - copie + + + + %1 - copy (%2) + %1 - copie (%2) + + + + Error + Erreur + + + + Try rename with using special characters + Essaie de renommage avec caratĆ©res interdits + + + + FileIsSameDialog + + + %1 - copy + %1 - copie + + + + %1 - copy (%2) + %1 - copie (%2) + + + + Error + Erreur + + + + Try rename with using special characters + Essaie de renommage avec caratĆ©res interdits + + + + FilterRules + + + Search: + Recherche: + + + + Search type: + Type de recherche: + + + + Raw text + Texte brut + + + + Simplified regex + Regex simplifiĆ©e + + + + Perl's regex + Regex perl + + + + Apply on: + Appliquer sur: + + + + File + Fichier + + + + Folder + Dossier + + + + File and folder + Fichier et dossier + + + + The test string matches with the regex + La chaine de texte corresponds avec la regex + + + + Checking + VĆ©rification + + + + Test string: + Chaine de test: + + + + Filters dialog + Dialogue des filtres + + + + Whole string must match + Toute la chaine doit correspondre + + + + The regex is valid + La regex est valid + + + + Filters + + + Filters + Filtres + + + + Exclusion filters + Filtres d'exclusion + + + + Inclusion filters + Filtres d'inclusion + + + + None = Include all + Aucun = tout inclure + + + + + Raw text + Texte brute + + + + + Simplified regex + Regex simplifiĆ© + + + + + Perl's regex + Regex perl + + + + + Only on file + Appliquer sur fichier + + + + + Only on folder + Appliquer sur dossier + + + + + + + Full match + Correspondance totale + + + + FolderExistsDialog + + + Folder already exists + Dossier dĆ©jĆ  existant + + + + %1 - copy + %1 - copie + + + + %1 - copy (%2) + %1 - copie (%2) + + + + Error + Erreur + + + + Try rename with using special characters + Essaie de renommage avec caratĆ©res interdits + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + Impossible de faire un dĆ©placement ou une copie dans le mauvais mode forcĆ©: %1 + + + + + Unable to save the transfer list: %1 + Impossible de sauvegarder la liste de transfert: %1 + + + + Problem reading file, or file-size is 0 + Problem durant la lecture, ou taille de fichier est 0 + + + + Wrong header: "%1" + Mauvais en-tĆŖte: "%1" + + + + The transfer list is in mixed mode, but this instance is not in this mode + La liste de transfert est en mode mixte, mais l'instance n'est pas dans ce mode + + + + The transfer list is in copy mode, but this instance is not in this mode + La liste de transfert est en mode copie, mais l'instance n'est pas dans ce mode + + + + The transfer list is in move mode, but this instance is not in this mode + La liste de transfert est en mode dĆ©placement, mais l'instance n'est pas dans ce mode + + + + Some errors have been found during the line parsing + Certaine erreur ont Ć©tĆ© trouvĆ© durant l'analise de la line + + + + Unable to open the transfer list: %1 + Impossible d'ouvrir la list de transfert: %1 + + + + MkPath + + + Unable to create the folder + Impossible de crĆ©er le rĆ©pertoire + + + + The source folder don't exists + Le dossier source n'Ć©xiste pas + + + + Unable to temporary rename the folder + Impossible de renommer le dossier + + + + Unable to do the final real move the folder + Impossible de faire le dĆ©placement final du dossier + + + + Unable to move the folder + Impossible de dĆ©placer le dossier + + + + + Unable to remove + Impossible de supprimer + + + + ReadThread + + + Internal error, please report it! + Erreur interne, merci de la reporter! + + + + Internal error reading the source file:block size out of range + Erreur interne lisant le fichier source: taille de block hors de la plage + + + + + Unable to read the source file: + Impossible de lire le fichier source: + + + + + File truncated during the read, possible data change + La taille du fichier a diminuĆ© durant -> changĆ© le texte original + Fichier a diminuĆ© durant la lecture, possible changement de donnĆ©es + + + + RenamingRules + + + First renaming + Premier renommage + + + + %name% - copy + %name% should not be translated + variables need never be translated + %name% - copie + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + variables need never be translated + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> pour le nom originel</p></body></html> + + + + Second renaming + Second renommage + + + + %name% - copy (%number%) + %name%, %number% should not be translated + variables need never be translated + %name% - copie (%number%) + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + variables need never be translated + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> pour le nom originel</p><p><span style=" font-weight:600;">%number%</span> pour le nombre extra</p></body></html> + + + + + %1 - copy + %1 - copie + + + + + %1 - copy (%2) + %1 - copie (%2) + + + + Renaming rules + RĆØgles de renommage + + + + ScanFileOrFolder + + + Blacklisted folder + Dossier banis + + + + + %1 - copy + %1 - copie + + + + + %1 - copy (%2) + %1 - copie (%2) + + + + This is not a folder + N'est pas un dossier + + + + The folder does exists + Le rĆ©pertoire n'existe pas + + + + The folder is not readable + Le rĆ©pertoire n'est pas lisible + + + + Problem with name encoding + ProblĆ©m d'encodage + + + + TransferThread + + + + + + File not found + Fichier non trouvĆ© + + + + Drive %1 + Lecteur %1 + + + + Unknown folder + Dossier inconnu + + + + root + racine + + + + %1 - copy + %1 - copie + + + + %1 - copy (%2) + %1 - copie (%2) + + + + The source doesn't exist + La source n'existe pas + + + + + The source file doesn't exist + Le fichier source n'existe pas + + + + The checksums do not match + Les sommes de controle ne correspondent pas + + + + Internal error: The size transfered doesn't match + Erreur interne: La taille transfĆ©rĆ© ne corresponds pas + + + + + Unable to do the folder + Impossible de crĆ©er le dossier + + + + Try rename with using special characters + Essaie de renommage avec caratĆ©res interdits + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + Mauvaise date de modification ou impossible de l'avoir, vous pouvez dĆ©sactivĆ© le transfert de celui-ci + + + + + Internal error: Already opening + Erreur interne: DĆ©jĆ  ouvert + + + + Another file exists at same place + Un autre fichier exists Ć  la mĆŖme place + + + + Internal error: The destination is not closed + Erreur interne: La destination n'est pas fermĆ© + + + + Internal error: The buffer is not empty + Erreur interne: Le buffer n'est pas vide + + + + + + Unable to change the date + Impossible de changer la date + + + + WriteThread + + + Path resolution error (Empty path) + Erreur de rĆ©solution de chemain (chemain vide) + + + + Internal error, please report it! + Erreur interne, merci de la reporter! + + + + Unable to read the source file: + Impossible de lire le fichier source: + + + + File truncated during read, possible data change + Fichier rĆ©trĆ©ci pendant la lecture, possible changement de donnĆ©es + + + + copyEngineOptions + + + Transfer + Transfert + + + + Move the whole folder + DĆ©placer le dossier complet + + + + Transfer the file rights + TransfĆ©rer les droits des fichiers + + + + Keep the file date + Garder la date du fichier + + + + Autostart the transfer + DĆ©marrer automatiquement le transfert + + + + + Less performance if checked + Moins de performance si cochĆ© + + + + Follow the strict order + Suivre l'ordre strict + + + + Error and collision + Erreur et collision + + + + When folder error + En cas d'erreur de rĆ©pertoire + + + + When file error + En cas d'erreur de fichier + + + + When file collision + En cas de collision de fichier + + + + When folder collision + Lors d'une collision de dossier + + + + Check if destination folder exists + VĆ©rifier si le rĆ©pertoire de destination existe + + + + Renaming rules + RĆØgles de renommage + + + + Delete partially transferred files + Supprimer les transferts partiels + + + + Rename the original destination + Renommer la destination originale + + + + Control + Controle + + + + Checksum + Somme de contrĆ“le + + + + Only after error + Seulement aprĆØs erreur + + + + Ignore if impossible + Ignorer si impossible + + + + Verify checksums + VĆ©rifier les sommes de contrĆ“les + + + + Performance + Performance + + + + Parallel buffer + Buffer parallĆ©le + + + + + + + + KB + Ko + + + + Block size + Taille de bloc + + + + Sequential buffer + Buffer sĆ©quentiel + + + + Enable OS buffer + Activer le tampon de l'OS + + + + OS buffer only if smaller than + Tampon de l'OS seulement si plus petit que + + + + Transfer algorithm + Algorithme de transfert + + + + Parallelize if smaller than + ParallĆØlise si plus petit que + + + + Inode threads + Thread d'inode + + + + + More cpu, but better organisation on the disk + Plus de cpu mais meilleur organisation sur le disque + + + + Order the list + Ordonner la liste + + + + Misc + Divers + + + + Check the disk space + VĆ©rifier l'espace disque + + + + Use this folder when destination is not set + Utiliser ce dossier quand la destination n'est pas dĆ©fini + + + + Browse + Parcourir + + + + Filters + Filtres + + + + fileErrorDialog + + + Error with file + Erreur avec un fichier + + + + Error + Erreur + + + + Size + Taille + + + + Modified + ModifiĆ© + + + + File name + Nom de fichier + + + + Destination + Destination + + + + Folder + Dossier + + + + &Always perform this action + &Toujours faire cette action + + + + Try in with elevated privileges + Essayer avec des privilĆ©ges suppĆ©rieurs + + + + Put to bottom + Mettre Ć  la fin + + + + Retry + RĆ©essayer + + + + &Skip + &Passer + + + + &Cancel + &Annuler + + + + fileExistsDialog + + + The file exists + Le fichier existe + + + + Source + Source + + + + Destination + Destination + + + + + Size + Taille + + + + + Modified + ModifiĆ© + + + + + File name + Nom de fichier + + + + + Folder + Dossier + + + + Suggest new &name + SuggĆ©rer un &nouveau nom + + + + &Always perform this action + &Toujours faire cette action + + + + + Overwrite if modification date differs + Ɖcraser si les dates diffĆ©res + + + + &Rename + &Renommer + + + + &Overwrite + &Ɖcraser + + + + &Skip + &Passer + + + + &Cancel + &Annuler + + + + Overwrite if newer + Ɖcraser si plus rĆ©cent + + + + + Overwrite if older + Ɖcraser si plus vieux + + + + fileIsSameDialog + + + Size + Taille + + + + Modified + ModifiĆ© + + + + File name + Nom de fichier + + + + The source and destination are same + La source et la destination sont identique + + + + Folder + Dossier + + + + Suggest new &name + SuggĆ©rer un &nouveau nom + + + + &Always perform this action + &Toujours faire cette action + + + + &Rename + &Renommer + + + + &Skip + &Passer + + + + &Cancel + &Annuler + + + + folderExistsDialog + + + Source + Source + + + + Destination + Destination + + + + The source and destination is identical + La source et la destination sont identique + + + + + Modified + ModifiĆ© + + + + + Folder name + Nom de rĆ©pertoire + + + + + Folder + Dossier + + + + Suggest new &name + SuggĆ©rer un &nouveau nom + + + + &Always perform this action + &Toujours faire cette action + + + + &Rename + &Renommer + + + + Merge + Fusionner + + + + Skip + Passer + + + + &Cancel + &Annuler + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/hi/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/hi/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/hi/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/hu/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/hu/translation.ts new file mode 100644 index 0000000..eaa968d --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/hu/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + Nem tĆ”mogatott ezen a platformon + + + + Last modified date is wrong + A mĆ³dosĆ­tĆ”s utolsĆ³ dĆ”tuma hibĆ”s + + + + Last access date is wrong + A hozzĆ”fĆ©rĆ©s utolsĆ³ dĆ”tuma hibĆ”sa + + + + Unknown error: %1 + Ismeretlen hiba: %1 + + + + Path conversion error + ƚtvonal konvertĆ”lĆ”si hiba + + + + Unknown error + Ismeretlen hiba + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + A motort mozgatĆ”sra kĆ©nyszerĆ­tik, nem mĆ”solhatsz vele + + + + + The engine is forced to copy, you can't move with it + A motort mĆ”solĆ”sra kĆ©nyszerĆ­tik, nem mozgathatsz vele + + + + Destination + CĆ©l + + + + Use the actual destination "%1"? + HasznĆ”lja a jelenlegi cĆ©lt: "%1"? + + + + The mode has been forced previously. This is an internal error, please report it + Ezt a mĆ³dot mĆ”r korĆ”bban kĆ©nyszerĆ­tettĆ©k. Belső hiba tƶrtĆ©nt, kĆ©rlek jelentsd be + + + + + + + Ask + KĆ©rdezzen rĆ” + + + + + + + Skip + Kihagy + + + + Merge + Ɩsszeolvaszt + + + + + Rename + Nevezze Ć”t + + + + Put at the end + Helyezze a vĆ©gĆ©re + + + + Overwrite + FelĆ¼lĆ­r + + + + Overwrite if different + FelĆ¼lĆ­r, ha kĆ¼lƶnbƶzik + + + + Overwrite if newer + FelĆ¼lĆ­r, ha Ćŗjabb + + + + Overwrite if older + FelĆ¼lĆ­r, ha rĆ©gebbi + + + + Automatic + Automatikus + + + + Sequential + SzekvenciĆ”lis + + + + Parallel + PĆ”rhuzamos + + + + Options error + BeĆ”llĆ­tĆ”si hiba + + + + Options engine is not loaded. Unable to access the filters + A beĆ”llĆ­tĆ”si motor nincs betƶltve. A szűrők elĆ©rĆ©se nem lehetsĆ©ges + + + + CopyEngineFactory + + + + + + Ask + KĆ©rdezzen rĆ” + + + + + + + Skip + Kihagy + + + + Merge + Ɩsszeolvaszt + + + + + Rename + Nevezze Ć”t + + + + Put at the end + Helyezze a vĆ©gĆ©re + + + + Overwrite + FelĆ¼lĆ­r + + + + Overwrite if different + FelĆ¼lĆ­r, ha kĆ¼lƶnbƶzik + + + + Overwrite if newer + FelĆ¼lĆ­r, ha Ćŗjabb + + + + Overwrite if older + FelĆ¼lĆ­r, ha rĆ©gebbi + + + + Automatic + Automatikus + + + + Sequential + SzekvenciĆ”lis + + + + Parallel + PĆ”rhuzamos + + + + + Options error + BeĆ”llĆ­tĆ”si hiba + + + + Options engine is not loaded. Unable to access the filters + A beĆ”llĆ­tĆ”si motor nincs betƶltve. A szűrők elĆ©rĆ©se nem lehetsĆ©ges + + + + Options engine is not loaded, can't access to the filters + A beĆ”llĆ­tĆ”si motor nincs betƶltve, a szűrők elĆ©rĆ©se nem lehetsĆ©ges + + + + DiskSpace + + + Disk space + LemezterĆ¼let + + + + You need more space on this drive to finish this transfer + Tƶbb szabad helyre van szĆ¼ksĆ©ged ezen a lemezen az Ć”tvitel befejezĆ©sĆ©hez + + + + Continue + FolytatĆ”s + + + + Cancel + MĆ©gse + + + + Drives %1 have %2 available but need %3 + %1 meghajtĆ³n %2 hely van, de %3 szĆ¼ksĆ©ges + + + + FileErrorDialog + + + Error on folder + Hiba a mappĆ”val + + + + Folder name + Mappa neve + + + + FileExistsDialog + + + %1 - copy + %1 - mĆ”solĆ”s + + + + %1 - copy (%2) + %1 - mĆ”solĆ”s (%2) + + + + Error + Hiba + + + + Try rename with using special characters + ƁtnevezĆ©s speciĆ”lis karakterek hasznĆ”latĆ”val + + + + FileIsSameDialog + + + %1 - copy + %1 - mĆ”solĆ”s + + + + %1 - copy (%2) + %1 - mĆ”solĆ”s (%2) + + + + Error + Hiba + + + + Try rename with using special characters + ƁtnevezĆ©s speciĆ”lis karakterek hasznĆ”latĆ”val + + + + FilterRules + + + Filters dialog + Szűrők Ć¼zenet + + + + Search: + KeresĆ©s: + + + + Search type: + KeresĆ©s tĆ­pusa: + + + + Raw text + Nyers szƶveg + + + + Simplified regex + EgyszerűsĆ­tett regex + + + + Perl's regex + Perl regex + + + + Apply on: + AlkalmazĆ”s ezen: + + + + File + FĆ”jl + + + + Folder + Mappa + + + + File and folder + FĆ”jl Ć©s mappa + + + + Whole string must match + A teljes szƶvegnek egyeznie kell + + + + The test string matches with the regex + A tesztszƶveg megegyezik a regexszel + + + + Checking + EllenőrzĆ©s + + + + The regex is valid + A regex Ć©rvĆ©nyes + + + + Test string: + PrĆ³baszƶveg: + + + + Filters + + + Filters + Szűrők + + + + Exclusion filters + KizĆ”rĆ³ szűrők + + + + Inclusion filters + HasznĆ”lt szűrők + + + + None = Include all + Nincs = Mindet hasznĆ”l + + + + + Raw text + Nyers szƶveg + + + + + Simplified regex + EgyszerűsĆ­tett regex + + + + + Perl's regex + Perl regex + + + + + Only on file + Csak fĆ”jlon + + + + + Only on folder + Csak mappĆ”n + + + + + + + Full match + Teljes egyezĆ©s + + + + FolderExistsDialog + + + Folder already exists + Mappa mĆ”r lĆ©tezik + + + + %1 - copy + %1 - mĆ”solĆ”s + + + + %1 - copy (%2) + %1 - mĆ”solĆ”s (%2) + + + + Error + Hiba + + + + Try rename with using special characters + ƁtnevezĆ©s speciĆ”lis karakterek hasznĆ”latĆ”val + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + Elem mĆ”solĆ”sa vagy mozgatĆ”s nem lehetsĆ©ges a hibĆ”s kĆ©nyszerĆ­tett mĆ³dban: %1 + + + + + Unable to save the transfer list: %1 + Ɓtviteli lista mentĆ©se nem lehetsĆ©ges: %1 + + + + Problem reading file, or file-size is 0 + Hiba a fĆ”jl olvasĆ”sĆ”nĆ”l vagy a fĆ”lmĆ©ret 0 + + + + Wrong header: "%1" + HibĆ”s fejlĆ©c: "%1" + + + + The transfer list is in mixed mode, but this instance is not in this mode + Az Ć”tviteli lista kevert mĆ³dban van, de ez a pĆ©ldĆ”ny nincs + + + + The transfer list is in copy mode, but this instance is not in this mode + Az Ć”tviteli lista mĆ”solĆ”s mĆ³dban van, de ez a pĆ©ldĆ”ny nincs + + + + The transfer list is in move mode, but this instance is not in this mode + Az Ć”tviteli lista mozgatĆ”s mĆ³dban van, de ez a pĆ©ldĆ”ny nincs + + + + Some errors have been found during the line parsing + NĆ©hĆ”ny hiba tƶrtĆ©nt a sorelemzĆ©s sorĆ”n + + + + Unable to open the transfer list: %1 + Az Ć”tviteli lista megnyitĆ”sa nem lehetsĆ©ges: %1 + + + + MkPath + + + Unable to create the folder + Mappa lĆ©trehozĆ”sa nem lehetsĆ©ges + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + EltĆ”volĆ­tĆ”s nem lehetsĆ©ges + + + + ReadThread + + + Internal error, please report it! + Belső hiba, kĆ©rlek jelentsd! + + + + Internal error reading the source file:block size out of range + Belső hiba tƶrtĆ©nt a forrĆ”sfĆ”jl olvasĆ”sakor: a blokkmĆ©ret tartomĆ”nyon kĆ­vĆ¼li + + + + + Unable to read the source file: + A forrĆ”sfĆ”jl olvasĆ”sa nem lehetsĆ©ges: + + + + + File truncated during the read, possible data change + A fĆ”jl olvasĆ”s sorĆ”n megcsonkult, valĆ³szĆ­nűleg adatvĆ”ltozĆ”s miatt + + + + RenamingRules + + + Renaming rules + ƁtnevezĆ©si szabĆ”lyok + + + + First renaming + Első Ć”tnevezĆ©s + + + + %name% - copy + %name% should not be translated + %name% - mĆ”solĆ”s + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + <html><head/><body><p>VĆ”ltozĆ³k: <span style=" font-weight:600;">%name%</span> az eredeti fĆ”jlnĆ©vhez</p></body></html> + + + + Second renaming + MĆ”sodik Ć”tnevezĆ©s + + + + %name% - copy (%number%) + %name%, %number% should not be translated + %name% - mĆ”solĆ”s (%number%) + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + <html><head/><body><p>VĆ”ltozĆ³k: <span style=" font-weight:600;">%name%</span> az eredeti fĆ”jlnĆ©vhez</p><p><span style=" font-weight:600;">%number%</span> az extra szĆ”mhoz</p></body></html> + + + + + %1 - copy + %1 - mĆ”solĆ”s + + + + + %1 - copy (%2) + %1 - mĆ”solĆ”s (%2) + + + + ScanFileOrFolder + + + Blacklisted folder + FeketelistĆ”s mappa + + + + + %1 - copy + %1 - mĆ”solĆ”s + + + + + %1 - copy (%2) + %1 - mĆ”solĆ”s (%2) + + + + This is not a folder + Ez nem mappa + + + + The folder does exists + A mappa lĆ©tezik + + + + The folder is not readable + A mappa nem olvashatĆ³ + + + + Problem with name encoding + ProblĆ©ma a nĆ©vkĆ³dolĆ”ssal + + + + TransferThread + + + + + + File not found + FĆ”jl nem talĆ”lhatĆ³ + + + + Drive %1 + %1 meghajtĆ³ + + + + Unknown folder + Ismeretlen mappa + + + + root + gyƶkĆ©r + + + + %1 - copy + %1 - mĆ”solĆ”s + + + + %1 - copy (%2) + %1 - mĆ”solĆ”s (%2) + + + + The source doesn't exist + A forrĆ”s nem lĆ©tezik + + + + + Unable to do the folder + Mappaművelet nem lehetsĆ©ges + + + + Try rename with using special characters + ƁtnevezĆ©s speciĆ”lis karakterek hasznĆ”latĆ”val + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + + The source file doesn't exist + A forrĆ”sfĆ”jl nem lĆ©tezik + + + + Another file exists at same place + Egy mĆ”sik fĆ”jl lĆ©tezik ugyanazon a helyen + + + + The checksums do not match + A checksumok nem egyeznek meg + + + + Internal error: The destination is not closed + Belső hiba: a cĆ©l nincs bezĆ”rva + + + + Internal error: The size transfered doesn't match + Belső hiba: az Ć”tvitt mĆ©ret nem egyezik meg + + + + Internal error: The buffer is not empty + Belső hiba: a puffer nem Ć¼res + + + + + + Unable to change the date + + + + + WriteThread + + + Path resolution error (Empty path) + ƚtvonal feloldĆ”si hiba (Ɯres Ćŗtvonal) + + + + Internal error, please report it! + Belső hiba, kĆ©rlek jelentsd! + + + + Unable to read the source file: + A forrĆ”sfĆ”jl olvasĆ”sa nem lehetsĆ©ges: + + + + File truncated during read, possible data change + FĆ”jl megsĆ©rĆ¼lt az olvasĆ”s kƶzben, valĆ³szĆ­nűleg adatvĆ”ltozĆ”s + + + + copyEngineOptions + + + Transfer + Ɓtvitel + + + + Move the whole folder + Mozgassa Ć”t az egĆ©sz mappĆ”t + + + + Transfer the file rights + FĆ”jljogok Ć”tadĆ”sa + + + + Keep the file date + FĆ”jl dĆ”tumĆ”nak megtartĆ”sa + + + + Autostart the transfer + Ɓtvitel automatikus indĆ­tĆ”sa + + + + + Less performance if checked + Kisebb teljesĆ­tmĆ©ny, ha be van jelƶlve + + + + Follow the strict order + Kƶvesse a szigorĆŗ sorrendet + + + + Error and collision + Hiba Ć©s Ć¼tkƶzĆ©s + + + + When folder error + Mappa hiba esetĆ©n + + + + When file error + FĆ”jl hiba esetĆ©n + + + + When file collision + FĆ”jl Ć¼tkƶzĆ©s esetĆ©n + + + + When folder collision + Mappa Ć¼tkƶzĆ©s esetĆ©n + + + + Check if destination folder exists + CĆ©lmappa lĆ©tezĆ©sĆ©nek ellenőrzĆ©se + + + + Renaming rules + ƁtnevezĆ©si szabĆ”lyok + + + + Delete partially transferred files + RĆ©szben Ć”tvitt fĆ”jlok tƶrlĆ©se + + + + Rename the original destination + Eredeti cĆ©l Ć”tnevezĆ©se + + + + Control + IrĆ”nyĆ­tĆ”s + + + + Checksum + Checksum + + + + Only after error + Csak hiba utĆ”n + + + + Ignore if impossible + Hagyja ki, ha nem lehetsĆ©ges + + + + Verify checksums + Checksumok ellenőrzĆ©se + + + + Performance + TeljesĆ­tmĆ©ny + + + + Parallel buffer + PĆ”rhuzamos puffer + + + + + + + + KB + KB + + + + Block size + BlokkmĆ©ret + + + + Sequential buffer + SzekvenciĆ”lis puffer + + + + Enable OS buffer + OS puffer engedĆ©lyezĆ©se + + + + OS buffer only if smaller than + OS buffer csak akkor, ha kisebb mint + + + + Transfer algorithm + Ɓtviteli algoritmus + + + + Parallelize if smaller than + PĆ”rhuzamosĆ­tĆ”s, ha kisebb mint + + + + Inode threads + Inode szĆ”lak + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + EgyĆ©b + + + + Check the disk space + LemezterĆ¼let ellenőrzĆ©se + + + + Use this folder when destination is not set + + + + + Browse + TallĆ³zĆ”s + + + + Filters + Szűrők + + + + fileErrorDialog + + + Error with file + Hiba a fĆ”jllal + + + + Error + Hiba + + + + Size + MĆ©ret + + + + Modified + MĆ³dosĆ­tva + + + + File name + FĆ”jlnĆ©v + + + + Destination + CĆ©l + + + + Folder + Mappa + + + + &Always perform this action + &Mindig hajtsa vĆ©gre ezt a műveletet + + + + Try in with elevated privileges + PrĆ³bĆ”lja meg emelt jogosultsĆ”ggal + + + + Put to bottom + Tegye legalulra + + + + Retry + ƚjra + + + + &Skip + &Kihagy + + + + &Cancel + M&Ć©gse + + + + fileExistsDialog + + + The file exists + A fĆ”jl lĆ©tezik + + + + Source + ForrĆ”s + + + + Destination + CĆ©l + + + + + Size + MĆ©ret + + + + + Modified + MĆ³dosĆ­tva + + + + + File name + FĆ”jlnĆ©v + + + + + Folder + Mappa + + + + Suggest new &name + ƚj &nĆ©v ajĆ”nlĆ”sa + + + + &Always perform this action + &Mindig hajtsa vĆ©gre ezt a műveletet + + + + + Overwrite if modification date differs + FelĆ¼lĆ­r, ha a mĆ³dosĆ­tĆ”s dĆ”tuma kĆ¼lƶnbƶzik + + + + + Overwrite if older + FelĆ¼lĆ­r, ha rĆ©gebbi + + + + &Rename + &Ɓtnevez + + + + &Overwrite + &FelĆ¼lĆ­r + + + + &Skip + &Kihagy + + + + &Cancel + &MĆ©gse + + + + Overwrite if newer + FelĆ¼lĆ­r, ha Ćŗjabb + + + + fileIsSameDialog + + + Size + MĆ©ret + + + + Modified + MĆ³dosĆ­tva + + + + File name + FĆ”jlnĆ©v + + + + The source and destination are same + A forrĆ”s Ć©s a cĆ©l megegyezik + + + + Folder + Mappa + + + + Suggest new &name + ƚj &nĆ©v javasolĆ”sa + + + + &Always perform this action + &Mindig hajtsa vĆ©gre ezt a műveletet + + + + &Rename + &Ɓtnevez + + + + &Skip + &Kihagy + + + + &Cancel + M&Ć©gse + + + + folderExistsDialog + + + Source + ForrĆ”s + + + + Destination + CĆ©l + + + + + Modified + MĆ³dosĆ­tva + + + + + Folder name + Mappa neve + + + + Suggest new &name + ƚj &nĆ©v javasolĆ”sa + + + + The source and destination is identical + A forrĆ”s Ć©s a cĆ©l megegyezik + + + + + Folder + Mappa + + + + &Always perform this action + &Mindig hajtsa vĆ©gre ezt a műveletet + + + + &Rename + &Ɓtnevez + + + + Merge + Ɩsszeolvaszt + + + + Skip + Kihagy + + + + &Cancel + M&Ć©gse + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/id/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/id/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/id/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/it/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/it/translation.ts new file mode 100644 index 0000000..8a95cd4 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/it/translation.ts @@ -0,0 +1,1299 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + Non supportato su questa piattaforma + + + + Last modified date is wrong + La data dell'ultima modifica ĆØ errata + + + + Last access date is wrong + La data dell'ultimo accesso ĆØ errata + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + Percorso dell'errore di conversione + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + Impossibile copiare, il motore per la copia forzerĆ  lo spostamento + + + + + The engine is forced to copy, you can't move with it + Impossibile effettuare lo spostamento, il motore per la copia forzerĆ  la copia + + + + Destination + Cartella di destinazione + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + Chiedi + + + + + + + Skip + Salta + + + + Merge + Unisci + + + + + Rename + Rinomina + + + + Put at the end + Metti in coda + + + + Overwrite + Sovrascrivi + + + + Overwrite if different + Sovrascrivi se differente + + + + Overwrite if newer + Sovrascrivi se piĆ¹ recente + + + + Overwrite if older + Sovrascrivi se meno recente + + + + Automatic + Automatico + + + + Sequential + Sequenziale + + + + Parallel + Parallelo + + + + Options error + Opzioni di errore + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + Chiedi + + + + + + + Skip + Salta + + + + Merge + Unisci + + + + + Rename + Rinomina + + + + Put at the end + Metti in coda + + + + Overwrite + Sovrascrivi + + + + Overwrite if different + Sovrascrivi se differente + + + + Overwrite if newer + Sovrascrivi se piĆ¹ recente + + + + Overwrite if older + Sovrascrivi se meno recente + + + + Automatic + Automatico + + + + Sequential + Sequenziale + + + + Parallel + Parallelo + + + + + Options error + Opzioni di errore + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + Le opzioni del motore per la copia non vengono caricate, impossibile accedere ai filtri + + + + DiskSpace + + + Disk space + Spazio su disco + + + + You need more space on this drive to finish this transfer + + + + + Continue + Continua + + + + Cancel + Annulla + + + + Drives %1 have %2 available but need %3 + L'unitĆ  %1 ha %2 disponibili, ma necessita di %3 + + + + FileErrorDialog + + + Error on folder + Errore nella cartella + + + + Folder name + Nome della cartella + + + + FileExistsDialog + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Error + Errore + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Error + Errore + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + Cerca: + + + + Search type: + Tipo di ricerca: + + + + Raw text + Testo raw + + + + Simplified regex + Regex semplificato + + + + Perl's regex + Regex in Perl + + + + Apply on: + Applicare su: + + + + File + File + + + + Folder + Cartelle + + + + File and folder + File e cartelle + + + + The test string matches with the regex + + + + + Checking + Verifica + + + + Test string: + Stringa di verifica: + + + + Filters dialog + Finestra dei filtri + + + + Whole string must match + + + + + The regex is valid + La regex ĆØ valida + + + + Filters + + + Filters + Filtri + + + + Exclusion filters + Filtri di esclusione + + + + Inclusion filters + o filtri per l'inserimento? + Filtri di inclusione + + + + None = Include all + o Nessuno = Includi tutti oppure Nessuno = Inserisci tutti oppure bisogna lasiare none? + Nessuno = Tutti inclusi + + + + + Raw text + Testo raw + + + + + Simplified regex + Regex semplificato + + + + + Perl's regex + Regex in Perl + + + + + Only on file + Solo su file + + + + + Only on folder + o cartella al singolare? + Solo su cartelle + + + + + + + Full match + Corrispondenza completa + + + + FolderExistsDialog + + + Folder already exists + Cartella giĆ  presente + + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Error + Errore + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + Impossibile spostare o copiare elementi in modalitĆ  forzata anomala: %1 + + + + + Unable to save the transfer list: %1 + Impossibile salvare la lista dei trasferimenti: %1 + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + Header si riferisce all'intestazione? + Intestazione sbagliata: "%1" + + + + The transfer list is in mixed mode, but this instance is not in this mode + La lista dei trasferimenti ĆØ in modalitĆ  mista, ma questa istanza non ĆØ in questa modalitĆ  + + + + The transfer list is in copy mode, but this instance is not in this mode + La lista dei trasferimenti ĆØ in modalitĆ  di copia, ma questa istanza non ĆØ in questa modalitĆ  + + + + The transfer list is in move mode, but this instance is not in this mode + La lista dei trasferimenti ĆØ in modalitĆ  di spostamento, ma questa istanza non ĆØ in questa modalitĆ  + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + Impossibile aprire la lista dei trasferimenti: %1 + + + + MkPath + + + Unable to create the folder + Impossibile creare la cartella + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + Impossibile eliminare + + + + ReadThread + + + Internal error, please report it! + Errore interno, pregasi di segnalarlo! + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + Impossibile leggere il file di origine: + + + + + File truncated during the read, possible data change + File troncato durante la lettura, possibili variazioni di dati + + + + RenamingRules + + + First renaming + o Prima ridenominazione? + Prima rinomina + + + + %name% - copy + %name% should not be translated + %name% non dovrĆ  essere tradotto + Copia di %name% + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + o per il nome originale del file + <html><head/><body><p>variabili: <span style=" font-weight:600;">%name%</span> per il nome del file di origine</p></body></html> + + + + Second renaming + o Seconda ridenominazione? + Seconda rinomina + + + + %name% - copy (%number%) + %name%, %number% should not be translated + %name% e %number% non dovranno essere tradotti + Copia di %name% (%number%) + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + %name% e %number% non dovranno essere tradotti + <html><head/><body><p>variabili: <span style=" font-weight:600;">%name%</span> per il nome del file di origine</p><p><span style=" font-weight:600;">%number%</span> per il numero progressivo</p></body></html> + + + + + %1 - copy + %1 - copia + + + + + %1 - copy (%2) + %1 - copia (%2) + + + + Renaming rules + Regole di rinomina + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + %1 - copia + + + + + %1 - copy (%2) + %1 - copia (%2) + + + + This is not a folder + Questa non ĆØ una cartella + + + + The folder does exists + + + + + The folder is not readable + La cartella non ĆØ leggibile + + + + Problem with name encoding + Problema con la codifica del nome + + + + TransferThread + + + + + + File not found + File non trovato + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + UnitĆ  %1 + + + + Unknown folder + + + + + root + root + + + + %1 - copy + %1 - copia + + + + %1 - copy (%2) + %1 - copia (%2) + + + + + The source file doesn't exist + + + + + + Unable to do the folder + Impossibile creare la cartella + + + + Try rename with using special characters + + + + + The source doesn't exist + + + + + Another file exists at same place + Nello stesso percorso ĆØ presente un altro file + + + + The checksums do not match + + + + + Internal error: The destination is not closed + Errore interno: la cartella di destinazione non ĆØ chiusa + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + Errore interno: il buffer non ĆØ vuoto + + + + + + Unable to change the date + Impossibile cambiare la data + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + Errore interno, pregasi di segnalarlo! + + + + Unable to read the source file: + Impossibile leggere il file di origine: + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + Trasferisci + + + + Move the whole folder + Spostare l'intera cartella + + + + Transfer the file rights + Trasferire le autorizzazioni dei file + + + + Keep the file date + Mantenere la data del file + + + + Autostart the transfer + + + + + + Less performance if checked + Se selezionato si avranno prestazioni ridotte + + + + Follow the strict order + Seguire rigorosamente l'ordine + + + + Error and collision + Errori di coincidenze + + + + When folder error + Quando si verifica un errore nelle cartelle + + + + When file error + Quando si verifica un errore nei file + + + + When file collision + Quando i file coincidono + + + + When folder collision + Quando le cartelle coincidono + + + + Check if destination folder exists + Controllare se la cartella di destinazione esiste + + + + Renaming rules + Regole di rinomina + + + + Delete partially transferred files + Eliminare i file parzialmente trasferiti + + + + Rename the original destination + Rinominare la destinazione all'origine + + + + Control + Controllare + + + + Checksum + Codice di controllo (Checksum) + + + + Only after error + Solo dopo l'errore + + + + Ignore if impossible + Ignora se non corrisponde + + + + Verify checksums + + + + + Performance + Prestazioni + + + + Parallel buffer + Buffer parallelo + + + + + + + + KB + KB + + + + Block size + Dimensione del blocco + + + + Sequential buffer + Buffer sequenziale + + + + Enable OS buffer + Attivare il buffer del sistema operativo + + + + OS buffer only if smaller than + Buffer del sistema operativo solo se inferiore a + + + + Transfer algorithm + Algoritmo di trasferimento + + + + Parallelize if smaller than + Affiancare se inferiore a + + + + Inode threads + Inode threads + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + Varie + + + + Check the disk space + Controllare lo spazio su disco + + + + Use this folder when destination is not set + + + + + Browse + Sfoglia + + + + Filters + Filtri + + + + fileErrorDialog + + + Error with file + + + + + Error + Errore + + + + Size + Dimensione + + + + Modified + Modificato + + + + File name + Nome del file + + + + Destination + Cartella di destinazione + + + + Folder + Cartelle + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + Mettere in coda + + + + Retry + Riprova + + + + &Skip + &Salta + + + + &Cancel + &Annulla + + + + fileExistsDialog + + + The file exists + Il file ĆØ giĆ  presente + + + + Source + Cartella di origine + + + + Destination + Cartella di destinazione + + + + + Size + Dimensione + + + + + Modified + Modificato + + + + + File name + Nome del file + + + + + Folder + Cartelle + + + + Suggest new &name + Suggerisci un nuovo &nome + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + &Rinomina + + + + &Overwrite + &Sovrascrivi + + + + &Skip + &Salta + + + + &Cancel + &Annulla + + + + Overwrite if newer + Sovrascrivi se piĆ¹ recente + + + + + Overwrite if older + Sovrascrivi se meno recente + + + + fileIsSameDialog + + + Size + Dimensione + + + + Modified + Modificato + + + + File name + Nome del file + + + + The source and destination are same + + + + + Folder + Cartelle + + + + Suggest new &name + Suggerisci nuovo &nome + + + + &Always perform this action + + + + + &Rename + &Rinomina + + + + &Skip + &Salta + + + + &Cancel + &Annulla + + + + folderExistsDialog + + + Source + Cartella di origine + + + + Destination + Cartella di destinazione + + + + The source and destination is identical + + + + + + Modified + Modificato + + + + + Folder name + Nome della cartella + + + + + Folder + Cartelle + + + + Suggest new &name + Suggerisci nuovo &nome + + + + &Always perform this action + + + + + &Rename + &Rinomina + + + + Merge + Unisci + + + + Skip + Salta + + + + &Cancel + &Annulla + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/ja/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/ja/translation.ts new file mode 100644 index 0000000..5c68ad9 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/ja/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Filters dialog + + + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + Whole string must match + + + + + The test string matches with the regex + + + + + Checking + + + + + The regex is valid + + + + + Test string: + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + Renaming rules + + + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/ko/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/ko/translation.ts new file mode 100644 index 0000000..ea7d584 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/ko/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + ģ“ ķ”Œėž«ķ¼ģ—ģ„œ ģ§€ģ›ė˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤ + + + + Last modified date is wrong + ė§ˆģ§€ė§‰ ģˆ˜ģ • ė‚ ģ§œź°€ ģž˜ėŖ»ė˜ģ—ˆģŠµė‹ˆė‹¤ + + + + Last access date is wrong + ė§ˆģ§€ė§‰ ģ—‘ģ„øģŠ¤ ė‚ ģ§œź°€ ģž˜ėŖ»ė˜ģ—ˆģŠµė‹ˆė‹¤ + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + ėŒ€ģƒ + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + ķ™•ģø + + + + + + + Skip + ź±“ė„ˆė›°źø° + + + + Merge + ķ•©ģ¹˜źø° + + + + + Rename + ģ“ė¦„ ė°”ź¾øźø° + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + ė” ģµœģ‹ ģ“ė©“ ė®ģ–“ģ”Œģš°źø° + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + ķ™•ģø + + + + + + + Skip + ź±“ė„ˆė›°źø° + + + + Merge + ķ•©ģ¹˜źø° + + + + + Rename + ģ“ė¦„ ė°”ź¾øźø° + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + ė” ģµœģ‹ ģ“ė©“ ė®ģ–“ģ”Œģš°źø° + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + ķ“ė” ģ“ė¦„ + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + ģ˜¤ė„˜ + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + ģ˜¤ė„˜ + + + + Try rename with using special characters + + + + + FilterRules + + + Filters dialog + + + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + Whole string must match + + + + + The test string matches with the regex + + + + + Checking + + + + + The regex is valid + + + + + Test string: + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + ģ˜¤ė„˜ + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + ķ“ė”ė„¼ ģƒģ„±ķ•  ģˆ˜ ģ—†ģŠµė‹ˆė‹¤ + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + ģ›ė³ø ķŒŒģ¼ ģ½źø° ė¶ˆź°€: + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + Renaming rules + + + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + ķ“ė”ė„¼ ģ½ģ„ ģˆ˜ ģ—†ģŠµė‹ˆė‹¤ + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + ģ›ė³ø ķŒŒģ¼ ģ½źø° ė¶ˆź°€: + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + ķŒŒģ¼ ź¶Œķ•œ ģ „ģ†” + + + + Keep the file date + ķŒŒģ¼ ė‚ ģ§œ ė³“ģ”“ + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + ķ“ė” ģ˜¤ė„˜ģ‹œ + + + + When file error + + + + + When file collision + + + + + When folder collision + ķ“ė” ģ¶©ėŒģ‹œ + + + + Check if destination folder exists + ėŒ€ģƒ ķ“ė“œ ģ”“ģž¬ģ‹œ ķ™•ģø + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + KB + + + + Block size + ėø”ėŸ­ ķ¬źø° + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + ģ˜¤ė„˜ + + + + Size + ķ¬źø° + + + + Modified + ģˆ˜ģ • ė‚ ģ§œ + + + + File name + ķŒŒģ¼ ģ“ė¦„ + + + + Destination + ėŒ€ģƒ + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + ģ•„ėž˜ģ— ė†“źø° + + + + Retry + ģž¬ģ‹œė„ + + + + &Skip + &ź±“ė„ˆė›°źø° + + + + &Cancel + &ģ·Øģ†Œ + + + + fileExistsDialog + + + The file exists + ķŒŒģ¼ģ“ ģ”“ģž¬ķ•©ė‹ˆė‹¤ + + + + Source + ģ›ė³ø + + + + Destination + ėŒ€ģƒ + + + + + Size + ķ¬źø° + + + + + Modified + ģˆ˜ģ • ė‚ ģ§œ + + + + + File name + ķŒŒģ¼ ģ“ė¦„ + + + + + Folder + + + + + Suggest new &name + ģƒˆ &ģ“ė¦„ ģ œģ•ˆ + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + &ģ“ė¦„ ė°”ź¾øźø° + + + + &Overwrite + &ė®ģ–“ģ”Œģš°źø° + + + + &Skip + &ź±“ė„ˆė›°źø° + + + + &Cancel + &ģ·Øģ†Œ + + + + Overwrite if newer + ė” ģµœģ‹ ģ“ė©“ ė®ģ–“ģ”Œģš°źø° + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + ķ¬źø° + + + + Modified + ģˆ˜ģ • ė‚ ģ§œ + + + + File name + ķŒŒģ¼ ģ“ė¦„ + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + ģƒˆ &ģ“ė¦„ ģ œģ•ˆ + + + + &Always perform this action + + + + + &Rename + &ģ“ė¦„ ė°”ź¾øźø° + + + + &Skip + &ź±“ė„ˆė›°źø° + + + + &Cancel + &ģ·Øģ†Œ + + + + folderExistsDialog + + + Source + ģ›ė³ø + + + + Destination + ėŒ€ģƒ + + + + The source and destination is identical + + + + + + Modified + ģˆ˜ģ • ė‚ ģ§œ + + + + + Folder name + ķ“ė” ģ“ė¦„ + + + + + Folder + + + + + Suggest new &name + ģƒˆ &ģ“ė¦„ ģ œģ•ˆ + + + + &Always perform this action + + + + + &Rename + &ģ“ė¦„ ė°”ź¾øźø° + + + + Merge + ķ•©ģ¹˜źø° + + + + Skip + ź±“ė„ˆė›°źø° + + + + &Cancel + &ģ·Øģ†Œ + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/nl/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/nl/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/nl/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/no/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/no/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/no/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/pl/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/pl/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/pl/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/pt/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/pt/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/pt/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/ru/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/ru/translation.ts new file mode 100644 index 0000000..abaf3bb --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/ru/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + ŠŠµ ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ся Š½Š° этŠ¾Š¹ ŠæŠ»Š°Ń‚Ń„Š¾Ń€Š¼Šµ + + + + Last modified date is wrong + Š”Š°Ń‚Š° Š¾Š±Š½Š¾Š²Š»ŠµŠ½Šøя Š½ŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Š¾ + + + + Last access date is wrong + Š”Š°Ń‚Š° ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠµŠ³Š¾ Š“Š¾ŃŃ‚ŃƒŠæŠ° Š½Šµ тŠ°Šŗ + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + Š”Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŒ Š²Ń‹Š½ŃƒŠ¶Š“ŠµŠ½Ń‹ ŠæŠ¾ŠŗŠøŠ½ŃƒŃ‚ŃŒ сŠ²Š¾Šø Š“Š¾Š¼Š°, Š²Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ сŠŗŠ¾ŠæŠøрŠ¾Š²Š°Ń‚ŃŒ с Š½ŠøŠ¼ + + + + + The engine is forced to copy, you can't move with it + Š”Š²ŠøŠ³Š°Ń‚ŠµŠ»ŃŒ Š²Ń‹Š½ŃƒŠ¶Š“ŠµŠ½ ŠŗŠ¾ŠæŠøŠø, Š²Ń‹ Š½Šµ Š¼Š¾Š¶ŠµŃ‚Šµ Š“Š²ŠøŠ³Š°Ń‚ŃŒŃŃ Š²Š¼ŠµŃŃ‚Šµ с Š½ŠøŠ¼ + + + + Destination + Š½Š°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + ŠæрŠ¾ŃŠøть + + + + + + + Skip + ŠæрŠ¾ŠæусŠŗŠ°Ń‚ŃŒ + + + + Merge + сŠ»ŠøяŠ½ŠøŠµ + + + + + Rename + ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Ń‚ŃŒ + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + Š—Š°Š¼ŠµŠ½Šøть, ŠµŃŠ»Šø Š½Š¾Š²ŠµŠµ + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + ŠžŠæцŠøŠø Š¾ŃˆŠøŠ±ŠŗŠµ + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + ŠæрŠ¾ŃŠøть + + + + + + + Skip + ŠæрŠ¾ŠæусŠŗŠ°Ń‚ŃŒ + + + + Merge + сŠ»ŠøяŠ½ŠøŠµ + + + + + Rename + ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Ń‚ŃŒ + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + Š—Š°Š¼ŠµŠ½Šøть, ŠµŃŠ»Šø Š½Š¾Š²ŠµŠµ + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + ŠžŠæцŠøŠø Š¾ŃˆŠøŠ±ŠŗŠµ + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + ŠŸŠ°Ń€Š°Š¼ŠµŃ‚ры Š“Š²ŠøŠ³Š°Ń‚ŠµŠ»Ń Š½Šµ Š·Š°Š³Ń€ŃƒŠ¶Š°ŠµŃ‚ся, Š½Šµ Š¼Š¾Š¶ŠµŃ‚ ŠæŠ¾Š»ŃƒŃ‡Šøть Š“Š¾ŃŃ‚ŃƒŠæ Šŗ фŠøŠ»ŃŒŃ‚Ń€Š°Š¼ + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + ŠžŃˆŠøŠ±ŠŗŠ° Š² ŠæŠ°ŠæŠŗу + + + + Folder name + ŠøŠ¼Ń ŠæŠ°ŠæŠŗŠø + + + + FileExistsDialog + + + %1 - copy + %1 - ŠŗŠ¾ŠæŠøя + + + + %1 - copy (%2) + %1 - ŠŗŠ¾ŠæŠøя (%2) + + + + Error + Š¾ŃˆŠøŠ±ŠŗŠ° + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + %1 - ŠŗŠ¾ŠæŠøя + + + + %1 - copy (%2) + %1 - ŠŗŠ¾ŠæŠøя (%2) + + + + Error + Š¾ŃˆŠøŠ±ŠŗŠ° + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + ŠŸŠ¾ŠøсŠŗ ŠæŠ¾ сŠ°Š¹Ń‚Ńƒ: + + + + Search type: + Š¢ŠøŠæ ŠæŠ¾ŠøсŠŗŠ°: + + + + Raw text + Š”ырŠ¾Š¹ тŠµŠŗст + + + + Simplified regex + уŠæрŠ¾Ń‰ŠµŠ½Š½Ń‹Š¹ regex + + + + Perl's regex + Perl's regex + + + + Apply on: + ŠŠ°Š½ŠµŃŠøтŠµ Š½Š°: + + + + File + фŠ°Š¹Š» + + + + Folder + ŠæŠ°ŠæŠŗŠ° + + + + File and folder + Š¤Š°Š¹Š»Š¾Š² Šø ŠæŠ°ŠæŠ¾Šŗ + + + + The test string matches with the regex + + + + + Checking + ŠŗŠ¾Š½Ń‚Ń€Š¾Š»ŃŒ + + + + Test string: + Š˜ŃŠæытŠ°Š½ŠøŠµ стрŠ¾ŠŗŠø: + + + + Filters dialog + Š¤ŠøŠ»ŃŒŃ‚ры Š“ŠøŠ°Š»Š¾Š³Š¾Š²Š¾Š³Š¾ + + + + Whole string must match + + + + + The regex is valid + Š ŠµŠ³ŃƒŠ»ŃŃ€Š½Š¾Šµ Š“ŠµŠ¹ŃŃ‚Š²ŃƒŠµŃ‚ + + + + Filters + + + Filters + Š¤ŠøŠ»ŃŒŃ‚ры + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + ŠŠø = Š’ŠŗŠ»ŃŽŃ‡Šøть Š²ŃŠµ + + + + + Raw text + Š”ырŠ¾Š¹ тŠµŠŗст + + + + + Simplified regex + Š£ŠæрŠ¾Ń‰ŠµŠ½Š½Š°Ń рŠµŠ³ŃƒŠ»ŃŃ€Š½Ń‹Ń… Š²Ń‹Ń€Š°Š¶ŠµŠ½ŠøŠ¹ + + + + + Perl's regex + Perl's regex + + + + + Only on file + Š¢Š¾Š»ŃŒŠŗŠ¾ Š½Š° фŠ°Š¹Š» + + + + + Only on folder + Š¢Š¾Š»ŃŒŠŗŠ¾ Š½Š° ŠæŠ°ŠæŠŗу + + + + + + + Full match + ŠŸŠ¾Š»Š½Ń‹Š¹ Š¼Š°Ń‚ч + + + + FolderExistsDialog + + + Folder already exists + ŠŸŠ°ŠæŠŗŠ° уŠ¶Šµ сущŠµŃŃ‚Š²ŃƒŠµŃ‚ + + + + %1 - copy + %1 - ŠŗŠ¾ŠæŠøя + + + + %1 - copy (%2) + %1 - ŠŗŠ¾ŠæŠøя (%2) + + + + Error + Š¾ŃˆŠøŠ±ŠŗŠ° + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ“ŠµŠ»Š°Ń‚ŃŒ, чтŠ¾Š±Ń‹ сŠŗŠ¾ŠæŠøрŠ¾Š²Š°Ń‚ŃŒ ŠøŠ»Šø ŠæŠµŃ€ŠµŠ¼ŠµŃŃ‚Šøть эŠ»ŠµŠ¼ŠµŠ½Ń‚ Š² Š½ŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Š¾Š¼ фŠ¾Ń€ŃŠøрŠ¾Š²Š°Š½Š½Š¾Š¼ рŠµŠ¶ŠøŠ¼Šµ: %1 + + + + + Unable to save the transfer list: %1 + ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Ń…Ń€Š°Š½Šøть трŠ°Š½ŃŃ„ŠµŃ€: %1 + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + ŠŠµŠæрŠ°Š²ŠøŠ»ŃŒŠ½Ń‹Š¹ Š·Š°Š³Š¾Š»Š¾Š²Š¾Šŗ: "%1" + + + + The transfer list is in mixed mode, but this instance is not in this mode + Š¢Ń€Š°Š½ŃŃ„ŠµŃ€ Š² сŠ¼ŠµŃˆŠ°Š½Š½Š¾Š¼ рŠµŠ¶ŠøŠ¼Šµ, Š½Š¾ этŠ¾Ń‚ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ Š½Šµ Š² этŠ¾Š¼ рŠµŠ¶ŠøŠ¼Šµ + + + + The transfer list is in copy mode, but this instance is not in this mode + ŠŸŠµŃ€ŠµŠ“Š°Ń‡Š° сŠæŠøсŠŗŠ° Š² рŠµŠ¶ŠøŠ¼Šµ ŠŗŠ¾ŠæŠøрŠ¾Š²Š°Š½Šøя, Š½Š¾ этŠ¾Ń‚ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ Š½Šµ Š² этŠ¾Š¼ рŠµŠ¶ŠøŠ¼Šµ + + + + The transfer list is in move mode, but this instance is not in this mode + Š¢Ń€Š°Š½ŃŃ„ŠµŃ€ Š² рŠµŠ¶ŠøŠ¼ ŠæŠµŃ€ŠµŠ¼ŠµŃ‰ŠµŠ½Šøя, Š½Š¾ этŠ¾Ń‚ эŠŗŠ·ŠµŠ¼ŠæŠ»ŃŃ€ Š½Šµ Š² этŠ¾Š¼ рŠµŠ¶ŠøŠ¼Šµ + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + ŠŠµ уŠ“Š°ŠµŃ‚ся Š¾Ń‚Šŗрыть трŠ°Š½ŃŃ„ŠµŃ€: %1 + + + + MkPath + + + Unable to create the folder + ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ сŠ¾Š·Š“Š°Ń‚ŃŒ ŠæŠ°ŠæŠŗу + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ ŠøсхŠ¾Š“Š½Ń‹Š¹ фŠ°Š¹Š»: + + + + + File truncated during the read, possible data change + Š¤Š°Š¹Š» усŠµŃ‡ŠµŠ½Ń‹ Š²Š¾ Š²Ń€ŠµŠ¼Ń чтŠµŠ½Šøя, Š²Š¾Š·Š¼Š¾Š¶Š½Š¾ŃŃ‚ŃŒ ŠøŠ·Š¼ŠµŠ½ŠµŠ½Šøя Š“Š°Š½Š½Ń‹Ń… + + + + RenamingRules + + + First renaming + ŠŸŠµŃ€Š²Š¾Šµ ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½ŠøŠµ + + + + %name% - copy + %name% should not be translated + %name% - ŠŗŠ¾ŠæŠøя + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + <html><head/><body><p>ŠŸŠµŃ€ŠµŠ¼ŠµŠ½Š½Ń‹Šµ: <span style=" font-weight:600;">%name%</span> ŠæŠ¾ Š¾Ń€ŠøŠ³ŠøŠ½Š°Š»ŃŒŠ½Š¾Š¼Ńƒ Š½Š°Š·Š²Š°Š½Šøю фŠ°Š¹Š»Š°</p></body></html> + + + + Second renaming + Š’Ń‚Š¾Ń€Š¾Šµ ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½ŠøŠµ + + + + %name% - copy (%number%) + %name%, %number% should not be translated + %name% - ŠŗŠ¾ŠæŠøя (%number%) + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + <html><head/><body><p>ŠŸŠµŃ€ŠµŠ¼ŠµŠ½Š½Ń‹Šµ: <span style=" font-weight:600;">%name%</span> ŠæŠ¾ Š¾Ń€ŠøŠ³ŠøŠ½Š°Š»ŃŒŠ½Š¾Š¼Ńƒ Š½Š°Š·Š²Š°Š½Šøю фŠ°Š¹Š»Š°</p><p><span style=" font-weight:600;">%number%</span> Š·Š° Š“Š¾ŠæŠ¾Š»Š½ŠøтŠµŠ»ŃŒŠ½Ń‹Š¹ Š½Š¾Š¼ŠµŃ€</p></body></html> + + + + + %1 - copy + %1 - ŠŗŠ¾ŠæŠøя + + + + + %1 - copy (%2) + %1 - ŠŗŠ¾ŠæŠøя (%2) + + + + Renaming rules + ŠŸŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½ŠøŠµ ŠæрŠ°Š²ŠøŠ»Š° + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + %1 - ŠŗŠ¾ŠæŠøя + + + + + %1 - copy (%2) + %1 - ŠŗŠ¾ŠæŠøя (%2) + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + ŠŸŠ°ŠæŠŗŠø Š½Šµ чŠøтŠ°ŠµŃ‚ся + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + %1 - ŠŗŠ¾ŠæŠøя + + + + %1 - copy (%2) + %1 - ŠŗŠ¾ŠæŠøя (%2) + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + ŠŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ ŠæрŠ¾Ń‡ŠøтŠ°Ń‚ŃŒ ŠøсхŠ¾Š“Š½Ń‹Š¹ фŠ°Š¹Š»: + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + ŠŸŠµŃ€ŠµŠ“Š°Ń‡Š° фŠ°Š¹Š»Š¾Š² ŠæрŠ°Š² + + + + Keep the file date + Š”ŠµŃ€Š¶ŠøтŠµ Š“Š°Ń‚Ńƒ фŠ°Š¹Š»Š° + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + ŠšŠ¾Š³Š“Š° ŠæŠ°ŠæŠŗŠ° Š¾ŃˆŠøŠ±ŠŗŠ° + + + + When file error + + + + + When file collision + + + + + When folder collision + ŠšŠ¾Š³Š“Š° ŠæŠ°ŠæŠŗŠ° стŠ¾Š»ŠŗŠ½Š¾Š²ŠµŠ½Šøя + + + + Check if destination folder exists + Š£Š±ŠµŠ“ŠøтŠµŃŃŒ, чтŠ¾ ŠæŠ°ŠæŠŗŠ° сущŠµŃŃ‚Š²ŃƒŠµŃ‚ + + + + Renaming rules + ŠŸŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Š½ŠøŠµ ŠæрŠ°Š²ŠøŠ»Š° + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + ŠšŠ¾Š½Ń‚Ń€Š¾Š»ŃŒŠ½Š°Ń + + + + Only after error + Š¢Š¾Š»ŃŒŠŗŠ¾ ŠæŠ¾ŃŠ»Šµ тŠ¾Š³Š¾, ŠŗŠ°Šŗ Š¾ŃˆŠøŠ±ŠŗŠ° + + + + Ignore if impossible + Š˜Š³Š½Š¾Ń€ŠøрŠ¾Š²Š°Ń‚ŃŒ, ŠµŃŠ»Šø Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶Š½Š¾ + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + KB + + + + Block size + рŠ°Š·Š¼ŠµŃ€ Š±Š»Š¾ŠŗŠ° + + + + Sequential buffer + + + + + Enable OS buffer + Š’ŠŗŠ»ŃŽŃ‡Šøть OS Š±ŃƒŃ„ŠµŃ€ + + + + OS buffer only if smaller than + ŠžŠ” Š±ŃƒŃ„ŠµŃ€, тŠ¾Š»ŃŒŠŗŠ¾ ŠµŃŠ»Šø Š¼ŠµŠ½ŃŒŃˆŠµ + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + Š¤ŠøŠ»ŃŒŃ‚ры + + + + fileErrorDialog + + + Error with file + + + + + Error + Š¾ŃˆŠøŠ±ŠŗŠ° + + + + Size + рŠ°Š·Š¼ŠµŃ€ + + + + Modified + Š¼Š¾Š“ŠøфŠøцŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ + + + + File name + ŠøŠ¼Ń фŠ°Š¹Š»Š° + + + + Destination + Š½Š°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ + + + + Folder + ŠæŠ°ŠæŠŗŠ° + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + ŠŸŠ¾Š»Š¾Š¶Šøть Š² Š½ŠøŠ¶Š½ŠµŠ¹ + + + + Retry + ŠŸŠ¾Š²Ń‚Š¾Ń€Šøть + + + + &Skip + ŠæрŠ¾ŠæусŠŗŠ°Ń‚ŃŒ + + + + &Cancel + Š¾Ń‚Š¼ŠµŠ½Šøть + + + + fileExistsDialog + + + The file exists + Š¤Š°Š¹Š» сущŠµŃŃ‚Š²ŃƒŠµŃ‚ + + + + Source + ŠøстŠ¾Ń‡Š½ŠøŠŗ + + + + Destination + Š½Š°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ + + + + + Size + рŠ°Š·Š¼ŠµŃ€ + + + + + Modified + Š¼Š¾Š“ŠøфŠøцŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ + + + + + File name + ŠøŠ¼Ń фŠ°Š¹Š»Š° + + + + + Folder + ŠæŠ°ŠæŠŗŠ° + + + + Suggest new &name + ŠŸŃ€ŠµŠ“Š»Š¾Š¶Šøть Š½Š¾Š²Š¾Šµ ŠøŠ¼Ń + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Ń‚ŃŒ + + + + &Overwrite + ŠæŠµŃ€ŠµŠæŠøсыŠ²Š°Ń‚ŃŒ + + + + &Skip + ŠæрŠ¾ŠæусŠŗŠ°Ń‚ŃŒ + + + + &Cancel + Š¾Ń‚Š¼ŠµŠ½Šøть + + + + Overwrite if newer + Š—Š°Š¼ŠµŠ½Šøть, ŠµŃŠ»Šø Š½Š¾Š²ŠµŠµ + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + рŠ°Š·Š¼ŠµŃ€ + + + + Modified + Š¼Š¾Š“ŠøфŠøцŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ + + + + File name + ŠøŠ¼Ń фŠ°Š¹Š»Š° + + + + The source and destination are same + + + + + Folder + ŠæŠ°ŠæŠŗŠ° + + + + Suggest new &name + ŠŸŃ€ŠµŠ“Š»Š¾Š¶Šøть Š½Š¾Š²Š¾Šµ ŠøŠ¼Ń + + + + &Always perform this action + + + + + &Rename + ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Ń‚ŃŒ + + + + &Skip + ŠæрŠ¾ŠæусŠŗŠ°Ń‚ŃŒ + + + + &Cancel + Š¾Ń‚Š¼ŠµŠ½Šøть + + + + folderExistsDialog + + + Source + ŠøстŠ¾Ń‡Š½ŠøŠŗ + + + + Destination + Š½Š°Š·Š½Š°Ń‡ŠµŠ½ŠøŠµ + + + + The source and destination is identical + + + + + + Modified + Š¼Š¾Š“ŠøфŠøцŠøрŠ¾Š²Š°Š½Š½Ń‹Š¹ + + + + + Folder name + ŠøŠ¼Ń ŠæŠ°ŠæŠŗŠø + + + + + Folder + ŠæŠ°ŠæŠŗŠ° + + + + Suggest new &name + ŠŸŃ€ŠµŠ“Š»Š¾Š¶Šøть Š½Š¾Š²Š¾Šµ ŠøŠ¼Ń + + + + &Always perform this action + + + + + &Rename + ŠæŠµŃ€ŠµŠøŠ¼ŠµŠ½Š¾Š²Š°Ń‚ŃŒ + + + + Merge + сŠ»ŠøяŠ½ŠøŠµ + + + + Skip + ŠæрŠ¾ŠæусŠŗŠ°Ń‚ŃŒ + + + + &Cancel + Š¾Ń‚Š¼ŠµŠ½Šøть + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/th/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/th/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/th/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/tr/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/tr/translation.ts new file mode 100644 index 0000000..a00b0cd --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/tr/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + The test string matches with the regex + + + + + Checking + + + + + Test string: + + + + + Filters dialog + + + + + Whole string must match + + + + + The regex is valid + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + Renaming rules + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/Languages/zh/translation.ts b/plugins/CopyEngine/Ultracopier/Languages/zh/translation.ts new file mode 100644 index 0000000..5c68ad9 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Languages/zh/translation.ts @@ -0,0 +1,1289 @@ + + + + + AvancedQFile + + + + + Not supported on this platform + + + + + Last modified date is wrong + + + + + Last access date is wrong + + + + + Unknown error: %1 + + + + + Unknown error + + + + + Path conversion error + + + + + CopyEngine + + + + The engine is forced to move, you can't copy with it + + + + + + The engine is forced to copy, you can't move with it + + + + + Destination + + + + + Use the actual destination "%1"? + + + + + The mode has been forced previously. This is an internal error, please report it + + + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + CopyEngineFactory + + + + + + Ask + + + + + + + + Skip + + + + + Merge + + + + + + Rename + + + + + Put at the end + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + Options error + + + + + Options engine is not loaded. Unable to access the filters + + + + + Options engine is not loaded, can't access to the filters + + + + + DiskSpace + + + Disk space + + + + + You need more space on this drive to finish this transfer + + + + + Continue + + + + + Cancel + + + + + Drives %1 have %2 available but need %3 + + + + + FileErrorDialog + + + Error on folder + + + + + Folder name + + + + + FileExistsDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FileIsSameDialog + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + FilterRules + + + Filters dialog + + + + + Search: + + + + + Search type: + + + + + Raw text + + + + + Simplified regex + + + + + Perl's regex + + + + + Apply on: + + + + + File + + + + + Folder + + + + + File and folder + + + + + Whole string must match + + + + + The test string matches with the regex + + + + + Checking + + + + + The regex is valid + + + + + Test string: + + + + + Filters + + + Filters + + + + + Exclusion filters + + + + + Inclusion filters + + + + + None = Include all + + + + + + Raw text + + + + + + Simplified regex + + + + + + Perl's regex + + + + + + Only on file + + + + + + Only on folder + + + + + + + + Full match + + + + + FolderExistsDialog + + + Folder already exists + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + Error + + + + + Try rename with using special characters + + + + + ListThread + + + + Unable do to move or copy item into wrong forced mode: %1 + + + + + + Unable to save the transfer list: %1 + + + + + Problem reading file, or file-size is 0 + + + + + Wrong header: "%1" + + + + + The transfer list is in mixed mode, but this instance is not in this mode + + + + + The transfer list is in copy mode, but this instance is not in this mode + + + + + The transfer list is in move mode, but this instance is not in this mode + + + + + Some errors have been found during the line parsing + + + + + Unable to open the transfer list: %1 + + + + + MkPath + + + Unable to create the folder + + + + + The source folder don't exists + + + + + Unable to temporary rename the folder + + + + + Unable to do the final real move the folder + + + + + Unable to move the folder + + + + + + Unable to remove + + + + + ReadThread + + + Internal error, please report it! + + + + + Internal error reading the source file:block size out of range + + + + + + Unable to read the source file: + + + + + + File truncated during the read, possible data change + + + + + RenamingRules + + + Renaming rules + + + + + First renaming + + + + + %name% - copy + %name% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + should not be translated + + + + + Second renaming + + + + + %name% - copy (%number%) + %name%, %number% should not be translated + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + %name%, %number% should not be translated + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + ScanFileOrFolder + + + Blacklisted folder + + + + + + %1 - copy + + + + + + %1 - copy (%2) + + + + + This is not a folder + + + + + The folder does exists + + + + + The folder is not readable + + + + + Problem with name encoding + + + + + TransferThread + + + + + + File not found + + + + + + Wrong modification date or unable to get it, you can disable time transfer to do it + + + + + + Internal error: Already opening + + + + + Drive %1 + + + + + Unknown folder + + + + + root + + + + + %1 - copy + + + + + %1 - copy (%2) + + + + + + The source file doesn't exist + + + + + + Unable to do the folder + + + + + The source doesn't exist + + + + + Another file exists at same place + + + + + The checksums do not match + + + + + Internal error: The destination is not closed + + + + + Internal error: The size transfered doesn't match + + + + + Internal error: The buffer is not empty + + + + + + + Unable to change the date + + + + + Try rename with using special characters + + + + + WriteThread + + + Path resolution error (Empty path) + + + + + Internal error, please report it! + + + + + Unable to read the source file: + + + + + File truncated during read, possible data change + + + + + copyEngineOptions + + + Transfer + + + + + Move the whole folder + + + + + Transfer the file rights + + + + + Keep the file date + + + + + Autostart the transfer + + + + + + Less performance if checked + + + + + Follow the strict order + + + + + Error and collision + + + + + When folder error + + + + + When file error + + + + + When file collision + + + + + When folder collision + + + + + Check if destination folder exists + + + + + Renaming rules + + + + + Delete partially transferred files + + + + + Rename the original destination + + + + + Control + + + + + Checksum + + + + + Only after error + + + + + Ignore if impossible + + + + + Verify checksums + + + + + Performance + + + + + Parallel buffer + + + + + + + + + KB + + + + + Block size + + + + + Sequential buffer + + + + + Enable OS buffer + + + + + OS buffer only if smaller than + + + + + Transfer algorithm + + + + + Parallelize if smaller than + + + + + Inode threads + + + + + + More cpu, but better organisation on the disk + + + + + Order the list + + + + + Misc + + + + + Check the disk space + + + + + Use this folder when destination is not set + + + + + Browse + + + + + Filters + + + + + fileErrorDialog + + + Error with file + + + + + Error + + + + + Size + + + + + Modified + + + + + File name + + + + + Destination + + + + + Folder + + + + + &Always perform this action + + + + + Try in with elevated privileges + + + + + Put to bottom + + + + + Retry + + + + + &Skip + + + + + &Cancel + + + + + fileExistsDialog + + + The file exists + + + + + Source + + + + + Destination + + + + + + Size + + + + + + Modified + + + + + + File name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + + Overwrite if modification date differs + + + + + &Rename + + + + + &Overwrite + + + + + &Skip + + + + + &Cancel + + + + + Overwrite if newer + + + + + + Overwrite if older + + + + + fileIsSameDialog + + + Size + + + + + Modified + + + + + File name + + + + + The source and destination are same + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + &Skip + + + + + &Cancel + + + + + folderExistsDialog + + + Source + + + + + Destination + + + + + The source and destination is identical + + + + + + Modified + + + + + + Folder name + + + + + + Folder + + + + + Suggest new &name + + + + + &Always perform this action + + + + + &Rename + + + + + Merge + + + + + Skip + + + + + &Cancel + + + + diff --git a/plugins/CopyEngine/Ultracopier/ListThread.cpp b/plugins/CopyEngine/Ultracopier/ListThread.cpp new file mode 100644 index 0000000..8d47326 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/ListThread.cpp @@ -0,0 +1,2399 @@ +#include "ListThread.h" +#include +#include +#include "../../../cpp11addition.h" + +ListThread::ListThread(FacilityInterface * facilityInterface) +{ + moveToThread(this); + start(HighPriority); + this->facilityInterface = facilityInterface; + putInPause = false; + sourceDriveMultiple = false; + destinationDriveMultiple = false; + destinationFolderMultiple = false; + stopIt = false; + bytesToTransfer = 0; + bytesTransfered = 0; + idIncrementNumber = 1; + actualRealByteTransfered = 0; + numberOfTransferIntoToDoList = 0; + numberOfInodeOperation = 0; + putAtBottom = 0; + maxSpeed = 0; + inodeThreads = 1; + renameTheOriginalDestination = false; + doRightTransfer = false; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + rsync = false; + #endif + keepDate = false; + checkDiskSpace = true; + blockSize = ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*1024; + sequentialBuffer = ULTRACOPIER_PLUGIN_DEFAULT_SEQUENTIAL_NUMBER_OF_BLOCK; + parallelBuffer = ULTRACOPIER_PLUGIN_DEFAULT_PARALLEL_NUMBER_OF_BLOCK; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + blockSizeAfterSpeedLimitation = blockSize; + #endif + osBufferLimit = 512; + alwaysDoThisActionForFileExists = FileExists_NotSet; + doChecksum = false; + checksumIgnoreIfImpossible = true; + checksumOnlyOnError = true; + osBuffer = false; + osBufferLimited = false; + forcedMode = false; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + clockForTheCopySpeed = NULL; + multiForBigSpeed = 0; + #endif + + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + connect(&timerUpdateDebugDialog,&QTimer::timeout,this,&ListThread::timedUpdateDebugDialog); + timerUpdateDebugDialog.start(ULTRACOPIER_PLUGIN_DEBUG_WINDOW_TIMER); + #endif + connect(this, &ListThread::tryCancel, this,&ListThread::cancel, Qt::QueuedConnection); + connect(this, &ListThread::askNewTransferThread, this,&ListThread::createTransferThread, Qt::QueuedConnection); + connect(&mkPathQueue, &MkPath::firstFolderFinish, this,&ListThread::mkPathFirstFolderFinish, Qt::QueuedConnection); + connect(&mkPathQueue, &MkPath::errorOnFolder, this,&ListThread::mkPathErrorOnFolder, Qt::QueuedConnection); + connect(this, &ListThread::send_syncTransferList, this,&ListThread::syncTransferList_internal, Qt::QueuedConnection); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + connect(&mkPathQueue, &MkPath::debugInformation, this,&ListThread::debugInformation, Qt::QueuedConnection); + connect(&driveManagement,&DriveManagement::debugInformation, this,&ListThread::debugInformation, Qt::QueuedConnection); + #endif // ULTRACOPIER_PLUGIN_DEBUG + + emit askNewTransferThread(); + mkpathTransfer.release(); +} + +ListThread::~ListThread() +{ + emit tryCancel(); + waitCancel.acquire(); + quit(); + wait(); +} + +//transfer is finished +void ListThread::transferInodeIsClosed() +{ + numberOfInodeOperation--; + #ifdef ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"numberOfInodeOperation: "+std::to_string(numberOfInodeOperation)); + #endif + TransferThread *temp_transfer_thread=qobject_cast(QObject::sender()); + if(temp_transfer_thread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"transfer thread not located!"); + return; + } + bool isFound=false; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + int countLocalParse=0; + #endif + if(temp_transfer_thread->getStat()!=TransferStat_Idle) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"transfer thread not idle!"); + return; + } + int int_for_internal_loop=0; + const int &loop_size=actionToDoListTransfer.size(); + while(int_for_internal_looptransferId) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[%1] have finish, put at idle; for id: %2").arg(int_for_internal_loop).arg(temp_transfer_thread->transferId).toStdString()); + Ultracopier::ReturnActionOnCopyList newAction; + newAction.type=Ultracopier::RemoveItem; + newAction.userAction.moveAt=0; + newAction.addAction=actionToDoTransferToItemOfCopyList(actionToDoListTransfer.at(int_for_internal_loop)); + newAction.userAction.position=int_for_internal_loop; + actionDone.push_back(newAction); + /// \todo check if item is at the right thread + actionToDoListTransfer.erase(actionToDoListTransfer.cbegin()+int_for_internal_loop); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("actionToDoListTransfer.size(): %1, actionToDoListInode: %2, actionToDoListInode_afterTheTransfer: %3").arg(actionToDoListTransfer.size()).arg(actionToDoListInode.size()).arg(actionToDoListInode_afterTheTransfer.size()).toStdString()); + if(actionToDoListTransfer.empty() && actionToDoListInode.empty() && actionToDoListInode_afterTheTransfer.empty()) + updateTheStatus(); + + //add the current size of file, to general size because it's finish + copiedSize=temp_transfer_thread->copiedSize(); + if(copiedSize>(qint64)temp_transfer_thread->transferSize) + { + oversize=copiedSize-temp_transfer_thread->transferSize; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"add oversize of: "+std::to_string(oversize)); + bytesToTransfer+=oversize; + bytesTransfered+=oversize; + } + bytesTransfered+=temp_transfer_thread->transferSize; + + if(temp_transfer_thread->haveStartTime) + { + timeToTransfer.push_back(std::pair(temp_transfer_thread->transferSize,temp_transfer_thread->startTransferTime.elapsed())); + temp_transfer_thread->haveStartTime=false; + } + temp_transfer_thread->transferId=0; + temp_transfer_thread->transferSize=0; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + countLocalParse++; + #endif + isFound=true; + if(actionToDoListTransfer.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"actionToDoListTransfer==0"); + actionToDoListInode.insert(actionToDoListInode.cbegin(),actionToDoListInode_afterTheTransfer.cbegin(),actionToDoListInode_afterTheTransfer.cend()); + actionToDoListInode_afterTheTransfer.clear(); + doNewActions_inode_manipulation(); + } + break; + } + int_for_internal_loop++; + } + if(isFound) + deleteTransferThread(); + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,QStringLiteral("unable to found item into the todo list, id: %1, index: %2").arg(temp_transfer_thread->transferId).arg(int_for_internal_loop).toStdString()); + temp_transfer_thread->transferId=0; + temp_transfer_thread->transferSize=0; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("countLocalParse: %1, actionToDoList.size(): %2").arg(countLocalParse).arg(actionToDoListTransfer.size()).toStdString()); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + if(countLocalParse!=1) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"countLocalParse != 1"); + #endif + doNewActions_inode_manipulation(); +} + +/** \brief put the current file at bottom in case of error +\note ONLY IN CASE OF ERROR */ +void ListThread::transferPutAtBottom() +{ + TransferThread *transfer=qobject_cast(QObject::sender()); + if(transfer==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"transfer thread not located!"); + return; + } + bool isFound=false; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + int countLocalParse=0; + #endif + unsigned int indexAction=0; + while(indexActiontransferId) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Put at the end: "+std::to_string(transfer->transferId)); + //push for interface at the end + Ultracopier::ReturnActionOnCopyList newAction; + newAction.type=Ultracopier::MoveItem; + newAction.addAction.id=transfer->transferId; + newAction.userAction.position=actionToDoListTransfer.size()-1; + actionDone.push_back(newAction); + //do the wait stat + actionToDoListTransfer[indexAction].isRunning=false; + //move at the end + actionToDoListTransfer.push_back(actionToDoListTransfer.at(indexAction)); + actionToDoListTransfer.erase(actionToDoListTransfer.cbegin()+indexAction); + //reset the thread list stat + transfer->transferId=0; + transfer->transferSize=0; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + countLocalParse++; + #endif + isFound=true; + break; + } + indexAction++; + } + if(!isFound) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,QStringLiteral("unable to found item into the todo list, id: %1, index: %2").arg(transfer->transferId).toStdString()); + transfer->transferId=0; + transfer->transferSize=0; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"countLocalParse: "+std::to_string(countLocalParse)); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + if(countLocalParse!=1) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"countLocalParse != 1"); + #endif + transfer->skip(); +} + +//set the copy info and options before runing +void ListThread::setRightTransfer(const bool doRightTransfer) +{ + mkPathQueue.setRightTransfer(doRightTransfer); + this->doRightTransfer=doRightTransfer; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetRightTransfer(doRightTransfer); + index++; + } +} + +//set keep date +void ListThread::setKeepDate(const bool keepDate) +{ + mkPathQueue.setKeepDate(keepDate); + this->keepDate=keepDate; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetKeepDate(keepDate); + index++; + } +} + +//set block size in KB +void ListThread::setBlockSize(const int blockSize) +{ + this->blockSize=blockSize*1024; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetBlockSize(this->blockSize); + index++; + } + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + setSpeedLimitation(maxSpeed); + #endif +} + +//set auto start +void ListThread::setAutoStart(const bool autoStart) +{ + this->autoStart=autoStart; +} + +#ifdef ULTRACOPIER_PLUGIN_RSYNC +/// \brief set rsync +void ListThread::setRsync(const bool rsync) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"set rsync: "+std::to_string(rsync)); + this->rsync=rsync; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetRsync(rsync); + index++; + } + for(unsigned int i=0;isetRsync(rsync); +} +#endif + +//set check destination folder +void ListThread::setCheckDestinationFolderExists(const bool checkDestinationFolderExists) +{ + this->checkDestinationFolderExists=checkDestinationFolderExists; + for(unsigned int i=0;isetCheckDestinationFolderExists(checkDestinationFolderExists && alwaysDoThisActionForFolderExists!=FolderExists_Merge); +} + +void ListThread::fileTransfer(const QFileInfo &sourceFileInfo,const QFileInfo &destinationFileInfo,const Ultracopier::CopyMode &mode) +{ + if(stopIt) + return; + addToTransfer(sourceFileInfo,destinationFileInfo,mode); +} + +// -> add thread safe, by Qt::BlockingQueuedConnection +bool ListThread::haveSameSource(const std::vector &sources) +{ + if(stopIt) + return false; + if(sourceDriveMultiple) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sourceDriveMultiple"); + return false; + } + if(sourceDrive.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sourceDrive.isEmpty()"); + return true; + } + unsigned int index=0; + while(index add thread safe, by Qt::BlockingQueuedConnection +bool ListThread::haveSameDestination(const std::string &destination) +{ + if(stopIt) + return false; + if(destinationDriveMultiple) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"destinationDriveMultiple"); + return false; + } + if(destinationDrive.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"destinationDrive.isEmpty()"); + return true; + } + if(driveManagement.getDrive(destination)!=destinationDrive) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"destination!=destinationDrive"); + return false; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"seam have same destination"); + return true; +} + +/// \return empty if multiple or no destination +std::string ListThread::getUniqueDestinationFolder() const +{ + if(stopIt) + return std::string(); + if(destinationFolderMultiple) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"destinationDriveMultiple"); + return std::string(); + } + return destinationFolder; +} + +ScanFileOrFolder * ListThread::newScanThread(Ultracopier::CopyMode mode) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start with: "+std::to_string(mode)); + + //create new thread because is auto-detroyed + scanFileOrFolderThreadsPool.push_back(new ScanFileOrFolder(mode)); + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::finishedTheListing, this,&ListThread::scanThreadHaveFinishSlot, Qt::QueuedConnection); + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::fileTransfer, this,&ListThread::fileTransfer, Qt::QueuedConnection); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::debugInformation, this,&ListThread::debugInformation, Qt::QueuedConnection); + #endif + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::newFolderListing, this,&ListThread::newFolderListing); + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::addToMovePath, this,&ListThread::addToMovePath, Qt::QueuedConnection); + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::addToRealMove, this,&ListThread::addToRealMove, Qt::QueuedConnection); + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::addToMkPath, this,&ListThread::addToMkPath, Qt::QueuedConnection); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::addToRmForRsync, this,&ListThread::addToRmForRsync, Qt::QueuedConnection); + #endif + + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::errorOnFolder, this,&ListThread::errorOnFolder, Qt::QueuedConnection); + connect(scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::folderAlreadyExists, this,&ListThread::folderAlreadyExists, Qt::QueuedConnection); + + connect(this,&ListThread::send_updateMount, scanFileOrFolderThreadsPool.back(),&ScanFileOrFolder::set_updateMount, Qt::QueuedConnection); + + scanFileOrFolderThreadsPool.back()->setFilters(include,exclude); + scanFileOrFolderThreadsPool.back()->setCheckDestinationFolderExists(checkDestinationFolderExists && alwaysDoThisActionForFolderExists!=FolderExists_Merge); + scanFileOrFolderThreadsPool.back()->setMoveTheWholeFolder(moveTheWholeFolder); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + scanFileOrFolderThreadsPool.back()->setRsync(rsync); + #endif + if(scanFileOrFolderThreadsPool.size()==1) + updateTheStatus(); + scanFileOrFolderThreadsPool.back()->setRenamingRules(firstRenamingRule,otherRenamingRule); + return scanFileOrFolderThreadsPool.back(); +} + +void ListThread::scanThreadHaveFinishSlot() +{ + scanThreadHaveFinish(); +} + +void ListThread::scanThreadHaveFinish(bool skipFirstRemove) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"listing thread have finish, skipFirstRemove: "+std::to_string(skipFirstRemove)); + if(!skipFirstRemove) + { + ScanFileOrFolder * senderThread = qobject_cast(QObject::sender()); + if(senderThread==NULL) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"sender pointer null (plugin copy engine)"); + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start the next thread, scanFileOrFolderThreadsPool.size(): "+std::to_string(scanFileOrFolderThreadsPool.size())); + delete senderThread; + vectorremoveOne(scanFileOrFolderThreadsPool,senderThread); + if(scanFileOrFolderThreadsPool.empty()) + updateTheStatus(); + } + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start the next thread, scanFileOrFolderThreadsPool.size(): "+std::to_string(scanFileOrFolderThreadsPool.size())); + if(scanFileOrFolderThreadsPool.size()>0) + { + //then start the next listing threads + if(scanFileOrFolderThreadsPool.front()->isFinished()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Start listing thread"); + scanFileOrFolderThreadsPool.front()->start(); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"The listing thread is already running"); + } + else + autoStartAndCheckSpace(); +} + +void ListThread::autoStartAndCheckSpace() +{ + if(needMoreSpace()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Need more space"); + return; + } + autoStartIfNeeded(); +} + +void ListThread::autoStartIfNeeded() +{ + if(autoStart) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Auto start the copy"); + startGeneralTransfer(); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Put the copy engine in pause"); + putInPause=true; + emit isInPause(true); + } +} + +void ListThread::startGeneralTransfer() +{ + doNewActions_inode_manipulation(); +} + +// -> add thread safe, by Qt::BlockingQueuedConnection +bool ListThread::newCopy(const std::vector &sources,const std::string &destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+stringimplode(sources,";")+", destination: "+destination); + ScanFileOrFolder * scanFileOrFolderThread = newScanThread(Ultracopier::Copy); + if(scanFileOrFolderThread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to get new thread"); + return false; + } + scanFileOrFolderThread->addToList(sources,destination); + scanThreadHaveFinish(true); + detectDrivesOfCurrentTransfer(sources,destination); + return true; +} + +// -> add thread safe, by Qt::BlockingQueuedConnection +bool ListThread::newMove(const std::vector &sources,const std::string &destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + ScanFileOrFolder * scanFileOrFolderThread = newScanThread(Ultracopier::Move); + if(scanFileOrFolderThread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to get new thread"); + return false; + } + scanFileOrFolderThread->addToList(sources,destination); + scanThreadHaveFinish(true); + detectDrivesOfCurrentTransfer(sources,destination); + return true; +} + +void ListThread::detectDrivesOfCurrentTransfer(const std::vector &sources,const std::string &destination) +{ + /* code to detect volume/mount point to group by windows */ + if(!sourceDriveMultiple) + { + unsigned int index=0; + while(indexalwaysDoThisActionForFileExists=alwaysDoThisActionForFileExists; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetAlwaysFileExistsAction(alwaysDoThisActionForFileExists); + index++; + } +} + +/** \brief to sync the transfer list + * Used when the interface is changed, useful to minimize the memory size */ +void ListThread::syncTransferList() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + emit send_syncTransferList(); +} + +//set the folder local collision +void ListThread::setFolderCollision(const FolderExistsAction &alwaysDoThisActionForFolderExists) +{ + this->alwaysDoThisActionForFolderExists=alwaysDoThisActionForFolderExists; +} + +bool ListThread::getReturnBoolToCopyEngine() const +{ + return returnBoolToCopyEngine; +} + +std::pair ListThread::getReturnPairQuint64ToCopyEngine() const +{ + return returnPairQuint64ToCopyEngine; +} + +Ultracopier::ItemOfCopyList ListThread::getReturnItemOfCopyListToCopyEngine() const +{ + return returnItemOfCopyListToCopyEngine; +} + +void ListThread::set_doChecksum(bool doChecksum) +{ + this->doChecksum=doChecksum; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexset_doChecksum(doChecksum); + index++; + } +} + +void ListThread::set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible) +{ + this->checksumIgnoreIfImpossible=checksumIgnoreIfImpossible; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexset_checksumIgnoreIfImpossible(checksumIgnoreIfImpossible); + index++; + } +} + +void ListThread::set_checksumOnlyOnError(bool checksumOnlyOnError) +{ + this->checksumOnlyOnError=checksumOnlyOnError; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexset_checksumOnlyOnError(checksumOnlyOnError); + index++; + } +} + +void ListThread::set_osBuffer(bool osBuffer) +{ + this->osBuffer=osBuffer; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexset_osBuffer(osBuffer); + index++; + } +} + +void ListThread::set_osBufferLimited(bool osBufferLimited) +{ + this->osBufferLimited=osBufferLimited; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexset_osBufferLimited(osBufferLimited); + index++; + } +} + +void ListThread::realByteTransfered() +{ + quint64 totalRealByteTransfered=0; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexrealByteTransfered(); + index++; + } + emit send_realBytesTransfered(totalRealByteTransfered); +} + +void ListThread::pause() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + if(putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Seam already in pause!"); + return; + } + putInPause=true; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexpause(); + index++; + } + emit isInPause(true); +} + +void ListThread::resume() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + if(!putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Seam already resumed!"); + return; + } + putInPause=false; + startGeneralTransfer(); + doNewActions_start_transfer(); + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexresume(); + index++; + } + emit isInPause(false); +} + +void ListThread::skip(const uint64_t &id) +{ + skipInternal(id); +} + +bool ListThread::skipInternal(const uint64_t &id) +{ + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indextransferId==id) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"skip one transfer: "+std::to_string(id)); + transferThreadList.at(index)->skip(); + return true; + } + index++; + } + int int_for_internal_loop=0; + const int &loop_size=actionToDoListTransfer.size(); + while(int_for_internal_loopstop(); + index++; + } + index=0; + loop_size=scanFileOrFolderThreadsPool.size(); + while(indexstop(); + delete scanFileOrFolderThreadsPool.at(index);//->deleteLayer(); + scanFileOrFolderThreadsPool[index]=NULL; + index++; + } + scanFileOrFolderThreadsPool.clear(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + if(clockForTheCopySpeed!=NULL) + { + clockForTheCopySpeed->stop(); + delete clockForTheCopySpeed; + clockForTheCopySpeed=NULL; + } + #endif + checkIfReadyToCancel(); +} + +void ListThread::checkIfReadyToCancel() +{ + if(!stopIt) + return; + int index=0; + int loop_size=transferThreadList.size(); + while(indextransferId!=0) + return; + delete transferThreadList.at(index);//->deleteLayer(); + transferThreadList[index]=NULL; + transferThreadList.erase(transferThreadList.cbegin()+index); + loop_size=transferThreadList.size(); + index--; + } + index++; + } + actionToDoListTransfer.clear(); + actionToDoListInode.clear(); + actionToDoListInode_afterTheTransfer.clear(); + actionDone.clear(); + progressionList.clear(); + returnListItemOfCopyListToCopyEngine.clear(); + quit(); + waitCancel.release(); + emit canBeDeleted(); +} + +//speedLimitation in KB/s +bool ListThread::setSpeedLimitation(const int64_t &speedLimitation) +{ + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"maxSpeed in KB/s: "+std::to_string(speedLimitation)); + + if(speedLimitation>1024*1024) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"speedLimitation out of range"); + return false; + } + maxSpeed=speedLimitation; + + multiForBigSpeed=0; + if(maxSpeed>0) + { + blockSizeAfterSpeedLimitation=blockSize; + + //try resolv the interval + int newInterval;//in ms + do + { + multiForBigSpeed++; + //at max speed, is out of range for int, it's why quint64 is used + newInterval=(((quint64)blockSize*(quint64)multiForBigSpeed*1000/* *1000 because interval is into ms, not s*/)/((quint64)maxSpeed*(quint64)1024)); + if(newInterval<0) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"calculated newInterval wrong"); + return false; + } + } + while(newIntervalULTRACOPIER_PLUGIN_MAXTIMERINTERVAL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"wait time too big, then shrink the block size and set interval to max size"); + newInterval=ULTRACOPIER_PLUGIN_MAXTIMERINTERVAL; + multiForBigSpeed=1; + blockSizeAfterSpeedLimitation=(this->maxSpeed*1024*newInterval)/1000; + + if(blockSizeAfterSpeedLimitation<10) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"calculated block size wrong"); + return false; + } + + //set the new block size into the thread + const int &loop_size=transferThreadList.size(); + int int_for_loop=0; + while(int_for_loopsetBlockSize(blockSizeAfterSpeedLimitation)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the block size"); + int_for_loop++; + } + } + + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("fixed speed with new block size and new interval in BlockSize: %1, multiForBigSpeed: %2, newInterval: %3, maxSpeed: %4") + .arg(blockSizeAfterSpeedLimitation) + .arg(multiForBigSpeed) + .arg(newInterval) + .arg(maxSpeed) + .toStdString() + ); + + clockForTheCopySpeed->setInterval(newInterval); + if(clockForTheCopySpeed!=NULL) + clockForTheCopySpeed->start(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"clockForTheCopySpeed == NULL at this point"); + } + else + { + if(clockForTheCopySpeed!=NULL) + clockForTheCopySpeed->stop(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"clockForTheCopySpeed == NULL at this point"); + int int_for_loop=0; + const int &loop_size=transferThreadList.size(); + while(int_for_loopsetBlockSize(blockSize); + int_for_loop++; + } + } + int int_for_loop=0; + const int &loop_size=transferThreadList.size(); + while(int_for_loopsetMultiForBigSpeed(multiForBigSpeed); + int_for_loop++; + } + + return true; + #else + Q_UNUSED(speedLimitation); + return false; + #endif +} + +void ListThread::updateTheStatus() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + sendActionDone(); + bool updateTheStatus_listing=scanFileOrFolderThreadsPool.size()>0; + bool updateTheStatus_copying=actionToDoListTransfer.size()>0 || actionToDoListInode.size()>0 || actionToDoListInode_afterTheTransfer.size()>0; + Ultracopier::EngineActionInProgress updateTheStatus_action_in_progress; + if(updateTheStatus_copying && updateTheStatus_listing) + updateTheStatus_action_in_progress=Ultracopier::CopyingAndListing; + else if(updateTheStatus_listing) + updateTheStatus_action_in_progress=Ultracopier::Listing; + else if(updateTheStatus_copying) + updateTheStatus_action_in_progress=Ultracopier::Copying; + else + updateTheStatus_action_in_progress=Ultracopier::Idle; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"emit actionInProgess("+std::to_string(updateTheStatus_action_in_progress)+")"); + emit actionInProgess(updateTheStatus_action_in_progress); +} + +//set data local to the thread +void ListThread::setAlwaysFileExistsAction(const FileExistsAction &alwaysDoThisActionForFileExists) +{ + this->alwaysDoThisActionForFileExists=alwaysDoThisActionForFileExists; + int int_for_loop=0; + const int &loop_size=transferThreadList.size(); + while(int_for_loopsetAlwaysFileExistsAction(alwaysDoThisActionForFileExists); + int_for_loop++; + } +} + +//mk path to do +uint64_t ListThread::addToMkPath(const QFileInfo& source,const QFileInfo& destination, const int& inode) +{ + if(stopIt) + return 0; + if(inode!=0 && (!keepDate && !doRightTransfer)) + return 0; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + ActionToDoInode temp; + temp.type = ActionType_MkPath; + temp.id = generateIdNumber(); + temp.source = source; + temp.destination= destination; + temp.isRunning = false; + actionToDoListInode.push_back(temp); + return temp.id; +} + +//add rm path to do +void ListThread::addToMovePath(const QFileInfo& source, const QFileInfo &destination, const int& inodeToRemove) +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2, inodeToRemove: %3").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).arg(inodeToRemove).toStdString()); + ActionToDoInode temp; + temp.type = ActionType_MovePath; + temp.id = generateIdNumber(); + temp.size = inodeToRemove; + temp.source = source; + temp.destination= destination; + temp.isRunning = false; + actionToDoListInode.push_back(temp); +} + +void ListThread::addToRealMove(const QFileInfo& source,const QFileInfo& destination) +{ + if(stopIt) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + ActionToDoInode temp; + temp.type = ActionType_RealMove; + temp.id = generateIdNumber(); + temp.size = 0; + temp.source = source; + temp.destination= destination; + temp.isRunning = false; + actionToDoListInode.push_back(temp); +} + +#ifdef ULTRACOPIER_PLUGIN_RSYNC +//rsync rm +void ListThread::addToRmForRsync(const QFileInfo& destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"inode: "+destination.absoluteFilePath().toStdString()); + ActionToDoInode temp; + temp.type = ActionType_RmSync; + temp.id = generateIdNumber(); + temp.destination= destination; + temp.isRunning = false; + actionToDoListInode.push_back(temp); +} +#endif + +//send action done +void ListThread::sendActionDone() +{ + if(!actionDone.empty()) + { + emit newActionOnList(actionDone); + actionDone.clear(); + } + if(!timeToTransfer.empty()) + { + emit doneTime(timeToTransfer); + timeToTransfer.clear(); + } +} + +//send progression +void ListThread::sendProgression() +{ + if(actionToDoListTransfer.empty()) + return; + oversize=0; + currentProgression=0; + int int_for_loop=0; + const int &loop_size=transferThreadList.size(); + while(int_for_loopgetStat()) + { + case TransferStat_Transfer: + case TransferStat_PostTransfer: + case TransferStat_Checksum: + case TransferStat_PostOperation: + { + copiedSize=temp_transfer_thread->copiedSize(); + + //for the general progression + currentProgression+=copiedSize; + + //the oversize (when the file is bigger after/during the copy then what was during the listing) + if(copiedSize>(qint64)temp_transfer_thread->transferSize) + localOverSize=copiedSize-temp_transfer_thread->transferSize; + else + localOverSize=0; + + //the current size copied + totalSize=temp_transfer_thread->transferSize+localOverSize; + std::pair progression=temp_transfer_thread->progression(); + tempItem.currentRead=progression.first; + tempItem.currentWrite=progression.second; + tempItem.id=temp_transfer_thread->transferId; + tempItem.total=totalSize; + progressionList.push_back(tempItem); + + //add the oversize to the general progression + oversize+=localOverSize; + } + break; + default: + break; + } + int_for_loop++; + } + emit pushFileProgression(progressionList); + progressionList.clear(); + emit pushGeneralProgression(bytesTransfered+currentProgression,bytesToTransfer+oversize); + realByteTransfered(); +} + +//send the progression, after full reset of the interface (then all is empty) +void ListThread::syncTransferList_internal() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + emit syncReady(); + actionDone.clear(); + //do list operation + TransferThread *transferThread; + const int &loop_size=actionToDoListTransfer.size(); + int loop_sub_size=transferThreadList.size(); + //this loop to have at max inodeThreads*inodeThreads, not inodeThreads*transferThreadList.size() + int int_for_internal_loop; + for(int int_for_loop=0; int_for_loopgetStat()!=TransferStat_PreOperation) + { + Ultracopier::ReturnActionOnCopyList newAction; + switch(transferThread->getStat()) + { + case TransferStat_Transfer: + newAction.type=Ultracopier::Transfer; + break; + /*case TransferStat_PostTransfer: + newAction.type=Ultracopier::PostOperation; + break;*/ + case TransferStat_PostOperation: + newAction.type=Ultracopier::PostOperation; + break; + default: + break; + } + newAction.addAction.id = item.id; + actionDone.push_back(newAction); + } + } + } + } +} + +//add file transfer to do +uint64_t ListThread::addToTransfer(const QFileInfo& source,const QFileInfo& destination,const Ultracopier::CopyMode& mode) +{ + if(stopIt) + return 0; + //add to transfer list + numberOfTransferIntoToDoList++; + quint64 size=0; + if(!source.isSymLink()) + size=source.size(); + const std::string &drive=driveManagement.getDrive(destination.absoluteFilePath().toStdString()); + if(!drive.empty())//can be a network drive + if(mode!=Ultracopier::Move || drive!=driveManagement.getDrive(source.absoluteFilePath().toStdString())) + { + if(requiredSpace.find(drive)!=requiredSpace.cend()) + { + requiredSpace[drive]+=size; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("space needed add: %1, space needed: %2, on: %3").arg(size).arg(requiredSpace.at(drive)).arg(QString::fromStdString(drive)).toStdString()); + } + else + { + requiredSpace[drive]=size; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("set space %1 needed, on: %2").arg(size).arg(QString::fromStdString(drive)).toStdString()); + } + } + bytesToTransfer+= size; + ActionToDoTransfer temp; + temp.id = generateIdNumber(); + temp.size = size; + temp.source = source; + temp.destination= destination; + temp.mode = mode; + temp.isRunning = false; + actionToDoListTransfer.push_back(temp); + //push the new transfer to interface + Ultracopier::ReturnActionOnCopyList newAction; + newAction.type = Ultracopier::AddingItem; + newAction.addAction=actionToDoTransferToItemOfCopyList(temp); + actionDone.push_back(newAction); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2, add entry: %3, size: %4, size2: %5, isSymLink: %6").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).arg(temp.id).arg(temp.size).arg(size).arg(source.isSymLink()).toStdString()); + return temp.id; +} + +Ultracopier::ItemOfCopyList ListThread::actionToDoTransferToItemOfCopyList(const ListThread::ActionToDoTransfer &actionToDoTransfer) +{ + Ultracopier::ItemOfCopyList itemOfCopyList; + itemOfCopyList.id = actionToDoTransfer.id; + itemOfCopyList.sourceFullPath = actionToDoTransfer.source.absoluteFilePath().toStdString(); + itemOfCopyList.sourceFileName = actionToDoTransfer.source.fileName().toStdString(); + itemOfCopyList.destinationFullPath = actionToDoTransfer.destination.absoluteFilePath().toStdString(); + itemOfCopyList.destinationFileName = actionToDoTransfer.destination.fileName().toStdString(); + itemOfCopyList.size = actionToDoTransfer.size; + itemOfCopyList.mode = actionToDoTransfer.mode; + return itemOfCopyList; +} + +//generate id number +uint64_t ListThread::generateIdNumber() +{ + idIncrementNumber++; + if(idIncrementNumber>(((quint64)1024*1024)*1024*1024*2)) + idIncrementNumber=0; + return idIncrementNumber; +} + +//warning the first entry is accessible will copy +void ListThread::removeItems(const std::vector &ids) +{ + for(unsigned int i=0;i ids) +{ + if(actionToDoListTransfer.size()<=1) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"list size is empty"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + //do list operation + int indexToMove=0; + for (unsigned int i=0; i ids) +{ + if(actionToDoListTransfer.size()<=1) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"list size is empty"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + //do list operation + int lastGoodPositionReal=0; + bool haveGoodPosition=false; + for (unsigned int i=0; i ids) +{ + if(actionToDoListTransfer.size()<=1) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"list size is empty"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + //do list operation + int lastGoodPositionReal=0; + bool haveGoodPosition=false; + for (int i=actionToDoListTransfer.size()-1; i>=0; --i) { + if(vectorcontainsAtLeastOne(ids,actionToDoListTransfer.at(i).id)) + { + if(haveGoodPosition) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"move item "+std::to_string(i)+" to "+std::to_string(i+1)); + Ultracopier::ReturnActionOnCopyList newAction; + newAction.type=Ultracopier::MoveItem; + newAction.addAction.id=actionToDoListTransfer.at(i).id; + newAction.userAction.moveAt=lastGoodPositionReal; + newAction.userAction.position=i; + actionDone.push_back(newAction); + ActionToDoTransfer temp1=actionToDoListTransfer.at(i); + ActionToDoTransfer temp2=actionToDoListTransfer.at(lastGoodPositionReal); + actionToDoListTransfer[i]=temp2; + actionToDoListTransfer[lastGoodPositionReal]=temp1; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Try move up false, item "+std::to_string(i)); + } + vectorremoveOne(ids,actionToDoListTransfer.at(i).id); + if(ids.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop with return"); + return; + } + } + else + { + lastGoodPositionReal=i; + haveGoodPosition=true; + } + } + sendActionDone(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop"); +} + +//put on bottom +void ListThread::moveItemsOnBottom(std::vector ids) +{ + if(actionToDoListTransfer.size()<=1) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"list size is empty"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + //do list operation + int lastGoodPositionReal=actionToDoListTransfer.size()-1; + for (int i=lastGoodPositionReal; i>=0; --i) { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Check action on item "+std::to_string(i)); + if(vectorcontainsAtLeastOne(ids,actionToDoListTransfer.at(i).id)) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"move item "+std::to_string(i)+" to "+std::to_string(lastGoodPositionReal)); + vectorremoveOne(ids,actionToDoListTransfer.at(i).id); + Ultracopier::ReturnActionOnCopyList newAction; + newAction.type=Ultracopier::MoveItem; + newAction.addAction.id=actionToDoListTransfer.at(i).id; + newAction.userAction.moveAt=lastGoodPositionReal; + newAction.userAction.position=i; + actionDone.push_back(newAction); + ActionToDoTransfer temp=actionToDoListTransfer.at(i); + actionToDoListTransfer.erase(actionToDoListTransfer.cbegin()+i); + actionToDoListTransfer.insert(actionToDoListTransfer.cbegin()+lastGoodPositionReal,temp); + lastGoodPositionReal--; + if(ids.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop with return"); + return; + } + } + } + sendActionDone(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop"); +} + +/** \brief give the forced mode, to export/import transfer list */ +void ListThread::forceMode(const Ultracopier::CopyMode &mode) +{ + #ifdef ULTRACOPIER_PLUGIN_RSYNC + if(mode==Ultracopier::Move) + setRsync(false); + #endif + if(mode==Ultracopier::Copy) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Force mode to copy"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Force mode to move"); + this->mode=mode; + forcedMode=true; +} + +void ListThread::exportTransferList(const std::string &fileName) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + QFile transferFile(QString::fromStdString(fileName)); + if(transferFile.open(QIODevice::WriteOnly|QIODevice::Truncate)) + { + transferFile.write(QStringLiteral("Ultracopier;Transfer-list;").toUtf8()); + if(!forcedMode) + transferFile.write(QStringLiteral("Transfer;").toUtf8()); + else + { + if(mode==Ultracopier::Copy) + transferFile.write(QStringLiteral("Copy;").toUtf8()); + else + transferFile.write(QStringLiteral("Move;").toUtf8()); + } + transferFile.write(QStringLiteral("Ultracopier\n").toUtf8()); + bool haveError=false; + int size=actionToDoListTransfer.size(); + for (int index=0;index0 || actionToDoListInode.size()>0 || actionToDoListInode_afterTheTransfer.size()>0; + Ultracopier::EngineActionInProgress updateTheStatus_action_in_progress; + if(updateTheStatus_copying) + updateTheStatus_action_in_progress=Ultracopier::CopyingAndListing; + else + updateTheStatus_action_in_progress=Ultracopier::Listing; + emit actionInProgess(updateTheStatus_action_in_progress); + + bool errorFound=false; + std::regex correctLine; + if(transferListMixedMode) + correctLine=std::regex("^(Copy|Move);[^;]+;[^;]+[\n\r]*$"); + else + correctLine=std::regex("^[^;]+;[^;]+[\n\r]*$"); + std::vector args; + Ultracopier::CopyMode tempMode; + do + { + data=transferFile.readLine(65535*2); + if(data.size()>0) + { + content=std::string(data.constData(),data.size()); + //do the import here + if(std::regex_match(content,correctLine)) + { + stringreplaceAll(content,"\n",""); + args=stringsplit(content,';'); + if(forcedMode) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("New data to import in forced mode: %2,%3") + .arg(QString::fromStdString(args.at(0))) + .arg(QString::fromStdString(args.at(1))) + .toStdString()); + addToTransfer(QFileInfo(QString::fromStdString(args.at(0))),QFileInfo(QString::fromStdString(args.at(1))),mode); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("New data to import: %1,%2,%3") + .arg(QString::fromStdString(args.at(0))) + .arg(QString::fromStdString(args.at(1))) + .arg(QString::fromStdString(args.at(2))) + .toStdString()); + if(args.at(0)=="Copy") + tempMode=Ultracopier::Copy; + else + tempMode=Ultracopier::Move; + addToTransfer(QFileInfo(QString::fromStdString(args.at(1))),QFileInfo(QString::fromStdString(args.at(2))),tempMode); + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Wrong line syntax: "+content); + errorFound=true; + } + } + } + while(data.size()>0); + transferFile.close(); + if(errorFound) + emit warningTransferList(tr("Some errors have been found during the line parsing").toStdString()); + + updateTheStatus();//->sendActionDone(); into this + autoStartAndCheckSpace(); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("Unable to open the transfer list: %1").arg(transferFile.errorString()).toStdString()); + emit errorTransferList(tr("Unable to open the transfer list: %1").arg(transferFile.errorString()).toStdString()); + return; + } +} + +int ListThread::getNumberOfTranferRuning() const +{ + int numberOfTranferRuning=0; + const int &loop_size=transferThreadList.size(); + //lunch the transfer in WaitForTheTransfer + int int_for_loop=0; + while(int_for_loopgetStat()==TransferStat_Transfer && transferThreadList.at(int_for_loop)->transferId!=0 && transferThreadList.at(int_for_loop)->transferSize>=parallelizeIfSmallerThan) + numberOfTranferRuning++; + int_for_loop++; + } + return numberOfTranferRuning; +} + +//return +bool ListThread::needMoreSpace() const +{ + if(!checkDiskSpace) + return false; + std::vector diskspace_list; + for( auto& spaceDrive : requiredSpace ) { + const QString &drive=QString::fromStdString(spaceDrive.first); + #ifdef Q_OS_WIN32 + if(spaceDrive.first!="A:\\" && spaceDrive.first!="A:/" && spaceDrive.first!="A:" && spaceDrive.first!="A" && spaceDrive.first!="a:\\" && spaceDrive.first!="a:/" && spaceDrive.first!="a:" && spaceDrive.first!="a") + { + #endif + QStorageInfo storageInfo(drive); + storageInfo.refresh(); + const qint64 &availableSpace=storageInfo.bytesAvailable(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + const qint64 &bytesFree=storageInfo.bytesFree(); + #endif + + if(availableSpace<0 || + //workaround for all 0 value in case of bug from Qt + (availableSpace==0 && storageInfo.bytesTotal()==0) + ) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("availableSpace: %1, space needed: %2, on: %3, bytesFree: %4").arg(availableSpace).arg(spaceDrive.second).arg(drive).arg(bytesFree).toStdString()); + } + else if(spaceDrive.second>(quint64)availableSpace) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("availableSpace: %1, space needed: %2, on: %3, bytesFree: %4").arg(availableSpace).arg(spaceDrive.second).arg(drive).arg(bytesFree).toStdString()); + #ifdef Q_OS_WIN32 + //if(drive.contains(QRegularExpression("^[a-zA-Z]:[\\\\/]"))) + if(drive.contains(QRegularExpression("^[a-zA-Z]:"))) + #endif + { + Diskspace diskspace; + diskspace.drive=spaceDrive.first; + diskspace.freeSpace=availableSpace; + diskspace.requiredSpace=spaceDrive.second; + diskspace_list.push_back(diskspace); + } + #ifdef Q_OS_WIN32 + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"not local drive"); + #endif + } + #ifdef Q_OS_WIN32 + } + #endif + } + if(!diskspace_list.empty()) + emit missingDiskSpace(diskspace_list); + return ! diskspace_list.empty(); +} + +//do new actions +void ListThread::doNewActions_start_transfer() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("actionToDoListTransfer.size(): %1, numberOfTranferRuning: %2").arg(actionToDoListTransfer.size()).arg(getNumberOfTranferRuning()).toStdString()); + if(stopIt || putInPause) + return; + int numberOfTranferRuning=getNumberOfTranferRuning(); + const int &loop_size=transferThreadList.size(); + //lunch the transfer in WaitForTheTransfer + int int_for_loop=0; + while(int_for_loopgetStat()==TransferStat_WaitForTheTransfer) + { + if(transferThreadList.at(int_for_loop)->transferSize>=parallelizeIfSmallerThan) + { + if(numberOfTranferRuningstartTheTransfer(); + numberOfTranferRuning++; + } + } + else + transferThreadList.at(int_for_loop)->startTheTransfer(); + } + int_for_loop++; + } + int_for_loop=0; + while(int_for_loopgetStat()==TransferStat_PreOperation) + { + if(transferThreadList.at(int_for_loop)->transferSize>=parallelizeIfSmallerThan) + { + if(numberOfTranferRuningstartTheTransfer(); + numberOfTranferRuning++; + } + } + else + transferThreadList.at(int_for_loop)->startTheTransfer(); + } + int_for_loop++; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"numberOfTranferRuning: "+std::to_string(numberOfTranferRuning)); +} + +/** \brief lunch the pre-op or inode op + 1) locate the next next item to do into the both list + 1a) optimisation posible on the mkpath/rmpath + 2) determine what need be lunched + 3) lunch it, rerun the 2) + */ +void ListThread::doNewActions_inode_manipulation() +{ + #ifdef ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"actionToDoList.size(): "+std::to_string(actionToDoListTransfer.size())); + #endif + if(stopIt) + checkIfReadyToCancel(); + if(stopIt || putInPause) + return; + #ifdef ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + #endif + //lunch the pre-op or inode op + TransferThread *currentTransferThread; + int int_for_loop=0; + int int_for_internal_loop=0; + int int_for_transfer_thread_search=0; + actionToDoListTransfer_count=actionToDoListTransfer.size(); + actionToDoListInode_count=actionToDoListInode.size(); + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + //search the next transfer action to do + while(int_for_looptransferId==0) /!\ important! + Because the other thread can have call doNewAction before than this thread have the finish event parsed! + I this case it lose all data + */ + currentTransferThread=transferThreadList.at(int_for_transfer_thread_search); + if(currentTransferThread->getStat()==TransferStat_Idle && currentTransferThread->transferId==0) // /!\ important! + { + std::string drive=driveManagement.getDrive(actionToDoListTransfer.at(int_for_internal_loop).destination.absoluteFilePath().toStdString()); + if(requiredSpace.find(drive)!=requiredSpace.cend() && (actionToDoListTransfer.at(int_for_internal_loop).mode!=Ultracopier::Move || drive!=driveManagement.getDrive(actionToDoListTransfer.at(int_for_internal_loop).source.absoluteFilePath().toStdString()))) + { + requiredSpace[drive]-=actionToDoListTransfer.at(int_for_internal_loop).size; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("space needed removed: %1, space needed: %2, on: %3").arg(actionToDoListTransfer.at(int_for_internal_loop).size).arg(requiredSpace.at(drive)).arg(QString::fromStdString(drive)).toStdString()); + } + currentTransferThread->transferId=currentActionToDoTransfer.id; + currentTransferThread->transferSize=currentActionToDoTransfer.size; + if(!currentTransferThread->setFiles( + currentActionToDoTransfer.source, + currentActionToDoTransfer.size, + currentActionToDoTransfer.destination, + currentActionToDoTransfer.mode + )) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[%1] id: %2 is idle, but seam busy at set name: %3").arg(int_for_loop).arg(currentTransferThread->transferId).arg(currentActionToDoTransfer.destination.absoluteFilePath()).toStdString()); + break; + } + currentActionToDoTransfer.isRunning=true; + + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[%1] id: %2 is idle, use it for %3").arg(int_for_loop).arg(currentTransferThread->transferId).arg(currentActionToDoTransfer.destination.absoluteFilePath()).toStdString()); + + /// \note wrong position? Else write why it's here + Ultracopier::ReturnActionOnCopyList newAction; + newAction.type = Ultracopier::PreOperation; + newAction.addAction.id = currentActionToDoTransfer.id; + newAction.addAction.sourceFullPath = currentActionToDoTransfer.source.absoluteFilePath().toStdString(); + newAction.addAction.sourceFileName = currentActionToDoTransfer.source.fileName().toStdString(); + newAction.addAction.destinationFullPath = currentActionToDoTransfer.destination.absoluteFilePath().toStdString(); + newAction.addAction.destinationFileName = currentActionToDoTransfer.destination.fileName().toStdString(); + newAction.addAction.size = currentActionToDoTransfer.size; + newAction.addAction.mode = currentActionToDoTransfer.mode; + actionDone.push_back(newAction); + int_for_transfer_thread_search++; + numberOfInodeOperation++; + #ifdef ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"numberOfInodeOperation: "+std::to_string(numberOfInodeOperation)); + #endif + break; + } + int_for_transfer_thread_search++; + } + if(int_for_internal_loop==loop_sub_size_transfer_thread_search) + { + /// \note Can be normal when all thread is not initialized + #ifdef ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"unable to found free thread to do the transfer"); + #endif + break; + } + #ifdef ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"numberOfInodeOperation: "+std::to_string(numberOfInodeOperation)); + #endif + if(numberOfInodeOperation>=inodeThreads) + break; + if(followTheStrictOrder) + break; + } + int_for_loop++; + } + //search the next inode action to do + int_for_internal_loop=0; + while(int_for_internal_loopinodeThreads) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("The index have been detected as out of max range: %1>%2").arg(actionToDoListInode_count).arg(inodeThreads).toStdString()); + return; + } +} + +//restart transfer if it can +void ListThread::restartTransferIfItCan() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + TransferThread *transfer=qobject_cast(QObject::sender()); + if(transfer==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"transfer thread not located!"); + return; + } + int numberOfTranferRuning=getNumberOfTranferRuning(); + if(numberOfTranferRuninggetStat()==TransferStat_WaitForTheTransfer) + transfer->startTheTransfer(); + doNewActions_start_transfer(); +} + +/// \brief update the transfer stat +void ListThread::newTransferStat(const TransferStat &stat,const quint64 &id) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"TransferStat: "+std::to_string(stat)); + Ultracopier::ReturnActionOnCopyList newAction; + switch(stat) + { + case TransferStat_Idle: + return; + break; + case TransferStat_PreOperation: + return; + break; + case TransferStat_WaitForTheTransfer: + return; + break; + case TransferStat_Transfer: + newAction.type=Ultracopier::Transfer; + break; + case TransferStat_PostTransfer: + case TransferStat_PostOperation: + newAction.type=Ultracopier::PostOperation; + break; + case TransferStat_Checksum: + newAction.type=Ultracopier::CustomOperation; + break; + default: + return; + break; + } + newAction.addAction.id = id; + actionDone.push_back(newAction); +} + +void ListThread::set_osBufferLimit(const unsigned int &osBufferLimit) +{ + this->osBufferLimit=osBufferLimit; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexset_osBufferLimit(osBufferLimit); + index++; + } +} + +void ListThread::set_setFilters(const std::vector &include,const std::vector &exclude) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("include.size(): %1, exclude.size(): %2").arg(include.size()).arg(exclude.size()).toStdString()); + this->include=include; + this->exclude=exclude; + unsigned int index=0; + while(indexsetFilters(include,exclude); + index++; + } +} + +void ListThread::set_sendNewRenamingRules(const std::string &firstRenamingRule,const std::string &otherRenamingRule) +{ + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + emit send_sendNewRenamingRules(firstRenamingRule,otherRenamingRule); +} + +void ListThread::set_updateMount() +{ + driveManagement.tryUpdate(); + emit send_updateMount(); +} + +void ListThread::mkPathFirstFolderFinish() +{ + int int_for_loop=0; + const int &loop_size=actionToDoListInode.size(); + while(int_for_loop newList; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexgetStat()) + { + case TransferStat_Idle: + stat="Idle"; + break; + case TransferStat_PreOperation: + stat="PreOperation"; + break; + case TransferStat_WaitForTheTransfer: + stat="WaitForTheTransfer"; + break; + case TransferStat_Transfer: + stat="Transfer"; + break; + case TransferStat_PostOperation: + stat="PostOperation"; + break; + case TransferStat_PostTransfer: + stat="PostTransfer"; + break; + case TransferStat_Checksum: + stat="Checksum"; + break; + default: + stat=QStringLiteral("??? (%1)").arg(transferThreadList.at(index)->getStat()); + break; + } + newList.push_back(QStringLiteral("%1) (%3,%4) %2") + .arg(index) + .arg(stat) + .arg(transferThreadList.at(index)->readingLetter()) + .arg(transferThreadList.at(index)->writingLetter()) + .toStdString() + ); + index++; + } + std::vector newList2; + index=0; + const int &loop_size=actionToDoListTransfer.size(); + while(index((inodeThreads+ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER)*2+1)) + { + newList2.push_back("..."); + break; + } + index++; + } + emit updateTheDebugInfo(newList,newList2,numberOfInodeOperation); +} + +#endif + +/// \note Can be call without queue because all call will be serialized +void ListThread::fileAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame) +{ + emit send_fileAlreadyExists(source,destination,isSame,qobject_cast(sender())); +} + +/// \note Can be call without queue because all call will be serialized +void ListThread::errorOnFile(const QFileInfo &fileInfo, const std::string &errorString, const ErrorType &errorType) +{ + TransferThread * transferThread=qobject_cast(sender()); + if(transferThread==NULL) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Thread locating error"); + return; + } + ErrorLogEntry errorLogEntry; + errorLogEntry.source=transferThread->getSourceInode(); + errorLogEntry.destination=transferThread->getDestinationInode(); + errorLogEntry.mode=transferThread->getMode(); + errorLogEntry.error=errorString; + errorLog.push_back(errorLogEntry); + emit errorToRetry(transferThread->getSourcePath(),transferThread->getDestinationPath(),errorString); + emit send_errorOnFile(fileInfo,errorString,transferThread,errorType); +} + +/// \note Can be call without queue because all call will be serialized +void ListThread::folderAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame) +{ + emit send_folderAlreadyExists(source,destination,isSame,qobject_cast(sender())); +} + +/// \note Can be call without queue because all call will be serialized +/// \todo all this part +void ListThread::errorOnFolder(const QFileInfo &fileInfo,const std::string &errorString,const ErrorType &errorType) +{ + emit send_errorOnFolder(fileInfo,errorString,qobject_cast(sender()),errorType); +} + +//to run the thread +void ListThread::run() +{ + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + clockForTheCopySpeed=new QTimer(); + #endif + + exec(); +} + +void ListThread::getNeedPutAtBottom(const QFileInfo &fileInfo, const std::string &errorString, TransferThread *thread, const ErrorType &errorType) +{ + if(actionToDoListTransfer.empty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"can't try put at bottom if empty"); + this->alwaysDoThisActionForFileExists=FileExists_NotSet; + putAtBottom=0; + emit haveNeedPutAtBottom(false,fileInfo,errorString,thread,errorType); + return; + } + bool needPutAtBottom=(putAtBottom<(quint32)actionToDoListTransfer.size()); + if(!needPutAtBottom) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Reset put at bottom"); + this->alwaysDoThisActionForFileExists=FileExists_NotSet; + putAtBottom=0; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Put at bottom for later try"); + thread->putAtBottom(); + putAtBottom++; + return; + } + emit haveNeedPutAtBottom(needPutAtBottom,fileInfo,errorString,thread,errorType); +} + +/// \to create transfer thread +void ListThread::createTransferThread() +{ + if(stopIt) + return; + if(transferThreadList.size()>=(unsigned int)inodeThreads) + return; + transferThreadList.push_back(new TransferThread()); + TransferThread * last=transferThreadList.back(); + last->transferId=0; + last->transferSize=0; + last->setRightTransfer(doRightTransfer); + last->setKeepDate(keepDate); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + if(!last->setBlockSize(blockSizeAfterSpeedLimitation)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the block size: "+std::to_string(blockSizeAfterSpeedLimitation)); + #else + if(!last->setBlockSize(blockSize)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the block size: "+std::to_string(blockSize)); + #endif + if(!last->setSequentialBuffer(sequentialBuffer)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the sequentialBuffer: "+std::to_string(sequentialBuffer)); + if(!last->setBlockSize(parallelBuffer)) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the parallelBuffer: "+std::to_string(parallelBuffer)); + last->setAlwaysFileExistsAction(alwaysDoThisActionForFileExists); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + last->setMultiForBigSpeed(multiForBigSpeed); + #endif + last->set_doChecksum(doChecksum); + last->set_checksumIgnoreIfImpossible(checksumIgnoreIfImpossible); + last->set_checksumOnlyOnError(checksumOnlyOnError); + last->set_osBuffer(osBuffer); + last->set_osBufferLimited(osBufferLimited); + last->set_osBufferLimit(osBufferLimit); + last->setDeletePartiallyTransferredFiles(deletePartiallyTransferredFiles); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + last->setRsync(rsync); + #endif + + #ifdef ULTRACOPIER_PLUGIN_DEBUG + connect(last,&TransferThread::debugInformation, this,&ListThread::debugInformation, Qt::QueuedConnection); + #endif // ULTRACOPIER_PLUGIN_DEBUG + connect(last,&TransferThread::errorOnFile, this,&ListThread::errorOnFile, Qt::QueuedConnection); + connect(last,&TransferThread::fileAlreadyExists, this,&ListThread::fileAlreadyExists, Qt::QueuedConnection); + connect(last,&TransferThread::tryPutAtBottom, this,&ListThread::transferPutAtBottom, Qt::QueuedConnection); + connect(last,&TransferThread::readStopped, this,&ListThread::doNewActions_start_transfer, Qt::QueuedConnection); + connect(last,&TransferThread::preOperationStopped, this,&ListThread::doNewActions_start_transfer, Qt::QueuedConnection); + connect(last,&TransferThread::postOperationStopped, this,&ListThread::transferInodeIsClosed, Qt::QueuedConnection); + connect(last,&TransferThread::checkIfItCanBeResumed, this,&ListThread::restartTransferIfItCan, Qt::QueuedConnection); + connect(last,&TransferThread::pushStat, this,&ListThread::newTransferStat, Qt::QueuedConnection); + + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + //speed limitation + connect(clockForTheCopySpeed, &QTimer::timeout, last, &TransferThread::timeOfTheBlockCopyFinished, Qt::QueuedConnection); + #endif + + connect(this,&ListThread::send_sendNewRenamingRules, last,&TransferThread::setRenamingRules, Qt::QueuedConnection); + + connect(this,&ListThread::send_setTransferAlgorithm, last,&TransferThread::setTransferAlgorithm, Qt::QueuedConnection); + connect(this,&ListThread::send_parallelBuffer, last,&TransferThread::setParallelBuffer, Qt::QueuedConnection); + connect(this,&ListThread::send_sequentialBuffer, last,&TransferThread::setSequentialBuffer, Qt::QueuedConnection); + connect(this,&ListThread::send_updateMount, last,&TransferThread::set_updateMount, Qt::QueuedConnection); + + last->start(); + last->setObjectName(QStringLiteral("transfer %1").arg(transferThreadList.size()-1)); + last->setMkpathTransfer(&mkpathTransfer); + last->setRenamingRules(firstRenamingRule,otherRenamingRule); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + last->setId(transferThreadList.size()-1); + #endif + if(transferThreadList.size()>=(unsigned int)inodeThreads) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"create the last of the "+std::to_string(inodeThreads)+" transferThread"); + return; + } + if(stopIt) + return; + doNewActions_inode_manipulation(); + emit askNewTransferThread(); +} + +void ListThread::deleteTransferThread() +{ + int loop_size=transferThreadList.size(); + if(loop_size>inodeThreads) + { + int index=0; + while(indexinodeThreads) + { + if(transferThreadList.at(index)->getStat()==TransferStat_Idle && transferThreadList.at(index)->transferId==0) + { + transferThreadList.at(index)->stop(); + delete transferThreadList.at(index);//->deleteLayer(); + transferThreadList[index]=NULL; + transferThreadList.erase(transferThreadList.cbegin()+index); + loop_size--; + } + else + index++; + } + if(loop_size==inodeThreads) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"inodeThreads is lowered to the right value: "+std::to_string(inodeThreads)); + } +} + +void ListThread::setTransferAlgorithm(const TransferAlgorithm &transferAlgorithm) +{ + if(transferAlgorithm==TransferAlgorithm_Sequential) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"transferAlgorithm==TransferAlgorithm_Sequential"); + else if(transferAlgorithm==TransferAlgorithm_Automatic) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"transferAlgorithm==TransferAlgorithm_Automatic"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"transferAlgorithm==TransferAlgorithm_Parallel"); + emit send_setTransferAlgorithm(transferAlgorithm); +} + +void ListThread::setParallelBuffer(int parallelBuffer) +{ + if(parallelBuffer<1 || parallelBuffer>ULTRACOPIER_PLUGIN_MAX_PARALLEL_NUMBER_OF_BLOCK) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"wrong number of block: "+std::to_string(parallelBuffer)); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"in number of block: "+std::to_string(parallelBuffer)); + this->parallelBuffer=parallelBuffer; + emit send_parallelBuffer(parallelBuffer); +} + +void ListThread::setSequentialBuffer(int sequentialBuffer) +{ + if(sequentialBuffer<1 || sequentialBuffer>ULTRACOPIER_PLUGIN_MAX_SEQUENTIAL_NUMBER_OF_BLOCK) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"wrong number of block: "+std::to_string(sequentialBuffer)); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"in number of block: "+std::to_string(sequentialBuffer)); + this->sequentialBuffer=sequentialBuffer; + emit send_sequentialBuffer(sequentialBuffer); +} + +void ListThread::setParallelizeIfSmallerThan(const unsigned int ¶llelizeIfSmallerThan) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"parallelizeIfSmallerThan in Bytes: "+std::to_string(parallelizeIfSmallerThan)); + this->parallelizeIfSmallerThan=parallelizeIfSmallerThan; +} + +void ListThread::setMoveTheWholeFolder(const bool &moveTheWholeFolder) +{ + for(unsigned int i=0;isetMoveTheWholeFolder(moveTheWholeFolder); + this->moveTheWholeFolder=moveTheWholeFolder; +} + +void ListThread::setFollowTheStrictOrder(const bool &followTheStrictOrder) +{ + this->followTheStrictOrder=followTheStrictOrder; +} + +void ListThread::setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles) +{ + this->deletePartiallyTransferredFiles=deletePartiallyTransferredFiles; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetDeletePartiallyTransferredFiles(deletePartiallyTransferredFiles); + index++; + } +} + +void ListThread::setInodeThreads(const int &inodeThreads) +{ + if(inodeThreads<1 || inodeThreads>32) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"inodeThreads is out of ranges: "+std::to_string(inodeThreads)); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"inodeThreads: "+std::to_string(inodeThreads)); + this->inodeThreads=inodeThreads; + createTransferThread(); + deleteTransferThread(); +} + +void ListThread::setRenameTheOriginalDestination(const bool &renameTheOriginalDestination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"renameTheOriginalDestination: "+std::to_string(renameTheOriginalDestination)); + this->renameTheOriginalDestination=renameTheOriginalDestination; + int index=0; + int loop_sub_size_transfer_thread_search=transferThreadList.size(); + while(indexsetRenameTheOriginalDestination(renameTheOriginalDestination); + index++; + } +} + +void ListThread::setCheckDiskSpace(const bool &checkDiskSpace) +{ + this->checkDiskSpace=checkDiskSpace; +} + +void ListThread::setCopyListOrder(const bool &order) +{ + this->copyListOrder=order; + for(unsigned int i=0;isetCopyListOrder(this->copyListOrder); +} + +void ListThread::exportErrorIntoTransferList(const std::string &fileName) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + QFile transferFile(QString::fromStdString(fileName)); + if(transferFile.open(QIODevice::WriteOnly|QIODevice::Truncate)) + { + transferFile.write(QStringLiteral("Ultracopier;Transfer-list;").toUtf8()); + if(!forcedMode) + transferFile.write(QStringLiteral("Transfer;").toUtf8()); + else + { + if(mode==Ultracopier::Copy) + transferFile.write(QStringLiteral("Copy;").toUtf8()); + else + transferFile.write(QStringLiteral("Move;").toUtf8()); + } + transferFile.write(QStringLiteral("Ultracopier\n").toUtf8()); + bool haveError=false; + int size=errorLog.size(); + for (int index=0;index +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../../interface/PluginInterface_CopyEngine.h" +#include "ScanFileOrFolder.h" +#include "TransferThread.h" +#include "MkPath.h" +#include "Environment.h" +#include "DriveManagement.h" + +/// \brief Define the list thread, and management to the action to do +class ListThread : public QThread +{ + Q_OBJECT +public: + explicit ListThread(FacilityInterface * facilityInterface); + ~ListThread(); + + //duplication copy detection + /** \brief compare the current sources of the copy, with the passed arguments + * \param sources the sources list to compares with the current sources list + * \return true if have same sources, else false (or empty) */ + bool haveSameSource(const std::vector &sources); + /** \brief compare the current destination of the copy, with the passed arguments + * \param destination the destination to compares with the current destination + * \return true if have same destination, else false (or empty) */ + bool haveSameDestination(const std::string &destination); + /// \return empty if multiple or no destination + std::string getUniqueDestinationFolder() const; + //external soft like file browser have send copy/move list to do + /** \brief send copy with destination + * \param sources the sources list to copy + * \param destination the destination to copy + * \return true if the copy have been accepted */ + bool newCopy(const std::vector &sources,const std::string &destination); + /** \brief send move without destination, ask the destination + * \param sources the sources list to move + * \param destination the destination to move + * \return true if the move have been accepted */ + bool newMove(const std::vector &sources,const std::string &destination); + /** \brief to set drives detected + * specific to this copy engine */ + /// \brief to set the collision action + void setCollisionAction(const FileExistsAction &alwaysDoThisActionForFileExists); + /** \brief to sync the transfer list + * Used when the interface is changed, useful to minimize the memory size */ + void syncTransferList(); + /// \brief to store one action to do + struct ActionToDoTransfer + { + uint64_t id; + uint64_t size;///< Used to set: used in case of transfer or remainingInode for drop folder + QFileInfo source;///< Used to set: source for transfer, folder to create, folder to drop + QFileInfo destination; + Ultracopier::CopyMode mode; + bool isRunning;///< store if the action si running + //TransferThread * transfer; // -> see transferThreadList + }; + std::vector actionToDoListTransfer; + /// \brief to store one action to do + struct ActionToDoInode + { + ActionType type;///< \see ActionType + uint64_t id; + int64_t size;///< Used to set: used in case of transfer or remainingInode for drop folder + QFileInfo source;///< Keep to copy the right/date, to remove (for move) + QFileInfo destination;///< Used to set: folder to create, folder to drop + bool isRunning;///< store if the action si running + }; + std::vector actionToDoListInode; + std::vector actionToDoListInode_afterTheTransfer; + int numberOfInodeOperation; + struct ErrorLogEntry + { + QFileInfo source; + QFileInfo destination; + std::string error; + Ultracopier::CopyMode mode; + }; + std::vector errorLog; + //dir operation thread queue + MkPath mkPathQueue; + //to get the return value from copyEngine + bool getReturnBoolToCopyEngine() const; + std::pair getReturnPairQuint64ToCopyEngine() const; + Ultracopier::ItemOfCopyList getReturnItemOfCopyListToCopyEngine() const; + + void set_doChecksum(bool doChecksum); + void set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible); + void set_checksumOnlyOnError(bool checksumOnlyOnError); + void set_osBuffer(bool osBuffer); + void set_osBufferLimited(bool osBufferLimited); + void autoStartIfNeeded(); +public slots: + //action on the copy + /// \brief put the transfer in pause + void pause(); + /// \brief resume the transfer + void resume(); + /** \brief skip one transfer entry + * \param id id of the file to remove */ + void skip(const uint64_t &id); + /** \brief skip as interanl one transfer entry + * \param id id of the file to remove */ + bool skipInternal(const uint64_t &id); + /// \brief cancel all the transfer + void cancel(); + //edit the transfer list + /** \brief remove the selected item + * \param ids ids is the id list of the selected items */ + void removeItems(const std::vector &ids); + /** \brief move on top of the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsOnTop(std::vector ids); + /** \brief move up the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsUp(std::vector ids); + /** \brief move down the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsDown(std::vector ids); + /** \brief move on bottom of the list the selected item + * \param ids ids is the id list of the selected items */ + void moveItemsOnBottom(std::vector ids); + + /** \brief give the forced mode, to export/import transfer list */ + void forceMode(const Ultracopier::CopyMode &mode); + /// \brief export the transfer list into a file + void exportTransferList(const std::string &fileName); + /// \brief import the transfer list into a file + void importTransferList(const std::string &fileName); + + /// \brief set the folder local collision + void setFolderCollision(const FolderExistsAction &alwaysDoThisActionForFolderExists); + /** \brief to set the speed limitation + * -1 if not able, 0 if disabled */ + bool setSpeedLimitation(const int64_t &speedLimitation); + /// \brief set the copy info and options before runing + void setRightTransfer(const bool doRightTransfer); + /// \brief set keep date + void setKeepDate(const bool keepDate); + /// \brief set block size in KB + void setBlockSize(const int blockSize); + /// \brief set auto start + void setAutoStart(const bool autoStart); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + /// \brief set rsync + void setRsync(const bool rsync); + #endif + /// \brief set check destination folder + void setCheckDestinationFolderExists(const bool checkDestinationFolderExists); + /// \brief set data local to the thread + void setAlwaysFileExistsAction(const FileExistsAction &alwaysDoThisActionForFileExists); + /// \brief do new actions, start transfer + void doNewActions_start_transfer(); + /** \brief lunch the pre-op or inode op + 1) locate the next next item to do into the both list + 1a) optimisation posible on the mkpath/rmpath + 2) determine what need be lunched + 3) lunch it, rerun the 2) + */ + void doNewActions_inode_manipulation(); + /// \brief restart transfer if it can + void restartTransferIfItCan(); + void getNeedPutAtBottom(const QFileInfo &fileInfo, const std::string &errorString, TransferThread *thread,const ErrorType &errorType); + + /// \brief update the transfer stat + void newTransferStat(const TransferStat &stat,const quint64 &id); + + void set_osBufferLimit(const unsigned int &osBufferLimit); + void set_setFilters(const std::vector &include,const std::vector &exclude); + void set_sendNewRenamingRules(const std::string &firstRenamingRule,const std::string &otherRenamingRule); + void set_updateMount(); + + //send action done + void sendActionDone(); + //send progression + void sendProgression(); + + void setTransferAlgorithm(const TransferAlgorithm &transferAlgorithm); + void setParallelBuffer(int parallelBuffer); + void setSequentialBuffer(int sequentialBuffer); + void setParallelizeIfSmallerThan(const unsigned int ¶llelizeIfSmallerThan); + void setMoveTheWholeFolder(const bool &moveTheWholeFolder); + void setFollowTheStrictOrder(const bool &followTheStrictOrder); + void setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles); + void setInodeThreads(const int &inodeThreads); + void setRenameTheOriginalDestination(const bool &renameTheOriginalDestination); + void setCheckDiskSpace(const bool &checkDiskSpace); + void setCopyListOrder(const bool &order); + void exportErrorIntoTransferList(const std::string &fileName); +private: + QSemaphore mkpathTransfer; + std::string sourceDrive; + bool sourceDriveMultiple; + std::string destinationDrive; + std::string destinationFolder; + bool destinationDriveMultiple; + bool destinationFolderMultiple; + DriveManagement driveManagement; + + bool stopIt; + std::vector scanFileOrFolderThreadsPool; + int numberOfTransferIntoToDoList; + std::vector transferThreadList; + ScanFileOrFolder * newScanThread(Ultracopier::CopyMode mode); + uint64_t bytesToTransfer; + uint64_t bytesTransfered; + bool autoStart; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + bool rsync; + #endif + bool putInPause; + std::vector actionDone;///< to action to send to the interface + uint64_t idIncrementNumber;///< to store the last id returned + int64_t actualRealByteTransfered; + int maxSpeed;///< in KB/s, assume as 0KB/s as default like every where + FolderExistsAction alwaysDoThisActionForFolderExists; + bool checkDestinationFolderExists; + bool doChecksum; + bool checksumIgnoreIfImpossible; + bool checksumOnlyOnError; + bool osBuffer; + bool osBufferLimited; + unsigned int parallelizeIfSmallerThan; + bool moveTheWholeFolder; + bool followTheStrictOrder; + bool deletePartiallyTransferredFiles; + int sequentialBuffer; + int parallelBuffer; + int inodeThreads; + bool renameTheOriginalDestination; + bool checkDiskSpace; + bool copyListOrder; + std::unordered_map requiredSpace; + std::vector > timeToTransfer; + unsigned int putAtBottom; + unsigned int osBufferLimit; + std::vector include,exclude; + Ultracopier::CopyMode mode; + bool forcedMode; + std::string firstRenamingRule; + std::string otherRenamingRule; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + int multiForBigSpeed; + #endif + /* here to prevent: + QObject::killTimer: timers cannot be stopped from another thread + QObject::startTimer: timers cannot be started from another thread */ + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + QTimer *clockForTheCopySpeed; ///< For the speed throttling + #endif + + inline static Ultracopier::ItemOfCopyList actionToDoTransferToItemOfCopyList(const ActionToDoTransfer &actionToDoTransfer); + //add file transfer to do + uint64_t addToTransfer(const QFileInfo& source,const QFileInfo& destination,const Ultracopier::CopyMode& mode); + //generate id number + uint64_t generateIdNumber(); + //warning the first entry is accessible will copy + bool removeSingleItem(const uint64_t &id); + //put on top + bool moveOnTopItem(const uint64_t &id); + //move up + bool moveUpItem(const uint64_t &id); + //move down + bool moveDownItem(const uint64_t &id); + //put on bottom + bool moveOnBottomItem(const uint64_t &id); + //general transfer + void startGeneralTransfer(); + //debug windows if needed + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + QTimer timerUpdateDebugDialog; + #endif + void detectDrivesOfCurrentTransfer(const std::vector &sources,const std::string &destination); + FacilityInterface * facilityInterface; + QSemaphore waitConstructor,waitCancel; + int actionToDoListTransfer_count,actionToDoListInode_count; + bool doTransfer,doInode; + int64_t oversize;//used as temp variable + int64_t currentProgression; + int64_t copiedSize,totalSize,localOverSize; + std::vector progressionList; + //memory variable for transfer thread creation + bool doRightTransfer; + bool keepDate; + int blockSize;//in Bytes + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + int blockSizeAfterSpeedLimitation;//in Bytes + #endif + std::vector drives; + FileExistsAction alwaysDoThisActionForFileExists; + //to return value to the copyEngine + bool returnBoolToCopyEngine; + std::pair returnPairQuint64ToCopyEngine; + std::vector returnListItemOfCopyListToCopyEngine; + Ultracopier::ItemOfCopyList returnItemOfCopyListToCopyEngine; + Ultracopier::ProgressionItem tempItem; + + void realByteTransfered(); + int getNumberOfTranferRuning() const; + bool needMoreSpace() const; +private slots: + void scanThreadHaveFinishSlot(); + void scanThreadHaveFinish(bool skipFirstRemove=false); + void autoStartAndCheckSpace(); + void updateTheStatus(); + void fileTransfer(const QFileInfo &sourceFileInfo,const QFileInfo &destinationFileInfo,const Ultracopier::CopyMode &mode); + //mkpath event + void mkPathFirstFolderFinish(); + /** \brief put the current file at bottom in case of error + \note ONLY IN CASE OF ERROR */ + void transferPutAtBottom(); + //transfer is finished + void transferInodeIsClosed(); + //debug windows if needed + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + void timedUpdateDebugDialog(); + #endif + //dialog message + /// \note Can be call without queue because all call will be serialized + void fileAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame); + /// \note Can be call without queue because all call will be serialized + void errorOnFile(const QFileInfo &fileInfo,const std::string &errorString, const ErrorType &errorType); + /// \note Can be call without queue because all call will be serialized + void folderAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame); + /// \note Can be call without queue because all call will be serialized + void errorOnFolder(const QFileInfo &fileInfo, const std::string &errorString, const ErrorType &errorType); + //to run the thread + void run(); + /// \to create transfer thread + void createTransferThread(); + void deleteTransferThread(); + //mk path to do + uint64_t addToMkPath(const QFileInfo& source, const QFileInfo& destination, const int &inode); + //add rm path to do + void addToMovePath(const QFileInfo& source,const QFileInfo& destination, const int& inodeToRemove); + //add to real move + void addToRealMove(const QFileInfo& source,const QFileInfo& destination); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + //rsync rm + void addToRmForRsync(const QFileInfo& destination); + #endif + //send the progression, after full reset of the interface (then all is empty) + void syncTransferList_internal(); + + void checkIfReadyToCancel(); +signals: + //send information about the copy + void actionInProgess(const Ultracopier::EngineActionInProgress &) const; //should update interface information on this event + + void newActionOnList(const std::vector &) const;///very important, need be temporized to group the modification to do and not flood the interface + void syncReady() const; + void doneTime(const std::vector >&) const; + + /** \brief to get the progression for a specific file + * \param id the id of the transfer, id send during population the transfer list + * first = current transfered byte, second = byte to transfer */ + void pushFileProgression(const std::vector &progressionList) const; + //get information about the copy + /** \brief to get the general progression + * first = current transfered byte, second = byte to transfer */ + void pushGeneralProgression(const uint64_t &,const uint64_t &) const; + + void newFolderListing(const std::string &path) const; + void isInPause(const bool &) const; + + //when can be deleted + void canBeDeleted() const; + void haveNeedPutAtBottom(bool needPutAtBottom,const QFileInfo &fileInfo,const std::string &errorString,TransferThread * thread,const ErrorType &errorType) const; + + //send error occurred + void error(const std::string &path,const uint64_t &size,const uint64_t &mtime,const std::string &error) const; + void errorToRetry(const std::string &source,const std::string &destination,const std::string &error) const; + //for the extra logging + void rmPath(const std::string &path) const; + void mkPath(const std::string &path) const; + /// \brief To debug source + #ifdef ULTRACOPIER_PLUGIN_DEBUG + void debugInformation(const Ultracopier::DebugLevel &level,const std::string &fonction,const std::string &text,const std::string &file,const int &ligne) const; + #endif + #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW + void updateTheDebugInfo(const std::vector &,const std::vector&,const int &) const; + #endif + + //other signal + /// \note Can be call without queue because all call will be serialized + void send_fileAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame,TransferThread * thread) const; + /// \note Can be call without queue because all call will be serialized + void send_errorOnFile(const QFileInfo &fileInfo,const std::string &errorString,TransferThread * thread, const ErrorType &errorType) const; + /// \note Can be call without queue because all call will be serialized + void send_folderAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame,ScanFileOrFolder * thread) const; + /// \note Can be call without queue because all call will be serialized + void send_errorOnFolder(const QFileInfo &fileInfo,const std::string &errorString,ScanFileOrFolder * thread, const ErrorType &errorType) const; + //send the progression + void send_syncTransferList() const; + //mkpath error event + void mkPathErrorOnFolder(const QFileInfo &fileInfo,const std::string &errorString,const ErrorType &errorType) const; + //to close + void tryCancel() const; + //to ask new transfer thread + void askNewTransferThread() const; + + void warningTransferList(const std::string &warning) const; + void errorTransferList(const std::string &error) const; + void send_sendNewRenamingRules(const std::string &firstRenamingRule,const std::string &otherRenamingRule) const; + void send_realBytesTransfered(const uint64_t &) const; + + void send_setTransferAlgorithm(TransferAlgorithm transferAlgorithm) const; + void send_parallelBuffer(const int ¶llelBuffer) const; + void send_sequentialBuffer(const int &sequentialBuffer) const; + void send_parallelizeIfSmallerThan(const int ¶llelizeIfSmallerThan) const; + void send_updateMount(); + void missingDiskSpace(std::vector list) const; +}; + +#endif // LISTTHREAD_H diff --git a/plugins/CopyEngine/Ultracopier/ListThread_InodeAction.cpp b/plugins/CopyEngine/Ultracopier/ListThread_InodeAction.cpp new file mode 100644 index 0000000..12421f2 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/ListThread_InodeAction.cpp @@ -0,0 +1,64 @@ +/** \file ListThread_InodeAction.cpp +\brief To be included into ListThread.cpp, to optimize and prevent code duplication +\see ListThread.cpp */ + +#ifdef LISTTHREAD_H + +//do the inode action +ActionToDoInode& currentActionToDoInode=actionToDoListInode[int_for_internal_loop]; +switch(currentActionToDoInode.type) +{ + case ActionType_RealMove: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("launch real move, source: %1, destination: %2").arg(currentActionToDoInode.source.absoluteFilePath()).arg(currentActionToDoInode.destination.absoluteFilePath()).toStdString()); + mkPathQueue.addPath(currentActionToDoInode.source.absoluteFilePath(),currentActionToDoInode.destination.absoluteFilePath(),currentActionToDoInode.type); + currentActionToDoInode.isRunning=true; + numberOfInodeOperation++; + if(numberOfInodeOperation>=inodeThreads) + return; + break; + case ActionType_MkPath: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("launch mkpath, source: %1, destination: %2").arg(currentActionToDoInode.source.absoluteFilePath()).arg(currentActionToDoInode.destination.absoluteFilePath()).toStdString()); + mkPathQueue.addPath(currentActionToDoInode.source.absoluteFilePath(),currentActionToDoInode.destination.absoluteFilePath(),currentActionToDoInode.type); + currentActionToDoInode.isRunning=true; + numberOfInodeOperation++; + if(numberOfInodeOperation>=inodeThreads) + return; + break; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + case ActionType_RmSync: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QString("launch rmsync, destination: %1").arg(currentActionToDoInode.destination.absoluteFilePath()).toStdString()); + mkPathQueue.addPath(currentActionToDoInode.destination.absoluteFilePath(),currentActionToDoInode.destination.absoluteFilePath(),currentActionToDoInode.type); + currentActionToDoInode.isRunning=true; + numberOfInodeOperation++; + if(numberOfInodeOperation>=inodeThreads) + return; + break; + #endif + case ActionType_MovePath: + //then empty (no file), can try remove it + if(currentActionToDoInode.size==0 || actionToDoListTransfer.empty())//don't put afterTheTransfer because actionToDoListInode_afterTheTransfer -> already afterTheTransfer + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("launch rmpath: %1").arg(currentActionToDoInode.source.absoluteFilePath()).toStdString()); + mkPathQueue.addPath(currentActionToDoInode.source.absoluteFilePath(),currentActionToDoInode.destination.absoluteFilePath(),currentActionToDoInode.type); + currentActionToDoInode.isRunning=true; + numberOfInodeOperation++; + if(numberOfInodeOperation>=inodeThreads) + return; + } + else //have do the destination, put the remove to after + { + currentActionToDoInode.size=0; + actionToDoListInode_afterTheTransfer.push_back(currentActionToDoInode); + actionToDoListInode.erase(actionToDoListInode.cbegin()+int_for_internal_loop); + int_for_internal_loop--; + actionToDoListInode_count--; + if(numberOfInodeOperation>=inodeThreads) + return; + } + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Wrong type at inode action"); + return; +} + +#endif diff --git a/plugins/CopyEngine/Ultracopier/MkPath.cpp b/plugins/CopyEngine/Ultracopier/MkPath.cpp new file mode 100644 index 0000000..52d67af --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/MkPath.cpp @@ -0,0 +1,517 @@ +#include "MkPath.h" + +#ifdef Q_OS_WIN32 + #ifndef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include + #endif +#endif + +std::string MkPath::text_slash="/"; + +MkPath::MkPath() +{ + stopIt=false; + waitAction=false; + doRightTransfer=false; + maxTime=QDateTime(QDate(ULTRACOPIER_PLUGIN_MINIMALYEAR,1,1)); + setObjectName("MkPath"); + moveToThread(this); + start(); + #ifdef Q_OS_WIN32 + #ifndef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + regRead=std::regex("^[a-z]:"); + #endif + #endif +} + +MkPath::~MkPath() +{ + stopIt=true; + quit(); + wait(); +} + +void MkPath::addPath(const QFileInfo& source, const QFileInfo& destination, const ActionType &actionType) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + if(stopIt) + return; + emit internalStartAddPath(source,destination,actionType); +} + +void MkPath::skip() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + emit internalStartSkip(); +} + +void MkPath::retry() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + emit internalStartRetry(); +} + +void MkPath::run() +{ + connect(this,&MkPath::internalStartAddPath, this,&MkPath::internalAddPath,Qt::QueuedConnection); + connect(this,&MkPath::internalStartDoThisPath, this,&MkPath::internalDoThisPath,Qt::QueuedConnection); + connect(this,&MkPath::internalStartSkip, this,&MkPath::internalSkip,Qt::QueuedConnection); + connect(this,&MkPath::internalStartRetry, this,&MkPath::internalRetry,Qt::QueuedConnection); + exec(); +} + +void MkPath::internalDoThisPath() +{ + if(waitAction || pathList.isEmpty()) + return; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2, move: %3").arg(pathList.first().source.absoluteFilePath()).arg(pathList.first().destination.absoluteFilePath()).arg(pathList.first().actionType).toStdString()); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + if(pathList.first().actionType==ActionType_RmSync) + { + if(pathList.first().destination.isFile()) + { + QFile removedFile(pathList.first().destination.absoluteFilePath()); + if(!removedFile.remove()) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to remove the inode: "+pathList.first().destination.absoluteFilePath().toStdString()+", error: "+removedFile.errorString().toStdString()); + emit errorOnFolder(pathList.first().destination,removedFile.errorString().toStdString()); + return; + } + } + else if(!rmpath(pathList.first().destination.absoluteFilePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to remove the inode: "+pathList.first().destination.absoluteFilePath().toStdString()); + emit errorOnFolder(pathList.first().destination,tr("Unable to remove").toStdString()); + return; + } + pathList.removeFirst(); + emit firstFolderFinish(); + checkIfCanDoTheNext(); + return; + } + #endif + doTheDateTransfer=false; + if(keepDate) + { + if(!pathList.first().source.exists()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"the sources not exists: "+pathList.first().source.absoluteFilePath().toStdString()); + doTheDateTransfer=false; + } + else if(maxTime>=pathList.first().source.lastModified()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"the sources is older to copy the time: "+pathList.first().source.absoluteFilePath().toStdString()+": "+maxTime.toString("dd.MM.yyyy hh:mm:ss.zzz").toStdString()+">="+pathList.first().source.lastModified().toString("dd.MM.yyyy hh:mm:ss.zzz").toStdString()); + doTheDateTransfer=false; + } + else + { + doTheDateTransfer=readFileDateTime(pathList.first().source); + /*if(!doTheDateTransfer) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get source folder time: "+pathList.first().source.absoluteFilePath()); + emit errorOnFolder(pathList.first().source,tr("Unable to get time")); + return; + }*/ + } + } + if(dir.exists(pathList.first().destination.absoluteFilePath()) && pathList.first().actionType==ActionType_RealMove) + pathList.first().actionType=ActionType_MovePath; + if(pathList.first().actionType!=ActionType_RealMove) + { + if(!dir.exists(pathList.first().destination.absoluteFilePath())) + if(!dir.mkpath(pathList.first().destination.absoluteFilePath())) + { + if(!dir.exists(pathList.first().destination.absoluteFilePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to make the folder: "+pathList.first().destination.absoluteFilePath().toStdString()); + emit errorOnFolder(pathList.first().destination,tr("Unable to create the folder").toStdString()); + return; + } + } + } + else + { + if(!pathList.first().source.exists()) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The source folder don't exists: "+pathList.first().source.absoluteFilePath().toStdString()); + emit errorOnFolder(pathList.first().destination,tr("The source folder don't exists").toStdString()); + return; + } + if(!pathList.first().source.isDir())//it's really an error? + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The source is not a folder: "+pathList.first().source.absoluteFilePath().toStdString()); + /*if(stopIt) + return; + waitAction=true; + emit errorOnFolder(pathList.first().destination,tr("The source is not a folder")); + return;*/ + } + if(pathList.first().destination.absoluteFilePath().startsWith(pathList.first().source.absoluteFilePath()+QString::fromStdString(text_slash))) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"move into it self: "+pathList.first().destination.absoluteFilePath().toStdString()); + int random=rand(); + QFileInfo tempFolder=pathList.first().source.absolutePath()+QString::fromStdString(text_slash)+QString::number(random); + while(tempFolder.exists()) + { + random=rand(); + tempFolder=pathList.first().source.absolutePath()+QString::fromStdString(text_slash)+QString::number(random); + } + if(!dir.rename(pathList.first().source.absoluteFilePath(),tempFolder.absoluteFilePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to temporary rename the folder: "+pathList.first().destination.absoluteFilePath().toStdString()); + emit errorOnFolder(pathList.first().destination,tr("Unable to temporary rename the folder").toStdString()); + return; + } + /* http://doc.qt.io/qt-5/qdir.html#rename + * On most file systems, rename() fails only if oldName does not exist, or if a file with the new name already exists. + if(!dir.mkpath(pathList.first().destination.absolutePath())) + { + if(!dir.exists(pathList.first().destination.absolutePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to make the folder: "+pathList.first().destination.absoluteFilePath()); + emit errorOnFolder(pathList.first().destination,tr("Unable to create the folder")); + return; + } + }*/ + if(!dir.rename(tempFolder.absoluteFilePath(),pathList.first().destination.absoluteFilePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to do the final real move the folder: "+pathList.first().destination.absoluteFilePath().toStdString()); + emit errorOnFolder(pathList.first().destination,tr("Unable to do the final real move the folder").toStdString()); + return; + } + } + else + { + /* http://doc.qt.io/qt-5/qdir.html#rename + * On most file systems, rename() fails only if oldName does not exist, or if a file with the new name already exists. + if(!dir.mkpath(pathList.first().destination.absolutePath())) + { + if(!dir.exists(pathList.first().destination.absolutePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to make the folder: "+pathList.first().destination.absoluteFilePath()); + emit errorOnFolder(pathList.first().destination,tr("Unable to create the folder")); + return; + } + }*/ + if(!dir.rename(pathList.first().source.absoluteFilePath(),pathList.first().destination.absoluteFilePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to make the folder: from: "+pathList.first().source.absoluteFilePath().toStdString()+", soruce exists: "+std::to_string(QDir(pathList.first().source.absoluteFilePath()).exists())+", to: "+pathList.first().destination.absoluteFilePath().toStdString() + +", destination exist: "+std::to_string(QDir(pathList.first().destination.absoluteFilePath()).exists())); + emit errorOnFolder(pathList.first().destination,tr("Unable to move the folder").toStdString()); + return; + } + } + } + if(doTheDateTransfer) + if(!writeFileDateTime(pathList.first().destination)) + { + if(!pathList.first().destination.exists()) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to set destination folder time (not exists): "+pathList.first().destination.absoluteFilePath().toStdString()); + else if(!pathList.first().destination.isDir()) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to set destination folder time (not a dir): "+pathList.first().destination.absoluteFilePath().toStdString()); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to set destination folder time: "+pathList.first().destination.absoluteFilePath().toStdString()); + /*if(stopIt) + return; + waitAction=true; + + emit errorOnFolder(pathList.first().source,tr("Unable to set time")); + return;*/ + } + if(doRightTransfer && pathList.first().actionType!=ActionType_RealMove) + { + QFile source(pathList.first().source.absoluteFilePath()); + QFile destination(pathList.first().destination.absoluteFilePath()); + if(!destination.setPermissions(source.permissions())) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to set the right: "+pathList.first().destination.absoluteFilePath().toStdString()); + /*if(stopIt) + return; + waitAction=true; + emit errorOnFolder(pathList.first().source,tr("Unable to set the access-right")); + return;*/ + } + } + if(pathList.first().actionType==ActionType_MovePath) + { + if(!rmpath(pathList.first().source.absoluteFilePath())) + { + if(stopIt) + return; + waitAction=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to remove the source folder: "+pathList.first().destination.absoluteFilePath().toStdString()); + emit errorOnFolder(pathList.first().source,tr("Unable to remove").toStdString()); + return; + } + } + pathList.removeFirst(); + emit firstFolderFinish(); + checkIfCanDoTheNext(); +} + +void MkPath::internalAddPath(const QFileInfo& source, const QFileInfo& destination, const ActionType &actionType) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("source: %1, destination: %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + Item tempPath; + tempPath.source=source; + tempPath.destination=destination; + tempPath.actionType=actionType; + pathList << tempPath; + if(!waitAction) + checkIfCanDoTheNext(); +} + +void MkPath::checkIfCanDoTheNext() +{ + if(!waitAction && !stopIt && pathList.size()>0) + emit internalStartDoThisPath(); +} + +void MkPath::internalSkip() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + waitAction=false; + pathList.removeFirst(); + emit firstFolderFinish(); + checkIfCanDoTheNext(); +} + +void MkPath::internalRetry() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + waitAction=false; + checkIfCanDoTheNext(); +} + +void MkPath::setRightTransfer(const bool doRightTransfer) +{ + this->doRightTransfer=doRightTransfer; +} + +void MkPath::setKeepDate(const bool keepDate) +{ + this->keepDate=keepDate; +} + +bool MkPath::rmpath(const QDir &dir + #ifdef ULTRACOPIER_PLUGIN_RSYNC + ,const bool &toSync + #endif + ) +{ + if(!dir.exists()) + return true; + bool allHaveWork=true; + QFileInfoList list = dir.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden|QDir::System,QDir::DirsFirst); + for (int i = 0; i < list.size(); ++i) + { + QFileInfo fileInfo(list.at(i)); + if(!fileInfo.isDir()) + { + #ifdef ULTRACOPIER_PLUGIN_RSYNC + if(toSync) + { + QFile file(fileInfo.absoluteFilePath()); + if(!file.remove()) + { + if(toSync) + { + QFile file(fileInfo.absoluteFilePath()); + if(!file.remove()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to remove a file: "+fileInfo.absoluteFilePath().toStdString()+", due to: "+file.errorString().toStdString()); + allHaveWork=false; + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"found a file: "+fileInfo.fileName().toStdString()); + allHaveWork=false; + } + } + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"found a file: "+fileInfo.fileName().toStdString()); + allHaveWork=false; + } + #else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"found a file: "+fileInfo.fileName().toStdString()); + allHaveWork=false; + #endif + } + else + { + //return the fonction for scan the new folder + if(!rmpath(dir.absolutePath()+'/'+fileInfo.fileName()+'/')) + allHaveWork=false; + } + } + if(!allHaveWork) + return false; + allHaveWork=dir.rmdir(dir.absolutePath()); + if(!allHaveWork) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to remove the folder: "+dir.absolutePath().toStdString()); + return allHaveWork; +} + +//fonction to edit the file date time +bool MkPath::readFileDateTime(const QFileInfo &source) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"readFileDateTime("+source.absoluteFilePath().toStdString()+")"); + /** Why not do it with Qt? Because it not support setModificationTime(), and get the time with Qt, that's mean use local time where in C is UTC time */ + #ifdef Q_OS_UNIX + #ifdef Q_OS_LINUX + struct stat info; + if(stat(source.absoluteFilePath().toLatin1().data(),&info)!=0) + return false; + time_t ctime=info.st_ctim.tv_sec; + time_t actime=info.st_atim.tv_sec; + time_t modtime=info.st_mtim.tv_sec; + //this function avalaible on unix and mingw + butime.actime=actime; + butime.modtime=modtime; + Q_UNUSED(ctime); + return true; + #else //mainly for mac + QFileInfo fileInfo(source); + time_t ctime=fileInfo.created().toTime_t(); + time_t actime=fileInfo.lastRead().toTime_t(); + time_t modtime=fileInfo.lastModified().toTime_t(); + //this function avalaible on unix and mingw + utimbuf butime; + butime.actime=actime; + butime.modtime=modtime; + Q_UNUSED(ctime); + return true; + #endif + #else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + struct stat info; + if(stat(source.toLatin1().data(),&info)!=0) + return false; + time_t ctime=info.st_ctim.tv_sec; + time_t actime=info.st_atim.tv_sec; + time_t modtime=info.st_mtim.tv_sec; + //this function avalaible on unix and mingw + butime.actime=actime; + butime.modtime=modtime; + Q_UNUSED(ctime); + return true; + #else + wchar_t filePath[65535]; + if(std::regex_match(source.absoluteFilePath().toStdString(),regRead)) + filePath[QDir::toNativeSeparators(QStringLiteral("\\\\?\\")+source.absoluteFilePath()).toWCharArray(filePath)]=L'\0'; + else + filePath[QDir::toNativeSeparators(source.absoluteFilePath()).toWCharArray(filePath)]=L'\0'; + HANDLE hFileSouce = CreateFileW(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_BACKUP_SEMANTICS, NULL); + if(hFileSouce == INVALID_HANDLE_VALUE) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"open failed to read: "+QString::fromWCharArray(filePath).toStdString()+", error: "+std::to_string(GetLastError())); + return false; + } + FILETIME ftCreate, ftAccess, ftWrite; + if(!GetFileTime(hFileSouce, &ftCreate, &ftAccess, &ftWrite)) + { + CloseHandle(hFileSouce); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to get the file time"); + return false; + } + this->ftCreateL=ftCreate.dwLowDateTime; + this->ftCreateH=ftCreate.dwHighDateTime; + this->ftAccessL=ftAccess.dwLowDateTime; + this->ftAccessH=ftAccess.dwHighDateTime; + this->ftWriteL=ftWrite.dwLowDateTime; + this->ftWriteH=ftWrite.dwHighDateTime; + CloseHandle(hFileSouce); + return true; + #endif + #else + return false; + #endif + #endif + return false; +} + +bool MkPath::writeFileDateTime(const QFileInfo &destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"writeFileDateTime("+destination.absoluteFilePath().toStdString()+")"); + /** Why not do it with Qt? Because it not support setModificationTime(), and get the time with Qt, that's mean use local time where in C is UTC time */ + #ifdef Q_OS_UNIX + #ifdef Q_OS_LINUX + return utime(destination.absoluteFilePath().toLatin1().data(),&butime)==0; + #else //mainly for mac + return utime(destination.absoluteFilePath().toLatin1().data(),&butime)==0; + #endif + #else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + return utime(destination.toLatin1().data(),&butime)==0; + #else + wchar_t filePath[65535]; + if(std::regex_match(destination.absoluteFilePath().toStdString(),regRead)) + filePath[QDir::toNativeSeparators(QStringLiteral("\\\\?\\")+destination.absoluteFilePath()).toWCharArray(filePath)]=L'\0'; + else + filePath[QDir::toNativeSeparators(destination.absoluteFilePath()).toWCharArray(filePath)]=L'\0'; + HANDLE hFileDestination = CreateFileW(filePath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if(hFileDestination == INVALID_HANDLE_VALUE) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"open failed to write: "+QString::fromWCharArray(filePath).toStdString()+", error: "+std::to_string(GetLastError())); + return false; + } + FILETIME ftCreate, ftAccess, ftWrite; + ftCreate.dwLowDateTime=this->ftCreateL; + ftCreate.dwHighDateTime=this->ftCreateH; + ftAccess.dwLowDateTime=this->ftAccessL; + ftAccess.dwHighDateTime=this->ftAccessH; + ftWrite.dwLowDateTime=this->ftWriteL; + ftWrite.dwHighDateTime=this->ftWriteH; + if(!SetFileTime(hFileDestination, &ftCreate, &ftAccess, &ftWrite)) + { + CloseHandle(hFileDestination); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to set the file time"); + return false; + } + CloseHandle(hFileDestination); + return true; + #endif + #else + return false; + #endif + #endif + return false; +} diff --git a/plugins/CopyEngine/Ultracopier/MkPath.h b/plugins/CopyEngine/Ultracopier/MkPath.h new file mode 100644 index 0000000..2bbebcc --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/MkPath.h @@ -0,0 +1,106 @@ +/** \file MkPath.h +\brief Make the path given as queued mkpath +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef MKPATH_H +#define MKPATH_H + +#include +#include +#include +#include +#include +#include +#include + +#include "Environment.h" + +#ifdef Q_OS_UNIX + #include + #include + #include + #include +#else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + #include + #include + #include + #include + #endif + #endif +#endif + +/// \brief Make the path given as queued mkpath +class MkPath : public QThread +{ + Q_OBJECT +public: + explicit MkPath(); + ~MkPath(); + /// \brief add path to make + void addPath(const QFileInfo& source,const QFileInfo& destination,const ActionType &actionType); + void setRightTransfer(const bool doRightTransfer); + void setKeepDate(const bool keepDate); +signals: + void errorOnFolder(const QFileInfo &,const std::string &,const ErrorType &errorType=ErrorType_FolderWithRety) const; + void firstFolderFinish(); + void internalStartAddPath(const QFileInfo& source,const QFileInfo& destination, const ActionType &actionType) const; + void internalStartDoThisPath() const; + void internalStartSkip() const; + void internalStartRetry() const; + void debugInformation(const Ultracopier::DebugLevel &level,const std::string &fonction,const std::string &text,const std::string &file,const int &ligne) const; +public slots: + /// \brief skip after creation error + void skip(); + /// \brief retry after creation error + void retry(); +private: + void run(); + bool waitAction; + bool stopIt; + bool skipIt; + QDateTime maxTime; + struct Item + { + QFileInfo source; + QFileInfo destination; + ActionType actionType; + }; + QList pathList; + void checkIfCanDoTheNext(); + QDir dir; + bool doRightTransfer; + bool keepDate; + bool doTheDateTransfer; + #ifdef Q_OS_UNIX + utimbuf butime; + #else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + utimbuf butime; + #else + uint64_t ftCreateL, ftAccessL, ftWriteL; + uint64_t ftCreateH, ftAccessH, ftWriteH; + std::regex regRead; + #endif + #endif + #endif + //fonction to edit the file date time + bool readFileDateTime(const QFileInfo &source); + bool writeFileDateTime(const QFileInfo &destination); + static std::string text_slash; +private slots: + void internalDoThisPath(); + void internalAddPath(const QFileInfo& source, const QFileInfo& destination,const ActionType &actionType); + void internalSkip(); + void internalRetry(); + bool rmpath(const QDir &dir + #ifdef ULTRACOPIER_PLUGIN_RSYNC + , const bool &toSync=false + #endif + ); +}; + +#endif // MKPATH_H diff --git a/plugins/CopyEngine/Ultracopier/ReadThread.cpp b/plugins/CopyEngine/Ultracopier/ReadThread.cpp new file mode 100644 index 0000000..e843d9b --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/ReadThread.cpp @@ -0,0 +1,687 @@ +#include "ReadThread.h" + +ReadThread::ReadThread() +{ + start(); + moveToThread(this); + stopIt=false; + putInPause=false; + blockSize=ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*1024; + setObjectName(QStringLiteral("read")); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + isInReadLoop=false; + tryStartRead=false; + lastGoodPosition=0; + isOpen.release(); +} + +ReadThread::~ReadThread() +{ + stopIt=true; + //disconnect(this);//-> do into ~TransferThread() + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + waitNewClockForSpeed.release(); + #endif + pauseMutex.release(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + waitNewClockForSpeed.release(); + #endif + pauseMutex.release(); + //if(isOpen.available()<=0) + emit internalStartClose(); + isOpen.acquire(); + exit(); + wait(); +} + +void ReadThread::run() +{ + connect(this,&ReadThread::internalStartOpen, this,&ReadThread::internalOpenSlot, Qt::QueuedConnection); + connect(this,&ReadThread::internalStartReopen, this,&ReadThread::internalReopen, Qt::QueuedConnection); + connect(this,&ReadThread::internalStartRead, this,&ReadThread::internalRead, Qt::QueuedConnection); + connect(this,&ReadThread::internalStartClose, this,&ReadThread::internalCloseSlot, Qt::QueuedConnection); + connect(this,&ReadThread::checkIfIsWait, this,&ReadThread::isInWait, Qt::QueuedConnection); + connect(this,&ReadThread::internalStartChecksum, this,&ReadThread::checkSum, Qt::QueuedConnection); + exec(); +} + +void ReadThread::open(const QFileInfo &file, const Ultracopier::CopyMode &mode) +{ + if(!isRunning()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] the thread not running to open destination: "+file.absoluteFilePath().toStdString()); + errorString_internal=tr("Internal error, please report it!").toStdString(); + emit error(); + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] open source: "+file.absoluteFilePath().toStdString()); + if(this->file.isOpen()) + { + if(file.absoluteFilePath()==this->file.fileName()) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Try reopen already opened same file: "+file.absoluteFilePath().toStdString()); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] previous file is already open: "+file.absoluteFilePath().toStdString()); + emit internalStartClose(); + isOpen.acquire(); + isOpen.release(); + } + if(isInReadLoop) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] previous file is already readding: "+file.absoluteFilePath().toStdString()); + return; + } + if(tryStartRead) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] previous file is already try read: "+file.absoluteFilePath().toStdString()); + return; + } + stopIt=false; + fakeMode=false; + lastGoodPosition=0; + this->file.setFileName(file.absoluteFilePath()); + this->mode=mode; + emit internalStartOpen(); +} + +std::string ReadThread::errorString() const +{ + return errorString_internal; +} + +void ReadThread::stop() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stop()"); + stopIt=true; + pauseMutex.release(); + pauseMutex.release(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + waitNewClockForSpeed.release(); + #endif + if(isOpen.available()<=0) + emit internalStartClose(); +} + +void ReadThread::pause() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] try put read thread in pause"); + if(stopIt) + return; + pauseMutex.tryAcquire(pauseMutex.available()); + putInPause=true; +} + +void ReadThread::resume() +{ + if(putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + putInPause=false; + stopIt=false; + } + else + return; + if(!file.isOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] file is not open"); + return; + } + pauseMutex.release(); +} + +bool ReadThread::seek(const int64_t &position) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start with: "+std::to_string(position)); + if(position>file.size()) + return false; + return file.seek(position); +} + +int64_t ReadThread::size() const +{ + return file.size(); +} + +void ReadThread::postOperation() +{ + emit internalStartClose(); +} + +void ReadThread::checkSum() +{ + QByteArray blockArray; + QCryptographicHash hash(QCryptographicHash::Sha1); + isInReadLoop=true; + lastGoodPosition=0; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + numberOfBlockCopied=0; + #endif + seek(0); + int sizeReaden=0; + do + { + //read one block + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Read; + #endif + if(putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"["+std::to_string(id)+"] read put in pause"); + if(stopIt) + return; + pauseMutex.acquire(); + if(stopIt) + return; + } + blockArray=file.read(blockSize); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + //can be smaller than min block size to do correct speed limitation + if(blockArray.size()>ULTRACOPIER_PLUGIN_MAX_BLOCK_SIZE*1024) + { + errorString_internal=tr("Internal error reading the source file:block size out of range").toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Internal error reading the source file:block size out of range"); + emit error(); + isInReadLoop=false; + return; + } + if(file.error()!=QFile::NoError) + { + errorString_internal=tr("Unable to read the source file: ").toStdString()+file.errorString().toStdString()+" ("+std::to_string(file.error())+")"; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("file.error()!=QFile::NoError: %1, error: ").arg(QString::number(file.error())).toStdString()+errorString_internal); + emit error(); + isInReadLoop=false; + return; + } + sizeReaden=blockArray.size(); + if(sizeReaden>0) + { + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Checksum; + #endif + hash.addData(blockArray); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(stopIt) + break; + + lastGoodPosition+=blockArray.size(); + + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + //wait for limitation speed if stop not query + if(multiForBigSpeed>0) + { + numberOfBlockCopied++; + if(numberOfBlockCopied>=multiForBigSpeed) + { + numberOfBlockCopied=0; + waitNewClockForSpeed.acquire(); + if(stopIt) + break; + } + } + #endif + } + } + while(sizeReaden>0 && !stopIt); + if(lastGoodPosition>file.size()) + { + errorString_internal=tr("File truncated during the read, possible data change").toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Source truncated during the read: %1 (%2)").arg(file.errorString()).arg(QString::number(file.error())).toStdString()); + emit error(); + isInReadLoop=false; + return; + } + isInReadLoop=false; + if(stopIt) + { + stopIt=false; + return; + } + emit checksumFinish(hash.result()); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stop the read"); +} + +bool ReadThread::internalOpenSlot() +{ + return internalOpen(); +} + +bool ReadThread::internalOpen(bool resetLastGoodPosition) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] internalOpen source: "+file.fileName().toStdString()+", open in write because move: "+std::to_string(mode==Ultracopier::Move)); + if(stopIt) + { + emit closed(); + return false; + } + putInPause=false; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=InodeOperation; + #endif + if(file.isOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] this file is already open: "+file.fileName().toStdString()); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + emit closed(); + return false; + } + QIODevice::OpenMode openMode=QIODevice::ReadOnly; + /*can have permision to remove but not write + * if(mode==Ultracopier::Move) + openMode=QIODevice::ReadWrite;*/ + seekToZero=false; + if(file.open(openMode)) + { + if(stopIt) + { + file.close(); + emit closed(); + return false; + } + pauseMutex.tryAcquire(pauseMutex.available()); + if(stopIt) + { + file.close(); + emit closed(); + return false; + } + size_at_open=file.size(); + mtime_at_open=QFileInfo(file).lastModified().toMSecsSinceEpoch()/1000; + putInPause=false; + if(resetLastGoodPosition) + lastGoodPosition=0; + if(!seek(lastGoodPosition)) + { + file.close(); + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to seek after open: %1, error: %2").arg(file.fileName()).toStdString()+errorString_internal); + emit error(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + return false; + } + isOpen.acquire(); + emit opened(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + return true; + } + else + { + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to open: %1, error: ").arg(file.fileName()).toStdString()+errorString_internal); + emit error(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + return false; + } +} + +void ReadThread::internalRead() +{ + isInReadLoop=true; + tryStartRead=false; + if(stopIt) + { + if(seekToZero && file.isOpen()) + { + stopIt=false; + lastGoodPosition=0; + file.seek(0); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopIt == true, then quit"); + isInReadLoop=false; + internalClose(); + return; + } + } + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=InodeOperation; + #endif + int sizeReaden=0; + if(!file.isOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] is not open!"); + isInReadLoop=false; + return; + } + QByteArray blockArray; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + numberOfBlockCopied=0; + #endif + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start the copy"); + emit readIsStarted(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopIt == true, then quit"); + isInReadLoop=false; + internalClose(); + return; + } + do + { + //read one block + if(putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"["+std::to_string(id)+"] read put in pause"); + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopIt == true, then quit"); + isInReadLoop=false; + internalClose(); + return; + } + pauseMutex.acquire(); + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopIt == true, then quit"); + isInReadLoop=false; + internalClose(); + return; + } + } + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Read; + #endif + blockArray=file.read(blockSize); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(file.error()!=QFile::NoError) + { + errorString_internal=tr("Unable to read the source file: ").toStdString()+file.errorString().toStdString()+" ("+std::to_string(file.error())+")"; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("file.error()!=QFile::NoError: %1, error: ").arg(QString::number(file.error())).toStdString()+errorString_internal); + isInReadLoop=false; + emit error(); + return; + } + sizeReaden=blockArray.size(); + if(sizeReaden>0) + { + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=WaitWritePipe; + #endif + if(!writeThread->write(blockArray))//speed limitation here + { + if(!stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopped because the write is stopped: "+std::to_string(lastGoodPosition)); + stopIt=true; + } + } + + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopIt == true, then quit"); + isInReadLoop=false; + internalClose();//need re-open the destination and then the source + return; + } + lastGoodPosition+=blockArray.size(); + } + /* + if(lastGoodPosition>16*1024) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Test error in reading: %1 (%2)").arg(file.errorString()).arg(file.error())); + errorString_internal=QStringLiteral("Test error in reading: %1 (%2)").arg(file.errorString()).arg(file.error()); + isInReadLoop=false; + emit error(); + return; + } + */ + } + while(sizeReaden>0 && !stopIt); + if(lastGoodPosition>file.size()) + { + errorString_internal=tr("File truncated during the read, possible data change").toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Source truncated during the read: %1 (%2)").arg(file.errorString()).arg(QString::number(file.error())).toStdString()); + isInReadLoop=false; + emit error(); + return; + } + isInReadLoop=false; + if(stopIt) + { + stopIt=false; + return; + } + emit readIsStopped();//will product by signal connection writeThread->endIsDetected(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stop the read"); +} + +void ReadThread::startRead() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + if(tryStartRead) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] already in try start"); + return; + } + if(isInReadLoop) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + else + { + tryStartRead=true; + emit internalStartRead(); + } +} + +void ReadThread::internalCloseSlot() +{ + internalClose(); +} + +void ReadThread::internalClose(bool callByTheDestructor) +{ + /// \note never send signal here, because it's called by the destructor + //ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] start")); + bool closeTheFile=false; + if(!fakeMode) + { + if(file.isOpen()) + { + closeTheFile=true; + file.close(); + isInReadLoop=false; + } + } + if(!callByTheDestructor) + emit closed(); + + /// \note always the last of this function + if(closeTheFile) + isOpen.release(); +} + +/** \brief set block size +\param block the new block size in B +\return Return true if succes */ +bool ReadThread::setBlockSize(const int blockSize) +{ + //can be smaller than min block size to do correct speed limitation + if(blockSize>1 && blockSizeblockSize=blockSize; + //set the new max speed because the timer have changed + return true; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"block size out of range: "+std::to_string(blockSize)); + return false; + } +} + +#ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT +/*! \brief Set the max speed +\param tempMaxSpeed Set the max speed in KB/s, 0 for no limit */ +void ReadThread::setMultiForBigSpeed(const int &multiForBigSpeed) +{ + this->multiForBigSpeed=multiForBigSpeed; + waitNewClockForSpeed.release(); +} + +/// \brief For give timer every X ms +void ReadThread::timeOfTheBlockCopyFinished() +{ + /* this is the old way to limit the speed, it product blocking + *if(waitNewClockForSpeed.available()maxSpeed>0)*/ + if(waitNewClockForSpeed.available()<=1) + waitNewClockForSpeed.release(); +} +#endif + +/// \brief do the fake open +void ReadThread::fakeOpen() +{ + fakeMode=true; + emit opened(); +} + +/// \brief do the fake writeIsStarted +void ReadThread::fakeReadIsStarted() +{ + emit readIsStarted(); +} + +/// \brief do the fake writeIsStopped +void ReadThread::fakeReadIsStopped() +{ + emit readIsStopped(); +} + +/// do the checksum +void ReadThread::startCheckSum() +{ + emit internalStartChecksum(); +} + +int64_t ReadThread::getLastGoodPosition() const +{ + /*if(lastGoodPosition>file.size()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,QStringLiteral("[")+QString::number(id)+QStringLiteral("] Bug, the lastGoodPosition is greater than the file size!")); + return file.size(); + } + else*/ + return lastGoodPosition; +} + +//reopen after an error +void ReadThread::reopen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + if(isInReadLoop) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] try reopen where read is not finish"); + return; + } + stopIt=true; + emit internalStartReopen(); +} + +bool ReadThread::internalReopen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + stopIt=false; + if(file.isOpen()) + { + file.close(); + isOpen.release(); + } + if(size_at_open!=file.size() && mtime_at_open!=(uint64_t)QFileInfo(file).lastModified().toMSecsSinceEpoch()/1000) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] source file have changed since the last open, restart all"); + //fix this function like the close function + if(internalOpen(true)) + { + emit resumeAfterErrorByRestartAll(); + return true; + } + else + return false; + } + else + { + //fix this function like the close function + if(internalOpen(false)) + { + emit resumeAfterErrorByRestartAtTheLastPosition(); + return true; + } + else + return false; + } +} + +//set the write thread +void ReadThread::setWriteThread(WriteThread * writeThread) +{ + this->writeThread=writeThread; +} + +#ifdef ULTRACOPIER_PLUGIN_DEBUG +//to set the id +void ReadThread::setId(int id) +{ + this->id=id; +} +#endif + +void ReadThread::seekToZeroAndWait() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + stopIt=true; + seekToZero=true; + emit checkIfIsWait(); +} + +void ReadThread::isInWait() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + if(seekToZero) + { + stopIt=false; + seekToZero=false; + if(file.isOpen()) + { + lastGoodPosition=0; + seek(0); + } + else + internalOpen(true); + emit isSeekToZeroAndWait(); + } +} + +bool ReadThread::isReading() const +{ + return isInReadLoop; +} + diff --git a/plugins/CopyEngine/Ultracopier/ReadThread.h b/plugins/CopyEngine/Ultracopier/ReadThread.h new file mode 100644 index 0000000..f817e35 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/ReadThread.h @@ -0,0 +1,147 @@ +/** \file ReadThread.h +\brief Thread changed to open/close and read the source file +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef READTHREAD_H +#define READTHREAD_H + +#include +#include +#include +#include +#include +#include + +#include "WriteThread.h" +#include "Environment.h" +#include "StructEnumDefinition_CopyEngine.h" +#include "AvancedQFile.h" + +/// \brief Thread changed to open/close and read the source file +class ReadThread : public QThread +{ + Q_OBJECT +public: + explicit ReadThread(); + ~ReadThread(); +protected: + void run(); +public: + /// \brief open with the name and copy mode + void open(const QFileInfo &file, const Ultracopier::CopyMode &mode); + /// \brief return the error string + std::string errorString() const; + //QByteArray read(qint64 position,qint64 maxSize); + /// \brief stop the copy + void stop(); + /// \brief put the copy in pause + void pause(); + /// \brief resume the copy + void resume(); + /// \brief get the size of the source file + int64_t size() const; + /// \brief get the last good position + int64_t getLastGoodPosition() const; + /// \brief start the reading of the source file + void startRead(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + /// \brief set the current max speed in KB/s + void setMultiForBigSpeed(const int &multiForBigSpeed); + #endif + /// \brief set block size in KB + bool setBlockSize(const int blockSize); + /// \brief reopen after an error + void reopen(); + /// \brief set the write thread + void setWriteThread(WriteThread * writeThread); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + /// \brief to set the id + void setId(int id); + /// \brief stat + enum ReadStat + { + Idle=0, + InodeOperation=1, + Read=2, + WaitWritePipe=3, + Checksum=4 + }; + ReadStat stat; + #endif + /// \brief return if it's reading + bool isReading() const; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + /// \brief executed at regular interval to do a speed throling + void timeOfTheBlockCopyFinished(); + #endif + /// \brief do the fake open + void fakeOpen(); + /// \brief do the fake readIsStarted + void fakeReadIsStarted(); + /// \brief do the fake readIsStopped + void fakeReadIsStopped(); + /// do the checksum + void startCheckSum(); +public slots: + /// \brief to reset the copy, and put at the same state when it just open + void seekToZeroAndWait(); + void postOperation(); + /// do the checksum + void checkSum(); +signals: + void error() const; + void opened() const; + void readIsStarted() const; + void readIsStopped() const; + void closed() const; + void isSeekToZeroAndWait() const; + void checkIfIsWait() const; + void resumeAfterErrorByRestartAll() const; + void resumeAfterErrorByRestartAtTheLastPosition() const; + void checksumFinish(const QByteArray&) const; + // internal signals + void internalStartOpen() const; + void internalStartChecksum() const; + void internalStartReopen() const; + void internalStartRead() const; + void internalStartClose() const; + /// \brief To debug source + void debugInformation(const Ultracopier::DebugLevel &level,std::string fonction,std::string text,std::string file,int ligne) const; + +private: + std::string errorString_internal; + AvancedQFile file; + volatile bool stopIt; + Ultracopier::CopyMode mode; + int64_t lastGoodPosition; + volatile int blockSize;//in Bytes + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + QSemaphore waitNewClockForSpeed; + volatile int numberOfBlockCopied; ///< Multiple for count the number of block copied + volatile int multiForBigSpeed; ///< Multiple for count the number of block needed + #endif + WriteThread* writeThread; + int id; + QSemaphore isOpen; + QSemaphore pauseMutex; + volatile bool putInPause; + volatile bool isInReadLoop; + volatile bool seekToZero; + volatile bool tryStartRead; + int64_t size_at_open; + uint64_t mtime_at_open; + bool fakeMode; + //internal function + bool seek(const int64_t &position);/// \todo search if is use full +private slots: + bool internalOpen(bool resetLastGoodPosition=true); + bool internalOpenSlot(); + bool internalReopen(); + void internalRead(); + void internalClose(bool callByTheDestructor=false); + void internalCloseSlot(); + void isInWait(); +}; + +#endif // READTHREAD_H diff --git a/plugins/CopyEngine/Ultracopier/RenamingRules.cpp b/plugins/CopyEngine/Ultracopier/RenamingRules.cpp new file mode 100644 index 0000000..4ae23b8 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/RenamingRules.cpp @@ -0,0 +1,85 @@ +#include "RenamingRules.h" +#include "ui_RenamingRules.h" + +#include + +RenamingRules::RenamingRules(QWidget *parent) : + QDialog(parent), + ui(new Ui::RenamingRules) +{ + ui->setupUi(this); + connectUI(); + setRenamingRules("",""); +} + +RenamingRules::~RenamingRules() +{ + delete ui; +} + +void RenamingRules::on_buttonBox_clicked(QAbstractButton *button) +{ + if(ui->buttonBox->buttonRole(button)==QDialogButtonBox::RejectRole) + reject(); + if(ui->buttonBox->buttonRole(button)==QDialogButtonBox::ResetRole) + { + setRenamingRules("",""); + emit sendNewRenamingRules(firstRenamingRule,otherRenamingRule); + } +} + +void RenamingRules::setRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule) +{ + disconnectUI(); + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; + if(!firstRenamingRule.empty()) + ui->firstRenamingRule->setText(QString::fromStdString(firstRenamingRule)); + else + ui->firstRenamingRule->setText(tr("%1 - copy").arg(QStringLiteral("%name%"))); + if(!otherRenamingRule.empty()) + ui->otherRenamingRule->setText(QString::fromStdString(otherRenamingRule)); + else + ui->otherRenamingRule->setText(tr("%1 - copy (%2)").arg(QStringLiteral("%name%")).arg(QStringLiteral("%number%"))); + connectUI(); +} + +void RenamingRules::connectUI() +{ + connect(ui->firstRenamingRule,&QLineEdit::editingFinished,this,&RenamingRules::firstRenamingRule_haveChanged); + connect(ui->otherRenamingRule,&QLineEdit::editingFinished,this,&RenamingRules::otherRenamingRule_haveChanged); +} + +void RenamingRules::disconnectUI() +{ + disconnect(ui->firstRenamingRule,&QLineEdit::editingFinished,this,&RenamingRules::firstRenamingRule_haveChanged); + disconnect(ui->otherRenamingRule,&QLineEdit::editingFinished,this,&RenamingRules::otherRenamingRule_haveChanged); +} + +void RenamingRules::firstRenamingRule_haveChanged() +{ + QString newValue=ui->firstRenamingRule->text(); + if(newValue==tr("%1 - copy").arg(QStringLiteral("%name%"))) + newValue=QStringLiteral(""); + if(newValue.toStdString()==firstRenamingRule) + return; + firstRenamingRule=newValue.toStdString(); + emit sendNewRenamingRules(firstRenamingRule,otherRenamingRule); +} + +void RenamingRules::otherRenamingRule_haveChanged() +{ + QString newValue=ui->otherRenamingRule->text(); + if(newValue==tr("%1 - copy (%2)").arg(QStringLiteral("%name%")).arg(QStringLiteral("%number%"))) + newValue=QStringLiteral(""); + if(newValue.toStdString()==otherRenamingRule) + return; + otherRenamingRule=newValue.toStdString(); + emit sendNewRenamingRules(firstRenamingRule,otherRenamingRule); +} + +void RenamingRules::newLanguageLoaded() +{ + ui->retranslateUi(this); + setRenamingRules(firstRenamingRule,otherRenamingRule); +} diff --git a/plugins/CopyEngine/Ultracopier/RenamingRules.h b/plugins/CopyEngine/Ultracopier/RenamingRules.h new file mode 100644 index 0000000..b2e9d02 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/RenamingRules.h @@ -0,0 +1,34 @@ +#ifndef RENAMINGRULES_H +#define RENAMINGRULES_H + +#include +#include + +namespace Ui { +class RenamingRules; +} + +/** Define rules for renaming */ +class RenamingRules : public QDialog +{ + Q_OBJECT +public: + explicit RenamingRules(QWidget *parent = 0); + ~RenamingRules(); + void setRenamingRules(std::string firstRenamingRule, std::string otherRenamingRule); + void newLanguageLoaded(); +private: + Ui::RenamingRules *ui; + void connectUI(); + void disconnectUI(); + std::string firstRenamingRule; + std::string otherRenamingRule; +private slots: + void on_buttonBox_clicked(QAbstractButton *button); + void firstRenamingRule_haveChanged(); + void otherRenamingRule_haveChanged(); +signals: + void sendNewRenamingRules(std::string firstRenamingRule,std::string otherRenamingRule) const; +}; + +#endif // RENAMINGRULES_H diff --git a/plugins/CopyEngine/Ultracopier/RenamingRules.ui b/plugins/CopyEngine/Ultracopier/RenamingRules.ui new file mode 100644 index 0000000..9e84f4b --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/RenamingRules.ui @@ -0,0 +1,129 @@ + + + RenamingRules + + + + 0 + 0 + 303 + 213 + + + + Renaming rules + + + + 2 + + + 2 + + + + + First renaming + + + + + + %name% - copy + + + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p></body></html> + + + + + + + + + + Second renaming + + + + + + %name% - copy (%number%) + + + + + + + <html><head/><body><p>Variables: <span style=" font-weight:600;">%name%</span> for the original file name</p><p><span style=" font-weight:600;">%number%</span> for the extra number</p></body></html> + + + + + + + + + + Qt::Vertical + + + + 20 + 1 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::RestoreDefaults + + + + + + + + + buttonBox + accepted() + RenamingRules + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + RenamingRules + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/plugins/CopyEngine/Ultracopier/ScanFileOrFolder.cpp b/plugins/CopyEngine/Ultracopier/ScanFileOrFolder.cpp new file mode 100644 index 0000000..736f589 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/ScanFileOrFolder.cpp @@ -0,0 +1,688 @@ +#include "ScanFileOrFolder.h" +#include "TransferThread.h" +#include +#include +#include +#include "../../../cpp11addition.h" + +#ifdef Q_OS_WIN32 + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include +#endif + +std::string ScanFileOrFolder::text_slash="/"; +std::string ScanFileOrFolder::text_antislash="\\"; +std::string ScanFileOrFolder::text_dot="."; + +ScanFileOrFolder::ScanFileOrFolder(const Ultracopier::CopyMode &mode) +{ + #ifdef ULTRACOPIER_PLUGIN_RSYNC + rsync = false; + #endif + moveTheWholeFolder = true; + stopped = true; + stopIt = false; + this->mode = mode; + folder_isolation = std::regex("^(.*/)?([^/]+)/$"); + setObjectName(QStringLiteral("ScanFileOrFolder")); + #ifdef Q_OS_WIN32 + QString userName; + DWORD size=255; + WCHAR * userNameW=new WCHAR[size]; + if(GetUserNameW(userNameW,&size)) + { + userName=QString::fromWCharArray(userNameW,size-1); + blackList.push_back(QFileInfo(QStringLiteral("C:/Users/%1/AppData/Roaming/").arg(userName)).absoluteFilePath().toStdString()); + } + delete userNameW; + #endif +} + +ScanFileOrFolder::~ScanFileOrFolder() +{ + stop(); + quit(); + wait(); +} + +bool ScanFileOrFolder::isFinished() const +{ + return stopped; +} + +void ScanFileOrFolder::addToList(const std::vector& sources,const std::string& destination) +{ + stopIt=false; + this->sources=parseWildcardSources(sources); + this->destination=destination; + QFileInfo destinationInfo(QString::fromStdString(this->destination)); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"check symblink: "+destinationInfo.absoluteFilePath().toStdString()); + while(destinationInfo.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"resolv destination to: "+destinationInfo.symLinkTarget().toStdString()); + if(QFileInfo(destinationInfo.symLinkTarget()).isAbsolute()) + this->destination=destinationInfo.symLinkTarget().toStdString(); + else + this->destination=destinationInfo.absolutePath().toStdString()+text_slash+destinationInfo.symLinkTarget().toStdString(); + destinationInfo.setFile(QString::fromStdString(this->destination)); + } + if(sources.size()>1 || QFileInfo(QString::fromStdString(destination)).isDir()) + /* Disabled because the separator transformation product bug + * if(!destination.endsWith(QDir::separator())) + this->destination+=QDir::separator();*/ + if(!stringEndsWith(destination,'/') && !stringEndsWith(destination,'\\')) + this->destination+=text_slash;//put unix separator because it's transformed into that's under windows too + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"addToList("+stringimplode(sources,";")+","+this->destination+")"); +} + + +std::vector ScanFileOrFolder::parseWildcardSources(const std::vector &sources) const +{ + std::regex splitFolder("[/\\\\]"); + std::vector returnList; + unsigned int index=0; + while(index<(unsigned int)sources.size()) + { + if(sources.at(index).find("*") != std::string::npos) + { + std::vector toParse=stringregexsplit(sources.at(index),splitFolder); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"before wildcard parse: "+sources.at(index)+", toParse: "+stringimplode(toParse,", ")); + std::vector > recomposedSource; + { + std::vector t; + t.push_back(""); + recomposedSource.push_back(t); + } + while(toParse.size()>0) + { + if(toParse.front().find("*") != std::string::npos) + { + std::string toParseFirst=toParse.front(); + if(toParseFirst.empty()) + toParseFirst=text_slash; + std::vector > newRecomposedSource; + stringreplaceAll(toParseFirst,"*","[^/\\\\]*"); + std::regex toResolv=std::regex(toParseFirst); + unsigned int index_recomposedSource=0; + while(index_recomposedSource tempList=recomposedSource.at(index_recomposedSource); + tempList.push_back(fileName); + newRecomposedSource.push_back(tempList); + } + index_fileList++; + } + } + index_recomposedSource++; + } + recomposedSource=newRecomposedSource; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"add toParse: "+stringimplode(toParse,text_slash)); + unsigned int index_recomposedSource=0; + while(index_recomposedSource &include, const std::vector &exclude) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); + QMutexLocker lock(&filtersMutex); + this->include_send=include; + this->exclude_send=exclude; + reloadTheNewFilters=true; + haveFilters=include_send.size()>0 || exclude_send.size()>0; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"haveFilters: "+std::to_string(haveFilters)+", include_send.size(): "+std::to_string(include_send.size())+", exclude_send.size(): "+std::to_string(exclude_send.size())); +} + +//set action if Folder are same or exists +void ScanFileOrFolder::setFolderExistsAction(const FolderExistsAction &action, const std::string &newName) +{ + this->newName=newName; + folderExistsAction=action; + waitOneAction.release(); +} + +//set action if error +void ScanFileOrFolder::setFolderErrorAction(const FileErrorAction &action) +{ + fileErrorAction=action; + waitOneAction.release(); +} + +void ScanFileOrFolder::stop() +{ + stopIt=true; + waitOneAction.release(); +} + +void ScanFileOrFolder::run() +{ + stopped=false; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start the listing with destination: "+destination+", mode: "+std::to_string(mode)); + destination=resolvDestination(QString::fromStdString(destination)).absoluteFilePath().toStdString(); + if(stopIt) + { + stopped=true; + return; + } + if(fileErrorAction==FileError_Skip) + { + stopped=true; + return; + } + unsigned int sourceIndex=0; + while(sourceIndexinclude=this->include_send; + this->exclude=this->exclude_send; + } + std::string fileName=fileInfo.fileName().toStdString(); + if(fileInfo.isDir() && !fileInfo.isSymLink()) + { + bool excluded=false,included=(include.size()==0); + unsigned int filters_index=0; + while(filters_indexcheckDestinationExists=checkDestinationFolderExists; +} + +void ScanFileOrFolder::setRenamingRules(const std::string &firstRenamingRule, const std::string &otherRenamingRule) +{ + this->firstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; +} + +void ScanFileOrFolder::setMoveTheWholeFolder(const bool &moveTheWholeFolder) +{ + this->moveTheWholeFolder=moveTheWholeFolder; +} + +void ScanFileOrFolder::setCopyListOrder(const bool &order) +{ + this->copyListOrder=order; +} + +#ifdef ULTRACOPIER_PLUGIN_RSYNC +/// \brief set rsync +void ScanFileOrFolder::setRsync(const bool rsync) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"set rsync: "+std::to_string(rsync)); + this->rsync=rsync; +} +#endif + +void ScanFileOrFolder::set_updateMount() +{ + driveManagement.tryUpdate(); +} diff --git a/plugins/CopyEngine/Ultracopier/ScanFileOrFolder.h b/plugins/CopyEngine/Ultracopier/ScanFileOrFolder.h new file mode 100644 index 0000000..0c625e9 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/ScanFileOrFolder.h @@ -0,0 +1,108 @@ +/** \file scanFileOrFolder.h +\brief Thread changed to list recursively the folder +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Environment.h" +#include "DriveManagement.h" + +#ifndef SCANFILEORFOLDER_H +#define SCANFILEORFOLDER_H + +/// \brief Thread changed to list recursively the folder +class ScanFileOrFolder : public QThread +{ + Q_OBJECT +public: + explicit ScanFileOrFolder(const Ultracopier::CopyMode &mode); + ~ScanFileOrFolder(); + /// \brief to the a folder listing + void stop(); + /// \brief to get if is finished + bool isFinished() const; + /// \brief set action if Folder are same or exists + void setFolderExistsAction(const FolderExistsAction &action, const std::string &newName=""); + /// \brief set action if error + void setFolderErrorAction(const FileErrorAction &action); + /// \brief set if need check if the destination exists + void setCheckDestinationFolderExists(const bool checkDestinationFolderExists); + void setRenamingRules(const std::string &firstRenamingRule,const std::string &otherRenamingRule); + void setMoveTheWholeFolder(const bool &moveTheWholeFolder); + #ifdef ULTRACOPIER_PLUGIN_RSYNC + void setRsync(const bool rsync); + #endif +signals: + void fileTransfer(const QFileInfo &source,const QFileInfo &destination,const Ultracopier::CopyMode &mode) const; + /// \brief To debug source + void debugInformation(const Ultracopier::DebugLevel &level,const std::string &fonction,const std::string &text,const std::string &file,const int &ligne) const; + void folderAlreadyExists(const QFileInfo &source,const QFileInfo &destination,const bool &isSame) const; + void errorOnFolder(const QFileInfo &fileInfo,const std::string &errorString,const ErrorType &errorType=ErrorType_FolderWithRety) const; + void finishedTheListing() const; + + void newFolderListing(const std::string &path) const; + void addToMkPath(const QFileInfo& source,const QFileInfo& destination, const int& inode) const; + void addToMovePath(const QFileInfo& source,const QFileInfo& destination, const int& inodeToRemove) const; + void addToRealMove(const QFileInfo& source,const QFileInfo& destination) const; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + void addToRmForRsync(const QFileInfo& destination) const; + #endif +public slots: + void addToList(const std::vector& sources,const std::string& destination); + void setFilters(const std::vector &include,const std::vector &exclude); + void setCopyListOrder(const bool &order); + void set_updateMount(); +protected: + void run(); +private: + DriveManagement driveManagement; + bool moveTheWholeFolder; + std::vector sources; + std::string destination; + volatile bool stopIt; + void listFolder(QFileInfo source, QFileInfo destination); + bool isBlackListed(const QFileInfo &destination); + QFileInfo resolvDestination(const QFileInfo &destination); + volatile bool stopped; + QSemaphore waitOneAction; + FolderExistsAction folderExistsAction; + FileErrorAction fileErrorAction; + volatile bool checkDestinationExists; + std::string newName; + bool copyListOrder; + std::regex folder_isolation; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + bool rsync; + #endif + Ultracopier::CopyMode mode; + std::vector include,exclude; + std::vector include_send,exclude_send; + bool reloadTheNewFilters; + bool haveFilters; + QMutex filtersMutex; + std::string firstRenamingRule; + std::string otherRenamingRule; + std::vector blackList; + /** Parse the multiple wildcard source, it allow resolv multiple wildcard with Qt into their path + * The string: /toto/f*a/yy*a/toto.mp3 + * Will give: /toto/f1a/yy*a/toto.mp3, /toto/f2a/yy*a/toto.mp3 + * Will give: /toto/f2a/yy1a/toto.mp3, /toto/f2a/yy2a/toto.mp3 + */ + std::vector parseWildcardSources(const std::vector &sources) const; + + static std::string text_slash; + static std::string text_antislash; + static std::string text_dot; +}; + +#endif // SCANFILEORFOLDER_H diff --git a/plugins/CopyEngine/Ultracopier/StructEnumDefinition.h b/plugins/CopyEngine/Ultracopier/StructEnumDefinition.h new file mode 100644 index 0000000..c1758f4 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/StructEnumDefinition.h @@ -0,0 +1 @@ +#include "../../../StructEnumDefinition.h" diff --git a/plugins/CopyEngine/Ultracopier/StructEnumDefinition_CopyEngine.h b/plugins/CopyEngine/Ultracopier/StructEnumDefinition_CopyEngine.h new file mode 100644 index 0000000..036803c --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/StructEnumDefinition_CopyEngine.h @@ -0,0 +1,124 @@ +/** \file StructEnumDefinition_CopyEngine.h +\brief Define the structure and enumeration used in the copy engine +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#include +#include + +#ifndef STRUCTDEF_COPYENGINE_H +#define STRUCTDEF_COPYENGINE_H + +/// \brief Define action if file exists +enum FileExistsAction +{ + FileExists_NotSet=0, + FileExists_Cancel=1, + FileExists_Skip=2, + FileExists_Overwrite=3, + FileExists_OverwriteIfNotSame=4, + FileExists_OverwriteIfNewer=5, + FileExists_OverwriteIfOlder=6, + FileExists_Rename=7 +}; + +/// \brief Define action if file error +enum FileErrorAction +{ + FileError_NotSet=1, + FileError_Cancel=2, + FileError_Skip=3, + FileError_Retry=4, + FileError_PutToEndOfTheList=5 +}; + +enum TransferAlgorithm +{ + TransferAlgorithm_Automatic=0, + TransferAlgorithm_Sequential=1, + TransferAlgorithm_Parallel=2 +}; + +/// \brief to have the transfer status +enum TransferStat +{ + TransferStat_Idle=0, + TransferStat_PreOperation=1, + TransferStat_WaitForTheTransfer=2, + TransferStat_Transfer=3, + TransferStat_Checksum=4, + TransferStat_PostTransfer=5, + TransferStat_PostOperation=6 +}; + +/// \brief Define overwrite mode +/*enum OverwriteMode +{ + OverwriteMode_None, + OverwriteMode_Overwrite, + OverwriteMode_OverwriteIfNewer, + OverwriteMode_OverwriteIfNotSameModificationDate +};*/ + +/// \brief Define action if file exists +enum FolderExistsAction +{ + FolderExists_NotSet=0, + FolderExists_Cancel=1, + FolderExists_Merge=2, + FolderExists_Skip=3, + FolderExists_Rename=4 +}; + +enum ErrorType +{ + ErrorType_Normal=0, + ErrorType_Folder=1, + ErrorType_FolderWithRety=2, + ErrorType_Rights=3 +}; + +enum SearchType +{ + SearchType_rawText=0, + SearchType_simpleRegex=1, + SearchType_perlRegex=2 +}; + +enum ApplyOn +{ + ApplyOn_file=0, + ApplyOn_fileAndFolder=1, + ApplyOn_folder=2 +}; + +/** to store into different way the filter rules to be exported */ +struct Filters_rules +{ + std::string search_text; + SearchType search_type; + ApplyOn apply_on; + bool need_match_all; + std::regex regex; +}; + +/// \brief get action type +enum ActionType +{ + ActionType_MkPath=1, + ActionType_MovePath=2, + ActionType_RealMove=3 + #ifdef ULTRACOPIER_PLUGIN_RSYNC + , + ActionType_RmSync=4 + #endif +}; + +struct Diskspace +{ + std::string drive; + uint64_t requiredSpace; + uint64_t freeSpace; +}; + +#endif // STRUCTDEF_COPYENGINE_H diff --git a/plugins/CopyEngine/Ultracopier/TransferThread.cpp b/plugins/CopyEngine/Ultracopier/TransferThread.cpp new file mode 100644 index 0000000..786a8e9 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/TransferThread.cpp @@ -0,0 +1,2091 @@ +//presume bug linked as multple paralelle inode to resume after "overwrite" +//then do overwrite node function to not re-set the file name + +#include "TransferThread.h" +#ifdef Q_OS_WIN32 +#include +#endif + +#ifdef Q_OS_WIN32 + #ifndef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + #ifndef NOMINMAX + #define NOMINMAX + #endif + #include + #endif +#endif + +#ifdef Q_OS_WIN32 +#define CURRENTSEPARATOR "\\" +#else +#define CURRENTSEPARATOR "/" +#endif + +#include "../../../cpp11addition.h" + +TransferThread::TransferThread() : + haveStartTime (false), + transfer_stat (TransferStat_Idle), + doRightTransfer (false), + #ifdef ULTRACOPIER_PLUGIN_RSYNC + rsync (false), + #endif + stopIt (false), + fileExistsAction (FileExists_NotSet), + alwaysDoFileExistsAction (FileExists_NotSet), + needSkip (false), + needRemove (false), + deletePartiallyTransferredFiles (true), + writeError (false), + readError (false), + renameTheOriginalDestination (false) +{ + start(); + moveToThread(this); + readThread.setWriteThread(&writeThread); + source.setCaching(false); + destination.setCaching(false); + renameRegex=std::regex("^(.*)(\\.[a-z0-9]+)$"); + #ifdef Q_OS_WIN32 + #ifndef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + regRead=std::regex("^[a-z]:"); + #endif + #endif + + minTime=QDateTime(QDate(ULTRACOPIER_PLUGIN_MINIMALYEAR,1,1)); +} + +TransferThread::~TransferThread() +{ + stopIt=true; + readThread.exit(); + readThread.wait(); + writeThread.exit(); + writeThread.wait(); + exit(); + //else cash without this disconnect + //disconnect(&readThread); + //disconnect(&writeThread); + wait(); +} + +void TransferThread::run() +{ + //ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+QStringLiteral("] start: ")+QString::number((qint64)QThread::currentThreadId()))); + transfer_stat = TransferStat_Idle; + stopIt = false; + fileExistsAction = FileExists_NotSet; + alwaysDoFileExistsAction= FileExists_NotSet; + //the error push + connect(&readThread,&ReadThread::error, this, &TransferThread::getReadError, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::error, this, &TransferThread::getWriteError, Qt::QueuedConnection); + //the thread change operation + connect(this,&TransferThread::internalStartPreOperation, this, &TransferThread::preOperation, Qt::QueuedConnection); + connect(this,&TransferThread::internalStartPostOperation, this, &TransferThread::postOperation, Qt::QueuedConnection); + //the state change operation + connect(&readThread,&ReadThread::opened, this, &TransferThread::readIsReady, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::opened, this, &TransferThread::writeIsReady, Qt::QueuedConnection); + connect(&readThread,&ReadThread::readIsStopped, this, &TransferThread::readIsStopped, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::writeIsStopped, this, &TransferThread::writeIsStopped, Qt::QueuedConnection); + connect(&readThread,&ReadThread::readIsStopped, &writeThread, &WriteThread::endIsDetected, Qt::QueuedConnection); + connect(&readThread,&ReadThread::closed, this, &TransferThread::readIsClosed, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::closed, this, &TransferThread::writeIsClosed, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::reopened, this, &TransferThread::writeThreadIsReopened, Qt::QueuedConnection); + connect(&readThread,&ReadThread::checksumFinish, this, &TransferThread::readChecksumFinish, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::checksumFinish, this, &TransferThread::writeChecksumFinish, Qt::QueuedConnection); + //error management + connect(&readThread,&ReadThread::isSeekToZeroAndWait, this, &TransferThread::readThreadIsSeekToZeroAndWait, Qt::QueuedConnection); + connect(&readThread,&ReadThread::resumeAfterErrorByRestartAtTheLastPosition,this, &TransferThread::readThreadResumeAfterError, Qt::QueuedConnection); + connect(&readThread,&ReadThread::resumeAfterErrorByRestartAll,&writeThread, &WriteThread::flushAndSeekToZero, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::flushedAndSeekedToZero, this, &TransferThread::readThreadResumeAfterError, Qt::QueuedConnection); + connect(this,&TransferThread::internalTryStartTheTransfer, this, &TransferThread::internalStartTheTransfer, Qt::QueuedConnection); + + #ifdef ULTRACOPIER_PLUGIN_DEBUG + connect(&readThread,&ReadThread::debugInformation, this, &TransferThread::debugInformation, Qt::QueuedConnection); + connect(&writeThread,&WriteThread::debugInformation, this, &TransferThread::debugInformation, Qt::QueuedConnection); + connect(&driveManagement,&DriveManagement::debugInformation,this, &TransferThread::debugInformation, Qt::QueuedConnection); + #endif + + exec(); +} + +TransferStat TransferThread::getStat() const +{ + return transfer_stat; +} + +void TransferThread::startTheTransfer() +{ + emit internalTryStartTheTransfer(); +} + +void TransferThread::internalStartTheTransfer() +{ + if(transfer_stat==TransferStat_Idle) + { + if(mode!=Ultracopier::Move) + { + /// \bug can pass here because in case of direct move on same media, it return to idle stat directly + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] can't start transfert at idle")); + } + return; + } + if(transfer_stat==TransferStat_PostOperation) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] can't start transfert at PostOperation")); + return; + } + if(transfer_stat==TransferStat_Transfer) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] can't start transfert at Transfer")); + return; + } + if(canStartTransfer) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] canStartTransfer is already set to true")); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+("] check how start the transfer")); + canStartTransfer=true; + if(readIsReadyVariable && writeIsReadyVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+("] start directly the transfer")); + ifCanStartTransfer(); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+("] start the transfer as delayed")); +} + +bool TransferThread::setFiles(const QFileInfo& source, const int64_t &size, const QFileInfo& destination, const Ultracopier::CopyMode &mode) +{ + if(transfer_stat!=TransferStat_Idle) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] already used, source: ")+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()); + return false; + } + //to prevent multiple file alocation into ListThread::doNewActions_inode_manipulation() + transfer_stat = TransferStat_PreOperation; + //emit pushStat(stat,transferId); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start, source: "+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()); + this->source = source; + this->destination = destination; + this->mode = mode; + this->size = size; + stopIt = false; + fileExistsAction = FileExists_NotSet; + canStartTransfer = false; + sended_state_preOperationStopped= false; + canBeMovedDirectlyVariable = false; + canBeCopiedDirectlyVariable = false; + fileContentError = false; + real_doChecksum = false; + writeError = false; + writeError_source_seeked = false; + writeError_destination_reopened = false; + readError = false; + fileContentError = false; + resetExtraVariable(); + emit internalStartPreOperation(); + return true; +} + +void TransferThread::setFileExistsAction(const FileExistsAction &action) +{ + if(transfer_stat!=TransferStat_PreOperation) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] already used, source: ")+source.absoluteFilePath().toStdString()+(", destination: ")+destination.absoluteFilePath().toStdString()); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+("] action: ")+std::to_string(action)); + if(action!=FileExists_Rename) + fileExistsAction = action; + else + { + //always rename pass here + fileExistsAction = action; + alwaysDoFileExistsAction=action; + } + if(action==FileExists_Skip) + { + skip(); + return; + } + resetExtraVariable(); + emit internalStartPreOperation(); +} + +void TransferThread::setFileRename(const std::string &nameForRename) +{ + if(transfer_stat!=TransferStat_PreOperation) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] already used, source: ")+source.absoluteFilePath().toStdString()+(", destination: ")+destination.absoluteFilePath().toStdString()); + return; + } + if(QString::fromStdString(nameForRename).contains(QRegularExpression(QStringLiteral("[/\\\\\\*]")))) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] can't use this kind of name, internal error")); + emit errorOnFile(destination,tr("Try rename with using special characters").toStdString()); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] nameForRename: "+nameForRename); + if(!renameTheOriginalDestination) + destination.setFile(destination.absolutePath()+CURRENTSEPARATOR+QString::fromStdString(nameForRename)); + else + { + QString tempDestination=destination.absoluteFilePath(); + QFile destinationFile(tempDestination); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"["+std::to_string(id)+"] "+QStringLiteral("rename %1: to: %2").arg(destination.absoluteFilePath()).arg(destination.absolutePath()+CURRENTSEPARATOR+QString::fromStdString(nameForRename)).toStdString()); + if(!destinationFile.rename(destination.absolutePath()+CURRENTSEPARATOR+QString::fromStdString(nameForRename))) + { + if(!destinationFile.exists()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("source not exists %1: destination: %2, error: %3").arg(destinationFile.fileName()).arg(destinationFile.fileName()).arg(destinationFile.errorString()).toStdString()); + emit errorOnFile(destinationFile,tr("File not found").toStdString()); + return; + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("unable to do real move %1: %2, error: %3").arg(destinationFile.fileName()).arg(destinationFile.fileName()).arg(destinationFile.errorString()).toStdString()); + emit errorOnFile(destinationFile,destinationFile.errorString().toStdString()); + return; + } + if(source.absoluteFilePath()==destination.absoluteFilePath()) + source.setFile(destination.absolutePath()+CURRENTSEPARATOR+QString::fromStdString(nameForRename)); + destination.setFile(tempDestination); + destination.refresh(); + } + fileExistsAction = FileExists_NotSet; + resetExtraVariable(); + emit internalStartPreOperation(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] destination is: "+destination.absoluteFilePath().toStdString()); +} + +void TransferThread::setAlwaysFileExistsAction(const FileExistsAction &action) +{ + //ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+QStringLiteral("] action to do always: ")+QString::number(action))); + alwaysDoFileExistsAction=action; +} + +void TransferThread::resetExtraVariable() +{ + sended_state_preOperationStopped=false; + sended_state_readStopped = false; + sended_state_writeStopped = false; + writeError = false; + readError = false; + readIsReadyVariable = false; + writeIsReadyVariable = false; + readIsFinishVariable = false; + writeIsFinishVariable = false; + readIsClosedVariable = false; + writeIsClosedVariable = false; + needRemove = false; + needSkip = false; + retry = false; + readIsOpenVariable = false; + writeIsOpenVariable = false; + readIsOpeningVariable = false; + writeIsOpeningVariable = false; +} + +void TransferThread::preOperation() +{ + if(transfer_stat!=TransferStat_PreOperation) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] already used, source: ")+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()); + return; + } + haveStartTime=true; + startTransferTime.restart(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start: source: "+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()); + needRemove=false; + if(isSame()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] is same "+source.absoluteFilePath().toStdString()+" than "+destination.absoluteFilePath().toStdString()); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] after is same"); + /*Why this code? + if(readError) + { + readError=false; + return; + }*/ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] before destination exists"); + if(destinationExists()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] destination exists: "+destination.absoluteFilePath().toStdString()); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] after destination exists"); + /*Why this code? + if(readError) + { + readError=false; + return; + }*/ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] before keep date"); + #ifdef Q_OS_WIN32 + doTheDateTransfer=!source.isSymLink(); + #else + doTheDateTransfer=true; + #endif + if(doTheDateTransfer) + { + if(source.lastModified()="+source.lastModified().toString(QStringLiteral("dd.MM.yyyy hh:mm:ss.zzz")).toStdString()); + doTheDateTransfer=false; + if(keepDate) + { + emit errorOnFile(source,tr("Wrong modification date or unable to get it, you can disable time transfer to do it").toStdString()); + return; + } + } + } + else + { + doTheDateTransfer=readFileDateTime(source); + #ifdef Q_OS_MAC + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] read the source time: "+std::to_string(butime.modtime)); + #endif + if(!doTheDateTransfer) + { + //will have the real error at source open + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] unable to read the source time: "+source.absoluteFilePath().toStdString()); + if(keepDate) + { + emit errorOnFile(source,tr("Wrong modification date or unable to get it, you can disable time transfer to do it").toStdString()); + return; + } + } + } + } + if(canBeMovedDirectly()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] "+QStringLiteral("need moved directly: %1 to %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + canBeMovedDirectlyVariable=true; + readThread.fakeOpen(); + writeThread.fakeOpen(); + return; + } + if(canBeCopiedDirectly()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] "+QStringLiteral("need copied directly: %1 to %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + canBeCopiedDirectlyVariable=true; + readThread.fakeOpen(); + writeThread.fakeOpen(); + return; + } + tryOpen(); +} + +void TransferThread::tryOpen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start source and destination: "+source.absoluteFilePath().toStdString()+" and "+destination.absoluteFilePath().toStdString()); + TransferAlgorithm transferAlgorithm=this->transferAlgorithm; + if(transferAlgorithm==TransferAlgorithm_Automatic) + { + #ifdef Q_OS_LINUX + if(driveManagement.isSameDrive(destination.absoluteFilePath().toStdString(),source.absoluteFilePath().toStdString())) + { + const QByteArray &type=driveManagement.getDriveType(driveManagement.getDrive(source.absoluteFilePath().toStdString())); + if(type=="nfs" || type=="smb") + transferAlgorithm=TransferAlgorithm_Parallel; + else + transferAlgorithm=TransferAlgorithm_Sequential; + } + else + #endif + transferAlgorithm=TransferAlgorithm_Parallel; + } + if(!readIsOpenVariable) + { + if(!readIsOpeningVariable) + { + readError=false; + readThread.open(source.absoluteFilePath(),mode); + readIsOpeningVariable=true; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] readIsOpeningVariable is true when try open"); + emit errorOnFile(source,tr("Internal error: Already opening").toStdString()); + readError=true; + return; + } + } + if(!writeIsOpenVariable) + { + if(!writeIsOpeningVariable) + { + if(transferAlgorithm==TransferAlgorithm_Sequential) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] transferAlgorithm==TransferAlgorithm_Sequential"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] transferAlgorithm==TransferAlgorithm_Parallel"); + writeError=false; + if(transferAlgorithm==TransferAlgorithm_Sequential) + writeThread.open(destination.absoluteFilePath(),size,osBuffer && (!osBufferLimited || (osBufferLimited && sizesource.lastModified()) + return false; + else + { + transfer_stat=TransferStat_Idle; + emit postOperationStopped(); + return true; + } + } + if(fileExistsAction==FileExists_OverwriteIfNotSame || (fileExistsAction==FileExists_NotSet && alwaysDoFileExistsAction==FileExists_OverwriteIfNotSame)) + { + if(destination.lastModified()!=source.lastModified() || destination.size()!=source.size()) + return false; + else + { + transfer_stat=TransferStat_Idle; + emit postOperationStopped(); + return true; + } + } + } + else + { + if(fileExistsAction!=FileExists_NotSet) + { + transfer_stat=TransferStat_Idle; + emit postOperationStopped(); + return true; + } + } + if(fileExistsAction==FileExists_NotSet) + { + emit fileAlreadyExists(source,destination,false); + return true; + } + } + return false; +} + +std::string TransferThread::resolvedName(const QFileInfo &inode) +{ + QString fileName=inode.fileName(); + if(fileName.isEmpty()) + { + QDir absoluteDir=inode.absoluteDir(); + fileName=absoluteDir.dirName(); + if(fileName.isEmpty()) + { + fileName=absoluteDir.cdUp(); + fileName=absoluteDir.dirName(); + } + } + #ifdef Q_OS_WIN32 + if(fileName.isEmpty()) + { + fileName=inode.absolutePath(); + fileName.replace(QRegularExpression(QStringLiteral("^([a-zA-Z]+):.*$")),QStringLiteral("\\1")); + if(inode.absolutePath().contains(QRegularExpression(QStringLiteral("^[a-zA-Z]+:[/\\\\]?$")))) + fileName=tr("Drive %1").arg(fileName); + else + fileName=tr("Unknown folder"); + } + #else + if(fileName.isEmpty()) + fileName=tr("root"); + #endif + return fileName.toStdString(); +} + +std::string TransferThread::getSourcePath() const +{ + return source.absoluteFilePath().toStdString(); +} + +std::string TransferThread::getDestinationPath() const +{ + return destination.absoluteFilePath().toStdString(); +} + +QFileInfo TransferThread::getSourceInode() const +{ + return source; +} + +QFileInfo TransferThread::getDestinationInode() const +{ + return destination; +} + +Ultracopier::CopyMode TransferThread::getMode() const +{ + return mode; +} + +//return true if has been renamed +bool TransferThread::checkAlwaysRename() +{ + if(alwaysDoFileExistsAction==FileExists_Rename) + { + QFileInfo newDestination=destination; + std::string fileName=resolvedName(newDestination); + std::string suffix; + std::string newFileName; + //resolv the suffix + if(std::regex_match(fileName,renameRegex)) + { + suffix=fileName; + suffix=std::regex_replace(suffix,renameRegex,"$2"); + fileName=std::regex_replace(fileName,renameRegex,"$1"); + } + //resolv the new name + int num=1; + do + { + if(num==1) + { + if(firstRenamingRule.empty()) + newFileName=tr("%1 - copy").arg(QString::fromStdString(fileName)).toStdString(); + else + { + newFileName=firstRenamingRule; + stringreplaceAll(newFileName,"%name%",fileName); + } + } + else + { + if(otherRenamingRule.empty()) + newFileName=tr("%1 - copy (%2)").arg(QString::fromStdString(fileName)).arg(num).toStdString(); + else + { + newFileName=otherRenamingRule; + stringreplaceAll(newFileName,"%name%",fileName); + stringreplaceAll(newFileName,"%number%",std::to_string(num)); + } + } + newDestination.setFile(newDestination.absolutePath()+CURRENTSEPARATOR+QString::fromStdString(newFileName+suffix)); + num++; + } + while(newDestination.exists()); + if(!renameTheOriginalDestination) + destination=newDestination; + else + { + QFile destinationFile(destination.absoluteFilePath()); + if(!destinationFile.rename(newDestination.absoluteFilePath())) + { + if(!destinationFile.exists()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("source not exists %1: destination: %2, error: %3").arg(destinationFile.fileName()).arg(destinationFile.fileName()).arg(destinationFile.errorString()).toStdString()); + emit errorOnFile(destinationFile,tr("File not found").toStdString()); + readError=true; + return true; + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("unable to do real move %1: %2, error: %3").arg(destinationFile.fileName()).arg(destinationFile.fileName()).arg(destinationFile.errorString()).toStdString()); + readError=true; + emit errorOnFile(destinationFile,destinationFile.errorString().toStdString()); + return true; + } + } + return true; + } + return false; +} + +void TransferThread::tryMoveDirectly() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] "+QStringLiteral("need moved directly: %1 to %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + + sended_state_readStopped = false; + sended_state_writeStopped = false; + writeError = false; + readError = false; + readIsFinishVariable = false; + writeIsFinishVariable = false; + readIsClosedVariable = false; + writeIsClosedVariable = false; + //move if on same mount point + QFile sourceFile(source.absoluteFilePath()); + QFile destinationFile(destination.absoluteFilePath()); + #ifndef Q_OS_WIN32 + if(destinationFile.exists() || destination.isSymLink()) + { + if(!sourceFile.exists() && !source.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+destinationFile.fileName().toStdString()+", source not exists"); + readError=true; + emit errorOnFile(destination,tr("The source file doesn't exist").toStdString()); + return; + } + else if(!destinationFile.remove()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+destinationFile.fileName().toStdString()+", error: "+destinationFile.errorString().toStdString()); + readError=true; + emit errorOnFile(destination,destinationFile.errorString().toStdString()); + return; + } + } + #endif + QDir dir(destination.absolutePath()); + { + mkpathTransfer->acquire(); + if(!dir.exists()) + dir.mkpath(destination.absolutePath()); + mkpathTransfer->release(); + } + #ifdef Q_OS_WIN32 + //if(!sourceFile.copy(destinationFile.fileName())) + if(MoveFileEx( + reinterpret_cast(sourceFile.fileName().utf16()), + reinterpret_cast(destinationFile.fileName().utf16()), + MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING + )==0) + #else + if(!sourceFile.rename(destinationFile.fileName())) + #endif + { + readError=true; + if(!sourceFile.exists() && !source.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("source not exists %1: destination: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).toStdString()); + emit errorOnFile(sourceFile,tr("File not found").toStdString()); + return; + } + else if(!dir.exists()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("destination folder not exists %1: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).toStdString()); + emit errorOnFile(destination.absolutePath(),tr("Unable to do the folder").toStdString()); + return; + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("unable to do real move %1: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).toStdString()); + emit errorOnFile(sourceFile,sourceFile.errorString().toStdString()); + return; + } + readThread.fakeReadIsStarted(); + writeThread.fakeWriteIsStarted(); + readThread.fakeReadIsStopped(); + writeThread.fakeWriteIsStopped(); +} + +void TransferThread::tryCopyDirectly() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] "+QStringLiteral("need copied directly: %1 to %2").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).toStdString()); + + sended_state_readStopped = false; + sended_state_writeStopped = false; + writeError = false; + readError = false; + readIsFinishVariable = false; + writeIsFinishVariable = false; + readIsClosedVariable = false; + writeIsClosedVariable = false; + //move if on same mount point + QFile sourceFile(source.absoluteFilePath()); + QFile destinationFile(destination.absoluteFilePath()); + #ifndef Q_OS_WIN32 + if(destinationFile.exists() || destination.isSymLink()) + { + if(!sourceFile.exists() && !source.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+destinationFile.fileName().toStdString()+", source not exists"); + readError=true; + emit errorOnFile(destination,tr("The source doesn't exist").toStdString()); + return; + } + else if(!destinationFile.remove()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+destinationFile.fileName().toStdString()+", error: "+destinationFile.errorString().toStdString()); + readError=true; + emit errorOnFile(destination,destinationFile.errorString().toStdString()); + return; + } + } + #endif + QDir dir(destination.absolutePath()); + { + mkpathTransfer->acquire(); + if(!dir.exists()) + dir.mkpath(destination.absolutePath()); + mkpathTransfer->release(); + } + /** on windows, symLink is normal file, can be copied + * on unix not, should be created **/ + #ifdef Q_OS_WIN32 + //if(!sourceFile.copy(destinationFile.fileName())) + if(CopyFileEx( + reinterpret_cast(sourceFile.fileName().utf16()), + reinterpret_cast(destinationFile.fileName().utf16()), + NULL, + NULL, + FALSE, + 0 + )==0) + #else + if(!QFile::link(sourceFile.symLinkTarget(),destinationFile.fileName())) + #endif + { + readError=true; + if(!sourceFile.exists() && !source.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("source not exists %1 -> %4: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).arg(sourceFile.symLinkTarget()).toStdString()); + emit errorOnFile(sourceFile,tr("The source file doesn't exist").toStdString()); + return; + } + else if(destinationFile.exists() || destination.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("destination already exists %1 -> %4: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).arg(sourceFile.symLinkTarget()).toStdString()); + emit errorOnFile(sourceFile,tr("Another file exists at same place").toStdString()); + return; + } + else if(!dir.exists()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("destination folder not exists %1 -> %4: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).arg(sourceFile.symLinkTarget()).toStdString()); + emit errorOnFile(sourceFile,tr("Unable to do the folder").toStdString()); + return; + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("unable to do sym link copy %1 -> %4: %2, error: %3").arg(sourceFile.fileName()).arg(destinationFile.fileName()).arg(sourceFile.errorString()).arg(sourceFile.symLinkTarget()).toStdString()); + emit errorOnFile(sourceFile,sourceFile.errorString().toStdString()); + return; + } + readThread.fakeReadIsStarted(); + writeThread.fakeWriteIsStarted(); + readThread.fakeReadIsStopped(); + writeThread.fakeWriteIsStopped(); +} + +bool TransferThread::canBeMovedDirectly() const +{ + if(mode!=Ultracopier::Move) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] mode!=Ultracopier::Move"); + return false; + } + return source.isSymLink() || driveManagement.isSameDrive(destination.absoluteFilePath().toStdString(),source.absoluteFilePath().toStdString()); +} + +bool TransferThread::canBeCopiedDirectly() const +{ + return source.isSymLink(); +} + +void TransferThread::readIsReady() +{ + if(readIsReadyVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + readIsReadyVariable=true; + readIsOpenVariable=true; + readIsClosedVariable=false; + readIsOpeningVariable=false; + ifCanStartTransfer(); +} + +void TransferThread::ifCanStartTransfer() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] readIsReadyVariable: "+std::to_string(readIsReadyVariable)+", writeIsReadyVariable: "+std::to_string(writeIsReadyVariable)); + if(readIsReadyVariable && writeIsReadyVariable) + { + transfer_stat=TransferStat_WaitForTheTransfer; + sended_state_readStopped = false; + sended_state_writeStopped = false; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stat=WaitForTheTransfer"); + if(!sended_state_preOperationStopped) + { + sended_state_preOperationStopped=true; + emit preOperationStopped(); + } + if(canStartTransfer) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stat=Transfer, "+QStringLiteral("canBeMovedDirectlyVariable: %1, canBeCopiedDirectlyVariable: %2").arg(canBeMovedDirectlyVariable).arg(canBeCopiedDirectlyVariable).toStdString()); + transfer_stat=TransferStat_Transfer; + if(canBeMovedDirectlyVariable) + tryMoveDirectly(); + else if(canBeCopiedDirectlyVariable) + tryCopyDirectly(); + else + { + needRemove=deletePartiallyTransferredFiles; + readThread.startRead(); + } + emit pushStat(transfer_stat,transferId); + } + //else + //emit pushStat(stat,transferId); + } +} + +void TransferThread::writeIsReady() +{ + if(writeIsReadyVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + writeIsReadyVariable=true; + writeIsOpenVariable=true; + writeIsClosedVariable=false; + writeIsOpeningVariable=false; + ifCanStartTransfer(); +} + + +//set the copy info and options before runing +void TransferThread::setRightTransfer(const bool doRightTransfer) +{ + this->doRightTransfer=doRightTransfer; +} + +//set keep date +void TransferThread::setKeepDate(const bool keepDate) +{ + this->keepDate=keepDate; +} + +#ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT +//set the current max speed in KB/s +void TransferThread::setMultiForBigSpeed(const int &multiForBigSpeed) +{ + readThread.setMultiForBigSpeed(multiForBigSpeed); + writeThread.setMultiForBigSpeed(multiForBigSpeed); +} +#endif + +//set block size in Bytes +bool TransferThread::setBlockSize(const unsigned int blockSize) +{ + bool read=readThread.setBlockSize(blockSize); + bool write=writeThread.setBlockSize(blockSize); + return (read && write); +} + +//pause the copy +void TransferThread::pause() +{ + //only pause/resume during the transfer of file data + //from transfer_stat!=TransferStat_Idle because it resume at wrong order + if(transfer_stat!=TransferStat_Transfer && transfer_stat!=TransferStat_PostTransfer && transfer_stat!=TransferStat_Checksum) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] wrong stat to put in pause"); + return; + } + haveStartTime=false; + readThread.pause(); + writeThread.pause(); +} + +//resume the copy +void TransferThread::resume() +{ + //only pause/resume during the transfer of file data + //from transfer_stat!=TransferStat_Idle because it resume at wrong order + if(transfer_stat!=TransferStat_Transfer && transfer_stat!=TransferStat_PostTransfer && transfer_stat!=TransferStat_Checksum) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] wrong stat to put in pause"); + return; + } + readThread.resume(); + writeThread.resume(); +} + +//stop the current copy +void TransferThread::stop() +{ + stopIt=true; + haveStartTime=false; + if(transfer_stat==TransferStat_Idle) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"transfer_stat==TransferStat_Idle"); + return; + } + if(remainSourceOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"remainSourceOpen()"); + readThread.stop(); + } + if(remainDestinationOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"remainDestinationOpen()"); + writeThread.stop(); + } + if(!remainFileOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"transfer_stat==TransferStat_Idle"); + if(needRemove && source.absoluteFilePath()!=destination.absoluteFilePath()) + { + if(source.exists()) + QFile(destination.absoluteFilePath()).remove(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] try destroy the destination when the source don't exists")); + } + transfer_stat=TransferStat_PostOperation; + emit internalStartPostOperation(); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("transfer_stat==%1 && remainFileOpen()").arg(transfer_stat).toStdString()); +} + +bool TransferThread::remainFileOpen() const +{ + return remainSourceOpen() || remainDestinationOpen(); +} + +bool TransferThread::remainSourceOpen() const +{ + return (readIsOpenVariable || readIsOpeningVariable) && !readIsClosedVariable; +} + +bool TransferThread::remainDestinationOpen() const +{ + return (writeIsOpenVariable || writeIsOpeningVariable) && !writeIsClosedVariable; +} + +void TransferThread::readIsFinish() +{ + if(readIsFinishVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] double event dropped")); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + readIsFinishVariable=true; + canStartTransfer=false; + //check here if need start checksuming or not + real_doChecksum=doChecksum && (!checksumOnlyOnError || fileContentError) && (!canBeMovedDirectlyVariable && !canBeCopiedDirectlyVariable); + if(real_doChecksum) + { + readIsFinishVariable=false; + transfer_stat=TransferStat_Checksum; + sourceChecksum=QByteArray(); + destinationChecksum=QByteArray(); + readThread.startCheckSum(); + } + else + { + transfer_stat=TransferStat_PostTransfer; + if(!needSkip || (canBeCopiedDirectlyVariable || canBeMovedDirectlyVariable))//if skip, stop call, then readIsClosed() already call + readThread.postOperation(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] in skip, don't start postOperation"); + } + emit pushStat(transfer_stat,transferId); +} + +void TransferThread::writeIsFinish() +{ + if(writeIsFinishVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] double event dropped"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + writeIsFinishVariable=true; + //check here if need start checksuming or not + if(real_doChecksum) + { + writeIsFinishVariable=false; + transfer_stat=TransferStat_Checksum; + writeThread.startCheckSum(); + } + else + { + if(!needSkip || (canBeCopiedDirectlyVariable || canBeMovedDirectlyVariable))//if skip, stop call, then writeIsClosed() already call + writeThread.postOperation(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] in skip, don't start postOperation"); + } +} + +void TransferThread::readChecksumFinish(const QByteArray& checksum) +{ + sourceChecksum=checksum; + compareChecksum(); +} + +void TransferThread::writeChecksumFinish(const QByteArray& checksum) +{ + destinationChecksum=checksum; + compareChecksum(); +} + +void TransferThread::compareChecksum() +{ + if(sourceChecksum.size()==0) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] the checksum of source is missing"); + return; + } + if(destinationChecksum.size()==0) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] the checksum of destination is missing"); + return; + } + if(sourceChecksum==destinationChecksum) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] the checksum match"); + readThread.postOperation(); + writeThread.postOperation(); + transfer_stat=TransferStat_PostTransfer; + emit pushStat(transfer_stat,transferId); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] the checksum not match")); + //emit error here, and wait to resume + emit errorOnFile(destination,tr("The checksums do not match").toStdString()); + } +} + +void TransferThread::readIsClosed() +{ + if(readIsClosedVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] double event dropped")); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + readIsClosedVariable=true; + readIsOpeningVariable=false; + checkIfAllIsClosedAndDoOperations(); +} + +void TransferThread::writeIsClosed() +{ + if(writeIsClosedVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] double event dropped"); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + writeIsClosedVariable=true; + writeIsOpeningVariable=false; + if(stopIt && needRemove && source.absoluteFilePath()!=destination.absoluteFilePath()) + { + if(source.exists()) + QFile(destination.absoluteFilePath()).remove(); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] try destroy the destination when the source don't exists")); + } + checkIfAllIsClosedAndDoOperations(); +} + +// return true if all is closed, and do some operations, don't use into condition to check if is closed! +bool TransferThread::checkIfAllIsClosedAndDoOperations() +{ + if((readError || writeError) && !needSkip && !stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] resolve error before progress"); + return false; + } + if(!remainFileOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit internalStartPostOperation() to do the real post operation"); + transfer_stat=TransferStat_PostOperation; + //emit pushStat(stat,transferId); + emit internalStartPostOperation(); + return true; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] "+QStringLiteral("wait self close: readIsReadyVariable: %1, readIsClosedVariable: %2, writeIsReadyVariable: %3, writeIsClosedVariable: %4") + .arg(readIsReadyVariable) + .arg(readIsClosedVariable) + .arg(writeIsReadyVariable) + .arg(writeIsClosedVariable) + .toStdString() + ); + return false; + } +} + +/// \todo found way to retry that's +/// \todo the rights copy +void TransferThread::postOperation() +{ + if(transfer_stat!=TransferStat_PostOperation) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] need be in transfer, source: "+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()+", stat:"+std::to_string(transfer_stat)); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + //all except closing + if((readError || writeError) && !needSkip && !stopIt)//normally useless by checkIfAllIsFinish() + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] resume after error"); + return; + } + + if(!needSkip && !stopIt) + { + if(!canBeCopiedDirectlyVariable && !canBeMovedDirectlyVariable) + { + if(writeIsOpenVariable && !writeIsClosedVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] can't pass in post operation if write is not closed")); + emit errorOnFile(destination,tr("Internal error: The destination is not closed").toStdString()); + needSkip=false; + if(deletePartiallyTransferredFiles) + needRemove=true; + writeError=true; + return; + } + if(readThread.getLastGoodPosition()!=writeThread.getLastGoodPosition()) + { + writeThread.flushBuffer(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+QString("] readThread.getLastGoodPosition(%1)!=writeThread.getLastGoodPosition(%2)") + .arg(readThread.getLastGoodPosition()) + .arg(writeThread.getLastGoodPosition()) + .toStdString() + ); + emit errorOnFile(destination,tr("Internal error: The size transfered doesn't match").toStdString()); + needSkip=false; + if(deletePartiallyTransferredFiles) + needRemove=true; + writeError=true; + return; + } + if(!writeThread.bufferIsEmpty()) + { + writeThread.flushBuffer(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] buffer is not empty")); + emit errorOnFile(destination,tr("Internal error: The buffer is not empty").toStdString()); + needSkip=false; + if(deletePartiallyTransferredFiles) + needRemove=true; + writeError=true; + return; + } + } + + if(!doFilePostOperation()) + return; + + //remove source in moving mode + if(mode==Ultracopier::Move && !canBeMovedDirectlyVariable) + { + if(destination.exists() && destination.isFile()) + { + QFile sourceFile(source.absoluteFilePath()); + if(!sourceFile.remove()) + { + needSkip=false; + emit errorOnFile(source,sourceFile.errorString().toStdString()); + return; + } + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] try remove source but destination not exists!")); + } + } + else//do difference skip a file and skip this error case + { + if(needRemove && destination.exists() && source.exists() && source.absoluteFilePath()!=destination.absoluteFilePath() && destination.isFile()) + { + QFile destinationFile(destination.absoluteFilePath()); + if(!destinationFile.remove()) + { + //emit errorOnFile(source,destinationFile.errorString()); + //return; + } + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] try remove destination but not exists!"); + } + source.setFile(QStringLiteral("")); + destination.setFile(QStringLiteral("")); + //don't need remove because have correctly finish (it's not in: have started) + needRemove=false; + needSkip=false; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit postOperationStopped()"); + transfer_stat=TransferStat_Idle; + emit postOperationStopped(); +} + +bool TransferThread::doFilePostOperation() +{ + //do operation needed by copy + //set the time if no write thread used + + destination.refresh(); + if(!destination.exists() && !destination.isSymLink()) + { + if(!stopIt) + if(/*true when the destination have been remove but not the symlink:*/!source.isSymLink()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Unable to change the date: File not found"); + emit errorOnFile(destination,tr("Unable to change the date").toStdString()+": "+tr("File not found").toStdString()); + return false; + } + } + else + { + if(doTheDateTransfer) + { + if(!writeFileDateTime(destination)) + { + if(!destination.isFile()) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Unable to change the date (is not a file)"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Unable to change the date"); + /* error with virtual folder under windows */ + #ifndef Q_OS_WIN32 + if(keepDate) + { + emit errorOnFile(destination,tr("Unable to change the date").toStdString()); + return false; + } + #endif + } + else + { + #ifndef Q_OS_WIN32 + destination.refresh(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] read the destination time: "+destination.lastModified().toString().toStdString()); + if(destination.lastModified() recheck all, because can be an error into isSame(), rename(), ... + return; + } + //data streaming error + if(transfer_stat!=TransferStat_PostOperation && transfer_stat!=TransferStat_Transfer && transfer_stat!=TransferStat_PostTransfer && transfer_stat!=TransferStat_Checksum) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+("] is not in right stat, source: ")+source.absoluteFilePath().toStdString()+", destination: "+destination.absoluteFilePath().toStdString()+", stat: "+std::to_string(transfer_stat)); + return; + } + if(transfer_stat==TransferStat_PostOperation) + { + if(readError || writeError) + { + readError=false; + //writeError=false; + resumeTransferAfterWriteError(); + writeThread.flushBuffer(); + transfer_stat=TransferStat_PreOperation; + emit internalStartPreOperation(); + return; + } + emit internalStartPostOperation(); + return; + } + if(canBeMovedDirectlyVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] retry the system move"); + tryMoveDirectly(); + return; + } + if(canBeCopiedDirectlyVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] retry the copy directly"); + tryCopyDirectly(); + return; + } + if(transfer_stat==TransferStat_Checksum) + { + if(writeError) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start and resume the write error"); + writeThread.reopen(); + } + else if(readError) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start and resume the read error"); + readThread.reopen(); + } + else //only checksum difference + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] retry all the transfer"); + canStartTransfer=true; + ifCanStartTransfer(); + } + return; + } + //can have error on source and destination at the same time + if(writeError) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start and resume the write error: "+std::to_string(readError)); + if(readError) + readThread.reopen(); + else + { + readIsClosedVariable=false; + readThread.seekToZeroAndWait(); + } + writeThread.reopen(); + } + if(readError) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start and resume the read error"); + readThread.reopen(); + } + if(!writeError && !readError) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] unknow error resume"); +} + +void TransferThread::writeThreadIsReopened() +{ + if(writeError_destination_reopened) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + return; + } + writeError_destination_reopened=true; + if(transfer_stat==TransferStat_Checksum) + { + writeThread.startCheckSum(); + return; + } + if(writeError_source_seeked && writeError_destination_reopened) + resumeTransferAfterWriteError(); +} + +void TransferThread::readThreadIsSeekToZeroAndWait() +{ + if(writeError_source_seeked) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + return; + } + writeError_source_seeked=true; + if(writeError_source_seeked && writeError_destination_reopened) + resumeTransferAfterWriteError(); +} + +void TransferThread::resumeTransferAfterWriteError() +{ + writeError=false; +/******************************** + if(canStartTransfer) + readThread.startRead(); +useless, because the open destination event +will restart the transfer as normal +*********************************/ +/********************************* +if(!canStartTransfer) + stat=WaitForTheTransfer; +useless because already do at open event +**********************************/ + //if is in wait + if(!canStartTransfer) + emit checkIfItCanBeResumed(); +} + +void TransferThread::readThreadResumeAfterError() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + readError=false; + writeIsReady(); + readIsReady(); +} + +////////////////////////////////////////////////////////////////// +///////////////////////// Normal event /////////////////////////// +////////////////////////////////////////////////////////////////// + +void TransferThread::readIsStopped() +{ + if(!sended_state_readStopped) + { + sended_state_readStopped=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit readIsStopped()"); + emit readStopped(); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] drop dual read stopped"); + return; + } + readIsFinish(); +} + +void TransferThread::writeIsStopped() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + if(!sended_state_writeStopped) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit writeStopped()"); + sended_state_writeStopped=true; + emit writeStopped(); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + return; + } + writeIsFinish(); +} + +#ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT +void TransferThread::timeOfTheBlockCopyFinished() +{ + readThread.timeOfTheBlockCopyFinished(); + writeThread.timeOfTheBlockCopyFinished(); +} +#endif + +bool TransferThread::setParallelBuffer(const int ¶llelBuffer) +{ + if(parallelBuffer<1 || parallelBuffer>ULTRACOPIER_PLUGIN_MAX_PARALLEL_NUMBER_OF_BLOCK) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] wrong parallelBuffer: "+std::to_string(parallelBuffer)); + return false; + } + else + { + this->parallelBuffer=parallelBuffer; + return true; + } +} + +bool TransferThread::setSequentialBuffer(const int &sequentialBuffer) +{ + if(sequentialBuffer<1 || sequentialBuffer>ULTRACOPIER_PLUGIN_MAX_SEQUENTIAL_NUMBER_OF_BLOCK) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] wrong sequentialBuffer: "+std::to_string(sequentialBuffer)); + return false; + } + else + { + this->sequentialBuffer=sequentialBuffer; + return true; + } +} + +void TransferThread::setTransferAlgorithm(const TransferAlgorithm &transferAlgorithm) +{ + this->transferAlgorithm=transferAlgorithm; + if(transferAlgorithm==TransferAlgorithm_Sequential) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] transferAlgorithm==TransferAlgorithm_Sequential"); + else if(transferAlgorithm==TransferAlgorithm_Automatic) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] transferAlgorithm==TransferAlgorithm_Automatic"); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] transferAlgorithm==TransferAlgorithm_Parallel"); +} + +//fonction to edit the file date time +bool TransferThread::readFileDateTime(const QFileInfo &source) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] readFileDateTime("+source.absoluteFilePath().toStdString()+")"); + if(source.lastModified()ftCreateL=ftCreate.dwLowDateTime; + this->ftCreateH=ftCreate.dwHighDateTime; + this->ftAccessL=ftAccess.dwLowDateTime; + this->ftAccessH=ftAccess.dwHighDateTime; + this->ftWriteL=ftWrite.dwLowDateTime; + this->ftWriteH=ftWrite.dwHighDateTime; + CloseHandle(hFileSouce); + return true; + #endif + #else + return false; + #endif + #endif + return false; +} + +bool TransferThread::writeFileDateTime(const QFileInfo &destination) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] writeFileDateTime("+destination.absoluteFilePath().toStdString()+")"); + /** Why not do it with Qt? Because it not support setModificationTime(), and get the time with Qt, that's mean use local time where in C is UTC time */ + #ifdef Q_OS_UNIX + #ifdef Q_OS_LINUX + return utime(destination.absoluteFilePath().toLatin1().data(),&butime)==0; + #else //mainly for mac + return utime(destination.absoluteFilePath().toLatin1().data(),&butime)==0; + #endif + #else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + return utime(destination.toLatin1().data(),&butime)==0; + #else + wchar_t filePath[65535]; + if(std::regex_match(destination.absoluteFilePath().toStdString(),regRead)) + filePath[QDir::toNativeSeparators(QStringLiteral("\\\\?\\")+destination.absoluteFilePath()).toWCharArray(filePath)]=L'\0'; + else + filePath[QDir::toNativeSeparators(destination.absoluteFilePath()).toWCharArray(filePath)]=L'\0'; + HANDLE hFileDestination = CreateFileW(filePath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if(hFileDestination == INVALID_HANDLE_VALUE) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] open failed to write: "+QString::fromWCharArray(filePath).toStdString()+", error: "+std::to_string(GetLastError())); + return false; + } + FILETIME ftCreate, ftAccess, ftWrite; + ftCreate.dwLowDateTime=this->ftCreateL; + ftCreate.dwHighDateTime=this->ftCreateH; + ftAccess.dwLowDateTime=this->ftAccessL; + ftAccess.dwHighDateTime=this->ftAccessH; + ftWrite.dwLowDateTime=this->ftWriteL; + ftWrite.dwHighDateTime=this->ftWriteH; + if(!SetFileTime(hFileDestination, &ftCreate, &ftAccess, &ftWrite)) + { + CloseHandle(hFileDestination); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] unable to set the file time"); + return false; + } + CloseHandle(hFileDestination); + return true; + #endif + #else + return false; + #endif + #endif + return false; +} + +//skip the copy +void TransferThread::skip() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start with stat: "+std::to_string(transfer_stat)); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] readIsOpeningVariable: "+std::to_string(readIsOpeningVariable)+", readIsOpenVariable: "+std::to_string(readIsOpenVariable)+", readIsReadyVariable: "+std::to_string(readIsReadyVariable)+", readIsFinishVariable: "+std::to_string(readIsFinishVariable)+", readIsClosedVariable: "+std::to_string(readIsClosedVariable)); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] writeIsOpeningVariable: "+std::to_string(writeIsOpeningVariable)+", writeIsOpenVariable: "+std::to_string(writeIsOpenVariable)+", writeIsReadyVariable: "+std::to_string(writeIsReadyVariable)+", writeIsFinishVariable: "+std::to_string(writeIsFinishVariable)+", writeIsClosedVariable: "+std::to_string(writeIsClosedVariable)); + switch(transfer_stat) + { + case TransferStat_WaitForTheTransfer: + //needRemove=true;never put that's here, can product destruction of the file + case TransferStat_PreOperation: + if(needSkip) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] skip already in progress"); + return; + } + needSkip=true; + //check if all is source and destination is closed + if(remainFileOpen()) + { + if(remainSourceOpen()) + readThread.stop(); + if(remainDestinationOpen()) + writeThread.stop(); + } + else // wait nothing, just quit + { + transfer_stat=TransferStat_PostOperation; + emit internalStartPostOperation(); + } + break; + case TransferStat_Transfer: + case TransferStat_PostTransfer: + if(needSkip) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] skip already in progress"); + return; + } + //needRemove=true;never put that's here, can product destruction of the file + needSkip=true; + if(canBeMovedDirectlyVariable || canBeCopiedDirectlyVariable) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] Do the direct FS fake close, canBeMovedDirectlyVariable: "+std::to_string(canBeMovedDirectlyVariable)+", canBeCopiedDirectlyVariable: "+std::to_string(canBeCopiedDirectlyVariable)); + readThread.fakeReadIsStarted(); + writeThread.fakeWriteIsStarted(); + readThread.fakeReadIsStopped(); + writeThread.fakeWriteIsStopped(); + return; + } + writeThread.flushBuffer(); + if(remainFileOpen()) + { + if(remainSourceOpen()) + readThread.stop(); + if(remainDestinationOpen()) + writeThread.stop(); + } + else // wait nothing, just quit + { + transfer_stat=TransferStat_PostOperation; + emit internalStartPostOperation(); + } + break; + case TransferStat_Checksum: + if(needSkip) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] skip already in progress"); + return; + } + //needRemove=true;never put that's here, can product destruction of the file + needSkip=true; + if(remainFileOpen()) + { + if(remainSourceOpen()) + readThread.stop(); + if(remainDestinationOpen()) + writeThread.stop(); + } + else // wait nothing, just quit + { + transfer_stat=TransferStat_PostOperation; + emit internalStartPostOperation(); + } + break; + case TransferStat_PostOperation: + if(needSkip) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] skip already in progress"); + return; + } + //needRemove=true;never put that's here, can product destruction of the file + needSkip=true; + writeThread.flushBuffer(); + emit internalStartPostOperation(); + break; + default: + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] can skip in this state: "+std::to_string(transfer_stat)); + return; + } +} + +//return info about the copied size +int64_t TransferThread::copiedSize() +{ + switch(transfer_stat) + { + case TransferStat_Transfer: + case TransferStat_PostOperation: + case TransferStat_PostTransfer: + return (readThread.getLastGoodPosition()+writeThread.getLastGoodPosition())/2; + case TransferStat_Checksum: + return transferSize; + default: + return 0; + } +} + +//retry after error +void TransferThread::putAtBottom() +{ + emit tryPutAtBottom(); +} + +#ifdef ULTRACOPIER_PLUGIN_RSYNC +/// \brief set rsync +void TransferThread::setRsync(const bool rsync) +{ + this->rsync=rsync; +} +#endif + +void TransferThread::set_osBufferLimit(const unsigned int &osBufferLimit) +{ + this->osBufferLimit=osBufferLimit; +} + +#ifdef ULTRACOPIER_PLUGIN_DEBUG +//to set the id +void TransferThread::setId(int id) +{ + this->id=id; + readThread.setId(id); + writeThread.setId(id); +} + +char TransferThread::readingLetter() const +{ + switch(readThread.stat) + { + case ReadThread::Idle: + return '_'; + break; + case ReadThread::InodeOperation: + return 'I'; + break; + case ReadThread::Read: + return 'R'; + break; + case ReadThread::WaitWritePipe: + return 'W'; + break; + case ReadThread::Checksum: + return 'S'; + break; + default: + return '?'; + } +} + +char TransferThread::writingLetter() const +{ + switch(writeThread.stat) + { + case WriteThread::Idle: + return '_'; + break; + case WriteThread::InodeOperation: + return 'I'; + break; + case WriteThread::Write: + return 'W'; + break; + case WriteThread::Close: + return 'C'; + break; + case WriteThread::Read: + return 'R'; + break; + case WriteThread::Checksum: + return 'S'; + break; + default: + return '?'; + } +} + +#endif + +void TransferThread::setMkpathTransfer(QSemaphore *mkpathTransfer) +{ + this->mkpathTransfer=mkpathTransfer; + writeThread.setMkpathTransfer(mkpathTransfer); +} + +void TransferThread::set_doChecksum(bool doChecksum) +{ + this->doChecksum=doChecksum; +} + +void TransferThread::set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible) +{ + this->checksumIgnoreIfImpossible=checksumIgnoreIfImpossible; +} + +void TransferThread::set_checksumOnlyOnError(bool checksumOnlyOnError) +{ + this->checksumOnlyOnError=checksumOnlyOnError; +} + +void TransferThread::set_osBuffer(bool osBuffer) +{ + this->osBuffer=osBuffer; +} + +void TransferThread::set_osBufferLimited(bool osBufferLimited) +{ + this->osBufferLimited=osBufferLimited; +} + +//not copied size, because that's count to the checksum, ... +uint64_t TransferThread::realByteTransfered() const +{ + switch(transfer_stat) + { + case TransferStat_Transfer: + case TransferStat_Checksum: + return (readThread.getLastGoodPosition()+writeThread.getLastGoodPosition())/2; + case TransferStat_PostTransfer: + return (readThread.getLastGoodPosition()+writeThread.getLastGoodPosition())/2; + case TransferStat_PostOperation: + return transferSize; + default: + return 0; + } +} + +//first is read, second is write +std::pair TransferThread::progression() const +{ + std::pair returnVar; + switch(transfer_stat) + { + case TransferStat_Transfer: + returnVar.first=readThread.getLastGoodPosition(); + returnVar.second=writeThread.getLastGoodPosition(); + /*if(returnVar.firstfirstRenamingRule=firstRenamingRule; + this->otherRenamingRule=otherRenamingRule; +} + +void TransferThread::setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles) +{ + this->deletePartiallyTransferredFiles=deletePartiallyTransferredFiles; +} + +void TransferThread::setRenameTheOriginalDestination(const bool &renameTheOriginalDestination) +{ + this->renameTheOriginalDestination=renameTheOriginalDestination; +} + +void TransferThread::set_updateMount() +{ + driveManagement.tryUpdate(); +} diff --git a/plugins/CopyEngine/Ultracopier/TransferThread.h b/plugins/CopyEngine/Ultracopier/TransferThread.h new file mode 100644 index 0000000..e1a3b3f --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/TransferThread.h @@ -0,0 +1,288 @@ +/** \file TransferThread.h +\brief Thread changed to manage the inode operation, the signals, canceling, pre and post operations +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef TRANSFERTHREAD_H +#define TRANSFERTHREAD_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_UNIX + #include + #include + #include + #include +#else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + #include + #include + #include + #include + #endif + #endif +#endif + +#include "ReadThread.h" +#include "WriteThread.h" +#include "Environment.h" +#include "DriveManagement.h" +#include "StructEnumDefinition_CopyEngine.h" + +/// \brief Thread changed to manage the inode operation, the signals, canceling, pre and post operations +class TransferThread : public QThread +{ + Q_OBJECT +public: + explicit TransferThread(); + ~TransferThread(); + /// \brief get transfer stat + TransferStat getStat() const; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + /// \brief to set the id + void setId(int id); + /// \brief get the reading letter + char readingLetter() const; + /// \brief get the writing letter + char writingLetter() const; + #endif + /// \brief to have semaphore, and try create just one by one + void setMkpathTransfer(QSemaphore *mkpathTransfer); + /// \brief to store the transfer id + uint64_t transferId; + /// \brief to store the transfer size + uint64_t transferSize; + bool haveStartTime; + QTime startTransferTime; + + void set_doChecksum(bool doChecksum); + void set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible); + void set_checksumOnlyOnError(bool checksumOnlyOnError); + void set_osBuffer(bool osBuffer); + void set_osBufferLimited(bool osBufferLimited); + + //not copied size, because that's count to the checksum, ... + uint64_t realByteTransfered() const; + std::pair progression() const; + static std::string resolvedName(const QFileInfo &inode); + std::string getSourcePath() const; + std::string getDestinationPath() const; + QFileInfo getSourceInode() const; + QFileInfo getDestinationInode() const; + Ultracopier::CopyMode getMode() const; +protected: + void run(); +signals: + //to send state + void preOperationStopped() const; + void checkIfItCanBeResumed() const; + //void transferStarted();//not sended (and not used then) + void readStopped() const; + void writeStopped() const; + void postOperationStopped() const; + //get dialog + void fileAlreadyExists(const QFileInfo &info,const QFileInfo &info2,const bool &isSame) const; + void errorOnFile(const QFileInfo &info,const std::string &string,const ErrorType &errorType=ErrorType_Normal) const; + //internal signal + void internalStartPostOperation() const; + void internalStartPreOperation() const; + void internalStartResumeAfterErrorAndSeek() const; + /// \brief To debug source + void debugInformation(const Ultracopier::DebugLevel &level,std::string fonction,std::string text,std::string file,int ligne) const; + void tryPutAtBottom() const; + //force into the right thread + void internalTryStartTheTransfer() const; + /// \brief update the transfer stat + void pushStat(const TransferStat &stat,const uint64_t &pos) const; +public slots: + /// \brief to start the transfer of data + void startTheTransfer(); + /// \brief to set files to transfer + bool setFiles(const QFileInfo& source,const int64_t &size,const QFileInfo& destination,const Ultracopier::CopyMode &mode); + /// \brief to set file exists action to do + void setFileExistsAction(const FileExistsAction &action); + /// \brief to set the new name of the destination + void setFileRename(const std::string &nameForRename); + /// \brief to start the transfer of data + void setAlwaysFileExistsAction(const FileExistsAction &action); + /// \brief set the copy info and options before runing + void setRightTransfer(const bool doRightTransfer); + /// \brief set keep date + void setKeepDate(const bool keepDate); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + /// \brief set the current max speed in KB/s + void setMultiForBigSpeed(const int &maxSpeed); + #endif + /// \brief set block size in KB + bool setBlockSize(const unsigned int blockSize); + /// \brief pause the copy + void pause(); + /// \brief resume the copy + void resume(); + /// \brief stop the copy + void stop(); + /// \brief skip the copy + void skip(); + /// \brief retry after error + void retryAfterError(); + /// \brief return info about the copied size + int64_t copiedSize(); + /// \brief put the current file at bottom + void putAtBottom(); + + #ifdef ULTRACOPIER_PLUGIN_RSYNC + void setRsync(const bool rsync); + #endif + + void set_osBufferLimit(const unsigned int &osBufferLimit); + void setRenamingRules(const std::string &firstRenamingRule,const std::string &otherRenamingRule); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + //speed limitation + void timeOfTheBlockCopyFinished(); + #endif + + bool setParallelBuffer(const int ¶llelBuffer); + bool setSequentialBuffer(const int &sequentialBuffer); + void setTransferAlgorithm(const TransferAlgorithm &transferAlgorithm); + void setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles); + void setRenameTheOriginalDestination(const bool &renameTheOriginalDestination); + void set_updateMount(); +private slots: + void preOperation(); + void readIsReady(); + void writeIsReady(); + void readIsFinish(); + void writeIsFinish(); + void readIsClosed(); + void writeIsClosed(); + void postOperation(); + void getWriteError(); + void getReadError(); + void readChecksumFinish(const QByteArray&); + void writeChecksumFinish(const QByteArray&); + void compareChecksum(); + //void syncAfterErrorAndReadFinish(); + void readThreadIsSeekToZeroAndWait(); + void writeThreadIsReopened(); + void readThreadResumeAfterError(); + //to filter the emition of signal + void readIsStopped(); + void writeIsStopped(); + //force into the right thread + void internalStartTheTransfer(); +private: + enum MoveReturn + { + MoveReturn_skip=0, + MoveReturn_moved=1, + MoveReturn_error=2 + }; + TransferStat transfer_stat; + ReadThread readThread; + WriteThread writeThread; + /*QString source; + QString destination;*/ + Ultracopier::CopyMode mode; + bool doRightTransfer; + #ifdef ULTRACOPIER_PLUGIN_RSYNC + bool rsync; + #endif + bool keepDate; + //ready = open + ready to operation (no error to resolv) + bool readIsReadyVariable; + bool writeIsReadyVariable; + //can be open but with error + bool readIsOpeningVariable;//after call open() and before the end of internalOpen(), mostly to prevent internal error by open() when another is running + bool writeIsOpeningVariable;//after call open() and before the end of internalOpen(), mostly to prevent internal error by open() when another is running + bool readIsOpenVariable; + bool writeIsOpenVariable; + bool readIsFinishVariable; + bool writeIsFinishVariable; + bool readIsClosedVariable; + bool writeIsClosedVariable; + bool canBeMovedDirectlyVariable,canBeCopiedDirectlyVariable; + DriveManagement driveManagement; + QByteArray sourceChecksum,destinationChecksum; + volatile bool stopIt; + volatile bool canStartTransfer; + bool retry; + QFileInfo source; + QFileInfo destination; + int64_t size; + FileExistsAction fileExistsAction; + FileExistsAction alwaysDoFileExistsAction; + bool needSkip,needRemove; + QDateTime minTime; + int id; + QSemaphore *mkpathTransfer; + bool doChecksum,real_doChecksum; + bool checksumIgnoreIfImpossible; + bool checksumOnlyOnError; + bool deletePartiallyTransferredFiles; + bool osBuffer; + bool osBufferLimited; + unsigned int osBufferLimit; + std::string firstRenamingRule; + std::string otherRenamingRule; + //error management + bool writeError,writeError_source_seeked,writeError_destination_reopened; + bool readError; + bool renameTheOriginalDestination; + bool fileContentError; + bool doTheDateTransfer; + int parallelBuffer; + int sequentialBuffer; + int parallelizeIfSmallerThan; + std::regex renameRegex; + TransferAlgorithm transferAlgorithm; + #ifdef Q_OS_UNIX + utimbuf butime; + #else + #ifdef Q_OS_WIN32 + #ifdef ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + utimbuf butime; + #else + uint32_t ftCreateL, ftAccessL, ftWriteL; + uint32_t ftCreateH, ftAccessH, ftWriteH; + std::regex regRead; + #endif + #endif + #endif + //different pre-operation + bool isSame(); + bool destinationExists(); + bool checkAlwaysRename();///< return true if has been renamed + bool canBeMovedDirectly() const; + bool canBeCopiedDirectly() const; + void tryMoveDirectly(); + void tryCopyDirectly(); + void ifCanStartTransfer(); + //fonction to edit the file date time + bool readFileDateTime(const QFileInfo &source); + bool writeFileDateTime(const QFileInfo &destination); + void resetExtraVariable(); + //error management function + void resumeTransferAfterWriteError(); + //to send state + bool sended_state_preOperationStopped; + bool sended_state_readStopped; + bool sended_state_writeStopped; + //different post-operation + bool checkIfAllIsClosedAndDoOperations();// return true if all is closed, and do some operations, don't use into condition to check if is closed! + bool doFilePostOperation(); + //different pre-operation + void tryOpen(); + bool remainFileOpen() const; + bool remainSourceOpen() const; + bool remainDestinationOpen() const; +}; + +#endif // TRANSFERTHREAD_H diff --git a/plugins/CopyEngine/Ultracopier/Variable.h b/plugins/CopyEngine/Ultracopier/Variable.h new file mode 100644 index 0000000..0fd1a3c --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/Variable.h @@ -0,0 +1,43 @@ +/** \file Variable.h +\brief Define the environment variable +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef VARIABLE_H +#define VARIABLE_H + +//Un-comment this next line to put ultracopier plugin in debug mode +#define ULTRACOPIER_PLUGIN_DEBUG +//#define ULTRACOPIER_PLUGIN_DEBUG_SCHEDULER +#define ULTRACOPIER_PLUGIN_DEBUG_WINDOW +#define ULTRACOPIER_PLUGIN_DEBUG_WINDOW_TIMER 150 + +#define ULTRACOPIER_PLUGIN_MINTIMERINTERVAL 50 +#define ULTRACOPIER_PLUGIN_MAXTIMERINTERVAL 100 +#define ULTRACOPIER_PLUGIN_NUMSEMSPEEDMANAGEMENT 2 +#define ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER 1 +#define ULTRACOPIER_PLUGIN_MINIMALYEAR 1995 +#define ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE 256 //in KB +#define ULTRACOPIER_PLUGIN_DEFAULT_SEQUENTIAL_NUMBER_OF_BLOCK 512 +#define ULTRACOPIER_PLUGIN_DEFAULT_PARALLEL_NUMBER_OF_BLOCK 4 //in KB +#define ULTRACOPIER_PLUGIN_MAX_BLOCK_SIZE 16*1024 //in KB +#define ULTRACOPIER_PLUGIN_MAX_SEQUENTIAL_NUMBER_OF_BLOCK 2048 +#define ULTRACOPIER_PLUGIN_MAX_PARALLEL_NUMBER_OF_BLOCK 128 //in KB + +//if set, check the inode type at scanFileOrFolder, deprecated into the new algorithm and not used +#define ULTRACOPIER_PLUGIN_CHECKLISTTYPE + +#define ULTRACOPIER_PLUGIN_SPEED_SUPPORT +//#define ULTRACOPIER_PLUGIN_RIGHTS + +/** \brief Need be greater than 2, but greater than 20 to be efficient */ +#define ULTRACOPIER_PLUGIN_TIME_UPDATE_TRASNFER_LIST 40 +#define ULTRACOPIER_PLUGIN_TIME_UPDATE_PROGRESSION 200 +#define ULTRACOPIER_PLUGIN_TIME_UPDATE_MOUNT_MS 60*1000 + +//#define ULTRACOPIER_PLUGIN_SET_TIME_UNIX_WAY + +#endif // VARIABLE_H + + + diff --git a/plugins/CopyEngine/Ultracopier/WriteThread.cpp b/plugins/CopyEngine/Ultracopier/WriteThread.cpp new file mode 100644 index 0000000..9993961 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/WriteThread.cpp @@ -0,0 +1,968 @@ +#include "WriteThread.h" + +#include + +QMultiHash WriteThread::writeFileList; +QMutex WriteThread::writeFileListMutex; + +WriteThread::WriteThread() +{ + deletePartiallyTransferredFiles = true; + lastGoodPosition = 0; + stopIt = false; + isOpen.release(); + moveToThread(this); + setObjectName(QStringLiteral("write")); + //this->mkpathTransfer = mkpathTransfer; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat = Idle; + #endif + numberOfBlock = ULTRACOPIER_PLUGIN_DEFAULT_PARALLEL_NUMBER_OF_BLOCK; + buffer = false; + putInPause = false; + needRemoveTheFile = false; + blockSize = ULTRACOPIER_PLUGIN_DEFAULT_BLOCK_SIZE*1024; + start(); +} + +WriteThread::~WriteThread() +{ + stopIt=true; + needRemoveTheFile=true; + pauseMutex.release(); + writeFull.release(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + waitNewClockForSpeed.release(); + waitNewClockForSpeed2.release(); + #endif + writeFull.release(); + pauseMutex.release(); + // useless because stopIt will close all thread, but if thread not runing run it + //endIsDetected(); + emit internalStartClose(); + isOpen.acquire(); + if(!file.fileName().isEmpty()) + resumeNotStarted(); + //disconnect(this);//-> do into ~TransferThread() + quit(); + wait(); +} + +void WriteThread::run() +{ + connect(this,&WriteThread::internalStartOpen, this,&WriteThread::internalOpen, Qt::QueuedConnection); + connect(this,&WriteThread::internalStartReopen, this,&WriteThread::internalReopen, Qt::QueuedConnection); + connect(this,&WriteThread::internalStartWrite, this,&WriteThread::internalWrite, Qt::QueuedConnection); + connect(this,&WriteThread::internalStartClose, this,&WriteThread::internalCloseSlot, Qt::QueuedConnection); + connect(this,&WriteThread::internalStartEndOfFile, this,&WriteThread::internalEndOfFile, Qt::QueuedConnection); + connect(this,&WriteThread::internalStartFlushAndSeekToZero, this,&WriteThread::internalFlushAndSeekToZero, Qt::QueuedConnection); + connect(this,&WriteThread::internalStartChecksum, this,&WriteThread::checkSum, Qt::QueuedConnection); + exec(); +} + +bool WriteThread::internalOpen() +{ + //do a bug + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] internalOpen destination: "+file.fileName().toStdString()); + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close because stopIt is at true"); + emit closed(); + return false; + } + if(file.isOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] already open! destination: "+file.fileName().toStdString()); + return false; + } + if(file.fileName().isEmpty()) + { + errorString_internal=tr("Path resolution error (Empty path)").toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to open: %1, error: %2").arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + return false; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] before the mutex"); + //set to LISTBLOCKSIZE + if(sequential) + { + while(writeFull.available()<1) + writeFull.release(); + if(writeFull.available()>1) + writeFull.acquire(writeFull.available()-1); + } + else + { + while(writeFull.available()numberOfBlock) + writeFull.acquire(writeFull.available()-numberOfBlock); + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] after the mutex"); + stopIt=false; + endDetected=false; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=InodeOperation; + #endif + //mkpath check if exists and return true if already exists + QFileInfo destinationInfo(file); + QDir destinationFolder; + { + mkpathTransfer->acquire(); + if(!destinationFolder.exists(destinationInfo.absolutePath())) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] Try create the path: "+ + destinationInfo.absolutePath().toStdString()); + if(!destinationFolder.mkpath(destinationInfo.absolutePath())) + { + if(!destinationFolder.exists(destinationInfo.absolutePath())) + { + /// \todo do real folder error here + errorString_internal="mkpath error on destination"; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable create the folder: %1, error: %2") + .arg(destinationInfo.absolutePath()) + .arg(QString::fromStdString(errorString_internal)) + .toStdString()); + emit error(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + mkpathTransfer->release(); + return false; + } + } + } + mkpathTransfer->release(); + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] after the mkpath"); + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close because stopIt is at true"); + emit closed(); + return false; + } + //try open it + QIODevice::OpenMode flags=QIODevice::ReadWrite; + if(!buffer) + flags|=QIODevice::Unbuffered; + { + QMutexLocker lock_mutex(&writeFileListMutex); + if(writeFileList.count(file.fileName(),this)==0) + { + writeFileList.insert(file.fileName(),this); + if(writeFileList.count(file.fileName())>1) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] in waiting because same file is found"); + return false; + } + } + } + bool fileWasExists=file.exists(); + if(file.open(flags)) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] after the open"); + { + QMutexLocker lock_mutex(&accessList); + if(!theBlockList.isEmpty()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] General file corruption detected"); + stopIt=true; + file.close(); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + return false; + } + } + pauseMutex.tryAcquire(pauseMutex.available()); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] after the pause mutex"); + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close because stopIt is at true"); + file.close(); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + emit closed(); + return false; + } + if(!file.seek(0)) + { + file.close(); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to seek after open: %1, error: %2").arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + return false; + } + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close because stopIt is at true"); + file.close(); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + emit closed(); + return false; + } + if(!file.resize(startSize)) + { + file.close(); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to resize to %1 after open: %2, error: %3").arg(startSize).arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + return false; + } + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close because stopIt is at true"); + file.close(); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + emit closed(); + return false; + } + isOpen.acquire(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit opened()"); + emit opened(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + needRemoveTheFile=false; + postOperationRequested=false; + return true; + } + else + { + if(!fileWasExists && file.exists()) + if(!file.remove()) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] file created but can't be removed"); + if(stopIt) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close because stopIt is at true"); + resumeNotStarted(); + file.setFileName(QStringLiteral("")); + emit closed(); + return false; + } + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to open: %1, error: %2").arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + return false; + } +} + +void WriteThread::open(const QFileInfo &file,const uint64_t &startSize,const bool &buffer,const int &numberOfBlock,const bool &sequential) +{ + if(!isRunning()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] the thread not running to open destination: "+file.absoluteFilePath().toStdString()+", numberOfBlock: "+std::to_string(numberOfBlock)); + errorString_internal=tr("Internal error, please report it!").toStdString(); + emit error(); + return; + } + if(this->file.isOpen()) + { + if(file.absoluteFilePath()==this->file.fileName()) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Try reopen already opened same file: "+file.absoluteFilePath().toStdString()); + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] previous file is already open: "+file.absoluteFilePath().toStdString()); + emit internalStartClose(); + isOpen.acquire(); + isOpen.release(); + } + if(numberOfBlock<1 || (numberOfBlock>ULTRACOPIER_PLUGIN_MAX_PARALLEL_NUMBER_OF_BLOCK && numberOfBlock>ULTRACOPIER_PLUGIN_MAX_SEQUENTIAL_NUMBER_OF_BLOCK)) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] numberOfBlock wrong, set to default"); + this->numberOfBlock=ULTRACOPIER_PLUGIN_DEFAULT_PARALLEL_NUMBER_OF_BLOCK; + } + else + this->numberOfBlock=numberOfBlock; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] "+QStringLiteral("open destination: %1, sequential: %2").arg(file.absoluteFilePath()).arg(sequential).toStdString()); + stopIt=false; + fakeMode=false; + lastGoodPosition=0; + this->file.setFileName(file.absoluteFilePath()); + this->startSize=startSize; + this->buffer=buffer; + this->sequential=sequential; + endDetected=false; + writeFullBlocked=false; + emit internalStartOpen(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + numberOfBlockCopied=0; + #endif +} + +void WriteThread::endIsDetected() +{ + if(endDetected) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] double event dropped"); + return; + } + endDetected=true; + pauseMutex.release(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + emit internalStartEndOfFile(); +} + +std::string WriteThread::errorString() const +{ + return errorString_internal; +} + +void WriteThread::stop() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stop()"); + needRemoveTheFile=true; + stopIt=true; + if(isOpen.available()>0) + return; + writeFull.release(); + pauseMutex.release(); + pauseMutex.release(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + waitNewClockForSpeed.release(); + waitNewClockForSpeed2.release(); + #endif + // useless because stopIt will close all thread, but if thread not runing run it + endIsDetected(); + //for the stop for skip: void TransferThread::skip() + emit internalStartClose(); +} + +void WriteThread::flushBuffer() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + writeFull.release(); + writeFull.acquire(); + pauseMutex.release(); + { + QMutexLocker lock_mutex(&accessList); + theBlockList.clear(); + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stop"); +} + +/// \brief buffer is empty +bool WriteThread::bufferIsEmpty() +{ + bool returnVal; + { + QMutexLocker lock_mutex(&accessList); + returnVal=theBlockList.isEmpty(); + } + return returnVal; +} + +void WriteThread::internalEndOfFile() +{ + if(!bufferIsEmpty()) + { + if(sequential) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start the write"); + emit internalStartWrite(); + } + else + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] buffer is not empty!"); + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] writeIsStopped"); + emit writeIsStopped(); + } +} + +#ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT +/*! \brief Set the max speed +\param tempMaxSpeed Set the max speed in KB/s, 0 for no limit */ +void WriteThread::setMultiForBigSpeed(const int &multiForBigSpeed) +{ + this->multiForBigSpeed=multiForBigSpeed; + waitNewClockForSpeed.release(); + waitNewClockForSpeed2.release(); +} + +/// \brief For give timer every X ms +void WriteThread::timeOfTheBlockCopyFinished() +{ + /* this is the old way to limit the speed, it product blocking + *if(waitNewClockForSpeed.available()maxSpeed>0)*/ + if(waitNewClockForSpeed.available()<=1) + waitNewClockForSpeed.release(); + if(waitNewClockForSpeed2.available()<=1) + waitNewClockForSpeed2.release(); +} +#endif + +void WriteThread::resumeNotStarted() +{ + QMutexLocker lock_mutex(&writeFileListMutex); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + if(!writeFileList.contains(file.fileName())) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] file: \""+file.fileName().toStdString()+"\" for similar inode is not located into the list of "+std::to_string(writeFileList.size())+" items!"); + #endif + writeFileList.remove(file.fileName(),this); + if(writeFileList.contains(file.fileName())) + { + QList writeList=writeFileList.values(file.fileName()); + if(!writeList.isEmpty()) + writeList.first()->reemitStartOpen(); + return; + } +} + +void WriteThread::pause() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] try put read thread in pause"); + pauseMutex.tryAcquire(pauseMutex.available()); + putInPause=true; + return; +} + +void WriteThread::resume() +{ + if(putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + putInPause=false; + stopIt=false; + } + else + return; + if(!file.isOpen()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] file is not open"); + return; + } + pauseMutex.release(); +} + +void WriteThread::reemitStartOpen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] start"); + emit internalStartOpen(); +} + +void WriteThread::postOperation() +{ + if(postOperationRequested) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"["+std::to_string(id)+"] double event dropped"); + return; + } + postOperationRequested=true; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + emit internalStartClose(); +} + +void WriteThread::internalCloseSlot() +{ + internalClose(); +} + +void WriteThread::internalClose(bool emitSignal) +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] close for file: "+file.fileName().toStdString()); + /// \note never send signal here, because it's called by the destructor + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Close; + #endif + bool emit_closed=false; + if(!fakeMode) + { + if(file.isOpen()) + { + if(!needRemoveTheFile) + { + if(startSize!=lastGoodPosition) + if(!file.resize(lastGoodPosition)) + { + if(emitSignal) + { + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to seek after open: %1, error: %2").arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + } + else + needRemoveTheFile=true; + } + } + file.close(); + if(needRemoveTheFile || stopIt) + { + if(deletePartiallyTransferredFiles) + { + if(!file.remove()) + if(emitSignal) + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] unable to remove the destination file"); + } + } + //here and not after, because the transferThread don't need try close if not open + if(emitSignal) + emit_closed=true; + } + } + else + { + //here and not after, because the transferThread don't need try close if not open + + if(emitSignal) + emit_closed=true; + } + needRemoveTheFile=false; + resumeNotStarted(); + //warning: file.setFileName(""); need be after resumeNotStarted() + file.setFileName(QStringLiteral("")); + if(emit_closed) + emit closed(); + + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + /// \note always the last of this function + if(!fakeMode) + isOpen.release(); +} + +void WriteThread::internalReopen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + QString tempFile=file.fileName(); + internalClose(false); + flushBuffer(); + stopIt=false; + lastGoodPosition=0; + file.setFileName(tempFile); + if(internalOpen()) + emit reopened(); +} + +void WriteThread::reopen() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] start"); + stopIt=true; + endDetected=false; + emit internalStartReopen(); +} + +#ifdef ULTRACOPIER_PLUGIN_DEBUG +//to set the id +void WriteThread::setId(int id) +{ + this->id=id; +} +#endif + +/// \brief do the fake open +void WriteThread::fakeOpen() +{ + fakeMode=true; + postOperationRequested=false; + emit opened(); +} + +/// \brief do the fake writeIsStarted +void WriteThread::fakeWriteIsStarted() +{ + emit writeIsStarted(); +} + +/// \brief do the fake writeIsStopped +void WriteThread::fakeWriteIsStopped() +{ + emit writeIsStopped(); +} + +/// do the checksum +void WriteThread::startCheckSum() +{ + emit internalStartChecksum(); +} + +/** \brief set block size +\param block the new block size in B +\return Return true if succes */ +bool WriteThread::setBlockSize(const int blockSize) +{ + //can be smaller than min block size to do correct speed limitation + if(blockSize>1 && blockSizeblockSize=blockSize; + return true; + } + else + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"block size out of range: "+std::to_string(blockSize)); + return false; + } +} + +/// \brief get the last good position +int64_t WriteThread::getLastGoodPosition() const +{ + return lastGoodPosition; +} + +void WriteThread::flushAndSeekToZero() +{ + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"flushAndSeekToZero: "+std::to_string(blockSize)); + stopIt=true; + emit internalStartFlushAndSeekToZero(); +} + + +void WriteThread::checkSum() +{ + //QByteArray blockArray; + QCryptographicHash hash(QCryptographicHash::Sha1); + endDetected=false; + lastGoodPosition=0; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + numberOfBlockCopied=0; + #endif + if(!file.seek(0)) + { + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to seek after open: %1, error: %2").arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + return; + } + int sizeReaden=0; + do + { + if(putInPause) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"["+std::to_string(id)+"] write put in pause"); + if(stopIt) + return; + pauseMutex.acquire(); + if(stopIt) + return; + } + //read one block + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Read; + #endif + blockArray=file.read(blockSize); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(file.error()!=QFile::NoError) + { + errorString_internal=tr("Unable to read the source file: ").toStdString()+file.errorString().toStdString()+" ("+std::to_string(file.error())+")"; + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("file.error()!=QFile::NoError: %1, error: %2").arg(QString::number(file.error())).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + return; + } + sizeReaden=blockArray.size(); + if(sizeReaden>0) + { + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Checksum; + #endif + hash.addData(blockArray); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(stopIt) + break; + + lastGoodPosition+=blockArray.size(); + } + } + while(sizeReaden>0 && !stopIt); + if(lastGoodPosition>(quint64)file.size()) + { + errorString_internal=tr("File truncated during read, possible data change").toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Source truncated during the read: %1 (%2)").arg(file.errorString()).arg(QString::number(file.error())).toStdString()); + emit error(); + return; + } + if(stopIt) + { +/* if(putInPause) + emit isInPause();*/ + stopIt=false; + return; + } + emit checksumFinish(hash.result()); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] stop the read"); +} + +void WriteThread::internalFlushAndSeekToZero() +{ + flushBuffer(); + if(!file.seek(0)) + { + errorString_internal=file.errorString().toStdString(); + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Unable to seek after open: %1, error: %2").arg(file.fileName()).arg(QString::fromStdString(errorString_internal)).toStdString()); + emit error(); + return; + } + stopIt=false; + emit flushedAndSeekedToZero(); +} + +void WriteThread::setMkpathTransfer(QSemaphore *mkpathTransfer) +{ + this->mkpathTransfer=mkpathTransfer; +} + +void WriteThread::setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles) +{ + this->deletePartiallyTransferredFiles=deletePartiallyTransferredFiles; +} + +bool WriteThread::write(const QByteArray &data) +{ + if(stopIt) + return false; + bool atMax; + if(sequential) + { + if(stopIt) + return false; + { + QMutexLocker lock_mutex(&accessList); + theBlockList.append(data); + atMax=(theBlockList.size()>=numberOfBlock); + } + if(atMax) + emit internalStartWrite(); + } + else + { + if(stopIt) + return false; + { + QMutexLocker lock_mutex(&accessList); + theBlockList.append(data); + atMax=(theBlockList.size()>=numberOfBlock); + } + emit internalStartWrite(); + } + if(atMax) + { + writeFullBlocked=true; + writeFull.acquire(); + writeFullBlocked=false; + } + if(stopIt) + return false; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + //wait for limitation speed if stop not query + if(multiForBigSpeed>0) + { + if(sequential) + { + numberOfBlockCopied++; + if(numberOfBlockCopied>=(multiForBigSpeed*2)) + { + numberOfBlockCopied=0; + waitNewClockForSpeed.acquire(); + } + } + else + { + numberOfBlockCopied2++; + if(numberOfBlockCopied2>=multiForBigSpeed) + { + numberOfBlockCopied2=0; + waitNewClockForSpeed2.acquire(); + } + } + } + #endif + if(stopIt) + return false; + return true; +} + +void WriteThread::internalWrite() +{ + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + if(sequential) + { + multiForBigSpeed=0; + QMutexLocker lock_mutex(&accessList); + if(theBlockList.size()0) + { + if(blockArray.size()==blockSize) + { + theBlockList.removeFirst(); + //if remove one block + if(!sequential) + writeFull.release(); + } + else + { + blockArray.clear(); + while(blockArray.size()!=blockSize) + { + //if larger + if(theBlockList.first().size()>blockSize) + { + blockArray+=theBlockList.first().mid(0,blockSize); + theBlockList.first().remove(0,blockSize); + if(!sequential) + { + //do write in loop to finish the actual block + emit internalStartWrite(); + } + break; + } + //if smaller + else + { + blockArray+=theBlockList.first(); + theBlockList.removeFirst(); + //if remove one block + if(!sequential) + writeFull.release(); + if(theBlockList.isEmpty()) + break; + } + } + } + //haveBlock=!blockArray.isEmpty(); + } + else + { + theBlockList.removeFirst(); + //if remove one block + if(!sequential) + writeFull.release(); + } + haveBlock=true; + } + } + if(stopIt) + return; + if(!haveBlock) + { + if(sequential) + { + if(endDetected) + internalEndOfFile(); + else + writeFull.release(); + return; + } + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] End detected of the file"); + return; + } + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + //wait for limitation speed if stop not query + if(multiForBigSpeed>0) + { + numberOfBlockCopied++; + if(sequential || (!sequential && writeFullBlocked)) + { + if(numberOfBlockCopied>=(multiForBigSpeed*2)) + { + numberOfBlockCopied=0; + waitNewClockForSpeed.acquire(); + if(stopIt) + break; + } + } + else + { + if(numberOfBlockCopied>=multiForBigSpeed) + { + numberOfBlockCopied=0; + waitNewClockForSpeed.acquire(); + if(stopIt) + break; + } + } + } + #endif + if(stopIt) + return; + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Write; + #endif + bytesWriten=file.write(blockArray); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + //mutex for stream this data + if(lastGoodPosition==0) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit writeIsStarted()"); + emit writeIsStarted(); + } + if(stopIt) + return; + if(file.error()!=QFile::NoError) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error()).toStdString()); + errorString_internal=QStringLiteral("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error()).toStdString(); + stopIt=true; + emit error(); + return; + } + if(bytesWriten!=blockArray.size()) + { + ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] "+QStringLiteral("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size()).toStdString()); + errorString_internal=QStringLiteral("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size()).toStdString(); + stopIt=true; + emit error(); + return; + } + lastGoodPosition+=bytesWriten; + } while(sequential); +} diff --git a/plugins/CopyEngine/Ultracopier/WriteThread.h b/plugins/CopyEngine/Ultracopier/WriteThread.h new file mode 100644 index 0000000..cadd022 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/WriteThread.h @@ -0,0 +1,160 @@ +/** \file WriteThread.h +\brief Thread changed to open/close and write the destination file +\author alpha_one_x86 +\licence GPL3, see the file COPYING */ + +#ifndef WRITETHREAD_H +#define WRITETHREAD_H + +#include +#include +#include +#include +#include +#include + +#include "Environment.h" +#include "StructEnumDefinition_CopyEngine.h" +#include "AvancedQFile.h" + +/// \brief Thread changed to open/close and write the destination file +class WriteThread : public QThread +{ + Q_OBJECT +public: + explicit WriteThread(); + ~WriteThread(); + /// \brief to have semaphore to do mkpath one by one + void setMkpathTransfer(QSemaphore *mkpathTransfer); +protected: + void run(); +public: + /// \brief open the destination to open it + void open(const QFileInfo &file,const uint64_t &startSize,const bool &buffer,const int &numberOfBlock,const bool &sequential); + /// \brief to return the error string + std::string errorString() const; + /// \brief to stop all + void stop(); + /// \brief to write data + bool write(const QByteArray &data); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + /// \brief to set the id + void setId(int id); + /// \brief get the write stat + enum WriteStat + { + Idle=0, + InodeOperation=1, + Write=2, + Close=3, + Read=5, + Checksum=6 + }; + WriteStat stat; + #endif + /// \brief do the fake open + void fakeOpen(); + /// \brief do the fake writeIsStarted + void fakeWriteIsStarted(); + /// \brief do the fake writeIsStopped + void fakeWriteIsStopped(); + /// do the checksum + void startCheckSum(); + /// \brief set block size in KB + bool setBlockSize(const int blockSize); + /// \brief get the last good position + int64_t getLastGoodPosition() const; + /// \brief buffer is empty + bool bufferIsEmpty(); + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + /// \brief set the current max speed in KB/s + void setMultiForBigSpeed(const int &multiForBigSpeed); + #endif + void pause(); + void resume(); + void reemitStartOpen(); +public slots: + /// \brief start the operation + void postOperation(); + /// \brief flush buffer + void flushBuffer(); + /// \brief set the end is detected + void endIsDetected(); + /// \brief reopen the file + void reopen(); + /// \brief flush and seek to zero + void flushAndSeekToZero(); + /// do the checksum + void checkSum(); + void setDeletePartiallyTransferredFiles(const bool &deletePartiallyTransferredFiles); + /// \brief executed at regular interval to do a speed throling + void timeOfTheBlockCopyFinished(); + + void resumeNotStarted(); +signals: + void error() const; + void opened() const; + void reopened() const; + void writeIsStarted() const; + void writeIsStopped() const; + void flushedAndSeekedToZero() const; + void closed() const; + void checksumFinish(const QByteArray&) const; + //internal signals + void internalStartOpen() const; + void internalStartChecksum() const; + void internalStartReopen() const; + void internalStartWrite() const; + void internalStartClose() const; + void internalStartEndOfFile() const; + void internalStartFlushAndSeekToZero() const; + /// \brief To debug source + void debugInformation(const Ultracopier::DebugLevel &level,const std::string &fonction,const std::string &text,const std::string &file,const int &ligne) const; +private: + std::string errorString_internal; + AvancedQFile file; + volatile bool stopIt; + volatile bool postOperationRequested; + volatile int blockSize;//only used in checksum + int numberOfBlock; + QMutex accessList; ///< For use the list + static QMultiHash writeFileList; + static QMutex writeFileListMutex; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + QSemaphore waitNewClockForSpeed,waitNewClockForSpeed2; + volatile int numberOfBlockCopied,numberOfBlockCopied2; ///< Multiple for count the number of block copied + volatile int multiplicatorForBigSpeed; ///< Multiple for count the number of block needed + volatile int MultiForBigSpeed; + #endif + QSemaphore writeFull; + volatile bool writeFullBlocked; + QSemaphore isOpen; + QSemaphore pauseMutex; + volatile bool putInPause; + QList theBlockList; ///< Store the block list + uint64_t lastGoodPosition; + QByteArray blockArray; ///< temp data for block writing, the data + int64_t bytesWriten; ///< temp data for block writing, the bytes writen + int id; + volatile bool endDetected; + uint64_t startSize; + QSemaphore *mkpathTransfer; + bool fakeMode; + bool buffer; + bool needRemoveTheFile; + volatile bool sequential; + bool deletePartiallyTransferredFiles; + #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT + volatile int multiForBigSpeed; ///< Multiple for count the number of block needed + #endif +private slots: + bool internalOpen(); + void internalWrite(); + void internalCloseSlot(); + void internalClose(bool emitSignal=true); + void internalReopen(); + void internalEndOfFile(); + void internalFlushAndSeekToZero(); +}; + +#endif // WRITETHREAD_H diff --git a/plugins/CopyEngine/Ultracopier/copyEngineOptions.ui b/plugins/CopyEngine/Ultracopier/copyEngineOptions.ui new file mode 100644 index 0000000..4870480 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/copyEngineOptions.ui @@ -0,0 +1,762 @@ + + + copyEngineOptions + + + + 0 + 0 + 801 + 504 + + + + + 0 + + + 0 + + + + + 0 + + + + + 0 + 0 + 791 + 364 + + + + Transfer + + + + + + + + + Move the whole folder + + + + + + + Transfer the file rights + + + + + + + + + + Keep the file date + + + + + + + + + + + + + Autostart the transfer + + + + + + + Less performance if checked + + + + + + + Qt::Vertical + + + + 20 + 278 + + + + + + + + Less performance if checked + + + Follow the strict order + + + + + + + Rsync + + + + + + + + + + + + 0 + 0 + 502 + 218 + + + + Error and collision + + + + + + When folder error + + + + + + + + + + When file error + + + + + + + + Ask + + + + + Skip + + + + + Put at the end + + + + + + + + When file collision + + + + + + + + Ask + + + + + Skip + + + + + Overwrite + + + + + Overwrite if different + + + + + Overwrite if newer + + + + + Overwrite if older + + + + + Rename + + + + + + + + + Ask + + + + + Skip + + + + + + + + When folder collision + + + + + + + + Ask + + + + + Merge + + + + + Skip + + + + + Rename + + + + + + + + Check if destination folder exists + + + + + + + Renaming rules + + + + + + + Qt::Vertical + + + + 20 + 193 + + + + + + + + Delete partially transferred files + + + + + + + + + + + + + Rename the original destination + + + + + label_12 + label_13 + label_6 + label_7 + label_8 + comboBoxFileError + comboBoxFileCollision + comboBoxFolderError + comboBoxFolderCollision + checkBoxDestinationFolderExists + renamingRules + label_20 + deletePartiallyTransferredFiles + renameTheOriginalDestination + label_22 + + + + + 0 + 0 + 172 + 119 + + + + Control + + + + + + Checksum + + + + + + + + + Only after error + + + + + + + Ignore if impossible + + + + + + + + + + true + + + + + + + Verify checksums + + + + + + + + + + Qt::Vertical + + + + 20 + 242 + + + + + + + + + + 0 + 0 + 791 + 364 + + + + Performance + + + + + + Parallel buffer + + + + + + + KB + + + 1 + + + 999999999 + + + + + + + KB + + + 1 + + + 65536 + + + + + + + KB + + + 1 + + + 999999999 + + + + + + + + + + Block size + + + + + + + Sequential buffer + + + + + + + Enable OS buffer + + + + + + + KB + + + 1 + + + 2048 + + + 512 + + + + + + + OS buffer only if smaller than + + + + + + + Transfer algorithm + + + + + + + + Automatic + + + + + Sequential + + + + + Parallel + + + + + + + + Qt::Vertical + + + + 20 + 197 + + + + + + + + Parallelize if smaller than + + + + + + + KB + + + 1024 + + + + + + + 1 + + + 32 + + + 16 + + + + + + + Inode threads + + + + + + + More cpu, but better organisation on the disk + + + + + + + + + + More cpu, but better organisation on the disk + + + Order the list + + + + + + + + + 0 + 0 + 449 + 89 + + + + Misc + + + + + + Check the disk space + + + + + + + + + + Use this folder when destination is not set + + + + + + + + + + + + Browse + + + + + + + + + Qt::Horizontal + + + + 353 + 20 + + + + + + + + Filters + + + + + + + Qt::Horizontal + + + + 352 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 159 + + + + + + + + + + + + + + doChecksum + clicked(bool) + label_9 + setEnabled(bool) + + + 583 + 136 + + + 109 + 161 + + + + + doChecksum + clicked(bool) + checksumOnlyOnError + setEnabled(bool) + + + 594 + 136 + + + 586 + 161 + + + + + doChecksum + clicked(bool) + label_10 + setEnabled(bool) + + + 641 + 136 + + + 132 + 186 + + + + + doChecksum + clicked(bool) + checksumIgnoreIfImpossible + setEnabled(bool) + + + 665 + 136 + + + 609 + 186 + + + + + diff --git a/plugins/CopyEngine/Ultracopier/copyEngineResources.qrc b/plugins/CopyEngine/Ultracopier/copyEngineResources.qrc new file mode 100644 index 0000000..0228c74 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/copyEngineResources.qrc @@ -0,0 +1,8 @@ + + + resources/add.png + resources/edit.png + resources/remove.png + resources/filter.png + + diff --git a/plugins/CopyEngine/Ultracopier/debugDialog.ui b/plugins/CopyEngine/Ultracopier/debugDialog.ui new file mode 100644 index 0000000..80fde7e --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/debugDialog.ui @@ -0,0 +1,98 @@ + + + debugDialog + + + + 665 + 392 + + + + Monitor + + + + + + + + Transfer thread + + + + + + true + + + + + + + + + + Transfer list + + + + + + true + + + + + + + + + + + + Variables + + + + + + Active transfer: + + + + + + + true + + + 9999 + + + + + + + Number of inode manipuled: + + + + + + + true + + + 9999 + + + + + + + + + + + diff --git a/plugins/CopyEngine/Ultracopier/documentation.dox b/plugins/CopyEngine/Ultracopier/documentation.dox new file mode 100644 index 0000000..5a0fbf6 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/documentation.dox @@ -0,0 +1,39 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- **/ + +/* + This file contains NO source code, just some documentation for doxygen to + parse. +*/ + +/*! + \mainpage Copy engine + + \section mainpage_overview Overview + + The default copy engine for Ultracopier. Support file/folder, copy/move, ...\n + More informations on the wiki of ultracopier. + + \section mainpage_platforms Platforms + + This plugin might be usable in all environments where you find Qt 5, but Gcc is requiered for some part. You need qtsystem modules for QtSystemInfo\n + This plugin requires Qt 5.0 or newer. Tested on Qt 5.0.\n + + \section mainpage_downloads Downloads + + You can find the link on Ultracopier project page, via git, snapshot sources, ... + + \section mainpage_algorithm Algorithm + + Like say previously you will have more informations on the wiki.\n + Then file transfer is done via pipe mecamism system:\n +
    +
  • push at no blocking into table up to the table is full, after is blocked up to one entry is free
  • +
  • Other thread read the table up to have no more data, then is blocked
  • +
+ The transfer thread do listing of the folder, removing folder, make folder is one thread for each.\n + The transfer list, have thread pool to do the inode operation (open, close, set date, ...). Do all inode operation in parallele, but transfer the data as sequential. + + \section license GPL Version 3 + The code source is under GPL3. The image is extacted from Oxygen icon pack of KDE4. + +*/ diff --git a/plugins/CopyEngine/Ultracopier/fileErrorDialog.ui b/plugins/CopyEngine/Ultracopier/fileErrorDialog.ui new file mode 100644 index 0000000..b603924 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/fileErrorDialog.ui @@ -0,0 +1,264 @@ + + + fileErrorDialog + + + + 0 + 0 + 723 + 185 + + + + Error with file + + + + + + Error + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFormLayout::ExpandingFieldsGrow + + + + + false + + + Size + + + + + + + 0 KiB + + + + + + + false + + + Modified + + + + + + + Today + + + + + + + false + + + File name + + + + + + + source.txt + + + + + + + false + + + Destination + + + + + + + ../toto.txt + + + + + + + false + + + Folder + + + + + + + /folder/ + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + &Always perform this action + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Try in with elevated privileges + + + + + + + Put to bottom + + + + + + + Retry + + + + + + + &Skip + + + + + + + &Cancel + + + + + + + + + + + checkBoxAlways + toggled(bool) + Cancel + setDisabled(bool) + + + 112 + 131 + + + 438 + 142 + + + + + checkBoxAlways + toggled(bool) + Retry + setDisabled(bool) + + + 155 + 131 + + + 309 + 134 + + + + + diff --git a/plugins/CopyEngine/Ultracopier/fileExistsDialog.ui b/plugins/CopyEngine/Ultracopier/fileExistsDialog.ui new file mode 100644 index 0000000..0c38a57 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/fileExistsDialog.ui @@ -0,0 +1,412 @@ + + + fileExistsDialog + + + + 0 + 0 + 469 + 162 + + + + The file exists + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Source + + + Qt::AlignCenter + + + + + + + + 75 + true + + + + Destination + + + Qt::AlignCenter + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + Size + + + + + + + 0 KiB + + + + + + + false + + + Modified + + + + + + + Today + + + + + + + false + + + File name + + + + + + + source.txt + + + + + + + false + + + Folder + + + + + + + /source/ + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFormLayout::ExpandingFieldsGrow + + + + + false + + + Size + + + + + + + 0 KiB + + + + + + + false + + + Modified + + + + + + + Today + + + + + + + false + + + File name + + + + + + + destination.txt + + + + + + + false + + + Folder + + + + + + + /destination/ + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + + Suggest new &name + + + + + + + + + + + &Always perform this action + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Rename + + + + + + + &Overwrite + + + QToolButton::MenuButtonPopup + + + + + + + &Skip + + + + + + + &Cancel + + + + + + + + + Overwrite if newer + + + + + Overwrite if modification date differs + + + Overwrite if modification date differs + + + + + Overwrite if older + + + Overwrite if older + + + + + + + checkBoxAlways + toggled(bool) + Cancel + setDisabled(bool) + + + 115 + 130 + + + 440 + 129 + + + + + checkBoxAlways + toggled(bool) + lineEditNewName + setDisabled(bool) + + + 62 + 129 + + + 108 + 93 + + + + + checkBoxAlways + toggled(bool) + SuggestNewName + setDisabled(bool) + + + 144 + 138 + + + 326 + 98 + + + + + diff --git a/plugins/CopyEngine/Ultracopier/fileIsSameDialog.ui b/plugins/CopyEngine/Ultracopier/fileIsSameDialog.ui new file mode 100644 index 0000000..c019a63 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/fileIsSameDialog.ui @@ -0,0 +1,214 @@ + + + fileIsSameDialog + + + + 0 + 0 + 411 + 142 + + + + The source and destination are same + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + Size + + + + + + + 0 KiB + + + Qt::PlainText + + + + + + + Today + + + Qt::PlainText + + + + + + + false + + + File name + + + + + + + source.txt + + + Qt::PlainText + + + + + + + false + + + Folder + + + + + + + /toto/ + + + Qt::PlainText + + + + + + + false + + + Modified + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + + Suggest new &name + + + + + + + + + + + &Always perform this action + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Rename + + + + + + + &Skip + + + + + + + &Cancel + + + + + + + + + + diff --git a/plugins/CopyEngine/Ultracopier/folderExistsDialog.ui b/plugins/CopyEngine/Ultracopier/folderExistsDialog.ui new file mode 100644 index 0000000..440b5ca --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/folderExistsDialog.ui @@ -0,0 +1,309 @@ + + + folderExistsDialog + + + + 0 + 0 + 476 + 140 + + + + The source and destination is identical + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Source + + + Qt::AlignCenter + + + + + + + + 75 + true + + + + Destination + + + Qt::AlignCenter + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + Modified + + + + + + + Today + + + + + + + false + + + Folder name + + + + + + + folder + + + + + + + false + + + Folder + + + + + + + /source/ + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + false + + + Modified + + + + + + + false + + + Folder name + + + + + + + Today + + + + + + + folder + + + + + + + false + + + Folder + + + + + + + /destination/ + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + + Suggest new &name + + + + + + + + + + + &Always perform this action + + + + + + + &Rename + + + + + + + Merge + + + + + + + Skip + + + + + + + &Cancel + + + + + + + + + + + checkBoxAlways + clicked(bool) + lineEditNewName + setDisabled(bool) + + + 132 + 126 + + + 135 + 101 + + + + + checkBoxAlways + clicked(bool) + SuggestNewName + setDisabled(bool) + + + 113 + 129 + + + 304 + 100 + + + + + diff --git a/plugins/CopyEngine/Ultracopier/informations-rsync.xml b/plugins/CopyEngine/Ultracopier/informations-rsync.xml new file mode 100644 index 0000000..43befc2 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/informations-rsync.xml @@ -0,0 +1,26 @@ + + + <![CDATA[Rsync copy engine]]> + <![CDATA[Moteur de copie rsync]]> + + CopyEngine + + + + + + + 1287496800 + + linux-x86_64-pc + + + + + 1.0.0.0 + + Rsync + + + \ No newline at end of file diff --git a/plugins/CopyEngine/Ultracopier/informations.xml b/plugins/CopyEngine/Ultracopier/informations.xml new file mode 100644 index 0000000..7968ca8 --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/informations.xml @@ -0,0 +1,26 @@ + + + <![CDATA[Copy engine of Ultracopier]]> + <![CDATA[Moteur de copie d'ultracopier]]> + + CopyEngine + + + + + + + 1287496800 + + windows-x86 + + + + + 1.4.0.4 + + Ultracopier + + + \ No newline at end of file diff --git a/plugins/CopyEngine/Ultracopier/plugin.json b/plugins/CopyEngine/Ultracopier/plugin.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/plugins/CopyEngine/Ultracopier/plugin.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/plugins/CopyEngine/Ultracopier/resources/add.png b/plugins/CopyEngine/Ultracopier/resources/add.png new file mode 100644 index 0000000..7932127 Binary files /dev/null and b/plugins/CopyEngine/Ultracopier/resources/add.png differ diff --git a/plugins/CopyEngine/Ultracopier/resources/edit.png b/plugins/CopyEngine/Ultracopier/resources/edit.png new file mode 100644 index 0000000..5464856 Binary files /dev/null and b/plugins/CopyEngine/Ultracopier/resources/edit.png differ diff --git a/plugins/CopyEngine/Ultracopier/resources/filter.png b/plugins/CopyEngine/Ultracopier/resources/filter.png new file mode 100644 index 0000000..9bb3164 Binary files /dev/null and b/plugins/CopyEngine/Ultracopier/resources/filter.png differ diff --git a/plugins/CopyEngine/Ultracopier/resources/remove.png b/plugins/CopyEngine/Ultracopier/resources/remove.png new file mode 100644 index 0000000..b711740 Binary files /dev/null and b/plugins/CopyEngine/Ultracopier/resources/remove.png differ -- cgit v1.2.3