[PowerRename] Don't treat extensions for folders (#14908)

* Dont treat extensions for folders

* Simplify fix and add test

* Add try/catch

* Update test to avoid updating spellcheck
This commit is contained in:
Stefan Markovic
2021-12-14 14:42:37 +01:00
committed by GitHub
parent f5d2f86c23
commit d359b3adc8
4 changed files with 119 additions and 72 deletions

View File

@@ -42,13 +42,23 @@ HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source)
return hr; return hr;
} }
HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, DWORD flags) HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, DWORD flags, bool isFolder)
{ {
std::locale::global(std::locale("")); std::locale::global(std::locale(""));
HRESULT hr = E_INVALIDARG; HRESULT hr = E_INVALIDARG;
if (source && flags) if (source && flags)
{ {
if (flags & Uppercase) if (flags & Uppercase)
{
if (isFolder)
{
hr = StringCchCopy(result, cchMax, source);
if (SUCCEEDED(hr))
{
std::transform(result, result + wcslen(result), result, ::towupper);
}
}
else
{ {
if (flags & NameOnly) if (flags & NameOnly)
{ {
@@ -82,7 +92,18 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
} }
} }
} }
}
else if (flags & Lowercase) else if (flags & Lowercase)
{
if (isFolder)
{
hr = StringCchCopy(result, cchMax, source);
if (SUCCEEDED(hr))
{
std::transform(result, result + wcslen(result), result, ::towlower);
}
}
else
{ {
if (flags & NameOnly) if (flags & NameOnly)
{ {
@@ -116,13 +137,14 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
} }
} }
} }
}
else if (flags & Titlecase) else if (flags & Titlecase)
{ {
if (!(flags & ExtensionOnly)) if (!(flags & ExtensionOnly))
{ {
std::vector<std::wstring> exceptions = { L"a", L"an", L"to", L"the", L"at", L"by", L"for", L"in", L"of", L"on", L"up", L"and", L"as", L"but", L"or", L"nor" }; std::vector<std::wstring> exceptions = { L"a", L"an", L"to", L"the", L"at", L"by", L"for", L"in", L"of", L"on", L"up", L"and", L"as", L"but", L"or", L"nor" };
std::wstring stem = fs::path(source).stem().wstring(); std::wstring stem = isFolder ? source : fs::path(source).stem().wstring();
std::wstring extension = fs::path(source).extension().wstring(); std::wstring extension = isFolder ? L"" : fs::path(source).extension().wstring();
size_t stemLength = stem.length(); size_t stemLength = stem.length();
bool isFirstWord = true; bool isFirstWord = true;
@@ -171,8 +193,8 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
{ {
if (!(flags & ExtensionOnly)) if (!(flags & ExtensionOnly))
{ {
std::wstring stem = fs::path(source).stem().wstring(); std::wstring stem = isFolder ? source : fs::path(source).stem().wstring();
std::wstring extension = fs::path(source).extension().wstring(); std::wstring extension = isFolder ? L"" : fs::path(source).extension().wstring();
size_t stemLength = stem.length(); size_t stemLength = stem.length();

View File

@@ -5,7 +5,7 @@
#include <string> #include <string>
HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source); HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source);
HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, DWORD flags); HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, DWORD flags, bool isFolder);
HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SYSTEMTIME fileTime); HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SYSTEMTIME fileTime);
bool isFileTimeUsed(_In_ PCWSTR source); bool isFileTimeUsed(_In_ PCWSTR source);
bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource); bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource);

View File

@@ -965,7 +965,8 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
winrt::check_hresult(spItem->GetIsSubFolderContent(&isSubFolderContent)); winrt::check_hresult(spItem->GetIsSubFolderContent(&isSubFolderContent));
if ((isFolder && (flags & PowerRenameFlags::ExcludeFolders)) || if ((isFolder && (flags & PowerRenameFlags::ExcludeFolders)) ||
(!isFolder && (flags & PowerRenameFlags::ExcludeFiles)) || (!isFolder && (flags & PowerRenameFlags::ExcludeFiles)) ||
(isSubFolderContent && (flags & PowerRenameFlags::ExcludeSubfolders))) (isSubFolderContent && (flags & PowerRenameFlags::ExcludeSubfolders)) ||
(isFolder && (flags & PowerRenameFlags::ExtensionOnly)))
{ {
// Exclude this item from renaming. Ensure new name is cleared. // Exclude this item from renaming. Ensure new name is cleared.
winrt::check_hresult(spItem->PutNewName(nullptr)); winrt::check_hresult(spItem->PutNewName(nullptr));
@@ -984,6 +985,14 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
winrt::check_hresult(spItem->GetNewName(&currentNewName)); winrt::check_hresult(spItem->GetNewName(&currentNewName));
wchar_t sourceName[MAX_PATH] = { 0 }; wchar_t sourceName[MAX_PATH] = { 0 };
if (isFolder)
{
StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName);
}
else
{
if (flags & NameOnly) if (flags & NameOnly)
{ {
StringCchCopy(sourceName, ARRAYSIZE(sourceName), fs::path(originalName).stem().c_str()); StringCchCopy(sourceName, ARRAYSIZE(sourceName), fs::path(originalName).stem().c_str());
@@ -1001,6 +1010,7 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
{ {
StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName); StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName);
} }
}
SYSTEMTIME fileTime = { 0 }; SYSTEMTIME fileTime = { 0 };
@@ -1037,6 +1047,13 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
if (newName != nullptr) if (newName != nullptr)
{ {
newNameToUse = resultName; newNameToUse = resultName;
if (isFolder)
{
StringCchCopy(resultName, ARRAYSIZE(resultName), newName);
}
else
{
if (flags & NameOnly) if (flags & NameOnly)
{ {
StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s%s", newName, fs::path(originalName).extension().c_str()); StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s%s", newName, fs::path(originalName).extension().c_str());
@@ -1058,6 +1075,7 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
StringCchCopy(resultName, ARRAYSIZE(resultName), newName); StringCchCopy(resultName, ARRAYSIZE(resultName), newName);
} }
} }
}
wchar_t trimmedName[MAX_PATH] = { 0 }; wchar_t trimmedName[MAX_PATH] = { 0 };
if (newNameToUse != nullptr) if (newNameToUse != nullptr)
@@ -1069,7 +1087,13 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
wchar_t transformedName[MAX_PATH] = { 0 }; wchar_t transformedName[MAX_PATH] = { 0 };
if (newNameToUse != nullptr && (flags & Uppercase || flags & Lowercase || flags & Titlecase || flags & Capitalized)) if (newNameToUse != nullptr && (flags & Uppercase || flags & Lowercase || flags & Titlecase || flags & Capitalized))
{ {
winrt::check_hresult(GetTransformedFileName(transformedName, ARRAYSIZE(transformedName), newNameToUse, flags)); try
{
winrt::check_hresult(GetTransformedFileName(transformedName, ARRAYSIZE(transformedName), newNameToUse, flags, isFolder));
}
catch (...)
{
}
newNameToUse = transformedName; newNameToUse = transformedName;
} }

View File

@@ -293,8 +293,9 @@ namespace PowerRenameManagerTests
TEST_METHOD (VerifyExtensionOnlyTransform) TEST_METHOD (VerifyExtensionOnlyTransform)
{ {
rename_pairs renamePairs[] = { rename_pairs renamePairs[] = {
{ L"foo.FOO", L"foo.bar", false, true, 0 }, { L"foo.FOO", L"foo.bar", true, true, 0 },
{ L"foo.bar", L"foo.bar_norename", false, false, 0 } { L"bar.FOO", L"bar.FOO_norename", false, false, 0 },
{ L"foo.bar", L"foo.bar_norename", true, false, 0 }
}; };
RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Lowercase | ExtensionOnly); RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Lowercase | ExtensionOnly);