summaryrefslogtreecommitdiff
path: root/structures.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'structures.cpp')
-rw-r--r--structures.cpp124
1 files changed, 67 insertions, 57 deletions
diff --git a/structures.cpp b/structures.cpp
index 3bc2c181..e5dc08fd 100644
--- a/structures.cpp
+++ b/structures.cpp
@@ -32,7 +32,7 @@ std::wstring zen::getVariantName(DirectionConfig::Variant var)
{
switch (var)
{
- case DirectionConfig::AUTOMATIC:
+ case DirectionConfig::TWOWAY:
return L"<- " + _("Two way") + L" ->";
case DirectionConfig::MIRROR:
return _("Mirror") + L" ->>";
@@ -51,7 +51,7 @@ DirectionSet zen::extractDirections(const DirectionConfig& cfg)
DirectionSet output;
switch (cfg.var)
{
- case DirectionConfig::AUTOMATIC:
+ case DirectionConfig::TWOWAY:
throw std::logic_error("there are no predefined directions for automatic mode!");
case DirectionConfig::MIRROR:
@@ -80,7 +80,26 @@ DirectionSet zen::extractDirections(const DirectionConfig& cfg)
}
-DirectionSet zen::getTwoWaySet()
+bool zen::detectMovedFilesSelectable(const DirectionConfig& cfg)
+{
+ if (cfg.var == DirectionConfig::TWOWAY)
+ return false; //moved files are always detected since we have the database file anyway
+
+ const DirectionSet tmp = zen::extractDirections(cfg);
+ return (tmp.exLeftSideOnly == SyncDirection::RIGHT &&
+ tmp.exRightSideOnly == SyncDirection::RIGHT) ||
+ (tmp.exLeftSideOnly == SyncDirection::LEFT&&
+ tmp.exRightSideOnly == SyncDirection::LEFT);
+}
+
+
+bool zen::detectMovedFilesEnabled(const DirectionConfig& cfg)
+{
+ return detectMovedFilesSelectable(cfg) ? cfg.detectMovedFiles : cfg.var == DirectionConfig::TWOWAY;
+}
+
+
+DirectionSet zen::getTwoWayUpdateSet()
{
DirectionSet output;
output.exLeftSideOnly = SyncDirection::RIGHT;
@@ -100,10 +119,10 @@ std::wstring MainConfiguration::getCompVariantName() const
cmpConfig.compareVar; //fallback to main sync cfg
//test if there's a deviating variant within the additional folder pairs
- for (auto fp = additionalPairs.begin(); fp != additionalPairs.end(); ++fp)
+ for (const FolderPairEnh& fp : additionalPairs)
{
- const CompareVariant thisVariant = fp->altCmpConfig.get() ?
- fp->altCmpConfig->compareVar :
+ const CompareVariant thisVariant = fp.altCmpConfig.get() ?
+ fp.altCmpConfig->compareVar :
cmpConfig.compareVar; //fallback to main sync cfg
if (thisVariant != firstVariant)
return _("Multiple...");
@@ -121,10 +140,10 @@ std::wstring MainConfiguration::getSyncVariantName() const
syncCfg.directionCfg.var; //fallback to main sync cfg
//test if there's a deviating variant within the additional folder pairs
- for (auto fp = additionalPairs.begin(); fp != additionalPairs.end(); ++fp)
+ for (const FolderPairEnh& fp : additionalPairs)
{
- const DirectionConfig::Variant thisVariant = fp->altSyncConfig.get() ?
- fp->altSyncConfig->directionCfg.var :
+ const DirectionConfig::Variant thisVariant = fp.altSyncConfig.get() ?
+ fp.altSyncConfig->directionCfg.var :
syncCfg.directionCfg.var;
if (thisVariant != firstVariant)
return _("Multiple...");
@@ -317,28 +336,14 @@ void zen::resolveUnits(size_t timeSpan, UnitTime unitTimeSpan,
namespace
{
-bool sameFilter(const std::vector<FolderPairEnh>& folderPairs)
-{
- if (folderPairs.empty())
- return true;
-
- for (std::vector<FolderPairEnh>::const_iterator fp = folderPairs.begin(); fp != folderPairs.end(); ++fp)
- if (!(fp->localFilter == folderPairs[0].localFilter))
- return false;
-
- return true;
-}
-
-
FilterConfig mergeFilterConfig(const FilterConfig& global, const FilterConfig& local)
{
FilterConfig out = local;
//hard filter
-
- //pragmatism: if both global and local include filter contain data, only local filter is preserved
if (out.includeFilter == FilterConfig().includeFilter)
out.includeFilter = global.includeFilter;
+ //else: if both global and local include filter contain data, only local filter is preserved
trim(out.excludeFilter, true, false);
out.excludeFilter = global.excludeFilter + Zstr("\n") + out.excludeFilter;
@@ -386,9 +391,14 @@ FilterConfig mergeFilterConfig(const FilterConfig& global, const FilterConfig& l
inline
-bool isEmpty(const FolderPairEnh& fp)
+bool effectivelyEmpty(const FolderPairEnh& fp)
{
- return fp == FolderPairEnh();
+ auto isEmpty = [](Zstring dirname)
+ {
+ trim(dirname);
+ return dirname.empty();
+ };
+ return isEmpty(fp.leftDirectory) && isEmpty(fp.rightDirectory);
}
}
@@ -404,28 +414,28 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs)
//merge folder pair config
std::vector<FolderPairEnh> fpMerged;
- for (auto iterMain = mainCfgs.begin(); iterMain != mainCfgs.end(); ++iterMain)
+ for (const MainConfiguration& mainCfg : mainCfgs)
{
std::vector<FolderPairEnh> fpTmp;
- //list non-empty local configurations
- if (!isEmpty(iterMain->firstPair))
- fpTmp.push_back(iterMain->firstPair);
- std::copy_if(iterMain->additionalPairs.begin(), iterMain->additionalPairs.end(), std::back_inserter(fpTmp),
- [](const FolderPairEnh& fp) { return !isEmpty(fp); });
+ //skip empty folder pairs
+ if (!effectivelyEmpty(mainCfg.firstPair))
+ fpTmp.push_back(mainCfg.firstPair);
+ for (const FolderPairEnh& fp : mainCfg.additionalPairs)
+ if (!effectivelyEmpty(fp))
+ fpTmp.push_back(fp);
//move all configuration down to item level
- for (std::vector<FolderPairEnh>::iterator fp = fpTmp.begin(); fp != fpTmp.end(); ++fp)
+ for (FolderPairEnh& fp : fpTmp)
{
- if (!fp->altCmpConfig.get())
- fp->altCmpConfig = std::make_shared<CompConfig>(iterMain->cmpConfig);
+ if (!fp.altCmpConfig.get())
+ fp.altCmpConfig = std::make_shared<CompConfig>(mainCfg.cmpConfig);
- if (!fp->altSyncConfig.get())
- fp->altSyncConfig = std::make_shared<SyncConfig>(iterMain->syncCfg);
+ if (!fp.altSyncConfig.get())
+ fp.altSyncConfig = std::make_shared<SyncConfig>(mainCfg.syncCfg);
- fp->localFilter = mergeFilterConfig(iterMain->globalFilter, fp->localFilter);
+ fp.localFilter = mergeFilterConfig(mainCfg.globalFilter, fp.localFilter);
}
-
fpMerged.insert(fpMerged.end(), fpTmp.begin(), fpTmp.end());
}
@@ -438,23 +448,24 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs)
//find out which comparison and synchronization setting are used most often and use them as new "header"
std::vector<std::pair<CompConfig, int>> cmpCfgStat;
std::vector<std::pair<SyncConfig, int>> syncCfgStat;
- for (auto fp = fpMerged.begin(); fp != fpMerged.end(); ++fp) //rather inefficient algorithm, but it does not require a less-than operator!
+ for (const FolderPairEnh& fp : fpMerged)
{
+ //rather inefficient algorithm, but it does not require a less-than operator:
{
- const CompConfig& cmpCfg = *fp->altCmpConfig;
+ const CompConfig& cmpCfg = *fp.altCmpConfig;
auto it = std::find_if(cmpCfgStat.begin(), cmpCfgStat.end(),
- [&](const std::pair<CompConfig, int>& entry) { return entry.first == cmpCfg; });
+ [&](const std::pair<CompConfig, int>& entry) { return effectivelyEqual(entry.first, cmpCfg); });
if (it == cmpCfgStat.end())
cmpCfgStat.push_back(std::make_pair(cmpCfg, 1));
else
++(it->second);
}
{
- const SyncConfig& syncCfg = *fp->altSyncConfig;
+ const SyncConfig& syncCfg = *fp.altSyncConfig;
auto it = std::find_if(syncCfgStat.begin(), syncCfgStat.end(),
- [&](const std::pair<SyncConfig, int>& entry) { return entry.first == syncCfg; });
+ [&](const std::pair<SyncConfig, int>& entry) { return effectivelyEqual(entry.first, syncCfg); });
if (it == syncCfgStat.end())
syncCfgStat.push_back(std::make_pair(syncCfg, 1));
else
@@ -462,7 +473,7 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs)
}
}
- //set most-used comparison and synchronization settions as new header options
+ //set most-used comparison and synchronization settings as new header options
const CompConfig cmpCfgHead = cmpCfgStat.empty() ? CompConfig() :
std::max_element(cmpCfgStat.begin(), cmpCfgStat.end(),
[](const std::pair<CompConfig, int>& lhs, const std::pair<CompConfig, int>& rhs) { return lhs.second < rhs.second; })->first;
@@ -473,24 +484,24 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs)
//########################################################################################################################
FilterConfig globalFilter;
- const bool equalFilters = sameFilter(fpMerged);
- if (equalFilters)
+ const bool allFiltersEqual = std::all_of(fpMerged.begin(), fpMerged.end(), [&](const FolderPairEnh& fp) { return fp.localFilter == fpMerged[0].localFilter; });
+ if (allFiltersEqual)
globalFilter = fpMerged[0].localFilter;
//strip redundancy...
- for (auto fp = fpMerged.begin(); fp != fpMerged.end(); ++fp)
+ for (FolderPairEnh& fp : fpMerged)
{
//if local config matches output global config we don't need local one
- if (fp->altCmpConfig &&
- *fp->altCmpConfig == cmpCfgHead)
- fp->altCmpConfig.reset();
+ if (fp.altCmpConfig &&
+ effectivelyEqual(*fp.altCmpConfig, cmpCfgHead))
+ fp.altCmpConfig.reset();
- if (fp->altSyncConfig &&
- *fp->altSyncConfig == syncCfgHead)
- fp->altSyncConfig.reset();
+ if (fp.altSyncConfig &&
+ effectivelyEqual(*fp.altSyncConfig, syncCfgHead))
+ fp.altSyncConfig.reset();
- if (equalFilters) //use global filter in this case
- fp->localFilter = FilterConfig();
+ if (allFiltersEqual) //use global filter in this case
+ fp.localFilter = FilterConfig();
}
//final assembly
@@ -501,6 +512,5 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs)
cfgOut.firstPair = fpMerged[0];
cfgOut.additionalPairs.assign(fpMerged.begin() + 1, fpMerged.end());
cfgOut.onCompletion = mainCfgs[0].onCompletion;
-
return cfgOut;
}
bgstack15