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 modeProperty = AvaloniaProperty.Register(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 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; } } }