bfr/BFR/Operations/Replace.cs

73 lines
3.6 KiB
C#
Raw Normal View History

using System;
using System.Linq;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Avalonia;
using BFR.Helpers;
using BFR.DataModels;
namespace BFR.Operations
{
public class Replace : Operation
{
public override string Name => nameof(Replace);
public override string Description => "Replaces the selected part of the file name.";
public static readonly AvaloniaProperty<ReplaceMode> ModeProperty =
AvaloniaProperty.Register<MainWindow, ReplaceMode>(nameof(Mode), ReplaceMode.Pattern);
public ReplaceMode Mode { get => GetValue(ModeProperty); set => SetValue(ModeProperty, value); }
[XmlIgnore]
public ReplaceOperationMode[] Modes => ReplaceOperationMode.Modes;
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 (Mode == ReplaceMode.FirstN && FirstN > shortestLength) throw new OperationException($"First N can't be greater than the shortest file name length ({shortestLength}).");
if (Mode == ReplaceMode.LastN && LastN > shortestLength) throw new OperationException($"Last N can't be greater than the shortest file name length ({shortestLength}).");
if (Mode == ReplaceMode.FromNToN && FromN > shortestLength) throw new OperationException($"From N can't be greater than the shortest file name length ({shortestLength}).");
if (Mode == ReplaceMode.FromNToN && ToN > shortestLength) throw new OperationException($"To N can't be greater than the shortest file name length ({shortestLength}).");
if (Mode == ReplaceMode.FromNToN && FromN > ToN) throw new OperationException("From N can't be greater than To N.");
// Regex Failure
if(Mode == ReplaceMode.Pattern && 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 switch
{
ReplaceMode.Pattern => newName.Replace(Pattern, Replacement, UseRegex, UseRegexReplace),
ReplaceMode.Characters => Characters.Length > 0 ? Regex.Replace(newName, $"[{Characters}]", Replacement.Replace("$", "$$")) : newName,
ReplaceMode.FromNToN => Regex.Replace(newName, $"^(.{{{FromN}}}).+(.{{{newName.Length - ToN - 1}}})$", $"$1{Replacement.Replace("$", "$$")}$2"),
ReplaceMode.FirstN => Regex.Replace(newName, $"^.{{{FirstN}}}", Replacement.Replace("$", "$$")),
ReplaceMode.LastN => Regex.Replace(newName, $".{{{LastN}}}$", Replacement.Replace("$", "$$")),
_ => newName
};
if (FullName) file.FullName = newName;
else file.Name = newName;
}
}
}
}