summaryrefslogtreecommitdiff
path: root/algorithm.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:11:56 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:11:56 +0200
commit98ecf620f7de377dc8ae9ad7fbd1e3b24477e138 (patch)
treefaadc6d8822c20cd3bc6f50b2a98e6c580585949 /algorithm.cpp
parent3.16 (diff)
downloadFreeFileSync-98ecf620f7de377dc8ae9ad7fbd1e3b24477e138.tar.gz
FreeFileSync-98ecf620f7de377dc8ae9ad7fbd1e3b24477e138.tar.bz2
FreeFileSync-98ecf620f7de377dc8ae9ad7fbd1e3b24477e138.zip
3.17
Diffstat (limited to 'algorithm.cpp')
-rw-r--r--algorithm.cpp350
1 files changed, 232 insertions, 118 deletions
diff --git a/algorithm.cpp b/algorithm.cpp
index e705e075..3b210d49 100644
--- a/algorithm.cpp
+++ b/algorithm.cpp
@@ -12,7 +12,7 @@
#include "shared/file_handling.h"
#include "shared/recycler.h"
#include <wx/msgdlg.h>
-#include "library/filter.h"
+#include "library/norm_filter.h"
#include <boost/bind.hpp>
#include "shared/string_conv.h"
#include "shared/global_func.h"
@@ -20,11 +20,12 @@
#include "shared/loki/TypeManip.h"
#include "library/db_file.h"
#include "library/cmp_filetime.h"
+#include "library/norm_filter.h"
-using namespace ffs3;
+using namespace zen;
-void ffs3::swapGrids(const MainConfiguration& config, FolderComparison& folderCmp)
+void zen::swapGrids(const MainConfiguration& config, FolderComparison& folderCmp)
{
std::for_each(folderCmp.begin(), folderCmp.end(), boost::bind(&BaseDirMapping::swap, _1));
redetermineSyncDirection(config, folderCmp, NULL);
@@ -35,7 +36,7 @@ void ffs3::swapGrids(const MainConfiguration& config, FolderComparison& folderCm
class Redetermine
{
public:
- Redetermine(const SyncConfiguration& configIn) : config(configIn) {}
+ Redetermine(const DirectionSet& dirCfgIn) : dirCfg(dirCfgIn) {}
void execute(HierarchyObject& hierObj) const
{
@@ -85,34 +86,34 @@ private:
switch (fileObj.getCategory())
{
case FILE_LEFT_SIDE_ONLY:
- if (fileObj.getFullName<LEFT_SIDE>().EndsWith(ffs3::TEMP_FILE_ENDING))
+ if (fileObj.getFullName<LEFT_SIDE>().EndsWith(zen::TEMP_FILE_ENDING))
fileObj.setSyncDir(SYNC_DIR_LEFT); //schedule potentially existing temporary files for deletion
else
- fileObj.setSyncDir(config.exLeftSideOnly);
+ fileObj.setSyncDir(dirCfg.exLeftSideOnly);
break;
case FILE_RIGHT_SIDE_ONLY:
- if (fileObj.getFullName<RIGHT_SIDE>().EndsWith(ffs3::TEMP_FILE_ENDING))
+ if (fileObj.getFullName<RIGHT_SIDE>().EndsWith(zen::TEMP_FILE_ENDING))
fileObj.setSyncDir(SYNC_DIR_RIGHT); //schedule potentially existing temporary files for deletion
else
- fileObj.setSyncDir(config.exRightSideOnly);
+ fileObj.setSyncDir(dirCfg.exRightSideOnly);
break;
case FILE_RIGHT_NEWER:
- fileObj.setSyncDir(config.rightNewer);
+ fileObj.setSyncDir(dirCfg.rightNewer);
break;
case FILE_LEFT_NEWER:
- fileObj.setSyncDir(config.leftNewer);
+ fileObj.setSyncDir(dirCfg.leftNewer);
break;
case FILE_DIFFERENT:
- fileObj.setSyncDir(config.different);
+ fileObj.setSyncDir(dirCfg.different);
break;
case FILE_CONFLICT:
- fileObj.setSyncDir(config.conflict);
+ fileObj.setSyncDir(dirCfg.conflict);
break;
case FILE_EQUAL:
fileObj.setSyncDir(SYNC_DIR_NONE);
break;
case FILE_DIFFERENT_METADATA:
- fileObj.setSyncDir(config.conflict); //use setting from "conflict/cannot categorize"
+ fileObj.setSyncDir(dirCfg.conflict); //use setting from "conflict/cannot categorize"
break;
}
}
@@ -122,28 +123,28 @@ private:
switch (linkObj.getLinkCategory())
{
case SYMLINK_LEFT_SIDE_ONLY:
- linkObj.setSyncDir(config.exLeftSideOnly);
+ linkObj.setSyncDir(dirCfg.exLeftSideOnly);
break;
case SYMLINK_RIGHT_SIDE_ONLY:
- linkObj.setSyncDir(config.exRightSideOnly);
+ linkObj.setSyncDir(dirCfg.exRightSideOnly);
break;
case SYMLINK_LEFT_NEWER:
- linkObj.setSyncDir(config.leftNewer);
+ linkObj.setSyncDir(dirCfg.leftNewer);
break;
case SYMLINK_RIGHT_NEWER:
- linkObj.setSyncDir(config.rightNewer);
+ linkObj.setSyncDir(dirCfg.rightNewer);
break;
case SYMLINK_CONFLICT:
- linkObj.setSyncDir(config.conflict);
+ linkObj.setSyncDir(dirCfg.conflict);
break;
case SYMLINK_DIFFERENT:
- linkObj.setSyncDir(config.different);
+ linkObj.setSyncDir(dirCfg.different);
break;
case SYMLINK_EQUAL:
linkObj.setSyncDir(SYNC_DIR_NONE);
break;
case SYMLINK_DIFFERENT_METADATA:
- linkObj.setSyncDir(config.conflict); //use setting from "conflict/cannot categorize"
+ linkObj.setSyncDir(dirCfg.conflict); //use setting from "conflict/cannot categorize"
break;
}
@@ -154,16 +155,16 @@ private:
switch (dirObj.getDirCategory())
{
case DIR_LEFT_SIDE_ONLY:
- dirObj.setSyncDir(config.exLeftSideOnly);
+ dirObj.setSyncDir(dirCfg.exLeftSideOnly);
break;
case DIR_RIGHT_SIDE_ONLY:
- dirObj.setSyncDir(config.exRightSideOnly);
+ dirObj.setSyncDir(dirCfg.exRightSideOnly);
break;
case DIR_EQUAL:
dirObj.setSyncDir(SYNC_DIR_NONE);
break;
case DIR_DIFFERENT_METADATA:
- dirObj.setSyncDir(config.conflict); //use setting from "conflict/cannot categorize"
+ dirObj.setSyncDir(dirCfg.conflict); //use setting from "conflict/cannot categorize"
break;
}
@@ -171,7 +172,7 @@ private:
execute(dirObj);
}
- const SyncConfiguration& config;
+ const DirectionSet dirCfg;
};
@@ -216,7 +217,7 @@ struct AllElementsEqual : public std::unary_function<BaseDirMapping, bool>
};
-bool ffs3::allElementsEqual(const FolderComparison& folderCmp)
+bool zen::allElementsEqual(const FolderComparison& folderCmp)
{
return std::find_if(folderCmp.begin(), folderCmp.end(), std::not1(AllElementsEqual())) == folderCmp.end();
}
@@ -280,9 +281,9 @@ private:
}
}
- Zstring shortName; //empty if object not existing
- wxLongLong lastWriteTime;
- wxULongLong fileSize;
+ Zstring shortName; //empty if object not existing
+ zen::Int64 lastWriteTime;
+ zen::UInt64 fileSize;
};
@@ -363,7 +364,7 @@ private:
}
Zstring shortName; //empty if object not existing
- wxLongLong lastWriteTime;
+ zen::Int64 lastWriteTime;
Zstring targetPath;
#ifdef FFS_WIN
LinkDescriptor::LinkType type;
@@ -559,8 +560,8 @@ public:
txtFilterChanged(wxString(_("Cannot determine sync-direction:")) + wxT(" \n") + _("Filter settings have changed!")),
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),
+ // dbFilterLeft(NULL),
+ // dbFilterRight(NULL),
handler_(handler)
{
if (AllElementsEqual()(baseDirectory)) //nothing to do: abort and don't show any nag-screens
@@ -571,23 +572,26 @@ public:
if (dirInfo.first.get() == NULL ||
dirInfo.second.get() == NULL)
{
- //use standard settings:
- SyncConfiguration defaultSync;
- ffs3::setTwoWay(defaultSync);
- Redetermine(defaultSync).execute(baseDirectory);
+ //set conservative "two-way" directions
+ DirectionSet twoWayCfg = getTwoWaySet();
+
+ Redetermine(twoWayCfg).execute(baseDirectory);
return;
}
const DirInformation& dirInfoLeft = *dirInfo.first;
const DirInformation& dirInfoRight = *dirInfo.second;
- //save db filter (if it needs to be considered only):
- if (respectFiltering(baseDirectory, dirInfoLeft))
- dbFilterLeft = dirInfoLeft.filter.get();
-
- if (respectFiltering(baseDirectory, dirInfoRight))
- dbFilterRight = dirInfoRight.filter.get();
+ //-> considering filter not relevant:
+ //if narrowing filter: all ok; if widening filter (if file ex on both sides -> conflict, fine; if file ex. on one side: copy to other side: fine)
+ /*
+ //save db filter (if it needs to be considered only):
+ if (respectFiltering(baseDirectory, dirInfoLeft))
+ dbFilterLeft = dirInfoLeft.filter.get();
+ if (respectFiltering(baseDirectory, dirInfoRight))
+ dbFilterRight = dirInfoRight.filter.get();
+ */
execute(baseDirectory,
&dirInfoLeft.baseDirContainer,
&dirInfoRight.baseDirContainer);
@@ -595,6 +599,7 @@ public:
private:
+ /*
static bool respectFiltering(const BaseDirMapping& baseDirectory, const DirInformation& dirInfo)
{
//respect filtering if sync-DB filter is active && different from baseDir's filter:
@@ -602,7 +607,7 @@ private:
// => dirInfo can be queried as if it were a scan without filters
return !dirInfo.filter->isNull() && *dirInfo.filter != *baseDirectory.getFilter();
}
-
+ */
std::pair<DirInfoPtr, DirInfoPtr> loadDBFile(const BaseDirMapping& baseDirectory) //return NULL on failure
{
@@ -666,12 +671,12 @@ private:
//##################### schedule potentially existing temporary files for deletion ####################
- if (cat == FILE_LEFT_SIDE_ONLY && fileObj.getFullName<LEFT_SIDE>().EndsWith(ffs3::TEMP_FILE_ENDING))
+ if (cat == FILE_LEFT_SIDE_ONLY && fileObj.getFullName<LEFT_SIDE>().EndsWith(zen::TEMP_FILE_ENDING))
{
fileObj.setSyncDir(SYNC_DIR_LEFT);
return;
}
- else if (cat == FILE_RIGHT_SIDE_ONLY && fileObj.getFullName<RIGHT_SIDE>().EndsWith(ffs3::TEMP_FILE_ENDING))
+ else if (cat == FILE_RIGHT_SIDE_ONLY && fileObj.getFullName<RIGHT_SIDE>().EndsWith(zen::TEMP_FILE_ENDING))
{
fileObj.setSyncDir(SYNC_DIR_RIGHT);
return;
@@ -895,40 +900,43 @@ private:
const wxString txtLastSyncFail;
const wxString txtDirDeleteConflict;
- const BaseFilter* dbFilterLeft; //optional
- const BaseFilter* dbFilterRight; //optional
+ //const HardFilter* dbFilterLeft; //optional
+ //const HardFilter* dbFilterRight; //optional
DeterminationProblem* const handler_;
};
//---------------------------------------------------------------------------------------------------------------
-void ffs3::redetermineSyncDirection(const SyncConfiguration& config, BaseDirMapping& baseDirectory, DeterminationProblem* handler)
+void zen::redetermineSyncDirection(const SyncConfig& config, BaseDirMapping& baseDirectory, DeterminationProblem* handler)
{
- if (config.automatic)
+ if (config.var == SyncConfig::AUTOMATIC)
RedetermineAuto(baseDirectory, handler);
else
- Redetermine(config).execute(baseDirectory);
+ {
+ DirectionSet dirCfg = extractDirections(config);
+ Redetermine(dirCfg).execute(baseDirectory);
+ }
}
-void ffs3::redetermineSyncDirection(const MainConfiguration& currentMainCfg, FolderComparison& folderCmp, DeterminationProblem* handler)
+void zen::redetermineSyncDirection(const MainConfiguration& mainCfg, FolderComparison& folderCmp, DeterminationProblem* handler)
{
if (folderCmp.size() == 0)
return;
- else if (folderCmp.size() != currentMainCfg.additionalPairs.size() + 1)
+ else if (folderCmp.size() != mainCfg.additionalPairs.size() + 1)
throw std::logic_error("Programming Error: Contract violation!");
//merge first and additional pairs
std::vector<FolderPairEnh> allPairs;
- allPairs.push_back(currentMainCfg.firstPair);
+ allPairs.push_back(mainCfg.firstPair);
allPairs.insert(allPairs.end(),
- currentMainCfg.additionalPairs.begin(), //add additional pairs
- currentMainCfg.additionalPairs.end());
+ mainCfg.additionalPairs.begin(), //add additional pairs
+ mainCfg.additionalPairs.end());
for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i)
{
- redetermineSyncDirection(i->altSyncConfig.get() ? i->altSyncConfig->syncConfiguration : currentMainCfg.syncConfiguration,
+ redetermineSyncDirection(i->altSyncConfig.get() ? i->altSyncConfig->syncConfiguration : mainCfg.syncConfiguration,
folderCmp[i - allPairs.begin()], handler);
}
}
@@ -975,7 +983,7 @@ private:
};
-void ffs3::setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj)
+void zen::setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj)
{
SetNewDirection dirSetter(newDirection);
@@ -1008,12 +1016,12 @@ template <bool include>
class InOrExcludeAllRows
{
public:
- void operator()(ffs3::BaseDirMapping& baseDirectory) const //be careful with operator() to no get called by std::for_each!
+ void operator()(zen::BaseDirMapping& baseDirectory) const //be careful with operator() to no get called by std::for_each!
{
execute(baseDirectory);
}
- void execute(ffs3::HierarchyObject& hierObj) const //don't create ambiguity by replacing with operator()
+ void execute(zen::HierarchyObject& hierObj) const //don't create ambiguity by replacing with operator()
{
util::ProxyForEach<const InOrExcludeAllRows<include> > prx(*this); //grant std::for_each access to private parts of this class
@@ -1025,17 +1033,17 @@ public:
private:
friend class util::ProxyForEach<const InOrExcludeAllRows<include> >; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
- void operator()(ffs3::FileMapping& fileObj) const
+ void operator()(zen::FileMapping& fileObj) const
{
fileObj.setActive(include);
}
- void operator()(ffs3::SymLinkMapping& linkObj) const
+ void operator()(zen::SymLinkMapping& linkObj) const
{
linkObj.setActive(include);
}
- void operator()(ffs3::DirMapping& dirObj) const
+ void operator()(zen::DirMapping& dirObj) const
{
dirObj.setActive(include);
execute(dirObj); //recursion
@@ -1043,7 +1051,7 @@ private:
};
-void ffs3::setActiveStatus(bool newStatus, ffs3::FolderComparison& folderCmp)
+void zen::setActiveStatus(bool newStatus, zen::FolderComparison& folderCmp)
{
if (newStatus)
std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<true>()); //include all rows
@@ -1052,7 +1060,7 @@ void ffs3::setActiveStatus(bool newStatus, ffs3::FolderComparison& folderCmp)
}
-void ffs3::setActiveStatus(bool newStatus, ffs3::FileSystemObject& fsObj)
+void zen::setActiveStatus(bool newStatus, zen::FileSystemObject& fsObj)
{
fsObj.setActive(newStatus);
@@ -1079,21 +1087,44 @@ namespace
{
enum FilterStrategy
{
- STRATEGY_ALL,
- STRATEGY_ACTIVE_ONLY
- //STRATEGY_INACTIVE_ONLY -> logical conflict with InOrExcludeAllRows<false>
+ STRATEGY_SET,
+ STRATEGY_AND,
+ STRATEGY_OR
+};
+
+template <FilterStrategy strategy> struct Eval;
+
+template <>
+struct Eval<STRATEGY_SET> //process all elements
+{
+ template <class T>
+ bool process(const T& obj) const { return true; }
+};
+
+template <>
+struct Eval<STRATEGY_AND>
+{
+ template <class T>
+ bool process(const T& obj) const { return obj.isActive(); }
+};
+
+template <>
+struct Eval<STRATEGY_OR>
+{
+ template <class T>
+ bool process(const T& obj) const { return !obj.isActive(); }
};
template <FilterStrategy strategy>
-class FilterData
+class ApplyHardFilter
{
public:
- FilterData(const BaseFilter& filterProcIn) : filterProc(filterProcIn) {}
+ ApplyHardFilter(const HardFilter& filterProcIn) : filterProc(filterProcIn) {}
- void execute(ffs3::HierarchyObject& hierObj) const
+ void execute(zen::HierarchyObject& hierObj) const
{
- util::ProxyForEach<const FilterData> prx(*this); //grant std::for_each access to private parts of this class
+ util::ProxyForEach<const ApplyHardFilter> prx(*this); //grant std::for_each access to private parts of this class
std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), prx); //files
std::for_each(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), prx); //symlinks
@@ -1101,28 +1132,26 @@ public:
};
private:
- friend class util::ProxyForEach<const FilterData>; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
-
- bool processObject(ffs3::FileSystemObject& fsObj) const;
+ friend class util::ProxyForEach<const ApplyHardFilter>; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
- void operator()(ffs3::FileMapping& fileObj) const
+ void operator()(zen::FileMapping& fileObj) const
{
- if (processObject(fileObj))
+ if (Eval<strategy>().process(fileObj))
fileObj.setActive(filterProc.passFileFilter(fileObj.getObjRelativeName()));
}
- void operator()(ffs3::SymLinkMapping& linkObj) const
+ void operator()(zen::SymLinkMapping& linkObj) const
{
- if (processObject(linkObj))
+ if (Eval<strategy>().process(linkObj))
linkObj.setActive(filterProc.passFileFilter(linkObj.getObjRelativeName()));
}
- void operator()(ffs3::DirMapping& dirObj) const
+ void operator()(zen::DirMapping& dirObj) const
{
bool subObjMightMatch = true;
const bool filterPassed = filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch);
- if (processObject(dirObj))
+ if (Eval<strategy>().process(dirObj))
dirObj.setActive(filterPassed);
if (!subObjMightMatch) //use same logic like directory traversing here: evaluate filter in subdirs only if objects could match
@@ -1134,65 +1163,150 @@ private:
execute(dirObj); //recursion
}
- const BaseFilter& filterProc;
+ const HardFilter& filterProc;
};
+template <>
+class ApplyHardFilter<STRATEGY_OR>; //usage of InOrExcludeAllRows doesn't allow for strategy "or"
+
+
-template <> //process all elements
-inline
-bool FilterData<STRATEGY_ALL>::processObject(ffs3::FileSystemObject& fsObj) const
+template <FilterStrategy strategy>
+class ApplySoftFilter //falsify only! -> can run directly after "hard/base filter"
{
- return true;
+public:
+ ApplySoftFilter(const SoftFilter& timeSizeFilter) : timeSizeFilter_(timeSizeFilter) {}
+
+ void execute(zen::HierarchyObject& hierObj) const
+ {
+ util::ProxyForEach<const ApplySoftFilter> prx(*this); //grant std::for_each access to private parts of this class
+
+ std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), prx); //files
+ std::for_each(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), prx); //symlinks
+ std::for_each(hierObj.useSubDirs ().begin(), hierObj.useSubDirs(). end(), prx); //directories
+ };
+
+private:
+ friend class util::ProxyForEach<const ApplySoftFilter>; //friend declaration of std::for_each is NOT sufficient as implementation is compiler dependent!
+
+ void operator()(zen::FileMapping& fileObj) const
+ {
+ if (Eval<strategy>().process(fileObj))
+ {
+ if (fileObj.isEmpty<LEFT_SIDE>())
+ fileObj.setActive(matchSize<RIGHT_SIDE>(fileObj) &&
+ matchTime<RIGHT_SIDE>(fileObj));
+ else if (fileObj.isEmpty<RIGHT_SIDE>())
+ fileObj.setActive(matchSize<LEFT_SIDE>(fileObj) &&
+ matchTime<LEFT_SIDE>(fileObj));
+ else
+ {
+ //the only case with partially unclear semantics:
+ //file and time filters may match on one side, leaving a total of 16 combinations for both sides!
+ /*
+ ST S T - ST := match size and time
+ --------- S := match size only
+ ST |X|X|X|X| T := match time only
+ ------------ - := no match
+ S |X|O|?|O|
+ ------------ X := include row
+ T |X|?|O|O| O := exclude row
+ ------------ ? := unclear
+ - |X|O|O|O|
+ ------------
+ */
+ //let's set ? := O
+ fileObj.setActive((matchSize<RIGHT_SIDE>(fileObj) &&
+ matchTime<RIGHT_SIDE>(fileObj)) ||
+ (matchSize<LEFT_SIDE>(fileObj) &&
+ matchTime<LEFT_SIDE>(fileObj)));
+ }
+ }
+ }
+
+ void operator()(zen::SymLinkMapping& linkObj) const
+ {
+ if (Eval<strategy>().process(linkObj))
+ {
+ if (linkObj.isEmpty<LEFT_SIDE>())
+ linkObj.setActive(matchTime<RIGHT_SIDE>(linkObj));
+ else if (linkObj.isEmpty<RIGHT_SIDE>())
+ linkObj.setActive(matchTime<LEFT_SIDE>(linkObj));
+ else
+ linkObj.setActive(matchTime<RIGHT_SIDE>(linkObj) ||
+ matchTime<LEFT_SIDE> (linkObj));
+ }
+ }
+
+ void operator()(zen::DirMapping& dirObj) const
+ {
+ execute(dirObj); //recursion
+ }
+
+ template <SelectedSide side, class T>
+ bool matchTime(const T& obj) const
+ {
+ return timeSizeFilter_.matchTime(obj.template getLastWriteTime<side>());
+ }
+
+ template <SelectedSide side, class T>
+ bool matchSize(const T& obj) const
+ {
+ return timeSizeFilter_.matchSize(obj.template getFileSize<side>());
+ }
+
+ const SoftFilter timeSizeFilter_;
+};
}
-template <>
-inline
-bool FilterData<STRATEGY_ACTIVE_ONLY>::processObject(ffs3::FileSystemObject& fsObj) const
+
+void zen::addExcludeFiltering(FolderComparison& folderCmp, const Zstring& excludeFilter)
{
- return fsObj.isActive();
-}
+ for (std::vector<BaseDirMapping>::iterator i = folderCmp.begin(); i != folderCmp.end(); ++i)
+ ApplyHardFilter<STRATEGY_AND>(*HardFilter::FilterRef(
+ new NameFilter(FilterConfig().includeFilter, excludeFilter))).execute(*i);
}
-void ffs3::addExcludeFiltering(const Zstring& excludeFilter, FolderComparison& folderCmp)
+void zen::addSoftFiltering(BaseDirMapping& baseMap, const SoftFilter& timeSizeFilter)
{
- for (std::vector<BaseDirMapping>::iterator i = folderCmp.begin(); i != folderCmp.end(); ++i)
- FilterData<STRATEGY_ACTIVE_ONLY>(*BaseFilter::FilterRef(new NameFilter(Zstr("*"), excludeFilter))).execute(*i);
+ if (!timeSizeFilter.isNull()) //since we use STRATEGY_AND, we may skip a "null" filter
+ ApplySoftFilter<STRATEGY_AND>(timeSizeFilter).execute(baseMap);
}
-void ffs3::applyFiltering(const MainConfiguration& currentMainCfg, FolderComparison& folderCmp)
+void zen::applyFiltering(FolderComparison& folderCmp, const MainConfiguration& mainCfg)
{
if (folderCmp.size() == 0)
return;
- else if (folderCmp.size() != currentMainCfg.additionalPairs.size() + 1)
+ else if (folderCmp.size() != mainCfg.additionalPairs.size() + 1)
throw std::logic_error("Programming Error: Contract violation!");
-
//merge first and additional pairs
std::vector<FolderPairEnh> allPairs;
- allPairs.push_back(currentMainCfg.firstPair);
+ allPairs.push_back(mainCfg.firstPair);
allPairs.insert(allPairs.end(),
- currentMainCfg.additionalPairs.begin(), //add additional pairs
- currentMainCfg.additionalPairs.end());
-
+ mainCfg.additionalPairs.begin(), //add additional pairs
+ mainCfg.additionalPairs.end());
- 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)
{
BaseDirMapping& baseDirectory = folderCmp[i - allPairs.begin()];
- FilterData<STRATEGY_ALL>(*combineFilters(globalFilter,
- BaseFilter::FilterRef(new NameFilter(
- i->localFilter.includeFilter,
- i->localFilter.excludeFilter)))).execute(baseDirectory);
+ const NormalizedFilter normFilter = normalizeFilters(mainCfg.globalFilter, i->localFilter);
+
+ //"set" hard filter
+ ApplyHardFilter<STRATEGY_SET>(*normFilter.nameFilter).execute(baseDirectory);
+
+ //"and" soft filter
+ addSoftFiltering(baseDirectory, normFilter.timeSizeFilter);
}
}
//############################################################################################################
-std::pair<wxString, int> ffs3::deleteFromGridAndHDPreview( //assemble message containing all files to be deleted
+std::pair<wxString, int> zen::deleteFromGridAndHDPreview( //assemble message containing all files to be deleted
const std::vector<FileSystemObject*>& rowsToDeleteOnLeft,
const std::vector<FileSystemObject*>& rowsToDeleteOnRight,
const bool deleteOnBothSides)
@@ -1256,7 +1370,7 @@ std::pair<wxString, int> ffs3::deleteFromGridAndHDPreview( //assemble message co
namespace
{
-struct RemoveCallbackImpl : public ffs3::CallbackRemoveDir
+struct RemoveCallbackImpl : public zen::CallbackRemoveDir
{
RemoveCallbackImpl(DeleteFilesHandler& deleteCallback) : deleteCallback_(deleteCallback) {}
@@ -1287,7 +1401,7 @@ void deleteFromGridAndHDOneSide(InputIterator first, InputIterator last,
{
if (useRecycleBin)
{
- if (ffs3::moveToRecycleBin(fsObj->getFullName<side>())) //throw (FileError)
+ if (zen::moveToRecycleBin(fsObj->getFullName<side>())) //throw (FileError)
statusHandler.notifyDeletion(fsObj->getFullName<side>());
}
else
@@ -1301,7 +1415,7 @@ void deleteFromGridAndHDOneSide(InputIterator first, InputIterator last,
virtual void visit(const FileMapping& fileObj)
{
- if (ffs3::removeFile(fileObj.getFullName<side>()))
+ if (zen::removeFile(fileObj.getFullName<side>()))
remCallback_.notifyDeletion(fileObj.getFullName<side>());
}
@@ -1310,10 +1424,10 @@ void deleteFromGridAndHDOneSide(InputIterator first, InputIterator last,
switch (linkObj.getLinkType<side>())
{
case LinkDescriptor::TYPE_DIR:
- ffs3::removeDirectory(linkObj.getFullName<side>(), &remCallback_);
+ zen::removeDirectory(linkObj.getFullName<side>(), &remCallback_);
break;
case LinkDescriptor::TYPE_FILE:
- if (ffs3::removeFile(linkObj.getFullName<side>()))
+ if (zen::removeFile(linkObj.getFullName<side>()))
remCallback_.notifyDeletion(linkObj.getFullName<side>());
break;
}
@@ -1321,7 +1435,7 @@ void deleteFromGridAndHDOneSide(InputIterator first, InputIterator last,
virtual void visit(const DirMapping& dirObj)
{
- ffs3::removeDirectory(dirObj.getFullName<side>(), &remCallback_);
+ zen::removeDirectory(dirObj.getFullName<side>(), &remCallback_);
}
private:
@@ -1374,12 +1488,12 @@ private:
};
-void ffs3::deleteFromGridAndHD(FolderComparison& folderCmp, //attention: rows will be physically deleted!
- std::vector<FileSystemObject*>& rowsToDeleteOnLeft, //refresh GUI grid after deletion to remove invalid rows
- std::vector<FileSystemObject*>& rowsToDeleteOnRight, //all pointers need to be bound!
- const bool deleteOnBothSides,
- const bool useRecycleBin,
- DeleteFilesHandler& statusHandler)
+void zen::deleteFromGridAndHD(FolderComparison& folderCmp, //attention: rows will be physically deleted!
+ std::vector<FileSystemObject*>& rowsToDeleteOnLeft, //refresh GUI grid after deletion to remove invalid rows
+ std::vector<FileSystemObject*>& rowsToDeleteOnRight, //all pointers need to be bound!
+ const bool deleteOnBothSides,
+ const bool useRecycleBin,
+ DeleteFilesHandler& statusHandler)
{
FinalizeDeletion dummy(folderCmp); //ensure cleanup: redetermination of sync-directions and removal of invalid rows
@@ -1472,7 +1586,7 @@ unsigned int getThreshold(const unsigned filesWithSameSizeTotal)
}
-void ffs3::checkForDSTChange(const FileCompareResult& gridData,
+void zen::checkForDSTChange(const FileCompareResult& gridData,
const std::vector<FolderPair>& directoryPairsFormatted,
int& timeShift, wxString& driveName)
{
bgstack15