mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[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:
@@ -42,7 +42,7 @@ 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;
|
||||||
@@ -50,19 +50,38 @@ HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR sour
|
|||||||
{
|
{
|
||||||
if (flags & Uppercase)
|
if (flags & Uppercase)
|
||||||
{
|
{
|
||||||
if (flags & NameOnly)
|
if (isFolder)
|
||||||
{
|
{
|
||||||
std::wstring stem = fs::path(source).stem().wstring();
|
hr = StringCchCopy(result, cchMax, source);
|
||||||
std::transform(stem.begin(), stem.end(), stem.begin(), ::towupper);
|
if (SUCCEEDED(hr))
|
||||||
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);
|
std::transform(result, result + wcslen(result), result, ::towupper);
|
||||||
hr = StringCchPrintf(result, cchMax, L"%s%s", fs::path(source).stem().c_str(), extension.c_str());
|
}
|
||||||
|
}
|
||||||
|
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
|
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);
|
hr = StringCchCopy(result, cchMax, source);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
std::transform(result, result + wcslen(result), result, ::towupper);
|
std::transform(result, result + wcslen(result), result, ::towlower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if (flags & Lowercase)
|
|
||||||
{
|
|
||||||
if (flags & NameOnly)
|
|
||||||
{
|
{
|
||||||
std::wstring stem = fs::path(source).stem().wstring();
|
if (flags & NameOnly)
|
||||||
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);
|
std::wstring stem = fs::path(source).stem().wstring();
|
||||||
hr = StringCchPrintf(result, cchMax, L"%s%s", fs::path(source).stem().c_str(), extension.c_str());
|
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
|
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)
|
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();
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,22 +985,31 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
|
|||||||
winrt::check_hresult(spItem->GetNewName(¤tNewName));
|
winrt::check_hresult(spItem->GetNewName(¤tNewName));
|
||||||
|
|
||||||
wchar_t sourceName[MAX_PATH] = { 0 };
|
wchar_t sourceName[MAX_PATH] = { 0 };
|
||||||
if (flags & NameOnly)
|
|
||||||
|
if (isFolder)
|
||||||
{
|
{
|
||||||
StringCchCopy(sourceName, ARRAYSIZE(sourceName), fs::path(originalName).stem().c_str());
|
StringCchCopy(sourceName, ARRAYSIZE(sourceName), originalName);
|
||||||
}
|
|
||||||
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
|
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 };
|
SYSTEMTIME fileTime = { 0 };
|
||||||
@@ -1037,25 +1047,33 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
|
|||||||
if (newName != nullptr)
|
if (newName != nullptr)
|
||||||
{
|
{
|
||||||
newNameToUse = resultName;
|
newNameToUse = resultName;
|
||||||
if (flags & NameOnly)
|
|
||||||
|
if (isFolder)
|
||||||
{
|
{
|
||||||
StringCchPrintf(resultName, ARRAYSIZE(resultName), L"%s%s", newName, fs::path(originalName).extension().c_str());
|
StringCchCopy(resultName, ARRAYSIZE(resultName), newName);
|
||||||
}
|
|
||||||
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
|
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 };
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user