summaryrefslogtreecommitdiff
path: root/plugins-alternative/CopyEngine/Rsync/ListThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-alternative/CopyEngine/Rsync/ListThread.cpp')
-rwxr-xr-xplugins-alternative/CopyEngine/Rsync/ListThread.cpp1720
1 files changed, 1720 insertions, 0 deletions
diff --git a/plugins-alternative/CopyEngine/Rsync/ListThread.cpp b/plugins-alternative/CopyEngine/Rsync/ListThread.cpp
new file mode 100755
index 0000000..e49cea5
--- /dev/null
+++ b/plugins-alternative/CopyEngine/Rsync/ListThread.cpp
@@ -0,0 +1,1720 @@
+#include "ListThread.h"
+
+ListThread::ListThread(FacilityInterface * facilityInterface)
+{
+ qRegisterMetaType<DebugLevel>("DebugLevel");
+ qRegisterMetaType<ItemOfCopyList>("ItemOfCopyList");
+ qRegisterMetaType<QFileInfo>("QFileInfo");
+ qRegisterMetaType<CopyMode>("CopyMode");
+ qRegisterMetaType<QList<Filters_rules> >("QList<Filters_rules>");
+ qRegisterMetaType<TransferStat>("TransferStat");
+
+ moveToThread(this);
+ start(HighPriority);
+ this->facilityInterface = facilityInterface;
+ putInPause = false;
+ sourceDrive = "";
+ sourceDriveMultiple = false;
+ destinationDrive = "";
+ destinationDriveMultiple = false;
+ stopIt = false;
+ bytesToTransfer = 0;
+ bytesTransfered = 0;
+ idIncrementNumber = 1;
+ actualRealByteTransfered = 0;
+ preOperationNumber = 0;
+ numberOfTranferRuning = 0;
+ numberOfTransferIntoToDoList = 0;
+ numberOfInodeOperation = 0;
+ maxSpeed = 0;
+ doRightTransfer = false;
+ rsync = false;
+ keepDate = false;
+ blockSize = 1024;
+ osBufferLimit = 512;
+ alwaysDoThisActionForFileExists = FileExists_NotSet;
+ doChecksum = false;
+ checksumIgnoreIfImpossible = true;
+ checksumOnlyOnError = true;
+ osBuffer = false;
+ osBufferLimited = false;
+ forcedMode = false;
+
+ #if ! defined (Q_CC_GNU)
+ ui->keepDate->setEnabled(false);
+ ui->keepDate->setToolTip("Not supported with this compiler");
+ #endif
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW
+ connect(&timerUpdateDebugDialog,SIGNAL(timeout()),this,SLOT(timedUpdateDebugDialog()));
+ timerUpdateDebugDialog.start(ULTRACOPIER_PLUGIN_DEBUG_WINDOW_TIMER);
+ #endif
+ connect(this, SIGNAL(tryCancel()), this,SLOT(cancel()), Qt::QueuedConnection);
+ connect(this, SIGNAL(askNewTransferThread()), this,SLOT(createTransferThread()), Qt::QueuedConnection);
+ connect(&mkPathQueue, SIGNAL(firstFolderFinish()), this,SLOT(mkPathFirstFolderFinish()), Qt::QueuedConnection);
+ connect(&rmPathQueue, SIGNAL(firstFolderFinish()), this,SLOT(rmPathFirstFolderFinish()), Qt::QueuedConnection);
+ connect(&mkPathQueue, SIGNAL(errorOnFolder(QFileInfo,QString)), this,SIGNAL(mkPathErrorOnFolder(QFileInfo,QString)), Qt::QueuedConnection);
+ connect(&rmPathQueue, SIGNAL(errorOnFolder(QFileInfo,QString)), this,SIGNAL(rmPathErrorOnFolder(QFileInfo,QString)), Qt::QueuedConnection);
+ connect(this, SIGNAL(send_syncTransferList()), this,SLOT(syncTransferList_internal()), Qt::QueuedConnection);
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ connect(&mkPathQueue, SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)), this,SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)), Qt::QueuedConnection);
+ connect(&rmPathQueue, SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)), this,SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)), 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--;
+ temp_transfer_thread=qobject_cast<TransferThread *>(QObject::sender());
+ if(temp_transfer_thread==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("transfer thread not located!"));
+ return;
+ }
+ isFound=false;
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ int countLocalParse=0;
+ #endif
+ if(temp_transfer_thread->getStat()!=TransferStat_Idle)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("transfer thread not idle!"));
+ return;
+ }
+ int_for_internal_loop=0;
+ loop_size=actionToDoListTransfer.size();
+ while(int_for_internal_loop<loop_size)
+ {
+ if(actionToDoListTransfer.at(int_for_internal_loop).id==temp_transfer_thread->transferId)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("[%1] have finish, put at idle; for id: %2").arg(int_for_internal_loop).arg(temp_transfer_thread->transferId));
+ returnActionOnCopyList newAction;
+ newAction.type=RemoveItem;
+ newAction.addAction.id=temp_transfer_thread->transferId;
+ newAction.userAction.position=int_for_internal_loop;
+ actionDone << newAction;
+ /// \todo check if item is at the right thread
+ actionToDoListTransfer.removeAt(int_for_internal_loop);
+ if(actionToDoListTransfer.size()==0 && actionToDoListInode.size()==0 && actionToDoListInode_afterTheTransfer.size()==0)
+ updateTheStatus();
+
+ temp_transfer_thread->transferId=0;
+ temp_transfer_thread->transferSize=0;
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ countLocalParse++;
+ #endif
+ isFound=true;
+ //emit newActionOnList();
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"numberOfTranferRuning: "+QString::number(numberOfTranferRuning));
+ if(actionToDoListTransfer.size()==0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"numberOfTranferRuning==0");
+ actionToDoListInode << actionToDoListInode_afterTheTransfer;
+ actionToDoListInode_afterTheTransfer.clear();
+ doNewActions_inode_manipulation();
+ }
+ break;
+ }
+ int_for_internal_loop++;
+ }
+ if(!isFound)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("unable to found item into the todo list, id: %1, index: %2").arg(temp_transfer_thread->transferId).arg(int_for_loop));
+ temp_transfer_thread->transferId=0;
+ temp_transfer_thread->transferSize=0;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("countLocalParse: %1, actionToDoList.size(): %2").arg(countLocalParse).arg(actionToDoListTransfer.size()));
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ if(countLocalParse!=1)
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("countLocalParse != 1"));
+ #endif
+ doNewActions_inode_manipulation();
+}
+
+//transfer is finished
+void ListThread::transferIsFinished()
+{
+ temp_transfer_thread=qobject_cast<TransferThread *>(QObject::sender());
+ if(temp_transfer_thread==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("transfer thread not located!"));
+ return;
+ }
+
+ //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;
+ bytesToTransfer+=oversize;
+ bytesTransfered+=oversize;
+ }
+ bytesTransfered+=temp_transfer_thread->transferSize;
+
+// emit newTransferStop(temp_transfer_thread->transferId);
+ numberOfTranferRuning--;
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start transferIsFinished(), numberOfTranferRuning: "+QString::number(numberOfTranferRuning));
+ doNewActions_start_transfer();
+}
+
+/** \brief put the current file at bottom in case of error
+\note ONLY IN CASE OF ERROR */
+void ListThread::transferPutAtBottom()
+{
+ TransferThread *transfer=qobject_cast<TransferThread *>(QObject::sender());
+ if(transfer==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("transfer thread not located!"));
+ return;
+ }
+ transfer->skip();
+ bool isFound=false;
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ int countLocalParse=0;
+ #endif
+ int indexAction=0;
+ while(indexAction<actionToDoListTransfer.size())
+ {
+ if(actionToDoListTransfer.at(indexAction).id==transfer->transferId)
+ {
+ //push for interface at the end
+ returnActionOnCopyList newAction;
+ newAction.type=MoveItem;
+ newAction.addAction.id=transfer->transferId;
+ newAction.userAction.position=actionToDoListTransfer.size()-1;
+ actionDone << newAction;
+ //do the wait stat
+ actionToDoListTransfer[indexAction].isRunning=false;
+ //move at the end
+ actionToDoListTransfer.move(indexAction,actionToDoListTransfer.size()-1);
+ //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(DebugLevel_Critical,QString("unable to found item into the todo list, id: %1, index: %2").arg(transfer->transferId));
+ transfer->transferId=0;
+ transfer->transferSize=0;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("countLocalParse: %1").arg(countLocalParse));
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ if(countLocalParse!=1)
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("countLocalParse != 1"));
+ #endif
+}
+
+//set the copy info and options before runing
+void ListThread::setRightTransfer(const bool doRightTransfer)
+{
+ this->doRightTransfer=doRightTransfer;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->setRightTransfer(doRightTransfer);
+ index++;
+ }
+}
+
+//set keep date
+void ListThread::setKeepDate(const bool keepDate)
+{
+ this->keepDate=keepDate;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->setKeepDate(keepDate);
+ index++;
+ }
+}
+
+//set block size in KB
+void ListThread::setBlockSize(const int blockSize)
+{
+ this->blockSize=blockSize;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->setBlockSize(blockSize);
+ index++;
+ }
+}
+
+//set auto start
+void ListThread::setAutoStart(const bool autoStart)
+{
+ this->autoStart=autoStart;
+}
+
+/// \brief set rsync
+void ListThread::setRsync(const bool rsync)
+{
+ this->rsync=rsync;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->setRsync(rsync);
+ index++;
+ }
+ for(int i=0;i<scanFileOrFolderThreadsPool.size();i++)
+ scanFileOrFolderThreadsPool.at(i)->setRsync(rsync);
+}
+
+//set check destination folder
+void ListThread::setCheckDestinationFolderExists(const bool checkDestinationFolderExists)
+{
+ this->checkDestinationFolderExists=checkDestinationFolderExists;
+ for(int i=0;i<scanFileOrFolderThreadsPool.size();i++)
+ scanFileOrFolderThreadsPool.at(i)->setCheckDestinationFolderExists(checkDestinationFolderExists && alwaysDoThisActionForFolderExists!=FolderExists_Merge);
+}
+
+void ListThread::fileTransfer(const QFileInfo &sourceFileInfo,const QFileInfo &destinationFileInfo,const CopyMode &mode)
+{
+ addToTransfer(sourceFileInfo,destinationFileInfo,mode);
+}
+
+// -> add thread safe, by Qt::BlockingQueuedConnection
+bool ListThread::haveSameSource(QStringList sources)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ if(sourceDriveMultiple)
+ return false;
+ if(sourceDrive.isEmpty())
+ return true;
+ int index=0;
+ while(index<sources.size())
+ {
+// if(threadOfTheTransfer.getDrive(sources.at(index))!=sourceDrive)
+// return false;
+ index++;
+ }
+ return true;
+}
+
+// -> add thread safe, by Qt::BlockingQueuedConnection
+bool ListThread::haveSameDestination(QString destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ if(destinationDriveMultiple)
+ return false;
+ if(destinationDrive.isEmpty())
+ return true;
+ int index=0;
+ while(index<destination.size())
+ {
+// if(threadOfTheTransfer.getDrive(destination.at(index))!=destinationDrive)
+// return false;
+ index++;
+ }
+ return true;
+}
+
+scanFileOrFolder * ListThread::newScanThread(CopyMode mode)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start with: "+QString::number(mode));
+
+ //create new thread because is auto-detroyed
+ scanFileOrFolderThreadsPool << new scanFileOrFolder(mode);
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(finishedTheListing()), this,SLOT(scanThreadHaveFinish()), Qt::QueuedConnection);
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(fileTransfer(QFileInfo,QFileInfo,CopyMode)), this,SLOT(fileTransfer(QFileInfo,QFileInfo,CopyMode)), Qt::QueuedConnection);
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)), this,SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)));
+ #endif
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(newFolderListing(QString)), this,SIGNAL(newFolderListing(QString)));
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(addToRmPath(QString,int)), this,SLOT(addToRmPath(QString,int)), Qt::QueuedConnection);
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(addToRmForRsync(QString)), this,SLOT(addToRmForRsync(QString)), Qt::QueuedConnection);
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(addToMkPath(QString)), this,SLOT(addToMkPath(QString)), Qt::QueuedConnection);
+
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(errorOnFolder(QFileInfo,QString)), this,SLOT(errorOnFolder(QFileInfo,QString)), Qt::QueuedConnection);
+ connect(scanFileOrFolderThreadsPool.last(),SIGNAL(folderAlreadyExists(QFileInfo,QFileInfo,bool)), this,SLOT(folderAlreadyExists(QFileInfo,QFileInfo,bool)), Qt::QueuedConnection);
+
+ scanFileOrFolderThreadsPool.last()->setRsync(rsync);
+ scanFileOrFolderThreadsPool.last()->setFilters(include,exclude);
+ scanFileOrFolderThreadsPool.last()->setCheckDestinationFolderExists(checkDestinationFolderExists && alwaysDoThisActionForFolderExists!=FolderExists_Merge);
+ if(scanFileOrFolderThreadsPool.size()==1)
+ updateTheStatus();
+ scanFileOrFolderThreadsPool.last()->setRenamingRules(firstRenamingRule,otherRenamingRule);
+ return scanFileOrFolderThreadsPool.last();
+}
+
+void ListThread::scanThreadHaveFinish(bool skipFirstRemove)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"listing thread have finish, skipFirstRemove: "+QString::number(skipFirstRemove));
+ if(!skipFirstRemove)
+ {
+ scanFileOrFolder * senderThread = qobject_cast<scanFileOrFolder *>(QObject::sender());
+ if(senderThread==NULL)
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"sender pointer null (plugin copy engine)");
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start the next thread, scanFileOrFolderThreadsPool.size(): "+QString::number(scanFileOrFolderThreadsPool.size()));
+ delete senderThread;
+ scanFileOrFolderThreadsPool.removeOne(senderThread);
+ if(scanFileOrFolderThreadsPool.size()==0)
+ updateTheStatus();
+ }
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start the next thread, scanFileOrFolderThreadsPool.size(): "+QString::number(scanFileOrFolderThreadsPool.size()));
+ if(scanFileOrFolderThreadsPool.size()>0)
+ {
+ //then start the next listing threads
+ if(scanFileOrFolderThreadsPool.first()->isFinished())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"Start listing thread");
+ scanFileOrFolderThreadsPool.first()->start();
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"The listing thread is already running");
+ }
+ else
+ {
+ if(autoStart)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Information,"Auto start the copy");
+ startGeneralTransfer();
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(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(QStringList sources,QString destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start: "+sources.join(";")+", destination: "+destination);
+ scanFileOrFolder * scanFileOrFolderThread = newScanThread(Copy);
+ if(scanFileOrFolderThread==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"unable to get new thread");
+ return false;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start the listing");
+ scanFileOrFolderThread->addToList(sources,destination);
+ scanThreadHaveFinish(true);
+ return true;
+}
+
+// -> add thread safe, by Qt::BlockingQueuedConnection
+bool ListThread::newMove(QStringList sources,QString destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ scanFileOrFolder * scanFileOrFolderThread = newScanThread(Move);
+ if(scanFileOrFolderThread==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"unable to get new thread");
+ return false;
+ }
+ scanFileOrFolderThread->addToList(sources,destination);
+ scanThreadHaveFinish(true);
+/* int index=0;
+ while(index<sources.size() && !sourceDriveMultiple)
+ {
+ QString tempDrive=threadOfTheTransfer.getDrive(sources.at(index));
+ if(sourceDrive=="")
+ sourceDrive=tempDrive;
+ if(tempDrive!=sourceDrive)
+ sourceDriveMultiple=true;
+ index++;
+ }*/
+/* QString tempDrive=threadOfTheTransfer.getDrive(destination);
+ if(!destinationDriveMultiple)
+ {
+ if(tempDrive=="")
+ destinationDrive=tempDrive;
+ if(tempDrive!=destinationDrive)
+ destinationDriveMultiple=true;
+ }*/
+ return true;
+}
+
+void ListThread::setDrive(QStringList drives)
+{
+ this->drives=drives;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->setDrive(drives);
+ index++;
+ }
+}
+
+void ListThread::setCollisionAction(FileExistsAction alwaysDoThisActionForFileExists)
+{
+ this->alwaysDoThisActionForFileExists=alwaysDoThisActionForFileExists;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->setAlwaysFileExistsAction(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(DebugLevel_Notice,"start");
+ emit send_syncTransferList();
+}
+
+//set the folder local colision
+void ListThread::setFolderColision(FolderExistsAction alwaysDoThisActionForFolderExists)
+{
+ this->alwaysDoThisActionForFolderExists=alwaysDoThisActionForFolderExists;
+}
+
+bool ListThread::getReturnBoolToCopyEngine()
+{
+ return returnBoolToCopyEngine;
+}
+
+QPair<quint64,quint64> ListThread::getReturnPairQuint64ToCopyEngine()
+{
+ return returnPairQuint64ToCopyEngine;
+}
+
+ItemOfCopyList ListThread::getReturnItemOfCopyListToCopyEngine()
+{
+ return returnItemOfCopyListToCopyEngine;
+}
+
+void ListThread::set_doChecksum(bool doChecksum)
+{
+ this->doChecksum=doChecksum;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->set_doChecksum(doChecksum);
+ index++;
+ }
+}
+
+void ListThread::set_checksumIgnoreIfImpossible(bool checksumIgnoreIfImpossible)
+{
+ this->checksumIgnoreIfImpossible=checksumIgnoreIfImpossible;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->set_checksumIgnoreIfImpossible(checksumIgnoreIfImpossible);
+ index++;
+ }
+}
+
+void ListThread::set_checksumOnlyOnError(bool checksumOnlyOnError)
+{
+ this->checksumOnlyOnError=checksumOnlyOnError;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->set_checksumOnlyOnError(checksumOnlyOnError);
+ index++;
+ }
+}
+
+void ListThread::set_osBuffer(bool osBuffer)
+{
+ this->osBuffer=osBuffer;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->set_osBuffer(osBuffer);
+ index++;
+ }
+}
+
+void ListThread::set_osBufferLimited(bool osBufferLimited)
+{
+ this->osBufferLimited=osBufferLimited;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->set_osBufferLimited(osBufferLimited);
+ index++;
+ }
+}
+
+void ListThread::realByteTransfered()
+{
+ quint64 totalRealByteTransfered=0;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ totalRealByteTransfered+=transferThreadList.at(index)->realByteTransfered();
+ index++;
+ }
+ emit send_realBytesTransfered(totalRealByteTransfered);
+}
+
+void ListThread::pause()
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ if(putInPause)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"Seam already in pause!");
+ return;
+ }
+ putInPause=true;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->pause();
+ index++;
+ }
+ emit isInPause(true);
+}
+
+void ListThread::resume()
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ if(!putInPause)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"Seam already resumed!");
+ return;
+ }
+ putInPause=false;
+ startGeneralTransfer();
+ doNewActions_start_transfer();
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->resume();
+ index++;
+ }
+ emit isInPause(false);
+}
+
+void ListThread::skip(const quint64 &id)
+{
+ skipInternal(id);
+// emit newActionOnList();
+}
+
+bool ListThread::skipInternal(const quint64 &id)
+{
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ if(transferThreadList.at(index)->transferId==id)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("skip one transfer: %1").arg(id));
+ transferThreadList.at(index)->skip();
+ return true;
+ }
+ index++;
+ }
+ int_for_internal_loop=0;
+ loop_size=actionToDoListTransfer.size();
+ while(int_for_internal_loop<loop_size)
+ {
+ if(actionToDoListTransfer.at(int_for_internal_loop).id==id)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("[%1] remove at not running, for id: %2").arg(int_for_internal_loop).arg(id));
+ returnActionOnCopyList newAction;
+ newAction.type=RemoveItem;
+ newAction.addAction.id=id;
+ newAction.userAction.position=int_for_internal_loop;
+ actionDone << newAction;
+ actionToDoListTransfer.removeAt(int_for_internal_loop);
+ if(actionToDoListTransfer.size()==0 && actionToDoListInode.size()==0 && actionToDoListInode_afterTheTransfer.size()==0)
+ updateTheStatus();
+ return true;
+ }
+ int_for_internal_loop++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("skip transfer not found: %1").arg(id));
+ return false;
+}
+
+void ListThread::cancel()
+{
+ if(stopIt)
+ {
+ waitCancel.release();
+ return;
+ }
+ stopIt=true;
+ int index=0;
+ loop_size=transferThreadList.size();
+ while(index<loop_size)
+ {
+ transferThreadList.at(index)->stop();
+ delete transferThreadList.at(index);//->deleteLayer();
+ transferThreadList[index]=NULL;
+ index++;
+ }
+ index=0;
+ loop_size=scanFileOrFolderThreadsPool.size();
+ while(index<loop_size)
+ {
+ scanFileOrFolderThreadsPool.at(index)->stop();
+ delete scanFileOrFolderThreadsPool.at(index);//->deleteLayer();
+ scanFileOrFolderThreadsPool[index]=NULL;
+ index++;
+ }
+ quit();
+ waitCancel.release();
+ emit canBeDeleted();
+}
+
+//speed limitation
+qint64 ListThread::getSpeedLimitation()
+{
+ return maxSpeed;
+}
+
+bool ListThread::setSpeedLimitation(const qint64 &speedLimitation)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"maxSpeed: "+QString::number(speedLimitation));
+ maxSpeed=speedLimitation;
+ int_for_loop=0;
+ loop_size=transferThreadList.size();
+ while(int_for_loop<loop_size)
+ {
+ transferThreadList.at(int_for_loop)->setMaxSpeed(speedLimitation/ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER);
+ int_for_loop++;
+ }
+ return true;
+}
+
+void ListThread::updateTheStatus()
+{
+ /*if(threadOfTheTransfer.haveContent())
+ copy=true;*/
+ updateTheStatus_listing=scanFileOrFolderThreadsPool.size()>0;
+ updateTheStatus_copying=actionToDoListTransfer.size()>0 || actionToDoListInode.size()>0 || actionToDoListInode_afterTheTransfer.size()>0;
+ if(updateTheStatus_copying && updateTheStatus_listing)
+ updateTheStatus_action_in_progress=CopyingAndListing;
+ else if(updateTheStatus_listing)
+ updateTheStatus_action_in_progress=Listing;
+ else if(updateTheStatus_copying)
+ updateTheStatus_action_in_progress=Copying;
+ else
+ updateTheStatus_action_in_progress=Idle;
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"emit actionInProgess("+QString::number(updateTheStatus_action_in_progress)+")");
+ emit actionInProgess(updateTheStatus_action_in_progress);
+ if(updateTheStatus_action_in_progress==Idle)
+ sendActionDone();
+}
+
+//set data local to the thread
+void ListThread::setAlwaysFileExistsAction(FileExistsAction alwaysDoThisActionForFileExists)
+{
+ this->alwaysDoThisActionForFileExists=alwaysDoThisActionForFileExists;
+ int_for_loop=0;
+ loop_size=transferThreadList.size();
+ while(int_for_loop<loop_size)
+ {
+ transferThreadList.at(int_for_loop)->setAlwaysFileExistsAction(alwaysDoThisActionForFileExists);
+ int_for_loop++;
+ }
+}
+
+//mk path to do
+quint64 ListThread::addToMkPath(const QString& folder)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"folder: "+folder);
+ actionToDoInode temp;
+ temp.type = ActionType_MkPath;
+ temp.id = generateIdNumber();
+ temp.folder.setFile(folder);
+ temp.isRunning = false;
+ actionToDoListInode << temp;
+ return temp.id;
+}
+
+//add rm path to do
+void ListThread::addToRmPath(const QString& folder,const int& inodeToRemove)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"folder: "+folder+",inodeToRemove: "+QString::number(inodeToRemove));
+ actionToDoInode temp;
+ temp.type = ActionType_RmPath;
+ temp.id = generateIdNumber();
+ temp.size = inodeToRemove;
+ temp.folder.setFile(folder);
+ temp.isRunning = false;
+ if(inodeToRemove==0)
+ actionToDoListInode << temp;
+ else
+ actionToDoListInode_afterTheTransfer << temp;
+}
+
+//rsync rm
+void ListThread::addToRmForRsync(const QString& inode)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"inode: "+inode);
+ actionToDoInode temp;
+ temp.type = ActionType_RmSync;
+ temp.id = generateIdNumber();
+ temp.folder.setFile(inode);
+ temp.isRunning = false;
+ actionToDoListInode << temp;
+}
+
+//send action done
+void ListThread::sendActionDone()
+{
+ if(actionDone.size()>0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ emit newActionOnList(actionDone);
+ actionDone.clear();
+ }
+}
+
+//send progression
+void ListThread::sendProgression()
+{
+ if(actionToDoListTransfer.size()==0)
+ return;
+ oversize=0;
+ currentProgression=0;
+ int_for_loop=0;
+ loop_size=transferThreadList.size();
+ while(int_for_loop<loop_size)
+ {
+ temp_transfer_thread=transferThreadList.at(int_for_loop);
+ if(temp_transfer_thread->getStat()==TransferStat_Transfer || temp_transfer_thread->getStat()==TransferStat_Checksum)
+ {
+ 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;
+ if(temp_transfer_thread->getStat()==TransferStat_Checksum)
+ tempItem.current=temp_transfer_thread->realByteTransfered();
+ else
+ tempItem.current=copiedSize;
+ tempItem.id=temp_transfer_thread->transferId;
+ tempItem.total=totalSize;
+ progressionList << tempItem;
+
+ //add the oversize to the general progression
+ oversize+=localOverSize;
+ }
+ 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(DebugLevel_Notice,"start");
+ emit syncReady();
+ actionDone.clear();
+ //do list operation
+ TransferThread *transferThread;
+ loop_size=actionToDoListTransfer.size();
+ loop_sub_size=transferThreadList.size();
+ //this loop to have at max ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT*ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT, not ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT*transferThreadList.size()
+ for(int_for_loop=0; int_for_loop<loop_size; ++int_for_loop) {
+ const actionToDoTransfer &item=actionToDoListTransfer.at(int_for_loop);
+ returnActionOnCopyList newAction;
+ newAction.type = PreOperation;
+ newAction.addAction.id = item.id;
+ newAction.addAction.sourceFullPath = item.source.absoluteFilePath();
+ newAction.addAction.sourceFileName = item.source.fileName();
+ newAction.addAction.destinationFullPath = item.destination.absoluteFilePath();
+ newAction.addAction.destinationFileName = item.destination.fileName();
+ newAction.addAction.size = item.size;
+ newAction.addAction.mode = item.mode;
+ actionDone << newAction;
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("id: %1, size: %2, name: %3, size2: %4").arg(item.id).arg(item.size).arg(item.source.absoluteFilePath()).arg(newAction.addAction.size));
+ if(item.isRunning)
+ {
+ for(int_for_internal_loop=0; int_for_internal_loop<loop_sub_size; ++int_for_internal_loop) {
+ transferThread=transferThreadList.at(int_for_internal_loop);
+ returnActionOnCopyList newAction;
+ newAction.type = PreOperation;
+ newAction.addAction.id = item.id;
+ newAction.addAction.sourceFullPath = item.source.absoluteFilePath();
+ newAction.addAction.sourceFileName = item.source.fileName();
+ newAction.addAction.destinationFullPath = item.destination.absoluteFilePath();
+ newAction.addAction.destinationFileName = item.destination.fileName();
+ newAction.addAction.size = item.size;
+ newAction.addAction.mode = item.mode;
+ actionDone << newAction;
+ if(transferThread->getStat()!=TransferStat_PreOperation)
+ {
+ returnActionOnCopyList newAction;
+ switch(transferThread->getStat())
+ {
+ case TransferStat_Transfer:
+ newAction.type=Transfer;
+ break;
+ case TransferStat_PostTransfer:
+ newAction.type=PostOperation;
+ break;
+ default:
+ break;
+ }
+ newAction.addAction.id = item.id;
+ actionDone << newAction;
+ }
+ }
+ }
+ }
+}
+
+//add file transfer to do
+quint64 ListThread::addToTransfer(const QFileInfo& source,const QFileInfo& destination,const CopyMode& mode)
+{
+ //add to transfer list
+ numberOfTransferIntoToDoList++;
+ bytesToTransfer+= source.size();
+ actionToDoTransfer temp;
+ temp.id = generateIdNumber();
+ temp.size = source.size();
+ temp.source = source;
+ temp.destination= destination;
+ temp.mode = mode;
+ temp.isRunning = false;
+ actionToDoListTransfer << temp;
+ //push the new transfer to interface
+ returnActionOnCopyList newAction;
+ newAction.type = AddingItem;
+ newAction.addAction.id = temp.id;
+ newAction.addAction.sourceFullPath = source.absoluteFilePath();
+ newAction.addAction.sourceFileName = source.fileName();
+ newAction.addAction.destinationFullPath = destination.absoluteFilePath();
+ newAction.addAction.destinationFileName = destination.fileName();
+ newAction.addAction.size = temp.size;
+ newAction.addAction.mode = mode;
+ actionDone << newAction;
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("source: %1, destination: %2, add entry: %3, size: %4, size2: %5").arg(source.absoluteFilePath()).arg(destination.absoluteFilePath()).arg(temp.id).arg(temp.size).arg(newAction.addAction.size));
+ return temp.id;
+}
+
+//generate id number
+quint64 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 QList<int> &ids)
+{
+ for(int i=0;i<ids.size();i++)
+ skipInternal(ids.at(i));
+// emit newActionOnList();
+}
+
+//put on top
+void ListThread::moveItemsOnTop(QList<int> ids)
+{
+ if(actionToDoListTransfer.size()<=1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"list size is empty");
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ //do list operation
+ int indexToMove=0;
+ loop_size=actionToDoListTransfer.size();
+ for (int i=0; i<loop_size; ++i) {
+ if(ids.contains(actionToDoListTransfer.at(i).id))
+ {
+ ids.removeOne(actionToDoListTransfer.at(i).id);
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("move item ")+QString::number(i)+" to "+QString::number(indexToMove));
+ returnActionOnCopyList newAction;
+ newAction.type=MoveItem;
+ newAction.addAction.id=actionToDoListTransfer.at(i).id;
+ newAction.userAction.moveAt=indexToMove;
+ newAction.userAction.position=i;
+ actionDone << newAction;
+ actionToDoListTransfer.move(i,indexToMove);
+ indexToMove++;
+ if(ids.size()==0)
+ {
+ //emit newActionOnList();
+ return;
+ }
+ }
+ }
+// emit newActionOnList();
+}
+
+//move up
+void ListThread::moveItemsUp(QList<int> ids)
+{
+ if(actionToDoListTransfer.size()<=1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"list size is empty");
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ //do list operation
+ int lastGoodPositionExtern=0;
+ int lastGoodPositionReal=0;
+ bool haveGoodPosition=false;
+ bool haveChanged=false;
+ loop_size=actionToDoListTransfer.size();
+ for (int i=0; i<loop_size; ++i) {
+ if(ids.contains(actionToDoListTransfer.at(i).id))
+ {
+ if(haveGoodPosition)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("move item ")+QString::number(i)+" to "+QString::number(i-1));
+ returnActionOnCopyList newAction;
+ newAction.type=MoveItem;
+ newAction.addAction.id=actionToDoListTransfer.at(i).id;
+ newAction.userAction.moveAt=lastGoodPositionExtern;
+ newAction.userAction.position=i;
+ actionDone << newAction;
+ actionToDoListTransfer.swap(i,lastGoodPositionReal);
+ haveChanged=true;
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("Try move up false, item ")+QString::number(i));
+ ids.removeOne(actionToDoListTransfer.at(i).id);
+ if(ids.size()==0)
+ {
+/* if(haveChanged)
+ emit newActionOnList();*/
+ return;
+ }
+ }
+ else
+ {
+ lastGoodPositionExtern++;
+ lastGoodPositionReal=i;
+ haveGoodPosition=true;
+ }
+ }
+ //emit newActionOnList();
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"stop");
+}
+
+//move down
+void ListThread::moveItemsDown(QList<int> ids)
+{
+ if(actionToDoListTransfer.size()<=1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"list size is empty");
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ //do list operation
+ int lastGoodPositionExtern=numberOfTransferIntoToDoList;
+ int lastGoodPositionReal=0;
+ bool haveGoodPosition=false;
+ bool haveChanged=false;
+ for (int i=actionToDoListTransfer.size()-1; i>=0; --i) {
+ if(ids.contains(actionToDoListTransfer.at(i).id))
+ {
+ if(haveGoodPosition)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("move item ")+QString::number(i)+" to "+QString::number(i+1));
+ returnActionOnCopyList newAction;
+ newAction.type=MoveItem;
+ newAction.addAction.id=actionToDoListTransfer.at(i).id;
+ newAction.userAction.moveAt=lastGoodPositionReal;
+ newAction.userAction.position=i;
+ actionDone << newAction;
+ actionToDoListTransfer.swap(i,lastGoodPositionReal);
+ haveChanged=true;
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("Try move up false, item ")+QString::number(i));
+ }
+ ids.removeOne(actionToDoListTransfer.at(i).id);
+ if(ids.size()==0)
+ {
+/* if(haveChanged)
+ emit newActionOnList();*/
+ return;
+ }
+ }
+ else
+ {
+ lastGoodPositionExtern--;
+ lastGoodPositionReal=i;
+ haveGoodPosition=true;
+ }
+ }
+ //emit newActionOnList();
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"stop");
+}
+
+//put on bottom
+void ListThread::moveItemsOnBottom(QList<int> ids)
+{
+ if(actionToDoListTransfer.size()<=1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"list size is empty");
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ //do list operation
+ int lastGoodPositionExtern=numberOfTransferIntoToDoList;
+ int lastGoodPositionReal=actionToDoListTransfer.size()-1;
+ for (int i=lastGoodPositionReal; i>=0; --i) {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("Check action on item ")+QString::number(i));
+ if(ids.contains(actionToDoListTransfer.at(i).id))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("move item ")+QString::number(i)+" to "+QString::number(lastGoodPositionReal));
+ ids.removeOne(actionToDoListTransfer.at(i).id);
+ returnActionOnCopyList newAction;
+ newAction.type=MoveItem;
+ newAction.addAction.id=actionToDoListTransfer.at(i).id;
+ newAction.userAction.moveAt=lastGoodPositionExtern;
+ newAction.userAction.position=i;
+ actionDone << newAction;
+ actionToDoListTransfer.move(i,lastGoodPositionReal);
+ lastGoodPositionReal--;
+ lastGoodPositionExtern--;
+ if(ids.size()==0)
+ {
+// emit newActionOnList();
+ return;
+ }
+ }
+ }
+// emit newActionOnList();
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"stop");
+}
+
+/** \brief give the forced mode, to export/import transfer list */
+void ListThread::forceMode(const CopyMode &mode)
+{
+ if(mode==Copy)
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("Force mode to copy"));
+ else
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("Force mode to move"));
+ this->mode=mode;
+ forcedMode=true;
+}
+
+void ListThread::exportTransferList(const QString &fileName)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ QFile transferFile(fileName);
+ if(transferFile.open(QIODevice::WriteOnly|QIODevice::Truncate))
+ {
+ transferFile.write(QString("Ultracopier-0.3;Transfer-list;").toUtf8());
+ if(!forcedMode)
+ transferFile.write(QString("Transfer;").toUtf8());
+ else
+ {
+ if(mode==Copy)
+ transferFile.write(QString("Copy;").toUtf8());
+ else
+ transferFile.write(QString("Move;").toUtf8());
+ }
+ transferFile.write(QString("Ultracopier-0.3\n").toUtf8());
+ bool haveError=false;
+ int size=actionToDoListTransfer.size();
+ for (int index=0;index<size;++index) {
+ if(actionToDoListTransfer.at(index).mode==Copy)
+ {
+ if(!forcedMode || mode==Copy)
+ {
+ if(forcedMode)
+ transferFile.write(QString("%1;%2\n").arg(actionToDoListTransfer.at(index).source.absoluteFilePath()).arg(actionToDoListTransfer.at(index).destination.absoluteFilePath()).toUtf8());
+ else
+ transferFile.write(QString("Copy;%1;%2\n").arg(actionToDoListTransfer.at(index).source.absoluteFilePath()).arg(actionToDoListTransfer.at(index).destination.absoluteFilePath()).toUtf8());
+ }
+ else
+ haveError=true;
+ }
+ else if(actionToDoListTransfer.at(index).mode==Move)
+ {
+ if(!forcedMode || mode==Move)
+ {
+ if(forcedMode)
+ transferFile.write(QString("Move;%1;%2\n").arg(actionToDoListTransfer.at(index).source.absoluteFilePath()).arg(actionToDoListTransfer.at(index).destination.absoluteFilePath()).toUtf8());
+ else
+ transferFile.write(QString("%1;%2\n").arg(actionToDoListTransfer.at(index).source.absoluteFilePath()).arg(actionToDoListTransfer.at(index).destination.absoluteFilePath()).toUtf8());
+ }
+ else
+ haveError=true;
+ }
+ }
+ if(haveError)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Unable do to move or copy item into wrong forced mode: %1").arg(transferFile.errorString()));
+ emit errorTransferList(tr("Unable do to move or copy item into wrong forced mode: %1").arg(transferFile.errorString()));
+ }
+ transferFile.close();
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Unable to save the transfer list: %1").arg(transferFile.errorString()));
+ emit errorTransferList(tr("Unable to save the transfer list: %1").arg(transferFile.errorString()));
+ return;
+ }
+}
+
+void ListThread::importTransferList(const QString &fileName)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ QFile transferFile(fileName);
+ if(transferFile.open(QIODevice::ReadOnly))
+ {
+ QString content;
+ QByteArray data=transferFile.readLine(64);
+ if(data.size()<=0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Problem at the reading, or file size is null"));
+ emit errorTransferList(tr("Problem at the reading, or file size is null"));
+ return;
+ }
+ content=QString::fromUtf8(data);
+ if(content!="Ultracopier-0.3;Transfer-list;Transfer;Ultracopier-0.3\n" && content!="Ultracopier-0.3;Transfer-list;Copy;Ultracopier-0.3\n" && content!="Ultracopier-0.3;Transfer-list;Move;Ultracopier-0.3\n")
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Wrong header: \"%1\"").arg(content));
+ emit errorTransferList(tr("Wrong header: \"%1\"").arg(content));
+ return;
+ }
+ bool transferListMixedMode=false;
+ if(content=="Ultracopier-0.3;Transfer-list;Transfer;Ultracopier-0.3\n")
+ {
+ if(forcedMode)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("The transfer list is in mixed mode, but this instance is not in this mode"));
+ emit errorTransferList(tr("The transfer list is in mixed mode, but this instance is not in this mode"));
+ return;
+ }
+ else
+ transferListMixedMode=true;
+ }
+ if(content=="Ultracopier-0.3;Transfer-list;Copy;Ultracopier-0.3\n" && (forcedMode && mode==Move))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("The transfer list is in copy mode, but this instance is not in this mode: forcedMode: %1, mode: %2").arg(forcedMode).arg(mode));
+ emit errorTransferList(tr("The transfer list is in copy mode, but this instance is not in this mode"));
+ return;
+ }
+ if(content=="Ultracopier-0.3;Transfer-list;Move;Ultracopier-0.3\n" && (forcedMode && mode==Copy))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("The transfer list is in move mode, but this instance is not in this mode: forcedMode: %1, mode: %2").arg(forcedMode).arg(mode));
+ emit errorTransferList(tr("The transfer list is in move mode, but this instance is not in this mode"));
+ return;
+ }
+ bool errorFound=false;
+ QRegExp correctLine;
+ if(transferListMixedMode)
+ correctLine=QRegExp("^(Copy|Move);[^;]+;[^;]+\n$");
+ else
+ correctLine=QRegExp("^[^;]+;[^;]+\n$");
+ QStringList args;
+ CopyMode tempMode;
+ do
+ {
+ data=transferFile.readLine(65535*2);
+ if(data.size()>0)
+ {
+ content=QString::fromUtf8(data);
+ //do the import here
+ if(content.contains(correctLine))
+ {
+ content.remove("\n");
+ args=content.split(";");
+ if(forcedMode)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("New data to import in forced mode: %2,%3").arg(args.at(0)).arg(args.at(1)));
+ addToTransfer(QFileInfo(args.at(0)),QFileInfo(args.at(1)),mode);
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("New data to import: %1,%2,%3").arg(args.at(0)).arg(args.at(1)).arg(args.at(2)));
+ if(args.at(0)=="Copy")
+ tempMode=Copy;
+ else
+ tempMode=Move;
+ addToTransfer(QFileInfo(args.at(1)),QFileInfo(args.at(2)),tempMode);
+ }
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Wrong line syntax: %1").arg(content));
+ errorFound=true;
+ }
+ }
+ }
+ while(data.size()>0);
+ transferFile.close();
+ if(errorFound)
+ emit warningTransferList(tr("Some error have been found during the line parsing"));
+// emit newActionOnList();
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("Unable to open the transfer list: %1").arg(transferFile.errorString()));
+ emit errorTransferList(tr("Unable to open the transfer list: %1").arg(transferFile.errorString()));
+ return;
+ }
+}
+
+//do new actions
+void ListThread::doNewActions_start_transfer()
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("actionToDoListTransfer.size(): %1, numberOfTranferRuning: %2").arg(actionToDoListTransfer.size()).arg(numberOfTranferRuning));
+ if(stopIt || putInPause)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ //lunch the transfer in WaitForTheTransfer
+ int_for_loop=0;
+ loop_size=transferThreadList.size();
+ while(int_for_loop<loop_size && numberOfTranferRuning<ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER)
+ {
+ if(transferThreadList.at(int_for_loop)->getStat()==TransferStat_WaitForTheTransfer)
+ {
+ transferThreadList.at(int_for_loop)->startTheTransfer();
+ numberOfTranferRuning++;
+ }
+ int_for_loop++;
+ }
+ int_for_loop=0;
+ while(int_for_loop<loop_size && numberOfTranferRuning<ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER)
+ {
+ if(transferThreadList.at(int_for_loop)->getStat()==TransferStat_PreOperation)
+ {
+ transferThreadList.at(int_for_loop)->startTheTransfer();
+ numberOfTranferRuning++;
+ }
+ int_for_loop++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"numberOfTranferRuning: "+QString::number(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()
+{
+ //ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("actionToDoList.size(): %1").arg(actionToDoList.size()));
+ if(stopIt || putInPause)
+ return;
+ //ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ //lunch the pre-op or inode op
+ int_for_loop=0;
+ int_for_internal_loop=0;
+ number_rm_path_moved=0;
+ int_for_transfer_thread_search=0;
+ actionToDoListTransfer_count=actionToDoListTransfer.count();
+ actionToDoListInode_count=actionToDoListInode.count();
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ //search the next transfer action to do
+ while(int_for_loop<actionToDoListTransfer_count)
+ {
+ if(!actionToDoListTransfer[int_for_loop].isRunning)
+ {
+ //search the next inode action to do
+ while(int_for_internal_loop<actionToDoListInode_count)
+ {
+ if(!actionToDoListInode[int_for_internal_loop].isRunning)
+ {
+ if(actionToDoListTransfer[int_for_loop].id<actionToDoListInode[int_for_internal_loop].id)
+ {
+ //do the tranfer action in the next code
+ break;
+ }
+ else
+ {
+ //do the inode action
+ #include "ListThread_InodeAction.cpp"
+ }
+ }
+ int_for_internal_loop++;
+ }
+ actionToDoTransfer& currentActionToDoTransfer=actionToDoListTransfer[int_for_loop];
+ //do the tranfer action
+ while(int_for_transfer_thread_search<loop_sub_size_transfer_thread_search)
+ {
+ /**
+ transferThreadList.at(int_for_transfer_thread_search)->transferId==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[int_for_transfer_thread_search];
+ if(currentTransferThread->getStat()==TransferStat_Idle && currentTransferThread->transferId==0) // /!\ important!
+ {
+ currentTransferThread->transferId=currentActionToDoTransfer.id;
+ currentTransferThread->transferSize=currentActionToDoTransfer.size;
+ currentTransferThread->setFiles(
+ currentActionToDoTransfer.source.absoluteFilePath(),
+ currentActionToDoTransfer.size,
+ currentActionToDoTransfer.destination.absoluteFilePath(),
+ currentActionToDoTransfer.mode
+ );
+ currentActionToDoTransfer.isRunning=true;
+
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("[%1] id: %2 is idle, use it for %3").arg(int_for_loop).arg(currentTransferThread->transferId).arg(currentActionToDoTransfer.destination.absoluteFilePath()));
+
+ /// \note wrong position? Else write why it's here
+ returnActionOnCopyList newAction;
+ newAction.type = PreOperation;
+ newAction.addAction.id = currentActionToDoTransfer.id;
+ newAction.addAction.sourceFullPath = currentActionToDoTransfer.source.absoluteFilePath();
+ newAction.addAction.sourceFileName = currentActionToDoTransfer.source.fileName();
+ newAction.addAction.destinationFullPath = currentActionToDoTransfer.destination.absoluteFilePath();
+ newAction.addAction.destinationFileName = currentActionToDoTransfer.destination.fileName();
+ newAction.addAction.size = currentActionToDoTransfer.size;
+ newAction.addAction.mode = currentActionToDoTransfer.mode;
+ actionDone << newAction;
+ int_for_transfer_thread_search++;
+ 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
+ //ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"unable to found free thread to do the transfer");
+ break;
+ }
+ numberOfInodeOperation++;
+ if(numberOfInodeOperation>=ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT)
+ return;
+ }
+ int_for_loop++;
+ }
+ //search the next inode action to do
+ while(int_for_internal_loop<actionToDoListInode_count)
+ {
+ if(!actionToDoListInode[int_for_internal_loop].isRunning)
+ {
+ //do the inode action
+ #include "ListThread_InodeAction.cpp"
+ }
+ int_for_internal_loop++;
+ }
+ //error checking
+ if((actionToDoListTransfer_count+actionToDoListInode_count)>ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,QString("The index have been detected as out of max range: %1>%2").arg(actionToDoListTransfer_count+actionToDoListInode_count).arg(ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT));
+ return;
+ }
+}
+
+//restart transfer if it can
+void ListThread::restartTransferIfItCan()
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start");
+ TransferThread *transfer=qobject_cast<TransferThread *>(QObject::sender());
+ if(transfer==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,QString("transfer thread not located!"));
+ return;
+ }
+ if(numberOfTranferRuning<ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER && transfer->getStat()==TransferStat_WaitForTheTransfer)
+ {
+ transfer->startTheTransfer();
+ numberOfTranferRuning++;
+ }
+ doNewActions_start_transfer();
+}
+
+/// \brief update the transfer stat
+void ListThread::newTransferStat(TransferStat stat,quint64 id)
+{
+ returnActionOnCopyList newAction;
+ switch(stat)
+ {
+ case TransferStat_Idle:
+ return;
+ break;
+ case TransferStat_PreOperation:
+ return;
+ break;
+ case TransferStat_WaitForTheTransfer:
+ return;
+ break;
+ case TransferStat_Transfer:
+ newAction.type=Transfer;
+ break;
+ case TransferStat_PostTransfer:
+ case TransferStat_PostOperation:
+ newAction.type=PostOperation;
+ break;
+ case TransferStat_Checksum:
+ newAction.type=CustomOperation;
+ break;
+ default:
+ return;
+ break;
+ }
+ newAction.addAction.id = id;
+ actionDone << newAction;
+}
+
+void ListThread::set_osBufferLimit(unsigned int osBufferLimit)
+{
+ this->osBufferLimit=osBufferLimit;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ transferThreadList.at(index)->set_osBufferLimit(osBufferLimit);
+ index++;
+ }
+}
+
+void ListThread::set_setFilters(QList<Filters_rules> include,QList<Filters_rules> exclude)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("include.size(): %1, exclude.size(): %2").arg(include.size()).arg(exclude.size()));
+ this->include=include;
+ this->exclude=exclude;
+ int index=0;
+ while(index<scanFileOrFolderThreadsPool.size())
+ {
+ scanFileOrFolderThreadsPool.at(index)->setFilters(include,exclude);
+ index++;
+ }
+}
+
+void ListThread::set_sendNewRenamingRules(QString firstRenamingRule,QString otherRenamingRule)
+{
+ this->firstRenamingRule=firstRenamingRule;
+ this->otherRenamingRule=otherRenamingRule;
+ emit send_sendNewRenamingRules(firstRenamingRule,otherRenamingRule);
+}
+
+void ListThread::mkPathFirstFolderFinish()
+{
+ int_for_loop=0;
+ loop_size=actionToDoListInode.size();
+ while(int_for_loop<loop_size)
+ {
+ if(actionToDoListInode.at(int_for_loop).type==ActionType_MkPath)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("stop mkpath: %1").arg(actionToDoListInode.at(int_for_loop).folder.absoluteFilePath()));
+ actionToDoListInode.removeAt(int_for_loop);
+ if(actionToDoListTransfer.size()==0 && actionToDoListInode.size()==0 && actionToDoListInode_afterTheTransfer.size()==0)
+ updateTheStatus();
+ numberOfInodeOperation--;
+ doNewActions_inode_manipulation();
+ return;
+ }
+ int_for_loop++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"unable to found item into the todo list");
+}
+
+void ListThread::rmPathFirstFolderFinish()
+{
+ int_for_loop=0;
+ loop_size=actionToDoListInode.size();
+ while(int_for_loop<loop_size)
+ {
+ if(actionToDoListInode.at(int_for_loop).type==ActionType_RmPath || actionToDoListInode.at(int_for_loop).type==ActionType_RmSync)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("stop rmpath: %1").arg(actionToDoListInode.at(int_for_loop).folder.absoluteFilePath()));
+ actionToDoListInode.removeAt(int_for_loop);
+ if(actionToDoListTransfer.size()==0 && actionToDoListInode.size()==0 && actionToDoListInode_afterTheTransfer.size()==0)
+ updateTheStatus();
+ numberOfInodeOperation--;
+ doNewActions_inode_manipulation();
+ return;
+ }
+ int_for_loop++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Critical,"unable to found item into the todo list");
+}
+
+#ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW
+
+void ListThread::timedUpdateDebugDialog()
+{
+ QStringList newList;
+ int index=0;
+ loop_sub_size_transfer_thread_search=transferThreadList.size();
+ while(index<loop_sub_size_transfer_thread_search)
+ {
+ QString stat;
+ switch(transferThreadList.at(index)->getStat())
+ {
+ 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=QString("??? (%1)").arg(transferThreadList.at(index)->getStat());
+ break;
+ }
+ newList << QString("%1) (%3,%4) %2")
+ .arg(index)
+ .arg(stat)
+ .arg(transferThreadList.at(index)->readingLetter())
+ .arg(transferThreadList.at(index)->writingLetter());
+ index++;
+ }
+ QStringList newList2;
+ index=0;
+ loop_size=actionToDoListTransfer.size();
+ while(index<loop_size)
+ {
+ newList2 << QString("%1 %2 %3")
+ .arg(actionToDoListTransfer.at(index).source.absoluteFilePath())
+ .arg(actionToDoListTransfer.at(index).size)
+ .arg(actionToDoListTransfer.at(index).destination.absoluteFilePath());
+ if(index>(actionToDoListTransfer.size()+2))
+ {
+ newList2 << QString("...");
+ 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<TransferThread *>(sender()));
+}
+
+/// \note Can be call without queue because all call will be serialized
+void ListThread::errorOnFile(const QFileInfo &fileInfo,const QString &errorString)
+{
+ emit send_errorOnFile(fileInfo,errorString,qobject_cast<TransferThread *>(sender()));
+}
+
+/// \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<scanFileOrFolder *>(sender()));
+}
+
+/// \note Can be call without queue because all call will be serialized
+/// \todo all this part
+void ListThread::errorOnFolder(const QFileInfo &fileInfo,const QString &errorString)
+{
+ emit send_errorOnFolder(fileInfo,errorString,qobject_cast<scanFileOrFolder *>(sender()));
+}
+
+//to run the thread
+void ListThread::run()
+{
+ exec();
+}
+
+/// \to create transfer thread
+void ListThread::createTransferThread()
+{
+ if(stopIt)
+ return;
+ transferThreadList << new TransferThread();
+ TransferThread * last=transferThreadList.last();
+ last->transferId=0;
+ last->transferSize=0;
+ last->setRightTransfer(doRightTransfer);
+ last->setKeepDate(keepDate);
+ last->setBlockSize(blockSize);
+ last->setDrive(drives);
+ last->setAlwaysFileExistsAction(alwaysDoThisActionForFileExists);
+ last->setMaxSpeed(maxSpeed/ULTRACOPIER_PLUGIN_MAXPARALLELTRANFER);
+ 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->setRsync(rsync);
+
+ #ifdef ULTRACOPIER_PLUGIN_DEBUG
+ connect(last,SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)),this,SIGNAL(debugInformation(DebugLevel,QString,QString,QString,int)), Qt::QueuedConnection);
+ #endif // ULTRACOPIER_PLUGIN_DEBUG
+ connect(last,SIGNAL(errorOnFile(QFileInfo,QString)), this,SLOT(errorOnFile(QFileInfo,QString)), Qt::QueuedConnection);
+ connect(last,SIGNAL(fileAlreadyExists(QFileInfo,QFileInfo,bool)), this,SLOT(fileAlreadyExists(QFileInfo,QFileInfo,bool)), Qt::QueuedConnection);
+ connect(last,SIGNAL(tryPutAtBottom()), this,SLOT(transferPutAtBottom()), Qt::QueuedConnection);
+ connect(last,SIGNAL(readStopped()), this,SLOT(transferIsFinished()), Qt::QueuedConnection);
+ connect(last,SIGNAL(preOperationStopped()), this,SLOT(doNewActions_start_transfer()), Qt::QueuedConnection);
+ connect(last,SIGNAL(postOperationStopped()), this,SLOT(transferInodeIsClosed()), Qt::QueuedConnection);
+ connect(last,SIGNAL(checkIfItCanBeResumed()), this,SLOT(restartTransferIfItCan()), Qt::QueuedConnection);
+ connect(last,SIGNAL(pushStat(TransferStat,quint64)), this,SLOT(newTransferStat(TransferStat,quint64)), Qt::QueuedConnection);
+
+ connect(this,SIGNAL(send_sendNewRenamingRules(QString,QString)), last,SLOT(setRenamingRules(QString,QString)), Qt::QueuedConnection);
+
+ last->start();
+ last->setObjectName(QString("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()>=ULTRACOPIER_PLUGIN_MAXPARALLELINODEOPT)
+ return;
+ if(stopIt)
+ return;
+ doNewActions_inode_manipulation();
+ emit askNewTransferThread();
+}