Sfoglia il codice sorgente

Refactor: move file operation commands to `Tools` namespace. Remove redundant methods and commands from `MainViewModel`, update bindings across views, and streamline command structure for file-related tasks.

Ruben 3 mesi fa
parent
commit
068c9772da

+ 7 - 7
src/PicView.Avalonia.MacOS/Views/ExifWindow.axaml

@@ -34,7 +34,7 @@
                 BorderThickness="0,0,1,0"
                 Classes="errorHover"
                 ClickMode="Release"
-                Command="{CompiledBinding RecycleFileCommand}"
+                Command="{CompiledBinding Tools.RecycleFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Data="{StaticResource RecycleGeometry}"
@@ -70,7 +70,7 @@
                 BorderBrush="{DynamicResource MainBorderColor}"
                 BorderThickness="0,0,1,0"
                 Classes="noBorderHover"
-                Command="{CompiledBinding OpenWithCommand}"
+                Command="{CompiledBinding Tools.OpenWithCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Data="{StaticResource OpenWithGeometry}"
@@ -88,7 +88,7 @@
                 BorderBrush="{DynamicResource MainBorderColor}"
                 BorderThickness="0,0,1,0"
                 Classes="noBorderHover"
-                Command="{CompiledBinding PrintCommand}"
+                Command="{CompiledBinding Tools.PrintCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Data="{StaticResource PrintGeometry}"
@@ -106,7 +106,7 @@
                 BorderBrush="{DynamicResource MainBorderColor}"
                 BorderThickness="0,0,1,0"
                 Classes="noBorderHover"
-                Command="{CompiledBinding CopyImageCommand}"
+                Command="{CompiledBinding Tools.CopyImageCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 DockPanel.Dock="Right"
@@ -123,7 +123,7 @@
                 BorderBrush="{DynamicResource MainBorderColor}"
                 BorderThickness="0,0,1,0"
                 Classes="noBorderHover"
-                Command="{CompiledBinding CopyFileCommand}"
+                Command="{CompiledBinding Tools.CopyFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Data="{StaticResource CopyGeometry}"
@@ -141,7 +141,7 @@
                 BorderBrush="{DynamicResource MainBorderColor}"
                 BorderThickness="0,0,1,0"
                 Classes="noBorderHover"
-                Command="{CompiledBinding DuplicateFileCommand}"
+                Command="{CompiledBinding Tools.DuplicateFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Data="{StaticResource DuplicateGeometry}"
@@ -159,7 +159,7 @@
                 BorderBrush="{DynamicResource MainBorderColor}"
                 BorderThickness="1,0,1,0"
                 Classes="noBorderHover"
-                Command="{CompiledBinding LocateOnDiskCommand}"
+                Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Data="{StaticResource ShowInFolderGeometry}"

+ 18 - 14
src/PicView.Avalonia.MacOS/Views/MacMainWindow.axaml

@@ -24,17 +24,17 @@
         <NativeMenu>
             <NativeMenuItem Header="{CompiledBinding Translation.File.Value}">
                 <NativeMenu>
-                    <NativeMenuItem Command="{CompiledBinding OpenFileCommand}" Header="{CompiledBinding Translation.Open.Value, Mode=OneWay}" />
+                    <NativeMenuItem Command="{CompiledBinding Tools.OpenFileCommand}" Header="{CompiledBinding Translation.Open.Value, Mode=OneWay}" />
                     <!--  <NativeMenuItem  -->
                     <!--  Command="{CompiledBinding OpenWithCommand}"  -->
                     <!--  CommandParameter="{CompiledBinding PicViewer.FileInfo.FullName,  -->
                     <!--  FallbackValue=''}"  -->
                     <!--  Header="{CompiledBinding Translation.OpenWith,  -->
                     <!--  Mode=OneWay}" />  -->
-                    <NativeMenuItem Command="{CompiledBinding SaveFileCommand}" Header="{CompiledBinding Translation.Save.Value, Mode=OneWay}" />
-                    <NativeMenuItem Command="{CompiledBinding SaveFileAsCommand}" Header="{CompiledBinding Translation.SaveAs.Value, Mode=OneWay}" />
+                    <NativeMenuItem Command="{CompiledBinding Tools.SaveFileCommand}" Header="{CompiledBinding Translation.Save.Value, Mode=OneWay}" />
+                    <NativeMenuItem Command="{CompiledBinding Tools.SaveFileAsCommand}" Header="{CompiledBinding Translation.SaveAs.Value, Mode=OneWay}" />
                     <NativeMenuItem
-                        Command="{CompiledBinding PrintCommand}"
+                        Command="{CompiledBinding Tools.PrintCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.Print.Value,
@@ -42,7 +42,7 @@
                         IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
                                                     Converter={x:Static ObjectConverters.IsNotNull}}" />
                     <NativeMenuItem
-                        Command="{CompiledBinding LocateOnDiskCommand}"
+                        Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.ShowInFolder.Value,
@@ -51,7 +51,7 @@
                                                     Converter={x:Static ObjectConverters.IsNotNull}}" />
                     <NativeMenuItemSeparator />
                     <NativeMenuItem
-                        Command="{CompiledBinding DeleteFileCommand}"
+                        Command="{CompiledBinding Tools.DeleteFilePermanentlyCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.DeleteFile.Value,
@@ -70,7 +70,7 @@
                     <NativeMenuItem Command="{CompiledBinding NewWindowCommand}" Header="{CompiledBinding Translation.NewWindow.Value, Mode=OneWay}" />
                     <NativeMenuItemSeparator />
                     <NativeMenuItem
-                        Command="{CompiledBinding RenameCommand}"
+                        Command="{CompiledBinding Tools.RenameCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.RenameFile.Value,
@@ -78,10 +78,10 @@
                         IsEnabled="{CompiledBinding PicViewer.FileInfo,
                                                     Converter={x:Static ObjectConverters.IsNotNull}}" />
                     <NativeMenuItemSeparator />
-                    <NativeMenuItem Command="{CompiledBinding PasteCommand}" Header="{CompiledBinding Translation.Paste.Value, Mode=OneWay}" />
+                    <NativeMenuItem Command="{CompiledBinding Tools.PasteCommand}" Header="{CompiledBinding Translation.Paste.Value, Mode=OneWay}" />
                     <NativeMenuItemSeparator />
                     <NativeMenuItem
-                        Command="{CompiledBinding CopyFileCommand}"
+                        Command="{CompiledBinding Tools.CopyFileCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.CopyFile.Value,
@@ -89,7 +89,7 @@
                         IsEnabled="{CompiledBinding PicViewer.FileInfo.Value,
                                                     Converter={x:Static ObjectConverters.IsNotNull}}" />
                     <NativeMenuItem
-                        Command="{CompiledBinding CopyImageCommand}"
+                        Command="{CompiledBinding Tools.CopyImageCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.CopyImage.Value,
@@ -97,7 +97,7 @@
                         IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
                                                     Converter={x:Static ObjectConverters.IsNotNull}}" />
                     <NativeMenuItem
-                        Command="{CompiledBinding CopyFilePathCommand}"
+                        Command="{CompiledBinding Tools.CopyFilePathCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.FileCopyPath.Value,
@@ -105,7 +105,7 @@
                         IsEnabled="{CompiledBinding PicViewer.FileInfo.Value,
                                                     Converter={x:Static ObjectConverters.IsNotNull}}" />
                     <NativeMenuItem
-                        Command="{CompiledBinding DuplicateFileCommand}"
+                        Command="{CompiledBinding Tools.DuplicateFileCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.DuplicateFile.Value,
@@ -157,7 +157,7 @@
                     <NativeMenuItemSeparator />
                     <NativeMenuItem Command="{CompiledBinding ShowExifWindowCommand}" Header="{CompiledBinding Translation.ImageInfo.Value, Mode=OneWay}" />
                     <NativeMenuItem
-                        Command="{CompiledBinding FilePropertiesCommand}"
+                        Command="{CompiledBinding Tools.FilePropertiesCommand}"
                         CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                            FallbackValue=''}"
                         Header="{CompiledBinding Translation.FileProperties.Value,
@@ -184,7 +184,11 @@
             <!--  Navigation  -->
             <NativeMenuItem Header="{CompiledBinding Translation.Navigation.Value, Mode=OneWay}">
                 <NativeMenu>
-                    <NativeMenuItem Command="{CompiledBinding SlideshowCommand}" Header="{CompiledBinding Translation.Slideshow.Value, Mode=OneWay}" />
+                    <NativeMenuItem
+                        Command="{CompiledBinding Tools.StartSlideShowTask}"
+                        CommandParameter="-1"
+                        Header="{CompiledBinding Translation.Slideshow.Value,
+                                                 Mode=OneWay}" />
                     <NativeMenuItemSeparator />
                     <NativeMenuItem Command="{CompiledBinding Navigation.FirstCommand}" Header="{CompiledBinding Translation.FirstImage.Value, Mode=OneWay}" />
                     <NativeMenuItem Command="{CompiledBinding Navigation.LastCommand}" Header="{CompiledBinding Translation.LastImage.Value, Mode=OneWay}" />

+ 3 - 3
src/PicView.Avalonia.Win32/Views/EffectsWindow.axaml

@@ -81,7 +81,7 @@
                     Width="30">
                     <customControls:IconButton.Flyout>
                         <MenuFlyout FlyoutPresenterClasses="noCornerRadius" Placement="Bottom">
-                            <MenuItem Command="{CompiledBinding SaveFileCommand}" Header="{CompiledBinding Translation.Save.Value, Mode=OneWay}">
+                            <MenuItem Command="{CompiledBinding Tools.SaveFileCommand}" Header="{CompiledBinding Translation.Save.Value, Mode=OneWay}">
                                 <MenuItem.Icon>
                                     <Path
                                         Data="{StaticResource SaveGeometry}"
@@ -91,7 +91,7 @@
                                         Width="12" />
                                 </MenuItem.Icon>
                             </MenuItem>
-                            <MenuItem Command="{CompiledBinding SaveFileAsCommand}" Header="{CompiledBinding Translation.SaveAs.Value, Mode=OneWay}">
+                            <MenuItem Command="{CompiledBinding Tools.SaveFileAsCommand}" Header="{CompiledBinding Translation.SaveAs.Value, Mode=OneWay}">
                                 <MenuItem.Icon>
                                     <Path
                                         Data="{StaticResource SaveGeometry}"
@@ -101,7 +101,7 @@
                                         Width="12" />
                                 </MenuItem.Icon>
                             </MenuItem>
-                            <MenuItem Command="{CompiledBinding CopyImageCommand}" Header="{CompiledBinding Translation.CopyImage.Value, Mode=OneWay}">
+                            <MenuItem Command="{CompiledBinding Tools.CopyImageCommand}" Header="{CompiledBinding Translation.CopyImage.Value, Mode=OneWay}">
                                 <MenuItem.Icon>
                                     <Path
                                         Data="{StaticResource CopyGeometry}"

+ 7 - 7
src/PicView.Avalonia.Win32/Views/ExifWindow.axaml

@@ -94,7 +94,7 @@
                     BorderThickness="0,0,1,0"
                     Classes="errorHover"
                     ClickMode="Release"
-                    Command="{CompiledBinding RecycleFileCommand}"
+                    Command="{CompiledBinding Tools.RecycleFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource RecycleGeometry}"
@@ -130,7 +130,7 @@
                     BorderBrush="{DynamicResource MainBorderColor}"
                     BorderThickness="0,0,1,0"
                     Classes="noBorderHover"
-                    Command="{CompiledBinding OpenWithCommand}"
+                    Command="{CompiledBinding Tools.OpenWithCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource OpenWithGeometry}"
@@ -148,7 +148,7 @@
                     BorderBrush="{DynamicResource MainBorderColor}"
                     BorderThickness="0,0,1,0"
                     Classes="noBorderHover"
-                    Command="{CompiledBinding PrintCommand}"
+                    Command="{CompiledBinding Tools.PrintCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource PrintGeometry}"
@@ -166,7 +166,7 @@
                     BorderBrush="{DynamicResource MainBorderColor}"
                     BorderThickness="0,0,1,0"
                     Classes="noBorderHover"
-                    Command="{CompiledBinding CopyImageCommand}"
+                    Command="{CompiledBinding Tools.CopyImageCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     DockPanel.Dock="Right"
@@ -183,7 +183,7 @@
                     BorderBrush="{DynamicResource MainBorderColor}"
                     BorderThickness="0,0,1,0"
                     Classes="noBorderHover"
-                    Command="{CompiledBinding CopyFileCommand}"
+                    Command="{CompiledBinding Tools.CopyFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource CopyGeometry}"
@@ -201,7 +201,7 @@
                     BorderBrush="{DynamicResource MainBorderColor}"
                     BorderThickness="0,0,1,0"
                     Classes="noBorderHover"
-                    Command="{CompiledBinding DuplicateFileCommand}"
+                    Command="{CompiledBinding Tools.DuplicateFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource DuplicateGeometry}"
@@ -219,7 +219,7 @@
                     BorderBrush="{DynamicResource MainBorderColor}"
                     BorderThickness="1,0,1,0"
                     Classes="noBorderHover"
-                    Command="{CompiledBinding LocateOnDiskCommand}"
+                    Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource ShowInFolderGeometry}"

+ 4 - 4
src/PicView.Avalonia.Win32/Views/WinTitleBar.axaml

@@ -15,28 +15,28 @@
     <UserControl.ContextMenu>
         <ContextMenu x:Name="RotationContextMenu">
             <MenuItem
-                Command="{CompiledBinding RotateToCommand}"
+                Command="{CompiledBinding Tools.RotateTask}"
                 CommandParameter="0"
                 GroupName="RotationGroup"
                 Header="0°"
                 ToggleType="Radio"
                 x:Name="Rotation0Item" />
             <MenuItem
-                Command="{CompiledBinding RotateToCommand}"
+                Command="{CompiledBinding Tools.RotateTask}"
                 CommandParameter="90"
                 GroupName="RotationGroup"
                 Header="90°"
                 ToggleType="Radio"
                 x:Name="Rotation90Item" />
             <MenuItem
-                Command="{CompiledBinding RotateToCommand}"
+                Command="{CompiledBinding Tools.RotateTask}"
                 CommandParameter="180"
                 GroupName="RotationGroup"
                 Header="180°"
                 ToggleType="Radio"
                 x:Name="Rotation180Item" />
             <MenuItem
-                Command="{CompiledBinding RotateToCommand}"
+                Command="{CompiledBinding Tools.RotateTask}"
                 CommandParameter="270"
                 GroupName="RotationGroup"
                 Header="270°"

+ 1 - 77
src/PicView.Avalonia/Converters/ConversionHelper.cs

@@ -1,8 +1,4 @@
-using ImageMagick;
-using PicView.Avalonia.Interfaces;
-using PicView.Avalonia.Navigation;
-using PicView.Avalonia.UI;
-using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.ViewModels;
 using PicView.Core.DebugTools;
 using PicView.Core.ImageDecoding;
 
@@ -10,33 +6,6 @@ namespace PicView.Avalonia.Converters;
 
 internal static class ConversionHelper
 {
-    public static async Task<bool> ResizeImageByPercentage(FileInfo fileInfo, int selectedIndex)
-    {
-        var percentage = 100 - selectedIndex * 5;
-
-        if (percentage is < 5 or > 100)
-        {
-            return false;
-        }
-
-        var magickPercentage = new Percentage(percentage);
-        return await SaveImageFileHelper.ResizeImageAsync(fileInfo, 0, 0, 100, magickPercentage).ConfigureAwait(false);
-    }
-    
-    public static async Task ResizeImageByPercentage(int percentage, MainViewModel vm)
-    {
-        TitleManager.SetLoadingTitle(vm);
-        var success = await ResizeImageByPercentage(vm.PicViewer.FileInfo.CurrentValue, percentage);
-        if (success)
-        {
-            await NavigationManager.QuickReload();
-        }
-        else
-        {
-            TitleManager.SetTitle(vm);
-        }
-    }
-
     public static async Task<bool> ResizeByWidth(FileInfo fileInfo, double width)
     {
         if (width <= 0)
@@ -57,51 +26,6 @@ internal static class ConversionHelper
         return await SaveImageFileHelper.ResizeImageAsync(fileInfo, 0, (uint)height).ConfigureAwait(false);
     }
 
-    public static async Task<string> ConvertTask(FileInfo fileInfo, int selectedIndex, IPlatformSpecificService platform)
-    {
-        var currentExtension = fileInfo.Extension.ToLower();
-        var newExtension = selectedIndex switch
-        {
-            1 => ".png",
-            2 => ".jpg",
-            3 => ".webp",
-            4 => ".avif",
-            5 => ".heic",
-            6 => ".jxl",
-            _ => currentExtension
-        };
-        if (currentExtension == newExtension)
-        {
-            return string.Empty;
-        }
-        var oldPath = fileInfo.FullName;
-        var newPath = Path.ChangeExtension(fileInfo.FullName, newExtension);
-
-        var success = await SaveImageFileHelper.SaveImageAsync(null, oldPath, null, null, null, null,
-            newExtension);
-        if (!success)
-        {
-            return string.Empty;
-        }
-
-        await platform.DeleteFile(oldPath, true);
-        return newPath;
-    }
-    
-    public static async Task ConvertFileExtension(int index, MainViewModel vm)
-    {
-        if (vm.PicViewer.FileInfo is null)
-        {
-            return;
-        }
-
-        var newPath = await ConvertTask(vm.PicViewer.FileInfo.CurrentValue, index, vm.PlatformService);
-        if (!string.IsNullOrWhiteSpace(newPath))
-        {
-            await NavigationManager.LoadPicFromStringAsync(newPath, vm);
-        }
-    }
-    
     public static void DetermineIfOptimizeImageShouldBeEnabled(MainViewModel vm)
     {
         if (vm.PicViewer.FileInfo is null)

+ 0 - 131
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -3,13 +3,9 @@ using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls.Primitives;
 using Avalonia.Media;
-using PicView.Avalonia.Clipboard;
-using PicView.Avalonia.Converters;
-using PicView.Avalonia.FileSystem;
 using PicView.Avalonia.Functions;
 using PicView.Avalonia.ImageTransformations.Rotation;
 using PicView.Avalonia.Interfaces;
-using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.WindowBehavior;
 using PicView.Core.FileSorting;
@@ -111,7 +107,6 @@ public class MainViewModel : ReactiveObject
         {
             await RotationNavigation.RotateRight(this, RotationButton.RotateRightButton);
         });
-        RotateToCommand = FunctionsHelper.CreateReactiveCommand<string>(RotateToTask);
 
         RotateRightWindowBorderButtonCommand = FunctionsHelper.CreateReactiveCommand(async () =>
         {
@@ -134,49 +129,6 @@ public class MainViewModel : ReactiveObject
 
         #endregion Image commands
 
-        #region File commands
-
-        OpenFileCommand = FunctionsHelper.CreateReactiveCommand(() => { Task.Run(FunctionsMapper.Open); });
-
-        OpenLastFileCommand = FunctionsHelper.CreateReactiveCommand(() => { Task.Run(FunctionsMapper.OpenLastFile); });
-
-        SaveFileCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.Save);
-
-        SaveFileAsCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.SaveAs);
-
-        CopyFileCommand = FunctionsHelper.CreateReactiveCommand<string>(CopyFileTask);
-
-        CopyFilePathCommand = FunctionsHelper.CreateReactiveCommand<string>(CopyFilePathTask);
-
-        FilePropertiesCommand = FunctionsHelper.CreateReactiveCommand<string>(ShowFilePropertiesTask);
-
-        CopyImageCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.CopyImage);
-
-        CopyBase64Command = FunctionsHelper.CreateReactiveCommand<string>(CopyBase64Task);
-
-        CutCommand = FunctionsHelper.CreateReactiveCommand<string>(CutFileTask);
-
-        PasteCommand = FunctionsHelper.CreateReactiveCommand(() => { Task.Run(FunctionsMapper.Paste); });
-
-        OpenWithCommand = FunctionsHelper.CreateReactiveCommand<string>(OpenWithTask);
-
-        RenameCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.Rename);
-
-        ResizeCommand = FunctionsHelper.CreateReactiveCommand<int>(ResizeImageByPercentage);
-        ConvertCommand = FunctionsHelper.CreateReactiveCommand<int>(ConvertFileExtension);
-
-        DuplicateFileCommand = FunctionsHelper.CreateReactiveCommand<string>(DuplicateFileTask);
-
-        PrintCommand = FunctionsHelper.CreateReactiveCommand<string>(PrintTask);
-
-        DeleteFileCommand = FunctionsHelper.CreateReactiveCommand<string>(DeleteFileTask);
-
-        RecycleFileCommand = FunctionsHelper.CreateReactiveCommand<string>(RecycleFileTask);
-
-        LocateOnDiskCommand = FunctionsHelper.CreateReactiveCommand<string>(LocateOnDiskTask);
-
-        #endregion File commands
-
         #region UI Commands
 
         ToggleUICommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.ToggleInterface);
@@ -196,7 +148,6 @@ public class MainViewModel : ReactiveObject
         ChangeCtrlZoomCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.ChangeCtrlZoom);
 
         ColorPickerCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.ColorPicker);
-        SlideshowCommand = FunctionsHelper.CreateReactiveCommand<int>(StartSlideShowTask);
 
         ToggleTaskbarProgressCommand = FunctionsHelper.CreateReactiveCommand(FunctionsMapper.ToggleTaskbarProgress);
         
@@ -241,35 +192,16 @@ public class MainViewModel : ReactiveObject
     public ReactiveCommand<Unit, Unit>? MaximizeCommand { get; }
     public ReactiveCommand<Unit, Unit>? RestoreCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleFullscreenCommand { get; }
-    public ReactiveCommand<Unit, Unit>? OpenFileCommand { get; }
-    public ReactiveCommand<Unit, Unit>? SaveFileCommand { get; }
-    public ReactiveCommand<Unit, Unit>? SaveFileAsCommand { get; }
-    public ReactiveCommand<Unit, Unit>? OpenLastFileCommand { get; }
-    public ReactiveCommand<Unit, Unit>? PasteCommand { get; }
-    public ReactiveCommand<string, Unit>? CopyFileCommand { get; }
-    public ReactiveCommand<string, Unit>? CopyBase64Command { get; }
-    public ReactiveCommand<string, Unit>? CopyFilePathCommand { get; }
-    public ReactiveCommand<string, Unit>? FilePropertiesCommand { get; }
-    public ReactiveCommand<Unit, Unit>? CopyImageCommand { get; }
-    public ReactiveCommand<string, Unit>? CutCommand { get; }
-    public ReactiveCommand<string, Unit>? PrintCommand { get; }
-    public ReactiveCommand<string, Unit>? DeleteFileCommand { get; }
-    public ReactiveCommand<string, Unit>? RecycleFileCommand { get; }
     public ReactiveCommand<Unit, Unit>? CloseMenuCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleFileMenuCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleImageMenuCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleSettingsMenuCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleToolsMenuCommand { get; }
-    public ReactiveCommand<string, Unit>? LocateOnDiskCommand { get; }
-    public ReactiveCommand<string, Unit>? OpenWithCommand { get; }
-    public ReactiveCommand<Unit, Unit>? RenameCommand { get; }
     public ReactiveCommand<Unit, Unit>? NewWindowCommand { get; }
-    public ReactiveCommand<string, Unit>? DuplicateFileCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleLoopingCommand { get; }
     public ReactiveCommand<Unit, Unit>? RotateLeftCommand { get; }
     public ReactiveCommand<Unit, Unit>? RotateLeftButtonCommand { get; }
     public ReactiveCommand<Unit, Unit>? RotateRightCommand { get; }
-    public ReactiveCommand<string, Unit>? RotateToCommand { get; }
     public ReactiveCommand<Unit, Unit>? RotateRightButtonCommand { get; }
     public ReactiveCommand<Unit, Unit>? RotateRightWindowBorderButtonCommand { get; }
     public ReactiveCommand<Unit, Unit>? FlipCommand { get; }
@@ -296,8 +228,6 @@ public class MainViewModel : ReactiveObject
     public ReactiveCommand<Unit, Unit>? ShowEffectsWindowCommand { get; }
 
     public ReactiveCommand<Unit, Unit>? OptimizeImageCommand { get; }
-    public ReactiveCommand<int, Unit>? ResizeCommand { get; }
-    public ReactiveCommand<int, Unit>? ConvertCommand { get; }
 
     public ReactiveCommand<Unit, Unit>? SortFilesByNameCommand { get; }
     public ReactiveCommand<Unit, Unit>? SortFilesBySizeCommand { get; }
@@ -314,8 +244,6 @@ public class MainViewModel : ReactiveObject
 
     public ReactiveCommand<Unit, Unit>? ColorPickerCommand { get; }
 
-    public ReactiveCommand<int, Unit>? SlideshowCommand { get; }
-
     public ReactiveCommand<Unit, Unit>? ResetSettingsCommand { get; }
 
     public ReactiveCommand<Unit, Unit>? ShowSideBySideCommand { get; }
@@ -725,63 +653,4 @@ public class MainViewModel : ReactiveObject
     #endregion Menus
 
     #endregion Fields
-
-    #region Methods
-
-    #region Tasks
-
-    private async Task ResizeImageByPercentage(int percentage) =>
-        await ConversionHelper.ResizeImageByPercentage(percentage, this).ConfigureAwait(false);
-
-    private async Task ConvertFileExtension(int index) =>
-        await ConversionHelper.ConvertFileExtension(index, this).ConfigureAwait(false);
-
-    private async Task CopyFileTask(string path) => 
-        await ClipboardFileOperations.CopyFileToClipboard(path, this).ConfigureAwait(false);
-
-    private static async Task CopyFilePathTask(string path) => 
-        await ClipboardTextOperations.CopyTextToClipboard(path).ConfigureAwait(false);
-
-    private async Task CopyBase64Task(string path) =>
-        await ClipboardImageOperations.CopyBase64ToClipboard(path, this).ConfigureAwait(false);
-
-    private async Task CutFileTask(string path) =>
-        await ClipboardFileOperations.CutFile(path, this).ConfigureAwait(false);
-
-    private async Task DeleteFileTask(string path) =>
-        await Task.Run(() => FileManager.DeleteFileWithOptionalDialog(false, path, PlatformService)).ConfigureAwait(false);
-
-    private async Task RecycleFileTask(string path) =>
-        await Task.Run(() => FileManager.DeleteFileWithOptionalDialog(true, path, PlatformService)).ConfigureAwait(false);
-
-    private async Task DuplicateFileTask(string path) =>
-        await ClipboardFileOperations.Duplicate(path, this).ConfigureAwait(false);
-
-    private async Task ShowFilePropertiesTask(string path) =>
-        await FileManager.ShowFileProperties(path, this).ConfigureAwait(false);
-
-    private async Task PrintTask(string path) =>
-        await FileManager.Print(path, this).ConfigureAwait(false);
-
-    private async Task OpenWithTask(string path) => 
-        await FileManager.OpenWith(path, this).ConfigureAwait(false);
-
-    private async Task LocateOnDiskTask(string path) =>
-        await FileManager.LocateOnDisk(path, this).ConfigureAwait(false);
-
-    public async Task StartSlideShowTask(int milliseconds) =>
-        await Slideshow.StartSlideshow(this, milliseconds);
-
-    public async Task RotateToTask(string angle)
-    {
-        if (int.TryParse(angle, out var result))
-        {
-            await RotationNavigation.RotateTo(this, result);
-        }
-    }
-        
-    
-    #endregion
-
-    #endregion Methods
 }

+ 71 - 34
src/PicView.Avalonia/ViewModels/ToolsViewModel.cs

@@ -1,4 +1,9 @@
-using PicView.Avalonia.UI;
+using PicView.Avalonia.Clipboard;
+using PicView.Avalonia.FileSystem;
+using PicView.Avalonia.Functions;
+using PicView.Avalonia.ImageTransformations.Rotation;
+using PicView.Avalonia.Navigation;
+using PicView.Avalonia.UI;
 using PicView.Avalonia.Wallpaper;
 using R3;
 
@@ -8,104 +13,136 @@ public class ToolsViewModel : IDisposable
 {
     
     // Open related
-    public ReactiveCommand<string> OpenFileCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand OpenFileCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await FunctionsMapper.Open();
     });
     
     public ReactiveCommand OpenLastFileCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await FunctionsMapper.OpenLastFile();
     });
     
     public ReactiveCommand<string> OpenWithCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await FileManager.OpenWith(path, vm).ConfigureAwait(false);
+        }
     });
     // Save related
-    public ReactiveCommand<string> SaveFileCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> SaveFileCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await FunctionsMapper.Save();
     });
     
-    public ReactiveCommand<string> SaveFileAsCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> SaveFileAsCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await FunctionsMapper.SaveAs();
     });
     
     // File Tasks
     public ReactiveCommand<string> RecycleFileCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await Task.Run(() => FileManager.DeleteFileWithOptionalDialog(true, path, vm.PlatformService)).ConfigureAwait(false);
+        }
     });
     
-    public ReactiveCommand<string> LocateOnDiskCommand { get; } = new(async (path, _) =>
-    {
-        await Task.Delay(1); // TODO implement
-    });
-    
-    public ReactiveCommand<string> FilePropertiesCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> DeleteFilePermanentlyCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await Task.Run(() => FileManager.DeleteFileWithOptionalDialog(false, path, vm.PlatformService)).ConfigureAwait(false);
+        }
     });
     
-    public ReactiveCommand<string> PrintCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> LocateOnDiskCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await FileManager.LocateOnDisk(path, vm).ConfigureAwait(false);
+        }
     });
     
-    public ReactiveCommand<string> RenameCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> FilePropertiesCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await FileManager.ShowFileProperties(path, vm).ConfigureAwait(false);
+        }
     });
     
-    public ReactiveCommand<string> ResizeCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> PrintCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await FileManager.Print(path, vm).ConfigureAwait(false);
+        }
     });
     
-    public ReactiveCommand<string> ConvertCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> RenameCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await Task.Run(FunctionsMapper.Rename);
     });
 
     
     // Copy related
-    public ReactiveCommand<string> PasteCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> PasteCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await Task.Run(FunctionsMapper.Paste);
     });
     
     public ReactiveCommand<string> DuplicateFileCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await ClipboardFileOperations.Duplicate(path, vm).ConfigureAwait(false);
+        }
     });
     
-    public ReactiveCommand<string> CopyImageCommand { get; } = new(async (path, _) =>
+    public ReactiveCommand<string> CopyImageCommand { get; } = new(async (_, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await FunctionsMapper.CopyImage().ConfigureAwait(false);
     });
     
     public ReactiveCommand<string> CopyFileCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await ClipboardFileOperations.CopyFileToClipboard(path, vm).ConfigureAwait(false);
+        }
     });
     
     public ReactiveCommand<string> CopyFilePathCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        await ClipboardTextOperations.CopyTextToClipboard(path).ConfigureAwait(false);
     });
     
     public ReactiveCommand<string> CutCommand { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await ClipboardFileOperations.CutFile(path, vm).ConfigureAwait(false);
+        }
     });
     
     public ReactiveCommand<string> CopyBase64Command { get; } = new(async (path, _) =>
     {
-        await Task.Delay(1); // TODO implement
+        if (UIHelper.GetMainView.DataContext is MainViewModel vm)
+        {
+            await ClipboardImageOperations.CopyBase64ToClipboard(path, vm).ConfigureAwait(false);
+        }
     });
     
+    
+    public async Task StartSlideShowTask(int milliseconds) =>
+        await Slideshow.StartSlideshow(UIHelper.GetMainView.DataContext as MainViewModel, milliseconds);
+    
+    public async Task RotateTask(int angle) =>
+        await RotationNavigation.RotateTo(UIHelper.GetMainView.DataContext as MainViewModel, angle);
+    
     // Wallpaper
     public ReactiveCommand<string> SetAsWallpaperCommand { get; } = new(async (path, _) =>
     {

+ 3 - 3
src/PicView.Avalonia/Views/EffectsView.axaml

@@ -17,7 +17,7 @@
     </UserControl.Styles>
     <UserControl.ContextMenu>
         <ContextMenu x:Name="ContextMenu">
-            <MenuItem Command="{CompiledBinding SaveFileCommand}" Header="{CompiledBinding Translation.Save.Value, Mode=OneWay}">
+            <MenuItem Command="{CompiledBinding Tools.SaveFileCommand}" Header="{CompiledBinding Translation.Save.Value, Mode=OneWay}">
                 <MenuItem.Icon>
                     <Path
                         Data="{StaticResource SaveGeometry}"
@@ -27,7 +27,7 @@
                         Width="12" />
                 </MenuItem.Icon>
             </MenuItem>
-            <MenuItem Command="{CompiledBinding SaveFileAsCommand}" Header="{CompiledBinding Translation.SaveAs.Value}">
+            <MenuItem Command="{CompiledBinding Tools.SaveFileAsCommand}" Header="{CompiledBinding Translation.SaveAs.Value}">
                 <MenuItem.Icon>
                     <Path
                         Data="{StaticResource SaveGeometry}"
@@ -37,7 +37,7 @@
                         Width="12" />
                 </MenuItem.Icon>
             </MenuItem>
-            <MenuItem Command="{CompiledBinding CopyImageCommand}" Header="{CompiledBinding Translation.CopyImage.Value, Mode=OneWay}">
+            <MenuItem Command="{CompiledBinding Tools.CopyImageCommand}" Header="{CompiledBinding Translation.CopyImage.Value, Mode=OneWay}">
                 <MenuItem.Icon>
                     <Path
                         Data="{StaticResource CopyGeometry}"

+ 13 - 13
src/PicView.Avalonia/Views/ImageInfoView.axaml

@@ -28,7 +28,7 @@
 
             <!--  Save  -->
             <MenuItem
-                Command="{CompiledBinding SaveFileCommand}"
+                Command="{CompiledBinding Tools.SaveFileCommand}"
                 Header="{CompiledBinding Translation.Save.Value,
                                          Mode=OneWay}"
                 IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
@@ -45,7 +45,7 @@
 
             <!--  Save as  -->
             <MenuItem
-                Command="{CompiledBinding SaveFileAsCommand}"
+                Command="{CompiledBinding Tools.SaveFileAsCommand}"
                 Header="{CompiledBinding Translation.SaveAs.Value,
                                          Mode=OneWay}"
                 IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
@@ -63,7 +63,7 @@
 
             <!--  Print  -->
             <MenuItem
-                Command="{CompiledBinding PrintCommand}"
+                Command="{CompiledBinding Tools.PrintCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.Print.Value,
@@ -83,7 +83,7 @@
 
             <!--  Open with  -->
             <MenuItem
-                Command="{CompiledBinding OpenWithCommand}"
+                Command="{CompiledBinding Tools.OpenWithCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.OpenWith.Value,
@@ -103,7 +103,7 @@
 
             <!--  Locate on disk  -->
             <MenuItem
-                Command="{CompiledBinding LocateOnDiskCommand}"
+                Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.ShowInFolder.Value,
@@ -236,7 +236,7 @@
 
             <!--  File properties  -->
             <MenuItem
-                Command="{CompiledBinding FilePropertiesCommand}"
+                Command="{CompiledBinding Tools.FilePropertiesCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.FileProperties.Value,
@@ -272,7 +272,7 @@
 
             <!--  Delete file  -->
             <MenuItem
-                Command="{CompiledBinding RecycleFileCommand}"
+                Command="{CompiledBinding Tools.RecycleFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.DeleteFile.Value,
@@ -293,7 +293,7 @@
 
             <!--  Copy  -->
             <MenuItem
-                Command="{CompiledBinding CopyFileCommand}"
+                Command="{CompiledBinding Tools.CopyFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.Copy.Value,
@@ -309,7 +309,7 @@
 
                 <!--  Copy file  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyFileCommand}"
+                    Command="{CompiledBinding Tools.CopyFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Header="{CompiledBinding Translation.CopyFile.Value,
@@ -328,7 +328,7 @@
 
                 <!--  Copy image  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyImageCommand}"
+                    Command="{CompiledBinding Tools.CopyImageCommand}"
                     Header="{CompiledBinding Translation.CopyImage.Value,
                                              Mode=OneWay}"
                     IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
@@ -345,7 +345,7 @@
 
                 <!--  Copy file path  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyFilePathCommand}"
+                    Command="{CompiledBinding Tools.CopyFilePathCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Header="{Binding Translation.FileCopyPath, Mode=OneWay}"
@@ -363,7 +363,7 @@
 
                 <!--  Copy base64  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyBase64Command}"
+                    Command="{CompiledBinding Tools.CopyBase64Command}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     IsEnabled="{CompiledBinding PicViewer.FileInfo.Value,
@@ -388,7 +388,7 @@
 
                 <!--  Duplicate file  -->
                 <MenuItem
-                    Command="{CompiledBinding DuplicateFileCommand}"
+                    Command="{CompiledBinding Tools.DuplicateFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Header="{CompiledBinding Translation.DuplicateFile,

+ 15 - 15
src/PicView.Avalonia/Views/MainView.axaml

@@ -29,7 +29,7 @@
 
             <!--  Open  -->
             <MenuItem
-                Command="{CompiledBinding OpenFileCommand}"
+                Command="{CompiledBinding Tools.OpenFileCommand}"
                 Header="{CompiledBinding Translation.Open.Value,
                                          Mode=OneWay}"
                 MinWidth="180">
@@ -45,7 +45,7 @@
 
             <!--  Save  -->
             <MenuItem
-                Command="{CompiledBinding SaveFileCommand}"
+                Command="{CompiledBinding Tools.SaveFileCommand}"
                 Header="{CompiledBinding Translation.Save.Value,
                                          Mode=OneWay}"
                 IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
@@ -62,7 +62,7 @@
 
             <!--  Save as  -->
             <MenuItem
-                Command="{CompiledBinding SaveFileAsCommand}"
+                Command="{CompiledBinding Tools.SaveFileAsCommand}"
                 Header="{CompiledBinding Translation.SaveAs.Value,
                                          Mode=OneWay}"
                 IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
@@ -79,7 +79,7 @@
 
             <!--  Print  -->
             <MenuItem
-                Command="{CompiledBinding PrintCommand}"
+                Command="{CompiledBinding Tools.PrintCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.Print.Value,
@@ -99,7 +99,7 @@
 
             <!--  Open with  -->
             <MenuItem
-                Command="{CompiledBinding OpenWithCommand}"
+                Command="{CompiledBinding Tools.OpenWithCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.OpenWith.Value,
@@ -119,7 +119,7 @@
 
             <!--  Locate on disk  -->
             <MenuItem
-                Command="{CompiledBinding LocateOnDiskCommand}"
+                Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.ShowInFolder.Value,
@@ -726,7 +726,7 @@
 
                 <!--  File properties  -->
                 <MenuItem
-                    Command="{CompiledBinding FilePropertiesCommand}"
+                    Command="{CompiledBinding Tools.FilePropertiesCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Header="{CompiledBinding Translation.FileProperties.Value,
@@ -865,7 +865,7 @@
 
             <!--  Delete file  -->
             <MenuItem
-                Command="{CompiledBinding RecycleFileCommand}"
+                Command="{CompiledBinding Tools.RecycleFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.DeleteFile.Value,
@@ -885,7 +885,7 @@
             <Separator />
 
             <!--  Paste  -->
-            <MenuItem Command="{CompiledBinding PasteCommand}" Header="{CompiledBinding Translation.Paste.Value, Mode=OneWay}">
+            <MenuItem Command="{CompiledBinding Tools.PasteCommand}" Header="{CompiledBinding Translation.Paste.Value, Mode=OneWay}">
                 <MenuItem.Icon>
                     <Path
                         Data="{StaticResource PasteGeometry}"
@@ -898,7 +898,7 @@
 
             <!--  Copy  -->
             <MenuItem
-                Command="{CompiledBinding CopyFileCommand}"
+                Command="{CompiledBinding Tools.CopyFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.Copy.Value,
@@ -914,7 +914,7 @@
 
                 <!--  Copy image  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyImageCommand}"
+                    Command="{CompiledBinding Tools.CopyImageCommand}"
                     Header="{CompiledBinding Translation.CopyImage.Value,
                                              Mode=OneWay}"
                     IsEnabled="{CompiledBinding PicViewer.ImageSource.Value,
@@ -931,7 +931,7 @@
 
                 <!--  Copy file path  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyFilePathCommand}"
+                    Command="{CompiledBinding Tools.CopyFilePathCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Header="{Binding Translation.FileCopyPath.Value, Mode=OneWay}"
@@ -949,7 +949,7 @@
 
                 <!--  Copy base64  -->
                 <MenuItem
-                    Command="{CompiledBinding CopyBase64Command}"
+                    Command="{CompiledBinding Tools.CopyBase64Command}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     IsEnabled="{CompiledBinding PicViewer.FileInfo.Value,
@@ -974,7 +974,7 @@
 
                 <!--  Duplicate file  -->
                 <MenuItem
-                    Command="{CompiledBinding DuplicateFileCommand}"
+                    Command="{CompiledBinding Tools.DuplicateFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Header="{CompiledBinding Translation.DuplicateFile.Value,
@@ -995,7 +995,7 @@
 
             <!--  Copy file  -->
             <MenuItem
-                Command="{CompiledBinding CopyFileCommand}"
+                Command="{CompiledBinding Tools.CopyFileCommand}"
                 CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding Translation.CopyFile.Value,

+ 3 - 3
src/PicView.Avalonia/Views/StartUpMenu.axaml

@@ -42,7 +42,7 @@
             VerticalAlignment="Center"
             x:Name="Buttons">
 
-            <Button Command="{CompiledBinding OpenFileCommand}" x:Name="SelectFileButton">
+            <Button Command="{CompiledBinding Tools.OpenFileCommand}" x:Name="SelectFileButton">
                 <StackPanel Orientation="Horizontal">
                     <Image Height="20.091">
                         <Image.Source>
@@ -83,7 +83,7 @@
                 </StackPanel>
             </Button>
 
-            <Button Command="{CompiledBinding OpenLastFileCommand}" x:Name="OpenLastFileButton">
+            <Button Command="{CompiledBinding Tools.OpenLastFileCommand}" x:Name="OpenLastFileButton">
                 <StackPanel Height="30" Orientation="Horizontal">
                     <Image Height="20.091">
                         <Image.Source>
@@ -124,7 +124,7 @@
                 </StackPanel>
             </Button>
 
-            <Button Command="{CompiledBinding PasteCommand}" x:Name="PasteButton">
+            <Button Command="{CompiledBinding Tools.PasteCommand}" x:Name="PasteButton">
                 <StackPanel Height="30" Orientation="Horizontal">
                     <Path
                         Data="{StaticResource PasteGeometry}"

+ 6 - 6
src/PicView.Avalonia/Views/UC/GalleryItem.axaml

@@ -58,7 +58,7 @@
         <Border.ContextMenu>
             <ContextMenu x:Name="GalleryContextMenu">
                 <MenuItem
-                    Command="{CompiledBinding PrintCommand}"
+                    Command="{CompiledBinding Tools.PrintCommand}"
                     CommandParameter="{CompiledBinding Path=Text,
                                                        ElementName=FileLocation}"
                     Header="{CompiledBinding Translation.Print.Value,
@@ -73,7 +73,7 @@
                     </MenuItem.Icon>
                 </MenuItem>
                 <MenuItem
-                    Command="{CompiledBinding OpenWithCommand}"
+                    Command="{CompiledBinding Tools.OpenWithCommand}"
                     CommandParameter="{CompiledBinding Path=Text,
                                                        ElementName=FileLocation}"
                     Header="{CompiledBinding Translation.OpenWith.Value,
@@ -89,7 +89,7 @@
                     </MenuItem.Icon>
                 </MenuItem>
                 <MenuItem
-                    Command="{CompiledBinding LocateOnDiskCommand}"
+                    Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                     CommandParameter="{CompiledBinding Path=Text,
                                                        ElementName=FileLocation}"
                     Header="{CompiledBinding Translation.ShowInFolder.Value,
@@ -121,7 +121,7 @@
                 </MenuItem>
                 <Separator />
                 <MenuItem
-                    Command="{CompiledBinding CopyFileCommand}"
+                    Command="{CompiledBinding Tools.CopyFileCommand}"
                     CommandParameter="{CompiledBinding Path=Text,
                                                        ElementName=FileLocation}"
                     Header="{CompiledBinding Translation.CopyFile.Value,
@@ -162,7 +162,7 @@
                     </MenuItem.Icon>
                 </MenuItem>
                 <MenuItem
-                    Command="{CompiledBinding DuplicateFileCommand}"
+                    Command="{CompiledBinding Tools.DuplicateFileCommand}"
                     CommandParameter="{CompiledBinding Path=Text,
                                                        ElementName=FileLocation}"
                     Header="{CompiledBinding Translation.DuplicateFile.Value,
@@ -180,7 +180,7 @@
                 <Separator />
 
                 <MenuItem
-                    Command="{CompiledBinding RecycleFileCommand}"
+                    Command="{CompiledBinding Tools.RecycleFileCommand}"
                     CommandParameter="{CompiledBinding Path=Text,
                                                        ElementName=FileLocation}"
                     Header="{CompiledBinding Translation.DeleteFile.Value,

+ 10 - 10
src/PicView.Avalonia/Views/UC/Menus/FileMenu.axaml

@@ -62,7 +62,7 @@
                 <customControls:IconButton
                     Canvas.Left="45"
                     Classes="hover btn"
-                    Command="{CompiledBinding PrintCommand}"
+                    Command="{CompiledBinding Tools.PrintCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource PrintGeometry}"
@@ -77,7 +77,7 @@
                 <customControls:IconButton
                     Canvas.Left="90"
                     Classes="hover btn"
-                    Command="{CompiledBinding RecycleFileCommand}"
+                    Command="{CompiledBinding Tools.RecycleFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource RecycleGeometry}"
@@ -91,7 +91,7 @@
                 <customControls:IconButton
                     Canvas.Left="135"
                     Classes="hover btn"
-                    Command="{CompiledBinding SaveFileCommand}"
+                    Command="{CompiledBinding Tools.SaveFileCommand}"
                     Data="{StaticResource SaveGeometry}"
                     IconHeight="17"
                     IconWidth="17"
@@ -103,7 +103,7 @@
                 <customControls:IconButton
                     Canvas.Left="180"
                     Classes="hover btn"
-                    Command="{CompiledBinding CopyFileCommand}"
+                    Command="{CompiledBinding Tools.CopyFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource CopyGeometry}"
@@ -117,7 +117,7 @@
                 <customControls:IconButton
                     Canvas.Left="225"
                     Classes="hover btn"
-                    Command="{CompiledBinding DuplicateFileCommand}"
+                    Command="{CompiledBinding Tools.DuplicateFileCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Data="{StaticResource DuplicateGeometry}"
@@ -145,7 +145,7 @@
                     Canvas.Left="7"
                     Canvas.Top="53"
                     Classes="ButtonBorder altHover"
-                    Command="{CompiledBinding OpenFileCommand}"
+                    Command="{CompiledBinding Tools.OpenFileCommand}"
                     Height="46"
                     ToolTip.Tip="{CompiledBinding Translation.OpenFileDialog.Value,
                                                   Mode=OneWay}">
@@ -167,7 +167,7 @@
                     Canvas.Left="7"
                     Canvas.Top="104"
                     Classes="ButtonBorder altHover"
-                    Command="{CompiledBinding OpenWithCommand}"
+                    Command="{CompiledBinding Tools.OpenWithCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Height="46"
@@ -193,7 +193,7 @@
                     Canvas.Left="160"
                     Canvas.Top="53"
                     Classes="ButtonBorder altHover"
-                    Command="{CompiledBinding LocateOnDiskCommand}"
+                    Command="{CompiledBinding Tools.LocateOnDiskCommand}"
                     CommandParameter="{CompiledBinding PicViewer.FileInfo.Value.FullName,
                                                        FallbackValue=''}"
                     Height="46"
@@ -218,7 +218,7 @@
                     Canvas.Left="160"
                     Canvas.Top="104"
                     Classes="ButtonBorder altHover"
-                    Command="{CompiledBinding SaveFileAsCommand}"
+                    Command="{CompiledBinding Tools.SaveFileAsCommand}"
                     Height="46"
                     IsEnabled="{CompiledBinding PicViewer.FileInfo.Value,
                                                 Converter={x:Static ObjectConverters.IsNotNull}}"
@@ -242,7 +242,7 @@
                     Canvas.Left="7"
                     Canvas.Top="155"
                     Classes="ButtonBorder altHover"
-                    Command="{CompiledBinding PasteCommand}"
+                    Command="{CompiledBinding Tools.PasteCommand}"
                     Height="46"
                     ToolTip.Tip="{CompiledBinding Translation.Paste.Value,
                                                   Mode=OneWay}">

+ 10 - 10
src/PicView.Avalonia/Views/UC/Menus/ImageMenu.axaml

@@ -266,7 +266,7 @@
                     Canvas.Left="7"
                     Canvas.Top="104"
                     Classes="ButtonBorder altHover up"
-                    Command="{CompiledBinding StartSlideShowTask}"
+                    Command="{CompiledBinding Tools.StartSlideShowTask}"
                     CommandParameter="0"
                     Foreground="{DynamicResource MainTextColor}"
                     Height="46"
@@ -289,7 +289,7 @@
                         <MenuFlyout Placement="Top" ShowMode="Transient">
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="2000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -299,7 +299,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="5000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -309,7 +309,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="10000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -319,7 +319,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="20000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -329,7 +329,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="30000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -339,7 +339,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="60000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -349,7 +349,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="120000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -359,7 +359,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="180000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">
@@ -369,7 +369,7 @@
                             </Button>
                             <Button
                                 Background="Transparent"
-                                Command="{CompiledBinding StartSlideShowTask}"
+                                Command="{CompiledBinding Tools.StartSlideShowTask}"
                                 CommandParameter="300000"
                                 Width="86">
                                 <TextBlock Classes="txt" Foreground="{DynamicResource MainTextColor}">