From 0a6de4561f607e82f3e9a6d0f4de3e7454403c50 Mon Sep 17 00:00:00 2001 From: Clare DuVal <37857579+darecluval@users.noreply.github.com> Date: Fri, 9 Apr 2021 08:24:06 -0400 Subject: [PATCH] [PowerRename] Add option for Capitalization (#10213) * Add camelcase instances + helper translation * Add camel case testing * Update Helpers.cpp * Update PowerRenameUI.cpp * Update src/modules/powerrename/ui/PowerRenameUI.cpp Co-authored-by: Enrico Giordani * Change camel case to capitalized, move ui * Update PowerRenameManagerTests.cpp * Update PowerRenameUI.base.rc * Update PowerRenameUI.base.rc Co-authored-by: Enrico Giordani --- .github/actions/spell-check/expect.txt | 1 + src/modules/powerrename/lib/Helpers.cpp | 36 ++++++++++++++++++ .../powerrename/lib/PowerRenameInterfaces.h | 3 +- .../powerrename/lib/PowerRenameManager.cpp | 4 +- .../powerrename/ui/PowerRenameUI.base.rc | Bin 7142 -> 7406 bytes src/modules/powerrename/ui/PowerRenameUI.cpp | 17 ++++++++- src/modules/powerrename/ui/Resources.resx | 3 ++ src/modules/powerrename/ui/resource.base.h | 9 +++-- .../unittests/PowerRenameManagerTests.cpp | 10 +++++ 9 files changed, 75 insertions(+), 8 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 375a764c79..89c1e67af8 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -192,6 +192,7 @@ buildtransitive BValue bytearray callbackptr +capitalized CANRENAME Captureascreenshot CAPTURECHANGED diff --git a/src/modules/powerrename/lib/Helpers.cpp b/src/modules/powerrename/lib/Helpers.cpp index 30447d34f8..47dafe0d82 100644 --- a/src/modules/powerrename/lib/Helpers.cpp +++ b/src/modules/powerrename/lib/Helpers.cpp @@ -159,6 +159,42 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour { hr = StringCchCopy(result, cchMax, source); } + } + else if (flags & Capitalized) + { + if (!(flags & ExtensionOnly)) + { + std::wstring stem = fs::path(source).stem().wstring(); + std::wstring extension = fs::path(source).extension().wstring(); + + size_t stemLength = stem.length(); + + while (stemLength > 0 && (iswspace(stem[stemLength - 1]) || iswpunct(stem[stemLength - 1]))) + { + stemLength--; + } + + for (size_t i = 0; i < stemLength; i++) + { + if (!i || iswspace(stem[i - 1]) || iswpunct(stem[i - 1])) + { + if (iswspace(stem[i]) || iswpunct(stem[i])) + { + continue; + } + stem[i] = towupper(stem[i]); + } + else + { + stem[i] = towlower(stem[i]); + } + } + hr = StringCchPrintf(result, cchMax, L"%s%s", stem.c_str(), extension.c_str()); + } + else + { + hr = StringCchCopy(result, cchMax, source); + } } else { diff --git a/src/modules/powerrename/lib/PowerRenameInterfaces.h b/src/modules/powerrename/lib/PowerRenameInterfaces.h index c274cdb99b..c9a03b23c6 100644 --- a/src/modules/powerrename/lib/PowerRenameInterfaces.h +++ b/src/modules/powerrename/lib/PowerRenameInterfaces.h @@ -14,7 +14,8 @@ enum PowerRenameFlags ExtensionOnly = 0x100, Uppercase = 0x200, Lowercase = 0x400, - Titlecase = 0x800 + Titlecase = 0x800, + Capitalized = 0x1000 }; enum PowerRenameFilters diff --git a/src/modules/powerrename/lib/PowerRenameManager.cpp b/src/modules/powerrename/lib/PowerRenameManager.cpp index bdf62fe1df..7b20b5dd52 100644 --- a/src/modules/powerrename/lib/PowerRenameManager.cpp +++ b/src/modules/powerrename/lib/PowerRenameManager.cpp @@ -945,7 +945,7 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv) // as nullptr so we clear the renamed column // Except string transformation is selected. - if (newName == nullptr && (flags & Uppercase || flags & Lowercase || flags & Titlecase)) + if (newName == nullptr && (flags & Uppercase || flags & Lowercase || flags & Titlecase || flags & Capitalized)) { SHStrDup(sourceName, &newName); } @@ -983,7 +983,7 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv) } wchar_t transformedName[MAX_PATH] = { 0 }; - if (newNameToUse != nullptr && (flags & Uppercase || flags & Lowercase || flags & Titlecase)) + if (newNameToUse != nullptr && (flags & Uppercase || flags & Lowercase || flags & Titlecase || flags & Capitalized)) { winrt::check_hresult(GetTransformedFileName(transformedName, ARRAYSIZE(transformedName), newNameToUse, flags)); newNameToUse = transformedName; diff --git a/src/modules/powerrename/ui/PowerRenameUI.base.rc b/src/modules/powerrename/ui/PowerRenameUI.base.rc index 0369a50812c9f847a0a865c97684a5e412a2c4f7..67f9fb973ba2ddf9b845e8655a3d257723e69784 100644 GIT binary patch delta 259 zcmaE6{?2m4D>hvPh6siL27iWN1_g#lI4hjNlfi`{guw$S>cQX&5PlV`F5AIs!ld_0ry@uy8L;Ln-7L7-@|i$Kt1KOvFH zU4liEHF!Ymw#k14(@LhE4Cb5T*-ben%Ls8zE)vL@%q5U9IY2OI@&|sY$@c_`CaVc$ zOx`9~G)XvZa-UGqKO>M~Jo%!8@Z>Ow3T9(4yPDaO!DMovWGu5eP|-$7 GTV?=1Dl~Ke diff --git a/src/modules/powerrename/ui/PowerRenameUI.cpp b/src/modules/powerrename/ui/PowerRenameUI.cpp index c6f1245c38..7f063b49f1 100644 --- a/src/modules/powerrename/ui/PowerRenameUI.cpp +++ b/src/modules/powerrename/ui/PowerRenameUI.cpp @@ -39,7 +39,8 @@ FlagCheckboxMap g_flagCheckboxMap[] = { { ExtensionOnly, IDC_CHECK_EXTENSIONONLY }, { Uppercase, IDC_TRANSFORM_UPPERCASE }, { Lowercase, IDC_TRANSFORM_LOWERCASE }, - { Titlecase, IDC_TRANSFORM_TITLECASE } + { Titlecase, IDC_TRANSFORM_TITLECASE }, + { Capitalized, IDC_TRANSFORM_CAPITALIZED } }; struct RepositionMap @@ -708,6 +709,7 @@ void CPowerRenameUI::_InitDlgText() UpdateDlgControl(m_hwnd, IDC_CHECK_NAMEONLY, IDS_ITEM_NAME_ONLY); UpdateDlgControl(m_hwnd, IDC_CHECK_EXTENSIONONLY, IDS_ITEM_EXTENSION_ONLY); UpdateDlgControl(m_hwnd, IDC_TRANSFORM_TITLECASE, IDS_MAKE_TITLECASE); + UpdateDlgControl(m_hwnd, IDC_TRANSFORM_CAPITALIZED, IDS_MAKE_CAPITALIZED); UpdateDlgControl(m_hwnd, ID_RENAME, IDS_RENAME_BUTTON); UpdateDlgControl(m_hwnd, ID_ABOUT, IDS_HELP_BUTTON); UpdateDlgControl(m_hwnd, IDCANCEL, IDS_CANCEL_BUTTON); @@ -756,6 +758,7 @@ void CPowerRenameUI::_OnCommand(_In_ WPARAM wParam, _In_ LPARAM lParam) case IDC_CHECK_NAMEONLY: case IDC_TRANSFORM_UPPERCASE: case IDC_TRANSFORM_LOWERCASE: + case IDC_TRANSFORM_CAPITALIZED: case IDC_TRANSFORM_TITLECASE: if (BN_CLICKED == HIWORD(wParam)) { @@ -981,6 +984,7 @@ void CPowerRenameUI::_ValidateFlagCheckbox(_In_ DWORD checkBoxId) { Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_LOWERCASE), FALSE); Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_TITLECASE), FALSE); + Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_CAPITALIZED), FALSE); } } else if (checkBoxId == IDC_TRANSFORM_LOWERCASE) @@ -989,6 +993,7 @@ void CPowerRenameUI::_ValidateFlagCheckbox(_In_ DWORD checkBoxId) { Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_UPPERCASE), FALSE); Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_TITLECASE), FALSE); + Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_CAPITALIZED), FALSE); } } else if (checkBoxId == IDC_TRANSFORM_TITLECASE) @@ -997,6 +1002,16 @@ void CPowerRenameUI::_ValidateFlagCheckbox(_In_ DWORD checkBoxId) { Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_UPPERCASE), FALSE); Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_LOWERCASE), FALSE); + Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_CAPITALIZED), FALSE); + } + } + else if (checkBoxId == IDC_TRANSFORM_CAPITALIZED) + { + if (Button_GetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_CAPITALIZED)) == BST_CHECKED) + { + Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_UPPERCASE), FALSE); + Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_LOWERCASE), FALSE); + Button_SetCheck(GetDlgItem(m_hwnd, IDC_TRANSFORM_TITLECASE), FALSE); } } else if (checkBoxId == IDC_CHECK_NAMEONLY) diff --git a/src/modules/powerrename/ui/Resources.resx b/src/modules/powerrename/ui/Resources.resx index 28b645e29e..3eeb24bf29 100644 --- a/src/modules/powerrename/ui/Resources.resx +++ b/src/modules/powerrename/ui/Resources.resx @@ -175,6 +175,9 @@ Please select from the options above to show items. Make Titlecase + + Make Capitalized + &Rename diff --git a/src/modules/powerrename/ui/resource.base.h b/src/modules/powerrename/ui/resource.base.h index a79a44208c..7b99147efe 100644 --- a/src/modules/powerrename/ui/resource.base.h +++ b/src/modules/powerrename/ui/resource.base.h @@ -26,9 +26,10 @@ #define IDC_TRANSFORM_UPPERCASE 3019 #define IDC_TRANSFORM_LOWERCASE 3020 #define IDC_TRANSFORM_TITLECASE 3021 -#define IDC_SEARCH_FOR 3022 -#define IDC_REPLACE_WITH 3023 +#define IDC_TRANSFORM_CAPITALIZED 3022 +#define IDC_SEARCH_FOR 3023 +#define IDC_REPLACE_WITH 3024 #define IDC_STATIC -1 -#define IDR_MAINFRAME 3024 -#define IDD_MAIN 3025 +#define IDR_MAINFRAME 3025 +#define IDD_MAIN 3026 #define IDI_RENAME 2001 diff --git a/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp b/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp index dad75999db..86746bbdf6 100644 --- a/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp +++ b/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp @@ -270,6 +270,16 @@ namespace PowerRenameManagerTests RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Titlecase); } + TEST_METHOD (VerifyCapitalizedTransform) + { + rename_pairs renamePairs[] = { + { L"foo and the to", L"Bar And The To", false, true, 0 }, + { L"Test", L"Test_norename", false, false, 0 } + }; + + RenameHelper(renamePairs, ARRAYSIZE(renamePairs), L"foo", L"bar", SYSTEMTIME{ 2020, 7, 3, 22, 15, 6, 42, 453 }, DEFAULT_FLAGS | Capitalized); + } + TEST_METHOD (VerifyNameOnlyTransform) { rename_pairs renamePairs[] = {