mirror of
https://github.com/microsoft/PowerToys
synced 2025-08-30 22:15:11 +00:00
[PowerRename] Show UI info if item cannot be renamed (#19934)
* PowerRename cleanup * Extract ExplorerItem as a UserControl * Add VisualStateManager * UI fixes * Implement error UI logic Highlight items that couldn't be renamed and add error message flyout * Update src/modules/powerrename/lib/PowerRenameManager.cpp Address PR comment Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com> * Update src/modules/powerrename/lib/PowerRenameManager.cpp Address PR comment Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com> * Folder max path is 247 * Implement State() properly Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>
This commit is contained in:
@@ -1,10 +1,42 @@
|
||||
#include "pch.h"
|
||||
#include "pch.h"
|
||||
#include "ExplorerItem.h"
|
||||
#if __has_include("ExplorerItem.g.cpp")
|
||||
#include "ExplorerItem.g.cpp"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
using namespace winrt;
|
||||
using namespace Microsoft::UI::Xaml;
|
||||
using namespace Microsoft::Windows::ApplicationModel::Resources;
|
||||
|
||||
namespace
|
||||
{
|
||||
const wchar_t fileImagePath[] = L"ms-appx:///Assets/file.png";
|
||||
const wchar_t folderImagePath[] = L"ms-appx:///Assets/folder.png";
|
||||
|
||||
std::wstring PowerRenameItemRenameStatusToString(PowerRenameItemRenameStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case PowerRenameItemRenameStatus::Init:
|
||||
{
|
||||
return L"Normal";
|
||||
}
|
||||
case PowerRenameItemRenameStatus::ShouldRename:
|
||||
{
|
||||
return L"Highlight";
|
||||
}
|
||||
case PowerRenameItemRenameStatus::ItemNameInvalidChar:
|
||||
{
|
||||
return L"Error";
|
||||
}
|
||||
case PowerRenameItemRenameStatus::ItemNameTooLong:
|
||||
{
|
||||
return L"Error";
|
||||
}
|
||||
default:
|
||||
return L"Normal";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace winrt::PowerRenameUI::implementation
|
||||
@@ -13,7 +45,6 @@ namespace winrt::PowerRenameUI::implementation
|
||||
m_id{ id }, m_idStr{ std::to_wstring(id) }, m_original{ original }, m_renamed{ renamed }, m_type{ type }, m_depth{ depth }, m_checked{ checked }
|
||||
{
|
||||
m_imagePath = (m_type == static_cast<UINT>(ExplorerItemType::Folder)) ? folderImagePath : fileImagePath;
|
||||
m_highlight = m_checked && !m_renamed.empty() ? Microsoft::UI::Xaml::Visibility::Visible : Microsoft::UI::Xaml::Visibility::Collapsed;
|
||||
}
|
||||
|
||||
int32_t ExplorerItem::Id()
|
||||
@@ -51,17 +82,11 @@ namespace winrt::PowerRenameUI::implementation
|
||||
{
|
||||
m_renamed = value;
|
||||
m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"Renamed" });
|
||||
|
||||
auto visibility = m_checked && !m_renamed.empty() ? Microsoft::UI::Xaml::Visibility::Visible : Microsoft::UI::Xaml::Visibility::Collapsed;
|
||||
if (m_highlight != visibility)
|
||||
{
|
||||
m_highlight = visibility;
|
||||
m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"Highlight" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double ExplorerItem::Indentation() {
|
||||
double ExplorerItem::Indentation()
|
||||
{
|
||||
return static_cast<double>(m_depth) * 12;
|
||||
}
|
||||
|
||||
@@ -96,18 +121,35 @@ namespace winrt::PowerRenameUI::implementation
|
||||
m_checked = value;
|
||||
m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"Checked" });
|
||||
|
||||
auto visibility = m_checked && !m_renamed.empty() ? Microsoft::UI::Xaml::Visibility::Visible : Microsoft::UI::Xaml::Visibility::Collapsed;
|
||||
if (m_highlight != visibility)
|
||||
if (m_checked && !m_renamed.empty())
|
||||
{
|
||||
m_highlight = visibility;
|
||||
m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"Highlight" });
|
||||
VisualStateManager::GoToState(*this, PowerRenameItemRenameStatusToString(m_state), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager::GoToState(*this, L"Normal", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Microsoft::UI::Xaml::Visibility ExplorerItem::Highlight()
|
||||
int32_t ExplorerItem::State()
|
||||
{
|
||||
return m_highlight;
|
||||
return static_cast<int32_t>(m_state);
|
||||
}
|
||||
|
||||
void ExplorerItem::State(int32_t value)
|
||||
{
|
||||
m_state = static_cast<PowerRenameItemRenameStatus>(value);
|
||||
ErrorMessageTxt().Text(StateToErrorMessage());
|
||||
|
||||
if (m_renamed == L"")
|
||||
{
|
||||
VisualStateManager::GoToState(*this, L"Normal", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager::GoToState(*this, PowerRenameItemRenameStatusToString(m_state), false);
|
||||
}
|
||||
}
|
||||
|
||||
winrt::event_token ExplorerItem::PropertyChanged(winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
|
||||
@@ -119,4 +161,26 @@ namespace winrt::PowerRenameUI::implementation
|
||||
{
|
||||
m_propertyChanged.remove(token);
|
||||
}
|
||||
|
||||
std::wstring ExplorerItem::StateToErrorMessage()
|
||||
{
|
||||
auto factory = winrt::get_activation_factory<ResourceManager, IResourceManagerFactory>();
|
||||
ResourceManager manager = factory.CreateInstance(L"resources.pri");
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case PowerRenameItemRenameStatus::ItemNameInvalidChar:
|
||||
{
|
||||
return std::wstring{ manager.MainResourceMap().GetValue(L"Resources/ErrorMessage_InvalidChar").ValueAsString() };
|
||||
}
|
||||
case PowerRenameItemRenameStatus::ItemNameTooLong:
|
||||
{
|
||||
return std::wstring{ manager.MainResourceMap().GetValue(L"Resources/ErrorMessage_FileNameTooLong").ValueAsString() };
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,11 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "winrt/Microsoft.UI.Xaml.h"
|
||||
#include "winrt/Microsoft.UI.Xaml.Markup.h"
|
||||
#include "winrt/Microsoft.UI.Xaml.Interop.h"
|
||||
#include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h"
|
||||
#include "ExplorerItem.g.h"
|
||||
#include "PowerRenameInterfaces.h"
|
||||
|
||||
namespace winrt::PowerRenameUI::implementation
|
||||
{
|
||||
@@ -10,7 +16,7 @@ namespace winrt::PowerRenameUI::implementation
|
||||
Folder = 0,
|
||||
File = 1
|
||||
};
|
||||
|
||||
|
||||
ExplorerItem() = default;
|
||||
|
||||
ExplorerItem(int32_t id, hstring const& original, hstring const& renamed, int32_t type, uint32_t depth, bool checked);
|
||||
@@ -26,12 +32,14 @@ namespace winrt::PowerRenameUI::implementation
|
||||
void Type(int32_t value);
|
||||
bool Checked();
|
||||
void Checked(bool value);
|
||||
Microsoft::UI::Xaml::Visibility Highlight();
|
||||
Windows::Foundation::Collections::IObservableVector<PowerRenameUI::ExplorerItem> Children();
|
||||
winrt::event_token PropertyChanged(Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
|
||||
int32_t State();
|
||||
void State(int32_t value);
|
||||
winrt::event_token PropertyChanged(winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
|
||||
void PropertyChanged(winrt::event_token const& token) noexcept;
|
||||
|
||||
|
||||
private:
|
||||
std::wstring StateToErrorMessage();
|
||||
|
||||
int32_t m_id;
|
||||
hstring m_idStr;
|
||||
winrt::hstring m_original;
|
||||
@@ -40,10 +48,12 @@ namespace winrt::PowerRenameUI::implementation
|
||||
hstring m_imagePath;
|
||||
int32_t m_type;
|
||||
bool m_checked;
|
||||
Microsoft::UI::Xaml::Visibility m_highlight;
|
||||
PowerRenameItemRenameStatus m_state;
|
||||
winrt::event<Microsoft::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::PowerRenameUI::factory_implementation
|
||||
{
|
||||
struct ExplorerItem : ExplorerItemT<ExplorerItem, implementation::ExplorerItem>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace PowerRenameUI
|
||||
{
|
||||
runtimeclass ExplorerItem : Microsoft.UI.Xaml.Data.INotifyPropertyChanged
|
||||
[default_interface] runtimeclass ExplorerItem : Microsoft.UI.Xaml.Controls.UserControl, Microsoft.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
ExplorerItem();
|
||||
ExplorerItem(Int32 id, String original, String renamed, Int32 type, UInt32 depth, Boolean checked);
|
||||
@@ -12,6 +12,6 @@ namespace PowerRenameUI
|
||||
String ImagePath { get; };
|
||||
Int32 Type;
|
||||
Boolean Checked;
|
||||
Microsoft.UI.Xaml.Visibility Highlight { get; };
|
||||
Int32 State;
|
||||
}
|
||||
}
|
||||
|
123
src/modules/powerrename/PowerRenameUILib/ExplorerItem.xaml
Normal file
123
src/modules/powerrename/PowerRenameUILib/ExplorerItem.xaml
Normal file
@@ -0,0 +1,123 @@
|
||||
<UserControl
|
||||
x:Class="PowerRenameUI.ExplorerItem"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:PowerRenameUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Height="28" Padding="0,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="4" />
|
||||
<!-- Some spacing in between -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Error tooltip -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border
|
||||
Name="HighlightBorder"
|
||||
Grid.ColumnSpan="4"
|
||||
Margin="0,0,0,-1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent" />
|
||||
|
||||
<Grid
|
||||
Grid.Column="0"
|
||||
Margin="10,4,0,4"
|
||||
HorizontalAlignment="Left">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MinWidth="{x:Bind Indentation}" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
||||
<CheckBox
|
||||
Name="{x:Bind IdStr}"
|
||||
Grid.Column="1"
|
||||
Width="28"
|
||||
Height="28"
|
||||
MinWidth="0"
|
||||
AutomationProperties.HelpText="{x:Bind Renamed}"
|
||||
AutomationProperties.Name="{x:Bind Original}"
|
||||
Content=""
|
||||
IsChecked="{x:Bind Checked, Mode=TwoWay}"
|
||||
IsTabStop="True"
|
||||
TabIndex="0"
|
||||
XYFocusKeyboardNavigation="Enabled" />
|
||||
<Image
|
||||
Grid.Column="2"
|
||||
Width="16"
|
||||
Margin="4,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
Source="{x:Bind ImagePath}" />
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
Margin="6,0,4,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind Original, Mode=OneWay}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</Grid>
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
Margin="0,0,4,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
|
||||
Text="{x:Bind Renamed, Mode=OneWay}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
|
||||
<Border
|
||||
x:Name="ErrorIcon"
|
||||
Grid.Column="3"
|
||||
Width="12"
|
||||
Height="12"
|
||||
CornerRadius="12"
|
||||
Margin="4,0,8,0"
|
||||
Background="{ThemeResource SystemFillColorCriticalBrush}"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Foreground="White"
|
||||
FontSize="8"
|
||||
Text="" />
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock
|
||||
x:Name="ErrorMessageTxt"
|
||||
Text="Error message goes here"
|
||||
TextWrapping="Wrap" />
|
||||
</ToolTipService.ToolTip>
|
||||
</Border>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Highlight">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="HighlightBorder.Opacity" Value="0.1" />
|
||||
<Setter Target="HighlightBorder.BorderBrush" Value="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
||||
<Setter Target="HighlightBorder.Background" Value="{ThemeResource AccentTextFillColorPrimaryBrush}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Error">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="HighlightBorder.Opacity" Value="1" />
|
||||
<Setter Target="HighlightBorder.BorderBrush" Value="{ThemeResource SystemFillColorCriticalBackgroundBrush}" />
|
||||
<Setter Target="HighlightBorder.Background" Value="{ThemeResource SystemFillColorCriticalBackgroundBrush}" />
|
||||
<Setter Target="ErrorIcon.Visibility" Value="Visible" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -16,9 +16,5 @@ namespace PowerRenameUI
|
||||
|
||||
String OriginalCount;
|
||||
String RenamedCount;
|
||||
|
||||
void AddExplorerItem(Int32 id, String original, String renamed, Int32 type, UInt32 depth, Boolean checked);
|
||||
void UpdateExplorerItem(Int32 id, String newName);
|
||||
void UpdateRenamedExplorerItem(Int32 id, String newOriginalName);
|
||||
}
|
||||
}
|
||||
|
@@ -2,18 +2,18 @@
|
||||
x:Class="PowerRenameUI.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:PowerRenameUI"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:animatedVisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
|
||||
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:PowerRenameUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Padding="12">
|
||||
<Grid Padding="12" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="0" />
|
||||
<!-- 48 if we need to draw the title bar ourself -->
|
||||
<!-- 48 if we need to draw the title bar ourself -->
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -21,14 +21,15 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Background="{ThemeResource LayerFillColorDefaultBrush}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
CornerRadius="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}">
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="{ThemeResource LayerFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="*" />
|
||||
@@ -40,10 +41,26 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox x:Name="checkBox_selectAll" IsChecked="True" MinWidth="0" Content="" x:Uid="SelectAllCheckBox" Margin="10,0,0,0" Checked="SelectAll" Unchecked="SelectAll" />
|
||||
<Image Width="16" Margin="4,0,0,0" Source="ms-appx:///Assets/file.png" HorizontalAlignment="Left" />
|
||||
<CheckBox
|
||||
x:Name="checkBox_selectAll"
|
||||
x:Uid="SelectAllCheckBox"
|
||||
MinWidth="0"
|
||||
Margin="10,0,0,0"
|
||||
Checked="SelectAll"
|
||||
Content=""
|
||||
IsChecked="True"
|
||||
Unchecked="SelectAll" />
|
||||
<Image
|
||||
Width="16"
|
||||
Margin="4,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
Source="ms-appx:///Assets/file.png" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Grid.Column="2" Margin="6,-2,0,0" >
|
||||
<StackPanel
|
||||
Grid.Column="2"
|
||||
Margin="6,-2,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock x:Uid="TxtBlock_Original" FontWeight="Medium" />
|
||||
<TextBlock FontWeight="Medium" Margin="4,0,0,0" >
|
||||
<Run Text="(" /><Run Text="{x:Bind OriginalCount, Mode=OneWay}" /><Run Text=")" />
|
||||
@@ -52,132 +69,128 @@
|
||||
</StackPanel>
|
||||
<AppBarSeparator Margin="-6,4,0,4" HorizontalAlignment="Right" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Grid.Column="2" Margin="4,-2,0,0" >
|
||||
<StackPanel
|
||||
Grid.Column="2"
|
||||
Margin="4,-2,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock x:Uid="TxtBlock_Renamed" FontWeight="Medium" />
|
||||
<TextBlock FontWeight="Medium" Margin="4,0,0,0" >
|
||||
<Run Text="(" /><Run Text="{x:Bind RenamedCount, Mode=OneWay}" /><Run Text=")" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<Button Content="" Background="Transparent" FontFamily="{ThemeResource SymbolThemeFontFamily}" Height="32" x:Uid="FilterButton" Grid.Column="1" BorderThickness="0" HorizontalAlignment="Right" Margin="0,0,8,0">
|
||||
<Button
|
||||
x:Uid="FilterButton"
|
||||
Grid.Column="1"
|
||||
Height="32"
|
||||
Margin="0,0,8,0"
|
||||
BorderThickness="0"
|
||||
HorizontalAlignment="Right"
|
||||
Background="Transparent"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}">
|
||||
<Button.Flyout>
|
||||
<MenuBarItemFlyout Placement="Bottom">
|
||||
<controls:RadioMenuFlyoutItem x:Name="button_showAll" Click="ShowAll" x:Uid="ShowAll" IsChecked="True" GroupName="Filter" />
|
||||
<controls:RadioMenuFlyoutItem x:Name="button_showRenamed" Click="ShowRenamed" x:Uid="ShowOnly" GroupName="Filter" />
|
||||
<controls:RadioMenuFlyoutItem
|
||||
x:Name="button_showAll"
|
||||
x:Uid="ShowAll"
|
||||
Click="ShowAll"
|
||||
GroupName="Filter"
|
||||
IsChecked="True" />
|
||||
<controls:RadioMenuFlyoutItem
|
||||
x:Name="button_showRenamed"
|
||||
x:Uid="ShowOnly"
|
||||
Click="ShowRenamed"
|
||||
GroupName="Filter" />
|
||||
</MenuBarItemFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
<Rectangle Height="1" Grid.ColumnSpan="5" Fill="{ThemeResource CardStrokeColorDefaultBrush}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" />
|
||||
<ListView IsTabStop="false"
|
||||
SelectionMode="None"
|
||||
XYFocusKeyboardNavigation="Enabled"
|
||||
IsItemClickEnabled="False"
|
||||
Grid.ColumnSpan="6"
|
||||
ItemsSource="{x:Bind ExplorerItems, Mode=OneWay}"
|
||||
Grid.Row="1">
|
||||
<Rectangle
|
||||
Grid.ColumnSpan="5"
|
||||
Height="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Bottom"
|
||||
Fill="{ThemeResource DividerStrokeColorDefaultBrush}" />
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="6"
|
||||
IsItemClickEnabled="False"
|
||||
IsTabStop="false"
|
||||
ItemsSource="{x:Bind ExplorerItems, Mode=OneWay}"
|
||||
SelectionMode="None"
|
||||
XYFocusKeyboardNavigation="Enabled">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListViewItem">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<ContentPresenter />
|
||||
<Rectangle Height="1" Margin="0,0,0,0" Opacity="0.8" Grid.ColumnSpan="5" Fill="{ThemeResource CardStrokeColorDefaultBrush}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" />
|
||||
|
||||
<Rectangle
|
||||
Grid.ColumnSpan="5"
|
||||
Height="1"
|
||||
Margin="0,0,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Bottom"
|
||||
Fill="{ThemeResource DividerStrokeColorDefaultBrush}"
|
||||
Opacity="1" />
|
||||
</StackPanel>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:Name="ExplorerItemTemplate" x:DataType="local:ExplorerItem">
|
||||
<Grid Height="28" Padding="0,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border HorizontalAlignment="Stretch" Grid.ColumnSpan="2" BorderThickness="0,0,0,1" Margin="0,0,0,-1" BorderBrush="{ThemeResource SystemAccentColor}" VerticalAlignment="Stretch" Background="{ThemeResource AccentTextFillColorPrimaryBrush}" Opacity="0.1" Visibility="{x:Bind Highlight, Mode=OneWay}" />
|
||||
|
||||
<Grid Grid.Column="0" HorizontalAlignment="Left" Margin="10,4,0,4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MinWidth="{x:Bind Indentation}"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
||||
<CheckBox TabIndex="0"
|
||||
MinWidth="0"
|
||||
Width="28"
|
||||
Height="28"
|
||||
Grid.Column="1"
|
||||
XYFocusKeyboardNavigation="Enabled"
|
||||
IsTabStop="True"
|
||||
Content=""
|
||||
Name="{x:Bind IdStr}"
|
||||
AutomationProperties.Name="{x:Bind Original}"
|
||||
AutomationProperties.HelpText="{x:Bind Renamed}"
|
||||
IsChecked="{x:Bind Checked, Mode=TwoWay}" />
|
||||
<Image Width="16"
|
||||
Grid.Column="2"
|
||||
Margin="4,0,0,0"
|
||||
Source="{x:Bind ImagePath}"
|
||||
HorizontalAlignment="Left" />
|
||||
<TextBlock Margin="6,0,0,0"
|
||||
Grid.Column="3"
|
||||
Text="{x:Bind Original, Mode=OneWay}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12" />
|
||||
</Grid>
|
||||
<TextBlock Text="{x:Bind Renamed, Mode=OneWay}"
|
||||
Grid.Column="1"
|
||||
FontWeight="Bold"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Column="0" Grid.Row="1" MaxWidth="359" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
MaxWidth="359"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="48" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical" Padding="0,0,0,16" Margin="0,0,12,0">
|
||||
<StackPanel
|
||||
Margin="0,0,12,0"
|
||||
Padding="0,0,0,16"
|
||||
Orientation="Vertical">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<AutoSuggestBox x:Name="textBox_search" x:Uid="SearchBox" Height="40" VerticalContentAlignment="Center" ItemsSource="{x:Bind SearchMRU}" />
|
||||
<AutoSuggestBox
|
||||
x:Name="textBox_search"
|
||||
x:Uid="SearchBox"
|
||||
Height="40"
|
||||
VerticalContentAlignment="Center"
|
||||
ItemsSource="{x:Bind SearchMRU}" />
|
||||
|
||||
<Button Grid.Column="1"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{Binding ElementName=checkBox_regex, Path=IsChecked}"
|
||||
Height="40"
|
||||
Width="28"
|
||||
Padding="0"
|
||||
Margin="0,0,-4,0"
|
||||
BorderBrush="Transparent"
|
||||
Background="Transparent"
|
||||
x:Uid="RegExButton"
|
||||
Content=""
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
x:Uid="RegExButton"
|
||||
Grid.Column="1"
|
||||
Width="28"
|
||||
Height="40"
|
||||
Margin="0,0,-4,0"
|
||||
Padding="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Visibility="{Binding ElementName=checkBox_regex, Path=IsChecked}">
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="RegExFlyout">
|
||||
<Grid>
|
||||
@@ -187,24 +200,47 @@
|
||||
<RowDefinition Height="48" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Uid="RegExCheatSheet_Title" FontWeight="SemiBold" />
|
||||
<ListView ItemsSource="{x:Bind SearchRegExShortcuts}" SelectionMode="None" Grid.Row="1" IsItemClickEnabled="True" Margin="-4,12,0,0" ItemClick="RegExItemClick">
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
Margin="-4,12,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="RegExItemClick"
|
||||
ItemsSource="{x:Bind SearchRegExShortcuts}"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:PatternSnippet">
|
||||
<Grid ColumnSpacing="8" Margin="-10,0,0,0">
|
||||
<Grid Margin="-10,0,0,0" ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="48" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border CornerRadius="4" Padding="8" HorizontalAlignment="Left" BorderThickness="1" BorderBrush="{ThemeResource ButtonBorderBrush}" Background="{ThemeResource ButtonBackground}">
|
||||
<TextBlock FontFamily="Consolas" Foreground="{ThemeResource ButtonForeground}" Text="{x:Bind Code}" />
|
||||
<Border
|
||||
Padding="8"
|
||||
HorizontalAlignment="Left"
|
||||
Background="{ThemeResource ButtonBackground}"
|
||||
BorderBrush="{ThemeResource ButtonBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4">
|
||||
<TextBlock
|
||||
FontFamily="Consolas"
|
||||
Foreground="{ThemeResource ButtonForeground}"
|
||||
Text="{x:Bind Code}" />
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="{x:Bind Description}" FontSize="12" Grid.Column="1" Foreground="{ThemeResource TextFillColorSecondaryBrush}" VerticalAlignment="Center" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind Description}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<HyperlinkButton Grid.Row="2" VerticalAlignment="Bottom" NavigateUri="https://aka.ms/powertoysRegExHelp">
|
||||
<HyperlinkButton
|
||||
Grid.Row="2"
|
||||
VerticalAlignment="Bottom"
|
||||
NavigateUri="https://aka.ms/powertoysRegExHelp">
|
||||
<TextBlock x:Uid="RegExCheatSheet_LearnMore" />
|
||||
</HyperlinkButton>
|
||||
</Grid>
|
||||
@@ -214,30 +250,50 @@
|
||||
</Grid>
|
||||
|
||||
|
||||
<CheckBox x:Name="checkBox_regex" x:Uid="CheckBox_RegEx" Margin="2,6,0,0" />
|
||||
<CheckBox x:Name="checkBox_matchAll" x:Uid="CheckBox_MatchAll" Margin="2,0,0,0" />
|
||||
<CheckBox x:Name="checkBox_case" x:Uid="CheckBox_Case" Margin="2,0,0,0" />
|
||||
<CheckBox
|
||||
x:Name="checkBox_regex"
|
||||
x:Uid="CheckBox_RegEx"
|
||||
Margin="2,6,0,0" />
|
||||
<CheckBox
|
||||
x:Name="checkBox_matchAll"
|
||||
x:Uid="CheckBox_MatchAll"
|
||||
Margin="2,0,0,0" />
|
||||
<CheckBox
|
||||
x:Name="checkBox_case"
|
||||
x:Uid="CheckBox_Case"
|
||||
Margin="2,0,0,0" />
|
||||
|
||||
<Rectangle Height="1" Fill="{ThemeResource CardStrokeColorDefaultBrush}" HorizontalAlignment="Stretch" Margin="0,16,0,20" />
|
||||
<Rectangle
|
||||
Height="1"
|
||||
Margin="0,16,0,20"
|
||||
HorizontalAlignment="Stretch"
|
||||
Fill="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<AutoSuggestBox x:Name="textBox_replace" x:Uid="ReplaceBox" Height="40" VerticalContentAlignment="Center" Padding="12,12,0,0" ItemsSource="{x:Bind ReplaceMRU}" />
|
||||
<AutoSuggestBox
|
||||
x:Name="textBox_replace"
|
||||
x:Uid="ReplaceBox"
|
||||
Height="40"
|
||||
Padding="12,12,0,0"
|
||||
VerticalContentAlignment="Center"
|
||||
ItemsSource="{x:Bind ReplaceMRU}" />
|
||||
|
||||
<Button FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
VerticalAlignment="Center"
|
||||
x:Uid="FileCreationButton"
|
||||
Grid.Column="1"
|
||||
Width="28"
|
||||
Height="40"
|
||||
Padding="0"
|
||||
Margin="0,0,-4,0"
|
||||
BorderBrush="Transparent"
|
||||
Background="Transparent"
|
||||
Content=""
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
x:Uid="FileCreationButton"
|
||||
Grid.Column="1"
|
||||
Width="28"
|
||||
Height="40"
|
||||
Margin="0,0,-4,0"
|
||||
Padding="0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}">
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="DateTimeFlyout" ShouldConstrainToRootBounds="False">
|
||||
<Grid>
|
||||
@@ -246,19 +302,39 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Uid="DateTimeCheatSheet_Title" FontWeight="SemiBold" />
|
||||
<ListView ItemsSource="{x:Bind DateTimeShortcuts}" SelectionMode="None" Grid.Row="1" IsItemClickEnabled="True" Margin="-4,12,0,0" ItemClick="DateTimeItemClick">
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
Margin="-4,12,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="DateTimeItemClick"
|
||||
ItemsSource="{x:Bind DateTimeShortcuts}"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:PatternSnippet">
|
||||
<Grid ColumnSpacing="8" Margin="-10,0,0,0">
|
||||
<Grid Margin="-10,0,0,0" ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="56" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border CornerRadius="4" Padding="8" HorizontalAlignment="Left" BorderThickness="1" BorderBrush="{ThemeResource ButtonBorderBrush}" Background="{ThemeResource ButtonBackground}">
|
||||
<TextBlock FontFamily="Consolas" Foreground="{ThemeResource ButtonForeground}" Text="{x:Bind Code}" />
|
||||
<Border
|
||||
Padding="8"
|
||||
HorizontalAlignment="Left"
|
||||
Background="{ThemeResource ButtonBackground}"
|
||||
BorderBrush="{ThemeResource ButtonBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4">
|
||||
<TextBlock
|
||||
FontFamily="Consolas"
|
||||
Foreground="{ThemeResource ButtonForeground}"
|
||||
Text="{x:Bind Code}" />
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="{x:Bind Description}" FontSize="12" Grid.Column="1" Foreground="{ThemeResource TextFillColorSecondaryBrush}" VerticalAlignment="Center" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind Description}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
@@ -270,51 +346,145 @@
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<TextBlock x:Uid="TextBox_ApplyTo" x:Name="ApplyToLabel" FontSize="12" Margin="0,12,0,8" Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock
|
||||
x:Name="ApplyToLabel"
|
||||
x:Uid="TextBox_ApplyTo"
|
||||
Margin="0,12,0,8"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Column="1" Spacing="4" Grid.Row="1">
|
||||
<ComboBox x:Name="comboBox_renameParts" SelectedIndex="0" Width="200" AutomationProperties.LabeledBy="{Binding ElementName=ApplyToLabel}" HorizontalAlignment="Stretch" Grid.Column="0" Grid.Row="1">
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<ComboBox
|
||||
x:Name="comboBox_renameParts"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Width="200"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.LabeledBy="{Binding ElementName=ApplyToLabel}"
|
||||
SelectedIndex="0">
|
||||
<x:String>Filename + extension</x:String>
|
||||
<x:String>Filename only</x:String>
|
||||
<x:String>Extension only</x:String>
|
||||
</ComboBox>
|
||||
<AppBarSeparator Margin="5,0,5,0" />
|
||||
<ToggleButton x:Name="toggleButton_includeFiles" Content="" MinHeight="0" Height="31" IsChecked="True" FontFamily="{ThemeResource SymbolThemeFontFamily}" x:Uid="ToggleButton_IncludeFiles" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton x:Name="toggleButton_includeFolders" Content="" MinHeight="0" Height="31" IsChecked="True" FontFamily="{ThemeResource SymbolThemeFontFamily}" x:Uid="ToggleButton_IncludeFolders" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton x:Name="toggleButton_includeSubfolders" Content="" MinHeight="0" Height="31" IsChecked="True" FontFamily="{ThemeResource SymbolThemeFontFamily}" x:Uid="ToggleButton_IncludeSubFolders" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_includeFiles"
|
||||
x:Uid="ToggleButton_IncludeFiles"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_includeFolders"
|
||||
x:Uid="ToggleButton_IncludeFolders"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_includeSubfolders"
|
||||
x:Uid="ToggleButton_IncludeSubFolders"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<TextBlock x:Uid="TextBlock_TextFormatting" FontSize="12" Foreground="{ThemeResource TextFillColorSecondaryBrush}" Margin="0,12,0,8" />
|
||||
<TextBlock
|
||||
x:Uid="TextBlock_TextFormatting"
|
||||
Margin="0,12,0,8"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<ToggleButton x:Name="toggleButton_lowerCase" Content="aa" FontWeight="Medium" MinHeight="0" Height="31" x:Uid="ToggleButton_Lowercase" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton x:Name="toggleButton_upperCase" Content="AA" FontWeight="Medium" MinHeight="0" Height="31" x:Uid="ToggleButton_Uppercase" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton x:Name="toggleButton_titleCase" Content="Aa" FontWeight="Medium" MinHeight="0" Height="31" x:Uid="ToggleButton_TitleCase" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton x:Name="toggleButton_capitalize" Content="Aa Aa" FontWeight="Medium" MinHeight="0" Height="31" x:Uid="ToggleButton_Capitalize" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_lowerCase"
|
||||
x:Uid="ToggleButton_Lowercase"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content="aa"
|
||||
FontWeight="Medium"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_upperCase"
|
||||
x:Uid="ToggleButton_Uppercase"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content="AA"
|
||||
FontWeight="Medium"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_titleCase"
|
||||
x:Uid="ToggleButton_TitleCase"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content="Aa"
|
||||
FontWeight="Medium"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_capitalize"
|
||||
x:Uid="ToggleButton_Capitalize"
|
||||
Height="31"
|
||||
MinHeight="0"
|
||||
Content="Aa Aa"
|
||||
FontWeight="Medium"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<AppBarSeparator Margin="5,0,5,0" />
|
||||
|
||||
<ToggleButton x:Name="toggleButton_enumItems" Content="" FontFamily="{ThemeResource SymbolThemeFontFamily}" MinHeight="32" x:Uid="ToggleButton_EnumItems" Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
<ToggleButton
|
||||
x:Name="toggleButton_enumItems"
|
||||
x:Uid="ToggleButton_EnumItems"
|
||||
MinHeight="32"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Style="{StaticResource CustomToggleButtonStyle}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<Rectangle Height="1" Fill="{ThemeResource CardStrokeColorDefaultBrush}" HorizontalAlignment="Stretch" Margin="0,0,12,0" VerticalAlignment="Top" Grid.Row="1" />
|
||||
<Rectangle
|
||||
Grid.Row="1"
|
||||
Height="1"
|
||||
Margin="0,0,12,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Fill="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Grid.Row="2"
|
||||
Spacing="8"
|
||||
Margin="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Left">
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
|
||||
<Button x:Name="button_settings" Height="32" x:Uid="TxtBlock_ButtonSettings" FontFamily="{ThemeResource SymbolThemeFontFamily}" Grid.Row="5" Padding="6" Background="Transparent" BorderBrush="Transparent" Grid.Column="1">
|
||||
<Button
|
||||
x:Name="button_settings"
|
||||
x:Uid="TxtBlock_ButtonSettings"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Height="32"
|
||||
Padding="6"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}">
|
||||
<Button.Content>
|
||||
<controls:AnimatedIcon x:Name="SearchAnimatedIcon">
|
||||
<controls:AnimatedIcon.Source>
|
||||
@@ -328,7 +498,18 @@
|
||||
</Button.Content>
|
||||
</Button>
|
||||
|
||||
<Button x:Name="button_docs" Content="" FontFamily="{ThemeResource SymbolThemeFontFamily}" x:Uid="DocsButton" Background="Transparent" BorderBrush="Transparent" Grid.Row="1" Height="32" VerticalAlignment="Bottom" HorizontalAlignment="Left" Click="OpenDocs" />
|
||||
<Button
|
||||
x:Name="button_docs"
|
||||
x:Uid="DocsButton"
|
||||
Grid.Row="1"
|
||||
Height="32"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
Click="OpenDocs"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}" />
|
||||
|
||||
|
||||
<!--<Button Content=""
|
||||
@@ -353,14 +534,27 @@
|
||||
|
||||
|
||||
|
||||
<muxc:SplitButton Grid.Row="2" Style="{StaticResource SplitAccentButtonStyle}" Grid.Column="0" Margin="0,0,12,1" x:Name="button_rename" x:Uid="ButtonApply" Click="button_rename_Click" HorizontalAlignment="Right" VerticalAlignment="Bottom">
|
||||
<muxc:SplitButton
|
||||
x:Name="button_rename"
|
||||
x:Uid="ButtonApply"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,12,1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Click="button_rename_Click"
|
||||
Style="{StaticResource SplitAccentButtonStyle}">
|
||||
<muxc:SplitButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="Enter" />
|
||||
<KeyboardAccelerator Key="Enter" Modifiers="Control" />
|
||||
</muxc:SplitButton.KeyboardAccelerators>
|
||||
<muxc:SplitButton.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon Glyph="" FontSize="14" VerticalAlignment="Center" Margin="0,2,10,0" />
|
||||
<FontIcon
|
||||
Margin="0,2,10,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="TxtBlock_ButtonApply" />
|
||||
</StackPanel>
|
||||
</muxc:SplitButton.Content>
|
||||
|
@@ -243,22 +243,22 @@ namespace winrt::PowerRenameUI::implementation
|
||||
m_explorerItemsMap[id] = newItem;
|
||||
}
|
||||
|
||||
void MainWindow::UpdateExplorerItem(int32_t id, hstring const& newName)
|
||||
void MainWindow::UpdateExplorerItem(int32_t id, std::optional<hstring> newOriginalName, std::optional<hstring> newName, PowerRenameItemRenameStatus itemStatus)
|
||||
{
|
||||
auto itemToUpdate = FindById(id);
|
||||
if (itemToUpdate != NULL)
|
||||
{
|
||||
itemToUpdate.Renamed(newName);
|
||||
}
|
||||
}
|
||||
if (newOriginalName.has_value())
|
||||
{
|
||||
itemToUpdate.Original(*newOriginalName);
|
||||
}
|
||||
|
||||
void MainWindow::UpdateRenamedExplorerItem(int32_t id, hstring const& newOriginalName)
|
||||
{
|
||||
auto itemToUpdate = FindById(id);
|
||||
if (itemToUpdate != NULL)
|
||||
{
|
||||
itemToUpdate.Original(newOriginalName);
|
||||
itemToUpdate.Renamed(L"");
|
||||
if (newName.has_value())
|
||||
{
|
||||
itemToUpdate.Renamed(*newName);
|
||||
}
|
||||
|
||||
itemToUpdate.State(static_cast<int32_t>(itemStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,8 +1007,13 @@ namespace winrt::PowerRenameUI::implementation
|
||||
hr = renameItem->GetNewName(&newName);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hstring newNameStr = newName == nullptr ? hstring{} : newName;
|
||||
UpdateExplorerItem(id, newNameStr);
|
||||
PowerRenameItemRenameStatus status;
|
||||
hr = renameItem->GetStatus(&status);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hstring newNameStr = newName == nullptr ? hstring{} : newName;
|
||||
UpdateExplorerItem(id, std::nullopt, newNameStr, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,7 +1031,7 @@ namespace winrt::PowerRenameUI::implementation
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hstring newNameStr = newName == nullptr ? hstring{} : newName;
|
||||
UpdateRenamedExplorerItem(id, newNameStr);
|
||||
UpdateExplorerItem(id, newNameStr, L"", PowerRenameItemRenameStatus::Init);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -88,8 +88,7 @@ namespace winrt::PowerRenameUI::implementation
|
||||
void PropertyChanged(winrt::event_token const& token) noexcept;
|
||||
|
||||
void AddExplorerItem(int32_t id, hstring const& original, hstring const& renamed, int32_t type, uint32_t depth, bool checked);
|
||||
void UpdateExplorerItem(int32_t id, hstring const& newName);
|
||||
void UpdateRenamedExplorerItem(int32_t id, hstring const& newOriginalName);
|
||||
void UpdateExplorerItem(int32_t id, std::optional<hstring> newOriginalName, std::optional<hstring> newName, PowerRenameItemRenameStatus itemStatus);
|
||||
|
||||
void SelectAll(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
|
||||
void ShowAll(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
|
||||
|
@@ -88,7 +88,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ExplorerItem.h">
|
||||
<DependentUpon>ExplorerItem.idl</DependentUpon>
|
||||
<DependentUpon>ExplorerItem.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PatternSnippet.h">
|
||||
<DependentUpon>PatternSnippet.idl</DependentUpon>
|
||||
@@ -103,11 +104,15 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml" />
|
||||
<Page Include="ExplorerItem.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ExplorerItem.cpp">
|
||||
<DependentUpon>ExplorerItem.idl</DependentUpon>
|
||||
<DependentUpon>ExplorerItem.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PatternSnippet.cpp">
|
||||
<DependentUpon>PatternSnippet.idl</DependentUpon>
|
||||
@@ -128,7 +133,10 @@
|
||||
<SubType>Code</SubType>
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Midl>
|
||||
<Midl Include="ExplorerItem.idl" />
|
||||
<Midl Include="ExplorerItem.idl">
|
||||
<DependentUpon>ExplorerItem.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="MainWindow.idl">
|
||||
<SubType>Code</SubType>
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
|
@@ -5,6 +5,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="MainWindow.xaml" />
|
||||
<Page Include="ExplorerItem.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="App.idl" />
|
||||
|
@@ -330,6 +330,12 @@
|
||||
<data name="FileCreationButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>File creation date and time help</value>
|
||||
</data>
|
||||
<data name="ErrorMessage_FileNameTooLong" xml:space="preserve">
|
||||
<value>File name is too long</value>
|
||||
</data>
|
||||
<data name="ErrorMessage_InvalidChar" xml:space="preserve">
|
||||
<value>File name contains invalid character(s):
 > < | " : ? * \ /</value>
|
||||
</data>
|
||||
|
||||
|
||||
</root>
|
||||
|
@@ -28,6 +28,14 @@ enum PowerRenameFilters
|
||||
ShouldRename = 4,
|
||||
};
|
||||
|
||||
enum class PowerRenameItemRenameStatus {
|
||||
Init = 0,
|
||||
ShouldRename,
|
||||
ItemNameTooLong,
|
||||
ItemNameInvalidChar,
|
||||
ItemNameAlreadyExists,
|
||||
};
|
||||
|
||||
interface __declspec(uuid("3ECBA62B-E0F0-4472-AA2E-DEE7A1AA46B9")) IPowerRenameRegExEvents : public IUnknown
|
||||
{
|
||||
public:
|
||||
@@ -71,6 +79,8 @@ public:
|
||||
IFACEMETHOD(GetId)(_Out_ int *id) = 0;
|
||||
IFACEMETHOD(GetDepth)(_Out_ UINT* depth) = 0;
|
||||
IFACEMETHOD(PutDepth)(_In_ int depth) = 0;
|
||||
IFACEMETHOD(GetStatus)(_Out_ PowerRenameItemRenameStatus* status) = 0;
|
||||
IFACEMETHOD(PutStatus)(_In_ PowerRenameItemRenameStatus status) = 0;
|
||||
IFACEMETHOD(ShouldRenameItem)(_In_ DWORD flags, _Out_ bool* shouldRename) = 0;
|
||||
IFACEMETHOD(IsItemVisible)(_In_ DWORD filter, _In_ DWORD flags, _Out_ bool* isItemVisible) = 0;
|
||||
IFACEMETHOD(Reset)() = 0;
|
||||
|
@@ -191,6 +191,18 @@ IFACEMETHODIMP CPowerRenameItem::PutDepth(_In_ int depth)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameItem::GetStatus(_Out_ PowerRenameItemRenameStatus* status)
|
||||
{
|
||||
*status = m_status;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameItem::PutStatus(_In_ PowerRenameItemRenameStatus status)
|
||||
{
|
||||
m_status = status;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP CPowerRenameItem::ShouldRenameItem(_In_ DWORD flags, _Out_ bool* shouldRename)
|
||||
{
|
||||
// Should we perform a rename on this item given its
|
||||
@@ -200,7 +212,7 @@ IFACEMETHODIMP CPowerRenameItem::ShouldRenameItem(_In_ DWORD flags, _Out_ bool*
|
||||
bool excludeBecauseFile = (!m_isFolder && (flags & PowerRenameFlags::ExcludeFiles));
|
||||
bool excludeBecauseSubFolderContent = (m_depth > 0 && (flags & PowerRenameFlags::ExcludeSubfolders));
|
||||
*shouldRename = (m_selected && m_canRename && hasChanged && !excludeBecauseFile &&
|
||||
!excludeBecauseFolder && !excludeBecauseSubFolderContent);
|
||||
!excludeBecauseFolder && !excludeBecauseSubFolderContent && m_status == PowerRenameItemRenameStatus::ShouldRename);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@@ -29,6 +29,8 @@ public:
|
||||
IFACEMETHODIMP GetId(_Out_ int* id);
|
||||
IFACEMETHODIMP GetDepth(_Out_ UINT* depth);
|
||||
IFACEMETHODIMP PutDepth(_In_ int depth);
|
||||
IFACEMETHODIMP GetStatus(_Out_ PowerRenameItemRenameStatus* status);
|
||||
IFACEMETHODIMP PutStatus(_In_ PowerRenameItemRenameStatus status);
|
||||
IFACEMETHODIMP Reset();
|
||||
IFACEMETHODIMP ShouldRenameItem(_In_ DWORD flags, _Out_ bool* shouldRename);
|
||||
IFACEMETHODIMP IsItemVisible(_In_ DWORD filter, _In_ DWORD flags, _Out_ bool* isItemVisible);
|
||||
@@ -49,18 +51,18 @@ protected:
|
||||
|
||||
HRESULT _Init(_In_ IShellItem* psi);
|
||||
|
||||
bool m_selected = true;
|
||||
bool m_isFolder = false;
|
||||
bool m_isTimeParsed = false;
|
||||
bool m_canRename = true;
|
||||
int m_id = -1;
|
||||
int m_iconIndex = -1;
|
||||
UINT m_depth = 0;
|
||||
HRESULT m_error = S_OK;
|
||||
PWSTR m_path = nullptr;
|
||||
PWSTR m_originalName = nullptr;
|
||||
PWSTR m_newName = nullptr;
|
||||
SYSTEMTIME m_time = {0};
|
||||
CSRWLock m_lock;
|
||||
long m_refCount = 0;
|
||||
bool m_selected = true;
|
||||
bool m_isFolder = false;
|
||||
bool m_isTimeParsed = false;
|
||||
bool m_canRename = true;
|
||||
int m_id = -1;
|
||||
int m_iconIndex = -1;
|
||||
UINT m_depth = 0;
|
||||
PowerRenameItemRenameStatus m_status = PowerRenameItemRenameStatus::Init;
|
||||
PWSTR m_path = nullptr;
|
||||
PWSTR m_originalName = nullptr;
|
||||
PWSTR m_newName = nullptr;
|
||||
SYSTEMTIME m_time = {0};
|
||||
CSRWLock m_lock;
|
||||
long m_refCount = 0;
|
||||
};
|
||||
|
@@ -1115,6 +1115,36 @@ DWORD WINAPI CPowerRenameManager::s_regexWorkerThread(_In_ void* pv)
|
||||
itemEnumIndex++;
|
||||
}
|
||||
|
||||
spItem->PutStatus(PowerRenameItemRenameStatus::ShouldRename);
|
||||
if (newNameToUse != nullptr)
|
||||
{
|
||||
std::wstring newNameToUseWstr{ newNameToUse };
|
||||
PWSTR path = nullptr;
|
||||
spItem->GetPath(&path);
|
||||
|
||||
// Following characters cannot be used for file names.
|
||||
// Ref https://docs.microsoft.com/windows/win32/fileio/naming-a-file#naming-conventions
|
||||
if (newNameToUseWstr.contains('<') ||
|
||||
newNameToUseWstr.contains('>') ||
|
||||
newNameToUseWstr.contains(':') ||
|
||||
newNameToUseWstr.contains('"') ||
|
||||
newNameToUseWstr.contains('\\') ||
|
||||
newNameToUseWstr.contains('/') ||
|
||||
newNameToUseWstr.contains('|') ||
|
||||
newNameToUseWstr.contains('?') ||
|
||||
newNameToUseWstr.contains('*'))
|
||||
{
|
||||
spItem->PutStatus(PowerRenameItemRenameStatus::ItemNameInvalidChar);
|
||||
}
|
||||
// Max file path is 260 and max folder path is 247.
|
||||
// Ref https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
|
||||
else if ((isFolder && lstrlen(path) + (lstrlen(newNameToUse) - lstrlen(originalName)) > 247) ||
|
||||
lstrlen(path) + (lstrlen(newNameToUse) - lstrlen(originalName)) > 260)
|
||||
{
|
||||
spItem->PutStatus(PowerRenameItemRenameStatus::ItemNameTooLong);
|
||||
}
|
||||
}
|
||||
|
||||
winrt::check_hresult(spItem->PutNewName(newNameToUse));
|
||||
|
||||
// Was there a change?
|
||||
|
Reference in New Issue
Block a user