Index: src/ch/FileFilter.cpp =================================================================== diff -u -r591f291e22d2ece89acb266c8aa0b05c257a407c -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/FileFilter.cpp (.../FileFilter.cpp) (revision 591f291e22d2ece89acb266c8aa0b05c257a407c) +++ src/ch/FileFilter.cpp (.../FileFilter.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -19,6 +19,7 @@ #include "stdafx.h" #include "FileInfo.h" #include "FileFilter.h" +#include "TConfig.h" //////////////////////////////////////////////////////////////////////////// bool _tcicmp(TCHAR c1, TCHAR c2) @@ -184,6 +185,124 @@ delete [] pszData; } +void CFileFilter::StoreInConfig(TConfig& rConfig) const +{ + rConfig.SetValue(_T("IncludeMask.Use"), m_bUseMask); + rConfig.SetValue(_T("IncludeMask.MaskList.Mask"), m_astrMask); + + rConfig.SetValue(_T("ExcludeMask.Use"), m_bUseExcludeMask); + rConfig.SetValue(_T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask); + + rConfig.SetValue(_T("SizeA.Use"), m_bUseSize); + rConfig.SetValue(_T("SizeA.FilteringType"), m_iSizeType1); + rConfig.SetValue(_T("SizeA.Value"), m_ullSize1); + rConfig.SetValue(_T("SizeB.Use"), m_bUseSize2); + rConfig.SetValue(_T("SizeB.FilteringType"), m_iSizeType2); + rConfig.SetValue(_T("SizeB.Value"), m_ullSize2); + + rConfig.SetValue(_T("DateA.Use"), m_bUseDate); + rConfig.SetValue(_T("DateA.Type"), m_iDateType); // created/last modified/last accessed + rConfig.SetValue(_T("DateA.FilteringType"), m_iDateType1); // before/after + rConfig.SetValue(_T("DateA.EnableDatePart"), m_bDate1); + rConfig.SetValue(_T("DateA.DateValue"), m_tDate1.GetTime()); + rConfig.SetValue(_T("DateA.EnableTimePart"), m_bTime1); + rConfig.SetValue(_T("DateA.TimeValue"), m_tTime1.GetTime()); + + rConfig.SetValue(_T("DateB.Type"), m_bUseDate2); + rConfig.SetValue(_T("DateB.FilteringType"), m_iDateType2); + rConfig.SetValue(_T("DateB.EnableDatePart"), m_bDate2); + rConfig.SetValue(_T("DateB.DateValue"), m_tDate2.GetTime()); + rConfig.SetValue(_T("DateB.EnableTimePart"), m_bTime2); + rConfig.SetValue(_T("DateB.TimeValue"), m_tTime2.GetTime()); + + rConfig.SetValue(_T("Attributes.Use"), m_bUseAttributes); + rConfig.SetValue(_T("Attributes.Archive"), m_iArchive); + rConfig.SetValue(_T("Attributes.ReadOnly"), m_iReadOnly); + rConfig.SetValue(_T("Attributes.Hidden"), m_iHidden); + rConfig.SetValue(_T("Attributes.System"), m_iSystem); + rConfig.SetValue(_T("Attributes.Directory"), m_iDirectory); +} + +void CFileFilter::ReadFromConfig(const TConfig& rConfig) +{ + __time64_t tTime = 0; + + if(!rConfig.GetValue(_T("IncludeMask.Use"), m_bUseMask)) + m_bUseMask = false; + + m_astrMask.clear(); + rConfig.GetValue(_T("IncludeMask.MaskList.Mask"), m_astrMask); + + if(!rConfig.GetValue(_T("ExcludeMask.Use"), m_bUseExcludeMask)) + m_bUseExcludeMask = false; + + m_astrExcludeMask.clear(); + rConfig.GetValue(_T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask); + + if(!rConfig.GetValue(_T("SizeA.Use"), m_bUseSize)) + m_bUseSize = false; + if(!rConfig.GetValue(_T("SizeA.FilteringType"), m_iSizeType1)) + m_iSizeType1 = EQ; + if(!rConfig.GetValue(_T("SizeA.Value"), m_ullSize1)) + m_ullSize1 = 0; + if(!rConfig.GetValue(_T("SizeB.Use"), m_bUseSize2)) + m_bUseSize2 = false; + if(!rConfig.GetValue(_T("SizeB.FilteringType"), m_iSizeType2)) + m_iSizeType2 = EQ; + if(!rConfig.GetValue(_T("SizeB.Value"), m_ullSize2)) + m_ullSize2 = 0; + + if(!rConfig.GetValue(_T("DateA.Use"), m_bUseDate)) + m_bUseDate = false; + + if(!rConfig.GetValue(_T("DateA.Type"), m_iDateType)) // created/last modified/last accessed + m_iDateType = DATE_CREATED; + if(!rConfig.GetValue(_T("DateA.FilteringType"), m_iDateType1)) // before/after + m_iDateType1 = EQ; + if(!rConfig.GetValue(_T("DateA.EnableDatePart"), m_bDate1)) + m_bDate1 = false; + + if(!rConfig.GetValue(_T("DateA.DateValue"), tTime)) + tTime = 0; + m_tDate1 = tTime; + + if(!rConfig.GetValue(_T("DateA.EnableTimePart"), m_bTime1)) + m_bTime1 = false; + + if(!rConfig.GetValue(_T("DateA.TimeValue"), tTime)) + tTime = 0; + m_tTime1 = tTime; + + if(!rConfig.GetValue(_T("DateB.Type"), m_bUseDate2)) + m_bUseDate2 = false; + if(!rConfig.GetValue(_T("DateB.FilteringType"), m_iDateType2)) + m_iDateType2 = EQ; + if(!rConfig.GetValue(_T("DateB.EnableDatePart"), m_bDate2)) + m_bDate2 = false; + + if(!rConfig.GetValue(_T("DateB.DateValue"), tTime)) + tTime = 0; + m_tDate2 = tTime; + if(!rConfig.GetValue(_T("DateB.EnableTimePart"), m_bTime2)) + m_bTime2 = false; + if(!rConfig.GetValue(_T("DateB.TimeValue"), tTime)) + tTime = 0; + m_tTime2 = tTime; + + if(!rConfig.GetValue(_T("Attributes.Use"), m_bUseAttributes)) + m_bUseAttributes = false; + if(!rConfig.GetValue(_T("Attributes.Archive"), m_iArchive)) + m_iArchive = 0; + if(!rConfig.GetValue(_T("Attributes.ReadOnly"), m_iReadOnly)) + m_iReadOnly = false; + if(!rConfig.GetValue(_T("Attributes.Hidden"), m_iHidden)) + m_iHidden = 0; + if(!rConfig.GetValue(_T("Attributes.System"), m_iSystem)) + m_iSystem = 0; + if(!rConfig.GetValue(_T("Attributes.Directory"), m_iDirectory)) + m_iDirectory = 0; +} + bool CFileFilter::Match(const CFileInfoPtr& spInfo) const { // check by mask @@ -467,6 +586,32 @@ return false; } +void CFiltersArray::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const +{ + rConfig.DeleteNode(pszNodeName); + BOOST_FOREACH(const CFileFilter& rFilter, m_vFilters) + { + TConfig cfgNode; + rFilter.StoreInConfig(cfgNode); + rConfig.AddSubConfig(CString(pszNodeName) + _T(".FilterDefinition"), cfgNode); + } +} + +void CFiltersArray::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) +{ + m_vFilters.clear(); + + std::vector vConfigs; + rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs); + BOOST_FOREACH(const TConfig& rCfg, vConfigs) + { + CFileFilter tFilter; + tFilter.ReadFromConfig(rCfg); + + m_vFilters.push_back(tFilter); + } +} + bool CFiltersArray::IsEmpty() const { return m_vFilters.empty(); Index: src/ch/FileFilter.h =================================================================== diff -u -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/FileFilter.h (.../FileFilter.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) +++ src/ch/FileFilter.h (.../FileFilter.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -31,6 +31,8 @@ #define DATE_MODIFIED 1 #define DATE_LASTACCESSED 2 +class TConfig; + class CFileFilter { public: @@ -46,6 +48,9 @@ CString& GetCombinedExcludeMask(CString& pMask) const; void SetCombinedExcludeMask(const CString& pMask); + void StoreInConfig(TConfig& rConfig) const; + void ReadFromConfig(const TConfig& rConfig); + template void serialize(Archive& ar, unsigned int /*uiVersion*/) { @@ -140,6 +145,9 @@ CFiltersArray& operator=(const CFiltersArray& rSrc); bool Match(const CFileInfoPtr& spInfo) const; + void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; + void ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + template void serialize(Archive& ar, unsigned int /*uiVersion*/) { Index: src/ch/MainWnd.cpp =================================================================== diff -u -r69b48f0b4d7fad78f95854e95fca166014311474 -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -530,14 +530,13 @@ SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); + ffFilters.StoreInConfig(tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + // create task with the above definition CTaskPtr spTask = m_tasks.CreateTask(); spTask->SetTaskDefinition(tTaskDefinition); - // set some stuff related with task - spTask->SetFilters(&ffFilters); - m_tasks.Add(spTask); // save state of a task @@ -620,12 +619,12 @@ SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); + dlg.m_ccData.m_afFilters.StoreInConfig(tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + // new task CTaskPtr spTask = m_tasks.CreateTask(); spTask->SetTaskDefinition(tTaskDefinition); - spTask->SetFilters(&dlg.m_ccData.m_afFilters); - m_tasks.Add(spTask); // save Index: src/ch/TConfig.cpp =================================================================== diff -u -r69b48f0b4d7fad78f95854e95fca166014311474 -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/TConfig.cpp (.../TConfig.cpp) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/TConfig.cpp (.../TConfig.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -470,6 +470,23 @@ rSubConfig.m_propTree = optChildren.get(); } +void TConfig::ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const +{ + TConfig cfg; + + boost::shared_lock lock(m_lock); + + boost::optional optChildren = m_propTree.get_child_optional(pszSubTreeName); + if(optChildren.is_initialized()) + { + BOOST_FOREACH(const boost::property_tree::wiptree::value_type& rEntry, optChildren.get()) + { + cfg.m_propTree = rEntry.second; + rSubConfigs.push_back(cfg); + } + } +} + void TConfig::PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig) { boost::unique_lock lock(m_lock); @@ -480,6 +497,22 @@ m_bModified = true; } +void TConfig::AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig) +{ + boost::unique_lock lock(m_lock); + boost::shared_lock src_lock(rSubConfig.m_lock); + + m_propTree.add_child(pszSubTreeName, rSubConfig.m_propTree); + + m_bModified = true; +} + +void TConfig::DeleteNode(PCTSTR pszNodeName) +{ + boost::unique_lock lock(m_lock); + m_propTree.erase(pszNodeName); +} + void TConfig::ConnectToNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam) { m_notifier.connect(TConfigNotifier(pfnCallback, pParam)); Index: src/ch/TConfig.h =================================================================== diff -u -r69b48f0b4d7fad78f95854e95fca166014311474 -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/TConfig.h (.../TConfig.h) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/TConfig.h (.../TConfig.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -111,9 +111,13 @@ bool GetValue(PCTSTR pszPropName, chcore::TPathContainer& rvValues) const; void SetValue(PCTSTR pszPropName, const chcore::TPathContainer& rvValues); + void DeleteNode(PCTSTR pszNodeName); + // extraction of subtrees void ExtractSubConfig(PCTSTR pszSubTreeName, TConfig& rSubConfig) const; + void ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const; void PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); + void AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); // property change notification void ConnectToNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam); Index: src/ch/TTaskConfigTracker.cpp =================================================================== diff -u -rb42450e5a25470c399e04cfbb7a368519aa455f2 -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/TTaskConfigTracker.cpp (.../TTaskConfigTracker.cpp) (revision b42450e5a25470c399e04cfbb7a368519aa455f2) +++ src/ch/TTaskConfigTracker.cpp (.../TTaskConfigTracker.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -232,12 +232,14 @@ return eTO_AlternateFilenameFormatString_AfterFirst; else if(strOption == TaskPropData::GetPropertyName()) return eTO_AlternateFilenameFormatString_First; + else if(strOption == TASK_PROP_NAME_FILTERING) + return eTO_Filters; else { BOOST_ASSERT(false); // unhandled case THROW(_T("Unhandled case"), 0, 0, 0); } // add new elements before this one - BOOST_STATIC_ASSERT(eTO_Last == eTO_AlternateFilenameFormatString_AfterFirst + 1); + BOOST_STATIC_ASSERT(eTO_Last == eTO_Filters + 1); } Index: src/ch/TTaskConfiguration.h =================================================================== diff -u -rb42450e5a25470c399e04cfbb7a368519aa455f2 -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/TTaskConfiguration.h (.../TTaskConfiguration.h) (revision b42450e5a25470c399e04cfbb7a368519aa455f2) +++ src/ch/TTaskConfiguration.h (.../TTaskConfiguration.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -51,6 +51,8 @@ eTO_AlternateFilenameFormatString_First, eTO_AlternateFilenameFormatString_AfterFirst, + eTO_Filters, + // add new elements before this one eTO_Last }; @@ -109,6 +111,10 @@ TASK_PROPERTY(eTO_AlternateFilenameFormatString_AfterFirst, CString, _T("Naming.AlternateFilenameFormatAfterFirst"), _T("Copy (%count) of %name")); ///////////////////////////////////////////////////////////////////////////////////////////// +// other properties names +#define TASK_PROP_NAME_FILTERING _T("Filtering") + +///////////////////////////////////////////////////////////////////////////////////////////// // Properties retrieval template typename TaskPropData::value_type GetTaskPropValue(const TConfig& rConfig) @@ -128,4 +134,5 @@ rConfig.SetPropValue >(rValue); } + #endif Index: src/ch/task.cpp =================================================================== diff -u -r591f291e22d2ece89acb266c8aa0b05c257a407c -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/task.cpp (.../task.cpp) (revision 591f291e22d2ece89acb266c8aa0b05c257a407c) +++ src/ch/task.cpp (.../task.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -590,8 +590,10 @@ m_tTaskDefinition.Load(strPath); m_strFilePath = strPath; + // update members according to the task definition // make sure to resize paths info array size to match source paths count m_arrSourcePathsInfo.SetCount(m_tTaskDefinition.GetSourcePathCount()); + m_afFilters.ReadFromConfig(m_tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); //////////////////////////////// // now rarely changing task progress data @@ -604,8 +606,6 @@ CalculateTotalSizeNL(); - ar >> m_afFilters; - /////////////////////////////////// // and often changing data CString strOftenChangingPath = GetRelatedPathNL(ePathType_TaskOftenChangingState); @@ -665,8 +665,6 @@ m_arrSourcePathsInfo.Store(ar, 0, true); m_files.Store(ar, 0, false); - - ar << m_afFilters; } if(m_bOftenStateModified) @@ -829,7 +827,7 @@ pData->m_nPriority = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); pData->m_pathDstPath = m_tTaskDefinition.GetDestinationPath(); - pData->m_pafFilters=&m_afFilters; + pData->m_pafFilters = &m_afFilters; pData->m_eTaskState = m_eCurrentState; pData->m_stIndex = stCurrentIndex; pData->m_ullProcessedSize = m_localStats.GetProcessedSize(); @@ -897,16 +895,6 @@ } } -void CTask::SetFilters(const CFiltersArray* pFilters) -{ - BOOST_ASSERT(pFilters); - if(!pFilters) - THROW(_T("Invalid argument"), 0, 0, 0); - - boost::unique_lock lock(m_lock); - m_afFilters = *pFilters; -} - bool CTask::CanBegin() { bool bRet=true; @@ -1045,6 +1033,9 @@ // delete the content of m_files m_files.Clear(); + // read filtering options + m_afFilters.ReadFromConfig(m_tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + // enter some data to m_files int iDestDrvNumber = 0; GetDriveData(m_tTaskDefinition.GetDestinationPath(), &iDestDrvNumber, NULL); Index: src/ch/task.h =================================================================== diff -u -r3fc1109991e7311d6b1e34ef0b730f9b4e1fd42a -rc54aa186fda8c0af84325325276245e9d8fcfa26 --- src/ch/task.h (.../task.h) (revision 3fc1109991e7311d6b1e34ef0b730f9b4e1fd42a) +++ src/ch/task.h (.../task.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) @@ -278,8 +278,6 @@ void SetTaskDefinition(const TTaskDefinition& rTaskDefinition); const TTaskDefinition& GetTaskDefinition() const { return m_tTaskDefinition; } - void SetFilters(const CFiltersArray* pFilters); - void SetTaskState(ETaskCurrentState eTaskState); ETaskCurrentState GetTaskState() const; @@ -412,9 +410,6 @@ TBasePathDataContainer m_arrSourcePathsInfo; - // task settings - CFiltersArray m_afFilters; // filtering settings for files (will be filtered according to the rules inside when searching for files) - // current task state (derivatives of the task initial information) // changing slowly or only partially CFileInfoArray m_files; // list of files/directories found during operating on the task input data (filled by search for files) @@ -427,6 +422,9 @@ // task control variables (per-session state) TTaskLocalStats m_localStats; // local statistics + // task settings + CFiltersArray m_afFilters; // filtering settings for files (will be filtered according to the rules inside when searching for files) + bool m_bForce; // if the continuation of tasks should be independent of max concurrently running task limit bool m_bContinue; // allows task to continue