diff options
Diffstat (limited to 'synchronization.cpp')
-rw-r--r-- | synchronization.cpp | 361 |
1 files changed, 212 insertions, 149 deletions
diff --git a/synchronization.cpp b/synchronization.cpp index b8f2d6a6..43bf22a6 100644 --- a/synchronization.cpp +++ b/synchronization.cpp @@ -17,48 +17,18 @@ using namespace FreeFileSync; inline -SyncConfiguration::Direction getSyncDirection(const CompareFilesResult cmpResult, const SyncConfiguration& config) -{ - switch (cmpResult) - { - case FILE_LEFT_SIDE_ONLY: - return config.exLeftSideOnly; - break; - - case FILE_RIGHT_SIDE_ONLY: - return config.exRightSideOnly; - break; - - case FILE_RIGHT_NEWER: - return config.rightNewer; - break; - - case FILE_LEFT_NEWER: - return config.leftNewer; - break; - - case FILE_DIFFERENT: - return config.different; - break; - - default: - return SyncConfiguration::SYNC_DIR_NONE; - } -} - - -inline bool getBytesToTransfer(const FileCompareLine& fileCmpLine, - const SyncConfiguration& config, int& objectsToCreate, int& objectsToOverwrite, int& objectsToDelete, + int& conflicts, wxULongLong& dataToProcess) { //return false if nothing has to be done objectsToCreate = 0; //always initialize variables objectsToOverwrite = 0; objectsToDelete = 0; + conflicts = 0; dataToProcess = 0; //do not add filtered entries @@ -70,93 +40,101 @@ bool getBytesToTransfer(const FileCompareLine& fileCmpLine, { case FILE_LEFT_SIDE_ONLY: //get data to process - switch (getSyncDirection(fileCmpLine.cmpResult, config)) + switch (fileCmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //delete file on left + case SYNC_DIR_LEFT: //delete file on left dataToProcess = 0; objectsToDelete = 1; - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //copy from left to right + return true; + case SYNC_DIR_RIGHT: //copy from left to right dataToProcess = fileCmpLine.fileDescrLeft.fileSize; objectsToCreate = 1; - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_UNRESOLVED_CONFLICT: + assert(false); //conflicts have files on both sides + conflicts = 1; + return true; + case SYNC_DIR_NONE: return false; } - break; case FILE_RIGHT_SIDE_ONLY: - switch (getSyncDirection(fileCmpLine.cmpResult, config)) + switch (fileCmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //copy from right to left + case SYNC_DIR_LEFT: //copy from right to left dataToProcess = fileCmpLine.fileDescrRight.fileSize; objectsToCreate = 1; - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //delete file on right + return true; + case SYNC_DIR_RIGHT: //delete file on right dataToProcess = 0; objectsToDelete = 1; - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_UNRESOLVED_CONFLICT: + assert(false); //conflicts have files on both sides + conflicts = 1; + return true; + case SYNC_DIR_NONE: return false; } - break; case FILE_LEFT_NEWER: case FILE_RIGHT_NEWER: case FILE_DIFFERENT: + case FILE_CONFLICT: //get data to process - switch (getSyncDirection(fileCmpLine.cmpResult, config)) + switch (fileCmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //copy from right to left + case SYNC_DIR_LEFT: //copy from right to left dataToProcess = fileCmpLine.fileDescrRight.fileSize; objectsToOverwrite = 1; - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //copy from left to right + return true; + case SYNC_DIR_RIGHT: //copy from left to right dataToProcess = fileCmpLine.fileDescrLeft.fileSize; objectsToOverwrite = 1; - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_UNRESOLVED_CONFLICT: + conflicts = 1; + return true; + case SYNC_DIR_NONE: return false; } - break; case FILE_EQUAL: return false; - - default: - assert(false); - return false; }; - return true; + return true; //dummy } //runs at folder pair level void calcBytesToSync(const FileComparison& fileCmp, - const SyncConfiguration& config, int& objectsToCreate, int& objectsToOverwrite, int& objectsToDelete, + int& conflicts, wxULongLong& dataToProcess) { objectsToCreate = 0; objectsToOverwrite = 0; objectsToDelete = 0; + conflicts = 0; dataToProcess = 0; - int toCreate = 0; - int toOverwrite = 0; - int toDelete = 0; + int toCreate = 0; + int toOverwrite = 0; + int toDelete = 0; + int newConflicts = 0; wxULongLong data; for (FileComparison::const_iterator i = fileCmp.begin(); i != fileCmp.end(); ++i) { //only sum up sizes of files AND directories - if (getBytesToTransfer(*i, config, toCreate, toOverwrite, toDelete, data)) + if (getBytesToTransfer(*i, toCreate, toOverwrite, toDelete, newConflicts, data)) { objectsToCreate += toCreate; objectsToOverwrite += toOverwrite; objectsToDelete += toDelete; + conflicts += newConflicts; dataToProcess += data; } } @@ -165,15 +143,16 @@ void calcBytesToSync(const FileComparison& fileCmp, //aggregate over all folder pairs void FreeFileSync::calcTotalBytesToSync(const FolderComparison& folderCmp, - const SyncConfiguration& config, int& objectsToCreate, int& objectsToOverwrite, int& objectsToDelete, + int& conflicts, wxULongLong& dataToProcess) { objectsToCreate = 0; objectsToOverwrite = 0; objectsToDelete = 0; + conflicts = 0; dataToProcess = 0; for (FolderComparison::const_iterator j = folderCmp.begin(); j != folderCmp.end(); ++j) @@ -183,20 +162,22 @@ void FreeFileSync::calcTotalBytesToSync(const FolderComparison& folderCmp, int toCreate = 0; int toOverwrite = 0; int toDelete = 0; + int newConflics = 0; wxULongLong data; - calcBytesToSync(fileCmp, config, toCreate, toOverwrite, toDelete, data); + calcBytesToSync(fileCmp, toCreate, toOverwrite, toDelete, newConflics, data); objectsToCreate += toCreate; objectsToOverwrite += toOverwrite; objectsToDelete += toDelete; + conflicts += newConflics; dataToProcess += data; } } template <bool recyclerUsed> -std::pair<wxLongLong, wxLongLong> spaceNeededSub(const FileComparison& fileCmp, const SyncConfiguration& config) +std::pair<wxLongLong, wxLongLong> spaceNeededSub(const FileComparison& fileCmp) { wxLongLong spaceNeededLeft; wxLongLong spaceNeededRight; @@ -206,21 +187,22 @@ std::pair<wxLongLong, wxLongLong> spaceNeededSub(const FileComparison& fileCmp, if (i->selectedForSynchronization) //do not add filtered entries { //get data to process - switch (getSyncDirection(i->cmpResult, config)) + switch (i->direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //copy from right to left + case SYNC_DIR_LEFT: //copy from right to left if (!recyclerUsed) spaceNeededLeft -= globalFunctions::convertToSigned(i->fileDescrLeft.fileSize); spaceNeededLeft += globalFunctions::convertToSigned(i->fileDescrRight.fileSize); break; - case SyncConfiguration::SYNC_DIR_RIGHT: //copy from left to right + case SYNC_DIR_RIGHT: //copy from left to right if (!recyclerUsed) spaceNeededRight -= globalFunctions::convertToSigned(i->fileDescrRight.fileSize); spaceNeededRight += globalFunctions::convertToSigned(i->fileDescrLeft.fileSize); break; - case SyncConfiguration::SYNC_DIR_NONE: + case SYNC_DIR_NONE: + case SYNC_UNRESOLVED_CONFLICT: break; } } @@ -230,49 +212,108 @@ std::pair<wxLongLong, wxLongLong> spaceNeededSub(const FileComparison& fileCmp, } -std::pair<wxLongLong, wxLongLong> freeDiskSpaceNeeded(const FileComparison& fileCmp, const SyncConfiguration& config, const bool recyclerUsed) +std::pair<wxLongLong, wxLongLong> freeDiskSpaceNeeded(const FileComparison& fileCmp, const bool recyclerUsed) { if (recyclerUsed) - return spaceNeededSub<true>(fileCmp, config); + return spaceNeededSub<true>(fileCmp); else - return spaceNeededSub<false>(fileCmp, config); + return spaceNeededSub<false>(fileCmp); +} + + +bool unresolvedConflictsExisting(const FolderComparison& folderCmp) +{ + for (FolderComparison::const_iterator j = folderCmp.begin(); j != folderCmp.end(); ++j) + { + const FileComparison& fileCmp = j->fileCmp; + for (FileComparison::const_iterator i = fileCmp.begin(); i != fileCmp.end(); ++i) + if (i->direction == SYNC_UNRESOLVED_CONFLICT) + return true; + } + return false; } -bool FreeFileSync::synchronizationNeeded(const FolderComparison& folderCmp, const SyncConfiguration& config) +bool FreeFileSync::synchronizationNeeded(const FolderComparison& folderCmp) { int objectsToCreate = 0; int objectsToOverwrite = 0; int objectsToDelete = 0; + int conflicts = 0; wxULongLong dataToProcess; FreeFileSync::calcTotalBytesToSync(folderCmp, - config, objectsToCreate, objectsToOverwrite, objectsToDelete, + conflicts, dataToProcess); - return objectsToCreate + objectsToOverwrite + objectsToDelete != 0; + return objectsToCreate + objectsToOverwrite + objectsToDelete + conflicts != 0; +} + + +void FreeFileSync::redetermineSyncDirection(const SyncConfiguration& config, FolderComparison& folderCmp) +{ + //do not handle i->selectedForSynchronization in this method! handled in synchronizeFile(), synchronizeFolder()! + + + for (FolderComparison::iterator j = folderCmp.begin(); j != folderCmp.end(); ++j) + { + FileComparison& fileCmp = j->fileCmp; + for (FileComparison::iterator i = fileCmp.begin(); i != fileCmp.end(); ++i) + { + switch (i->cmpResult) + { + case FILE_LEFT_SIDE_ONLY: + i->direction = config.exLeftSideOnly; + break; + + case FILE_RIGHT_SIDE_ONLY: + i->direction = config.exRightSideOnly; + break; + + case FILE_RIGHT_NEWER: + i->direction = config.rightNewer; + break; + + case FILE_LEFT_NEWER: + i->direction = config.leftNewer; + break; + + case FILE_DIFFERENT: + i->direction = config.different; + break; + + case FILE_CONFLICT: + i->direction = SYNC_UNRESOLVED_CONFLICT; + break; + + case FILE_EQUAL: + i->direction = SYNC_DIR_NONE; + } + } + } } //test if more then 50% of files will be deleted/overwritten -bool significantDifferenceDetected(const FileComparison& fileCmp, const SyncConfiguration& config) +bool significantDifferenceDetected(const FileComparison& fileCmp) { int objectsToCreate = 0; int objectsToOverwrite = 0; int objectsToDelete = 0; + int conflicts = 0; wxULongLong dataToProcess; calcBytesToSync(fileCmp, - config, objectsToCreate, objectsToOverwrite, objectsToDelete, + conflicts, dataToProcess); - const int changedFiles = objectsToCreate + objectsToOverwrite + objectsToDelete; //include objectsToCreate also! + const int changedFiles = objectsToCreate + objectsToOverwrite + objectsToDelete + conflicts; //include objectsToCreate also! return changedFiles >= 10 && changedFiles > 0.5 * fileCmp.size(); } @@ -283,12 +324,14 @@ SyncProcess::SyncProcess(const bool useRecycler, const bool traverseDirSymLinks, bool& warningSignificantDifference, bool& warningNotEnoughDiskSpace, + bool& warningUnresolvedConflict, StatusHandler* handler) : m_useRecycleBin(useRecycler), m_copyFileSymLinks(copyFileSymLinks), m_traverseDirSymLinks(traverseDirSymLinks), m_warningSignificantDifference(warningSignificantDifference), m_warningNotEnoughDiskSpace(warningNotEnoughDiskSpace), + m_warningUnresolvedConflict(warningUnresolvedConflict), statusUpdater(handler), txtCopyingFile(Zstring(_("Copying file %x to %y")).Replace(wxT("%x"), wxT("\"%x\""), false).Replace(wxT("%y"), wxT("\n\"%y\""), false)), txtOverwritingFile(Zstring(_("Copying file %x to %y overwriting target")).Replace(wxT("%x"), wxT("\"%x\""), false).Replace(wxT("%y"), wxT("\n\"%y\""), false)), @@ -298,7 +341,7 @@ SyncProcess::SyncProcess(const bool useRecycler, inline -bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const SyncConfiguration& config, const FolderPair& folderPair) +bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const FolderPair& folderPair) { //return false if nothing had to be done if (!cmpLine.selectedForSynchronization) return false; @@ -310,16 +353,16 @@ bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const SyncConf switch (cmpLine.cmpResult) { case FILE_LEFT_SIDE_ONLY: - switch (config.exLeftSideOnly) + switch (cmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //delete files on left + case SYNC_DIR_LEFT: //delete files on left statusText = txtDeletingFile; statusText.Replace(wxT("%x"), cmpLine.fileDescrLeft.fullName, false); statusUpdater->updateStatusText(statusText); removeFile(cmpLine.fileDescrLeft.fullName, m_useRecycleBin); - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //copy files to right + return true; + case SYNC_DIR_RIGHT: //copy files to right target = folderPair.rightDirectory + cmpLine.fileDescrLeft.relativeName.c_str(); statusText = txtCopyingFile; @@ -328,16 +371,16 @@ bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const SyncConf statusUpdater->updateStatusText(statusText); copyFileUpdating(cmpLine.fileDescrLeft.fullName, target, cmpLine.fileDescrLeft.fileSize); - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_DIR_NONE: + case SYNC_UNRESOLVED_CONFLICT: return false; } - break; case FILE_RIGHT_SIDE_ONLY: - switch (config.exRightSideOnly) + switch (cmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //copy files to left + case SYNC_DIR_LEFT: //copy files to left target = folderPair.leftDirectory + cmpLine.fileDescrRight.relativeName.c_str(); statusText = txtCopyingFile; @@ -346,25 +389,26 @@ bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const SyncConf statusUpdater->updateStatusText(statusText); copyFileUpdating(cmpLine.fileDescrRight.fullName, target, cmpLine.fileDescrRight.fileSize); - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //delete files on right + return true; + case SYNC_DIR_RIGHT: //delete files on right statusText = txtDeletingFile; statusText.Replace(wxT("%x"), cmpLine.fileDescrRight.fullName, false); statusUpdater->updateStatusText(statusText); removeFile(cmpLine.fileDescrRight.fullName, m_useRecycleBin); - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_DIR_NONE: + case SYNC_UNRESOLVED_CONFLICT: return false; } - break; case FILE_LEFT_NEWER: case FILE_RIGHT_NEWER: case FILE_DIFFERENT: - switch (getSyncDirection(cmpLine.cmpResult, config)) + case FILE_CONFLICT: + switch (cmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //copy from right to left + case SYNC_DIR_LEFT: //copy from right to left statusText = txtOverwritingFile; statusText.Replace(wxT("%x"), cmpLine.fileDescrRight.fullName.AfterLast(GlobalResources::FILE_NAME_SEPARATOR), false); statusText.Replace(wxT("%y"), cmpLine.fileDescrLeft.fullName.BeforeLast(GlobalResources::FILE_NAME_SEPARATOR), false); @@ -372,8 +416,8 @@ bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const SyncConf removeFile(cmpLine.fileDescrLeft.fullName, m_useRecycleBin); //only used if switch activated by user, else file is simply deleted copyFileUpdating(cmpLine.fileDescrRight.fullName, cmpLine.fileDescrLeft.fullName, cmpLine.fileDescrRight.fileSize); - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //copy from left to right + return true; + case SYNC_DIR_RIGHT: //copy from left to right statusText = txtOverwritingFile; statusText.Replace(wxT("%x"), cmpLine.fileDescrLeft.fullName.AfterLast(GlobalResources::FILE_NAME_SEPARATOR), false); statusText.Replace(wxT("%y"), cmpLine.fileDescrRight.fullName.BeforeLast(GlobalResources::FILE_NAME_SEPARATOR), false); @@ -381,24 +425,22 @@ bool SyncProcess::synchronizeFile(const FileCompareLine& cmpLine, const SyncConf removeFile(cmpLine.fileDescrRight.fullName, m_useRecycleBin); //only used if switch activated by user, else file is simply deleted copyFileUpdating(cmpLine.fileDescrLeft.fullName, cmpLine.fileDescrRight.fullName, cmpLine.fileDescrLeft.fileSize); - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_DIR_NONE: + case SYNC_UNRESOLVED_CONFLICT: return false; } - break; case FILE_EQUAL: return false; - - default: - assert (false); } - return true; + + return false; //dummy } inline -bool SyncProcess::synchronizeFolder(const FileCompareLine& cmpLine, const SyncConfiguration& config, const FolderPair& folderPair) +bool SyncProcess::synchronizeFolder(const FileCompareLine& cmpLine, const FolderPair& folderPair) { //return false if nothing had to be done if (!cmpLine.selectedForSynchronization) return false; @@ -410,16 +452,16 @@ bool SyncProcess::synchronizeFolder(const FileCompareLine& cmpLine, const SyncCo switch (cmpLine.cmpResult) { case FILE_LEFT_SIDE_ONLY: - switch (config.exLeftSideOnly) + switch (cmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //delete folders on left + case SYNC_DIR_LEFT: //delete folders on left statusText = txtDeletingFolder; statusText.Replace(wxT("%x"), cmpLine.fileDescrLeft.fullName, false); statusUpdater->updateStatusText(statusText); removeDirectory(cmpLine.fileDescrLeft.fullName, m_useRecycleBin); - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //create folders on right + return true; + case SYNC_DIR_RIGHT: //create folders on right target = folderPair.rightDirectory + cmpLine.fileDescrLeft.relativeName.c_str(); statusText = txtCreatingFolder; @@ -430,16 +472,16 @@ bool SyncProcess::synchronizeFolder(const FileCompareLine& cmpLine, const SyncCo if (!wxDirExists(cmpLine.fileDescrLeft.fullName)) throw FileError(Zstring(_("Error: Source directory does not exist anymore:")) + wxT("\n\"") + cmpLine.fileDescrLeft.fullName + wxT("\"")); createDirectory(target, cmpLine.fileDescrLeft.fullName, !m_traverseDirSymLinks); //traverse symlinks <=> !copy symlinks - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_DIR_NONE: + case SYNC_UNRESOLVED_CONFLICT: return false; } - break; case FILE_RIGHT_SIDE_ONLY: - switch (config.exRightSideOnly) + switch (cmpLine.direction) { - case SyncConfiguration::SYNC_DIR_LEFT: //create folders on left + case SYNC_DIR_LEFT: //create folders on left target = folderPair.leftDirectory + cmpLine.fileDescrRight.relativeName.c_str(); statusText = txtCreatingFolder; @@ -450,18 +492,18 @@ bool SyncProcess::synchronizeFolder(const FileCompareLine& cmpLine, const SyncCo if (!wxDirExists(cmpLine.fileDescrRight.fullName)) throw FileError(Zstring(_("Error: Source directory does not exist anymore:")) + wxT("\n\"") + cmpLine.fileDescrRight.fullName + wxT("\"")); createDirectory(target, cmpLine.fileDescrRight.fullName, !m_traverseDirSymLinks); //traverse symlinks <=> !copy symlinks - break; - case SyncConfiguration::SYNC_DIR_RIGHT: //delete folders on right + return true; + case SYNC_DIR_RIGHT: //delete folders on right statusText = txtDeletingFolder; statusText.Replace(wxT("%x"), cmpLine.fileDescrRight.fullName, false); statusUpdater->updateStatusText(statusText); removeDirectory(cmpLine.fileDescrRight.fullName, m_useRecycleBin); - break; - case SyncConfiguration::SYNC_DIR_NONE: + return true; + case SYNC_DIR_NONE: + case SYNC_UNRESOLVED_CONFLICT: return false; } - break; case FILE_EQUAL: return false; @@ -469,18 +511,20 @@ bool SyncProcess::synchronizeFolder(const FileCompareLine& cmpLine, const SyncCo case FILE_RIGHT_NEWER: case FILE_LEFT_NEWER: case FILE_DIFFERENT: - default: + case FILE_CONFLICT: assert (false); + return false; } - return true; + + return false; //dummy } inline -bool deletionImminent(const FileCompareLine& line, const SyncConfiguration& config) +bool deletionImminent(const FileCompareLine& line) { //test if current sync-line will result in deletion of files -> used to avoid disc space bottlenecks - if ( (line.cmpResult == FILE_LEFT_SIDE_ONLY && config.exLeftSideOnly == SyncConfiguration::SYNC_DIR_LEFT) || - (line.cmpResult == FILE_RIGHT_SIDE_ONLY && config.exRightSideOnly == SyncConfiguration::SYNC_DIR_RIGHT)) + if ( (line.cmpResult == FILE_LEFT_SIDE_ONLY && line.direction == SYNC_DIR_LEFT) || + (line.cmpResult == FILE_RIGHT_SIDE_ONLY && line.direction == SYNC_DIR_RIGHT)) return true; else return false; @@ -510,12 +554,30 @@ private: //synchronize and returns all rows that have not been synced -void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const SyncConfiguration& config) +void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp) { #ifndef __WXDEBUG__ wxLogNull noWxLogs; //prevent wxWidgets logging #endif + //inform about the total amount of data that will be processed from now on + int objectsToCreate = 0; + int objectsToOverwrite = 0; + int objectsToDelete = 0; + int conflicts = 0; + wxULongLong dataToProcess; + + FreeFileSync::calcTotalBytesToSync(folderCmp, + objectsToCreate, + objectsToOverwrite, + objectsToDelete, + conflicts, + dataToProcess); + + statusUpdater->initNewProcess(objectsToCreate + objectsToOverwrite + objectsToDelete, //keep at beginning so that all gui elements are initialized properly + globalFunctions::convertToSigned(dataToProcess), + StatusHandler::PROCESS_SYNCHRONIZING); + //-------------------some basic checks:------------------------------------------ //test existence of Recycle Bin @@ -532,7 +594,7 @@ void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const //check if more than 50% of total number of files/dirs are to be created/overwritten/deleted if (m_warningSignificantDifference) //test if check should be executed { - if (significantDifferenceDetected(fileCmp, config)) + if (significantDifferenceDetected(fileCmp)) { bool dontShowAgain = false; statusUpdater->reportWarning(Zstring(_("Significant difference detected:")) + wxT("\n") + @@ -546,7 +608,7 @@ void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const //check for sufficient free diskspace in left directory if (m_warningNotEnoughDiskSpace) { - const std::pair<wxLongLong, wxLongLong> spaceNeeded = freeDiskSpaceNeeded(fileCmp, config, m_useRecycleBin); + const std::pair<wxLongLong, wxLongLong> spaceNeeded = freeDiskSpaceNeeded(fileCmp, m_useRecycleBin); wxLongLong freeDiskSpaceLeft; if (wxGetDiskSpace(j->syncPair.leftDirectory.c_str(), NULL, &freeDiskSpaceLeft)) @@ -581,25 +643,21 @@ void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const } } } - //-------------------end of basic checks------------------------------------------ + //check if unresolved conflicts exist + if (m_warningUnresolvedConflict) //test if check should be executed + { + if (conflicts > 0) + { + bool dontShowAgain = false; + statusUpdater->reportWarning(_("Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization."), + dontShowAgain); + m_warningUnresolvedConflict = !dontShowAgain; + } + } - //inform about the total amount of data that will be processed from now on - int objectsToCreate = 0; - int objectsToOverwrite = 0; - int objectsToDelete = 0; - wxULongLong dataToProcess; - - FreeFileSync::calcTotalBytesToSync(folderCmp, - config, - objectsToCreate, - objectsToOverwrite, - objectsToDelete, - dataToProcess); + //-------------------end of basic checks------------------------------------------ - statusUpdater->initNewProcess(objectsToCreate + objectsToOverwrite + objectsToDelete, - globalFunctions::convertToSigned(dataToProcess), - StatusHandler::PROCESS_SYNCHRONIZING); try { @@ -629,7 +687,7 @@ void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const try { - if (synchronizeFolder(*i, config, currentPair)) + if (synchronizeFolder(*i, currentPair)) //progress indicator update //indicator is updated only if directory is sync'ed correctly (and if some work was done)! statusUpdater->updateProcessedData(1, 0); //each call represents one processed file/directory @@ -662,11 +720,15 @@ void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const for (FileComparison::const_iterator i = fileCmp.begin(); i != fileCmp.end(); ++i) { + //skip processing of unresolved errors (do not remove row from GUI grid) + if (i->direction == SYNC_UNRESOLVED_CONFLICT && i->selectedForSynchronization) + continue; + if ( i->fileDescrLeft.objType == FileDescrLine::TYPE_FILE || i->fileDescrRight.objType == FileDescrLine::TYPE_FILE) { - if ( (deleteLoop && deletionImminent(*i, config)) || - (!deleteLoop && !deletionImminent(*i, config))) + if ( (deleteLoop && deletionImminent(*i)) || + (!deleteLoop && !deletionImminent(*i))) { while (true) { //trigger display refresh @@ -674,20 +736,21 @@ void SyncProcess::startSynchronizationProcess(FolderComparison& folderCmp, const try { - if (synchronizeFile(*i, config, currentPair)) + if (synchronizeFile(*i, currentPair)) { //progress indicator update //indicator is updated only if file is sync'ed correctly (and if some sync was done)! int objectsToCreate = 0; int objectsToOverwrite = 0; int objectsToDelete = 0; + int conflictDummy = 0; wxULongLong dataToProcess; if (getBytesToTransfer(*i, - config, objectsToCreate, objectsToOverwrite, objectsToDelete, + conflictDummy, dataToProcess)) //update status if some work was done (answer is always "yes" in this context) statusUpdater->updateProcessedData(objectsToCreate + objectsToOverwrite + objectsToDelete, 0); //processed data is communicated in subfunctions! } |