diff --git a/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs b/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs index 17274f8..2a20555 100644 --- a/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs +++ b/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs @@ -6,6 +6,7 @@ using Filtration.ItemFilterPreview.Tests.Properties; using Filtration.ObjectModel; using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.Enums; +using Filtration.ObjectModel.Factories; using Filtration.Parser.Services; using Moq; using NUnit.Framework; @@ -71,7 +72,12 @@ namespace Filtration.ItemFilterPreview.Tests.Services //Arrange var testInputScriptFile = Resources.MuldiniFilterScript; var blockGroupHierarchyBuilder = new BlockGroupHierarchyBuilder(); - var scriptTranslator = new ItemFilterScriptTranslator(new ItemFilterBlockTranslator(blockGroupHierarchyBuilder), blockGroupHierarchyBuilder); + var mockItemFilterScriptFactory = new Mock<IItemFilterScriptFactory>(); + mockItemFilterScriptFactory + .Setup(i => i.Create()) + .Returns(new ItemFilterScript()); + + var scriptTranslator = new ItemFilterScriptTranslator(blockGroupHierarchyBuilder, new ItemFilterBlockTranslator(blockGroupHierarchyBuilder), mockItemFilterScriptFactory.Object); var script = scriptTranslator.TranslateStringToItemFilterScript(testInputScriptFile); var testInputItem = new Item @@ -101,7 +107,11 @@ namespace Filtration.ItemFilterPreview.Tests.Services //Arrange var testInputScriptFile = Resources.MuldiniFilterScript; var blockGroupHierarchyBuilder = new BlockGroupHierarchyBuilder(); - var scriptTranslator = new ItemFilterScriptTranslator(new ItemFilterBlockTranslator(blockGroupHierarchyBuilder), blockGroupHierarchyBuilder); + var mockItemFilterScriptFactory = new Mock<IItemFilterScriptFactory>(); + mockItemFilterScriptFactory + .Setup(i => i.Create()) + .Returns(new ItemFilterScript()); + var scriptTranslator = new ItemFilterScriptTranslator(blockGroupHierarchyBuilder, new ItemFilterBlockTranslator(blockGroupHierarchyBuilder), mockItemFilterScriptFactory.Object); var script = scriptTranslator.TranslateStringToItemFilterScript(testInputScriptFile); var testInputItems = new List<IItem> diff --git a/Filtration.ObjectModel/Commands/CommandManager.cs b/Filtration.ObjectModel/Commands/CommandManager.cs new file mode 100644 index 0000000..e8dc6f7 --- /dev/null +++ b/Filtration.ObjectModel/Commands/CommandManager.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; + +namespace Filtration.ObjectModel.Commands +{ + public interface ICommandManager + { + void ExecuteCommand(ICommand command); + void Undo(int undoLevels = 1); + void Redo(int redoLevels = 1); + } + + public interface ICommandManagerInternal : ICommandManager + { + void SetScript(IItemFilterScriptInternal layout); + } + + internal class CommandManager : ICommandManagerInternal + { + private readonly Stack<IUndoableCommand> _undoCommandStack = new Stack<IUndoableCommand>(); + private readonly Stack<IUndoableCommand> _redoCommandStack = new Stack<IUndoableCommand>(); + private IItemFilterScriptInternal _itemFilterScript; + + public void SetScript(IItemFilterScriptInternal itemFilterScript) + { + _itemFilterScript = itemFilterScript; + } + + public void ExecuteCommand(ICommand command) + { + command.Execute(); + var undoableCommand = command as IUndoableCommand; + if (undoableCommand != null) + { + _undoCommandStack.Push(undoableCommand); + _redoCommandStack.Clear(); + } + _itemFilterScript.SetIsDirty(true); + } + + public void Undo(int undoLevels = 1) + { + for (var index = undoLevels; _undoCommandStack.Count > 0 && index > 0; --index) + { + var undoableCommand = _undoCommandStack.Pop(); + undoableCommand.Undo(); + _redoCommandStack.Push(undoableCommand); + } + _itemFilterScript.SetIsDirty(true); + } + + public void Redo(int redoLevels = 1) + { + for (int index = redoLevels; _redoCommandStack.Count > 0 && index > 0; --index) + { + var undoableCommand = _redoCommandStack.Pop(); + undoableCommand.Redo(); + _undoCommandStack.Push(undoableCommand); + } + _itemFilterScript.SetIsDirty(true); + } + } +} diff --git a/Filtration.ObjectModel/Commands/ICommand.cs b/Filtration.ObjectModel/Commands/ICommand.cs new file mode 100644 index 0000000..84cfe3c --- /dev/null +++ b/Filtration.ObjectModel/Commands/ICommand.cs @@ -0,0 +1,7 @@ +namespace Filtration.ObjectModel.Commands +{ + public interface ICommand + { + void Execute(); + } +} diff --git a/Filtration.ObjectModel/Commands/IUndoableCommand.cs b/Filtration.ObjectModel/Commands/IUndoableCommand.cs new file mode 100644 index 0000000..9a9eb76 --- /dev/null +++ b/Filtration.ObjectModel/Commands/IUndoableCommand.cs @@ -0,0 +1,8 @@ +namespace Filtration.ObjectModel.Commands +{ + internal interface IUndoableCommand : ICommand + { + void Undo(); + void Redo(); + } +} diff --git a/Filtration.ObjectModel/Factories/IItemFilterScriptFactory.cs b/Filtration.ObjectModel/Factories/IItemFilterScriptFactory.cs new file mode 100644 index 0000000..2a5c0b2 --- /dev/null +++ b/Filtration.ObjectModel/Factories/IItemFilterScriptFactory.cs @@ -0,0 +1,9 @@ +namespace Filtration.ObjectModel.Factories +{ + public interface IItemFilterScriptFactory + { + IItemFilterScript Create(); + + void Release(IItemFilterScript itemFilterScript); + } +} diff --git a/Filtration.ObjectModel/Filtration.ObjectModel.csproj b/Filtration.ObjectModel/Filtration.ObjectModel.csproj index 23e9171..17c34c7 100644 --- a/Filtration.ObjectModel/Filtration.ObjectModel.csproj +++ b/Filtration.ObjectModel/Filtration.ObjectModel.csproj @@ -31,6 +31,12 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> + <Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> + <HintPath>..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll</HintPath> + </Reference> + <Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> + <HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath> + </Reference> <Reference Include="PresentationCore" /> <Reference Include="System" /> <Reference Include="System.ComponentModel.DataAnnotations" /> @@ -68,6 +74,9 @@ <Compile Include="BlockItemTypes\SoundBlockItem.cs" /> <Compile Include="BlockItemTypes\TextColorBlockItem.cs" /> <Compile Include="BlockItemTypes\WidthBlockItem.cs" /> + <Compile Include="Commands\CommandManager.cs" /> + <Compile Include="Commands\ICommand.cs" /> + <Compile Include="Commands\IUndoableCommand.cs" /> <Compile Include="Enums\BlockAction.cs" /> <Compile Include="Enums\BlockItemType.cs" /> <Compile Include="Enums\FilterPredicateOperator.cs" /> @@ -77,6 +86,7 @@ <Compile Include="Enums\ThemeComponentType.cs" /> <Compile Include="Extensions\EnumHelper.cs" /> <Compile Include="Extensions\ItemRarityExtensions.cs" /> + <Compile Include="Factories\IItemFilterScriptFactory.cs" /> <Compile Include="FilteredItem.cs" /> <Compile Include="IAudioVisualBlockItem.cs" /> <Compile Include="IItemFilterBlockItem.cs" /> @@ -97,6 +107,12 @@ <Compile Include="ThemeEditor\Theme.cs" /> <Compile Include="ThemeEditor\ThemeComponent.cs" /> <Compile Include="ThemeEditor\ThemeComponentCollection.cs" /> + <Compile Include="WindsorInstallers\CommandsInstaller.cs" /> + <Compile Include="WindsorInstallers\ModelsInstaller.cs" /> + </ItemGroup> + <ItemGroup /> + <ItemGroup> + <None Include="packages.config" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. diff --git a/Filtration.ObjectModel/ItemFilterScript.cs b/Filtration.ObjectModel/ItemFilterScript.cs index 4938800..9548e51 100644 --- a/Filtration.ObjectModel/ItemFilterScript.cs +++ b/Filtration.ObjectModel/ItemFilterScript.cs @@ -1,39 +1,62 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Linq; +using System.Runtime.CompilerServices; +using Filtration.ObjectModel.Annotations; using Filtration.ObjectModel.BlockItemTypes; +using Filtration.ObjectModel.Commands; using Filtration.ObjectModel.ThemeEditor; namespace Filtration.ObjectModel { - public interface IItemFilterScript + public interface IItemFilterScript : INotifyPropertyChanged { + ICommandManager CommandManager { get; } + ObservableCollection<IItemFilterBlockBase> ItemFilterBlocks { get; } ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; } ThemeComponentCollection ThemeComponents { get; set; } string FilePath { get; set; } string Description { get; set; } DateTime DateModified { get; set; } + bool IsDirty { get; } + IItemFilterScriptSettings ItemFilterScriptSettings { get; } List<string> Validate(); void ReplaceColors(ReplaceColorsParameterSet replaceColorsParameterSet); } - public class ItemFilterScript : IItemFilterScript + public interface IItemFilterScriptInternal : IItemFilterScript { - public ItemFilterScript() + void SetIsDirty(bool isDirty); + } + + public class ItemFilterScript : IItemFilterScriptInternal + { + private bool _isDirty; + + internal ItemFilterScript() { ItemFilterBlocks = new ObservableCollection<IItemFilterBlockBase>(); ItemFilterBlockGroups = new ObservableCollection<ItemFilterBlockGroup> { new ItemFilterBlockGroup("Root", null) }; - ThemeComponents = new ThemeComponentCollection { IsMasterCollection = true}; + ThemeComponents = new ThemeComponentCollection { IsMasterCollection = true }; ItemFilterScriptSettings = new ItemFilterScriptSettings(ThemeComponents); } + public ItemFilterScript(ICommandManagerInternal commandManager) : this() + { + CommandManager = commandManager; + commandManager.SetScript(this); + } + + public ICommandManager CommandManager { get; } + public ObservableCollection<IItemFilterBlockBase> ItemFilterBlocks { get; } public ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; } @@ -45,6 +68,22 @@ namespace Filtration.ObjectModel public string Description { get; set; } public DateTime DateModified { get; set; } + public bool IsDirty + { + get => _isDirty; + private set + { + if (value == _isDirty) return; + _isDirty = value; + OnPropertyChanged(); + } + } + + public void SetIsDirty(bool isDirty) + { + IsDirty = isDirty; + } + public List<string> Validate() { var validationErrors = new List<string>(); @@ -106,5 +145,12 @@ namespace Filtration.ObjectModel return true; } + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } } } diff --git a/Filtration.ObjectModel/Properties/Annotations.cs b/Filtration.ObjectModel/Properties/Annotations.cs index c30d43a..2e7c846 100644 --- a/Filtration.ObjectModel/Properties/Annotations.cs +++ b/Filtration.ObjectModel/Properties/Annotations.cs @@ -1,4 +1,26 @@ -using System; +/* MIT License + +Copyright (c) 2016 JetBrains http://www.jetbrains.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. */ + +using System; #pragma warning disable 1591 // ReSharper disable UnusedMember.Global @@ -7,7 +29,6 @@ // ReSharper disable IntroduceOptionalParameters.Global // ReSharper disable MemberCanBeProtected.Global // ReSharper disable InconsistentNaming -// ReSharper disable CheckNamespace namespace Filtration.ObjectModel.Annotations { @@ -16,32 +37,37 @@ namespace Filtration.ObjectModel.Annotations /// so the check for <c>null</c> is necessary before its usage. /// </summary> /// <example><code> - /// [CanBeNull] public object Test() { return null; } - /// public void UseTest() { + /// [CanBeNull] object Test() => null; + /// + /// void UseTest() { /// var p = Test(); /// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' /// } /// </code></example> [AttributeUsage( AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] + AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)] public sealed class CanBeNullAttribute : Attribute { } /// <summary> /// Indicates that the value of the marked element could never be <c>null</c>. /// </summary> /// <example><code> - /// [NotNull] public object Foo() { + /// [NotNull] object Foo() { /// return null; // Warning: Possible 'null' assignment /// } /// </code></example> [AttributeUsage( AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] + AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)] public sealed class NotNullAttribute : Attribute { } /// <summary> - /// Indicates that collection or enumerable value does not contain null elements. + /// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task + /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property + /// or of the Lazy.Value property can never be null. /// </summary> [AttributeUsage( AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | @@ -49,7 +75,9 @@ namespace Filtration.ObjectModel.Annotations public sealed class ItemNotNullAttribute : Attribute { } /// <summary> - /// Indicates that collection or enumerable value can contain null elements. + /// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task + /// and Lazy classes to indicate that the value of a collection item, of the Task.Result property + /// or of the Lazy.Value property can be null. /// </summary> [AttributeUsage( AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | @@ -63,8 +91,9 @@ namespace Filtration.ObjectModel.Annotations /// </summary> /// <example><code> /// [StringFormatMethod("message")] - /// public void ShowError(string message, params object[] args) { /* do something */ } - /// public void Foo() { + /// void ShowError(string message, params object[] args) { /* do something */ } + /// + /// void Foo() { /// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string /// } /// </code></example> @@ -76,22 +105,24 @@ namespace Filtration.ObjectModel.Annotations /// <param name="formatParameterName"> /// Specifies which parameter of an annotated method should be treated as format-string /// </param> - public StringFormatMethodAttribute(string formatParameterName) + public StringFormatMethodAttribute([NotNull] string formatParameterName) { FormatParameterName = formatParameterName; } - public string FormatParameterName { get; private set; } + [NotNull] public string FormatParameterName { get; private set; } } /// <summary> /// For a parameter that is expected to be one of the limited set of values. /// Specify fields of which type should be used as values for this parameter. /// </summary> - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] + [AttributeUsage( + AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field, + AllowMultiple = true)] public sealed class ValueProviderAttribute : Attribute { - public ValueProviderAttribute(string name) + public ValueProviderAttribute([NotNull] string name) { Name = name; } @@ -105,7 +136,7 @@ namespace Filtration.ObjectModel.Annotations /// the parameter of <see cref="System.ArgumentNullException"/>. /// </summary> /// <example><code> - /// public void Foo(string param) { + /// void Foo(string param) { /// if (param == null) /// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol /// } @@ -131,10 +162,12 @@ namespace Filtration.ObjectModel.Annotations /// <example><code> /// public class Foo : INotifyPropertyChanged { /// public event PropertyChangedEventHandler PropertyChanged; + /// /// [NotifyPropertyChangedInvocator] /// protected virtual void NotifyChanged(string propertyName) { ... } /// - /// private string _name; + /// string _name; + /// /// public string Name { /// get { return _name; } /// set { _name = value; NotifyChanged("LastName"); /* Warning */ } @@ -153,12 +186,12 @@ namespace Filtration.ObjectModel.Annotations public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute { public NotifyPropertyChangedInvocatorAttribute() { } - public NotifyPropertyChangedInvocatorAttribute(string parameterName) + public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName) { ParameterName = parameterName; } - public string ParameterName { get; private set; } + [CanBeNull] public string ParameterName { get; private set; } } /// <summary> @@ -174,15 +207,16 @@ namespace Filtration.ObjectModel.Annotations /// <item>Value ::= true | false | null | notnull | canbenull</item> /// </list> /// If method has single input parameter, it's name could be omitted.<br/> - /// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) - /// for method output means that the methos doesn't return normally.<br/> - /// <c>canbenull</c> annotation is only applicable for output parameters.<br/> - /// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, - /// or use single attribute with rows separated by semicolon.<br/> + /// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) for method output + /// means that the methos doesn't return normally (throws or terminates the process).<br/> + /// Value <c>canbenull</c> is only applicable for output parameters.<br/> + /// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, or use single attribute + /// with rows separated by semicolon. There is no notion of order rows, all rows are checked + /// for applicability and applied per each program state tracked by R# analysis.<br/> /// </syntax> /// <examples><list> /// <item><code> - /// [ContractAnnotation("=> halt")] + /// [ContractAnnotation("=> halt")] /// public void TerminationMethod() /// </code></item> /// <item><code> @@ -190,17 +224,17 @@ namespace Filtration.ObjectModel.Annotations /// public void Assert(bool condition, string text) // regular assertion method /// </code></item> /// <item><code> - /// [ContractAnnotation("s:null => true")] + /// [ContractAnnotation("s:null => true")] /// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty() /// </code></item> /// <item><code> /// // A method that returns null if the parameter is null, /// // and not null if the parameter is not null - /// [ContractAnnotation("null => null; notnull => notnull")] + /// [ContractAnnotation("null => null; notnull => notnull")] /// public object Transform(object data) /// </code></item> /// <item><code> - /// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] + /// [ContractAnnotation("=> true, result: notnull; => false, result: null")] /// public bool TryParse(string s, out Person result) /// </code></item> /// </list></examples> @@ -216,7 +250,8 @@ namespace Filtration.ObjectModel.Annotations ForceFullStates = forceFullStates; } - public string Contract { get; private set; } + [NotNull] public string Contract { get; private set; } + public bool ForceFullStates { get; private set; } } @@ -225,14 +260,15 @@ namespace Filtration.ObjectModel.Annotations /// </summary> /// <example><code> /// [LocalizationRequiredAttribute(true)] - /// public class Foo { - /// private string str = "my string"; // Warning: Localizable string + /// class Foo { + /// string str = "my string"; // Warning: Localizable string /// } /// </code></example> [AttributeUsage(AttributeTargets.All)] public sealed class LocalizationRequiredAttribute : Attribute { public LocalizationRequiredAttribute() : this(true) { } + public LocalizationRequiredAttribute(bool required) { Required = required; @@ -250,8 +286,9 @@ namespace Filtration.ObjectModel.Annotations /// <example><code> /// [CannotApplyEqualityOperator] /// class NoEquality { } + /// /// class UsesNoEquality { - /// public void Test() { + /// void Test() { /// var ca1 = new NoEquality(); /// var ca2 = new NoEquality(); /// if (ca1 != null) { // OK @@ -269,9 +306,10 @@ namespace Filtration.ObjectModel.Annotations /// </summary> /// <example><code> /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement - /// public class ComponentAttribute : Attribute { } + /// class ComponentAttribute : Attribute { } + /// /// [Component] // ComponentAttribute requires implementing IComponent interface - /// public class MyComponent : IComponent { } + /// class MyComponent : IComponent { } /// </code></example> [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] [BaseTypeRequired(typeof(Attribute))] @@ -308,6 +346,7 @@ namespace Filtration.ObjectModel.Annotations } public ImplicitUseKindFlags UseKindFlags { get; private set; } + public ImplicitUseTargetFlags TargetFlags { get; private set; } } @@ -334,6 +373,7 @@ namespace Filtration.ObjectModel.Annotations } [UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; } + [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; } } @@ -377,12 +417,13 @@ namespace Filtration.ObjectModel.Annotations public sealed class PublicAPIAttribute : Attribute { public PublicAPIAttribute() { } + public PublicAPIAttribute([NotNull] string comment) { Comment = comment; } - public string Comment { get; private set; } + [CanBeNull] public string Comment { get; private set; } } /// <summary> @@ -398,15 +439,51 @@ namespace Filtration.ObjectModel.Annotations /// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>. /// </summary> /// <example><code> - /// [Pure] private int Multiply(int x, int y) { return x * y; } - /// public void Foo() { - /// const int a = 2, b = 2; - /// Multiply(a, b); // Waring: Return value of pure method is not used + /// [Pure] int Multiply(int x, int y) => x * y; + /// + /// void M() { + /// Multiply(123, 42); // Waring: Return value of pure method is not used /// } /// </code></example> [AttributeUsage(AttributeTargets.Method)] public sealed class PureAttribute : Attribute { } + /// <summary> + /// Indicates that the return value of method invocation must be used. + /// </summary> + [AttributeUsage(AttributeTargets.Method)] + public sealed class MustUseReturnValueAttribute : Attribute + { + public MustUseReturnValueAttribute() { } + + public MustUseReturnValueAttribute([NotNull] string justification) + { + Justification = justification; + } + + [CanBeNull] public string Justification { get; private set; } + } + + /// <summary> + /// Indicates the type member or parameter of some type, that should be used instead of all other ways + /// to get the value that type. This annotation is useful when you have some "context" value evaluated + /// and stored somewhere, meaning that all other ways to get this value must be consolidated with existing one. + /// </summary> + /// <example><code> + /// class Foo { + /// [ProvidesContext] IBarService _barService = ...; + /// + /// void ProcessNode(INode node) { + /// DoSomething(node, node.GetGlobalServices().Bar); + /// // ^ Warning: use value of '_barService' field + /// } + /// } + /// </code></example> + [AttributeUsage( + AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.Method | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.GenericParameter)] + public sealed class ProvidesContextAttribute : Attribute { } + /// <summary> /// Indicates that a parameter is a path to a file or a folder within a web project. /// Path can be relative or absolute, starting from web root (~). @@ -415,12 +492,13 @@ namespace Filtration.ObjectModel.Annotations public sealed class PathReferenceAttribute : Attribute { public PathReferenceAttribute() { } - public PathReferenceAttribute([PathReference] string basePath) + + public PathReferenceAttribute([NotNull, PathReference] string basePath) { BasePath = basePath; } - public string BasePath { get; private set; } + [CanBeNull] public string BasePath { get; private set; } } /// <summary> @@ -484,7 +562,7 @@ namespace Filtration.ObjectModel.Annotations /// Allows specifying a macro that will be executed for a <see cref="SourceTemplateAttribute">source template</see> /// parameter when the template is expanded. /// </summary> - public string Expression { get; set; } + [CanBeNull] public string Expression { get; set; } /// <summary> /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. @@ -500,73 +578,73 @@ namespace Filtration.ObjectModel.Annotations /// Identifies the target parameter of a <see cref="SourceTemplateAttribute">source template</see> if the /// <see cref="MacroAttribute"/> is applied on a template method. /// </summary> - public string Target { get; set; } + [CanBeNull] public string Target { get; set; } } - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] public sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute { - public AspMvcAreaMasterLocationFormatAttribute(string format) + public AspMvcAreaMasterLocationFormatAttribute([NotNull] string format) { Format = format; } - public string Format { get; private set; } + [NotNull] public string Format { get; private set; } } - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] public sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute { - public AspMvcAreaPartialViewLocationFormatAttribute(string format) + public AspMvcAreaPartialViewLocationFormatAttribute([NotNull] string format) { Format = format; } - public string Format { get; private set; } + [NotNull] public string Format { get; private set; } } - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] public sealed class AspMvcAreaViewLocationFormatAttribute : Attribute { - public AspMvcAreaViewLocationFormatAttribute(string format) + public AspMvcAreaViewLocationFormatAttribute([NotNull] string format) { Format = format; } - public string Format { get; private set; } + [NotNull] public string Format { get; private set; } } - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] public sealed class AspMvcMasterLocationFormatAttribute : Attribute { - public AspMvcMasterLocationFormatAttribute(string format) + public AspMvcMasterLocationFormatAttribute([NotNull] string format) { Format = format; } - public string Format { get; private set; } + [NotNull] public string Format { get; private set; } } - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] public sealed class AspMvcPartialViewLocationFormatAttribute : Attribute { - public AspMvcPartialViewLocationFormatAttribute(string format) + public AspMvcPartialViewLocationFormatAttribute([NotNull] string format) { Format = format; } - public string Format { get; private set; } + [NotNull] public string Format { get; private set; } } - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] public sealed class AspMvcViewLocationFormatAttribute : Attribute { - public AspMvcViewLocationFormatAttribute(string format) + public AspMvcViewLocationFormatAttribute([NotNull] string format) { Format = format; } - public string Format { get; private set; } + [NotNull] public string Format { get; private set; } } /// <summary> @@ -579,12 +657,13 @@ namespace Filtration.ObjectModel.Annotations public sealed class AspMvcActionAttribute : Attribute { public AspMvcActionAttribute() { } - public AspMvcActionAttribute(string anonymousProperty) + + public AspMvcActionAttribute([NotNull] string anonymousProperty) { AnonymousProperty = anonymousProperty; } - public string AnonymousProperty { get; private set; } + [CanBeNull] public string AnonymousProperty { get; private set; } } /// <summary> @@ -596,12 +675,13 @@ namespace Filtration.ObjectModel.Annotations public sealed class AspMvcAreaAttribute : Attribute { public AspMvcAreaAttribute() { } - public AspMvcAreaAttribute(string anonymousProperty) + + public AspMvcAreaAttribute([NotNull] string anonymousProperty) { AnonymousProperty = anonymousProperty; } - public string AnonymousProperty { get; private set; } + [CanBeNull] public string AnonymousProperty { get; private set; } } /// <summary> @@ -614,12 +694,13 @@ namespace Filtration.ObjectModel.Annotations public sealed class AspMvcControllerAttribute : Attribute { public AspMvcControllerAttribute() { } - public AspMvcControllerAttribute(string anonymousProperty) + + public AspMvcControllerAttribute([NotNull] string anonymousProperty) { AnonymousProperty = anonymousProperty; } - public string AnonymousProperty { get; private set; } + [CanBeNull] public string AnonymousProperty { get; private set; } } /// <summary> @@ -649,7 +730,7 @@ namespace Filtration.ObjectModel.Annotations /// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method. /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] - public sealed class AspMvcSupressViewErrorAttribute : Attribute { } + public sealed class AspMvcSuppressViewErrorAttribute : Attribute { } /// <summary> /// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template. @@ -677,13 +758,27 @@ namespace Filtration.ObjectModel.Annotations /// <summary> /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC view. If applied to a method, the MVC view name is calculated implicitly + /// is an MVC view component. If applied to a method, the MVC view name is calculated implicitly /// from the context. Use this attribute for custom wrappers similar to /// <c>System.Web.Mvc.Controller.View(Object)</c>. /// </summary> [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] public sealed class AspMvcViewAttribute : Attribute { } + /// <summary> + /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter + /// is an MVC view component name. + /// </summary> + [AttributeUsage(AttributeTargets.Parameter)] + public sealed class AspMvcViewComponentAttribute : Attribute { } + + /// <summary> + /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter + /// is an MVC view component view. If applied to a method, the MVC view component view name is default. + /// </summary> + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] + public sealed class AspMvcViewComponentViewAttribute : Attribute { } + /// <summary> /// ASP.NET MVC attribute. When applied to a parameter of an attribute, /// indicates that this parameter is an MVC action name. @@ -702,12 +797,13 @@ namespace Filtration.ObjectModel.Annotations public sealed class HtmlElementAttributesAttribute : Attribute { public HtmlElementAttributesAttribute() { } - public HtmlElementAttributesAttribute(string name) + + public HtmlElementAttributesAttribute([NotNull] string name) { Name = name; } - public string Name { get; private set; } + [CanBeNull] public string Name { get; private set; } } [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] @@ -730,9 +826,10 @@ namespace Filtration.ObjectModel.Annotations public sealed class RazorSectionAttribute : Attribute { } /// <summary> - /// Indicates how method invocation affects content of the collection. + /// Indicates how method, constructor invocation or property access + /// over collection type affects content of the collection. /// </summary> - [AttributeUsage(AttributeTargets.Method)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)] public sealed class CollectionAccessAttribute : Attribute { public CollectionAccessAttribute(CollectionAccessType collectionAccessType) @@ -824,6 +921,16 @@ namespace Filtration.ObjectModel.Annotations [AttributeUsage(AttributeTargets.Parameter)] public sealed class RegexPatternAttribute : Attribute { } + /// <summary> + /// Prevents the Member Reordering feature from tossing members of the marked class. + /// </summary> + /// <remarks> + /// The attribute must be mentioned in your member reordering patterns + /// </remarks> + [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum)] + public sealed class NoReorderAttribute : Attribute { } + /// <summary> /// XAML attribute. Indicates the type that has <c>ItemsSource</c> property and should be treated /// as <c>ItemsControl</c>-derived type, to enable inner items <c>DataContext</c> type resolve. @@ -832,7 +939,7 @@ namespace Filtration.ObjectModel.Annotations public sealed class XamlItemsControlAttribute : Attribute { } /// <summary> - /// XAML attibute. Indicates the property of some <c>BindingBase</c>-derived type, that + /// XAML attribute. Indicates the property of some <c>BindingBase</c>-derived type, that /// is used to bind some item of <c>ItemsControl</c>-derived type. This annotation will /// enable the <c>DataContext</c> type resolve for XAML bindings for such properties. /// </summary> @@ -846,14 +953,15 @@ namespace Filtration.ObjectModel.Annotations [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public sealed class AspChildControlTypeAttribute : Attribute { - public AspChildControlTypeAttribute(string tagName, Type controlType) + public AspChildControlTypeAttribute([NotNull] string tagName, [NotNull] Type controlType) { TagName = tagName; ControlType = controlType; } - public string TagName { get; private set; } - public Type ControlType { get; private set; } + [NotNull] public string TagName { get; private set; } + + [NotNull] public Type ControlType { get; private set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] @@ -873,7 +981,7 @@ namespace Filtration.ObjectModel.Annotations Attribute = attribute; } - public string Attribute { get; private set; } + [NotNull] public string Attribute { get; private set; } } [AttributeUsage(AttributeTargets.Property)] @@ -890,25 +998,37 @@ namespace Filtration.ObjectModel.Annotations [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class RazorImportNamespaceAttribute : Attribute { - public RazorImportNamespaceAttribute(string name) + public RazorImportNamespaceAttribute([NotNull] string name) { Name = name; } - public string Name { get; private set; } + [NotNull] public string Name { get; private set; } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class RazorInjectionAttribute : Attribute { - public RazorInjectionAttribute(string type, string fieldName) + public RazorInjectionAttribute([NotNull] string type, [NotNull] string fieldName) { Type = type; FieldName = fieldName; } - public string Type { get; private set; } - public string FieldName { get; private set; } + [NotNull] public string Type { get; private set; } + + [NotNull] public string FieldName { get; private set; } + } + + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + public sealed class RazorDirectiveAttribute : Attribute + { + public RazorDirectiveAttribute([NotNull] string directive) + { + Directive = directive; + } + + [NotNull] public string Directive { get; private set; } } [AttributeUsage(AttributeTargets.Method)] @@ -925,13 +1045,4 @@ namespace Filtration.ObjectModel.Annotations [AttributeUsage(AttributeTargets.Parameter)] public sealed class RazorWriteMethodParameterAttribute : Attribute { } - - /// <summary> - /// Prevents the Member Reordering feature from tossing members of the marked class. - /// </summary> - /// <remarks> - /// The attribute must be mentioned in your member reordering patterns - /// </remarks> - [AttributeUsage(AttributeTargets.All)] - public sealed class NoReorder : Attribute { } } \ No newline at end of file diff --git a/Filtration.ObjectModel/Properties/AssemblyInfo.cs b/Filtration.ObjectModel/Properties/AssemblyInfo.cs index 6ecac2f..5f4cbb6 100644 --- a/Filtration.ObjectModel/Properties/AssemblyInfo.cs +++ b/Filtration.ObjectModel/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -33,3 +34,9 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: InternalsVisibleTo("Filtration.ItemFilterPreview.Tests")] +[assembly: InternalsVisibleTo("Filtration.ObjectModel.Tests")] +[assembly: InternalsVisibleTo("Filtration.Parser.Tests")] +[assembly: InternalsVisibleTo("Filtration.Tests")] +[assembly: InternalsVisibleTo("Filtration.ThemeEditor.Tests")] \ No newline at end of file diff --git a/Filtration.ObjectModel/WindsorInstallers/CommandsInstaller.cs b/Filtration.ObjectModel/WindsorInstallers/CommandsInstaller.cs new file mode 100644 index 0000000..eba5a12 --- /dev/null +++ b/Filtration.ObjectModel/WindsorInstallers/CommandsInstaller.cs @@ -0,0 +1,21 @@ +using Castle.MicroKernel.Registration; +using Castle.MicroKernel.SubSystems.Configuration; +using Castle.Windsor; +using Filtration.ObjectModel.Commands; + +namespace Filtration.ObjectModel.WindsorInstallers +{ + public class CommandsInstaller : IWindsorInstaller + { + public void Install(IWindsorContainer container, IConfigurationStore store) + { + + container.Register(Component + .For<ICommandManager>() + .Forward<ICommandManagerInternal>() + .ImplementedBy<CommandManager>() + .LifestyleTransient()); + + } + } +} diff --git a/Filtration.ObjectModel/WindsorInstallers/ModelsInstaller.cs b/Filtration.ObjectModel/WindsorInstallers/ModelsInstaller.cs new file mode 100644 index 0000000..d0c38d4 --- /dev/null +++ b/Filtration.ObjectModel/WindsorInstallers/ModelsInstaller.cs @@ -0,0 +1,23 @@ +using Castle.Facilities.TypedFactory; +using Castle.MicroKernel.Registration; +using Castle.MicroKernel.SubSystems.Configuration; +using Castle.Windsor; +using Filtration.ObjectModel.Factories; + +namespace Filtration.ObjectModel.WindsorInstallers +{ + public class ModelsInstaller : IWindsorInstaller + { + public void Install(IWindsorContainer container, IConfigurationStore store) + { + container.Register(Component + .For<IItemFilterScript>() + .ImplementedBy<ItemFilterScript>() + .LifestyleTransient()); + + container.Register(Component + .For<IItemFilterScriptFactory>() + .AsFactory()); + } + } +} diff --git a/Filtration.ObjectModel/packages.config b/Filtration.ObjectModel/packages.config new file mode 100644 index 0000000..2eb5957 --- /dev/null +++ b/Filtration.ObjectModel/packages.config @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Castle.Core" version="3.3.0" targetFramework="net461" /> + <package id="Castle.Windsor" version="3.4.0" targetFramework="net461" /> +</packages> \ No newline at end of file diff --git a/Filtration.Parser.Interface/Services/IItemFilterScriptTranslator.cs b/Filtration.Parser.Interface/Services/IItemFilterScriptTranslator.cs index 6cb2e70..06c9a93 100644 --- a/Filtration.Parser.Interface/Services/IItemFilterScriptTranslator.cs +++ b/Filtration.Parser.Interface/Services/IItemFilterScriptTranslator.cs @@ -4,7 +4,7 @@ namespace Filtration.Parser.Interface.Services { public interface IItemFilterScriptTranslator { - ItemFilterScript TranslateStringToItemFilterScript(string inputString); - string TranslateItemFilterScriptToString(ItemFilterScript script); + IItemFilterScript TranslateStringToItemFilterScript(string inputString); + string TranslateItemFilterScriptToString(IItemFilterScript script); } } \ No newline at end of file diff --git a/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs b/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs index 9bca5bb..886102e 100644 --- a/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs +++ b/Filtration.Parser.Tests/Services/TestItemFilterScriptTranslator.cs @@ -5,6 +5,7 @@ using System.Linq; using Filtration.ObjectModel; using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.Enums; +using Filtration.ObjectModel.Factories; using Filtration.ObjectModel.ThemeEditor; using Filtration.Parser.Interface.Services; using Filtration.Parser.Services; @@ -19,12 +20,9 @@ namespace Filtration.Parser.Tests.Services [TestFixture] public class TestItemFilterScriptTranslator { - private ItemFilterScriptTranslatorTestUtility _testUtility; - [SetUp] public void ItemFilterScriptTranslatorTestSetup() { - _testUtility = new ItemFilterScriptTranslatorTestUtility(); Settings.Default.Reset(); } @@ -33,13 +31,16 @@ namespace Filtration.Parser.Tests.Services { // Arrange var testInput = Resources.testscript; + + var mockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>(); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: mockItemFilterBlockTranslator.Object); // Act - var script = _testUtility.ScriptTranslator.TranslateStringToItemFilterScript(testInput); + var script = translator.TranslateStringToItemFilterScript(testInput); // Assert Assert.AreEqual(5, script.ItemFilterBlocks.Count); - _testUtility.MockItemFilterBlockTranslator.Verify(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>(), It.IsAny<IItemFilterScriptSettings>())); + mockItemFilterBlockTranslator.Verify(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>(), It.IsAny<IItemFilterScriptSettings>())); } [Test] @@ -54,8 +55,10 @@ namespace Filtration.Parser.Tests.Services Environment.NewLine + "End Script Description"; + var translator = CreateItemFilterScriptTranslator(); + // Act - var script = _testUtility.ScriptTranslator.TranslateStringToItemFilterScript(testInput); + var script = translator.TranslateStringToItemFilterScript(testInput); // Assert Assert.AreEqual(expectedDescription, script.Description); @@ -67,8 +70,8 @@ namespace Filtration.Parser.Tests.Services // Arrange var testInput = Resources.ThioleItemFilter; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act translator.TranslateStringToItemFilterScript(testInput); @@ -83,9 +86,9 @@ namespace Filtration.Parser.Tests.Services // Arrange var testInput = Resources.testscript2; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, _testUtility.MockBlockGroupHierarchyBuilder.Object); - + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); + // Act var result = translator.TranslateStringToItemFilterScript(testInput); @@ -119,15 +122,20 @@ namespace Filtration.Parser.Tests.Services const string blockOutput = "Test Script Output"; testScript.ItemFilterBlocks.Add(testBlock); + + var mockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>(); + mockItemFilterBlockTranslator + .Setup(t => t.TranslateItemFilterBlockToString(testBlock)) + .Returns(blockOutput) + .Verifiable(); - _testUtility.MockItemFilterBlockTranslator.Setup(t => t.TranslateItemFilterBlockToString(testBlock)).Returns(blockOutput).Verifiable(); - + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: mockItemFilterBlockTranslator.Object); // Act - _testUtility.ScriptTranslator.TranslateItemFilterScriptToString(testScript); + translator.TranslateItemFilterScriptToString(testScript); // Assert - _testUtility.MockItemFilterBlockTranslator.Verify(); + mockItemFilterBlockTranslator.Verify(); } [Test] @@ -156,9 +164,8 @@ namespace Filtration.Parser.Tests.Services " Width = 3" + Environment.NewLine + " SetFontSize 7" + Environment.NewLine; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateItemFilterScriptToString(script); @@ -201,9 +208,8 @@ namespace Filtration.Parser.Tests.Services " Width = 3" + Environment.NewLine + " SetFontSize 7" + Environment.NewLine + Environment.NewLine; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateItemFilterScriptToString(script); @@ -225,8 +231,10 @@ namespace Filtration.Parser.Tests.Services Environment.NewLine + "# Test script description" + Environment.NewLine + Environment.NewLine; + var translator = CreateItemFilterScriptTranslator(); + // Act - var result = _testUtility.ScriptTranslator.TranslateItemFilterScriptToString(script); + var result = translator.TranslateItemFilterScriptToString(script); // Assert Assert.AreEqual(expectedOutput, result); @@ -240,9 +248,8 @@ namespace Filtration.Parser.Tests.Services Environment.NewLine + "Show" + Environment.NewLine + "BaseType \"Maelström Staff\"" + Environment.NewLine + Environment.NewLine; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateStringToItemFilterScript(testInputScript); @@ -274,9 +281,8 @@ namespace Filtration.Parser.Tests.Services " SetTextColor 255 255 0"; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateStringToItemFilterScript(testInputScript); @@ -306,9 +312,8 @@ namespace Filtration.Parser.Tests.Services " SetTextColor 255 255 0"; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateStringToItemFilterScript(testInputScript); @@ -340,9 +345,8 @@ namespace Filtration.Parser.Tests.Services "#Disabled Block End"; - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>()); + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateStringToItemFilterScript(testInputScript); @@ -370,14 +374,14 @@ namespace Filtration.Parser.Tests.Services "#Disabled Block End"; - - var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); - _testUtility.MockBlockGroupHierarchyBuilder.Setup( - b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())) + var mockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>(); + mockBlockGroupHierarchyBuilder.Setup( + b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())) .Returns(new ItemFilterBlockGroup("My Block Group", null)); - var translator = new ItemFilterScriptTranslator(blockTranslator, - _testUtility.MockBlockGroupHierarchyBuilder.Object); + var blockTranslator = new ItemFilterBlockTranslator(mockBlockGroupHierarchyBuilder.Object); + + var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator); // Act var result = translator.TranslateStringToItemFilterScript(testInputScript); @@ -389,21 +393,18 @@ namespace Filtration.Parser.Tests.Services Assert.AreEqual("My Block Group", secondBlock.BlockGroup.GroupName); } - private class ItemFilterScriptTranslatorTestUtility + private ItemFilterScriptTranslator CreateItemFilterScriptTranslator(IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder = null, + IItemFilterBlockTranslator itemFilterBlockTranslator = null, + IItemFilterScriptFactory itemFilterScriptFactory = null) { - public ItemFilterScriptTranslatorTestUtility() - { - // Mock setups - MockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>(); - MockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>(); + var mockItemFilterScriptFactory = new Mock<IItemFilterScriptFactory>(); + mockItemFilterScriptFactory + .Setup(i => i.Create()) + .Returns(new ItemFilterScript()); - // Class under test instantiation - ScriptTranslator = new ItemFilterScriptTranslator(MockItemFilterBlockTranslator.Object, MockBlockGroupHierarchyBuilder.Object); - } - - public ItemFilterScriptTranslator ScriptTranslator { get; } - public Mock<IItemFilterBlockTranslator> MockItemFilterBlockTranslator { get; } - public Mock<IBlockGroupHierarchyBuilder> MockBlockGroupHierarchyBuilder { get; } + return new ItemFilterScriptTranslator(blockGroupHierarchyBuilder ?? new Mock<IBlockGroupHierarchyBuilder>().Object, + itemFilterBlockTranslator ?? new Mock<IItemFilterBlockTranslator>().Object, + itemFilterScriptFactory ?? mockItemFilterScriptFactory.Object); } } } diff --git a/Filtration.Parser/Services/ItemFilterScriptTranslator.cs b/Filtration.Parser/Services/ItemFilterScriptTranslator.cs index e420c33..2e214a3 100644 --- a/Filtration.Parser/Services/ItemFilterScriptTranslator.cs +++ b/Filtration.Parser/Services/ItemFilterScriptTranslator.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using Filtration.Common.Utilities; using Filtration.ObjectModel; +using Filtration.ObjectModel.Factories; using Filtration.Parser.Interface.Services; using Filtration.Properties; @@ -35,13 +36,16 @@ namespace Filtration.Parser.Services internal class ItemFilterScriptTranslator : IItemFilterScriptTranslator { private readonly IItemFilterBlockTranslator _blockTranslator; + private readonly IItemFilterScriptFactory _itemFilterScriptFactory; private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder; - public ItemFilterScriptTranslator(IItemFilterBlockTranslator blockTranslator, - IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder) + public ItemFilterScriptTranslator(IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder, + IItemFilterBlockTranslator blockTranslator, + IItemFilterScriptFactory itemFilterScriptFactory) { - _blockTranslator = blockTranslator; _blockGroupHierarchyBuilder = blockGroupHierarchyBuilder; + _blockTranslator = blockTranslator; + _itemFilterScriptFactory = itemFilterScriptFactory; } public static string PreprocessDisabledBlocks(string inputString) @@ -104,9 +108,9 @@ namespace Filtration.Parser.Services return lines.Aggregate((c, n) => c + Environment.NewLine + n); } - public ItemFilterScript TranslateStringToItemFilterScript(string inputString) + public IItemFilterScript TranslateStringToItemFilterScript(string inputString) { - var script = new ItemFilterScript(); + var script = _itemFilterScriptFactory.Create(); _blockGroupHierarchyBuilder.Initialise(script.ItemFilterBlockGroups.First()); inputString = inputString.Replace("\t", ""); @@ -224,7 +228,7 @@ namespace Filtration.Parser.Services return blockBoundaries; } - public string TranslateItemFilterScriptToString(ItemFilterScript script) + public string TranslateItemFilterScriptToString(IItemFilterScript script) { var outputString = string.Empty; diff --git a/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs b/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs index 5563451..4f6097a 100644 --- a/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs +++ b/Filtration.Tests/Repositories/TestItemFilterScriptRepository.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading.Tasks; using Filtration.ObjectModel; +using Filtration.ObjectModel.Factories; using Filtration.Repositories; using Filtration.Services; using Filtration.ViewModels; @@ -29,7 +30,8 @@ namespace Filtration.Tests.Repositories var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); mockItemFilterScriptViewModelFactory.Setup(f => f.Create()).Returns(mockItemFilterScriptViewModel.Object); - var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); + var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object, + itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object); // Act var result = await repository.LoadScriptFromFileAsync(testInputPath); @@ -50,7 +52,8 @@ namespace Filtration.Tests.Repositories var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); - var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); + var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object, + itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object); // Act Func<Task<IItemFilterScriptViewModel>> result = async () => await repository.LoadScriptFromFileAsync(testInputPath); @@ -70,7 +73,8 @@ namespace Filtration.Tests.Repositories var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); - var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); + var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object, + itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object); // Act repository.SetItemFilterScriptDirectory(testInputPath); @@ -90,7 +94,8 @@ namespace Filtration.Tests.Repositories var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); - var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); + var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object, + itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object); // Act string result = repository.GetItemFilterScriptDirectory(); @@ -111,13 +116,23 @@ namespace Filtration.Tests.Repositories var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); mockItemFilterScriptViewModelFactory.Setup(f => f.Create()).Returns(mockItemFilterScriptViewModel.Object); - var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); - + var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object, + itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object); + // Act IItemFilterScriptViewModel result = repository.NewScript(); // Assert Assert.AreEqual(mockItemFilterScriptViewModel.Object, result); } + + private ItemFilterScriptRepository CreateItemFilterScriptRepository(IItemFilterPersistenceService itemFilterPersistenceService = null, + IItemFilterScriptFactory itemFilterScriptFactory = null, + IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory = null) + { + return new ItemFilterScriptRepository(itemFilterPersistenceService ?? new Mock<IItemFilterPersistenceService>().Object, + itemFilterScriptFactory ?? new Mock<IItemFilterScriptFactory>().Object, + itemFilterScriptViewModelFactory ?? new Mock<IItemFilterScriptViewModelFactory>().Object); + } } } diff --git a/Filtration.ThemeEditor/Providers/ThemeProvider.cs b/Filtration.ThemeEditor/Providers/ThemeProvider.cs index 9cac475..238c392 100644 --- a/Filtration.ThemeEditor/Providers/ThemeProvider.cs +++ b/Filtration.ThemeEditor/Providers/ThemeProvider.cs @@ -11,8 +11,8 @@ namespace Filtration.ThemeEditor.Providers { public interface IThemeProvider { - IThemeEditorViewModel NewThemeForScript(ItemFilterScript script); - IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script); + IThemeEditorViewModel NewThemeForScript(IItemFilterScript script); + IThemeEditorViewModel MasterThemeForScript(IItemFilterScript script); Task<IThemeEditorViewModel> LoadThemeFromFile(string filePath); Task<Theme> LoadThemeModelFromFile(string filePath); Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath); @@ -29,7 +29,7 @@ namespace Filtration.ThemeEditor.Providers _themePersistenceService = themePersistenceService; } - public IThemeEditorViewModel NewThemeForScript(ItemFilterScript script) + public IThemeEditorViewModel NewThemeForScript(IItemFilterScript script) { var themeComponentCollection = script.ThemeComponents.Aggregate(new ThemeComponentCollection(), (c, component) => @@ -45,7 +45,7 @@ namespace Filtration.ThemeEditor.Providers return themeViewModel; } - public IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script) + public IThemeEditorViewModel MasterThemeForScript(IItemFilterScript script) { var themeViewModel = _themeViewModelFactory.Create(); themeViewModel.InitialiseForMasterTheme(script); diff --git a/Filtration.ThemeEditor/Services/ThemeService.cs b/Filtration.ThemeEditor/Services/ThemeService.cs index 360c24f..6ebaa94 100644 --- a/Filtration.ThemeEditor/Services/ThemeService.cs +++ b/Filtration.ThemeEditor/Services/ThemeService.cs @@ -12,7 +12,7 @@ namespace Filtration.ThemeEditor.Services { public interface IThemeService { - void ApplyThemeToScript(Theme theme, ItemFilterScript script); + void ApplyThemeToScript(Theme theme, IItemFilterScript script); } public class ThemeService : IThemeService @@ -24,7 +24,7 @@ namespace Filtration.ThemeEditor.Services _messageBoxService = messageBoxService; } - public void ApplyThemeToScript(Theme theme, ItemFilterScript script) + public void ApplyThemeToScript(Theme theme, IItemFilterScript script) { var mismatchedComponents = false; foreach (var component in theme.Components) diff --git a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs index dfb0490..ab9f796 100644 --- a/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs +++ b/Filtration.ThemeEditor/ViewModels/ThemeEditorViewModel.cs @@ -26,9 +26,9 @@ namespace Filtration.ThemeEditor.ViewModels RelayCommand CloseCommand { get; } void InitialiseForNewTheme(ThemeComponentCollection themeComponentCollection); - void InitialiseForMasterTheme(ItemFilterScript script); + void InitialiseForMasterTheme(IItemFilterScript script); bool IsMasterTheme { get; } - ItemFilterScript IsMasterThemeForScript { get; } + IItemFilterScript IsMasterThemeForScript { get; } string Title { get; } string FilePath { get; set; } string Filename { get; } @@ -72,7 +72,7 @@ namespace Filtration.ThemeEditor.ViewModels public bool IsMasterTheme => Components.IsMasterCollection; - public ItemFilterScript IsMasterThemeForScript { get; private set; } + public IItemFilterScript IsMasterThemeForScript { get; private set; } public void InitialiseForNewTheme(ThemeComponentCollection themeComponentCollection) { @@ -80,7 +80,7 @@ namespace Filtration.ThemeEditor.ViewModels _filenameIsFake = true; } - public void InitialiseForMasterTheme(ItemFilterScript script) + public void InitialiseForMasterTheme(IItemFilterScript script) { Components = script.ThemeComponents; IsMasterThemeForScript = script; diff --git a/Filtration.sln.DotSettings b/Filtration.sln.DotSettings index c7dfe84..c6806ba 100644 --- a/Filtration.sln.DotSettings +++ b/Filtration.sln.DotSettings @@ -1,4 +1,5 @@ <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=Filtration_002EAnnotations/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=Filtration_002EObjectModel_002EAnnotations/@EntryIndexedValue">True</s:Boolean> <s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data /></s:String> <s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Filtration.ItemFilterPreview.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /><Filter ModuleMask="Filtration.ObjectModel.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /><Filter ModuleMask="Filtration.ThemeEditor.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /><Filter ModuleMask="Filtration.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data></s:String></wpf:ResourceDictionary> \ No newline at end of file diff --git a/Filtration/Repositories/ItemFilterScriptRepository.cs b/Filtration/Repositories/ItemFilterScriptRepository.cs index e119daa..c50a9b2 100644 --- a/Filtration/Repositories/ItemFilterScriptRepository.cs +++ b/Filtration/Repositories/ItemFilterScriptRepository.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Filtration.ObjectModel; +using Filtration.ObjectModel.Factories; using Filtration.Services; using Filtration.ViewModels; @@ -16,12 +17,15 @@ namespace Filtration.Repositories internal class ItemFilterScriptRepository : IItemFilterScriptRepository { private readonly IItemFilterPersistenceService _itemFilterPersistenceService; + private readonly IItemFilterScriptFactory _itemFilterScriptFactory; private readonly IItemFilterScriptViewModelFactory _itemFilterScriptViewModelFactory; public ItemFilterScriptRepository(IItemFilterPersistenceService itemFilterPersistenceService, + IItemFilterScriptFactory itemFilterScriptFactory, IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory) { _itemFilterPersistenceService = itemFilterPersistenceService; + _itemFilterScriptFactory = itemFilterScriptFactory; _itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory; } @@ -37,7 +41,7 @@ namespace Filtration.Repositories public IItemFilterScriptViewModel NewScript() { - var newScript = new ItemFilterScript(); + var newScript = _itemFilterScriptFactory.Create(); var newViewModel = _itemFilterScriptViewModelFactory.Create(); newViewModel.Initialise(newScript, true); diff --git a/Filtration/Services/ItemFilterPersistenceService.cs b/Filtration/Services/ItemFilterPersistenceService.cs index 27646ec..14cd9dc 100644 --- a/Filtration/Services/ItemFilterPersistenceService.cs +++ b/Filtration/Services/ItemFilterPersistenceService.cs @@ -11,8 +11,8 @@ namespace Filtration.Services { void SetItemFilterScriptDirectory(string path); string ItemFilterScriptDirectory { get; } - Task<ItemFilterScript> LoadItemFilterScriptAsync(string filePath); - Task SaveItemFilterScriptAsync(ItemFilterScript script); + Task<IItemFilterScript> LoadItemFilterScriptAsync(string filePath); + Task SaveItemFilterScriptAsync(IItemFilterScript script); string DefaultPathOfExileDirectory(); } @@ -59,9 +59,9 @@ namespace Filtration.Services Settings.Default.DefaultFilterDirectory = path; } - public async Task<ItemFilterScript> LoadItemFilterScriptAsync(string filePath) + public async Task<IItemFilterScript> LoadItemFilterScriptAsync(string filePath) { - ItemFilterScript loadedScript = null; + IItemFilterScript loadedScript = null; await Task.Run(() => { loadedScript = _itemFilterScriptTranslator.TranslateStringToItemFilterScript( @@ -76,7 +76,7 @@ namespace Filtration.Services return loadedScript; } - public async Task SaveItemFilterScriptAsync(ItemFilterScript script) + public async Task SaveItemFilterScriptAsync(IItemFilterScript script) { await Task.Run(() => { diff --git a/Filtration/ViewModels/ItemFilterScriptViewModel.cs b/Filtration/ViewModels/ItemFilterScriptViewModel.cs index 2c589cc..1435f70 100644 --- a/Filtration/ViewModels/ItemFilterScriptViewModel.cs +++ b/Filtration/ViewModels/ItemFilterScriptViewModel.cs @@ -25,7 +25,7 @@ namespace Filtration.ViewModels { internal interface IItemFilterScriptViewModel : IEditableDocument { - ItemFilterScript Script { get; } + IItemFilterScript Script { get; } IItemFilterBlockViewModelBase SelectedBlockViewModel { get; set; } IItemFilterCommentBlockViewModel CommentBlockBrowserBrowserSelectedBlockViewModel { get; set; } IEnumerable<IItemFilterCommentBlockViewModel> ItemFilterCommentBlockViewModels { get; } @@ -35,7 +35,7 @@ namespace Filtration.ViewModels string Description { get; set; } string DisplayName { get; } - void Initialise(ItemFilterScript itemFilterScript, bool newScript); + void Initialise(IItemFilterScript itemFilterScript, bool newScript); void RemoveDirtyFlag(); void SetDirtyFlag(); bool HasSelectedEnabledBlock(); @@ -294,7 +294,7 @@ namespace Filtration.ViewModels } } - public ItemFilterScript Script { get; private set; } + public IItemFilterScript Script { get; private set; } public bool IsDirty { @@ -341,7 +341,7 @@ namespace Filtration.ViewModels private bool _filenameIsFake; private bool _showAdvanced; - public void Initialise(ItemFilterScript itemFilterScript, bool newScript) + public void Initialise(IItemFilterScript itemFilterScript, bool newScript) { ItemFilterBlockViewModels.Clear(); diff --git a/Filtration/ViewModels/ReplaceColorsViewModel.cs b/Filtration/ViewModels/ReplaceColorsViewModel.cs index 8c4b77e..a9dc2e7 100644 --- a/Filtration/ViewModels/ReplaceColorsViewModel.cs +++ b/Filtration/ViewModels/ReplaceColorsViewModel.cs @@ -1,7 +1,6 @@ using System.Collections.ObjectModel; using System.Linq; using System.Windows.Media; -using Filtration.Common.ViewModels; using Filtration.ObjectModel; using Filtration.ObjectModel.BlockItemTypes; using Filtration.Views; @@ -13,13 +12,13 @@ namespace Filtration.ViewModels { internal interface IReplaceColorsViewModel { - void Initialise(ItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock); - void Initialise(ItemFilterScript itemFilterScript); + void Initialise(IItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock); + void Initialise(IItemFilterScript itemFilterScript); } internal class ReplaceColorsViewModel : ViewModelBase, IReplaceColorsViewModel { - private ItemFilterScript _itemFilterScript; + private IItemFilterScript _itemFilterScript; private ReplaceColorsParameterSet _replaceColorsParameterSet; public ReplaceColorsViewModel() @@ -29,7 +28,7 @@ namespace Filtration.ViewModels public RelayCommand ReplaceColorsCommand { get; private set; } - public void Initialise(ItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock) + public void Initialise(IItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock) { _replaceColorsParameterSet = new ReplaceColorsParameterSet(); @@ -67,7 +66,7 @@ namespace Filtration.ViewModels public Color NewTextColor { - get { return _replaceColorsParameterSet.NewTextColor; } + get => _replaceColorsParameterSet.NewTextColor; set { _replaceColorsParameterSet.NewTextColor = value; @@ -82,7 +81,7 @@ namespace Filtration.ViewModels public bool ReplaceTextColor { - get { return _replaceColorsParameterSet.ReplaceTextColor; } + get => _replaceColorsParameterSet.ReplaceTextColor; set { _replaceColorsParameterSet.ReplaceTextColor = value; @@ -92,7 +91,7 @@ namespace Filtration.ViewModels public Color NewBackgroundColor { - get { return _replaceColorsParameterSet.NewBackgroundColor; } + get => _replaceColorsParameterSet.NewBackgroundColor; set { _replaceColorsParameterSet.NewBackgroundColor = value; @@ -107,7 +106,7 @@ namespace Filtration.ViewModels public bool ReplaceBackgroundColor { - get { return _replaceColorsParameterSet.ReplaceBackgroundColor; } + get => _replaceColorsParameterSet.ReplaceBackgroundColor; set { _replaceColorsParameterSet.ReplaceBackgroundColor = value; @@ -117,7 +116,7 @@ namespace Filtration.ViewModels public Color NewBorderColor { - get { return _replaceColorsParameterSet.NewBorderColor; } + get => _replaceColorsParameterSet.NewBorderColor; set { _replaceColorsParameterSet.NewBorderColor = value; @@ -132,7 +131,7 @@ namespace Filtration.ViewModels public bool ReplaceBorderColor { - get { return _replaceColorsParameterSet.ReplaceBorderColor; } + get => _replaceColorsParameterSet.ReplaceBorderColor; set { _replaceColorsParameterSet.ReplaceBorderColor = value; @@ -142,7 +141,7 @@ namespace Filtration.ViewModels public ReplaceColorsParameterSet ReplaceColorsParameterSet => _replaceColorsParameterSet; - public void Initialise(ItemFilterScript itemFilterScript) + public void Initialise(IItemFilterScript itemFilterScript) { _replaceColorsParameterSet = new ReplaceColorsParameterSet(); _itemFilterScript = itemFilterScript; diff --git a/Filtration/Views/ItemFilterScriptView.xaml b/Filtration/Views/ItemFilterScriptView.xaml index 3fd14bd..f258054 100644 --- a/Filtration/Views/ItemFilterScriptView.xaml +++ b/Filtration/Views/ItemFilterScriptView.xaml @@ -17,9 +17,9 @@ <KeyBinding Command="{Binding CopyBlockStyleCommand}" Modifiers="Shift+Control" Key="C" /> <KeyBinding Command="{Binding PasteBlockStyleCommand}" Modifiers="Shift+Control" Key="V" /> </UserControl.InputBindings> - <utility:RoutedCommandHandlers.Commands> + <!--<utility:RoutedCommandHandlers.Commands> <utility:RoutedCommandHandler RoutedCommand="{StaticResource MoveBlockUpRoutedCommand}" Command="{Binding MoveBlockUpCommand}" IsActive="{Binding IsActiveDocument}" /> - </utility:RoutedCommandHandlers.Commands> + </utility:RoutedCommandHandlers.Commands>--> <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> @@ -42,7 +42,6 @@ </Grid.RowDefinitions> <Border Grid.Row="0" BorderThickness="1" BorderBrush="DarkGray" Margin="5,5,5,0"> <StackPanel Margin="2,2,2,2"> - <Button Command="{StaticResource MoveBlockUpRoutedCommand}">MOVE BLOCK UP TEST BUTTON</Button> <Expander Style="{StaticResource ExpanderRightAlignStyle}"> <Expander.Header> <TextBlock Text="Script Description" VerticalAlignment="Center" /> diff --git a/Filtration/Views/StartPageView.xaml b/Filtration/Views/StartPageView.xaml index 150334c..8e3793c 100644 --- a/Filtration/Views/StartPageView.xaml +++ b/Filtration/Views/StartPageView.xaml @@ -8,7 +8,7 @@ <Grid> <TextBlock FontStyle="Italic" Margin="5" FontSize="13"> Welcome to Filtration, to get started either - <Hyperlink Command="{Binding NewScriptCommand}">create a new script</Hyperlink> or <Hyperlink Command="{StaticResource OpenScriptRoutedCommand}">open an existing script</Hyperlink> + <Hyperlink Command="{Binding NewScriptCommand}">create a new script</Hyperlink> or <Hyperlink Command="{Binding OpenScriptCommand}">open an existing script</Hyperlink> </TextBlock> </Grid> </UserControl>