Skip to content

Commit 5b2bd92

Browse files
committed
Updated solution 2
1 parent c1e7666 commit 5b2bd92

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+4835
-98
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Components.Controllers;
5+
using Components.Models;
6+
using Buffer = Components.Models.Buffer;
7+
8+
namespace Components.Commands
9+
{
10+
/// <summary>
11+
/// The command wrapper for changing the current input encoding.
12+
/// The Execute operation changes the file encoding property in a given file buffer to a given encoding type.
13+
/// The Undo operation changes the encoding property in said file to the value it had when the command was created.
14+
/// </summary>
15+
[Leskovar]
16+
public class ChangeEncodingInterpretation : ICommand
17+
{
18+
public string Name { get; set; }
19+
private readonly Buffer _buffer;
20+
private readonly EncodingType _newEncoding;
21+
private readonly Encoding _previousEncoding;
22+
23+
/// <summary>
24+
/// Looks up the buffer for a given file and saves its current encoding for the undo operation.
25+
/// </summary>
26+
/// <param name="filePath">The path to the open file whose interpretation should change.</param>
27+
/// <param name="newEncoding">The encoding to which the interpretation should change.</param>
28+
public ChangeEncodingInterpretation(string filePath, EncodingType newEncoding)
29+
{
30+
Name = "Interpret as " + newEncoding;
31+
32+
_buffer = ApplicationState.Instance.FileHandlerInstance.GetFileBuffer(filePath);
33+
_newEncoding = newEncoding;
34+
_previousEncoding = _buffer.FileInstance.InputEncoding;
35+
}
36+
37+
public void Execute()
38+
{
39+
_buffer.FileInstance.SetInputEncoding(_newEncoding);
40+
_buffer.FillBufferFromFile();
41+
}
42+
43+
public void Undo()
44+
{
45+
_buffer.FileInstance.SetInputEncoding(_previousEncoding);
46+
_buffer.FillBufferFromFile();
47+
}
48+
}
49+
}
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Components.Models;
5+
using Buffer = Components.Models.Buffer;
6+
7+
namespace Components.Commands
8+
{
9+
/// <summary>
10+
/// The command wrapper for changing the current line ending character.
11+
/// The Execute operation changes the EOL property in a given file buffer to a given EOL style.
12+
/// The Undo operation changes the EOL property in said file to the value it had when the command was created.
13+
/// </summary>
14+
[Leskovar]
15+
public class ChangeLineEndings : ICommand
16+
{
17+
public string Name { get; set; }
18+
private readonly Buffer _buffer;
19+
private readonly LineEndings _newLineEndingCharacter;
20+
private readonly LineEndings _previousLineEndingsCharacter;
21+
22+
/// <summary>
23+
/// Looks up the buffer for a given file and saves the its current line ending character for the undo operation.
24+
/// </summary>
25+
/// <param name="filePath">The path to the open file whose line endings should change.</param>
26+
/// <param name="newLineEnding">The EOL style to which the file should change.</param>
27+
public ChangeLineEndings(string filePath, LineEndings newLineEnding)
28+
{
29+
Name = "Change EOLs to " + newLineEnding;
30+
31+
_buffer = ApplicationState.Instance.FileHandlerInstance.GetFileBuffer(filePath);
32+
_newLineEndingCharacter = newLineEnding;
33+
_previousLineEndingsCharacter = _buffer.FileInstance.EndOfLineCharacter;
34+
}
35+
36+
public void Execute()
37+
{
38+
_buffer.FileInstance.SetLineEndings(_newLineEndingCharacter);
39+
}
40+
41+
public void Undo()
42+
{
43+
_buffer.FileInstance.SetLineEndings(_previousLineEndingsCharacter);
44+
}
45+
}
46+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Components.Controllers;
5+
using Components.Models;
6+
using Buffer = Components.Models.Buffer;
7+
8+
namespace Components.Commands
9+
{
10+
/// <summary>
11+
/// The command wrapper for changing the current output encoding.
12+
/// The Execute operation changes the file encoding property in a given file buffer to a given encoding type.
13+
/// The Undo operation changes the encoding property in said file to the value it had when the command was created.
14+
/// </summary>
15+
[Leskovar]
16+
public class ConvertEncoding : ICommand
17+
{
18+
public string Name { get; set; }
19+
private readonly Buffer _buffer;
20+
private readonly EncodingType _newEncoding;
21+
private readonly Encoding _previousEncoding;
22+
23+
/// <summary>
24+
/// Looks up the buffer for a given file and saves the its current encoding for the undo operation.
25+
/// </summary>
26+
/// <param name="filePath">The path to the open file whose encoding should change.</param>
27+
/// <param name="newEncoding">The encoding to which the file should change.</param>
28+
public ConvertEncoding(string filePath, EncodingType newEncoding)
29+
{
30+
Name = "Convert Encoding to " + newEncoding;
31+
32+
_buffer = ApplicationState.Instance.FileHandlerInstance.GetFileBuffer(filePath);
33+
_newEncoding = newEncoding;
34+
_previousEncoding = _buffer.FileInstance.OutputEncoding;
35+
}
36+
37+
public void Execute()
38+
{
39+
_buffer.FileInstance.SetOutputEncoding(_newEncoding);
40+
}
41+
42+
public void Undo()
43+
{
44+
_buffer.FileInstance.SetOutputEncoding(_previousEncoding);
45+
}
46+
}
47+
}

Components/Commands/ICommand.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
5-
namespace Components.Controllers
1+
namespace Components.Commands
62
{
73
[Leskovar]
84
public interface ICommand

Components/Components.csproj

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<LangVersion>8.0</LangVersion>
56
</PropertyGroup>
67

7-
<ItemGroup>
8-
<Folder Include="Views\" />
9-
</ItemGroup>
10-
118
</Project>

Components/Controllers/AutoSaver.cs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Components.Models;
5+
6+
namespace Components.Controllers
7+
{
8+
[Leskovar]
9+
public class AutoSaver
10+
{
11+
private static AutoSaver _instance;
12+
private static readonly object Mutex = new object();
13+
private string _currentFilePath;
14+
15+
private AutoSaver()
16+
{
17+
}
18+
19+
/// <summary>
20+
/// Makes sure only one instance is ever created.
21+
/// </summary>
22+
/// <returns>Reference to the singleton instance.</returns>
23+
public static AutoSaver Instance
24+
{
25+
get
26+
{
27+
lock (Mutex)
28+
{
29+
return _instance ??= new AutoSaver();
30+
}
31+
}
32+
}
33+
34+
public void Update(string filePath)
35+
{
36+
_currentFilePath = filePath;
37+
}
38+
39+
public void Trigger()
40+
{
41+
Console.WriteLine($"#DEBUG: Saving the file {_currentFilePath}.");
42+
ApplicationState.Instance.FileHandlerInstance.SaveFile(_currentFilePath, _currentFilePath);
43+
}
44+
}
45+
}

Components/Controllers/CommandHandler.cs

+61-14
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Collections.Generic;
33
using System.ComponentModel;
44
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Components.Commands;
57

68
namespace Components.Controllers
79
{
@@ -13,7 +15,8 @@ public class CommandInvoker
1315
{
1416
private static CommandInvoker _instance;
1517
private static readonly object Mutex = new object();
16-
private readonly Stack<ICommand> _commandHistory = new Stack<ICommand>();
18+
private readonly Stack<ICommand> _executeCommandHistory = new Stack<ICommand>();
19+
private readonly Stack<ICommand> _undoCommandHistory = new Stack<ICommand>();
1720

1821
private CommandInvoker()
1922
{
@@ -40,36 +43,80 @@ public static CommandInvoker Instance
4043
/// <returns>A list of command names in an ordered manner - recent commands come first.</returns>
4144
public List<string> GetCommandHistory()
4245
{
43-
return _commandHistory.Select(x => x.Name).ToList();
46+
return _executeCommandHistory.Select(x => x.Name).ToList();
4447
}
4548

4649
/// <summary>
47-
/// Executes a single command and adds it to the command history.
50+
/// Executes a single command and adds it to the command history. Clears the undo history since all undoing has been done, the user now invokes commands.
4851
/// </summary>
4952
/// <typeparam name="T"></typeparam>
5053
/// <param name="command">The command object whose execute methods should be called.</param>
51-
public void Execute<T>(T command) where T : ICommand
54+
public async Task Execute<T>(T command) where T : ICommand
5255
{
53-
command.Execute();
54-
_commandHistory.Push(command);
56+
var task = new Task(() =>
57+
{
58+
command.Execute();
59+
_executeCommandHistory.Push(command);
60+
_undoCommandHistory.Clear();
61+
AutoSaver.Instance.Trigger();
62+
});
63+
64+
task.Start();
65+
await task;
5566
}
5667

5768
/// <summary>
5869
/// Undoes a given number of commands (if that number is valid) and removes them from the command history.
70+
/// Adds the command to the undo history for the possible redo.
5971
/// </summary>
6072
/// <param name="numberOfCommands">The number of commands to be undone. Default is one.</param>
61-
public void Undo(int numberOfCommands = 1)
73+
public async Task Undo(int numberOfCommands = 1)
6274
{
63-
if (numberOfCommands < 1 || numberOfCommands > _commandHistory.Count)
75+
var task = new Task(() =>
6476
{
65-
throw new InvalidOperationException();
66-
}
77+
if (numberOfCommands < 1 || numberOfCommands > _executeCommandHistory.Count)
78+
{
79+
throw new InvalidOperationException();
80+
}
6781

68-
for (var i = 0; i < numberOfCommands; i++)
82+
for (var i = 0; i < numberOfCommands; i++)
83+
{
84+
var command = _executeCommandHistory.Pop();
85+
command.Undo();
86+
_undoCommandHistory.Push(command);
87+
}
88+
89+
AutoSaver.Instance.Trigger();
90+
});
91+
92+
task.Start();
93+
await task;
94+
}
95+
96+
/// <summary>
97+
/// Redoes a given number of undone commands (if that number is valid) and removes them from the undo command history.
98+
/// </summary>
99+
/// <param name="numberOfCommands">The number of commands to be redone. Default is one.</param>
100+
public async Task Redo(int numberOfCommands = 1)
101+
{
102+
var task = new Task(() =>
69103
{
70-
var command = _commandHistory.Pop();
71-
command.Undo();
72-
}
104+
if (numberOfCommands < 1 || numberOfCommands > _undoCommandHistory.Count)
105+
{
106+
throw new InvalidOperationException();
107+
}
108+
109+
for (var i = 0; i < numberOfCommands; i++)
110+
{
111+
var command = _undoCommandHistory.Pop();
112+
command.Execute();
113+
}
114+
115+
AutoSaver.Instance.Trigger();
116+
});
117+
118+
task.Start();
119+
await task;
73120
}
74121
}
75122
}

0 commit comments

Comments
 (0)