2019-11-17 15:22:19 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
2019-11-21 18:07:46 +00:00
|
|
|
|
using System.Xml.Serialization;
|
2019-11-17 15:22:19 +00:00
|
|
|
|
using System.Collections.Generic;
|
2019-11-21 18:07:46 +00:00
|
|
|
|
using System.Text.RegularExpressions;
|
2019-11-17 15:22:19 +00:00
|
|
|
|
|
|
|
|
|
using Avalonia;
|
|
|
|
|
|
|
|
|
|
using BFR.Helpers;
|
|
|
|
|
using BFR.DataModels;
|
|
|
|
|
|
|
|
|
|
namespace BFR.Operations
|
|
|
|
|
{
|
|
|
|
|
public class Replace : Operation
|
|
|
|
|
{
|
2019-11-21 18:07:46 +00:00
|
|
|
|
public override string Name => nameof(Replace);
|
2019-11-17 15:22:19 +00:00
|
|
|
|
public override string Description => "Replaces the selected part of the file name.";
|
|
|
|
|
|
2019-11-21 18:07:46 +00:00
|
|
|
|
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;
|
2019-11-17 15:22:19 +00:00
|
|
|
|
|
|
|
|
|
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
|
2019-11-21 18:07:46 +00:00
|
|
|
|
if(Modes[(int)Mode].IsPattern && UseRegex)
|
2019-11-17 15:22:19 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2019-11-21 18:07:46 +00:00
|
|
|
|
newName = Mode switch
|
2019-11-17 15:22:19 +00:00
|
|
|
|
{
|
2019-11-21 18:07:46 +00:00
|
|
|
|
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("$", "$$")),
|
2019-11-17 15:22:19 +00:00
|
|
|
|
_ => newName
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (FullName) file.FullName = newName;
|
|
|
|
|
else file.Name = newName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|