From c4c5fdc5372ff36953a1443f20dfa51653dcadbb Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:55:47 -0400 Subject: [PATCH 1/8] 1 --- .../Actions/FileSystem/RenameAction.cs | 22 +++++++------- src/Files.App/Dialogs/BulkRenameDialog.xaml | 20 +++++++++++++ .../Dialogs/BulkRenameDialog.xaml.cs | 30 +++++++++++++++++++ .../Services/App/AppDialogService.cs | 1 + .../Dialogs/BulkRenameDialogViewModel.cs | 20 +++++++++++++ 5 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 src/Files.App/Dialogs/BulkRenameDialog.xaml create mode 100644 src/Files.App/Dialogs/BulkRenameDialog.xaml.cs create mode 100644 src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs diff --git a/src/Files.App/Actions/FileSystem/RenameAction.cs b/src/Files.App/Actions/FileSystem/RenameAction.cs index 1896a5bbbb00..20172a0ee348 100644 --- a/src/Files.App/Actions/FileSystem/RenameAction.cs +++ b/src/Files.App/Actions/FileSystem/RenameAction.cs @@ -23,7 +23,7 @@ public RichGlyph Glyph context.ShellPage is not null && IsPageTypeValid() && context.ShellPage.SlimContentPage is not null && - IsSelectionValid(); + context.HasSelection; public RenameAction() { @@ -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(); + var result = await dialogService.ShowDialogAsync(viewModel); + } + else + { + context.ShellPage?.SlimContentPage?.ItemManipulationModel.StartRenameItem(); + } } private bool IsPageTypeValid() diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml new file mode 100644 index 000000000000..457969de538f --- /dev/null +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs new file mode 100644 index 000000000000..da7bd2bc47a9 --- /dev/null +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs @@ -0,0 +1,30 @@ +// 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 + { + private FrameworkElement RootAppElement + => (FrameworkElement)MainWindow.Instance.Content; + + public BulkRenameDialogViewModel ViewModel + { + get => (BulkRenameDialogViewModel)DataContext; + set => DataContext = value; + } + + public BulkRenameDialog() + { + InitializeComponent(); + } + + public new async Task ShowAsync() + { + return (DialogResult)await base.ShowAsync(); + } + } +} diff --git a/src/Files.App/Services/App/AppDialogService.cs b/src/Files.App/Services/App/AppDialogService.cs index 298533b94d04..ab30b5e6c959 100644 --- a/src/Files.App/Services/App/AppDialogService.cs +++ b/src/Files.App/Services/App/AppDialogService.cs @@ -35,6 +35,7 @@ public DialogService() { typeof(GitHubLoginDialogViewModel), () => new GitHubLoginDialog() }, { typeof(FileTooLargeDialogViewModel), () => new FileTooLargeDialog() }, { typeof(ReleaseNotesDialogViewModel), () => new ReleaseNotesDialog() }, + { typeof(BulkRenameDialogViewModel), () => new BulkRenameDialog() }, }.ToFrozenDictionary(); } diff --git a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs new file mode 100644 index 000000000000..a9ae73e39723 --- /dev/null +++ b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2024 Files Community +// Licensed under the MIT License. See the LICENSE. + +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Input; +using Windows.Storage.Pickers; +using Files.Shared.Helpers; + +namespace Files.App.ViewModels.Dialogs +{ + public sealed class BulkRenameDialogViewModel : ObservableObject + { + public BulkRenameDialogViewModel() + { + + } + } +} \ No newline at end of file From 9078a4329ceef173778beb79f2d0c55a3a1c81d8 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:02:47 -0400 Subject: [PATCH 2/8] Title --- src/Files.App/Dialogs/BulkRenameDialog.xaml | 4 +++- src/Files.App/Strings/en-US/Resources.resw | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml index 457969de538f..9936d58d2ec1 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -7,10 +7,12 @@ 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=NewShortcutDialogTitle}" + Title="{helpers:ResourceString Name=BulkRename}" DefaultButton="Primary" HighContrastAdjustment="None" + PrimaryButtonText="{helpers:ResourceString Name=Rename}" RequestedTheme="{x:Bind RootAppElement.RequestedTheme, Mode=OneWay}" + SecondaryButtonText="{helpers:ResourceString Name=Cancel}" Style="{StaticResource DefaultContentDialogStyle}" mc:Ignorable="d"> diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index c0352332b016..ed3df48d111f 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -3947,4 +3947,7 @@ User ID + + Bulk rename + \ No newline at end of file From 1d4fe52113d9c2ba66e5a6a701c79fe8dfc6931d Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:16:30 -0400 Subject: [PATCH 3/8] Validation --- src/Files.App/Dialogs/BulkRenameDialog.xaml | 42 +++++++++++++++++-- .../Dialogs/BulkRenameDialogViewModel.cs | 23 ++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml index 9936d58d2ec1..27a6da17df43 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -16,7 +16,43 @@ Style="{StaticResource DefaultContentDialogStyle}" mc:Ignorable="d"> - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs index a9ae73e39723..d3c5f421f452 100644 --- a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs +++ b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs @@ -12,6 +12,29 @@ namespace Files.App.ViewModels.Dialogs { public sealed class BulkRenameDialogViewModel : ObservableObject { + // Properties + + public bool IsNameValid => + FilesystemHelpers.IsValidForFilename(fileName); + + 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)); + } + } + } + public BulkRenameDialogViewModel() { From 19e01c76fbc03a46a43845810124fcf879b867f1 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:05:35 -0400 Subject: [PATCH 4/8] Finished --- src/Files.App/Dialogs/BulkRenameDialog.xaml | 2 + .../Dialogs/BulkRenameDialogViewModel.cs | 39 ++++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml index 27a6da17df43..39afbb00ea58 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -10,6 +10,8 @@ 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}" diff --git a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs index d3c5f421f452..1f227120f08e 100644 --- a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs +++ b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs @@ -1,26 +1,23 @@ // Copyright (c) 2024 Files Community // Licensed under the MIT License. See the LICENSE. -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Windows.Input; -using Windows.Storage.Pickers; -using Files.Shared.Helpers; +using Windows.Storage; namespace Files.App.ViewModels.Dialogs { public sealed class BulkRenameDialogViewModel : ObservableObject { + private IContentPageContext context { get; } = Ioc.Default.GetRequiredService(); + // Properties public bool IsNameValid => - FilesystemHelpers.IsValidForFilename(fileName); - + FilesystemHelpers.IsValidForFilename(fileName) && !fileName.Contains("."); + public bool ShowNameWarning => !string.IsNullOrEmpty(fileName) && !IsNameValid; - + private string fileName = string.Empty; public string FileName { @@ -35,9 +32,31 @@ public string FileName } } + // 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 + ); + })); + } } } \ No newline at end of file From 8805d907f87a721573b6e9ad0943f99f3be5e062 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:01:33 -0400 Subject: [PATCH 5/8] Requested changes --- src/Files.App/Dialogs/BulkRenameDialog.xaml | 5 +++++ src/Files.App/Dialogs/BulkRenameDialog.xaml.cs | 7 ------- .../Dialogs/BulkRenameDialogViewModel.cs | 14 ++++++-------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml index 39afbb00ea58..dbc84b7ccaad 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -7,6 +7,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:helpers="using:Files.App.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:vm="using:Files.App.ViewModels.Dialogs" Title="{helpers:ResourceString Name=BulkRename}" DefaultButton="Primary" HighContrastAdjustment="None" @@ -18,6 +19,10 @@ Style="{StaticResource DefaultContentDialogStyle}" mc:Ignorable="d"> + + + + diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs index da7bd2bc47a9..18d36fd2ec7a 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs @@ -1,6 +1,5 @@ // Copyright (c) 2024 Files Community // Licensed under the MIT License. See the LICENSE. - using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -11,12 +10,6 @@ public sealed partial class BulkRenameDialog : ContentDialog, IDialog (FrameworkElement)MainWindow.Instance.Content; - public BulkRenameDialogViewModel ViewModel - { - get => (BulkRenameDialogViewModel)DataContext; - set => DataContext = value; - } - public BulkRenameDialog() { InitializeComponent(); diff --git a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs index 1f227120f08e..7cc18efb9de4 100644 --- a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs +++ b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs @@ -12,19 +12,18 @@ public sealed class BulkRenameDialogViewModel : ObservableObject // Properties public bool IsNameValid => - FilesystemHelpers.IsValidForFilename(fileName) && !fileName.Contains("."); + FilesystemHelpers.IsValidForFilename(_FileName) && !_FileName.Contains("."); public bool ShowNameWarning => - !string.IsNullOrEmpty(fileName) && !IsNameValid; + !string.IsNullOrEmpty(_FileName) && !IsNameValid; - - private string fileName = string.Empty; + private string _FileName = string.Empty; public string FileName { - get => fileName; + get => _FileName; set { - if (SetProperty(ref fileName, value)) + if (SetProperty(ref _FileName, value)) { OnPropertyChanged(nameof(IsNameValid)); OnPropertyChanged(nameof(ShowNameWarning)); @@ -50,13 +49,12 @@ 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, + FileName + item.FileExtension, NameCollisionOption.GenerateUniqueName, true, false ); })); - } } } \ No newline at end of file From 608c4a7d2450ff8dac3cf051baade43a5e2a4da4 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:02:04 -0400 Subject: [PATCH 6/8] Fix --- src/Files.App/Dialogs/BulkRenameDialog.xaml | 5 ----- src/Files.App/Dialogs/BulkRenameDialog.xaml.cs | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml index dbc84b7ccaad..39afbb00ea58 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -7,7 +7,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:helpers="using:Files.App.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:vm="using:Files.App.ViewModels.Dialogs" Title="{helpers:ResourceString Name=BulkRename}" DefaultButton="Primary" HighContrastAdjustment="None" @@ -19,10 +18,6 @@ Style="{StaticResource DefaultContentDialogStyle}" mc:Ignorable="d"> - - - - diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs index 18d36fd2ec7a..a7f5b5478b65 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml.cs @@ -10,6 +10,12 @@ public sealed partial class BulkRenameDialog : ContentDialog, IDialog (FrameworkElement)MainWindow.Instance.Content; + public BulkRenameDialogViewModel ViewModel + { + get => (BulkRenameDialogViewModel)DataContext; + set => DataContext = value; + } + public BulkRenameDialog() { InitializeComponent(); From a584d318f2bea5310d2167572a4c3986b91a121d Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:15:39 -0400 Subject: [PATCH 7/8] Update src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs Co-authored-by: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> --- src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs index 7cc18efb9de4..cf363bf90482 100644 --- a/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs +++ b/src/Files.App/ViewModels/Dialogs/BulkRenameDialogViewModel.cs @@ -32,6 +32,7 @@ public string FileName } // Commands + public IAsyncRelayCommand CommitRenameCommand { get; private set; } public BulkRenameDialogViewModel() From 4ff188409e00d7a21d6eac690672eb8b3c9472d3 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:15:57 -0400 Subject: [PATCH 8/8] Update src/Files.App/Dialogs/BulkRenameDialog.xaml Co-authored-by: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> --- src/Files.App/Dialogs/BulkRenameDialog.xaml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Files.App/Dialogs/BulkRenameDialog.xaml b/src/Files.App/Dialogs/BulkRenameDialog.xaml index 39afbb00ea58..21c462ab6fda 100644 --- a/src/Files.App/Dialogs/BulkRenameDialog.xaml +++ b/src/Files.App/Dialogs/BulkRenameDialog.xaml @@ -1,4 +1,3 @@ -