diff --git a/src/modules/powerrename/lib/Helpers.cpp b/src/modules/powerrename/lib/Helpers.cpp index 090bc583e7..a61a874ecd 100644 --- a/src/modules/powerrename/lib/Helpers.cpp +++ b/src/modules/powerrename/lib/Helpers.cpp @@ -42,7 +42,7 @@ HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source) 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("")); HRESULT hr = E_INVALIDARG; @@ -50,19 +50,38 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour { if (flags & Uppercase) { - if (flags & NameOnly) + if (isFolder) { - std::wstring stem = fs::path(source).stem().wstring(); - std::transform(stem.begin(), stem.end(), stem.begin(), ::towupper); - hr = StringCchPrintf(result, cchMax, L"%s%s", stem.c_str(), fs::path(source).extension().c_str()); - } - else if (flags & ExtensionOnly) - { - std::wstring extension = fs::path(source).extension().wstring(); - if (!extension.empty()) + hr = StringCchCopy(result, cchMax, source); + if (SUCCEEDED(hr)) { - std::transform(extension.begin(), extension.end(), extension.begin(), ::towupper); - hr = StringCchPrintf(result, cchMax, L"%s%s", fs::path(source).stem().c_str(), extension.c_str()); + std::transform(result, result + wcslen(result), result, ::towupper); + } + } + else + { + if (flags & NameOnly) + { + std::wstring stem = fs::path(source).stem().wstring(); + std::transform(stem.begin(), stem.end(), stem.begin(), ::towupper); + hr = StringCchPrintf(result, cchMax, L"%s%s", stem.c_str(), fs::path(source).extension().c_str()); + } + else if (flags & ExtensionOnly) + { + std::wstring extension = fs::path(source).extension().wstring(); + if (!extension.empty()) + { + std::transform(extension.begin(), extension.end(), extension.begin(), ::towupper); + hr = StringCchPrintf(result, cchMax, L"%s%s", fs::path(source).stem().c_str(), extension.c_str()); + } + else + { + hr = StringCchCopy(result, cchMax, source); + if (SUCCEEDED(hr)) + { + std::transform(result, result + wcslen(result), result, ::towupper); + } + } } else { @@ -73,30 +92,41 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour } } } - else + } + else if (flags & Lowercase) + { + if (isFolder) { hr = StringCchCopy(result, cchMax, source); if (SUCCEEDED(hr)) { - std::transform(result, result + wcslen(result), result, ::towupper); + std::transform(result, result + wcslen(result), result, ::towlower); } } - } - else if (flags & Lowercase) - { - if (flags & NameOnly) + else { - std::wstring stem = fs::path(source).stem().wstring(); - std::transform(stem.begin(), stem.end(), stem.begin(), ::towlower); - hr = StringCchPrintf(result, cchMax, L"%s%s", stem.c_str(), fs::path(source).extension().c_str()); - } - else if (flags & ExtensionOnly) - { - std::wstring extension = fs::path(source).extension().wstring(); - if (!extension.empty()) + if (flags & NameOnly) { - std::transform(extension.begin(), extension.end(), extension.begin(), ::towlower); - hr = StringCchPrintf(result, cchMax, L"%s%s", fs::path(source).stem().c_str(), extension.c_str()); + std::wstring stem = fs::path(source).stem().wstring(); + std::transform(stem.begin(), stem.end(), stem.begin(), ::towlower); + hr = StringCchPrintf(result, cchMax, L"%s%s", stem.c_str(), fs::path(source).extension().c_str()); + } + else if (flags & ExtensionOnly) + { + std::wstring extension = fs::path(source).extension().wstring(); + if (!extension.empty()) + { + std::transform(extension.begin(), extension.end(), extension.begin(), ::towlower); + hr = StringCchPrintf(result, cchMax, L"%s%s", fs::path(source).stem().c_str(), extension.c_str()); + } + else + { + hr = StringCchCopy(result, cchMax, source); + if (SUCCEEDED(hr)) + { + std::transform(result, result + wcslen(result), result, ::towlower); + } + } } else { @@ -107,22 +137,14 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour } } } - else - { - hr = StringCchCopy(result, cchMax, source); - if (SUCCEEDED(hr)) - { - std::transform(result, result + wcslen(result), result, ::towlower); - } - } } else if (flags & Titlecase) { if (!(flags & ExtensionOnly)) { std::vector 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 extension = fs::path(source).extension().wstring(); + std::wstring stem = isFolder ? source : fs::path(source).stem().wstring(); + std::wstring extension = isFolder ? L"" : fs::path(source).extension().wstring(); size_t stemLength = stem.length(); bool isFirstWord = true; @@ -171,8 +193,8 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour { if (!(flags & ExtensionOnly)) { - std::wstring stem = fs::path(source).stem().wstring(); - std::wstring extension = fs::path(source).extension().wstring(); + std::wstring stem = isFolder ? source : fs::path(source).stem().wstring(); + std::wstring extension = isFolder ? L"" : fs::path(source).extension().wstring(); size_t stemLength = stem.length(); diff --git a/src/modules/powerrename/lib/Helpers.h b/src/modules/powerrename/lib/Helpers.h index 18705a45c1..68a5264e08 100644 --- a/src/modules/powerrename/lib/Helpers.h +++ b/src/modules/powerrename/lib/Helpers.h @@ -5,7 +5,7 @@ #include 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); bool isFileTimeUsed(_In_ PCWSTR source); bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource); diff --git a/src/modules/powerrename/lib/PowerRenameManager.cpp b/src/modules/powerrename/lib/PowerRenameManager.cpp index 1ec6de2c4a..1281ae6e7c 100644 --- a/src/modules/powerrename/lib/PowerRenameManager.cpp +++ b/src/modules/powerrename/lib/PowerRenameManager.cpp @@ -965,7 +965,8 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv) winrt::check_hresult(spItem->GetIsSubFolderContent(&isSubFolderContent)); if ((isFolder && (flags & PowerRenameFlags::ExcludeFolders)) || (!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. winrt::check_hresult(spItem->PutNewName(nullptr)); @@ -984,22 +985,31 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv) winrt::check_hresult(spItem->GetNewName(¤tNewName)); wchar_t sourceName[MAX_PATH] = { 0 }; - if (flags & NameOnly) + + if (isFolder) { - StringCchCopy(sourceName, ARRAYSIZE(sourceName), fs::path(originalName).stem().c_str()); - } - else if (flags & ExtensionOnly) - { - std::wstring extension = fs::path(originalName).extension().wstring(); - if (!extension.empty() && extension.front() == '.') - { - extension = extension.erase(0, 1); - } - StringCchCopy(sourceName, ARRAYSIZE(sourceName), extension.c_str()); + StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName); + } else { - StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName); + if (flags & NameOnly) + { + StringCchCopy(sourceName, ARRAYSIZE(sourceName), fs::path(originalName).stem().c_str()); + } + else if (flags & ExtensionOnly) + { + std::wstring extension = fs::path(originalName).extension().wstring(); + if (!extension.empty() && extension.front() == '.') + { + extension = extension.erase(0, 1); + } + StringCchCopy(sourceName, ARRAYSIZE(sourceName), extension.c_str()); + } + else + { + StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName); + } } SYSTEMTIME fileTime = { 0 }; @@ -1037,25 +1047,33 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv) if (newName != nullptr) { newNameToUse = resultName; - if (flags & NameOnly) + + if (isFolder) { - StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s%s", newName, fs::path(originalName).extension().c_str()); - } - else if (flags & ExtensionOnly) - { - std::wstring extension = fs::path(originalName).extension().wstring(); - if (!extension.empty()) - { - StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s.%s", fs::path(originalName).stem().c_str(), newName); - } - else - { - StringCchCopy(resultName, ARRAYSIZE(resultName), originalName); - } + StringCchCopy(resultName, ARRAYSIZE(resultName), newName); } else { - StringCchCopy(resultName, ARRAYSIZE(resultName), newName); + if (flags & NameOnly) + { + StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s%s", newName, fs::path(originalName).extension().c_str()); + } + else if (flags & ExtensionOnly) + { + std::wstring extension = fs::path(originalName).extension().wstring(); + if (!extension.empty()) + { + StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s.%s", fs::path(originalName).stem().c_str(), newName); + } + else + { + StringCchCopy(resultName, ARRAYSIZE(resultName), originalName); + } + } + else + { + StringCchCopy(resultName, ARRAYSIZE(resultName), newName); + } } } @@ -1069,7 +1087,13 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv) wchar_t transformedName[MAX_PATH] = { 0 }; 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; } diff --git a/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp b/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp index 5ed669fec0..ebcc226540 100644 --- a/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp +++ b/src/modules/powerrename/unittests/PowerRenameManagerTests.cpp @@ -293,8 +293,9 @@ namespace PowerRenameManagerTests TEST_METHOD (VerifyExtensionOnlyTransform) { rename_pairs renamePairs[] = { - { L"foo.FOO", L"foo.bar", false, true, 0 }, - { L"foo.bar", L"foo.bar_norename", false, false, 0 } + { L"foo.FOO", L"foo.bar", true, true, 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);