From d84b17ced31499ed187daf15572c04c367acc259 Mon Sep 17 00:00:00 2001 From: Ben Wallis Date: Thu, 7 Dec 2017 18:14:47 +0000 Subject: [PATCH] Implemented script-level undo/redo (currently hidden in UI) --- .gitignore | 184 ++++++++-- .../Commands/CommandManager.cs | 3 +- .../ItemFilterScript/AddBlockCommand.cs | 37 ++ .../AddCommentBlockCommand.cs | 37 ++ .../ItemFilterScript/MoveBlockDownCommand.cs | 39 ++ .../MoveBlockToBottomCommand.cs | 30 ++ .../ItemFilterScript/MoveBlockToTopCommand.cs | 30 ++ .../ItemFilterScript/MoveBlockUpCommand.cs | 39 ++ .../ItemFilterScript/PasteBlockCommand.cs | 37 ++ .../ItemFilterScript/RemoveBlockCommand.cs | 29 ++ .../SetScriptDescriptionCommand.cs | 30 ++ .../Filtration.ObjectModel.csproj | 9 + Filtration.ObjectModel/ItemFilterBlock.cs | 37 +- Filtration.ObjectModel/ItemFilterScript.cs | 14 +- .../Services/IItemFilterBlockTranslator.cs | 5 +- .../Services/TestItemFilterBlockTranslator.cs | 106 +++--- .../TestItemFilterScriptTranslator.cs | 2 +- .../Services/ItemFilterBlockTranslator.cs | 17 +- .../Services/ItemFilterScriptTranslator.cs | 4 +- .../TestItemFilterScriptRepository.cs | 1 + Filtration/Filtration.csproj | 11 +- .../ItemFilterScriptRepository.cs | 1 + Filtration/Resources/Icons/redo_icon.png | Bin 0 -> 579 bytes Filtration/Resources/Icons/undo_icon.png | Bin 0 -> 339 bytes .../IItemFilterBlockViewModelFactory.cs | 2 +- ...IItemFilterCommentBlockViewModelFactory.cs | 2 +- .../IItemFilterScriptViewModelFactory.cs | 2 +- .../ItemFilterBlockBaseViewModelFactory.cs | 37 ++ .../ViewModels/ItemFilterBlockViewModel.cs | 71 +--- .../ItemFilterBlockViewModelBase.cs | 42 +++ .../ItemFilterCommentBlockViewModel.cs | 29 ++ .../ViewModels/ItemFilterScriptViewModel.cs | 343 +++++++----------- Filtration/ViewModels/MainWindowViewModel.cs | 22 +- Filtration/Views/IconsDictionary.xaml | 2 + Filtration/Views/MainWindow.xaml | 12 +- .../WindsorInstallers/ViewModelsInstaller.cs | 6 + 36 files changed, 888 insertions(+), 384 deletions(-) create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/AddBlockCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/AddCommentBlockCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockDownCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToBottomCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToTopCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockUpCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/PasteBlockCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/RemoveBlockCommand.cs create mode 100644 Filtration.ObjectModel/Commands/ItemFilterScript/SetScriptDescriptionCommand.cs create mode 100644 Filtration/Resources/Icons/redo_icon.png create mode 100644 Filtration/Resources/Icons/undo_icon.png rename Filtration/ViewModels/{ => Factories}/IItemFilterBlockViewModelFactory.cs (80%) rename Filtration/ViewModels/{ => Factories}/IItemFilterCommentBlockViewModelFactory.cs (82%) rename Filtration/ViewModels/{ => Factories}/IItemFilterScriptViewModelFactory.cs (81%) create mode 100644 Filtration/ViewModels/Factories/ItemFilterBlockBaseViewModelFactory.cs create mode 100644 Filtration/ViewModels/ItemFilterBlockViewModelBase.cs create mode 100644 Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs diff --git a/.gitignore b/.gitignore index 7964536..bce8a85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,29 +1,42 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.suo *.user +*.userosscache *.sln.docstates +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ +[Rr]eleases/ x64/ -build/ +x86/ bld/ [Bb]in/ [Oo]bj/ +[Ll]og/ -# Roslyn cache directories -*.ide/ +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* -#NUNIT +# NUNIT *.VisualState.xml TestResult.xml @@ -32,6 +45,19 @@ TestResult.xml [Rr]eleasePS/ dlldata.c +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c *_i.h @@ -64,14 +90,21 @@ _Chutzpah* ipch/ *.aps *.ncb +*.opendb *.opensdf *.sdf *.cachefile +*.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx +*.sap + +# Visual Studio Trace Files +*.e2e # TFS 2012 Local Workspace $tf/ @@ -84,7 +117,7 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding addin-in +# JustCode is a .NET coding add-in .JustCode # TeamCity is a build add-in @@ -93,9 +126,18 @@ _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch _NCrunch_* .*crunch*.local.xml +nCrunchTemp_* # MightyMoose *.mm.* @@ -123,42 +165,63 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -## TODO: Comment the next line if you want to checkin your -## web deploy settings but do note that will include unencrypted -## passwords -#*.pubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj -# NuGet Packages Directory -packages/* -## TODO: If the tool you use requires repositories.config -## uncomment the next line -#!packages/repositories.config +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ -# Enable "build/" folder in the NuGet Packages folder since -# NuGet packages use it for MSBuild targets. -# This line needs to be after the ignore of the build folder -# (and the packages folder if the line above has been uncommented) -!packages/build/ +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets -# Windows Azure Build Output +# Microsoft Azure Build Output csx/ *.build.csdef -# Windows Store app package directory +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ # Others -sql/ -*.Cache ClientBin/ -[Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.dbproj.schemaview +*.jfm *.pfx *.publishsettings -node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ # RIA/Silverlight projects Generated_Code/ @@ -174,6 +237,7 @@ UpgradeLog*.htm # SQL Server files *.mdf *.ldf +*.ndf # Business Intelligence projects *.rdl.data @@ -183,7 +247,69 @@ UpgradeLog*.htm # Microsoft Fakes FakesAssemblies/ -# LightSwitch generated files -GeneratedArtifacts/ -_Pvt_Extensions/ -ModelManifest.xml \ No newline at end of file +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# TypeScript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ \ No newline at end of file diff --git a/Filtration.ObjectModel/Commands/CommandManager.cs b/Filtration.ObjectModel/Commands/CommandManager.cs index e8dc6f7..2f58cee 100644 --- a/Filtration.ObjectModel/Commands/CommandManager.cs +++ b/Filtration.ObjectModel/Commands/CommandManager.cs @@ -28,8 +28,7 @@ namespace Filtration.ObjectModel.Commands public void ExecuteCommand(ICommand command) { command.Execute(); - var undoableCommand = command as IUndoableCommand; - if (undoableCommand != null) + if (command is IUndoableCommand undoableCommand) { _undoCommandStack.Push(undoableCommand); _redoCommandStack.Clear(); diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/AddBlockCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/AddBlockCommand.cs new file mode 100644 index 0000000..7aa9e85 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/AddBlockCommand.cs @@ -0,0 +1,37 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class AddBlockCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _addAfterItemFilterBlock; + private IItemFilterBlock _newItemFilterBlock; + + public AddBlockCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase addAfterItemFilterBlock) + { + _itemFilterScript = itemFilterScript; + _addAfterItemFilterBlock = addAfterItemFilterBlock; + } + public void Execute() + { + _newItemFilterBlock = new ItemFilterBlock(_itemFilterScript); + if (_addAfterItemFilterBlock != null) + { + _itemFilterScript.ItemFilterBlocks.Insert(_itemFilterScript.ItemFilterBlocks.IndexOf(_addAfterItemFilterBlock) + 1, _newItemFilterBlock); + } + else + { + _itemFilterScript.ItemFilterBlocks.Add(_newItemFilterBlock); + } + + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_newItemFilterBlock); + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/AddCommentBlockCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/AddCommentBlockCommand.cs new file mode 100644 index 0000000..1c627df --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/AddCommentBlockCommand.cs @@ -0,0 +1,37 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class AddCommentBlockCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _addAfterItemFilterBlock; + private IItemFilterCommentBlock _newItemFilterBlock; + + public AddCommentBlockCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase addAfterItemFilterBlock) + { + _itemFilterScript = itemFilterScript; + _addAfterItemFilterBlock = addAfterItemFilterBlock; + } + public void Execute() + { + _newItemFilterBlock = new ItemFilterCommentBlock(_itemFilterScript); + if (_addAfterItemFilterBlock != null) + { + _itemFilterScript.ItemFilterBlocks.Insert(_itemFilterScript.ItemFilterBlocks.IndexOf(_addAfterItemFilterBlock) + 1, _newItemFilterBlock); + } + else + { + _itemFilterScript.ItemFilterBlocks.Add(_newItemFilterBlock); + } + + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_newItemFilterBlock); + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockDownCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockDownCommand.cs new file mode 100644 index 0000000..0f837e6 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockDownCommand.cs @@ -0,0 +1,39 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class MoveBlockDownCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _blockToMove; + private int _indexMovedFrom; + + public MoveBlockDownCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase blockToMove) + { + _itemFilterScript = itemFilterScript; + _blockToMove = blockToMove; + } + + public void Execute() + { + _indexMovedFrom = _itemFilterScript.ItemFilterBlocks.IndexOf(_blockToMove); + + if (_indexMovedFrom >= _itemFilterScript.ItemFilterBlocks.Count) + { + throw new InvalidOperationException("Cannot move the bottom block down"); + } + + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(_indexMovedFrom + 1, _blockToMove); + + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(_indexMovedFrom, _blockToMove); + } + + public void Redo() => Execute(); + } +} \ No newline at end of file diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToBottomCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToBottomCommand.cs new file mode 100644 index 0000000..3b680a7 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToBottomCommand.cs @@ -0,0 +1,30 @@ +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class MoveBlockToBottomCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _blockToMove; + private int _indexMovedFrom; + + public MoveBlockToBottomCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase blockToMove) + { + _itemFilterScript = itemFilterScript; + _blockToMove = blockToMove; + } + public void Execute() + { + _indexMovedFrom = _itemFilterScript.ItemFilterBlocks.IndexOf(_blockToMove); + + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Add(_blockToMove); + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(_indexMovedFrom, _blockToMove); + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToTopCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToTopCommand.cs new file mode 100644 index 0000000..49ac04a --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockToTopCommand.cs @@ -0,0 +1,30 @@ +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class MoveBlockToTopCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _blockToMove; + private int _indexMovedFrom; + + public MoveBlockToTopCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase blockToMove) + { + _itemFilterScript = itemFilterScript; + _blockToMove = blockToMove; + } + public void Execute() + { + _indexMovedFrom = _itemFilterScript.ItemFilterBlocks.IndexOf(_blockToMove); + + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(0, _blockToMove); + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(_indexMovedFrom, _blockToMove); + } + + public void Redo() => Execute(); + } +} \ No newline at end of file diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockUpCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockUpCommand.cs new file mode 100644 index 0000000..44b7fec --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/MoveBlockUpCommand.cs @@ -0,0 +1,39 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class MoveBlockUpCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _blockToMove; + private int _indexMovedFrom; + + public MoveBlockUpCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase blockToMove) + { + _itemFilterScript = itemFilterScript; + _blockToMove = blockToMove; + } + + public void Execute() + { + _indexMovedFrom = _itemFilterScript.ItemFilterBlocks.IndexOf(_blockToMove); + + if (_indexMovedFrom <= 0) + { + throw new InvalidOperationException("Cannot move the top block up"); + } + + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(_indexMovedFrom-1, _blockToMove); + + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_blockToMove); + _itemFilterScript.ItemFilterBlocks.Insert(_indexMovedFrom, _blockToMove); + } + + public void Redo() => Execute(); + } +} \ No newline at end of file diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/PasteBlockCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/PasteBlockCommand.cs new file mode 100644 index 0000000..7d7c680 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/PasteBlockCommand.cs @@ -0,0 +1,37 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class PasteBlockCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly IItemFilterBlockBase _pastedItemFilterBlock; + private readonly IItemFilterBlockBase _addAfterItemFilterBlock; + + public PasteBlockCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase pastedItemFilterBlock, IItemFilterBlockBase addAfterItemFilterBlock) + { + _itemFilterScript = itemFilterScript; + _pastedItemFilterBlock = pastedItemFilterBlock; + _addAfterItemFilterBlock = addAfterItemFilterBlock; + } + + public void Execute() + { + if (_addAfterItemFilterBlock != null) + { + _itemFilterScript.ItemFilterBlocks.Insert(_itemFilterScript.ItemFilterBlocks.IndexOf(_addAfterItemFilterBlock) + 1, _pastedItemFilterBlock); + } + else + { + _itemFilterScript.ItemFilterBlocks.Add(_pastedItemFilterBlock); + } + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Remove(_pastedItemFilterBlock); + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/RemoveBlockCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/RemoveBlockCommand.cs new file mode 100644 index 0000000..07e61ac --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/RemoveBlockCommand.cs @@ -0,0 +1,29 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class RemoveBlockCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private IItemFilterBlockBase _removedItemFilterBlock; + private int _indexRemovedFrom; + + public RemoveBlockCommand(IItemFilterScript itemFilterScript, IItemFilterBlockBase itemFilterBlockBase) + { + _itemFilterScript = itemFilterScript; + _removedItemFilterBlock = itemFilterBlockBase; + } + public void Execute() + { + _indexRemovedFrom = _itemFilterScript.ItemFilterBlocks.IndexOf(_removedItemFilterBlock); + _itemFilterScript.ItemFilterBlocks.Remove(_removedItemFilterBlock); + } + + public void Undo() + { + _itemFilterScript.ItemFilterBlocks.Insert(_indexRemovedFrom, _removedItemFilterBlock); + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Commands/ItemFilterScript/SetScriptDescriptionCommand.cs b/Filtration.ObjectModel/Commands/ItemFilterScript/SetScriptDescriptionCommand.cs new file mode 100644 index 0000000..ec99154 --- /dev/null +++ b/Filtration.ObjectModel/Commands/ItemFilterScript/SetScriptDescriptionCommand.cs @@ -0,0 +1,30 @@ +using System; + +namespace Filtration.ObjectModel.Commands.ItemFilterScript +{ + public class SetScriptDescriptionCommand : IUndoableCommand + { + private readonly IItemFilterScript _itemFilterScript; + private readonly string _newDescription; + private string _oldDescription; + + public SetScriptDescriptionCommand(IItemFilterScript itemFilterScript, string newDescription) + { + _itemFilterScript = itemFilterScript; + _newDescription = newDescription; + } + + public void Execute() + { + _oldDescription = _itemFilterScript.Description; + _itemFilterScript.Description = _newDescription; + } + + public void Undo() + { + _itemFilterScript.Description = _oldDescription; + } + + public void Redo() => Execute(); + } +} diff --git a/Filtration.ObjectModel/Filtration.ObjectModel.csproj b/Filtration.ObjectModel/Filtration.ObjectModel.csproj index 17c34c7..e4a341c 100644 --- a/Filtration.ObjectModel/Filtration.ObjectModel.csproj +++ b/Filtration.ObjectModel/Filtration.ObjectModel.csproj @@ -76,6 +76,15 @@ + + + + + + + + + diff --git a/Filtration.ObjectModel/ItemFilterBlock.cs b/Filtration.ObjectModel/ItemFilterBlock.cs index d8cfcc1..92bd8ef 100644 --- a/Filtration.ObjectModel/ItemFilterBlock.cs +++ b/Filtration.ObjectModel/ItemFilterBlock.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Windows.Media; using Filtration.ObjectModel.BlockItemBaseTypes; using Filtration.ObjectModel.BlockItemTypes; +using Filtration.ObjectModel.Commands; using Filtration.ObjectModel.Enums; using Filtration.ObjectModel.Extensions; @@ -29,9 +30,20 @@ namespace Filtration.ObjectModel { } - public class ItemFilterBlockBase : IItemFilterBlockBase + public abstract class ItemFilterBlockBase : IItemFilterBlockBase { - + protected ItemFilterBlockBase() + { + } + + protected ItemFilterBlockBase(IItemFilterScript parentScript) + { + CommandManager = parentScript.CommandManager; + ParentScript = parentScript; + } + + public ICommandManager CommandManager { get; } + public IItemFilterScript ParentScript { get; set; } } public interface IItemFilterCommentBlock : IItemFilterBlockBase @@ -41,6 +53,10 @@ namespace Filtration.ObjectModel public class ItemFilterCommentBlock : ItemFilterBlockBase, IItemFilterCommentBlock { + public ItemFilterCommentBlock(IItemFilterScript parentScript) : base(parentScript) + { + } + public string Comment { get; set; } } @@ -48,14 +64,19 @@ namespace Filtration.ObjectModel { private ItemFilterBlockGroup _blockGroup; - public ItemFilterBlock() + internal ItemFilterBlock() { - ActionBlockItem = new ActionBlockItem(BlockAction.Show); - BlockItems = new ObservableCollection {ActionBlockItem}; - Enabled = true; + BlockItems = new ObservableCollection { ActionBlockItem }; } - public bool Enabled { get; set; } + public ItemFilterBlock(IItemFilterScript parentScript) : base(parentScript) + { + BlockItems = new ObservableCollection { ActionBlockItem }; + } + + public ICommandManager CommandManager { get; } + + public bool Enabled { get; set; } = true; public string Description { get; set; } public ItemFilterBlockGroup BlockGroup @@ -98,7 +119,7 @@ namespace Filtration.ObjectModel } } - public ActionBlockItem ActionBlockItem { get; } + public ActionBlockItem ActionBlockItem { get; } = new ActionBlockItem(BlockAction.Show); public ObservableCollection BlockItems { get; } diff --git a/Filtration.ObjectModel/ItemFilterScript.cs b/Filtration.ObjectModel/ItemFilterScript.cs index 9548e51..703ad6d 100644 --- a/Filtration.ObjectModel/ItemFilterScript.cs +++ b/Filtration.ObjectModel/ItemFilterScript.cs @@ -37,6 +37,7 @@ namespace Filtration.ObjectModel public class ItemFilterScript : IItemFilterScriptInternal { private bool _isDirty; + private string _description; internal ItemFilterScript() { @@ -65,7 +66,18 @@ namespace Filtration.ObjectModel public IItemFilterScriptSettings ItemFilterScriptSettings { get; } public string FilePath { get; set; } - public string Description { get; set; } + + public string Description + { + get => _description; + set + { + if (value == _description) return; + _description = value; + OnPropertyChanged(); + } + } + public DateTime DateModified { get; set; } public bool IsDirty diff --git a/Filtration.Parser.Interface/Services/IItemFilterBlockTranslator.cs b/Filtration.Parser.Interface/Services/IItemFilterBlockTranslator.cs index 6704bb6..859e276 100644 --- a/Filtration.Parser.Interface/Services/IItemFilterBlockTranslator.cs +++ b/Filtration.Parser.Interface/Services/IItemFilterBlockTranslator.cs @@ -5,10 +5,11 @@ namespace Filtration.Parser.Interface.Services { public interface IItemFilterBlockTranslator { - IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScriptSettings itemFilterScriptSettings); + IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScript parentItemFilterScript, bool initialiseBlockGroupHierarchyBuilder = false); + IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString, IItemFilterScript parentItemFilterScript); + string TranslateItemFilterBlockToString(IItemFilterBlock block); void ReplaceAudioVisualBlockItemsFromString(ObservableCollection blockItems, string inputString); - IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString); string TranslateItemFilterCommentBlockToString(IItemFilterCommentBlock itemFilterCommentBlock); string TranslateItemFilterBlockBaseToString(IItemFilterBlockBase itemFilterBlockBase); } diff --git a/Filtration.Parser.Tests/Services/TestItemFilterBlockTranslator.cs b/Filtration.Parser.Tests/Services/TestItemFilterBlockTranslator.cs index f2f3acd..8c5dc7c 100644 --- a/Filtration.Parser.Tests/Services/TestItemFilterBlockTranslator.cs +++ b/Filtration.Parser.Tests/Services/TestItemFilterBlockTranslator.cs @@ -33,7 +33,7 @@ namespace Filtration.Parser.Tests.Services var testInputString = "# This is a comment\r\n# Line 2 \r\n # Test"; //Act - var result = _testUtility.Translator.TranslateStringToItemFilterCommentBlock(testInputString); + var result = _testUtility.Translator.TranslateStringToItemFilterCommentBlock(testInputString, Mock.Of()); //Assert Assert.AreEqual(" This is a comment\r\n Line 2 \r\n Test", result.Comment); @@ -52,7 +52,7 @@ namespace Filtration.Parser.Tests.Services .Returns(inputBlockGroup); // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); //Assert Assert.IsTrue(string.IsNullOrEmpty(result.ActionBlockItem.Comment)); @@ -68,7 +68,7 @@ namespace Filtration.Parser.Tests.Services var inputString = $"Show #{testInputExpectedComment}" + Environment.NewLine; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled == false)); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled == false)); //Assert Assert.AreEqual(testInputExpectedComment, result.ActionBlockItem.Comment); @@ -82,7 +82,7 @@ namespace Filtration.Parser.Tests.Services " ItemLevel >= 55"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(true, result.Enabled); @@ -96,7 +96,7 @@ namespace Filtration.Parser.Tests.Services " ItemLevel >= 55"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(2, result.BlockItems.Count); @@ -112,7 +112,7 @@ namespace Filtration.Parser.Tests.Services " ItemLevel >= 55"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is ItemLevelBlockItem)); @@ -130,7 +130,7 @@ namespace Filtration.Parser.Tests.Services // Act _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny>())).Returns(inputBlockGroup).Verifiable(); - _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert Assert.AreEqual(true, inputBlockGroup.IsChecked); @@ -145,7 +145,7 @@ namespace Filtration.Parser.Tests.Services // Act _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny>())).Returns(inputBlockGroup).Verifiable(); - _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert Assert.AreEqual(false, inputBlockGroup.IsChecked); @@ -160,7 +160,7 @@ namespace Filtration.Parser.Tests.Services // Act _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny>())).Returns(inputBlockGroup).Verifiable(); - _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert _testUtility.MockBlockGroupHierarchyBuilder.Verify(); @@ -174,7 +174,7 @@ namespace Filtration.Parser.Tests.Services // Act _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny>())).Verifiable(); - _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny>()), Times.Never); @@ -187,7 +187,7 @@ namespace Filtration.Parser.Tests.Services var inputString = "Show #" + Environment.NewLine; // Act - _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny>()), Times.Never); @@ -206,7 +206,7 @@ namespace Filtration.Parser.Tests.Services .Returns(testBlockGroup) .Verifiable(); - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert Assert.AreEqual(testBlockGroup, result.BlockGroup); @@ -226,7 +226,7 @@ namespace Filtration.Parser.Tests.Services .Returns(testBlockGroup) .Verifiable(); - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled)); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled)); // Assert Assert.AreEqual(testBlockGroup, result.BlockGroup); @@ -240,7 +240,7 @@ namespace Filtration.Parser.Tests.Services var inputString = "Show # AAA - BBB - CCC" + Environment.NewLine; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.BlockGroupsEnabled == false)); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.BlockGroupsEnabled == false)); // Assert Assert.IsNull(result.BlockGroup); @@ -254,7 +254,7 @@ namespace Filtration.Parser.Tests.Services var inputString = "Hide" + Environment.NewLine; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem)); @@ -270,7 +270,7 @@ namespace Filtration.Parser.Tests.Services " ItemLevel >= 55"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual("This is a test Block", result.Description); @@ -290,7 +290,7 @@ namespace Filtration.Parser.Tests.Services " ItemLevel >= 55"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual("Second Line", result.Description); @@ -308,7 +308,7 @@ namespace Filtration.Parser.Tests.Services " DropLevel = 40"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -326,7 +326,7 @@ namespace Filtration.Parser.Tests.Services " Corrupted True"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -343,7 +343,7 @@ namespace Filtration.Parser.Tests.Services " Identified True"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -360,7 +360,7 @@ namespace Filtration.Parser.Tests.Services " Quality < 18"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -378,7 +378,7 @@ namespace Filtration.Parser.Tests.Services " Rarity > Normal"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -396,7 +396,7 @@ namespace Filtration.Parser.Tests.Services " Rarity Normal"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is RarityBlockItem)); @@ -413,7 +413,7 @@ namespace Filtration.Parser.Tests.Services @" Class ""Test Class 1"" ""TestOneWordClassInQuotes"" TestOneWordClassNotInQuotes ""Test Class 2"""; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is ClassBlockItem)); @@ -432,7 +432,7 @@ namespace Filtration.Parser.Tests.Services @" BaseType ""Test Base Type 1"" ""TestOneWordBaseTypeInQuotes"" TestOneWordBaseTypeNotInQuotes ""Test BaseType 2"""; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is BaseTypeBlockItem)); @@ -451,7 +451,7 @@ namespace Filtration.Parser.Tests.Services " Sockets > 2"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -469,7 +469,7 @@ namespace Filtration.Parser.Tests.Services " LinkedSockets > 1"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -487,7 +487,7 @@ namespace Filtration.Parser.Tests.Services " Width = 1"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -505,7 +505,7 @@ namespace Filtration.Parser.Tests.Services " Height <= 3"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert @@ -523,7 +523,7 @@ namespace Filtration.Parser.Tests.Services " Height <=3"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is HeightBlockItem)); @@ -540,7 +540,7 @@ namespace Filtration.Parser.Tests.Services " SocketGroup RRGB"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is SocketGroupBlockItem)); @@ -558,7 +558,7 @@ namespace Filtration.Parser.Tests.Services " SetTextColor 255 20 100"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem)); @@ -576,7 +576,7 @@ namespace Filtration.Parser.Tests.Services " SetTextColor 65 0 255 12"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem)); @@ -595,7 +595,7 @@ namespace Filtration.Parser.Tests.Services " SetBackgroundColor 255 20 100"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is BackgroundColorBlockItem)); @@ -614,7 +614,7 @@ namespace Filtration.Parser.Tests.Services " SetBorderColor 255 20 100"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem)); @@ -633,8 +633,8 @@ namespace Filtration.Parser.Tests.Services // Act - Assert.DoesNotThrow(() => _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of())); - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + Assert.DoesNotThrow(() => _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript)); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem)); @@ -652,10 +652,9 @@ namespace Filtration.Parser.Tests.Services " SetTextColor 255 20 100 # Rare Item Text"; var testComponent = new ThemeComponent(ThemeComponentType.TextColor, "Rare Item Text", new Color { R = 255, G = 20, B = 100}); var testInputThemeComponentCollection = new ThemeComponentCollection { testComponent }; - var testInputItemFilterScriptSettings = Mock.Of(i => i.ThemeComponentCollection == testInputThemeComponentCollection); // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, testInputItemFilterScriptSettings); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of(i => i.ItemFilterScriptSettings.ThemeComponentCollection == testInputThemeComponentCollection)); // Assert var blockItem = result.BlockItems.OfType().First(); @@ -673,7 +672,7 @@ namespace Filtration.Parser.Tests.Services " SetFontSize 15"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is FontSizeBlockItem)); @@ -690,7 +689,7 @@ namespace Filtration.Parser.Tests.Services " PlayAlertSound 4"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem)); @@ -708,7 +707,7 @@ namespace Filtration.Parser.Tests.Services " PlayAlertSound 2 95"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem)); @@ -745,7 +744,7 @@ namespace Filtration.Parser.Tests.Services " PlayAlertSound 3"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual("Test filter with everything", result.Description); @@ -833,7 +832,7 @@ namespace Filtration.Parser.Tests.Services " Quality < 17"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(2, result.BlockItems.Count(b => b is ItemLevelBlockItem)); @@ -862,7 +861,7 @@ namespace Filtration.Parser.Tests.Services " SetTextColor 255 20 100"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem)); @@ -883,7 +882,7 @@ namespace Filtration.Parser.Tests.Services " SetFontSize 27" + Environment.NewLine; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is FontSizeBlockItem)); @@ -902,7 +901,7 @@ namespace Filtration.Parser.Tests.Services " PlayAlertSound 2" + Environment.NewLine; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem)); @@ -920,7 +919,7 @@ namespace Filtration.Parser.Tests.Services " SetBackgroundColor 255 20 100"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is BackgroundColorBlockItem)); @@ -939,7 +938,7 @@ namespace Filtration.Parser.Tests.Services " SetBorderColor 255 20 100"; // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem)); @@ -967,7 +966,7 @@ namespace Filtration.Parser.Tests.Services _testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4)); // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is RarityBlockItem)); @@ -994,7 +993,7 @@ namespace Filtration.Parser.Tests.Services _testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4)); // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem)); @@ -1029,7 +1028,7 @@ namespace Filtration.Parser.Tests.Services _testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4)); // Act - var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of()); + var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript); // Assert Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem)); @@ -1870,6 +1869,7 @@ namespace Filtration.Parser.Tests.Services // Mock setups MockBlockGroupHierarchyBuilder = new Mock(); + MockItemFilterScript = Mock.Of(i => i.ItemFilterScriptSettings.ThemeComponentCollection == new ThemeComponentCollection()); // Class under test instantiation Translator = new ItemFilterBlockTranslator(MockBlockGroupHierarchyBuilder.Object); @@ -1878,6 +1878,8 @@ namespace Filtration.Parser.Tests.Services public ItemFilterBlock TestBlock { get; set; } public Mock MockBlockGroupHierarchyBuilder { get; } public ItemFilterBlockTranslator Translator { get; } + + public IItemFilterScript MockItemFilterScript { get; } } } } diff --git a/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs b/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs index 886102e..32ac065 100644 --- a/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs +++ b/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs @@ -40,7 +40,7 @@ namespace Filtration.Parser.Tests.Services // Assert Assert.AreEqual(5, script.ItemFilterBlocks.Count); - mockItemFilterBlockTranslator.Verify(t => t.TranslateStringToItemFilterBlock(It.IsAny(), It.IsAny())); + mockItemFilterBlockTranslator.Verify(t => t.TranslateStringToItemFilterBlock(It.IsAny(), It.IsAny(), false)); } [Test] diff --git a/Filtration.Parser/Services/ItemFilterBlockTranslator.cs b/Filtration.Parser/Services/ItemFilterBlockTranslator.cs index 485ccfd..b8b10a1 100644 --- a/Filtration.Parser/Services/ItemFilterBlockTranslator.cs +++ b/Filtration.Parser/Services/ItemFilterBlockTranslator.cs @@ -30,9 +30,9 @@ namespace Filtration.Parser.Services } // Converts a string into an ItemFilterCommentBlock maintaining newlines and spaces but removing # characters - public IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString) + public IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString, IItemFilterScript parentItemFilterScript) { - var itemFilterCommentBlock = new ItemFilterCommentBlock(); + var itemFilterCommentBlock = new ItemFilterCommentBlock(parentItemFilterScript); foreach (var line in new LineReader(() => new StringReader(inputString))) { @@ -47,10 +47,15 @@ namespace Filtration.Parser.Services // This method converts a string into a ItemFilterBlock. This is used for pasting ItemFilterBlocks // and reading ItemFilterScripts from a file. - public IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScriptSettings itemFilterScriptSettings) + public IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScript parentItemFilterScript, bool initialiseBlockGroupHierarchyBuilder = false) { - _masterComponentCollection = itemFilterScriptSettings.ThemeComponentCollection; - var block = new ItemFilterBlock(); + if (initialiseBlockGroupHierarchyBuilder) + { + _blockGroupHierarchyBuilder.Initialise(parentItemFilterScript.ItemFilterBlockGroups.First()); + } + + _masterComponentCollection = parentItemFilterScript.ItemFilterScriptSettings.ThemeComponentCollection; + var block = new ItemFilterBlock(parentItemFilterScript); var showHideFound = false; foreach (var line in new LineReader(() => new StringReader(inputString))) @@ -78,7 +83,7 @@ namespace Filtration.Parser.Services // If block groups are enabled for this script, the comment after Show/Hide is parsed as a block // group hierarchy, if block groups are disabled it is preserved as a simple text comment. - if (itemFilterScriptSettings.BlockGroupsEnabled) + if (parentItemFilterScript.ItemFilterScriptSettings.BlockGroupsEnabled) { AddBlockGroupToBlock(block, trimmedLine); } diff --git a/Filtration.Parser/Services/ItemFilterScriptTranslator.cs b/Filtration.Parser/Services/ItemFilterScriptTranslator.cs index 2e214a3..2c7d8b9 100644 --- a/Filtration.Parser/Services/ItemFilterScriptTranslator.cs +++ b/Filtration.Parser/Services/ItemFilterScriptTranslator.cs @@ -154,11 +154,11 @@ namespace Filtration.Parser.Services if (boundary.Value.BoundaryType == ItemFilterBlockBoundaryType.ItemFilterBlock) { - script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString, script.ItemFilterScriptSettings)); + script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString, script)); } else { - script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterCommentBlock(blockString)); + script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterCommentBlock(blockString, script)); } } diff --git a/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs b/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs index 4f6097a..12a911e 100644 --- a/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs +++ b/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs @@ -6,6 +6,7 @@ using Filtration.ObjectModel.Factories; using Filtration.Repositories; using Filtration.Services; using Filtration.ViewModels; +using Filtration.ViewModels.Factories; using FluentAssertions; using Moq; using NUnit.Framework; diff --git a/Filtration/Filtration.csproj b/Filtration/Filtration.csproj index 52cd482..b0a83bb 100644 --- a/Filtration/Filtration.csproj +++ b/Filtration/Filtration.csproj @@ -184,11 +184,14 @@ - + + + + - - + + @@ -443,6 +446,8 @@ + + diff --git a/Filtration/Repositories/ItemFilterScriptRepository.cs b/Filtration/Repositories/ItemFilterScriptRepository.cs index c50a9b2..2348b2a 100644 --- a/Filtration/Repositories/ItemFilterScriptRepository.cs +++ b/Filtration/Repositories/ItemFilterScriptRepository.cs @@ -3,6 +3,7 @@ using Filtration.ObjectModel; using Filtration.ObjectModel.Factories; using Filtration.Services; using Filtration.ViewModels; +using Filtration.ViewModels.Factories; namespace Filtration.Repositories { diff --git a/Filtration/Resources/Icons/redo_icon.png b/Filtration/Resources/Icons/redo_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8618cdb1e3c8f14652f03f9ea87daacb5469cfaf GIT binary patch literal 579 zcmV-J0=)f+P)ybOTd* ze&w)Q*u^=mJ>1vnq{tU*rNylF>e5O^_n=@f4iSOCi7>JqbUTBlE9LWpy<24fSby|E z_mxzi0Kh0zOKVrNd+A&Tzby}(a|9v5aYGEp9*7ZQA_m*EAjkH$Q0RpaqV8aBgYx%k zdS)T{<=Xm+F1-ltmW6hE*l_*G48aU7l`@2?B8WW9#p7^o2hM0{W|wmM(Ju>vK&31B ztWJ#M;PW@L)j8h!TD!A<5^cHo_L+9UeVNXs5s(jcLB+hT>4_u*05CPFY$miMejN4C z>Df=tE(5^#*SEJFIl3|E4ZtY|4?Yl!;2{J6h& z55tRqvF}4LJ^^?EGaMPfasA4)-PH#lbww!k%;H6Z#W@s4V2r?N5SjRCB_SzG)3yw7QNtZQ#@Hb(+>cO=pk1O3##F#5Vpl_*Z~6^vcJ!G`SF~ zGXc8qi>52(4uG380RSM3!tDq!mhQeYW&*U|6ii~YMMO_$adE2U`}O~R+U57o-u05U=~Rr}=kNNQy6Rt&-$s4fkFn>l#_Td_+@-(jaF*O+i`rL%-iD#z zS$xwrV$4r^+MTlFVT9Mn)$kYh`I`U$0FX&UK~xx(U5(okf-nq3lU}H$6hXX$Vyi9X z|9{X(pX$yelRcAcfWc3LODQee?5X!LMk#jB&=bH9d$(RRf|HO4x)4WenmXx@^S}Uo zE$T+n7540<9`QDJVZ?GARw1rSpw(P-r!;63p^Zf@x$W lxZg^Dz5FelPo;+=)fcW|2lh8{Ir;zq002ovPDHLkV1jEgqMQH# literal 0 HcmV?d00001 diff --git a/Filtration/ViewModels/IItemFilterBlockViewModelFactory.cs b/Filtration/ViewModels/Factories/IItemFilterBlockViewModelFactory.cs similarity index 80% rename from Filtration/ViewModels/IItemFilterBlockViewModelFactory.cs rename to Filtration/ViewModels/Factories/IItemFilterBlockViewModelFactory.cs index 349fd9b..9c43c78 100644 --- a/Filtration/ViewModels/IItemFilterBlockViewModelFactory.cs +++ b/Filtration/ViewModels/Factories/IItemFilterBlockViewModelFactory.cs @@ -1,4 +1,4 @@ -namespace Filtration.ViewModels +namespace Filtration.ViewModels.Factories { internal interface IItemFilterBlockViewModelFactory { diff --git a/Filtration/ViewModels/IItemFilterCommentBlockViewModelFactory.cs b/Filtration/ViewModels/Factories/IItemFilterCommentBlockViewModelFactory.cs similarity index 82% rename from Filtration/ViewModels/IItemFilterCommentBlockViewModelFactory.cs rename to Filtration/ViewModels/Factories/IItemFilterCommentBlockViewModelFactory.cs index 2323baf..947fd52 100644 --- a/Filtration/ViewModels/IItemFilterCommentBlockViewModelFactory.cs +++ b/Filtration/ViewModels/Factories/IItemFilterCommentBlockViewModelFactory.cs @@ -1,4 +1,4 @@ -namespace Filtration.ViewModels +namespace Filtration.ViewModels.Factories { internal interface IItemFilterCommentBlockViewModelFactory { diff --git a/Filtration/ViewModels/IItemFilterScriptViewModelFactory.cs b/Filtration/ViewModels/Factories/IItemFilterScriptViewModelFactory.cs similarity index 81% rename from Filtration/ViewModels/IItemFilterScriptViewModelFactory.cs rename to Filtration/ViewModels/Factories/IItemFilterScriptViewModelFactory.cs index f488b44..ddb0fd4 100644 --- a/Filtration/ViewModels/IItemFilterScriptViewModelFactory.cs +++ b/Filtration/ViewModels/Factories/IItemFilterScriptViewModelFactory.cs @@ -1,4 +1,4 @@ -namespace Filtration.ViewModels +namespace Filtration.ViewModels.Factories { internal interface IItemFilterScriptViewModelFactory { diff --git a/Filtration/ViewModels/Factories/ItemFilterBlockBaseViewModelFactory.cs b/Filtration/ViewModels/Factories/ItemFilterBlockBaseViewModelFactory.cs new file mode 100644 index 0000000..6e55a3d --- /dev/null +++ b/Filtration/ViewModels/Factories/ItemFilterBlockBaseViewModelFactory.cs @@ -0,0 +1,37 @@ +using System; +using Filtration.ObjectModel; + +namespace Filtration.ViewModels.Factories +{ + internal interface IItemFilterBlockBaseViewModelFactory + { + IItemFilterBlockViewModelBase Create(IItemFilterBlockBase itemFilterBlockBase); + } + + internal class ItemFilterBlockBaseViewModelFactory : IItemFilterBlockBaseViewModelFactory + { + private readonly IItemFilterBlockViewModelFactory _itemFilterBlockViewModelFactory; + private readonly IItemFilterCommentBlockViewModelFactory _itemFilterCommentBlockViewModelFactory; + + public ItemFilterBlockBaseViewModelFactory(IItemFilterBlockViewModelFactory itemFilterBlockViewModelFactory, + IItemFilterCommentBlockViewModelFactory itemFilterCommentBlockViewModelFactory) + { + _itemFilterBlockViewModelFactory = itemFilterBlockViewModelFactory; + _itemFilterCommentBlockViewModelFactory = itemFilterCommentBlockViewModelFactory; + } + + public IItemFilterBlockViewModelBase Create(IItemFilterBlockBase itemFilterBlockBase) + { + if (itemFilterBlockBase is IItemFilterBlock) + { + return _itemFilterBlockViewModelFactory.Create(); + } + if (itemFilterBlockBase is IItemFilterCommentBlock) + { + return _itemFilterCommentBlockViewModelFactory.Create(); + } + + throw new InvalidOperationException("Unknown IItemFilterBlockBase type"); + } + } +} diff --git a/Filtration/ViewModels/ItemFilterBlockViewModel.cs b/Filtration/ViewModels/ItemFilterBlockViewModel.cs index a009579..0a6c205 100644 --- a/Filtration/ViewModels/ItemFilterBlockViewModel.cs +++ b/Filtration/ViewModels/ItemFilterBlockViewModel.cs @@ -9,7 +9,6 @@ using Filtration.ObjectModel.BlockItemBaseTypes; using Filtration.ObjectModel.BlockItemTypes; using Filtration.Services; using Filtration.Views; -using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.CommandWpf; using Xceed.Wpf.Toolkit; @@ -17,7 +16,6 @@ namespace Filtration.ViewModels { internal interface IItemFilterBlockViewModel : IItemFilterBlockViewModelBase { - void Initialise(IItemFilterBlock itemFilterBlock, ItemFilterScriptViewModel parentScriptViewModel); bool IsExpanded { get; set; } IItemFilterBlock Block { get; } bool BlockEnabled { get; set; } @@ -25,72 +23,12 @@ namespace Filtration.ViewModels void RefreshBlockPreview(); } - internal interface IItemFilterBlockViewModelBase - { - IItemFilterBlockBase BaseBlock { get; } - bool IsDirty { get; set; } - event EventHandler BlockBecameDirty; - } - - internal abstract class ItemFilterBlockViewModelBase : ViewModelBase, IItemFilterBlockViewModelBase - { - private bool _isDirty; - - protected void Initialise(IItemFilterBlockBase itemfilterBlock) - { - BaseBlock = itemfilterBlock; - } - - - public event EventHandler BlockBecameDirty; - - public IItemFilterBlockBase BaseBlock { get; protected set; } - - public bool IsDirty - { - get => _isDirty; - set - { - if (value != _isDirty) - { - _isDirty = value; - RaisePropertyChanged(); - BlockBecameDirty?.Invoke(this, EventArgs.Empty); - } - } - } - } - - internal interface IItemFilterCommentBlockViewModel : IItemFilterBlockViewModelBase - { - void Initialise(IItemFilterCommentBlock itemFilterCommentBlock); - IItemFilterCommentBlock ItemFilterCommentBlock { get; } - string Comment { get; } - } - - internal class ItemFilterCommentBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterCommentBlockViewModel - { - public ItemFilterCommentBlockViewModel() - { - } - - public void Initialise(IItemFilterCommentBlock itemFilterCommentBlock) - { - ItemFilterCommentBlock = itemFilterCommentBlock; - BaseBlock = itemFilterCommentBlock; - } - - public IItemFilterCommentBlock ItemFilterCommentBlock { get; private set; } - - public string Comment => ItemFilterCommentBlock.Comment; - } - internal class ItemFilterBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterBlockViewModel { private readonly IStaticDataService _staticDataService; private readonly IReplaceColorsViewModel _replaceColorsViewModel; private readonly MediaPlayer _mediaPlayer = new MediaPlayer(); - private ItemFilterScriptViewModel _parentScriptViewModel; + private IItemFilterScriptViewModel _parentScriptViewModel; private bool _displaySettingsPopupOpen; private bool _isExpanded; @@ -120,8 +58,9 @@ namespace Filtration.ViewModels PlaySoundCommand = new RelayCommand(OnPlaySoundCommand, () => HasSound); } - public void Initialise(IItemFilterBlock itemFilterBlock, ItemFilterScriptViewModel parentScriptViewModel) + public override void Initialise(IItemFilterBlockBase itemFilterBlockBase, IItemFilterScriptViewModel parentScriptViewModel) { + var itemFilterBlock = itemFilterBlockBase as IItemFilterBlock; if (itemFilterBlock == null || parentScriptViewModel == null) { throw new ArgumentNullException(nameof(itemFilterBlock)); @@ -139,7 +78,7 @@ namespace Filtration.ViewModels } - base.Initialise(itemFilterBlock); + base.Initialise(itemFilterBlock, parentScriptViewModel); } public RelayCommand CopyBlockCommand { get; } @@ -350,7 +289,7 @@ namespace Filtration.ViewModels private void OnAddSectionCommand() { - _parentScriptViewModel.AddSection(this); + _parentScriptViewModel.AddCommentBlock(this); } private void OnDeleteBlockCommand() diff --git a/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs b/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs new file mode 100644 index 0000000..347da48 --- /dev/null +++ b/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs @@ -0,0 +1,42 @@ +using System; +using Filtration.ObjectModel; +using GalaSoft.MvvmLight; + +namespace Filtration.ViewModels +{ + internal interface IItemFilterBlockViewModelBase + { + void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel); + IItemFilterBlockBase BaseBlock { get; } + bool IsDirty { get; set; } + event EventHandler BlockBecameDirty; + } + + internal abstract class ItemFilterBlockViewModelBase : ViewModelBase, IItemFilterBlockViewModelBase + { + private bool _isDirty; + + public virtual void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel) + { + BaseBlock = itemfilterBlock; + } + + public event EventHandler BlockBecameDirty; + + public IItemFilterBlockBase BaseBlock { get; protected set; } + + public bool IsDirty + { + get => _isDirty; + set + { + if (value != _isDirty) + { + _isDirty = value; + RaisePropertyChanged(); + BlockBecameDirty?.Invoke(this, EventArgs.Empty); + } + } + } + } +} \ No newline at end of file diff --git a/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs b/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs new file mode 100644 index 0000000..84b292c --- /dev/null +++ b/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs @@ -0,0 +1,29 @@ +using Filtration.ObjectModel; + +namespace Filtration.ViewModels +{ + internal interface IItemFilterCommentBlockViewModel : IItemFilterBlockViewModelBase + { + IItemFilterCommentBlock ItemFilterCommentBlock { get; } + string Comment { get; } + } + + internal class ItemFilterCommentBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterCommentBlockViewModel + { + public ItemFilterCommentBlockViewModel() + { + } + + public override void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel) + { + ItemFilterCommentBlock = itemfilterBlock as IItemFilterCommentBlock; + BaseBlock = ItemFilterCommentBlock; + + base.Initialise(itemfilterBlock, itemFilterScriptViewModel); + } + + public IItemFilterCommentBlock ItemFilterCommentBlock { get; private set; } + + public string Comment => ItemFilterCommentBlock.Comment; + } +} \ No newline at end of file diff --git a/Filtration/ViewModels/ItemFilterScriptViewModel.cs b/Filtration/ViewModels/ItemFilterScriptViewModel.cs index 1435f70..e76f10f 100644 --- a/Filtration/ViewModels/ItemFilterScriptViewModel.cs +++ b/Filtration/ViewModels/ItemFilterScriptViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.IO; @@ -15,8 +16,11 @@ using Filtration.Common.ViewModels; using Filtration.Interface; using Filtration.ObjectModel; using Filtration.ObjectModel.BlockItemBaseTypes; +using Filtration.ObjectModel.Commands; +using Filtration.ObjectModel.Commands.ItemFilterScript; using Filtration.Parser.Interface.Services; using Filtration.Services; +using Filtration.ViewModels.Factories; using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.Messaging; using NLog; @@ -59,21 +63,25 @@ namespace Filtration.ViewModels RelayCommand ToggleShowAdvancedCommand { get; } RelayCommand ClearFilterCommand { get; } - void AddSection(IItemFilterBlockViewModelBase targetBlockViewModel); + void AddCommentBlock(IItemFilterBlockViewModelBase targetBlockViewModel); void AddBlock(IItemFilterBlockViewModelBase targetBlockViewModel); void CopyBlock(IItemFilterBlockViewModelBase targetBlockViewModel); void CopyBlockStyle(IItemFilterBlockViewModel targetBlockViewModel); void PasteBlock(IItemFilterBlockViewModelBase targetBlockViewModel); void PasteBlockStyle(IItemFilterBlockViewModel targetBlockViewModel); + void DeleteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase); + void MoveBlockToTop(IItemFilterBlockViewModelBase targetBlockViewModelBase); + void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase); + void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase); + void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase); } internal class ItemFilterScriptViewModel : PaneViewModel, IItemFilterScriptViewModel { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - private readonly IItemFilterBlockViewModelFactory _itemFilterBlockViewModelFactory; + private readonly IItemFilterBlockBaseViewModelFactory _itemFilterBlockBaseViewModelFactory; private readonly IItemFilterBlockTranslator _blockTranslator; - private readonly IItemFilterCommentBlockViewModelFactory _itemFilterCommentBlockViewModelFactory; private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel; private readonly IItemFilterPersistenceService _persistenceService; private readonly IMessageBoxService _messageBoxService; @@ -86,19 +94,18 @@ namespace Filtration.ViewModels private readonly ObservableCollection _itemFilterBlockViewModels; private ICollectionView _itemFilterBlockViewModelsCollectionView; private Predicate _blockFilterPredicate; + private ICommandManager _scriptCommandManager; - public ItemFilterScriptViewModel(IItemFilterBlockViewModelFactory itemFilterBlockViewModelFactory, + public ItemFilterScriptViewModel(IItemFilterBlockBaseViewModelFactory itemFilterBlockBaseViewModelFactory, IItemFilterBlockTranslator blockTranslator, - IItemFilterCommentBlockViewModelFactory itemFilterCommentBlockViewModelFactory, IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel, IItemFilterPersistenceService persistenceService, IMessageBoxService messageBoxService, IClipboardService clipboardService, IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder) { - _itemFilterBlockViewModelFactory = itemFilterBlockViewModelFactory; + _itemFilterBlockBaseViewModelFactory = itemFilterBlockBaseViewModelFactory; _blockTranslator = blockTranslator; - _itemFilterCommentBlockViewModelFactory = itemFilterCommentBlockViewModelFactory; _avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel; _avalonDockWorkspaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged; _persistenceService = persistenceService; @@ -116,12 +123,12 @@ namespace Filtration.ViewModels ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null); CloseCommand = new RelayCommand(async () => await OnCloseCommand()); DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null); - MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null); - MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null); - MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => SelectedBlockViewModel != null); - MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => SelectedBlockViewModel != null); + MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) > 0); + MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) > 0); + MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) < ItemFilterBlockViewModels.Count); + MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) < ItemFilterBlockViewModels.Count); AddBlockCommand = new RelayCommand(OnAddBlockCommand); - AddSectionCommand = new RelayCommand(OnAddSectionCommand, () => SelectedBlockViewModel != null); + AddSectionCommand = new RelayCommand(OnAddCommentBlockCommand, () => SelectedBlockViewModel != null); DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, HasSelectedEnabledBlock); EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, HasSelectedDisabledBlock); CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null); @@ -138,6 +145,94 @@ namespace Filtration.ViewModels IconSource = icon; } + public void Initialise(IItemFilterScript itemFilterScript, bool newScript) + { + ItemFilterBlockViewModels.Clear(); + + Script = itemFilterScript; + _scriptCommandManager = Script.CommandManager; + AddItemFilterBlockViewModels(Script.ItemFilterBlocks, -1); + + Script.ItemFilterBlocks.CollectionChanged += ItemFilterBlocksOnCollectionChanged; + + _filenameIsFake = newScript; + + if (newScript) + { + Script.FilePath = "Untitled.filter"; + } + + Title = Filename; + ContentId = "ScriptContentId"; + } + + private void ItemFilterBlocksOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) + { + switch (notifyCollectionChangedEventArgs.Action) + { + case NotifyCollectionChangedAction.Add: + { + AddItemFilterBlockViewModels(notifyCollectionChangedEventArgs.NewItems.Cast(), notifyCollectionChangedEventArgs.NewStartingIndex); + break; + } + case NotifyCollectionChangedAction.Remove: + { + RemoveItemFilterBlockviewModels(notifyCollectionChangedEventArgs.OldItems.Cast()); + break; + } + default: + { + Debugger.Break(); // Unhandled NotifyCollectionChangedAction + break; + } + } + } + + private void AddItemFilterBlockViewModels(IEnumerable itemFilterBlocks, int addAtIndex) + { + var firstNewViewModel = true; + + foreach (var itemFilterBlock in itemFilterBlocks) + { + var vm = _itemFilterBlockBaseViewModelFactory.Create(itemFilterBlock); + vm.Initialise(itemFilterBlock, this); + vm.BlockBecameDirty += OnBlockBecameDirty; + + if (addAtIndex == -1) + { + ItemFilterBlockViewModels.Add(vm); + } + else + { + ItemFilterBlockViewModels.Insert(addAtIndex, vm); + } + + if (firstNewViewModel) + { + SelectedBlockViewModel = vm; + firstNewViewModel = false; + } + } + } + + private void RemoveItemFilterBlockviewModels(IEnumerable itemFilterBlocks) + { + foreach (var itemFilterBlock in itemFilterBlocks) + { + var itemFilterBlockViewModel = ItemFilterBlockViewModels.FirstOrDefault(f => f.BaseBlock == itemFilterBlock); + if (itemFilterBlockViewModel == null) + { + throw new InvalidOperationException("Item Filter Block removed from model but does not exist in view model!"); + } + + ItemFilterBlockViewModels.Remove(itemFilterBlockViewModel); + if (SelectedBlockViewModel == itemFilterBlockViewModel) + { + SelectedBlockViewModel = null; + } + } + } + public RelayCommand ToggleShowAdvancedCommand { get; } public RelayCommand ClearFilterCommand { get; } public RelayCommand CloseCommand { get; } @@ -229,12 +324,7 @@ namespace Filtration.ViewModels public string Description { get => Script.Description; - set - { - Script.Description = value; - IsDirty = true; - RaisePropertyChanged(); - } + set => _scriptCommandManager.ExecuteCommand(new SetScriptDescriptionCommand(Script, value)); } public bool ShowAdvanced @@ -340,54 +430,7 @@ namespace Filtration.ViewModels private bool _filenameIsFake; private bool _showAdvanced; - - public void Initialise(IItemFilterScript itemFilterScript, bool newScript) - { - ItemFilterBlockViewModels.Clear(); - - Script = itemFilterScript; - - foreach (var block in Script.ItemFilterBlocks) - { - var itemFilterBlock = block as IItemFilterBlock; - if (itemFilterBlock != null) - { - var itemFilterBlockViewModel = _itemFilterBlockViewModelFactory.Create(); - itemFilterBlockViewModel.Initialise(itemFilterBlock, this); - itemFilterBlockViewModel.BlockBecameDirty += OnBlockBecameDirty; - ItemFilterBlockViewModels.Add(itemFilterBlockViewModel); - continue; - } - - var itemFilterCommentBlock = block as IItemFilterCommentBlock; - if (itemFilterCommentBlock == null) - { - throw new InvalidOperationException("Unknown item filter block type"); - } - - - var itemFilterCommentBlockViewModel = _itemFilterCommentBlockViewModelFactory.Create(); - itemFilterCommentBlockViewModel.Initialise(itemFilterCommentBlock); - itemFilterCommentBlockViewModel.BlockBecameDirty += OnBlockBecameDirty; - ItemFilterBlockViewModels.Add(itemFilterCommentBlockViewModel); - } - - _filenameIsFake = newScript; - - if (newScript) - { - Script.FilePath = "Untitled.filter"; - } - - if (ItemFilterBlockViewModels.Count > 0) - { - SelectedBlockViewModel = ItemFilterBlockViewModels.First(); - } - - Title = Filename; - ContentId = "ScriptContentId"; - } - + public async Task SaveAsync() { if (!ValidateScript()) return; @@ -602,8 +645,7 @@ namespace Filtration.ViewModels } catch { - _messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.", - MessageBoxButton.OK, MessageBoxImage.Error); + _messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.", MessageBoxButton.OK, MessageBoxImage.Error); } } @@ -671,39 +713,18 @@ namespace Filtration.ViewModels { var clipboardText = _clipboardService.GetClipboardText(); if (string.IsNullOrEmpty(clipboardText)) return; - _blockGroupHierarchyBuilder.Initialise(Script.ItemFilterBlockGroups.First()); - - var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script.ItemFilterScriptSettings); + + var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script, true); // TODO: Doesn't handle pasting comment blocks? if (translatedBlock == null) return; - var vm = _itemFilterBlockViewModelFactory.Create(); - vm.Initialise(translatedBlock, this); - - if (ItemFilterBlockViewModels.Count > 0) - { - Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModelBase.BaseBlock) + 1, - translatedBlock); - ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase) + 1, vm); - } - else - { - Script.ItemFilterBlocks.Add(translatedBlock); - ItemFilterBlockViewModels.Add(vm); - } - - vm.BlockBecameDirty += OnBlockBecameDirty; - - SelectedBlockViewModel = vm; - IsDirty = true; + _scriptCommandManager.ExecuteCommand(new PasteBlockCommand(Script, translatedBlock, targetBlockViewModelBase.BaseBlock)); } catch (Exception e) { Logger.Error(e); var innerException = e.InnerException?.Message ?? string.Empty; - _messageBoxService.Show("Paste Error", - e.Message + Environment.NewLine + innerException, MessageBoxButton.OK, - MessageBoxImage.Error); + _messageBoxService.Show("Paste Error", e.Message + Environment.NewLine + innerException, MessageBoxButton.OK, MessageBoxImage.Error); } } @@ -712,21 +733,6 @@ namespace Filtration.ViewModels MoveBlockToTop(SelectedBlockViewModel); } - public void MoveBlockToTop(IItemFilterBlockViewModelBase targetBlockViewModelBase) - { - var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); - - if (currentIndex > 0) - { - var block = targetBlockViewModelBase.BaseBlock; - Script.ItemFilterBlocks.Remove(block); - Script.ItemFilterBlocks.Insert(0, block); - ItemFilterBlockViewModels.Move(currentIndex, 0); - IsDirty = true; - RaisePropertyChanged(nameof(ItemFilterCommentBlockViewModels)); - } - } - private void OnMoveBlockUpCommand() { MoveBlockUp(SelectedBlockViewModel); @@ -734,18 +740,7 @@ namespace Filtration.ViewModels public void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase) { - var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); - - if (currentIndex > 0) - { - var block = targetBlockViewModelBase.BaseBlock; - var blockPos = Script.ItemFilterBlocks.IndexOf(block); - Script.ItemFilterBlocks.RemoveAt(blockPos); - Script.ItemFilterBlocks.Insert(blockPos - 1, block); - ItemFilterBlockViewModels.Move(currentIndex, currentIndex - 1); - IsDirty = true; - RaisePropertyChanged(nameof(ItemFilterCommentBlockViewModels)); - } + _scriptCommandManager.ExecuteCommand(new MoveBlockUpCommand(Script, targetBlockViewModelBase?.BaseBlock)); } private void OnMoveBlockDownCommand() @@ -755,18 +750,7 @@ namespace Filtration.ViewModels public void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase) { - var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); - - if (currentIndex < ItemFilterBlockViewModels.Count - 1) - { - var block = targetBlockViewModelBase.BaseBlock; - var blockPos = Script.ItemFilterBlocks.IndexOf(block); - Script.ItemFilterBlocks.RemoveAt(blockPos); - Script.ItemFilterBlocks.Insert(blockPos + 1, block); - ItemFilterBlockViewModels.Move(currentIndex, currentIndex + 1); - IsDirty = true; - RaisePropertyChanged(nameof(ItemFilterCommentBlockViewModels)); - } + _scriptCommandManager.ExecuteCommand(new MoveBlockDownCommand(Script, targetBlockViewModelBase?.BaseBlock)); } private void OnMoveBlockToBottomCommand() @@ -774,21 +758,6 @@ namespace Filtration.ViewModels MoveBlockToBottom(SelectedBlockViewModel); } - public void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase) - { - var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase); - - if (currentIndex < ItemFilterBlockViewModels.Count - 1) - { - var block = targetBlockViewModelBase.BaseBlock; - Script.ItemFilterBlocks.Remove(block); - Script.ItemFilterBlocks.Add(block); - ItemFilterBlockViewModels.Move(currentIndex, ItemFilterBlockViewModels.Count - 1); - IsDirty = true; - RaisePropertyChanged(nameof(ItemFilterCommentBlockViewModels)); - } - } - private void OnAddBlockCommand() { AddBlock(SelectedBlockViewModel); @@ -796,25 +765,28 @@ namespace Filtration.ViewModels public void AddBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase) { - var vm = _itemFilterBlockViewModelFactory.Create(); - var newBlock = new ItemFilterBlock(); - vm.Initialise(newBlock, this); + _scriptCommandManager.ExecuteCommand(new AddBlockCommand(Script, targetBlockViewModelBase?.BaseBlock)); + // TODO: Expand new viewmodel + } - if (targetBlockViewModelBase != null) - { - Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModelBase.BaseBlock) + 1, newBlock); - ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase) + 1, vm); - } - else - { - Script.ItemFilterBlocks.Add(newBlock); - ItemFilterBlockViewModels.Add(vm); - } + public void AddCommentBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase) + { + _scriptCommandManager.ExecuteCommand(new AddCommentBlockCommand(Script, targetBlockViewModelBase.BaseBlock)); + } - vm.BlockBecameDirty += OnBlockBecameDirty; - SelectedBlockViewModel = vm; - vm.IsExpanded = true; - IsDirty = true; + public void DeleteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase) + { + _scriptCommandManager.ExecuteCommand(new RemoveBlockCommand(Script, targetBlockViewModelBase.BaseBlock)); + } + + public void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase) + { + _scriptCommandManager.ExecuteCommand(new MoveBlockToBottomCommand(Script, targetBlockViewModelBase.BaseBlock)); + } + + public void MoveBlockToTop(IItemFilterBlockViewModelBase targetBlockViewModelBase) + { + _scriptCommandManager.ExecuteCommand(new MoveBlockToTopCommand(Script, targetBlockViewModelBase.BaseBlock)); } private void OnBlockBecameDirty(object sender, EventArgs e) @@ -822,23 +794,9 @@ namespace Filtration.ViewModels SetDirtyFlag(); } - private void OnAddSectionCommand() + private void OnAddCommentBlockCommand() { - AddSection(SelectedBlockViewModel); - } - - public void AddSection(IItemFilterBlockViewModelBase targetBlockViewModelBase) - { - var vm = _itemFilterCommentBlockViewModelFactory.Create(); - var newSection = new ItemFilterCommentBlock { Comment = "New Comment Block" }; - vm.Initialise(newSection); - - Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModelBase.BaseBlock), newSection); - ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase), vm); - IsDirty = true; - SelectedBlockViewModel = vm; - RaisePropertyChanged(nameof(ItemFilterCommentBlockViewModels)); - Messenger.Default.Send(new NotificationMessage("SectionsChanged")); + AddCommentBlock(SelectedBlockViewModel); } private void OnExpandAllBlocksCommand() @@ -862,31 +820,6 @@ namespace Filtration.ViewModels DeleteBlock(SelectedBlockViewModel); } - public void DeleteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase) - { - var result = _messageBoxService.Show("Delete Confirmation", "Are you sure you wish to delete this block?", - MessageBoxButton.YesNo, - MessageBoxImage.Question); - - if (result == MessageBoxResult.Yes) - { - var isSection = targetBlockViewModelBase.BaseBlock is ItemFilterCommentBlock; - - Script.ItemFilterBlocks.Remove(targetBlockViewModelBase.BaseBlock); - ItemFilterBlockViewModels.Remove(targetBlockViewModelBase); - IsDirty = true; - - targetBlockViewModelBase.BlockBecameDirty -= OnBlockBecameDirty; - - if (isSection) - { - Messenger.Default.Send(new NotificationMessage("SectionsChanged")); - } - - } - SelectedBlockViewModel = null; - } - private void OnDisableBlockCommand() { var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel; diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs index 962fa9b..105851d 100644 --- a/Filtration/ViewModels/MainWindowViewModel.cs +++ b/Filtration/ViewModels/MainWindowViewModel.cs @@ -85,6 +85,11 @@ namespace Filtration.ViewModels PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); PasteBlockStyleCommand = new RelayCommand(OnPasteBlockStyleCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); + // TODO: Only enabled if undo/redo available + UndoCommand = new RelayCommand(OnUndoCommand, () => ActiveDocumentIsScript); + RedoCommand = new RelayCommand(OnRedoCommand, () => ActiveDocumentIsScript); + + MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); @@ -158,9 +163,7 @@ namespace Filtration.ViewModels } case "OpenScript": { -#pragma warning disable 4014 - Task.Run(OnOpenScriptCommand).GetAwaiter().GetResult(); -#pragma warning restore 4014 + OnOpenScriptCommand(); break; } case "ShowLoadingBanner": @@ -191,6 +194,9 @@ namespace Filtration.ViewModels public RelayCommand OpenAboutWindowCommand { get; } public RelayCommand ReplaceColorsCommand { get; } + public RelayCommand UndoCommand { get;} + public RelayCommand RedoCommand { get; } + public RelayCommand EditMasterThemeCommand { get; } public RelayCommand CreateThemeCommand { get; } public RelayCommand ApplyThemeToScriptCommand { get; } @@ -521,6 +527,16 @@ namespace Filtration.ViewModels _avalonDockWorkspaceViewModel.ActiveScriptViewModel.PasteBlockStyleCommand.Execute(null); } + private void OnUndoCommand() + { + _avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.CommandManager.Undo(); + } + + private void OnRedoCommand() + { + _avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.CommandManager.Redo(); + } + private void OnNewScriptCommand() { var newViewModel = _itemFilterScriptRepository.NewScript(); diff --git a/Filtration/Views/IconsDictionary.xaml b/Filtration/Views/IconsDictionary.xaml index 281fa83..e3e426c 100644 --- a/Filtration/Views/IconsDictionary.xaml +++ b/Filtration/Views/IconsDictionary.xaml @@ -30,6 +30,8 @@ + + diff --git a/Filtration/Views/MainWindow.xaml b/Filtration/Views/MainWindow.xaml index 6e57bfe..e914d0d 100644 --- a/Filtration/Views/MainWindow.xaml +++ b/Filtration/Views/MainWindow.xaml @@ -19,6 +19,10 @@ + + + @@ -32,7 +36,7 @@ - Recent Documents will go here in a future release. + Recent Documents will go here in a future release. @@ -85,6 +89,12 @@ + + + diff --git a/Filtration/WindsorInstallers/ViewModelsInstaller.cs b/Filtration/WindsorInstallers/ViewModelsInstaller.cs index 14d2c55..30afd6e 100644 --- a/Filtration/WindsorInstallers/ViewModelsInstaller.cs +++ b/Filtration/WindsorInstallers/ViewModelsInstaller.cs @@ -3,6 +3,7 @@ using Castle.MicroKernel.Registration; using Castle.MicroKernel.SubSystems.Configuration; using Castle.Windsor; using Filtration.ViewModels; +using Filtration.ViewModels.Factories; using Filtration.ViewModels.ToolPanes; namespace Filtration.WindsorInstallers @@ -79,6 +80,11 @@ namespace Filtration.WindsorInstallers container.Register( Component.For().AsFactory()); + + container.Register( + Component.For() + .ImplementedBy() + .LifeStyle.Singleton); } } }