Skip to content

Commit

Permalink
Feature: Added support for bulk rename (#16228)
Browse files Browse the repository at this point in the history
Co-authored-by: 0x5BFA <[email protected]>
  • Loading branch information
yaira2 and 0x5bfa authored Sep 30, 2024
1 parent e3f8f15 commit 593d11e
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/Files.App/Actions/FileSystem/RenameAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public RichGlyph Glyph
context.ShellPage is not null &&
IsPageTypeValid() &&
context.ShellPage.SlimContentPage is not null &&
IsSelectionValid();
context.HasSelection;

public RenameAction()
{
Expand All @@ -32,16 +32,18 @@ public RenameAction()
context.PropertyChanged += Context_PropertyChanged;
}

public Task ExecuteAsync(object? parameter = null)
public async Task ExecuteAsync(object? parameter = null)
{
context.ShellPage?.SlimContentPage?.ItemManipulationModel.StartRenameItem();

return Task.CompletedTask;
}

private bool IsSelectionValid()
{
return context.HasSelection && context.SelectedItems.Count == 1;
if (context.SelectedItems.Count > 1)
{
var viewModel = new BulkRenameDialogViewModel();
var dialogService = Ioc.Default.GetRequiredService<IDialogService>();
var result = await dialogService.ShowDialogAsync(viewModel);
}
else
{
context.ShellPage?.SlimContentPage?.ItemManipulationModel.StartRenameItem();
}
}

private bool IsPageTypeValid()
Expand Down
59 changes: 59 additions & 0 deletions src/Files.App/Dialogs/BulkRenameDialog.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!-- Copyright (c) 2024 Files Community. Licensed under the MIT License. See the LICENSE. -->
<ContentDialog
x:Class="Files.App.Dialogs.BulkRenameDialog"
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:helpers="using:Files.App.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{helpers:ResourceString Name=BulkRename}"
DefaultButton="Primary"
HighContrastAdjustment="None"
IsPrimaryButtonEnabled="{x:Bind ViewModel.IsNameValid, Mode=OneWay}"
PrimaryButtonCommand="{x:Bind ViewModel.CommitRenameCommand, Mode=OneWay}"
PrimaryButtonText="{helpers:ResourceString Name=Rename}"
RequestedTheme="{x:Bind RootAppElement.RequestedTheme, Mode=OneWay}"
SecondaryButtonText="{helpers:ResourceString Name=Cancel}"
Style="{StaticResource DefaultContentDialogStyle}"
mc:Ignorable="d">

<StackPanel Width="440" Spacing="4">

<!-- Name -->
<Grid
Padding="12"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
ColumnSpacing="8"
CornerRadius="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
Text="{helpers:ResourceString Name=Name}" />

<TextBox
x:Name="FileNameBox"
Grid.Column="1"
Width="260"
PlaceholderText="{helpers:ResourceString Name=EnterName}"
Text="{x:Bind ViewModel.FileName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Resources>
<TeachingTip
x:Name="InvalidNameWarning"
Title="{helpers:ResourceString Name=InvalidFilename/Text}"
IsOpen="{x:Bind ViewModel.ShowNameWarning, Mode=OneWay}"
PreferredPlacement="Bottom"
Target="{x:Bind FileNameBox}" />
</TextBox.Resources>
</TextBox>

</Grid>

</StackPanel>
</ContentDialog>
29 changes: 29 additions & 0 deletions src/Files.App/Dialogs/BulkRenameDialog.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace Files.App.Dialogs
{
public sealed partial class BulkRenameDialog : ContentDialog, IDialog<BulkRenameDialogViewModel>
{
private FrameworkElement RootAppElement
=> (FrameworkElement)MainWindow.Instance.Content;

public BulkRenameDialogViewModel ViewModel
{
get => (BulkRenameDialogViewModel)DataContext;
set => DataContext = value;
}

public BulkRenameDialog()
{
InitializeComponent();
}

public new async Task<DialogResult> ShowAsync()
{
return (DialogResult)await base.ShowAsync();
}
}
}
1 change: 1 addition & 0 deletions src/Files.App/Services/App/AppDialogService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public DialogService()
{ typeof(GitHubLoginDialogViewModel), () => new GitHubLoginDialog() },
{ typeof(FileTooLargeDialogViewModel), () => new FileTooLargeDialog() },
{ typeof(ReleaseNotesDialogViewModel), () => new ReleaseNotesDialog() },
{ typeof(BulkRenameDialogViewModel), () => new BulkRenameDialog() },
}.ToFrozenDictionary();
}

Expand Down
3 changes: 3 additions & 0 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -3947,4 +3947,7 @@
<data name="UserID" xml:space="preserve">
<value>User ID</value>
</data>
<data name="BulkRename" xml:space="preserve">
<value>Bulk rename</value>
</data>
</root>
61 changes: 61 additions & 0 deletions src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using Windows.Storage;

namespace Files.App.ViewModels.Dialogs
{
public sealed class BulkRenameDialogViewModel : ObservableObject
{
private IContentPageContext context { get; } = Ioc.Default.GetRequiredService<IContentPageContext>();

// Properties

public bool IsNameValid =>
FilesystemHelpers.IsValidForFilename(_FileName) && !_FileName.Contains(".");

public bool ShowNameWarning =>
!string.IsNullOrEmpty(_FileName) && !IsNameValid;

private string _FileName = string.Empty;
public string FileName
{
get => _FileName;
set
{
if (SetProperty(ref _FileName, value))
{
OnPropertyChanged(nameof(IsNameValid));
OnPropertyChanged(nameof(ShowNameWarning));
}
}
}

// Commands

public IAsyncRelayCommand CommitRenameCommand { get; private set; }

public BulkRenameDialogViewModel()
{
CommitRenameCommand = new AsyncRelayCommand(DoCommitRenameAsync);
}

private async Task DoCommitRenameAsync()
{
if (context.ShellPage is null)
return;

await Task.WhenAll(context.SelectedItems.Select(item =>
{
var itemType = item.PrimaryItemAttribute == StorageItemTypes.Folder ? FilesystemItemType.Directory : FilesystemItemType.File;
return context.ShellPage.FilesystemHelpers.RenameAsync(
StorageHelpers.FromPathAndType(item.ItemPath, itemType),
FileName + item.FileExtension,
NameCollisionOption.GenerateUniqueName,
true,
false
);
}));
}
}
}

0 comments on commit 593d11e

Please sign in to comment.