mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[PowerRename] Add ModificationTime and AccessTime support when renaming with $YY-$MM-$DD patterns (#39653)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request 1. Add new configuration to control this behaviour. By default, set to creation time to align with previous version 2. Add UI in PowerRename's MainWindow 3. Implement the logic  Original discussion here: https://github.com/microsoft/PowerToys/pull/38186 <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #36040 - [x] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com> Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
This commit is contained in:
@@ -184,6 +184,7 @@
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="48" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel
|
||||
@@ -558,6 +559,33 @@
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
x:Name="FileTimeLabel"
|
||||
x:Uid="TextBlock_FileTime"
|
||||
Margin="0,16,0,8"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<ComboBox
|
||||
x:Name="comboBox_fileTimeParts"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Width="200"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.LabeledBy="{Binding ElementName=FileDateLabel}"
|
||||
SelectedIndex="0">
|
||||
<ComboBoxItem x:Uid="FileTimeParts_CreationTime" />
|
||||
<ComboBoxItem x:Uid="FileTimeParts_ModificationTime" />
|
||||
<ComboBoxItem x:Uid="FileTimeParts_AccessTime" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<Rectangle
|
||||
|
||||
@@ -792,6 +792,32 @@ namespace winrt::PowerRenameUI::implementation
|
||||
button_settings().Click([&](auto const&, auto const&) {
|
||||
OpenSettingsApp();
|
||||
});
|
||||
|
||||
// ComboBox RenameParts
|
||||
comboBox_fileTimeParts().SelectionChanged([&](auto const&, auto const&) {
|
||||
int selectedIndex = comboBox_fileTimeParts().SelectedIndex();
|
||||
if (selectedIndex == 0)
|
||||
{
|
||||
// default behaviour. Date Created
|
||||
UpdateFlag(CreationTime, UpdateFlagCommand::Set);
|
||||
UpdateFlag(ModificationTime, UpdateFlagCommand::Reset);
|
||||
UpdateFlag(AccessTime, UpdateFlagCommand::Reset);
|
||||
}
|
||||
else if (selectedIndex == 1)
|
||||
{
|
||||
// Date Modified
|
||||
UpdateFlag(ModificationTime, UpdateFlagCommand::Set);
|
||||
UpdateFlag(CreationTime, UpdateFlagCommand::Reset);
|
||||
UpdateFlag(AccessTime, UpdateFlagCommand::Reset);
|
||||
}
|
||||
else if (selectedIndex == 2)
|
||||
{
|
||||
// Accessed
|
||||
UpdateFlag(AccessTime, UpdateFlagCommand::Set);
|
||||
UpdateFlag(CreationTime, UpdateFlagCommand::Reset);
|
||||
UpdateFlag(ModificationTime, UpdateFlagCommand::Reset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::ToggleItem(int32_t id, bool checked)
|
||||
|
||||
@@ -411,4 +411,16 @@
|
||||
<data name="ToggleButton_RandItems.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Random string features</value>
|
||||
</data>
|
||||
<data name="TextBlock_FileTime.Text" xml:space="preserve">
|
||||
<value>Time used for replacement</value>
|
||||
</data>
|
||||
<data name="FileTimeParts_CreationTime.Content" xml:space="preserve">
|
||||
<value>Creation Time</value>
|
||||
</data>
|
||||
<data name="FileTimeParts_ModificationTime.Content" xml:space="preserve">
|
||||
<value>Modification Time</value>
|
||||
</data>
|
||||
<data name="FileTimeParts_AccessTime.Content" xml:space="preserve">
|
||||
<value>Access Time</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -18,7 +18,10 @@ enum PowerRenameFlags
|
||||
Lowercase = 0x400,
|
||||
Titlecase = 0x800,
|
||||
Capitalized = 0x1000,
|
||||
RandomizeItems = 0x2000
|
||||
RandomizeItems = 0x2000,
|
||||
CreationTime = 0x4000,
|
||||
ModificationTime = 0x8000,
|
||||
AccessTime = 0x10000,
|
||||
};
|
||||
|
||||
enum PowerRenameFilters
|
||||
@@ -67,7 +70,7 @@ interface __declspec(uuid("C7F59201-4DE1-4855-A3A2-26FC3279C8A5")) IPowerRenameI
|
||||
public:
|
||||
IFACEMETHOD(PutPath)(_In_opt_ PCWSTR newPath) = 0;
|
||||
IFACEMETHOD(GetPath)(_Outptr_ PWSTR * path) = 0;
|
||||
IFACEMETHOD(GetTime)(_Outptr_ SYSTEMTIME* time) = 0;
|
||||
IFACEMETHOD(GetTime)(_In_ DWORD flags, _Outptr_ SYSTEMTIME * time) = 0;
|
||||
IFACEMETHOD(GetShellItem)(_Outptr_ IShellItem** ppsi) = 0;
|
||||
IFACEMETHOD(GetOriginalName)(_Outptr_ PWSTR * originalName) = 0;
|
||||
IFACEMETHOD(PutOriginalName)(_In_opt_ PCWSTR originalName) = 0;
|
||||
|
||||
@@ -56,12 +56,28 @@ IFACEMETHODIMP CPowerRenameItem::GetPath(_Outptr_ PWSTR* path)
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameItem::GetTime(_Outptr_ SYSTEMTIME* time)
|
||||
IFACEMETHODIMP CPowerRenameItem::GetTime(_In_ DWORD flags, _Outptr_ SYSTEMTIME* time)
|
||||
{
|
||||
CSRWSharedAutoLock lock(&m_lock);
|
||||
HRESULT hr = E_FAIL;
|
||||
PowerRenameFlags parsedTimeType;
|
||||
|
||||
if (m_isTimeParsed)
|
||||
// Get Time by PowerRenameFlags
|
||||
if (flags & PowerRenameFlags::ModificationTime)
|
||||
{
|
||||
parsedTimeType = PowerRenameFlags::ModificationTime;
|
||||
}
|
||||
else if (flags & PowerRenameFlags::AccessTime)
|
||||
{
|
||||
parsedTimeType = PowerRenameFlags::AccessTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to modification time if no specific flag is set
|
||||
parsedTimeType = PowerRenameFlags::CreationTime;
|
||||
}
|
||||
|
||||
if (m_isTimeParsed && parsedTimeType == m_parsedTimeType)
|
||||
{
|
||||
hr = S_OK;
|
||||
}
|
||||
@@ -70,21 +86,43 @@ IFACEMETHODIMP CPowerRenameItem::GetTime(_Outptr_ SYSTEMTIME* time)
|
||||
HANDLE hFile = CreateFileW(m_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FILETIME CreationTime;
|
||||
if (GetFileTime(hFile, &CreationTime, NULL, NULL))
|
||||
FILETIME FileTime;
|
||||
bool success = false;
|
||||
|
||||
// Get Time by PowerRenameFlags
|
||||
switch (parsedTimeType)
|
||||
{
|
||||
case PowerRenameFlags::CreationTime:
|
||||
success = GetFileTime(hFile, &FileTime, NULL, NULL);
|
||||
break;
|
||||
case PowerRenameFlags::ModificationTime:
|
||||
success = GetFileTime(hFile, NULL, NULL, &FileTime);
|
||||
break;
|
||||
case PowerRenameFlags::AccessTime:
|
||||
success = GetFileTime(hFile, NULL, &FileTime, NULL);
|
||||
break;
|
||||
default:
|
||||
// Default to modification time if no specific flag is set
|
||||
success = GetFileTime(hFile, NULL, NULL, &FileTime);
|
||||
break;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
SYSTEMTIME SystemTime, LocalTime;
|
||||
if (FileTimeToSystemTime(&CreationTime, &SystemTime))
|
||||
if (FileTimeToSystemTime(&FileTime, &SystemTime))
|
||||
{
|
||||
if (SystemTimeToTzSpecificLocalTime(NULL, &SystemTime, &LocalTime))
|
||||
{
|
||||
m_time = LocalTime;
|
||||
m_isTimeParsed = true;
|
||||
m_parsedTimeType = parsedTimeType;
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
*time = m_time;
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
// IPowerRenameItem
|
||||
IFACEMETHODIMP PutPath(_In_opt_ PCWSTR newPath);
|
||||
IFACEMETHODIMP GetPath(_Outptr_ PWSTR* path);
|
||||
IFACEMETHODIMP GetTime(_Outptr_ SYSTEMTIME* time);
|
||||
IFACEMETHODIMP GetTime(_In_ DWORD flags, _Outptr_ SYSTEMTIME* time);
|
||||
IFACEMETHODIMP GetShellItem(_Outptr_ IShellItem** ppsi);
|
||||
IFACEMETHODIMP PutOriginalName(_In_opt_ PCWSTR originalName);
|
||||
IFACEMETHODIMP GetOriginalName(_Outptr_ PWSTR* originalName);
|
||||
@@ -54,6 +54,7 @@ protected:
|
||||
bool m_selected = true;
|
||||
bool m_isFolder = false;
|
||||
bool m_isTimeParsed = false;
|
||||
PowerRenameFlags m_parsedTimeType = PowerRenameFlags::CreationTime;
|
||||
bool m_canRename = true;
|
||||
int m_id = -1;
|
||||
int m_iconIndex = -1;
|
||||
|
||||
@@ -78,7 +78,7 @@ bool DoRename(CComPtr<IPowerRenameRegEx>& spRenameRegEx, unsigned long& itemEnum
|
||||
|
||||
if (useFileTime)
|
||||
{
|
||||
winrt::check_hresult(spItem->GetTime(&fileTime));
|
||||
winrt::check_hresult(spItem->GetTime(flags, &fileTime));
|
||||
winrt::check_hresult(spRenameRegEx->PutFileTime(fileTime));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user