bfr/BFR/Operations/Replace.cs

86 lines
3.9 KiB
C#
Raw Normal View History

using System;
using System.Linq;
using System.Collections.Generic;
using Avalonia;
using BFR.Helpers;
using BFR.DataModels;
using System.Text.RegularExpressions;
namespace BFR.Operations
{
public class Replace : Operation
{
private static readonly ReplaceMode DefaultMode = new ReplaceMode(0, "Pattern");
public override string Name => "Replace";
public override string Description => "Replaces the selected part of the file name.";
public AvaloniaProperty<ReplaceMode> modeProperty =
AvaloniaProperty.Register<MainWindow, ReplaceMode>(nameof(Mode), defaultValue: DefaultMode);
public ReplaceMode Mode { get => GetValue(modeProperty); set => SetValue(modeProperty, value); }
public ReplaceMode[] Modes { get; } = new ReplaceMode[]
{
DefaultMode,
new ReplaceMode(1, "Characters"),
new ReplaceMode(2, "FromNToN"),
new ReplaceMode(3, "FirstN"),
new ReplaceMode(4, "LastN"),
};
public string Replacement { get; set; } = "";
public bool FullName { get; set; } = false;
public string Pattern { get; set; } = "";
public bool UseRegex { get; set; } = false;
public bool UseRegexReplace { get; set; } = false;
public string Characters { get; set; } = "";
public int FirstN { get; set; } = 0;
public int LastN { get; set; } = 0;
public int FromN { get; set; } = 0;
public int ToN { get; set; } = 0;
protected override void ApplyToInternal(IList<FileModel> files)
{
// Fail conditions: Various out-of-bounds
var shortestLength = files.Min(x => FullName ? x.FullName.Length : x.Name.Length);
if (FirstN > shortestLength) throw new OperationException($"First N can't be greater than the shortest file name length ({shortestLength}).");
if (LastN > shortestLength) throw new OperationException($"Last N can't be greater than the shortest file name length ({shortestLength}).");
if (FromN > shortestLength) throw new OperationException($"From N can't be greater than the shortest file name length ({shortestLength}).");
if (ToN > shortestLength) throw new OperationException($"To N can't be greater than the shortest file name length ({shortestLength}).");
if (FromN > ToN) throw new OperationException("From N can't be greater than To N.");
// Regex Failure
if(Mode.IsPatternMode && UseRegex)
try { "".Replace(Pattern, Replacement, true, false); }
catch(Exception) { throw new OperationException("Invalid Regex Pattern."); }
// Apply operation
foreach(var file in files)
{
var newName = FullName ? file.FullName : file.Name;
newName = Mode.Index switch
{
0 => newName.Replace(Pattern, Replacement, UseRegex, UseRegexReplace),
1 => Characters.Length > 0 ? Regex.Replace(newName, $"[{Characters}]", Replacement.Replace("$", "$$")) : newName,
2 => Regex.Replace(newName, $"^(.{{{FromN}}}).+(.{{{newName.Length - ToN - 1}}})$", $"$1{Replacement.Replace("$", "$$")}$2"),
3 => Regex.Replace(newName, $"^.{{{FirstN}}}", Replacement.Replace("$", "$$")),
4 => Regex.Replace(newName, $".{{{LastN}}}$", Replacement.Replace("$", "$$")),
_ => newName
};
if (FullName) file.FullName = 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;
}
}
}