2020-04-29 13:02:18 -07:00
# include "pch.h"
2019-10-17 20:57:19 -07:00
# include "PowerRenameRegEx.h"
2023-08-14 16:53:49 +02:00
# include "Enumerating.h"
2020-11-09 19:13:43 +01:00
# include "Settings.h"
2019-10-17 20:57:19 -07:00
# include <regex>
# include <string>
# include <algorithm>
2020-11-09 19:13:43 +01:00
# include <boost/regex.hpp>
2020-12-21 18:51:48 +03:00
# include <helpers.h>
2019-10-17 20:57:19 -07:00
2023-08-14 16:53:49 +02:00
using std : : conditional_t ;
2019-10-17 20:57:19 -07:00
using std : : regex_error ;
2023-08-14 16:53:49 +02:00
IFACEMETHODIMP_ ( ULONG )
CPowerRenameRegEx : : AddRef ( )
2019-10-17 20:57:19 -07:00
{
return InterlockedIncrement ( & m_refCount ) ;
}
2023-08-14 16:53:49 +02:00
IFACEMETHODIMP_ ( ULONG )
CPowerRenameRegEx : : Release ( )
2019-10-17 20:57:19 -07:00
{
long refCount = InterlockedDecrement ( & m_refCount ) ;
if ( refCount = = 0 )
{
delete this ;
}
return refCount ;
}
IFACEMETHODIMP CPowerRenameRegEx : : QueryInterface ( _In_ REFIID riid , _Outptr_ void * * ppv )
{
static const QITAB qit [ ] = {
QITABENT ( CPowerRenameRegEx , IPowerRenameRegEx ) ,
{ 0 }
} ;
return QISearch ( this , qit , riid , ppv ) ;
}
IFACEMETHODIMP CPowerRenameRegEx : : Advise ( _In_ IPowerRenameRegExEvents * regExEvents , _Out_ DWORD * cookie )
{
CSRWExclusiveAutoLock lock ( & m_lockEvents ) ;
m_cookie + + ;
2019-11-11 11:00:42 -08:00
RENAME_REGEX_EVENT srre ;
2019-10-17 20:57:19 -07:00
srre . cookie = m_cookie ;
srre . pEvents = regExEvents ;
regExEvents - > AddRef ( ) ;
2019-11-11 11:00:42 -08:00
m_renameRegExEvents . push_back ( srre ) ;
2019-10-17 20:57:19 -07:00
* cookie = m_cookie ;
return S_OK ;
}
IFACEMETHODIMP CPowerRenameRegEx : : UnAdvise ( _In_ DWORD cookie )
{
HRESULT hr = E_FAIL ;
CSRWExclusiveAutoLock lock ( & m_lockEvents ) ;
2019-11-11 20:58:39 -08:00
for ( std : : vector < RENAME_REGEX_EVENT > : : iterator it = m_renameRegExEvents . begin ( ) ; it ! = m_renameRegExEvents . end ( ) ; + + it )
2019-10-17 20:57:19 -07:00
{
2019-11-11 20:58:39 -08:00
if ( it - > cookie = = cookie )
2019-10-17 20:57:19 -07:00
{
hr = S_OK ;
2019-11-11 20:58:39 -08:00
it - > cookie = 0 ;
if ( it - > pEvents )
2019-10-17 20:57:19 -07:00
{
2019-11-11 20:58:39 -08:00
it - > pEvents - > Release ( ) ;
it - > pEvents = nullptr ;
2019-10-17 20:57:19 -07:00
}
break ;
}
}
return hr ;
}
2020-08-25 08:22:05 +03:00
IFACEMETHODIMP CPowerRenameRegEx : : GetSearchTerm ( _Outptr_ PWSTR * searchTerm )
2019-10-17 20:57:19 -07:00
{
* searchTerm = nullptr ;
2020-12-14 12:28:12 +03:00
HRESULT hr = S_OK ;
if ( m_searchTerm )
2019-10-17 20:57:19 -07:00
{
CSRWSharedAutoLock lock ( & m_lock ) ;
hr = SHStrDup ( m_searchTerm , searchTerm ) ;
}
return hr ;
}
2021-10-25 15:40:19 +02:00
IFACEMETHODIMP CPowerRenameRegEx : : PutSearchTerm ( _In_ PCWSTR searchTerm , bool forceRenaming )
2019-10-17 20:57:19 -07:00
{
2021-10-25 15:40:19 +02:00
bool changed = false | | forceRenaming ;
2020-12-14 12:28:12 +03:00
HRESULT hr = S_OK ;
if ( searchTerm )
2019-10-17 20:57:19 -07:00
{
CSRWExclusiveAutoLock lock ( & m_lock ) ;
if ( m_searchTerm = = nullptr | | lstrcmp ( searchTerm , m_searchTerm ) ! = 0 )
{
changed = true ;
CoTaskMemFree ( m_searchTerm ) ;
2021-10-25 15:40:19 +02:00
if ( lstrcmp ( searchTerm , L " " ) = = 0 )
{
m_searchTerm = NULL ;
}
else
{
hr = SHStrDup ( searchTerm , & m_searchTerm ) ;
}
2019-10-17 20:57:19 -07:00
}
}
if ( SUCCEEDED ( hr ) & & changed )
{
_OnSearchTermChanged ( ) ;
}
return hr ;
}
2020-08-25 08:22:05 +03:00
IFACEMETHODIMP CPowerRenameRegEx : : GetReplaceTerm ( _Outptr_ PWSTR * replaceTerm )
2019-10-17 20:57:19 -07:00
{
* replaceTerm = nullptr ;
2020-12-14 12:28:12 +03:00
HRESULT hr = S_OK ;
if ( m_replaceTerm )
2019-10-17 20:57:19 -07:00
{
CSRWSharedAutoLock lock ( & m_lock ) ;
hr = SHStrDup ( m_replaceTerm , replaceTerm ) ;
}
return hr ;
}
2024-06-20 18:26:31 +03:00
HRESULT CPowerRenameRegEx : : _OnEnumerateOrRandomizeItemsChanged ( )
2023-08-14 16:53:49 +02:00
{
m_enumerators . clear ( ) ;
2024-06-20 18:26:31 +03:00
m_randomizer . clear ( ) ;
2023-08-14 16:53:49 +02:00
2024-06-20 18:26:31 +03:00
if ( m_flags & RandomizeItems )
{
const auto options = parseRandomizerOptions ( m_RawReplaceTerm ) ;
for ( const auto & option : options )
{
m_randomizer . emplace_back ( option ) ;
}
}
if ( m_flags & EnumerateItems )
{
const auto options = parseEnumOptions ( m_RawReplaceTerm ) ;
for ( const auto & option : options )
{
if ( m_randomizer . end ( ) = =
std : : find_if (
m_randomizer . begin ( ) ,
m_randomizer . end ( ) ,
[ option ] ( const Randomizer & r ) - > bool { return r . options . replaceStrSpan . offset = = option . replaceStrSpan . offset ; }
) )
{
// Only add as enumerator if we didn't find a randomizer already at this offset.
// Every randomizer will also be a valid enumerator according to the definition of enumerators, which allows any string to mean the default enumerator, so it should be interpreted that the user wanted a randomizer if both were found at the same offset of the replace string.
m_enumerators . emplace_back ( option ) ;
}
}
}
m_replaceWithRandomizerOffsets . clear ( ) ;
2023-08-14 16:53:49 +02:00
m_replaceWithEnumeratorOffsets . clear ( ) ;
2024-06-20 18:26:31 +03:00
int32_t offset = 0 ;
int ei = 0 ; // Enumerators index
int ri = 0 ; // Randomizer index
2023-08-14 16:53:49 +02:00
std : : wstring replaceWith { m_RawReplaceTerm } ;
// Remove counter expressions and calculate their offsets in replaceWith string.
2024-06-20 18:26:31 +03:00
if ( ( m_flags & EnumerateItems ) & & ( m_flags & RandomizeItems ) )
2023-08-14 16:53:49 +02:00
{
2024-06-20 18:26:31 +03:00
// Both flags are on, we need to merge which ones should be applied.
while ( ( ei < m_enumerators . size ( ) ) & & ( ri < m_randomizer . size ( ) ) )
{
const auto & e = m_enumerators [ ei ] ;
const auto & r = m_randomizer [ ri ] ;
if ( e . replaceStrSpan . offset < r . options . replaceStrSpan . offset )
{
// if the enumerator is next in line, remove counter expression and calculate offset with it.
replaceWith . erase ( e . replaceStrSpan . offset + offset , e . replaceStrSpan . length ) ;
m_replaceWithEnumeratorOffsets . push_back ( offset ) ;
offset - = static_cast < int32_t > ( e . replaceStrSpan . length ) ;
ei + + ;
}
else
{
// if the randomizer is next in line, remove randomizer expression and calculate offset with it.
replaceWith . erase ( r . options . replaceStrSpan . offset + offset , r . options . replaceStrSpan . length ) ;
m_replaceWithRandomizerOffsets . push_back ( offset ) ;
offset - = static_cast < int32_t > ( r . options . replaceStrSpan . length ) ;
ri + + ;
}
}
}
if ( m_flags & EnumerateItems )
{
// Continue with all remaining enumerators
while ( ei < m_enumerators . size ( ) )
{
const auto & e = m_enumerators [ ei ] ;
replaceWith . erase ( e . replaceStrSpan . offset + offset , e . replaceStrSpan . length ) ;
m_replaceWithEnumeratorOffsets . push_back ( offset ) ;
offset - = static_cast < int32_t > ( e . replaceStrSpan . length ) ;
ei + + ;
}
}
if ( m_flags & RandomizeItems )
{
// Continue with all remaining randomizer instances
while ( ri < m_randomizer . size ( ) )
{
const auto & r = m_randomizer [ ri ] ;
replaceWith . erase ( r . options . replaceStrSpan . offset + offset , r . options . replaceStrSpan . length ) ;
m_replaceWithRandomizerOffsets . push_back ( offset ) ;
offset - = static_cast < int32_t > ( r . options . replaceStrSpan . length ) ;
ri + + ;
}
2023-08-14 16:53:49 +02:00
}
2024-06-20 18:26:31 +03:00
2023-08-14 16:53:49 +02:00
return SHStrDup ( replaceWith . data ( ) , & m_replaceTerm ) ;
}
2021-10-25 15:40:19 +02:00
IFACEMETHODIMP CPowerRenameRegEx : : PutReplaceTerm ( _In_ PCWSTR replaceTerm , bool forceRenaming )
2019-10-17 20:57:19 -07:00
{
2021-10-25 15:40:19 +02:00
bool changed = false | | forceRenaming ;
2020-12-14 12:28:12 +03:00
HRESULT hr = S_OK ;
if ( replaceTerm )
2019-10-17 20:57:19 -07:00
{
CSRWExclusiveAutoLock lock ( & m_lock ) ;
2023-08-14 16:53:49 +02:00
if ( m_replaceTerm = = nullptr | | lstrcmp ( replaceTerm , m_RawReplaceTerm . c_str ( ) ) ! = 0 )
2019-10-17 20:57:19 -07:00
{
changed = true ;
CoTaskMemFree ( m_replaceTerm ) ;
2023-08-14 16:53:49 +02:00
m_RawReplaceTerm = replaceTerm ;
2024-06-20 18:26:31 +03:00
if ( ( m_flags & RandomizeItems ) | | ( m_flags & EnumerateItems ) )
hr = _OnEnumerateOrRandomizeItemsChanged ( ) ;
2023-08-14 16:53:49 +02:00
else
hr = SHStrDup ( replaceTerm , & m_replaceTerm ) ;
2019-10-17 20:57:19 -07:00
}
}
if ( SUCCEEDED ( hr ) & & changed )
{
_OnReplaceTermChanged ( ) ;
}
return hr ;
}
2020-08-25 08:22:05 +03:00
IFACEMETHODIMP CPowerRenameRegEx : : GetFlags ( _Out_ DWORD * flags )
2019-10-17 20:57:19 -07:00
{
* flags = m_flags ;
return S_OK ;
}
2020-08-25 08:22:05 +03:00
IFACEMETHODIMP CPowerRenameRegEx : : PutFlags ( _In_ DWORD flags )
2019-10-17 20:57:19 -07:00
{
if ( m_flags ! = flags )
{
2023-08-14 16:53:49 +02:00
const bool newEnumerate = flags & EnumerateItems ;
2024-06-20 18:26:31 +03:00
const bool newRandomizer = flags & RandomizeItems ;
const bool refreshReplaceTerm =
( ! ! ( m_flags & EnumerateItems ) ! = newEnumerate ) | |
( ! ! ( m_flags & RandomizeItems ) ! = newRandomizer ) ;
2019-10-17 20:57:19 -07:00
m_flags = flags ;
2024-06-20 18:26:31 +03:00
2023-08-14 16:53:49 +02:00
if ( refreshReplaceTerm )
{
CSRWExclusiveAutoLock lock ( & m_lock ) ;
2024-06-20 18:26:31 +03:00
if ( newEnumerate | | newRandomizer )
{
_OnEnumerateOrRandomizeItemsChanged ( ) ;
}
2023-08-14 16:53:49 +02:00
else
{
CoTaskMemFree ( m_replaceTerm ) ;
SHStrDup ( m_RawReplaceTerm . c_str ( ) , & m_replaceTerm ) ;
}
}
2019-10-17 20:57:19 -07:00
_OnFlagsChanged ( ) ;
}
return S_OK ;
}
2020-12-14 12:28:12 +03:00
IFACEMETHODIMP CPowerRenameRegEx : : PutFileTime ( _In_ SYSTEMTIME fileTime )
{
union timeunion
{
FILETIME fileTime ;
ULARGE_INTEGER ul ;
} ;
timeunion ft1 ;
timeunion ft2 ;
SystemTimeToFileTime ( & m_fileTime , & ft1 . fileTime ) ;
SystemTimeToFileTime ( & fileTime , & ft2 . fileTime ) ;
if ( ft2 . ul . QuadPart ! = ft1 . ul . QuadPart )
{
m_fileTime = fileTime ;
m_useFileTime = true ;
_OnFileTimeChanged ( ) ;
}
return S_OK ;
}
IFACEMETHODIMP CPowerRenameRegEx : : ResetFileTime ( )
{
SYSTEMTIME ZERO = { 0 } ;
m_fileTime = ZERO ;
m_useFileTime = false ;
_OnFileTimeChanged ( ) ;
return S_OK ;
}
2019-10-17 20:57:19 -07:00
HRESULT CPowerRenameRegEx : : s_CreateInstance ( _Outptr_ IPowerRenameRegEx * * renameRegEx )
{
* renameRegEx = nullptr ;
2023-08-14 16:53:49 +02:00
CPowerRenameRegEx * newRenameRegEx = new CPowerRenameRegEx ( ) ;
2020-12-14 12:28:12 +03:00
HRESULT hr = E_OUTOFMEMORY ;
if ( newRenameRegEx )
2019-10-17 20:57:19 -07:00
{
hr = newRenameRegEx - > QueryInterface ( IID_PPV_ARGS ( renameRegEx ) ) ;
newRenameRegEx - > Release ( ) ;
}
return hr ;
}
CPowerRenameRegEx : : CPowerRenameRegEx ( ) :
m_refCount ( 1 )
{
// Init to empty strings
SHStrDup ( L " " , & m_searchTerm ) ;
SHStrDup ( L " " , & m_replaceTerm ) ;
2020-11-09 19:13:43 +01:00
_useBoostLib = CSettingsInstance ( ) . GetUseBoostLib ( ) ;
2019-10-17 20:57:19 -07:00
}
CPowerRenameRegEx : : ~ CPowerRenameRegEx ( )
{
CoTaskMemFree ( m_searchTerm ) ;
CoTaskMemFree ( m_replaceTerm ) ;
}
2023-08-14 16:53:49 +02:00
template < bool Std , class Regex = conditional_t < Std , std : : wregex , boost : : wregex > , class Options = decltype ( Regex : : icase ) >
static std : : wstring RegexReplaceEx ( const std : : wstring & source , const std : : wstring & searchTerm , const std : : wstring & replaceTerm , const bool matchAll , const bool caseInsensitive )
{
Regex pattern ( searchTerm , Options : : ECMAScript | ( caseInsensitive ? Options : : icase : Options { } ) ) ;
using Flags = conditional_t < Std , std : : regex_constants : : match_flag_type , boost : : regex_constants : : match_flags > ;
const auto flags = matchAll ? Flags : : match_default : Flags : : format_first_only ;
return regex_replace ( source , pattern , replaceTerm , flags ) ;
}
static constexpr std : : array RegexReplaceDispatch = { RegexReplaceEx < true > , RegexReplaceEx < false > } ;
HRESULT CPowerRenameRegEx : : Replace ( _In_ PCWSTR source , _Outptr_ PWSTR * result , unsigned long & enumIndex )
2019-10-17 20:57:19 -07:00
{
* result = nullptr ;
CSRWSharedAutoLock lock ( & m_lock ) ;
2020-12-14 12:28:12 +03:00
HRESULT hr = S_OK ;
if ( ! ( m_searchTerm & & wcslen ( m_searchTerm ) > 0 & & source & & wcslen ( source ) > 0 ) )
2019-10-17 20:57:19 -07:00
{
2020-12-14 12:28:12 +03:00
return hr ;
}
2023-08-14 16:53:49 +02:00
std : : wstring res = source ;
2020-12-14 12:28:12 +03:00
try
{
// TODO: creating the regex could be costly. May want to cache this.
wchar_t newReplaceTerm [ MAX_PATH ] = { 0 } ;
bool fileTimeErrorOccurred = false ;
if ( m_useFileTime )
{
if ( FAILED ( GetDatedFileName ( newReplaceTerm , ARRAYSIZE ( newReplaceTerm ) , m_replaceTerm , m_fileTime ) ) )
fileTimeErrorOccurred = true ;
}
2023-08-14 16:53:49 +02:00
std : : wstring sourceToUse ;
std : : wstring originalSource ;
sourceToUse . reserve ( MAX_PATH ) ;
originalSource . reserve ( MAX_PATH ) ;
sourceToUse = source ;
originalSource = sourceToUse ;
2020-12-14 12:28:12 +03:00
std : : wstring searchTerm ( m_searchTerm ) ;
2023-08-14 16:53:49 +02:00
std : : wstring replaceTerm ;
2020-12-14 12:28:12 +03:00
if ( m_useFileTime & & ! fileTimeErrorOccurred )
{
2023-08-14 16:53:49 +02:00
replaceTerm = newReplaceTerm ;
2020-12-14 12:28:12 +03:00
}
else if ( m_replaceTerm )
2019-10-17 20:57:19 -07:00
{
2023-08-14 16:53:49 +02:00
replaceTerm = m_replaceTerm ;
2020-12-14 12:28:12 +03:00
}
2019-10-17 20:57:19 -07:00
2023-08-14 16:53:49 +02:00
static const std : : wregex zeroGroupRegex ( L " (([^ \\ $]|^)( \\ $ \\ $)*) \\ $[0] " ) ;
static const std : : wregex otherGroupsRegex ( L " (([^ \\ $]|^)( \\ $ \\ $)*) \\ $([1-9]) " ) ;
2020-07-23 00:12:46 +03:00
2024-06-20 18:26:31 +03:00
if ( ( m_flags & EnumerateItems ) | | ( m_flags & RandomizeItems ) )
2020-12-14 12:28:12 +03:00
{
2024-06-20 18:26:31 +03:00
int ei = 0 ; // Enumerators index
int ri = 0 ; // Randomizer index
2023-08-14 16:53:49 +02:00
std : : array < wchar_t , MAX_PATH > buffer ;
int32_t offset = 0 ;
2024-06-20 18:26:31 +03:00
if ( ( m_flags & EnumerateItems ) & & ( m_flags & RandomizeItems ) )
{
// Both flags are on, we need to merge which ones should be applied.
while ( ( ei < m_enumerators . size ( ) ) & & ( ri < m_randomizer . size ( ) ) )
{
const auto & e = m_enumerators [ ei ] ;
const auto & r = m_randomizer [ ri ] ;
if ( e . replaceStrSpan . offset < r . options . replaceStrSpan . offset )
{
// if the enumerator is next in line, apply it.
const auto replacementLength = static_cast < int32_t > ( e . printTo ( buffer . data ( ) , buffer . size ( ) , enumIndex ) ) ;
replaceTerm . insert ( e . replaceStrSpan . offset + offset + m_replaceWithEnumeratorOffsets [ ei ] , buffer . data ( ) ) ;
offset + = replacementLength ;
ei + + ;
}
else
{
// if the randomizer is next in line, apply it.
std : : string randomValue = r . randomize ( ) ;
std : : wstring wRandomValue ( randomValue . begin ( ) , randomValue . end ( ) ) ;
replaceTerm . insert ( r . options . replaceStrSpan . offset + offset + m_replaceWithRandomizerOffsets [ ri ] , wRandomValue ) ;
offset + = static_cast < int32_t > ( wRandomValue . length ( ) ) ;
if ( e . replaceStrSpan . offset = = r . options . replaceStrSpan . offset )
{
// In theory, this shouldn't happen here as we were guarding against it when filling the randomizer and enumerator structures, but it's still here as a fail safe.
// Every randomizer will also be a valid enumerator according to the definition of enumerators, which allow any string to mean the default enumerator, so it should be interpreted that the user wanted a randomizer if both were found at the same offset of the replace string.
ei + + ;
}
ri + + ;
}
}
}
if ( m_flags & EnumerateItems )
{
// Replace all remaining enumerators
while ( ei < m_enumerators . size ( ) )
{
const auto & e = m_enumerators [ ei ] ;
const auto replacementLength = static_cast < int32_t > ( e . printTo ( buffer . data ( ) , buffer . size ( ) , enumIndex ) ) ;
replaceTerm . insert ( e . replaceStrSpan . offset + offset + m_replaceWithEnumeratorOffsets [ ei ] , buffer . data ( ) ) ;
offset + = replacementLength ;
ei + + ;
}
}
if ( m_flags & RandomizeItems )
2019-10-17 20:57:19 -07:00
{
2024-06-20 18:26:31 +03:00
// Replace all remaining randomizer instances
while ( ri < m_randomizer . size ( ) )
{
const auto & r = m_randomizer [ ri ] ;
std : : string randomValue = r . randomize ( ) ;
std : : wstring wRandomValue ( randomValue . begin ( ) , randomValue . end ( ) ) ;
replaceTerm . insert ( r . options . replaceStrSpan . offset + offset + m_replaceWithRandomizerOffsets [ ri ] , wRandomValue ) ;
offset + = static_cast < int32_t > ( wRandomValue . length ( ) ) ;
ri + + ;
}
2019-10-17 20:57:19 -07:00
}
}
2023-08-14 16:53:49 +02:00
bool replacedSomething = false ;
if ( m_flags & UseRegularExpressions )
{
replaceTerm = regex_replace ( replaceTerm , zeroGroupRegex , L " $1$$$0 " ) ;
replaceTerm = regex_replace ( replaceTerm , otherGroupsRegex , L " $1$0$4 " ) ;
res = RegexReplaceDispatch [ _useBoostLib ] ( source , m_searchTerm , replaceTerm , m_flags & MatchAllOccurrences , ! ( m_flags & CaseSensitive ) ) ;
replacedSomething = originalSource ! = res ;
}
2020-12-14 12:28:12 +03:00
else
2019-10-17 20:57:19 -07:00
{
2020-12-14 12:28:12 +03:00
// Simple search and replace
size_t pos = 0 ;
do
{
pos = _Find ( sourceToUse , searchTerm , ( ! ( m_flags & CaseSensitive ) ) , pos ) ;
if ( pos ! = std : : string : : npos )
{
res = sourceToUse . replace ( pos , searchTerm . length ( ) , replaceTerm ) ;
pos + = replaceTerm . length ( ) ;
2023-08-14 16:53:49 +02:00
replacedSomething = true ;
2020-12-14 12:28:12 +03:00
}
2022-07-01 10:09:41 -04:00
if ( ! ( m_flags & MatchAllOccurrences ) )
2020-12-14 12:28:12 +03:00
{
break ;
}
} while ( pos ! = std : : string : : npos ) ;
2019-10-17 20:57:19 -07:00
}
2020-12-14 12:28:12 +03:00
hr = SHStrDup ( res . c_str ( ) , result ) ;
2023-08-14 16:53:49 +02:00
if ( replacedSomething )
enumIndex + + ;
2020-12-14 12:28:12 +03:00
}
catch ( regex_error e )
{
hr = E_FAIL ;
2019-10-17 20:57:19 -07:00
}
return hr ;
}
size_t CPowerRenameRegEx : : _Find ( std : : wstring data , std : : wstring toSearch , bool caseInsensitive , size_t pos )
{
if ( caseInsensitive )
{
// Convert to lower
std : : transform ( data . begin ( ) , data . end ( ) , data . begin ( ) , : : towlower ) ;
std : : transform ( toSearch . begin ( ) , toSearch . end ( ) , toSearch . begin ( ) , : : towlower ) ;
}
// Find sub string position in given string starting at position pos
return data . find ( toSearch , pos ) ;
}
void CPowerRenameRegEx : : _OnSearchTermChanged ( )
{
CSRWSharedAutoLock lock ( & m_lockEvents ) ;
2019-11-11 11:00:42 -08:00
for ( auto it : m_renameRegExEvents )
2019-10-17 20:57:19 -07:00
{
if ( it . pEvents )
{
it . pEvents - > OnSearchTermChanged ( m_searchTerm ) ;
}
}
}
void CPowerRenameRegEx : : _OnReplaceTermChanged ( )
{
CSRWSharedAutoLock lock ( & m_lockEvents ) ;
2019-11-11 11:00:42 -08:00
for ( auto it : m_renameRegExEvents )
2019-10-17 20:57:19 -07:00
{
if ( it . pEvents )
{
it . pEvents - > OnReplaceTermChanged ( m_replaceTerm ) ;
}
}
}
void CPowerRenameRegEx : : _OnFlagsChanged ( )
{
CSRWSharedAutoLock lock ( & m_lockEvents ) ;
2019-11-11 11:00:42 -08:00
for ( auto it : m_renameRegExEvents )
2019-10-17 20:57:19 -07:00
{
if ( it . pEvents )
{
it . pEvents - > OnFlagsChanged ( m_flags ) ;
}
}
}
2020-12-14 12:28:12 +03:00
void CPowerRenameRegEx : : _OnFileTimeChanged ( )
{
CSRWSharedAutoLock lock ( & m_lockEvents ) ;
for ( auto it : m_renameRegExEvents )
{
if ( it . pEvents )
{
it . pEvents - > OnFileTimeChanged ( m_fileTime ) ;
}
}
}