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:
adroslice 2019-11-21 19:07:46 +01:00
parent 5633cd2afe
commit ae7c3a3fff
10 changed files with 160 additions and 92 deletions

View File

@ -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;
}
}
} }

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,12 @@
using System;
namespace BFR.Operations.Attributes
{
class DescriptionAttribute : Attribute
{
public string Description { get; }
public DescriptionAttribute(string description) =>
Description = description;
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace BFR.Operations.Attributes
{
class DisplayNameAttribute : Attribute
{
public string DisplayName { get; }
public DisplayNameAttribute(string displayName) =>
DisplayName = displayName;
}
}

View File

@ -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; }

View File

@ -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);
} }
} }

View File

@ -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;
}
} }
} }

View File

@ -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,
} }
} }