OperationMode overhaul, improved event handling, fixed properties
- OperationMode now designed and implemented in a way that allows serialization - Modes are now defined using an enumeration with with attributes decorated values - MainWindow.xaml.cs's event handlers now only listen for changes to certain properties - Property naming conventions fixed - AvaloniaProperties are now public + static + readonly
This commit is contained in:
parent
5633cd2afe
commit
ae7c3a3fff
|
@ -27,4 +27,15 @@ namespace BFR.Helpers
|
||||||
catch(Exception) { return false; }
|
catch(Exception) { return false; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class EnumExtensions
|
||||||
|
{
|
||||||
|
public static T GetAttribute<T>(this Enum enumVal) where T : Attribute
|
||||||
|
{
|
||||||
|
var type = enumVal.GetType();
|
||||||
|
var memInfo = type.GetMember(enumVal.ToString());
|
||||||
|
var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
|
||||||
|
return (attributes.Length > 0) ? (T)attributes[0] : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,31 +166,31 @@
|
||||||
<Expander Classes="OperationExpander">
|
<Expander Classes="OperationExpander">
|
||||||
<Grid ColumnDefinitions="auto,*" RowDefinitions="auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto">
|
<Grid ColumnDefinitions="auto,*" RowDefinitions="auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto">
|
||||||
<TextBlock Grid.Row="0" Text="Mode:"/>
|
<TextBlock Grid.Row="0" Text="Mode:"/>
|
||||||
<ComboBox Grid.Row="0" Items="{Binding Modes}" SelectedItem="{Binding Mode}" PropertyChanged="PreviewChanged">
|
<ComboBox Grid.Row="0" Items="{Binding Modes}" Name="ModeSelector" SelectedIndex="{Binding Mode}" PropertyChanged="PreviewChanged">
|
||||||
<ComboBox.ItemTemplate>
|
<ComboBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<TextBlock Text="{Binding Name}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ComboBox.ItemTemplate>
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<TextBlock Grid.Row="1" Text="Pattern:" IsVisible="{Binding Mode.IsPatternMode}"/>
|
<TextBlock Grid.Row="1" Text="Pattern:" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}"/>
|
||||||
<TextBox Grid.Row="1" Text="{Binding Pattern}" IsVisible="{Binding Mode.IsPatternMode}" PropertyChanged="PreviewChanged"/>
|
<TextBox Grid.Row="1" Text="{Binding Pattern}" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="2" Text="Characters:" IsVisible="{Binding Mode.IsCharactersMode}"/>
|
<TextBlock Grid.Row="2" Text="Characters:" IsVisible="{Binding #ModeSelector.SelectedItem.IsCharacters}"/>
|
||||||
<TextBox Grid.Row="2" Text="{Binding Characters}" IsVisible="{Binding Mode.IsCharactersMode}" PropertyChanged="PreviewChanged"/>
|
<TextBox Grid.Row="2" Text="{Binding Characters}" IsVisible="{Binding #ModeSelector.SelectedItem.IsCharacters}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="3" Text="From N:" IsVisible="{Binding Mode.IsFromNToNMode}"/>
|
<TextBlock Grid.Row="3" Text="From N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}"/>
|
||||||
<NumericUpDown Grid.Row="3" Value="{Binding FromN}" IsVisible="{Binding Mode.IsFromNToNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="3" Value="{Binding FromN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="4" Text="To N:" IsVisible="{Binding Mode.IsFromNToNMode}"/>
|
<TextBlock Grid.Row="4" Text="To N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}"/>
|
||||||
<NumericUpDown Grid.Row="4" Value="{Binding ToN}" IsVisible="{Binding Mode.IsFromNToNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="4" Value="{Binding ToN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="5" Text="First N:" IsVisible="{Binding Mode.IsFirstNMode}"/>
|
<TextBlock Grid.Row="5" Text="First N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsFirstN}"/>
|
||||||
<NumericUpDown Grid.Row="5" Value="{Binding FirstN}" IsVisible="{Binding Mode.IsFirstNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="5" Value="{Binding FirstN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsFirstN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="6" Text="Last N:" IsVisible="{Binding Mode.IsLastNMode}"/>
|
<TextBlock Grid.Row="6" Text="Last N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsLastN}"/>
|
||||||
<NumericUpDown Grid.Row="6" Value="{Binding LastN}" IsVisible="{Binding Mode.IsLastNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="6" Value="{Binding LastN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsLastN}" PropertyChanged="PreviewChanged"/>
|
||||||
<!--TextBlock Grid.Row="7" Text="Replacement:"/>
|
<!--TextBlock Grid.Row="7" Text="Replacement:"/>
|
||||||
<TextBox Grid.Row="7" Text="{Binding Replacement}" PropertyChanged="PreviewChanged"/-->
|
<TextBox Grid.Row="7" Text="{Binding Replacement}" PropertyChanged="PreviewChanged"/-->
|
||||||
<TextBlock Grid.Row="8" Text="Regex:" IsVisible="{Binding Mode.IsPatternMode}"/>
|
<TextBlock Grid.Row="8" Text="Regex:" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}"/>
|
||||||
<CheckBox Grid.Row="8" IsChecked="{Binding UseRegex}" IsVisible="{Binding Mode.IsPatternMode}" PropertyChanged="PreviewChanged"/>
|
<CheckBox Grid.Row="8" IsChecked="{Binding UseRegex}" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="9" Text="Replace Regex:" IsVisible="{Binding Mode.IsPatternMode}"/>
|
<TextBlock Grid.Row="9" Text="Replace Regex:" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}"/>
|
||||||
<CheckBox Grid.Row="9" IsChecked="{Binding UseRegexReplace}" IsVisible="{Binding Mode.IsPatternMode}" PropertyChanged="PreviewChanged"/>
|
<CheckBox Grid.Row="9" IsChecked="{Binding UseRegexReplace}" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="10" Text="Full Name:"/>
|
<TextBlock Grid.Row="10" Text="Full Name:"/>
|
||||||
<CheckBox Grid.Row="10" IsChecked="{Binding FullName}" PropertyChanged="PreviewChanged"/>
|
<CheckBox Grid.Row="10" IsChecked="{Binding FullName}" PropertyChanged="PreviewChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -200,31 +200,31 @@
|
||||||
<Expander Classes="OperationExpander">
|
<Expander Classes="OperationExpander">
|
||||||
<Grid ColumnDefinitions="auto,*" RowDefinitions="auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto">
|
<Grid ColumnDefinitions="auto,*" RowDefinitions="auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto">
|
||||||
<TextBlock Grid.Row="0" Text="Mode:"/>
|
<TextBlock Grid.Row="0" Text="Mode:"/>
|
||||||
<ComboBox Grid.Row="0" Items="{Binding Modes}" SelectedItem="{Binding Mode}" PropertyChanged="PreviewChanged">
|
<ComboBox Grid.Row="0" Items="{Binding Modes}" Name="ModeSelector" SelectedIndex="{Binding Mode}" PropertyChanged="PreviewChanged">
|
||||||
<ComboBox.ItemTemplate>
|
<ComboBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<TextBlock Text="{Binding Name}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ComboBox.ItemTemplate>
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<TextBlock Grid.Row="1" Text="Pattern:" IsVisible="{Binding Mode.IsPatternMode}"/>
|
<TextBlock Grid.Row="1" Text="Pattern:" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}"/>
|
||||||
<TextBox Grid.Row="1" Text="{Binding Pattern}" IsVisible="{Binding Mode.IsPatternMode}" PropertyChanged="PreviewChanged"/>
|
<TextBox Grid.Row="1" Text="{Binding Pattern}" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="2" Text="Characters:" IsVisible="{Binding Mode.IsCharactersMode}"/>
|
<TextBlock Grid.Row="2" Text="Characters:" IsVisible="{Binding #ModeSelector.SelectedItem.IsCharacters}"/>
|
||||||
<TextBox Grid.Row="2" Text="{Binding Characters}" IsVisible="{Binding Mode.IsCharactersMode}" PropertyChanged="PreviewChanged"/>
|
<TextBox Grid.Row="2" Text="{Binding Characters}" IsVisible="{Binding #ModeSelector.SelectedItem.IsCharacters}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="3" Text="From N:" IsVisible="{Binding Mode.IsFromNToNMode}"/>
|
<TextBlock Grid.Row="3" Text="From N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}"/>
|
||||||
<NumericUpDown Grid.Row="3" Value="{Binding FromN}" IsVisible="{Binding Mode.IsFromNToNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="3" Value="{Binding FromN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="4" Text="To N:" IsVisible="{Binding Mode.IsFromNToNMode}"/>
|
<TextBlock Grid.Row="4" Text="To N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}"/>
|
||||||
<NumericUpDown Grid.Row="4" Value="{Binding ToN}" IsVisible="{Binding Mode.IsFromNToNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="4" Value="{Binding ToN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsFromNToN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="5" Text="First N:" IsVisible="{Binding Mode.IsFirstNMode}"/>
|
<TextBlock Grid.Row="5" Text="First N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsFirstN}"/>
|
||||||
<NumericUpDown Grid.Row="5" Value="{Binding FirstN}" IsVisible="{Binding Mode.IsFirstNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="5" Value="{Binding FirstN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsFirstN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="6" Text="Last N:" IsVisible="{Binding Mode.IsLastNMode}"/>
|
<TextBlock Grid.Row="6" Text="Last N:" IsVisible="{Binding #ModeSelector.SelectedItem.IsLastN}"/>
|
||||||
<NumericUpDown Grid.Row="6" Value="{Binding LastN}" IsVisible="{Binding Mode.IsLastNMode}" PropertyChanged="PreviewChanged"/>
|
<NumericUpDown Grid.Row="6" Value="{Binding LastN}" IsVisible="{Binding #ModeSelector.SelectedItem.IsLastN}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="7" Text="Replacement:"/>
|
<TextBlock Grid.Row="7" Text="Replacement:"/>
|
||||||
<TextBox Grid.Row="7" Text="{Binding Replacement}" PropertyChanged="PreviewChanged"/>
|
<TextBox Grid.Row="7" Text="{Binding Replacement}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="8" Text="Regex:" IsVisible="{Binding Mode.IsPatternMode}"/>
|
<TextBlock Grid.Row="8" Text="Regex:" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}"/>
|
||||||
<CheckBox Grid.Row="8" IsChecked="{Binding UseRegex}" IsVisible="{Binding Mode.IsPatternMode}" PropertyChanged="PreviewChanged"/>
|
<CheckBox Grid.Row="8" IsChecked="{Binding UseRegex}" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="9" Text="Replace Regex:" IsVisible="{Binding Mode.IsPatternMode}"/>
|
<TextBlock Grid.Row="9" Text="Replace Regex:" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}"/>
|
||||||
<CheckBox Grid.Row="9" IsChecked="{Binding UseRegexReplace}" IsVisible="{Binding Mode.IsPatternMode}" PropertyChanged="PreviewChanged"/>
|
<CheckBox Grid.Row="9" IsChecked="{Binding UseRegexReplace}" IsVisible="{Binding #ModeSelector.SelectedItem.IsPattern}" PropertyChanged="PreviewChanged"/>
|
||||||
<TextBlock Grid.Row="10" Text="Full Name:"/>
|
<TextBlock Grid.Row="10" Text="Full Name:"/>
|
||||||
<CheckBox Grid.Row="10" IsChecked="{Binding FullName}" PropertyChanged="PreviewChanged"/>
|
<CheckBox Grid.Row="10" IsChecked="{Binding FullName}" PropertyChanged="PreviewChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -16,6 +16,8 @@ namespace BFR
|
||||||
{
|
{
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
|
public readonly AvaloniaProperty[] HandledProperties = new AvaloniaProperty[] { TextBox.TextProperty, ComboBox.SelectedItemProperty, NumericUpDown.ValueProperty, CheckBox.IsCheckedProperty };
|
||||||
|
|
||||||
public async Task OpenDirectoryButtonClick() => OpenDirectory(await new OpenFolderDialog() { Directory = WorkingDirectory }.ShowAsync(this));
|
public async Task OpenDirectoryButtonClick() => OpenDirectory(await new OpenFolderDialog() { Directory = WorkingDirectory }.ShowAsync(this));
|
||||||
public void OpenDirectory(string directory)
|
public void OpenDirectory(string directory)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +26,11 @@ namespace BFR
|
||||||
Filter();
|
Filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FilterChanged(object sender, AvaloniaPropertyChangedEventArgs e) => Filter(); // Bind to PropertyChanged
|
public void FilterChanged(object sender, AvaloniaPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if(HandledProperties.Contains(e.Property))
|
||||||
|
Filter(); // Bind to PropertyChanged
|
||||||
|
}
|
||||||
public void Filter()
|
public void Filter()
|
||||||
{
|
{
|
||||||
// Filter all files in the directory for those satisfying the given filters
|
// Filter all files in the directory for those satisfying the given filters
|
||||||
|
@ -35,7 +41,11 @@ namespace BFR
|
||||||
Preview();
|
Preview();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PreviewChanged(object sender, AvaloniaPropertyChangedEventArgs e) => Preview(); // Bind to PropertyChanged
|
public void PreviewChanged(object sender, AvaloniaPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (HandledProperties.Contains(e.Property))
|
||||||
|
Preview(); // Bind to PropertyChanged
|
||||||
|
}
|
||||||
public void Preview()
|
public void Preview()
|
||||||
{
|
{
|
||||||
// Reset all files to how they currently exist
|
// Reset all files to how they currently exist
|
||||||
|
|
|
@ -11,9 +11,9 @@ namespace BFR
|
||||||
{
|
{
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
private readonly AvaloniaProperty<string> workingDirectoryProperty =
|
public static readonly AvaloniaProperty<string> WorkingDirectoryProperty =
|
||||||
AvaloniaProperty.Register<MainWindow, string>(nameof(WorkingDirectory));
|
AvaloniaProperty.Register<MainWindow, string>(nameof(WorkingDirectory));
|
||||||
public string WorkingDirectory { get => GetValue(workingDirectoryProperty); set => SetValue(workingDirectoryProperty, value); }
|
public string WorkingDirectory { get => GetValue(WorkingDirectoryProperty); set => SetValue(WorkingDirectoryProperty, value); }
|
||||||
|
|
||||||
public AvaloniaList<FileModel> AllFiles { get; } = new AvaloniaList<FileModel>();
|
public AvaloniaList<FileModel> AllFiles { get; } = new AvaloniaList<FileModel>();
|
||||||
public AvaloniaList<FileModel> Files { get; } = new AvaloniaList<FileModel>();
|
public AvaloniaList<FileModel> Files { get; } = new AvaloniaList<FileModel>();
|
||||||
|
@ -28,12 +28,12 @@ namespace BFR
|
||||||
OperationType.Make<Remove>(),
|
OperationType.Make<Remove>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public readonly AvaloniaProperty<bool> isCommitButtonEnabled =
|
public static readonly AvaloniaProperty<bool> IsCommitButtonEnabledProperty =
|
||||||
AvaloniaProperty.Register<MainWindow, bool>("IsCommitButtonEnabled", defaultValue: false);
|
AvaloniaProperty.Register<MainWindow, bool>("IsCommitButtonEnabled", defaultValue: false);
|
||||||
public bool IsCommitButtonEnabled { get => GetValue(isCommitButtonEnabled); set => SetValue(isCommitButtonEnabled, value); }
|
public bool IsCommitButtonEnabled { get => GetValue(IsCommitButtonEnabledProperty); set => SetValue(IsCommitButtonEnabledProperty, value); }
|
||||||
public readonly AvaloniaProperty<int> undoCount =
|
public static readonly AvaloniaProperty<int> UndoCountProperty =
|
||||||
AvaloniaProperty.Register<MainWindow, int>("UndoCount", defaultValue: 0);
|
AvaloniaProperty.Register<MainWindow, int>("UndoCount", defaultValue: 0);
|
||||||
public int UndoCount { get => GetValue(undoCount); set => SetValue(undoCount, value); }
|
public int UndoCount { get => GetValue(UndoCountProperty); set => SetValue(UndoCountProperty, value); }
|
||||||
private readonly Stack<List<FileModel>> UndoStack = new Stack<List<FileModel>>();
|
private readonly Stack<List<FileModel>> UndoStack = new Stack<List<FileModel>>();
|
||||||
|
|
||||||
// Filters
|
// Filters
|
||||||
|
|
12
BFR/Operations/Attributes/DescriptionAttribute.cs
Normal file
12
BFR/Operations/Attributes/DescriptionAttribute.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BFR.Operations.Attributes
|
||||||
|
{
|
||||||
|
class DescriptionAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Description { get; }
|
||||||
|
|
||||||
|
public DescriptionAttribute(string description) =>
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
}
|
12
BFR/Operations/Attributes/DisplayNameAttribute.cs
Normal file
12
BFR/Operations/Attributes/DisplayNameAttribute.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BFR.Operations.Attributes
|
||||||
|
{
|
||||||
|
class DisplayNameAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string DisplayName { get; }
|
||||||
|
|
||||||
|
public DisplayNameAttribute(string displayName) =>
|
||||||
|
DisplayName = displayName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
|
||||||
|
@ -11,8 +12,10 @@ namespace BFR.Operations
|
||||||
public abstract class Operation : AvaloniaObject
|
public abstract class Operation : AvaloniaObject
|
||||||
{
|
{
|
||||||
// Needs to be avalonia property to update UI with any potential error.
|
// Needs to be avalonia property to update UI with any potential error.
|
||||||
private readonly AvaloniaProperty<string> errorProperty = AvaloniaProperty.Register<MainWindow, string>(nameof(Error), defaultValue: "");
|
[XmlIgnore]
|
||||||
public string Error { get => GetValue(errorProperty); set => SetValue(errorProperty, value); }
|
public static readonly AvaloniaProperty<string> ErrorProperty = AvaloniaProperty.Register<MainWindow, string>(nameof(Error), defaultValue: "");
|
||||||
|
[XmlIgnore]
|
||||||
|
public string Error { get => GetValue(ErrorProperty); set => SetValue(ErrorProperty, value); }
|
||||||
public bool IsEnabled { get; set; } = true;
|
public bool IsEnabled { get; set; } = true;
|
||||||
public abstract string Name { get; }
|
public abstract string Name { get; }
|
||||||
public abstract string Description { get; }
|
public abstract string Description { get; }
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
namespace BFR.Operations
|
using System;
|
||||||
{
|
|
||||||
public class OperationMode
|
|
||||||
{
|
|
||||||
public int Index { get; }
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
public OperationMode(int index, string name) =>
|
namespace BFR.Operations
|
||||||
(Index, Name) = (index, name);
|
{
|
||||||
|
public abstract class OperationMode<T> where T : Enum
|
||||||
|
{
|
||||||
|
public T Index { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string Description { get; }
|
||||||
|
|
||||||
|
protected OperationMode(T index, string name, string description) =>
|
||||||
|
(Index, Name, Description) = (index, name, description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,27 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Xml.Serialization;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
|
||||||
using BFR.Helpers;
|
using BFR.Helpers;
|
||||||
using BFR.DataModels;
|
using BFR.DataModels;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace BFR.Operations
|
namespace BFR.Operations
|
||||||
{
|
{
|
||||||
public class Replace : Operation
|
public class Replace : Operation
|
||||||
{
|
{
|
||||||
private static readonly ReplaceMode DefaultMode = new ReplaceMode(0, "Pattern");
|
public override string Name => nameof(Replace);
|
||||||
|
|
||||||
public override string Name => "Replace";
|
|
||||||
public override string Description => "Replaces the selected part of the file name.";
|
public override string Description => "Replaces the selected part of the file name.";
|
||||||
|
|
||||||
public AvaloniaProperty<ReplaceMode> modeProperty =
|
public static readonly AvaloniaProperty<ReplaceMode> ModeProperty =
|
||||||
AvaloniaProperty.Register<MainWindow, ReplaceMode>(nameof(Mode), defaultValue: DefaultMode);
|
AvaloniaProperty.Register<MainWindow, ReplaceMode>(nameof(Mode), ReplaceMode.Pattern);
|
||||||
public ReplaceMode Mode { get => GetValue(modeProperty); set => SetValue(modeProperty, value); }
|
public ReplaceMode Mode { get => GetValue(ModeProperty); set => SetValue(ModeProperty, value); }
|
||||||
public ReplaceMode[] Modes { get; } = new ReplaceMode[]
|
|
||||||
{
|
[XmlIgnore]
|
||||||
DefaultMode,
|
public ReplaceOperationMode[] Modes => ReplaceOperationMode.Modes;
|
||||||
new ReplaceMode(1, "Characters"),
|
|
||||||
new ReplaceMode(2, "FromNToN"),
|
|
||||||
new ReplaceMode(3, "FirstN"),
|
|
||||||
new ReplaceMode(4, "LastN"),
|
|
||||||
};
|
|
||||||
|
|
||||||
public string Replacement { get; set; } = "";
|
public string Replacement { get; set; } = "";
|
||||||
public bool FullName { get; set; } = false;
|
public bool FullName { get; set; } = false;
|
||||||
|
@ -51,7 +45,7 @@ namespace BFR.Operations
|
||||||
if (FromN > ToN) throw new OperationException("From N can't be greater than To N.");
|
if (FromN > ToN) throw new OperationException("From N can't be greater than To N.");
|
||||||
|
|
||||||
// Regex Failure
|
// Regex Failure
|
||||||
if(Mode.IsPatternMode && UseRegex)
|
if(Modes[(int)Mode].IsPattern && UseRegex)
|
||||||
try { "".Replace(Pattern, Replacement, true, false); }
|
try { "".Replace(Pattern, Replacement, true, false); }
|
||||||
catch(Exception) { throw new OperationException("Invalid Regex Pattern."); }
|
catch(Exception) { throw new OperationException("Invalid Regex Pattern."); }
|
||||||
|
|
||||||
|
@ -60,13 +54,13 @@ namespace BFR.Operations
|
||||||
{
|
{
|
||||||
var newName = FullName ? file.FullName : file.Name;
|
var newName = FullName ? file.FullName : file.Name;
|
||||||
|
|
||||||
newName = Mode.Index switch
|
newName = Mode switch
|
||||||
{
|
{
|
||||||
0 => newName.Replace(Pattern, Replacement, UseRegex, UseRegexReplace),
|
ReplaceMode.Pattern => newName.Replace(Pattern, Replacement, UseRegex, UseRegexReplace),
|
||||||
1 => Characters.Length > 0 ? Regex.Replace(newName, $"[{Characters}]", Replacement.Replace("$", "$$")) : newName,
|
ReplaceMode.Characters => Characters.Length > 0 ? Regex.Replace(newName, $"[{Characters}]", Replacement.Replace("$", "$$")) : newName,
|
||||||
2 => Regex.Replace(newName, $"^(.{{{FromN}}}).+(.{{{newName.Length - ToN - 1}}})$", $"$1{Replacement.Replace("$", "$$")}$2"),
|
ReplaceMode.FromNToN => Regex.Replace(newName, $"^(.{{{FromN}}}).+(.{{{newName.Length - ToN - 1}}})$", $"$1{Replacement.Replace("$", "$$")}$2"),
|
||||||
3 => Regex.Replace(newName, $"^.{{{FirstN}}}", Replacement.Replace("$", "$$")),
|
ReplaceMode.FirstN => Regex.Replace(newName, $"^.{{{FirstN}}}", Replacement.Replace("$", "$$")),
|
||||||
4 => Regex.Replace(newName, $".{{{LastN}}}$", Replacement.Replace("$", "$$")),
|
ReplaceMode.LastN => Regex.Replace(newName, $".{{{LastN}}}$", Replacement.Replace("$", "$$")),
|
||||||
_ => newName
|
_ => newName
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,12 +68,5 @@ namespace BFR.Operations
|
||||||
else file.Name = newName;
|
else file.Name = newName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ReplaceAllCharacters(string input, string characters, string replacement)
|
|
||||||
{
|
|
||||||
foreach (var character in characters)
|
|
||||||
input = input.Replace(character.ToString(), replacement);
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,44 @@
|
||||||
namespace BFR.Operations
|
using System;
|
||||||
{
|
using System.Linq;
|
||||||
public class ReplaceMode : OperationMode
|
using System.Collections.Generic;
|
||||||
{
|
|
||||||
public bool IsPatternMode => Index == 0;
|
|
||||||
public bool IsCharactersMode => Index == 1;
|
|
||||||
public bool IsFromNToNMode => Index == 2;
|
|
||||||
public bool IsFirstNMode => Index == 3;
|
|
||||||
public bool IsLastNMode => Index == 4;
|
|
||||||
|
|
||||||
public ReplaceMode(int index, string name) :
|
using BFR.Helpers;
|
||||||
base(index, name) { }
|
using BFR.Operations.Attributes;
|
||||||
|
|
||||||
|
namespace BFR.Operations
|
||||||
|
{
|
||||||
|
public class ReplaceOperationMode : OperationMode<ReplaceMode>
|
||||||
|
{
|
||||||
|
public bool IsPattern => Index == ReplaceMode.Pattern;
|
||||||
|
public bool IsCharacters => Index == ReplaceMode.Characters;
|
||||||
|
public bool IsFromNToN => Index == ReplaceMode.FromNToN;
|
||||||
|
public bool IsFirstN => Index == ReplaceMode.FirstN;
|
||||||
|
public bool IsLastN => Index == ReplaceMode.LastN;
|
||||||
|
|
||||||
|
public readonly static ReplaceOperationMode[] Modes = All();
|
||||||
|
|
||||||
|
protected ReplaceOperationMode(ReplaceMode index, string name, string description) :
|
||||||
|
base(index, name, description) { }
|
||||||
|
|
||||||
|
protected static ReplaceOperationMode[] All() => ((IEnumerable<ReplaceMode>)Enum.GetValues(typeof(ReplaceMode))).Select(x =>
|
||||||
|
new ReplaceOperationMode(
|
||||||
|
x,
|
||||||
|
x.GetAttribute<DisplayNameAttribute>().DisplayName,
|
||||||
|
x.GetAttribute<DescriptionAttribute>().Description
|
||||||
|
)).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ReplaceMode
|
||||||
|
{
|
||||||
|
[DisplayName(nameof(Pattern)), Description("Replaces the specified pattern.")]
|
||||||
|
Pattern,
|
||||||
|
[DisplayName(nameof(Characters)), Description("Replaces each of the specified characters.")]
|
||||||
|
Characters,
|
||||||
|
[DisplayName("From N to N"), Description("Replaces everything in the specified range (zero-based indeces).")]
|
||||||
|
FromNToN,
|
||||||
|
[DisplayName("First N"), Description("Replaces the first N characters.")]
|
||||||
|
FirstN,
|
||||||
|
[DisplayName("Last N"), Description("Replaces the last N characters.")]
|
||||||
|
LastN,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user