Delete command

This commit is contained in:
2023-01-28 14:34:23 +01:00
parent ebbc3f6fc0
commit b3755f4ceb
13 changed files with 200 additions and 56 deletions

View File

@@ -90,9 +90,10 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
else if (_currentSelectedItem?.BaseItem != null)
{
var item = _currentSelectedItem.BaseItem;
_clipboardService.AddContent(item.FullName ??
throw new ArgumentException($"{nameof(item.FullName)} can not be null.",
nameof(item)));
_clipboardService.AddContent(
item.FullName
?? throw new ArgumentException($"{nameof(item.FullName)} can not be null.", nameof(item))
);
}
return Task.CompletedTask;
@@ -233,14 +234,12 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
return;
}
var deleteCommand = new FileTime.Core.Command.Delete.DeleteCommand()
{
HardDelete = command.IsHardDelete
};
var deleteCommand = _serviceProvider.GetRequiredService<FileTime.Core.Command.Delete.DeleteCommand>();
deleteCommand.HardDelete = command.IsHardDelete;
deleteCommand.ItemsToDelete.AddRange(itemsToDelete!);
await AddCommand(deleteCommand);
_selectedTab?.ClearMarkedItems();
}

View File

@@ -6,6 +6,7 @@ using FileTime.Core.Command;
using FileTime.Core.Command.Copy;
using FileTime.Core.Command.CreateContainer;
using FileTime.Core.Command.CreateElement;
using FileTime.Core.Command.Delete;
using FileTime.Core.CommandHandlers;
using FileTime.Core.ContentAccess;
using FileTime.Core.Services;
@@ -49,6 +50,7 @@ public static class DependencyInjection
return serviceCollection
.AddTransient<CreateContainerCommand>()
.AddTransient<CreateElementCommand>()
.AddTransient<CopyCommand>();
.AddTransient<CopyCommand>()
.AddTransient<DeleteCommand>();
}
}

View File

@@ -8,4 +8,6 @@ public interface IContentAccessorFactory
IContentReaderFactory GetContentReaderFactory(IContentProvider provider);
IContentWriterFactory<TContentProvider> GetContentWriterFactory<TContentProvider>() where TContentProvider : IContentProvider;
IContentWriterFactory GetContentWriterFactory(IContentProvider provider);
IItemDeleter GetItemDeleter(IContentProvider provider);
IItemDeleter<TContentProvider> GetItemDeleter<TContentProvider>() where TContentProvider : IContentProvider;
}

View File

@@ -0,0 +1,13 @@
using FileTime.Core.Models;
namespace FileTime.Core.ContentAccess;
public interface IItemDeleter
{
Task DeleteAsync(IContentProvider contentProvider, FullName fullName);
}
public interface IItemDeleter<in TContentProvider> : IItemDeleter where TContentProvider : IContentProvider
{
Task DeleteAsync(TContentProvider contentProvider, FullName fullName);
}

View File

@@ -1,7 +1,6 @@
using System.Reactive.Linq;
using FileTime.Core.ContentAccess;
using FileTime.Core.Enums;
using FileTime.Core.Services;
using FileTime.Core.Timeline;
namespace FileTime.Core.Models;
@@ -26,4 +25,4 @@ public interface IItem
ReadOnlyExtensionCollection Extensions { get; }
T? GetExtension<T>() => (T?)Extensions.FirstOrDefault(i => i is T);
}
}

View File

@@ -1,3 +1,5 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Extensions;
using FileTime.Core.Models;
using FileTime.Core.Timeline;
@@ -5,21 +7,76 @@ namespace FileTime.Core.Command.Delete;
public class DeleteCommand : IExecutableCommand
{
public bool HardDelete { get; init; }
public List<FullName> ItemsToDelete { get; } = new List<FullName>();
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ITimelessContentProvider _timelessContentProvider;
public bool HardDelete { get; set; }
public List<FullName> ItemsToDelete { get; } = new();
public DeleteCommand(
IContentAccessorFactory contentAccessorFactory,
ITimelessContentProvider timelessContentProvider)
{
_contentAccessorFactory = contentAccessorFactory;
_timelessContentProvider = timelessContentProvider;
}
public Task<CanCommandRun> CanRun(PointInTime currentTime)
{
throw new NotImplementedException();
//TODO
return Task.FromResult(CanCommandRun.True);
}
public Task<PointInTime> SimulateCommand(PointInTime currentTime)
{
throw new NotImplementedException();
//TODO
return Task.FromResult(currentTime);
}
public Task Execute()
public async Task Execute()
{
throw new NotImplementedException();
//Calculate
//Delete
await TraverseTree(
PointInTime.Present,
ItemsToDelete,
new Dictionary<string, IItemDeleter>(),
new DeleteStrategy()
);
}
private async Task TraverseTree(
PointInTime currentTime,
IEnumerable<FullName> itemsToDelete,
Dictionary<string, IItemDeleter> itemDeleters,
IDeleteStrategy deleteStrategy)
{
foreach (var itemToDeleteName in itemsToDelete)
{
var itemToDelete = await _timelessContentProvider.GetItemByFullNameAsync(itemToDeleteName, currentTime);
IItemDeleter itemDeleter;
if (itemDeleters.ContainsKey(itemToDelete.Provider.Name))
{
itemDeleter = itemDeleters[itemToDelete.Provider.Name];
}
else
{
itemDeleter = _contentAccessorFactory.GetItemDeleter(itemToDelete.Provider);
itemDeleters.Add(itemToDelete.Provider.Name, itemDeleter);
}
if (itemToDelete is IContainer container)
{
await TraverseTree(
currentTime,
(await container.Items.GetItemsAsync())?.Select(i => i.Path) ?? Enumerable.Empty<FullName>(),
itemDeleters,
deleteStrategy
);
}
await itemDeleter.DeleteAsync(itemToDelete.Provider, itemToDelete.FullName!);
}
}
}

View File

@@ -0,0 +1,12 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
namespace FileTime.Core.Command.Delete;
public class DeleteStrategy : IDeleteStrategy
{
public async Task DeleteItem(IItem item, IItemDeleter deleter)
{
await deleter.DeleteAsync(item.Provider, item.FullName!);
}
}

View File

@@ -0,0 +1,9 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
namespace FileTime.Core.Command.Delete;
public interface IDeleteStrategy
{
Task DeleteItem(IItem item, IItemDeleter deleter);
}

View File

@@ -52,4 +52,18 @@ public class ContentAccessorFactory : IContentAccessorFactory
return (IContentWriterFactory)_serviceProvider.GetRequiredService(genericType);
}
public IItemDeleter<TContentProvider> GetItemDeleter<TContentProvider>() where TContentProvider : IContentProvider
{
var genericType = typeof(IItemDeleter<>).MakeGenericType(typeof(TContentProvider));
return (IItemDeleter<TContentProvider>)_serviceProvider.GetRequiredService(genericType);
}
public IItemDeleter GetItemDeleter(IContentProvider provider)
{
var genericType = typeof(IItemDeleter<>).MakeGenericType(provider.GetType());
return (IItemDeleter)_serviceProvider.GetRequiredService(genericType);
}
}

View File

@@ -45,64 +45,64 @@ public static class MainConfiguration
{
//new CommandBindingConfiguration(ConfigCommand.AutoRefresh, new KeyConfig(Key.R, shift: true)),
//new CommandBindingConfiguration(ConfigCommand.ChangeTimelineMode, new[] { Key.T, Key.M }),
new CommandBindingConfiguration(CloseTabCommand.CommandName, Key.Q),
new(CloseTabCommand.CommandName, Key.Q),
//new CommandBindingConfiguration(ConfigCommand.Compress, new[] { Key.Y, Key.C }),
new CommandBindingConfiguration(CopyCommand.CommandName, new[] { Key.Y, Key.Y }),
new(CopyCommand.CommandName, new[] { Key.Y, Key.Y }),
//new CommandBindingConfiguration(ConfigCommand.CopyHash, new[] { Key.C, Key.H }),
new CommandBindingConfiguration(CopyNativePathCommand.CommandName, new[] { Key.C, Key.P }),
new CommandBindingConfiguration(CreateContainer.CommandName, Key.F7),
new CommandBindingConfiguration(CreateContainer.CommandName, new[] { Key.C, Key.C }),
new CommandBindingConfiguration(CreateElement.CommandName, new[] { Key.C, Key.E }),
new(CopyNativePathCommand.CommandName, new[] { Key.C, Key.P }),
new(CreateContainer.CommandName, Key.F7),
new(CreateContainer.CommandName, new[] { Key.C, Key.C }),
new(CreateElement.CommandName, new[] { Key.C, Key.E }),
//new CommandBindingConfiguration(ConfigCommand.Cut, new[] { Key.D, Key.D }),
//new CommandBindingConfiguration(ConfigCommand.Edit, new KeyConfig(Key.F4)),
new CommandBindingConfiguration(EnterRapidTravelCommand.CommandName,new KeyConfig(Key.OemComma, shift: true)),
new(EnterRapidTravelCommand.CommandName,new KeyConfig(Key.OemComma, shift: true)),
//new CommandBindingConfiguration(ConfigCommand.FindByName, new[] { Key.F, Key.N }),
//new CommandBindingConfiguration(ConfigCommand.FindByNameRegex, new[] { Key.F, Key.R }),
new CommandBindingConfiguration(GoToHomeCommand.CommandName, new[] { Key.G, Key.H }),
new CommandBindingConfiguration(GoToPathCommand.CommandName, new KeyConfig(Key.L, ctrl: true)),
new CommandBindingConfiguration(GoToPathCommand.CommandName, new[] { Key.G, Key.P }),
new CommandBindingConfiguration(GoToProviderCommand.CommandName, new[] { Key.G, Key.T }),
new CommandBindingConfiguration(GoToRootCommand.CommandName, new[] { Key.G, Key.R }),
new CommandBindingConfiguration(DeleteCommand.HardDeleteCommandName, new[] { new KeyConfig(Key.D,shift: true), new KeyConfig(Key.D, shift: true) }),
new CommandBindingConfiguration(MarkCommand.CommandName, Key.Space),
new CommandBindingConfiguration(MoveCursorToLastCommand.CommandName, new KeyConfig(Key.G, shift: true)),
new CommandBindingConfiguration(MoveCursorToFirstCommand.CommandName, new[] { Key.G, Key.G }),
new(GoToHomeCommand.CommandName, new[] { Key.G, Key.H }),
new(GoToPathCommand.CommandName, new KeyConfig(Key.L, ctrl: true)),
new(GoToPathCommand.CommandName, new[] { Key.G, Key.P }),
new(GoToProviderCommand.CommandName, new[] { Key.G, Key.T }),
new(GoToRootCommand.CommandName, new[] { Key.G, Key.R }),
new(DeleteCommand.HardDeleteCommandName, new[] { new KeyConfig(Key.D,shift: true), new KeyConfig(Key.D, shift: true) }),
new(MarkCommand.CommandName, Key.Space),
new(MoveCursorToLastCommand.CommandName, new KeyConfig(Key.G, shift: true)),
new(MoveCursorToFirstCommand.CommandName, new[] { Key.G, Key.G }),
//new CommandBindingConfiguration(ConfigCommand.NextTimelineBlock, Key.L ),
//new CommandBindingConfiguration(ConfigCommand.NextTimelineCommand, Key.J ),
new CommandBindingConfiguration(OpenInDefaultFileExplorerCommand.CommandName, new[] { Key.O, Key.E }),
new CommandBindingConfiguration(PasteCommand.PasteMergeCommandName, new[] { Key.P, Key.P }),
new CommandBindingConfiguration(PasteCommand.PasteOverwriteCommandName, new[] { Key.P, Key.O }),
new CommandBindingConfiguration(PasteCommand.PasteSkipCommandName, new[] { Key.P, Key.S }),
new(OpenInDefaultFileExplorerCommand.CommandName, new[] { Key.O, Key.E }),
new(PasteCommand.PasteMergeCommandName, new[] { Key.P, Key.P }),
new(PasteCommand.PasteOverwriteCommandName, new[] { Key.P, Key.O }),
new(PasteCommand.PasteSkipCommandName, new[] { Key.P, Key.S }),
//new CommandBindingConfiguration(ConfigCommand.PinFavorite, new[] { Key.F, Key.P }),
//new CommandBindingConfiguration(ConfigCommand.PreviousTimelineBlock, Key.H ),
//new CommandBindingConfiguration(ConfigCommand.PreviousTimelineCommand, Key.K ),
new CommandBindingConfiguration(RefreshCommand.CommandName, Key.R),
new(RefreshCommand.CommandName, Key.R),
//new CommandBindingConfiguration(ConfigCommand.Rename, Key.F2),
//new CommandBindingConfiguration(ConfigCommand.Rename, new[] { Key.C, Key.W }),
//new CommandBindingConfiguration(ConfigCommand.RunCommand, new KeyConfig(Key.D4, shift: true)),
//new CommandBindingConfiguration(ConfigCommand.ScanContainerSize, new[] { Key.C, Key.S }),
//new CommandBindingConfiguration(ConfigCommand.ShowAllShortcut, Key.F1),
new CommandBindingConfiguration(DeleteCommand.SoftDeleteCommandName, new[] { new KeyConfig(Key.D), new KeyConfig(Key.D, shift: true) }),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToLastTabCommandName, Key.D9),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab1CommandName, Key.D1),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab2CommandName, Key.D2),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab3CommandName, Key.D3),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab4CommandName, Key.D4),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab5CommandName, Key.D5),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab6CommandName, Key.D6),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab7CommandName, Key.D7),
new CommandBindingConfiguration(SwitchToTabCommand.SwitchToTab8CommandName, Key.D8),
new(DeleteCommand.SoftDeleteCommandName, new[] { new KeyConfig(Key.D), new KeyConfig(Key.D, shift: true) }),
new(SwitchToTabCommand.SwitchToLastTabCommandName, Key.D9),
new(SwitchToTabCommand.SwitchToTab1CommandName, Key.D1),
new(SwitchToTabCommand.SwitchToTab2CommandName, Key.D2),
new(SwitchToTabCommand.SwitchToTab3CommandName, Key.D3),
new(SwitchToTabCommand.SwitchToTab4CommandName, Key.D4),
new(SwitchToTabCommand.SwitchToTab5CommandName, Key.D5),
new(SwitchToTabCommand.SwitchToTab6CommandName, Key.D6),
new(SwitchToTabCommand.SwitchToTab7CommandName, Key.D7),
new(SwitchToTabCommand.SwitchToTab8CommandName, Key.D8),
//new CommandBindingConfiguration(ConfigCommand.TimelinePause, new[] { Key.T, Key.P }),
//new CommandBindingConfiguration(ConfigCommand.TimelineRefresh, new[] { Key.T, Key.R }),
//new CommandBindingConfiguration(ConfigCommand.TimelineStart, new[] { Key.T, Key.S }),
//new CommandBindingConfiguration(ConfigCommand.ToggleAdvancedIcons, new[] { Key.Z, Key.I }),
new CommandBindingConfiguration(GoUpCommand.CommandName, Key.Left),
new CommandBindingConfiguration(OpenSelectedCommand.CommandName, Key.Right),
new(GoUpCommand.CommandName, Key.Left),
new(OpenSelectedCommand.CommandName, Key.Right),
//new CommandBindingConfiguration(ConfigCommand.OpenOrRun, Key.Enter),
new CommandBindingConfiguration(MoveCursorUpCommand.CommandName, Key.Up),
new CommandBindingConfiguration(MoveCursorDownCommand.CommandName, Key.Down),
new CommandBindingConfiguration(MoveCursorUpPageCommand.CommandName, Key.PageUp),
new CommandBindingConfiguration(MoveCursorDownPageCommand.CommandName, Key.PageDown),
new(MoveCursorUpCommand.CommandName, Key.Up),
new(MoveCursorDownCommand.CommandName, Key.Down),
new(MoveCursorUpPageCommand.CommandName, Key.PageUp),
new(MoveCursorDownPageCommand.CommandName, Key.PageDown),
};
}

View File

@@ -11,7 +11,7 @@ public partial class MessageBoxViewModel : IModalViewModel
public string Text { get; }
public string Name => "MessageBoxViewModel";
public MessageBoxViewModel(string text, Action<MessageBoxViewModel, MessageBoxResult> handler)
public MessageBoxViewModel(string text, Action<MessageBoxViewModel, MessageBoxResult> handler) : this()
{
_handler = handler;
Text = text;

View File

@@ -0,0 +1,35 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Models;
namespace FileTime.Providers.Local;
public class LocalItemDeleter : IItemDeleter<ILocalContentProvider>
{
public Task DeleteAsync(ILocalContentProvider contentProvider, FullName fullName)
{
var nativePath = contentProvider.GetNativePath(fullName).Path;
if (File.Exists(nativePath))
{
File.Delete(nativePath);
}
else if (Directory.Exists(nativePath))
{
Directory.Delete(nativePath, true);
}
else
{
throw new FileNotFoundException(nativePath);
}
return Task.CompletedTask;
}
public async Task DeleteAsync(IContentProvider contentProvider, FullName fullName)
{
var localContentProvider = contentProvider as ILocalContentProvider;
if (localContentProvider is null) throw new ArgumentException("Content provider is not a local content provider", nameof(contentProvider));
await DeleteAsync(localContentProvider, fullName);
}
}

View File

@@ -12,6 +12,8 @@ public static class Startup
serviceCollection.TryAddSingleton<IContentProvider>(sp => sp.GetRequiredService<ILocalContentProvider>());
serviceCollection.TryAddSingleton<IItemCreator<ILocalContentProvider>, LocalItemCreator>();
serviceCollection.TryAddSingleton<IItemCreator<LocalContentProvider>>(sp => sp.GetRequiredService<IItemCreator<ILocalContentProvider>>());
serviceCollection.TryAddSingleton<IItemDeleter<ILocalContentProvider>, LocalItemDeleter>();
serviceCollection.TryAddSingleton<IItemDeleter<LocalContentProvider>>(sp => sp.GetRequiredService<IItemDeleter<ILocalContentProvider>>());
serviceCollection.TryAddSingleton<IContentReaderFactory<ILocalContentProvider>, LocalContentReaderFactory>();
serviceCollection.TryAddSingleton<IContentReaderFactory<LocalContentProvider>>(sp => sp.GetRequiredService<IContentReaderFactory<ILocalContentProvider>>());
serviceCollection.TryAddSingleton<IContentWriterFactory<ILocalContentProvider>, LocalContentWriterFactory>();