From 7019918496e7c83a40f01d907dbf55b574b60466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Sun, 13 Feb 2022 16:49:59 +0100 Subject: [PATCH] Copy status, fixes --- src/Core/FileTime.Core/Command/CopyCommand.cs | 85 +++++++++++++------ .../Command/CopyCommandContext.cs | 14 +++ .../Command/CreateContainerCommand.cs | 2 + .../Command/CreateElementCommand.cs | 1 + .../FileTime.Core/Command/DeleteCommand.cs | 3 +- src/Core/FileTime.Core/Command/ICommand.cs | 1 + src/Core/FileTime.Core/Command/MoveCommand.cs | 1 + .../Command/OperationProgress.cs | 12 ++- .../FileTime.Core/Command/RenameCommand.cs | 1 + src/FileTime.sln | 25 ++++++ .../FileTime.Avalonia.csproj | 2 +- .../Services/KeyboardConfigurationService.cs | 1 + .../FileTime.Avalonia/Views/MainWindow.axaml | 1 + .../CommandHandlers/CopyCommandHandler.cs | 4 +- .../Command/CompressCommand.cs | 35 ++++++++ .../Command/DecompressCommand.cs | 34 ++++++++ .../FileTime.Tools.Compression.csproj | 17 ++++ 17 files changed, 207 insertions(+), 32 deletions(-) create mode 100644 src/Core/FileTime.Core/Command/CopyCommandContext.cs create mode 100644 src/Tools/FileTime.Tools.Compression/Command/CompressCommand.cs create mode 100644 src/Tools/FileTime.Tools.Compression/Command/DecompressCommand.cs create mode 100644 src/Tools/FileTime.Tools.Compression/FileTime.Tools.Compression.csproj diff --git a/src/Core/FileTime.Core/Command/CopyCommand.cs b/src/Core/FileTime.Core/Command/CopyCommand.cs index ecd87e6..4d572ec 100644 --- a/src/Core/FileTime.Core/Command/CopyCommand.cs +++ b/src/Core/FileTime.Core/Command/CopyCommand.cs @@ -6,10 +6,11 @@ namespace FileTime.Core.Command { public class CopyCommand : ITransportationCommand { - private Func? _copyOperation; - private Dictionary _operationStatuses = new(); + private Func? _copyOperation; + private Dictionary> _operationStatuses = new(); private Func>? _createContainer; private Func? _containerCopyDone; + private OperationProgress? _currentOperationProgress; public IList Sources { get; } = new List(); @@ -18,6 +19,7 @@ namespace FileTime.Core.Command public TransportMode? TransportMode { get; set; } = Command.TransportMode.Merge; public int Progress { get; private set; } + public int CurrentProgress { get; private set; } public AsyncEventHandler ProgressChanged { get; } = new(); @@ -26,16 +28,27 @@ namespace FileTime.Core.Command private async Task UpdateProgress() { - var total = 0; - var current = 0; + var total = 0L; + var current = 0L; - foreach (var item in _operationStatuses.Values) + foreach (var folder in _operationStatuses.Values) { - current += item.Progress; - total += item.TotalCount; + foreach (var item in folder) + { + current += item.Progress; + total += item.TotalCount; + } } - Progress = current * 100 / total; + Progress = (int)(current * 100 / total); + if (_currentOperationProgress == null) + { + CurrentProgress = 0; + } + else + { + CurrentProgress = (int)(_currentOperationProgress.Progress * 100 / _currentOperationProgress.TotalCount); + } await ProgressChanged.InvokeAsync(this, AsyncEventArgs.Empty); } @@ -47,7 +60,7 @@ namespace FileTime.Core.Command var newDiffs = new List(); - _copyOperation = (_, to) => + _copyOperation = (_, to, _, _) => { var target = to.GetParentAsAbsolutePath().Resolve(); newDiffs.Add(new Difference( @@ -79,7 +92,7 @@ namespace FileTime.Core.Command return startPoint.WithDifferences(newDiffs); } - public async Task Execute(Action copy, TimeRunner timeRunner) + public async Task Execute(Func copy, TimeRunner timeRunner) { if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null"); if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null"); @@ -87,13 +100,12 @@ namespace FileTime.Core.Command await CalculateProgress(); - _copyOperation = async (from, to) => + _copyOperation = async (from, to, operation, context) => { - copy(from, to); - var parentPath = to.GetParentAsAbsolutePath(); - if (_operationStatuses.ContainsKey(parentPath)) + await copy(from, to, operation, context); + if (operation != null) { - _operationStatuses[parentPath].Progress++; + operation.Progress = operation.TotalCount; } await UpdateProgress(); }; @@ -101,7 +113,11 @@ namespace FileTime.Core.Command _createContainer = async (IContainer target, string name) => await target.CreateContainer(name); _containerCopyDone = async (path) => { - _operationStatuses[path].Progress = _operationStatuses[path].TotalCount; + foreach (var item in _operationStatuses[path]) + { + item.Progress = item.TotalCount; + } + if (timeRunner != null) { await timeRunner.RefreshContainer.InvokeAsync(this, path); @@ -117,24 +133,23 @@ namespace FileTime.Core.Command if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null"); if (TransportMode == null) throw new ArgumentException(nameof(TransportMode) + " can not be null"); - var operationStatuses = new Dictionary(); + var operationStatuses = new Dictionary>(); - _copyOperation = (_, to) => + _copyOperation = async (from, to, _, _) => { var parentPath = to.GetParentAsAbsolutePath(); - OperationProgress operation; + List operationsByFolder; if (operationStatuses.ContainsKey(parentPath)) { - operation = operationStatuses[parentPath]; + operationsByFolder = operationStatuses[parentPath]; } else { - operation = new OperationProgress(); - operationStatuses.Add(parentPath, operation); + var resolvedFrom = await from.Resolve(); + operationsByFolder = new List(); + operationStatuses.Add(parentPath, operationsByFolder); + operationsByFolder.Add(new OperationProgress(from.Path, resolvedFrom is IElement element ? await element.GetElementSize() : 0L)); } - operation.TotalCount++; - - return Task.CompletedTask; }; await TraverseTree(Sources, Target, TransportMode.Value); @@ -180,7 +195,25 @@ namespace FileTime.Core.Command continue; } - _copyOperation?.Invoke(new AbsolutePath(element), AbsolutePath.FromParentAndChildName(target, targetName)); + OperationProgress? operation = null; + var targetFolderPath = new AbsolutePath(target); + var targetElementPath = AbsolutePath.FromParentAndChildName(target, targetName); + + foreach(var asd in _operationStatuses.Keys) + { + var hash1 = asd.GetHashCode(); + var hash2 = targetFolderPath.GetHashCode(); + var eq = asd == targetFolderPath; + } + + if (_operationStatuses.TryGetValue(targetFolderPath, out var targetPathOperations)) + { + var path = new AbsolutePath(element).Path; + operation = targetPathOperations.Find(o => o.Key == path); + } + _currentOperationProgress = operation; + + if (_copyOperation != null) await _copyOperation.Invoke(new AbsolutePath(element), targetElementPath, operation, new CopyCommandContext(UpdateProgress)); } } } diff --git a/src/Core/FileTime.Core/Command/CopyCommandContext.cs b/src/Core/FileTime.Core/Command/CopyCommandContext.cs new file mode 100644 index 0000000..3896e48 --- /dev/null +++ b/src/Core/FileTime.Core/Command/CopyCommandContext.cs @@ -0,0 +1,14 @@ +namespace FileTime.Core.Command +{ + public class CopyCommandContext + { + private readonly Func _updateProgress; + + public CopyCommandContext(Func updateProgress) + { + _updateProgress = updateProgress; + } + + public async Task UpdateProgress() => await _updateProgress.Invoke(); + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core/Command/CreateContainerCommand.cs b/src/Core/FileTime.Core/Command/CreateContainerCommand.cs index 8c118e2..83698de 100644 --- a/src/Core/FileTime.Core/Command/CreateContainerCommand.cs +++ b/src/Core/FileTime.Core/Command/CreateContainerCommand.cs @@ -10,11 +10,13 @@ namespace FileTime.Core.Command public string NewContainerName { get; } public int Progress => 100; + public int CurrentProgress => 100; public AsyncEventHandler ProgressChanged { get; } = new(); public string DisplayLabel { get; } public IReadOnlyList CanRunMessages { get; } = new List().AsReadOnly(); + public CreateContainerCommand(AbsolutePath container, string newContainerName) { Container = container; diff --git a/src/Core/FileTime.Core/Command/CreateElementCommand.cs b/src/Core/FileTime.Core/Command/CreateElementCommand.cs index defea1a..fc1298a 100644 --- a/src/Core/FileTime.Core/Command/CreateElementCommand.cs +++ b/src/Core/FileTime.Core/Command/CreateElementCommand.cs @@ -10,6 +10,7 @@ namespace FileTime.Core.Command public string NewElementName { get; } public int Progress => 100; + public int CurrentProgress => 100; public AsyncEventHandler ProgressChanged { get; } = new(); public string DisplayLabel { get; } public IReadOnlyList CanRunMessages { get; } = new List().AsReadOnly(); diff --git a/src/Core/FileTime.Core/Command/DeleteCommand.cs b/src/Core/FileTime.Core/Command/DeleteCommand.cs index b143c56..d65d820 100644 --- a/src/Core/FileTime.Core/Command/DeleteCommand.cs +++ b/src/Core/FileTime.Core/Command/DeleteCommand.cs @@ -1,5 +1,4 @@ using AsyncEvent; -using FileTime.Core.Extensions; using FileTime.Core.Models; using FileTime.Core.Timeline; @@ -11,6 +10,7 @@ namespace FileTime.Core.Command private Func? _deleteElement; public int Progress => 100; + public int CurrentProgress => 100; public AsyncEventHandler ProgressChanged { get; } = new(); @@ -85,7 +85,6 @@ namespace FileTime.Core.Command if (_deleteContainer != null) await _deleteContainer.Invoke(container); } - } else if (item is IElement element) { diff --git a/src/Core/FileTime.Core/Command/ICommand.cs b/src/Core/FileTime.Core/Command/ICommand.cs index 0bbde3d..bb51634 100644 --- a/src/Core/FileTime.Core/Command/ICommand.cs +++ b/src/Core/FileTime.Core/Command/ICommand.cs @@ -10,6 +10,7 @@ namespace FileTime.Core.Command Task CanRun(PointInTime startPoint); Task SimulateCommand(PointInTime startPoint); int Progress { get; } + int CurrentProgress { get; } AsyncEventHandler ProgressChanged { get; } } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Command/MoveCommand.cs b/src/Core/FileTime.Core/Command/MoveCommand.cs index a3f5219..389ffd6 100644 --- a/src/Core/FileTime.Core/Command/MoveCommand.cs +++ b/src/Core/FileTime.Core/Command/MoveCommand.cs @@ -12,6 +12,7 @@ namespace FileTime.Core.Command public TransportMode? TransportMode { get; set; } = Command.TransportMode.Merge; public int Progress => 100; + public int CurrentProgress => 100; public AsyncEventHandler ProgressChanged { get; } = new(); public string DisplayLabel { get; } = "MoveCommand"; public IReadOnlyList CanRunMessages { get; } = new List().AsReadOnly(); diff --git a/src/Core/FileTime.Core/Command/OperationProgress.cs b/src/Core/FileTime.Core/Command/OperationProgress.cs index eb54462..3849530 100644 --- a/src/Core/FileTime.Core/Command/OperationProgress.cs +++ b/src/Core/FileTime.Core/Command/OperationProgress.cs @@ -2,7 +2,15 @@ namespace FileTime.Core.Command { public class OperationProgress { - public int Progress { get; set; } - public int TotalCount { get; set; } + public string Key { get; } + public long Progress { get; set; } + public long TotalCount { get; } + public bool IsDone => Progress == TotalCount; + + public OperationProgress(string key, long totalCount) + { + Key = key; + TotalCount = totalCount; + } } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Command/RenameCommand.cs b/src/Core/FileTime.Core/Command/RenameCommand.cs index 959c152..6354ba9 100644 --- a/src/Core/FileTime.Core/Command/RenameCommand.cs +++ b/src/Core/FileTime.Core/Command/RenameCommand.cs @@ -11,6 +11,7 @@ namespace FileTime.Core.Command public string Target { get; } public int Progress => 100; + public int CurrentProgress => 100; public AsyncEventHandler ProgressChanged { get; } = new(); public string DisplayLabel { get; } = "RenameCommand"; public IReadOnlyList CanRunMessages { get; } = new List().AsReadOnly(); diff --git a/src/FileTime.sln b/src/FileTime.sln index 4f97d10..757758c 100644 --- a/src/FileTime.sln +++ b/src/FileTime.sln @@ -35,6 +35,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsyncEvent", "Core\AsyncEve EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.Avalonia", "GuiApp\FileTime.Avalonia\FileTime.Avalonia.csproj", "{22B33BC6-3987-4BE6-8C54-BFC75C78CCE7}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{0D2B4BAA-0399-459C-B022-41DB7F408225}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.Tools.Compression", "Tools\FileTime.Tools.Compression\FileTime.Tools.Compression.csproj", "{B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -269,6 +273,26 @@ Global {22B33BC6-3987-4BE6-8C54-BFC75C78CCE7}.Release|x64.Build.0 = Release|Any CPU {22B33BC6-3987-4BE6-8C54-BFC75C78CCE7}.Release|x86.ActiveCfg = Release|Any CPU {22B33BC6-3987-4BE6-8C54-BFC75C78CCE7}.Release|x86.Build.0 = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|ARM.ActiveCfg = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|ARM.Build.0 = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|ARM64.Build.0 = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|x64.ActiveCfg = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|x64.Build.0 = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|x86.ActiveCfg = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Debug|x86.Build.0 = Debug|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|Any CPU.Build.0 = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|ARM.ActiveCfg = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|ARM.Build.0 = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|ARM64.ActiveCfg = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|ARM64.Build.0 = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|x64.ActiveCfg = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|x64.Build.0 = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|x86.ActiveCfg = Release|Any CPU + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -285,6 +309,7 @@ Global {35963404-39F6-4CDA-A0FE-A91036FA8DAC} = {517D96CE-A956-4638-A93D-465D34DE22B1} {9BDAC126-200F-4056-8D35-36EC059B40F3} = {38B1B927-4201-4B7A-87EE-737B8C6D4090} {22B33BC6-3987-4BE6-8C54-BFC75C78CCE7} = {890275FF-943A-4D07-83BA-14E5C52D7846} + {B6F6A8F9-9B7B-4E3E-AE99-A90ECFDDC966} = {0D2B4BAA-0399-459C-B022-41DB7F408225} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8D679DCE-AC84-4A91-BFED-8F8D8E1D8183} diff --git a/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj b/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj index 912d6c1..e794cc5 100644 --- a/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj +++ b/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj @@ -41,7 +41,7 @@ - + diff --git a/src/GuiApp/FileTime.Avalonia/Services/KeyboardConfigurationService.cs b/src/GuiApp/FileTime.Avalonia/Services/KeyboardConfigurationService.cs index 4428a0a..460d55e 100644 --- a/src/GuiApp/FileTime.Avalonia/Services/KeyboardConfigurationService.cs +++ b/src/GuiApp/FileTime.Avalonia/Services/KeyboardConfigurationService.cs @@ -56,6 +56,7 @@ namespace FileTime.Avalonia.Services || keyMapping.Command == Commands.Open || keyMapping.Command == Commands.OpenOrRun || keyMapping.Command == Commands.MoveCursorUp + || keyMapping.Command == Commands.MoveCursorDown || keyMapping.Command == Commands.MoveCursorUpPage || keyMapping.Command == Commands.MoveCursorDownPage; } diff --git a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml index ba88146..e34bd09 100644 --- a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml +++ b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml @@ -245,6 +245,7 @@ 0); } diff --git a/src/Tools/FileTime.Tools.Compression/Command/CompressCommand.cs b/src/Tools/FileTime.Tools.Compression/Command/CompressCommand.cs new file mode 100644 index 0000000..520c6cc --- /dev/null +++ b/src/Tools/FileTime.Tools.Compression/Command/CompressCommand.cs @@ -0,0 +1,35 @@ +using AsyncEvent; +using FileTime.Core.Command; +using FileTime.Core.Models; +using FileTime.Core.Timeline; + +namespace FileTime.Tools.Compression.Command +{ + public class CompressCommand : IExecutableCommand + { + public IList Sources { get; } = new List(); + public string DisplayLabel { get; } = "Compress"; + + public IReadOnlyList CanRunMessages { get; } = new List().AsReadOnly(); + + public int Progress { get; } + + public AsyncEventHandler ProgressChanged { get; } = new AsyncEventHandler(); + + public Task CanRun(PointInTime startPoint) + { + //TODO: implement + return Task.FromResult(CanCommandRun.True); + } + + public Task SimulateCommand(PointInTime startPoint) + { + return Task.FromResult(startPoint.WithDifferences(new List())); + } + + public Task Execute(TimeRunner timeRunner) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Tools/FileTime.Tools.Compression/Command/DecompressCommand.cs b/src/Tools/FileTime.Tools.Compression/Command/DecompressCommand.cs new file mode 100644 index 0000000..d3d187b --- /dev/null +++ b/src/Tools/FileTime.Tools.Compression/Command/DecompressCommand.cs @@ -0,0 +1,34 @@ +using AsyncEvent; +using FileTime.Core.Command; +using FileTime.Core.Timeline; + +namespace FileTime.Tools.Compression.Command +{ + public class DecompressCommand : IExecutableCommand + { + public string DisplayLabel => throw new NotImplementedException(); + + public IReadOnlyList CanRunMessages => throw new NotImplementedException(); + + public int Progress => throw new NotImplementedException(); + + public AsyncEventHandler ProgressChanged => throw new NotImplementedException(); + + public int CurrentProgress => throw new NotImplementedException(); + + public Task CanRun(PointInTime startPoint) + { + throw new NotImplementedException(); + } + + public Task Execute(TimeRunner timeRunner) + { + throw new NotImplementedException(); + } + + public Task SimulateCommand(PointInTime startPoint) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Tools/FileTime.Tools.Compression/FileTime.Tools.Compression.csproj b/src/Tools/FileTime.Tools.Compression/FileTime.Tools.Compression.csproj new file mode 100644 index 0000000..badfe2c --- /dev/null +++ b/src/Tools/FileTime.Tools.Compression/FileTime.Tools.Compression.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + +