86 lines
3.9 KiB
C#
86 lines
3.9 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|