summaryrefslogtreecommitdiff
path: root/algorithm.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:07:15 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:07:15 +0200
commit8318453bf9d4fd50b137ff6c6fc8d1fd22aa6395 (patch)
tree975c6e590c31e56007006a23e7b15d0245d75b08 /algorithm.cpp
parent3.6 (diff)
downloadFreeFileSync-8318453bf9d4fd50b137ff6c6fc8d1fd22aa6395.tar.gz
FreeFileSync-8318453bf9d4fd50b137ff6c6fc8d1fd22aa6395.tar.bz2
FreeFileSync-8318453bf9d4fd50b137ff6c6fc8d1fd22aa6395.zip
3.7
Diffstat (limited to 'algorithm.cpp')
-rw-r--r--algorithm.cpp151
1 files changed, 101 insertions, 50 deletions
diff --git a/algorithm.cpp b/algorithm.cpp
index 159cef52..1f34ca6a 100644
--- a/algorithm.cpp
+++ b/algorithm.cpp
@@ -53,10 +53,16 @@ private:
switch (fileObj.getCategory())
{
case FILE_LEFT_SIDE_ONLY:
- fileObj.setSyncDir(config.exLeftSideOnly);
+ if (fileObj.getFullName<LEFT_SIDE>().EndsWith(FreeFileSync::TEMP_FILE_ENDING))
+ fileObj.setSyncDir(SYNC_DIR_LEFT); //schedule potentially existing temporary files for deletion
+ else
+ fileObj.setSyncDir(config.exLeftSideOnly);
break;
case FILE_RIGHT_SIDE_ONLY:
- fileObj.setSyncDir(config.exRightSideOnly);
+ if (fileObj.getFullName<RIGHT_SIDE>().EndsWith(FreeFileSync::TEMP_FILE_ENDING))
+ fileObj.setSyncDir(SYNC_DIR_RIGHT); //schedule potentially existing temporary files for deletion
+ else
+ fileObj.setSyncDir(config.exRightSideOnly);
break;
case FILE_RIGHT_NEWER:
fileObj.setSyncDir(config.rightNewer);
@@ -105,14 +111,11 @@ class FindNonEqual //test if non-equal items exist in scanned data
public:
bool findNonEqual(const HierarchyObject& hierObj) const
{
- //files
- if (std::find_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), *this) != hierObj.useSubFiles().end())
- return true;
-
- //directories
- return std::find_if(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), *this) != hierObj.useSubDirs().end();
+ return std::find_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), *this) != hierObj.useSubFiles().end() || //files
+ std::find_if(hierObj.useSubDirs(). begin(), hierObj.useSubDirs(). end(), *this) != hierObj.useSubDirs(). end(); //directories
}
+ //logical private! => __find_if (used by std::find_if) needs public access
bool operator()(const FileMapping& fileObj) const
{
return fileObj.getCategory() != FILE_EQUAL;
@@ -144,7 +147,7 @@ bool FreeFileSync::allElementsEqual(const FolderComparison& folderCmp)
//---------------------------------------------------------------------------------------------------------------
inline
-bool sameFileTime(const wxLongLong& a, const wxLongLong& b, const unsigned int tolerance)
+bool sameFileTime(const wxLongLong& a, const wxLongLong& b, size_t tolerance)
{
if (a < b)
return b <= a + tolerance;
@@ -331,6 +334,39 @@ private:
};
+//test whether planned deletion of a directory is in conflict with (direct!) sub-elements that are not categorized for deletion (e.g. shall be copied or are in conflict themselves)
+class FindDeleteDirConflictNonRec
+{
+public:
+ bool conflictFound(const HierarchyObject& hierObj) const
+ {
+ return std::find_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), *this) != hierObj.useSubFiles().end() || //files
+ std::find_if(hierObj.useSubDirs(). begin(), hierObj.useSubDirs(). end(), *this) != hierObj.useSubDirs(). end(); //directories
+ }
+
+ //logical private! => __find_if (used by std::find_if) needs public access
+ bool operator()(const FileSystemObject& fsObj) const
+ {
+ switch (fsObj.getSyncOperation())
+ {
+ case SO_CREATE_NEW_LEFT:
+ case SO_CREATE_NEW_RIGHT:
+ case SO_UNRESOLVED_CONFLICT:
+ return true;
+
+ case SO_DELETE_LEFT:
+ case SO_DELETE_RIGHT:
+ case SO_OVERWRITE_LEFT:
+ case SO_OVERWRITE_RIGHT:
+ case SO_DO_NOTHING:
+ case SO_EQUAL:
+ ;
+ }
+ return false;
+ }
+};
+
+
//----------------------------------------------------------------------------------------------
class RedetermineAuto
{
@@ -340,7 +376,8 @@ public:
txtBothSidesChanged(_("Both sides have changed since last synchronization!")),
txtNoSideChanged(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("No change since last synchronization!")),
txtFilterChanged(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("Filter settings have changed!")),
- txtLastSyncFail(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("Last synchronization not completed!")),
+ txtLastSyncFail(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("The file was not processed by last synchronization!")),
+ txtDirDeleteConflict(_("Planned directory deletion is in conflict with its subdirectories and -files!")),
dbFilterLeft(NULL),
dbFilterRight(NULL),
handler_(handler)
@@ -395,7 +432,7 @@ private:
catch (FileError& error) //e.g. incompatible database version
{
if (handler_) handler_->reportWarning(error.show() + wxT(" \n\n") +
- _("Setting default synchronization directions: Old files will be overwritten by newer files."));
+ _("Setting default synchronization directions: Old files will be overwritten with newer files."));
}
return std::pair<DirInfoPtr, DirInfoPtr>(); //NULL
}
@@ -442,6 +479,21 @@ private:
if (cat == FILE_EQUAL)
return;
+
+ //##################### schedule potentially existing temporary files for deletion ####################
+ if (cat == FILE_LEFT_SIDE_ONLY && fileObj.getFullName<LEFT_SIDE>().EndsWith(FreeFileSync::TEMP_FILE_ENDING))
+ {
+ fileObj.setSyncDir(SYNC_DIR_LEFT);
+ return;
+ }
+ else if (cat == FILE_RIGHT_SIDE_ONLY && fileObj.getFullName<RIGHT_SIDE>().EndsWith(FreeFileSync::TEMP_FILE_ENDING))
+ {
+ fileObj.setSyncDir(SYNC_DIR_RIGHT);
+ return;
+ }
+ //#####################################################################################################
+
+
if (filterConflictFound(fileObj))
{
if (cat == FILE_LEFT_SIDE_ONLY)
@@ -478,14 +530,7 @@ private:
if (changeOnRight)
fileObj.setSyncDir(SYNC_DIR_LEFT);
else
- {
- if (cat == FILE_LEFT_SIDE_ONLY)
- fileObj.setSyncDir(SYNC_DIR_RIGHT);
- else if (cat == FILE_RIGHT_SIDE_ONLY)
- fileObj.setSyncDir(SYNC_DIR_LEFT);
- else
- fileObj.setSyncDirConflict(txtNoSideChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
- }
+ fileObj.setSyncDirConflict(txtNoSideChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
}
}
else //object did not complete last sync
@@ -494,12 +539,12 @@ private:
fileObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
else
{
- if (cat == FILE_LEFT_SIDE_ONLY)
- fileObj.setSyncDir(SYNC_DIR_RIGHT);
- else if (cat == FILE_RIGHT_SIDE_ONLY)
- fileObj.setSyncDir(SYNC_DIR_LEFT);
- else
- fileObj.setSyncDirConflict(txtLastSyncFail); //set syncDir = SYNC_DIR_INT_CONFLICT
+// if (cat == FILE_LEFT_SIDE_ONLY)
+// fileObj.setSyncDir(SYNC_DIR_RIGHT);
+// else if (cat == FILE_RIGHT_SIDE_ONLY)
+// fileObj.setSyncDir(SYNC_DIR_LEFT);
+// else
+ fileObj.setSyncDirConflict(txtLastSyncFail); //set syncDir = SYNC_DIR_INT_CONFLICT
}
}
}
@@ -557,17 +602,8 @@ private:
dirObj.setSyncDir(SYNC_DIR_LEFT);
else
{
- switch (cat)
- {
- case DIR_LEFT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_RIGHT);
- break;
- case DIR_RIGHT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_LEFT);
- break;
- case DIR_EQUAL:
- assert(false);
- }
+ assert(false);
+ dirObj.setSyncDirConflict(txtNoSideChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
}
}
}
@@ -577,28 +613,41 @@ private:
dirObj.setSyncDirConflict(txtBothSidesChanged); //set syncDir = SYNC_DIR_INT_CONFLICT
else
{
- switch (cat)
- {
- case DIR_LEFT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_RIGHT);
- break;
- case DIR_RIGHT_SIDE_ONLY:
- dirObj.setSyncDir(SYNC_DIR_LEFT);
- break;
- case DIR_EQUAL:
- assert(false);
- }
+// switch (cat)
+// {
+// case DIR_LEFT_SIDE_ONLY:
+// dirObj.setSyncDir(SYNC_DIR_RIGHT);
+// break;
+// case DIR_RIGHT_SIDE_ONLY:
+// dirObj.setSyncDir(SYNC_DIR_LEFT);
+// break;
+// case DIR_EQUAL:
+// assert(false);
+// }
+
+ dirObj.setSyncDirConflict(txtLastSyncFail); //set syncDir = SYNC_DIR_INT_CONFLICT
}
}
}
execute(dirObj, dataDbLeftStuff.second, dataDbRightStuff.second); //recursion
+ //###################################################################################################
+
+ //if a directory is to be deleted on one side, ensure that directions of sub-elements are "d’accord"
+ const SyncOperation syncOp = dirObj.getSyncOperation();
+ if ( syncOp == SO_DELETE_LEFT ||
+ syncOp == SO_DELETE_RIGHT)
+ {
+ if (FindDeleteDirConflictNonRec().conflictFound(dirObj))
+ dirObj.setSyncDirConflict(txtDirDeleteConflict);
+ }
}
const wxString txtBothSidesChanged;
const wxString txtNoSideChanged;
const wxString txtFilterChanged;
const wxString txtLastSyncFail;
+ const wxString txtDirDeleteConflict;
const BaseFilter* dbFilterLeft; //optional
const BaseFilter* dbFilterRight; //optional
@@ -771,9 +820,11 @@ private:
void operator()(FreeFileSync::DirMapping& dirObj) const
{
bool subObjMightMatch = true;
- dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch));
+ const bool filterPassed = filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch);
+
+ dirObj.setActive(filterPassed);
- if (subObjMightMatch) //use same logic as within directory traversing here: evaluate filter in subdirs only if objects could match
+ if (subObjMightMatch) //use same logic like directory traversing here: evaluate filter in subdirs only if objects could match
execute(dirObj); //recursion
else
InOrExcludeAllRows<false>().execute(dirObj); //exclude all files dirs in subfolders
@@ -805,7 +856,7 @@ void FreeFileSync::applyFiltering(const MainConfiguration& currentMainCfg, Folde
currentMainCfg.additionalPairs.end());
- const BaseFilter::FilterRef globalFilter(new NameFilter(currentMainCfg.includeFilter, currentMainCfg.excludeFilter));
+ const BaseFilter::FilterRef globalFilter(new NameFilter(currentMainCfg.globalFilter.includeFilter, currentMainCfg.globalFilter.excludeFilter));
for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i)
{
bgstack15