/** \file ListThread.h \brief Define the list thread, and management to the action to do \author alpha_one_x86 \version 0.3 \date 2011 */ #ifndef LISTTHREAD_H #define LISTTHREAD_H #include #include #include #include #include #include #include #include #include "../../../interface/PluginInterface_CopyEngine.h" #include "scanFileOrFolder.h" #include "TransferThread.h" #include "MkPath.h" #include "RmPath.h" #include "Environment.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(QStringList 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(QString destination); //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(QStringList sources,QString 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(QStringList sources,QString destination); /** \brief get the speed limitation * < -1 if not able, 0 if disabled */ qint64 getSpeedLimitation(); /** \brief to set drives detected * specific to this copy engine */ void setDrive(QStringList drives); /// \brief to set the collision action void setCollisionAction(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 { quint64 id; qint64 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; CopyMode mode; bool isRunning;///< store if the action si running //TransferThread * transfer; // -> see transferThreadList }; QList actionToDoListTransfer; /// \brief get action type enum ActionType { ActionType_MkPath=1, ActionType_RmPath=2, ActionType_RmSync=3 }; /// \brief to store one action to do struct actionToDoInode { ActionType type;///< \see ActionType quint64 id; qint64 size;///< Used to set: used in case of transfer or remainingInode for drop folder QFileInfo folder;///< Used to set: source for transfer, folder to create, folder to drop bool isRunning;///< store if the action si running }; QList actionToDoListInode; QList actionToDoListInode_afterTheTransfer; int numberOfInodeOperation; //dir operation thread queue MkPath mkPathQueue; RmPath rmPathQueue; //to get the return value from copyEngine bool getReturnBoolToCopyEngine(); QPair getReturnPairQuint64ToCopyEngine(); ItemOfCopyList getReturnItemOfCopyListToCopyEngine(); 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); 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 quint64 &id); /** \brief skip as interanl one transfer entry * \param id id of the file to remove */ bool skipInternal(const quint64 &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 QList &ids); /** \brief move on top of the list the selected item * \param ids ids is the id list of the selected items */ void moveItemsOnTop(QList ids); /** \brief move up the list the selected item * \param ids ids is the id list of the selected items */ void moveItemsUp(QList ids); /** \brief move down the list the selected item * \param ids ids is the id list of the selected items */ void moveItemsDown(QList ids); /** \brief move on bottom of the list the selected item * \param ids ids is the id list of the selected items */ void moveItemsOnBottom(QList ids); /** \brief give the forced mode, to export/import transfer list */ void forceMode(const CopyMode &mode); /// \brief export the transfer list into a file void exportTransferList(const QString &fileName); /// \brief import the transfer list into a file void importTransferList(const QString &fileName); /// \brief set the folder local colision void setFolderColision(FolderExistsAction alwaysDoThisActionForFolderExists); /** \brief to set the speed limitation * -1 if not able, 0 if disabled */ bool setSpeedLimitation(const qint64 &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); /// \brief set rsync void setRsync(const bool rsync); /// \brief set check destination folder void setCheckDestinationFolderExists(const bool checkDestinationFolderExists); /// \brief set data local to the thread void setAlwaysFileExistsAction(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(); /// \brief update the transfer stat void newTransferStat(TransferStat stat,quint64 id); void set_osBufferLimit(unsigned int osBufferLimit); void set_setFilters(QList include,QList exclude); void set_sendNewRenamingRules(QString firstRenamingRule,QString otherRenamingRule); //send action done void sendActionDone(); //send progression void sendProgression(); private: QSemaphore mkpathTransfer; QString sourceDrive; bool sourceDriveMultiple; bool stopIt; QString destinationDrive; bool destinationDriveMultiple; QList scanFileOrFolderThreadsPool; int numberOfTransferIntoToDoList; QList transferThreadList; scanFileOrFolder * newScanThread(CopyMode mode); quint64 bytesToTransfer; quint64 bytesTransfered; bool autoStart; bool rsync; bool putInPause; QList actionDone;///< to action to send to the interface quint64 idIncrementNumber;///< to store the last id returned qint64 actualRealByteTransfered; int preOperationNumber; int numberOfTranferRuning; 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 osBufferLimit; QList include,exclude; CopyMode mode; bool forcedMode; QString firstRenamingRule; QString otherRenamingRule; //add file transfer to do quint64 addToTransfer(const QFileInfo& source,const QFileInfo& destination,const CopyMode& mode); //generate id number quint64 generateIdNumber(); //warning the first entry is accessible will copy bool removeItems(quint64 id); //put on top bool moveOnTopItem(quint64 id); //move up bool moveUpItem(quint64 id); //move down bool moveDownItem(quint64 id); //put on bottom bool moveOnBottomItem(quint64 id); //general transfer void startGeneralTransfer(); //debug windows if needed #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW QTimer timerUpdateDebugDialog; #endif FacilityInterface * facilityInterface; //temp variable for not always alocate the memory int int_for_loop,int_for_internal_loop,int_for_transfer_thread_search,loop_size,loop_sub_size,loop_sub_size_transfer_thread_search,number_rm_path_moved; TransferThread *temp_transfer_thread; bool isFound; bool updateTheStatus_listing,updateTheStatus_copying; EngineActionInProgress updateTheStatus_action_in_progress; QSemaphore waitConstructor,waitCancel; int actionToDoListTransfer_count,actionToDoListInode_count; bool doTransfer,doInode; qint64 oversize;//used as temp variable qint64 currentProgression; qint64 copiedSize,totalSize,localOverSize; QList progressionList; TransferThread* currentTransferThread; //memory variable for transfer thread creation bool doRightTransfer; bool keepDate; int blockSize; QStringList drives; FileExistsAction alwaysDoThisActionForFileExists; //to return value to the copyEngine bool returnBoolToCopyEngine; QPair returnPairQuint64ToCopyEngine; QList returnListItemOfCopyListToCopyEngine; ItemOfCopyList returnItemOfCopyListToCopyEngine; ProgressionItem tempItem; void realByteTransfered(); private slots: void scanThreadHaveFinish(bool skipFirstRemove=false); void updateTheStatus(); void fileTransfer(const QFileInfo &sourceFileInfo,const QFileInfo &destinationFileInfo,const CopyMode &mode); //mkpath event void mkPathFirstFolderFinish(); //rmpath event void rmPathFirstFolderFinish(); //transfer is finished void transferIsFinished(); /** \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 QString &errorString); /// \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 QString &errorString); //to run the thread void run(); /// \to create transfer thread void createTransferThread(); //mk path to do quint64 addToMkPath(const QString& folder); //add rm path to do void addToRmPath(const QString& folder,const int& inodeToRemove); //rsync rm void addToRmForRsync(const QString& inode); //send the progression, after full reset of the interface (then all is empty) void syncTransferList_internal(); signals: //send information about the copy void actionInProgess(EngineActionInProgress); //should update interface information on this event void newActionOnList(const QList &);///very important, need be temporized to group the modification to do and not flood the interface void syncReady(); /** \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 QList &progressionList); //get information about the copy /** \brief to get the general progression * first = current transfered byte, second = byte to transfer */ void pushGeneralProgression(const quint64 &,const quint64 &); void newFolderListing(const QString &path); void newCollisionAction(QString action); void newErrorAction(QString action); void isInPause(bool); //when can be deleted void canBeDeleted(); //send error occurred void error(QString path,quint64 size,QDateTime mtime,QString error); //for the extra logging void rmPath(QString path); void mkPath(QString path); /// \brief To debug source #ifdef ULTRACOPIER_PLUGIN_DEBUG void debugInformation(DebugLevel level,QString fonction,QString text,QString file,int ligne); #endif #ifdef ULTRACOPIER_PLUGIN_DEBUG_WINDOW void updateTheDebugInfo(QStringList,QStringList,int); #endif //other signal /// \note Can be call without queue because all call will be serialized void send_fileAlreadyExists(QFileInfo source,QFileInfo destination,bool isSame,TransferThread * thread); /// \note Can be call without queue because all call will be serialized void send_errorOnFile(QFileInfo fileInfo,QString errorString,TransferThread * thread); /// \note Can be call without queue because all call will be serialized void send_folderAlreadyExists(QFileInfo source,QFileInfo destination,bool isSame,scanFileOrFolder * thread); /// \note Can be call without queue because all call will be serialized void send_errorOnFolder(QFileInfo fileInfo,QString errorString,scanFileOrFolder * thread); //send the progression void send_syncTransferList(); //mkpath error event void mkPathErrorOnFolder(QFileInfo fileInfo,QString errorString); //rmpath error event void rmPathErrorOnFolder(QFileInfo fileInfo,QString errorString); //to close void tryCancel(); //to ask new transfer thread void askNewTransferThread(); void warningTransferList(QString warning); void errorTransferList(QString error); void send_sendNewRenamingRules(QString firstRenamingRule,QString otherRenamingRule); void send_realBytesTransfered(quint64); }; #endif // LISTTHREAD_H