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 ) ;
2019-11-22 18:18:28 +00:00
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." ) ;
2019-11-17 15:22:19 +00:00
// Regex Failure
2019-11-22 18:18:28 +00:00
if ( Mode = = ReplaceMode . Pattern & & 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 ;
}
}
}
}