Implemented preview TODO, modified exception handling

- Better handles unexpected exceptions
- Expected exceptions should be OperationException
- Leaves files unchanged even if the exception occurs at *any* point of the operation
- TODO: Probably have to optimize this.
- Operations now operate on IList<T> instead of List<T> to maintain compatibility with AvaloniaList<T>
- Slightly better comments
This commit is contained in:
adroslice 2019-11-16 02:47:07 +01:00
parent 704b7ea1a9
commit 0eb940012d
5 changed files with 37 additions and 9 deletions

View File

@ -43,7 +43,9 @@ namespace BFR
foreach (var file in Files) foreach (var file in Files)
file.Path = file.OldPath; file.Path = file.OldPath;
// TODO: Apply operations // Apply operations
foreach (var operation in Operations)
operation.ApplyTo(Files);
// Refresh the file list to guarantee that changes are displayed. TODO: Find a better way to do this. // Refresh the file list to guarantee that changes are displayed. TODO: Find a better way to do this.
Files.ReplaceAll(new List<FileModel>(Files)); Files.ReplaceAll(new List<FileModel>(Files));

View File

@ -3,6 +3,7 @@ using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using BFR.DataModels; using BFR.DataModels;
using BFR.Operations;
namespace BFR namespace BFR
{ {
@ -14,6 +15,7 @@ namespace BFR
public AvaloniaList<FileModel> AllFiles { get; } = new AvaloniaList<FileModel>(); public AvaloniaList<FileModel> AllFiles { get; } = new AvaloniaList<FileModel>();
public AvaloniaList<FileModel> Files { get; } = new AvaloniaList<FileModel>(); public AvaloniaList<FileModel> Files { get; } = new AvaloniaList<FileModel>();
public AvaloniaList<Operation> Operations { get; } = new AvaloniaList<Operation>();
// Filters // Filters
public string FilterExtension { get; set; } = ""; public string FilterExtension { get; set; } = "";

View File

@ -1,15 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Avalonia; using Avalonia;
using BFR.DataModels; using BFR.DataModels;
using BFR.Helpers;
namespace BFR.Operations namespace BFR.Operations
{ {
public abstract class Operation : AvaloniaObject public abstract class Operation : AvaloniaObject
{ {
// Needs to be an avalonia property to update the UI with with any potential error. // Needs to be avalonia property to update UI with any potential error.
public AvaloniaProperty<string> errorProperty = AvaloniaProperty.Register<Operation, string>(nameof(Error), defaultValue: ""); public AvaloniaProperty<string> errorProperty = AvaloniaProperty.Register<Operation, string>(nameof(Error), defaultValue: "");
public string Error { get => GetValue(errorProperty); set => SetValue(errorProperty, value); } public string Error { get => GetValue(errorProperty); set => SetValue(errorProperty, value); }
public bool IsEnabled { get; set; } = true; public bool IsEnabled { get; set; } = true;
@ -17,13 +18,25 @@ namespace BFR.Operations
public abstract string Description { get; } public abstract string Description { get; }
public abstract OperationType OperationType { get; } public abstract OperationType OperationType { get; }
protected abstract void ApplyToInternal(List<FileModel> files); protected abstract void ApplyToInternal(IList<FileModel> files);
// Updates the UI with the appropriate error if the operation fails public void ApplyTo(IList<FileModel> files)
public void ApplyTo(List<FileModel> files)
{ {
try { ApplyToInternal(files); Error = ""; } // Backup of all changes thus far, in case something goes wrong
catch (Exception e) { Error = e.Message; } var backup = files.Select(file => file.Path).ToList();
try
{
ApplyToInternal(files); // Try to apply operation
Error = ""; // If successul, remove any previous error
}
catch (OperationException e) { Error = e.Message; } // If expected, show user a concise and descriptive message
catch (Exception e) { Error = $"Unexpected {e}"; } // If not, hint with the exception thrown that this is unexpected behaviour
finally
{
if (Error != "") // If something went wrong, restore backup
for (int i = 0; i < files.Count; i++)
files[i].Path = backup[i];
}
} }
} }
} }

View File

@ -0,0 +1,11 @@
using System;
namespace BFR.Operations
{
public class OperationException : Exception
{
public OperationException(string message) :
base(message)
{ }
}
}

View File

@ -15,7 +15,7 @@ namespace BFR.Operations
public string Replacement { get; set; } = ""; public string Replacement { get; set; } = "";
public bool FullName { get; set; } = false; public bool FullName { get; set; } = false;
protected override void ApplyToInternal(List<FileModel> files) protected override void ApplyToInternal(IList<FileModel> files)
{ {
// Fail conditions: No fail conditions // Fail conditions: No fail conditions
// Apply Operation // Apply Operation