Added internal Operation Infrastructure + Example

- Overwrite might be a bad example, because it has no fail conditions. The intended behaviour for those is to throw an exception for invalid parameters, with an error text describing to the user what went wrong.
- Fail condition check may be moved to a seperate abstract method, forcing implementers to at least give fail conditions a thought.
- Minor refactor
- TODO: Better folder structure to group operations (Looking for suggestions)
This commit is contained in:
adroslice 2019-11-16 02:00:17 +01:00
parent e671fd4185
commit 704b7ea1a9
4 changed files with 78 additions and 6 deletions

View File

@ -17,9 +17,7 @@ namespace BFR
{ {
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
public async Task OpenDirectoryButtonClick() => public async Task OpenDirectoryButtonClick() => OpenDirectory(await new OpenFolderDialog() { Directory = WorkingDirectory }.ShowAsync(this));
OpenDirectory(await new OpenFolderDialog() { Directory = WorkingDirectory }.ShowAsync(this));
public void OpenDirectory(string directory) public void OpenDirectory(string directory)
{ {
WorkingDirectory = directory; WorkingDirectory = directory;
@ -51,9 +49,7 @@ namespace BFR
Files.ReplaceAll(new List<FileModel>(Files)); Files.ReplaceAll(new List<FileModel>(Files));
} }
public MainWindow() => public MainWindow() => InitializeComponent();
InitializeComponent();
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using Avalonia;
using BFR.DataModels;
namespace BFR.Operations
{
public abstract class Operation : AvaloniaObject
{
// Needs to be an avalonia property to update the UI with with any potential error.
public AvaloniaProperty<string> errorProperty = AvaloniaProperty.Register<Operation, string>(nameof(Error), defaultValue: "");
public string Error { get => GetValue(errorProperty); set => SetValue(errorProperty, value); }
public bool IsEnabled { get; set; } = true;
public abstract string Name { get; }
public abstract string Description { get; }
public abstract OperationType OperationType { get; }
protected abstract void ApplyToInternal(List<FileModel> files);
// Updates the UI with the appropriate error if the operation fails
public void ApplyTo(List<FileModel> files)
{
try { ApplyToInternal(files); Error = ""; }
catch (Exception e) { Error = e.Message; }
}
}
}

View File

@ -0,0 +1,20 @@
using System;
namespace BFR.Operations
{
public class OperationType
{
public string Name { get; }
public string Description { get; }
public Func<Operation> Create { get; }
internal static OperationType Make<T>() where T : Operation, new()
{
var pilot = new T();
return new OperationType(pilot.Name, pilot.Description, () => new T());
}
private OperationType(string name, string description, Func<Operation> create) =>
(Name, Description, Create) = (name, description, create);
}
}

View File

@ -0,0 +1,27 @@
using System.Collections.Generic;
using BFR.DataModels;
namespace BFR.Operations
{
public class Overwrite : Operation
{
// Operation Info
public override string Name => nameof(Overwrite);
public override string Description => "Overwrites all file names. To produce a valid result this has to be combined with numbering.";
public override OperationType OperationType { get; } = OperationType.Make<Overwrite>();
// Operation Parameters
public string Replacement { get; set; } = "";
public bool FullName { get; set; } = false;
protected override void ApplyToInternal(List<FileModel> files)
{
// Fail conditions: No fail conditions
// Apply Operation
foreach (var file in files)
if (FullName) file.FullName = Replacement;
else file.Name = Replacement;
}
}
}