Merge pull request #50 from ben-wallis/develop

Various changes from local repo
This commit is contained in:
Ben Wallis 2017-12-07 18:24:46 +00:00 committed by GitHub
commit d14e4e9320
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
115 changed files with 2939 additions and 1253 deletions

182
.gitignore vendored
View File

@ -1,23 +1,36 @@
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files # User-specific files
*.suo *.suo
*.user *.user
*.userosscache
*.sln.docstates *.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results # Build results
[Dd]ebug/ [Dd]ebug/
[Dd]ebugPublic/ [Dd]ebugPublic/
[Rr]elease/ [Rr]elease/
[Rr]eleases/
x64/ x64/
build/ x86/
bld/ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
[Ll]og/
# Roslyn cache directories # Visual Studio 2015/2017 cache/options directory
*.ide/ .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 # MSTest test Results
[Tt]est[Rr]esult*/ [Tt]est[Rr]esult*/
@ -32,6 +45,19 @@ TestResult.xml
[Rr]eleasePS/ [Rr]eleasePS/
dlldata.c 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 *_i.c
*_p.c *_p.c
*_i.h *_i.h
@ -64,14 +90,21 @@ _Chutzpah*
ipch/ ipch/
*.aps *.aps
*.ncb *.ncb
*.opendb
*.opensdf *.opensdf
*.sdf *.sdf
*.cachefile *.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler # Visual Studio profiler
*.psess *.psess
*.vsp *.vsp
*.vspx *.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace # TFS 2012 Local Workspace
$tf/ $tf/
@ -84,7 +117,7 @@ _ReSharper*/
*.[Rr]e[Ss]harper *.[Rr]e[Ss]harper
*.DotSettings.user *.DotSettings.user
# JustCode is a .NET coding addin-in # JustCode is a .NET coding add-in
.JustCode .JustCode
# TeamCity is a build add-in # TeamCity is a build add-in
@ -93,9 +126,18 @@ _TeamCity*
# DotCover is a Code Coverage Tool # DotCover is a Code Coverage Tool
*.dotCover *.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch # NCrunch
_NCrunch_* _NCrunch_*
.*crunch*.local.xml .*crunch*.local.xml
nCrunchTemp_*
# MightyMoose # MightyMoose
*.mm.* *.mm.*
@ -123,42 +165,63 @@ publish/
# Publish Web Output # Publish Web Output
*.[Pp]ublish.xml *.[Pp]ublish.xml
*.azurePubxml *.azurePubxml
## TODO: Comment the next line if you want to checkin your # Note: Comment the next line if you want to checkin your web deploy settings,
## web deploy settings but do note that will include unencrypted # but database connection strings (with potential passwords) will be unencrypted
## passwords *.pubxml
#*.pubxml *.publishproj
# NuGet Packages Directory # Microsoft Azure Web App publish settings. Comment the next line if you want to
packages/* # checkin your Azure Web App publish settings, but sensitive information contained
## TODO: If the tool you use requires repositories.config # in these scripts will be unencrypted
## uncomment the next line PublishScripts/
#!packages/repositories.config
# Enable "build/" folder in the NuGet Packages folder since # NuGet Packages
# NuGet packages use it for MSBuild targets. *.nupkg
# This line needs to be after the ignore of the build folder # The packages folder can be ignored because of Package Restore
# (and the packages folder if the line above has been uncommented) **/[Pp]ackages/*
!packages/build/ # 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/ csx/
*.build.csdef *.build.csdef
# Windows Store app package directory # Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/ 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 # Others
sql/
*.Cache
ClientBin/ ClientBin/
[Ss]tyle[Cc]op.*
~$* ~$*
*~ *~
*.dbmdl *.dbmdl
*.dbproj.schemaview *.dbproj.schemaview
*.jfm
*.pfx *.pfx
*.publishsettings *.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 # RIA/Silverlight projects
Generated_Code/ Generated_Code/
@ -174,6 +237,7 @@ UpgradeLog*.htm
# SQL Server files # SQL Server files
*.mdf *.mdf
*.ldf *.ldf
*.ndf
# Business Intelligence projects # Business Intelligence projects
*.rdl.data *.rdl.data
@ -183,7 +247,69 @@ UpgradeLog*.htm
# Microsoft Fakes # Microsoft Fakes
FakesAssemblies/ FakesAssemblies/
# LightSwitch generated files # GhostDoc plugin setting file
GeneratedArtifacts/ *.GhostDoc.xml
_Pvt_Extensions/
ModelManifest.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/

View File

@ -35,13 +35,11 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
</packages> </packages>

View File

@ -35,8 +35,8 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Windsor"> <Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath> <HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath>
</Reference> </Reference>
<Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL"> <Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath> <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -21,6 +22,7 @@ namespace Filtration.Common.Utilities
/// the stream into text. /// the stream into text.
/// </summary> /// </summary>
/// <param name="streamSource">Data source</param> /// <param name="streamSource">Data source</param>
[DebuggerStepThrough]
public LineReader(Func<Stream> streamSource) public LineReader(Func<Stream> streamSource)
: this(streamSource, Encoding.UTF8) : this(streamSource, Encoding.UTF8)
{ {
@ -33,6 +35,7 @@ namespace Filtration.Common.Utilities
/// <param name="streamSource">Data source</param> /// <param name="streamSource">Data source</param>
/// <param name="encoding">Encoding to use to decode the stream /// <param name="encoding">Encoding to use to decode the stream
/// into text</param> /// into text</param>
[DebuggerStepThrough]
public LineReader(Func<Stream> streamSource, Encoding encoding) public LineReader(Func<Stream> streamSource, Encoding encoding)
: this(() => new StreamReader(streamSource(), encoding)) : this(() => new StreamReader(streamSource(), encoding))
{ {
@ -44,6 +47,7 @@ namespace Filtration.Common.Utilities
/// UTF8 is used to decode the file into text. /// UTF8 is used to decode the file into text.
/// </summary> /// </summary>
/// <param name="filename">File to read from</param> /// <param name="filename">File to read from</param>
[DebuggerStepThrough]
public LineReader(string filename) public LineReader(string filename)
: this(filename, Encoding.UTF8) : this(filename, Encoding.UTF8)
{ {
@ -56,6 +60,7 @@ namespace Filtration.Common.Utilities
/// <param name="filename">File to read from</param> /// <param name="filename">File to read from</param>
/// <param name="encoding">Encoding to use to decode the file /// <param name="encoding">Encoding to use to decode the file
/// into text</param> /// into text</param>
[DebuggerStepThrough]
public LineReader(string filename, Encoding encoding) public LineReader(string filename, Encoding encoding)
: this(() => new StreamReader(filename, encoding)) : this(() => new StreamReader(filename, encoding))
{ {
@ -66,6 +71,7 @@ namespace Filtration.Common.Utilities
/// is only called when the enumerator is fetched /// is only called when the enumerator is fetched
/// </summary> /// </summary>
/// <param name="dataSource">Data source</param> /// <param name="dataSource">Data source</param>
[DebuggerStepThrough]
public LineReader(Func<TextReader> dataSource) public LineReader(Func<TextReader> dataSource)
{ {
_dataSource = dataSource; _dataSource = dataSource;
@ -74,6 +80,7 @@ namespace Filtration.Common.Utilities
/// <summary> /// <summary>
/// Enumerates the data source line by line. /// Enumerates the data source line by line.
/// </summary> /// </summary>
[DebuggerStepThrough]
public IEnumerator<string> GetEnumerator() public IEnumerator<string> GetEnumerator()
{ {
using (TextReader reader = _dataSource()) using (TextReader reader = _dataSource())
@ -89,6 +96,7 @@ namespace Filtration.Common.Utilities
/// <summary> /// <summary>
/// Enumerates the data source line by line. /// Enumerates the data source line by line.
/// </summary> /// </summary>
[DebuggerStepThrough]
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator(); return GetEnumerator();

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net451" /> <package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net451" /> <package id="Castle.Windsor" version="3.4.0" targetFramework="net461" />
<package id="CommonServiceLocator" version="1.3" targetFramework="net451" /> <package id="CommonServiceLocator" version="1.3" targetFramework="net451" />
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" /> <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" />
</packages> </packages>

View File

@ -46,9 +46,8 @@
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath> <HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.ComponentModel.DataAnnotations" />

View File

@ -6,6 +6,7 @@ using NUnit.Framework;
namespace Filtration.ItemFilterPreview.Data.Tests.Repositories namespace Filtration.ItemFilterPreview.Data.Tests.Repositories
{ {
[Ignore("integration test")]
[TestFixture] [TestFixture]
public class TestItemSetRepository public class TestItemSetRepository
{ {

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="EntityFramework" version="6.1.3" targetFramework="net461" /> <package id="EntityFramework" version="6.1.3" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
<package id="System.Data.SQLite" version="1.0.102.0" targetFramework="net461" /> <package id="System.Data.SQLite" version="1.0.102.0" targetFramework="net461" />
<package id="System.Data.SQLite.Core" version="1.0.102.0" targetFramework="net461" /> <package id="System.Data.SQLite.Core" version="1.0.102.0" targetFramework="net461" />
<package id="System.Data.SQLite.EF6" version="1.0.102.0" targetFramework="net461" /> <package id="System.Data.SQLite.EF6" version="1.0.102.0" targetFramework="net461" />

View File

@ -46,21 +46,17 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="FluentAssertions, Version=4.13.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <Reference Include="FluentAssertions, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.13.1\lib\net45\FluentAssertions.dll</HintPath> <HintPath>..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="FluentAssertions.Core, Version=4.13.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <Reference Include="FluentAssertions.Core, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.13.1\lib\net45\FluentAssertions.Core.dll</HintPath> <HintPath>..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
@ -121,7 +117,6 @@
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="Resources\MuldiniFilterScript.txt" /> <None Include="Resources\MuldiniFilterScript.txt" />
</ItemGroup> </ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -6,6 +6,7 @@ using Filtration.ItemFilterPreview.Tests.Properties;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.BlockItemTypes;
using Filtration.ObjectModel.Enums; using Filtration.ObjectModel.Enums;
using Filtration.ObjectModel.Factories;
using Filtration.Parser.Services; using Filtration.Parser.Services;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -29,7 +30,7 @@ namespace Filtration.ItemFilterPreview.Tests.Services
//Arrange //Arrange
var testInputItem = Mock.Of<IItem>(); var testInputItem = Mock.Of<IItem>();
var testInputBlock = Mock.Of<IItemFilterBlock>(); var testInputBlock = Mock.Of<IItemFilterBlock>();
var testInputScript = Mock.Of<IItemFilterScript>(s => s.ItemFilterBlocks == new ObservableCollection<IItemFilterBlock> {testInputBlock}); var testInputScript = Mock.Of<IItemFilterScript>(s => s.ItemFilterBlocks == new ObservableCollection<IItemFilterBlockBase> {testInputBlock});
_testUtility.MockBlockItemMatcher _testUtility.MockBlockItemMatcher
.Setup(b => b.ItemBlockMatch(testInputBlock, testInputItem)) .Setup(b => b.ItemBlockMatch(testInputBlock, testInputItem))
@ -50,7 +51,7 @@ namespace Filtration.ItemFilterPreview.Tests.Services
//Arrange //Arrange
var testInputItem = Mock.Of<IItem>(); var testInputItem = Mock.Of<IItem>();
var testInputBlock = Mock.Of<IItemFilterBlock>(); var testInputBlock = Mock.Of<IItemFilterBlock>();
var testInputScript = Mock.Of<IItemFilterScript>(s => s.ItemFilterBlocks == new ObservableCollection<IItemFilterBlock> { testInputBlock }); var testInputScript = Mock.Of<IItemFilterScript>(s => s.ItemFilterBlocks == new ObservableCollection<IItemFilterBlockBase> { testInputBlock });
_testUtility.MockBlockItemMatcher _testUtility.MockBlockItemMatcher
.Setup(b => b.ItemBlockMatch(testInputBlock, testInputItem)) .Setup(b => b.ItemBlockMatch(testInputBlock, testInputItem))
@ -71,7 +72,12 @@ namespace Filtration.ItemFilterPreview.Tests.Services
//Arrange //Arrange
var testInputScriptFile = Resources.MuldiniFilterScript; var testInputScriptFile = Resources.MuldiniFilterScript;
var blockGroupHierarchyBuilder = new BlockGroupHierarchyBuilder(); 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 script = scriptTranslator.TranslateStringToItemFilterScript(testInputScriptFile);
var testInputItem = new Item var testInputItem = new Item
@ -101,7 +107,11 @@ namespace Filtration.ItemFilterPreview.Tests.Services
//Arrange //Arrange
var testInputScriptFile = Resources.MuldiniFilterScript; var testInputScriptFile = Resources.MuldiniFilterScript;
var blockGroupHierarchyBuilder = new BlockGroupHierarchyBuilder(); 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 script = scriptTranslator.TranslateStringToItemFilterScript(testInputScriptFile);
var testInputItems = new List<IItem> var testInputItems = new List<IItem>

View File

@ -6,7 +6,6 @@ using System.Xml.Serialization;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.Enums; using Filtration.ObjectModel.Enums;
using NUnit.Framework; using NUnit.Framework;
using YamlDotNet.Serialization;
namespace Filtration.ItemFilterPreview.Tests.Services namespace Filtration.ItemFilterPreview.Tests.Services
{ {
@ -40,7 +39,6 @@ namespace Filtration.ItemFilterPreview.Tests.Services
output = textWriter.ToString(); output = textWriter.ToString();
} }
var x = 2;
//Assert //Assert
} }
} }

View File

@ -8,7 +8,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ControlzEx" publicKeyToken="f08b075e934b7045" culture="neutral" /> <assemblyIdentity name="ControlzEx" publicKeyToken="f08b075e934b7045" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.2.3" newVersion="2.1.2.3" /> <bindingRedirect oldVersion="0.0.0.0-2.2.0.4" newVersion="2.2.0.4" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="FluentAssertions" version="4.13.1" targetFramework="net461" /> <package id="FluentAssertions" version="4.19.2" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
<package id="YamlDotNet" version="3.9.0" targetFramework="net461" /> <package id="YamlDotNet" version="3.9.0" targetFramework="net461" />
</packages> </packages>

View File

@ -40,9 +40,8 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Windsor, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> <Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath> <HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL"> <Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath> <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
@ -60,9 +59,8 @@
<HintPath>..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath> <HintPath>..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />

View File

@ -31,7 +31,7 @@ namespace Filtration.ItemFilterPreview.Services
sw.Restart(); sw.Restart();
var matchedBlock = itemFilterScript.ItemFilterBlocks var matchedBlock = itemFilterScript.ItemFilterBlocks
.Where(b => !(b is ItemFilterSection)) .OfType<IItemFilterBlock>()
.FirstOrDefault(block => _blockItemMatcher.ItemBlockMatch(block, item)); .FirstOrDefault(block => _blockItemMatcher.ItemBlockMatch(block, item));
filteredItems.Add(new FilteredItem(item, matchedBlock)); filteredItems.Add(new FilteredItem(item, matchedBlock));

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net461" /> <package id="Castle.Windsor" version="3.4.0" targetFramework="net461" />
<package id="CommonServiceLocator" version="1.3" targetFramework="net461" /> <package id="CommonServiceLocator" version="1.3" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" /> <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" />
</packages> </packages>

View File

@ -35,13 +35,11 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />

View File

@ -6,23 +6,6 @@ namespace Filtration.ObjectModel.Tests
[TestFixture] [TestFixture]
public class TestItemFilterBlock public class TestItemFilterBlock
{ {
[Test]
public void ItemFilterBlock_BlockCount_ReturnsCorrectNumber()
{
// Arrange
var block = new ItemFilterBlock();
block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem());
block.BlockItems.Add(new ItemLevelBlockItem());
// Act
var count = block.BlockCount(typeof (ItemLevelBlockItem));
// Assert
Assert.AreEqual(4, count);
}
[Test] [Test]
public void ItemFilterBlock_AddBlockItemAllowed_LessThanMaximum_ReturnsTrue() public void ItemFilterBlock_AddBlockItemAllowed_LessThanMaximum_ReturnsTrue()
{ {

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
</packages> </packages>

View File

@ -15,7 +15,7 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes
public BlockAction Action public BlockAction Action
{ {
get { return _action; } get => _action;
set set
{ {
_action = value; _action = value;
@ -27,6 +27,8 @@ namespace Filtration.ObjectModel.BlockItemBaseTypes
} }
} }
public string Comment { get; set; }
public override string OutputText => Action.GetAttributeDescription(); public override string OutputText => Action.GetAttributeDescription();
public override string PrefixText => string.Empty; public override string PrefixText => string.Empty;

View File

@ -0,0 +1,61 @@
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();
if (command is IUndoableCommand undoableCommand)
{
_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);
}
}
}

View File

@ -0,0 +1,7 @@
namespace Filtration.ObjectModel.Commands
{
public interface ICommand
{
void Execute();
}
}

View File

@ -0,0 +1,8 @@
namespace Filtration.ObjectModel.Commands
{
internal interface IUndoableCommand : ICommand
{
void Undo();
void Redo();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,9 @@
namespace Filtration.ObjectModel.Factories
{
public interface IItemFilterScriptFactory
{
IItemFilterScript Create();
void Release(IItemFilterScript itemFilterScript);
}
}

View File

@ -31,6 +31,12 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.ComponentModel.DataAnnotations" />
@ -68,6 +74,18 @@
<Compile Include="BlockItemTypes\SoundBlockItem.cs" /> <Compile Include="BlockItemTypes\SoundBlockItem.cs" />
<Compile Include="BlockItemTypes\TextColorBlockItem.cs" /> <Compile Include="BlockItemTypes\TextColorBlockItem.cs" />
<Compile Include="BlockItemTypes\WidthBlockItem.cs" /> <Compile Include="BlockItemTypes\WidthBlockItem.cs" />
<Compile Include="Commands\CommandManager.cs" />
<Compile Include="Commands\ICommand.cs" />
<Compile Include="Commands\ItemFilterScript\PasteBlockCommand.cs" />
<Compile Include="Commands\ItemFilterScript\MoveBlockToBottomCommand.cs" />
<Compile Include="Commands\ItemFilterScript\AddCommentBlockCommand.cs" />
<Compile Include="Commands\ItemFilterScript\MoveBlockDownCommand.cs" />
<Compile Include="Commands\ItemFilterScript\MoveBlockUpCommand.cs" />
<Compile Include="Commands\ItemFilterScript\MoveBlockToTopCommand.cs" />
<Compile Include="Commands\ItemFilterScript\SetScriptDescriptionCommand.cs" />
<Compile Include="Commands\ItemFilterScript\RemoveBlockCommand.cs" />
<Compile Include="Commands\ItemFilterScript\AddBlockCommand.cs" />
<Compile Include="Commands\IUndoableCommand.cs" />
<Compile Include="Enums\BlockAction.cs" /> <Compile Include="Enums\BlockAction.cs" />
<Compile Include="Enums\BlockItemType.cs" /> <Compile Include="Enums\BlockItemType.cs" />
<Compile Include="Enums\FilterPredicateOperator.cs" /> <Compile Include="Enums\FilterPredicateOperator.cs" />
@ -77,6 +95,7 @@
<Compile Include="Enums\ThemeComponentType.cs" /> <Compile Include="Enums\ThemeComponentType.cs" />
<Compile Include="Extensions\EnumHelper.cs" /> <Compile Include="Extensions\EnumHelper.cs" />
<Compile Include="Extensions\ItemRarityExtensions.cs" /> <Compile Include="Extensions\ItemRarityExtensions.cs" />
<Compile Include="Factories\IItemFilterScriptFactory.cs" />
<Compile Include="FilteredItem.cs" /> <Compile Include="FilteredItem.cs" />
<Compile Include="IAudioVisualBlockItem.cs" /> <Compile Include="IAudioVisualBlockItem.cs" />
<Compile Include="IItemFilterBlockItem.cs" /> <Compile Include="IItemFilterBlockItem.cs" />
@ -84,7 +103,7 @@
<Compile Include="ItemFilterBlock.cs" /> <Compile Include="ItemFilterBlock.cs" />
<Compile Include="ItemFilterBlockGroup.cs" /> <Compile Include="ItemFilterBlockGroup.cs" />
<Compile Include="ItemFilterScript.cs" /> <Compile Include="ItemFilterScript.cs" />
<Compile Include="ItemFilterSection.cs" /> <Compile Include="ItemFilterScriptSettings.cs" />
<Compile Include="ItemSet.cs" /> <Compile Include="ItemSet.cs" />
<Compile Include="NumericFilterPredicate.cs" /> <Compile Include="NumericFilterPredicate.cs" />
<Compile Include="PathOfExileNamedColors.cs" /> <Compile Include="PathOfExileNamedColors.cs" />
@ -97,6 +116,12 @@
<Compile Include="ThemeEditor\Theme.cs" /> <Compile Include="ThemeEditor\Theme.cs" />
<Compile Include="ThemeEditor\ThemeComponent.cs" /> <Compile Include="ThemeEditor\ThemeComponent.cs" />
<Compile Include="ThemeEditor\ThemeComponentCollection.cs" /> <Compile Include="ThemeEditor\ThemeComponentCollection.cs" />
<Compile Include="WindsorInstallers\CommandsInstaller.cs" />
<Compile Include="WindsorInstallers\ModelsInstaller.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="packages.config" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -5,8 +5,6 @@ namespace Filtration.ObjectModel
{ {
public interface IItemFilterBlockItem : INotifyPropertyChanged public interface IItemFilterBlockItem : INotifyPropertyChanged
{ {
event PropertyChangedEventHandler PropertyChanged;
string PrefixText { get; } string PrefixText { get; }
string OutputText { get; } string OutputText { get; }
string DisplayHeading { get; } string DisplayHeading { get; }

View File

@ -4,44 +4,82 @@ using System.Linq;
using System.Windows.Media; using System.Windows.Media;
using Filtration.ObjectModel.BlockItemBaseTypes; using Filtration.ObjectModel.BlockItemBaseTypes;
using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.BlockItemTypes;
using Filtration.ObjectModel.Commands;
using Filtration.ObjectModel.Enums; using Filtration.ObjectModel.Enums;
using Filtration.ObjectModel.Extensions; using Filtration.ObjectModel.Extensions;
namespace Filtration.ObjectModel namespace Filtration.ObjectModel
{ {
public interface IItemFilterBlock public interface IItemFilterBlock : IItemFilterBlockBase
{ {
bool Enabled { get; set; } bool Enabled { get; set; }
string Description { get; set; } string Description { get; set; }
ItemFilterBlockGroup BlockGroup { get; set; } ItemFilterBlockGroup BlockGroup { get; set; }
BlockAction Action { get; set; } BlockAction Action { get; set; }
ActionBlockItem ActionBlockItem { get; }
ObservableCollection<IItemFilterBlockItem> BlockItems { get; } ObservableCollection<IItemFilterBlockItem> BlockItems { get; }
Color DisplayBackgroundColor { get; } Color DisplayBackgroundColor { get; }
Color DisplayTextColor { get; } Color DisplayTextColor { get; }
Color DisplayBorderColor { get; } Color DisplayBorderColor { get; }
double DisplayFontSize { get; } double DisplayFontSize { get; }
int BlockCount(Type type);
bool AddBlockItemAllowed(Type type);
bool HasBlockItemOfType<T>(); bool HasBlockItemOfType<T>();
bool HasBlockGroupInParentHierarchy(ItemFilterBlockGroup targetBlockGroup, ItemFilterBlockGroup startingBlockGroup); bool HasBlockGroupInParentHierarchy(ItemFilterBlockGroup targetBlockGroup, ItemFilterBlockGroup startingBlockGroup);
} }
public class ItemFilterBlock : IItemFilterBlock public interface 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
{
string Comment { get; set; }
}
public class ItemFilterCommentBlock : ItemFilterBlockBase, IItemFilterCommentBlock
{
public ItemFilterCommentBlock(IItemFilterScript parentScript) : base(parentScript)
{
}
public string Comment { get; set; }
}
public class ItemFilterBlock : ItemFilterBlockBase, IItemFilterBlock
{ {
private ItemFilterBlockGroup _blockGroup; private ItemFilterBlockGroup _blockGroup;
public ItemFilterBlock() internal ItemFilterBlock()
{ {
BlockItems = new ObservableCollection<IItemFilterBlockItem> {new ActionBlockItem(BlockAction.Show)}; BlockItems = new ObservableCollection<IItemFilterBlockItem> { ActionBlockItem };
Enabled = true;
} }
public bool Enabled { get; set; } public ItemFilterBlock(IItemFilterScript parentScript) : base(parentScript)
{
BlockItems = new ObservableCollection<IItemFilterBlockItem> { ActionBlockItem };
}
public bool Enabled { get; set; } = true;
public string Description { get; set; } public string Description { get; set; }
public ItemFilterBlockGroup BlockGroup public ItemFilterBlockGroup BlockGroup
{ {
get { return _blockGroup; } get => _blockGroup;
set set
{ {
var oldBlockGroup = _blockGroup; var oldBlockGroup = _blockGroup;
@ -79,17 +117,19 @@ namespace Filtration.ObjectModel
} }
} }
public ActionBlockItem ActionBlockItem { get; } = new ActionBlockItem(BlockAction.Show);
public ObservableCollection<IItemFilterBlockItem> BlockItems { get; } public ObservableCollection<IItemFilterBlockItem> BlockItems { get; }
public int BlockCount(Type type) public bool AddBlockItemAllowed(Type type)
{
int BlockCount()
{ {
return BlockItems?.Count(b => b.GetType() == type) ?? 0; return BlockItems?.Count(b => b.GetType() == type) ?? 0;
} }
public bool AddBlockItemAllowed(Type type)
{
var blockItem = (IItemFilterBlockItem)Activator.CreateInstance(type); var blockItem = (IItemFilterBlockItem)Activator.CreateInstance(type);
return BlockCount(type) < blockItem.MaximumAllowed; return BlockCount() < blockItem.MaximumAllowed;
} }
public bool HasBlockItemOfType<T>() public bool HasBlockItemOfType<T>()

View File

@ -1,45 +1,101 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using Filtration.ObjectModel.Annotations;
using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.BlockItemTypes;
using Filtration.ObjectModel.Commands;
using Filtration.ObjectModel.ThemeEditor; using Filtration.ObjectModel.ThemeEditor;
namespace Filtration.ObjectModel namespace Filtration.ObjectModel
{ {
public interface IItemFilterScript public interface IItemFilterScript : INotifyPropertyChanged
{ {
ObservableCollection<IItemFilterBlock> ItemFilterBlocks { get; } ICommandManager CommandManager { get; }
ObservableCollection<IItemFilterBlockBase> ItemFilterBlocks { get; }
ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; } ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; }
ThemeComponentCollection ThemeComponents { get; set; } ThemeComponentCollection ThemeComponents { get; set; }
string FilePath { get; set; } string FilePath { get; set; }
string Description { get; set; } string Description { get; set; }
DateTime DateModified { get; set; } DateTime DateModified { get; set; }
bool IsDirty { get; }
IItemFilterScriptSettings ItemFilterScriptSettings { get; }
List<string> Validate(); List<string> Validate();
void ReplaceColors(ReplaceColorsParameterSet replaceColorsParameterSet); void ReplaceColors(ReplaceColorsParameterSet replaceColorsParameterSet);
} }
public class ItemFilterScript : IItemFilterScript public interface IItemFilterScriptInternal : IItemFilterScript
{ {
public ItemFilterScript() void SetIsDirty(bool isDirty);
}
public class ItemFilterScript : IItemFilterScriptInternal
{ {
ItemFilterBlocks = new ObservableCollection<IItemFilterBlock>(); private bool _isDirty;
private string _description;
internal ItemFilterScript()
{
ItemFilterBlocks = new ObservableCollection<IItemFilterBlockBase>();
ItemFilterBlockGroups = new ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups = new ObservableCollection<ItemFilterBlockGroup>
{ {
new ItemFilterBlockGroup("Root", null) new ItemFilterBlockGroup("Root", null)
}; };
ThemeComponents = new ThemeComponentCollection { IsMasterCollection = true }; ThemeComponents = new ThemeComponentCollection { IsMasterCollection = true };
ItemFilterScriptSettings = new ItemFilterScriptSettings(ThemeComponents);
} }
public ObservableCollection<IItemFilterBlock> ItemFilterBlocks { get; } public ItemFilterScript(ICommandManagerInternal commandManager) : this()
{
CommandManager = commandManager;
commandManager.SetScript(this);
}
public ICommandManager CommandManager { get; }
public ObservableCollection<IItemFilterBlockBase> ItemFilterBlocks { get; }
public ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; } public ObservableCollection<ItemFilterBlockGroup> ItemFilterBlockGroups { get; }
public ThemeComponentCollection ThemeComponents { get; set; } public ThemeComponentCollection ThemeComponents { get; set; }
public IItemFilterScriptSettings ItemFilterScriptSettings { get; }
public string FilePath { get; set; } 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 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() public List<string> Validate()
{ {
var validationErrors = new List<string>(); var validationErrors = new List<string>();
@ -54,9 +110,7 @@ namespace Filtration.ObjectModel
public void ReplaceColors(ReplaceColorsParameterSet replaceColorsParameterSet) public void ReplaceColors(ReplaceColorsParameterSet replaceColorsParameterSet)
{ {
foreach ( foreach (var block in ItemFilterBlocks.OfType<ItemFilterBlock>().Where(b => BlockIsColorReplacementCandidate(replaceColorsParameterSet, b)))
var block in
ItemFilterBlocks.Where(b => BlockIsColorReplacementCandidate(replaceColorsParameterSet, b)))
{ {
if (replaceColorsParameterSet.ReplaceTextColor) if (replaceColorsParameterSet.ReplaceTextColor)
{ {
@ -78,15 +132,9 @@ namespace Filtration.ObjectModel
private bool BlockIsColorReplacementCandidate(ReplaceColorsParameterSet replaceColorsParameterSet, IItemFilterBlock block) private bool BlockIsColorReplacementCandidate(ReplaceColorsParameterSet replaceColorsParameterSet, IItemFilterBlock block)
{ {
var textColorItem = block.HasBlockItemOfType<TextColorBlockItem>() var textColorItem = block.BlockItems.OfType<TextColorBlockItem>().FirstOrDefault();
? block.BlockItems.OfType<TextColorBlockItem>().First() var backgroundColorItem = block.BlockItems.OfType<BackgroundColorBlockItem>().FirstOrDefault();
: null; var borderColorItem = block.BlockItems.OfType<BorderColorBlockItem>().FirstOrDefault();
var backgroundColorItem = block.HasBlockItemOfType<BackgroundColorBlockItem>()
? block.BlockItems.OfType<BackgroundColorBlockItem>().First()
: null;
var borderColorItem = block.HasBlockItemOfType<BorderColorBlockItem>()
? block.BlockItems.OfType<BorderColorBlockItem>().First()
: null;
// If we don't have all of the things we want to replace, then we aren't a candidate for replacing those things. // If we don't have all of the things we want to replace, then we aren't a candidate for replacing those things.
if ((textColorItem == null && replaceColorsParameterSet.ReplaceTextColor) || if ((textColorItem == null && replaceColorsParameterSet.ReplaceTextColor) ||
@ -109,5 +157,12 @@ namespace Filtration.ObjectModel
return true; return true;
} }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }

View File

@ -0,0 +1,21 @@
using Filtration.ObjectModel.ThemeEditor;
namespace Filtration.ObjectModel
{
public interface IItemFilterScriptSettings
{
bool BlockGroupsEnabled { get; set; }
ThemeComponentCollection ThemeComponentCollection { get; }
}
public class ItemFilterScriptSettings : IItemFilterScriptSettings
{
public ItemFilterScriptSettings(ThemeComponentCollection themeComponentCollection)
{
ThemeComponentCollection = themeComponentCollection;
}
public bool BlockGroupsEnabled { get; set; }
public ThemeComponentCollection ThemeComponentCollection { get; }
}
}

View File

@ -1,6 +0,0 @@
namespace Filtration.ObjectModel
{
public class ItemFilterSection : ItemFilterBlock
{
}
}

View File

@ -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 #pragma warning disable 1591
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
@ -7,7 +29,6 @@
// ReSharper disable IntroduceOptionalParameters.Global // ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable MemberCanBeProtected.Global // ReSharper disable MemberCanBeProtected.Global
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
// ReSharper disable CheckNamespace
namespace Filtration.ObjectModel.Annotations namespace Filtration.ObjectModel.Annotations
{ {
@ -16,32 +37,37 @@ namespace Filtration.ObjectModel.Annotations
/// so the check for <c>null</c> is necessary before its usage. /// so the check for <c>null</c> is necessary before its usage.
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// [CanBeNull] public object Test() { return null; } /// [CanBeNull] object Test() => null;
/// public void UseTest() { ///
/// void UseTest() {
/// var p = Test(); /// var p = Test();
/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' /// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
/// } /// }
/// </code></example> /// </code></example>
[AttributeUsage( [AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | 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 { } public sealed class CanBeNullAttribute : Attribute { }
/// <summary> /// <summary>
/// Indicates that the value of the marked element could never be <c>null</c>. /// Indicates that the value of the marked element could never be <c>null</c>.
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// [NotNull] public object Foo() { /// [NotNull] object Foo() {
/// return null; // Warning: Possible 'null' assignment /// return null; // Warning: Possible 'null' assignment
/// } /// }
/// </code></example> /// </code></example>
[AttributeUsage( [AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | 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 { } public sealed class NotNullAttribute : Attribute { }
/// <summary> /// <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> /// </summary>
[AttributeUsage( [AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
@ -49,7 +75,9 @@ namespace Filtration.ObjectModel.Annotations
public sealed class ItemNotNullAttribute : Attribute { } public sealed class ItemNotNullAttribute : Attribute { }
/// <summary> /// <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> /// </summary>
[AttributeUsage( [AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
@ -63,8 +91,9 @@ namespace Filtration.ObjectModel.Annotations
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// [StringFormatMethod("message")] /// [StringFormatMethod("message")]
/// public void ShowError(string message, params object[] args) { /* do something */ } /// void ShowError(string message, params object[] args) { /* do something */ }
/// public void Foo() { ///
/// void Foo() {
/// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string /// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
/// } /// }
/// </code></example> /// </code></example>
@ -76,22 +105,24 @@ namespace Filtration.ObjectModel.Annotations
/// <param name="formatParameterName"> /// <param name="formatParameterName">
/// Specifies which parameter of an annotated method should be treated as format-string /// Specifies which parameter of an annotated method should be treated as format-string
/// </param> /// </param>
public StringFormatMethodAttribute(string formatParameterName) public StringFormatMethodAttribute([NotNull] string formatParameterName)
{ {
FormatParameterName = formatParameterName; FormatParameterName = formatParameterName;
} }
public string FormatParameterName { get; private set; } [NotNull] public string FormatParameterName { get; private set; }
} }
/// <summary> /// <summary>
/// For a parameter that is expected to be one of the limited set of values. /// 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. /// Specify fields of which type should be used as values for this parameter.
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] [AttributeUsage(
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field,
AllowMultiple = true)]
public sealed class ValueProviderAttribute : Attribute public sealed class ValueProviderAttribute : Attribute
{ {
public ValueProviderAttribute(string name) public ValueProviderAttribute([NotNull] string name)
{ {
Name = name; Name = name;
} }
@ -105,7 +136,7 @@ namespace Filtration.ObjectModel.Annotations
/// the parameter of <see cref="System.ArgumentNullException"/>. /// the parameter of <see cref="System.ArgumentNullException"/>.
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// public void Foo(string param) { /// void Foo(string param) {
/// if (param == null) /// if (param == null)
/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol /// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
/// } /// }
@ -131,10 +162,12 @@ namespace Filtration.ObjectModel.Annotations
/// <example><code> /// <example><code>
/// public class Foo : INotifyPropertyChanged { /// public class Foo : INotifyPropertyChanged {
/// public event PropertyChangedEventHandler PropertyChanged; /// public event PropertyChangedEventHandler PropertyChanged;
///
/// [NotifyPropertyChangedInvocator] /// [NotifyPropertyChangedInvocator]
/// protected virtual void NotifyChanged(string propertyName) { ... } /// protected virtual void NotifyChanged(string propertyName) { ... }
/// ///
/// private string _name; /// string _name;
///
/// public string Name { /// public string Name {
/// get { return _name; } /// get { return _name; }
/// set { _name = value; NotifyChanged("LastName"); /* Warning */ } /// set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@ -153,12 +186,12 @@ namespace Filtration.ObjectModel.Annotations
public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute
{ {
public NotifyPropertyChangedInvocatorAttribute() { } public NotifyPropertyChangedInvocatorAttribute() { }
public NotifyPropertyChangedInvocatorAttribute(string parameterName) public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName)
{ {
ParameterName = parameterName; ParameterName = parameterName;
} }
public string ParameterName { get; private set; } [CanBeNull] public string ParameterName { get; private set; }
} }
/// <summary> /// <summary>
@ -174,15 +207,16 @@ namespace Filtration.ObjectModel.Annotations
/// <item>Value ::= true | false | null | notnull | canbenull</item> /// <item>Value ::= true | false | null | notnull | canbenull</item>
/// </list> /// </list>
/// If method has single input parameter, it's name could be omitted.<br/> /// 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) /// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same) for method output
/// for method output means that the methos doesn't return normally.<br/> /// means that the methos doesn't return normally (throws or terminates the process).<br/>
/// <c>canbenull</c> annotation is only applicable for output parameters.<br/> /// Value <c>canbenull</c> is only applicable for output parameters.<br/>
/// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, /// You can use multiple <c>[ContractAnnotation]</c> for each FDT row, or use single attribute
/// or use single attribute with rows separated by semicolon.<br/> /// 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> /// </syntax>
/// <examples><list> /// <examples><list>
/// <item><code> /// <item><code>
/// [ContractAnnotation("=> halt")] /// [ContractAnnotation("=&gt; halt")]
/// public void TerminationMethod() /// public void TerminationMethod()
/// </code></item> /// </code></item>
/// <item><code> /// <item><code>
@ -190,17 +224,17 @@ namespace Filtration.ObjectModel.Annotations
/// public void Assert(bool condition, string text) // regular assertion method /// public void Assert(bool condition, string text) // regular assertion method
/// </code></item> /// </code></item>
/// <item><code> /// <item><code>
/// [ContractAnnotation("s:null => true")] /// [ContractAnnotation("s:null =&gt; true")]
/// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty() /// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
/// </code></item> /// </code></item>
/// <item><code> /// <item><code>
/// // A method that returns null if the parameter is null, /// // A method that returns null if the parameter is null,
/// // and not null if the parameter is not null /// // and not null if the parameter is not null
/// [ContractAnnotation("null => null; notnull => notnull")] /// [ContractAnnotation("null =&gt; null; notnull =&gt; notnull")]
/// public object Transform(object data) /// public object Transform(object data)
/// </code></item> /// </code></item>
/// <item><code> /// <item><code>
/// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] /// [ContractAnnotation("=&gt; true, result: notnull; =&gt; false, result: null")]
/// public bool TryParse(string s, out Person result) /// public bool TryParse(string s, out Person result)
/// </code></item> /// </code></item>
/// </list></examples> /// </list></examples>
@ -216,7 +250,8 @@ namespace Filtration.ObjectModel.Annotations
ForceFullStates = forceFullStates; ForceFullStates = forceFullStates;
} }
public string Contract { get; private set; } [NotNull] public string Contract { get; private set; }
public bool ForceFullStates { get; private set; } public bool ForceFullStates { get; private set; }
} }
@ -225,14 +260,15 @@ namespace Filtration.ObjectModel.Annotations
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// [LocalizationRequiredAttribute(true)] /// [LocalizationRequiredAttribute(true)]
/// public class Foo { /// class Foo {
/// private string str = "my string"; // Warning: Localizable string /// string str = "my string"; // Warning: Localizable string
/// } /// }
/// </code></example> /// </code></example>
[AttributeUsage(AttributeTargets.All)] [AttributeUsage(AttributeTargets.All)]
public sealed class LocalizationRequiredAttribute : Attribute public sealed class LocalizationRequiredAttribute : Attribute
{ {
public LocalizationRequiredAttribute() : this(true) { } public LocalizationRequiredAttribute() : this(true) { }
public LocalizationRequiredAttribute(bool required) public LocalizationRequiredAttribute(bool required)
{ {
Required = required; Required = required;
@ -250,8 +286,9 @@ namespace Filtration.ObjectModel.Annotations
/// <example><code> /// <example><code>
/// [CannotApplyEqualityOperator] /// [CannotApplyEqualityOperator]
/// class NoEquality { } /// class NoEquality { }
///
/// class UsesNoEquality { /// class UsesNoEquality {
/// public void Test() { /// void Test() {
/// var ca1 = new NoEquality(); /// var ca1 = new NoEquality();
/// var ca2 = new NoEquality(); /// var ca2 = new NoEquality();
/// if (ca1 != null) { // OK /// if (ca1 != null) { // OK
@ -269,9 +306,10 @@ namespace Filtration.ObjectModel.Annotations
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// [BaseTypeRequired(typeof(IComponent)] // Specify requirement /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement
/// public class ComponentAttribute : Attribute { } /// class ComponentAttribute : Attribute { }
///
/// [Component] // ComponentAttribute requires implementing IComponent interface /// [Component] // ComponentAttribute requires implementing IComponent interface
/// public class MyComponent : IComponent { } /// class MyComponent : IComponent { }
/// </code></example> /// </code></example>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
[BaseTypeRequired(typeof(Attribute))] [BaseTypeRequired(typeof(Attribute))]
@ -308,6 +346,7 @@ namespace Filtration.ObjectModel.Annotations
} }
public ImplicitUseKindFlags UseKindFlags { get; private set; } public ImplicitUseKindFlags UseKindFlags { get; private set; }
public ImplicitUseTargetFlags TargetFlags { 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 ImplicitUseKindFlags UseKindFlags { get; private set; }
[UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; } [UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; }
} }
@ -377,12 +417,13 @@ namespace Filtration.ObjectModel.Annotations
public sealed class PublicAPIAttribute : Attribute public sealed class PublicAPIAttribute : Attribute
{ {
public PublicAPIAttribute() { } public PublicAPIAttribute() { }
public PublicAPIAttribute([NotNull] string comment) public PublicAPIAttribute([NotNull] string comment)
{ {
Comment = comment; Comment = comment;
} }
public string Comment { get; private set; } [CanBeNull] public string Comment { get; private set; }
} }
/// <summary> /// <summary>
@ -398,15 +439,51 @@ namespace Filtration.ObjectModel.Annotations
/// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>. /// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>.
/// </summary> /// </summary>
/// <example><code> /// <example><code>
/// [Pure] private int Multiply(int x, int y) { return x * y; } /// [Pure] int Multiply(int x, int y) => x * y;
/// public void Foo() { ///
/// const int a = 2, b = 2; /// void M() {
/// Multiply(a, b); // Waring: Return value of pure method is not used /// Multiply(123, 42); // Waring: Return value of pure method is not used
/// } /// }
/// </code></example> /// </code></example>
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method)]
public sealed class PureAttribute : Attribute { } 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> /// <summary>
/// Indicates that a parameter is a path to a file or a folder within a web project. /// 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 (~). /// Path can be relative or absolute, starting from web root (~).
@ -415,12 +492,13 @@ namespace Filtration.ObjectModel.Annotations
public sealed class PathReferenceAttribute : Attribute public sealed class PathReferenceAttribute : Attribute
{ {
public PathReferenceAttribute() { } public PathReferenceAttribute() { }
public PathReferenceAttribute([PathReference] string basePath)
public PathReferenceAttribute([NotNull, PathReference] string basePath)
{ {
BasePath = basePath; BasePath = basePath;
} }
public string BasePath { get; private set; } [CanBeNull] public string BasePath { get; private set; }
} }
/// <summary> /// <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> /// Allows specifying a macro that will be executed for a <see cref="SourceTemplateAttribute">source template</see>
/// parameter when the template is expanded. /// parameter when the template is expanded.
/// </summary> /// </summary>
public string Expression { get; set; } [CanBeNull] public string Expression { get; set; }
/// <summary> /// <summary>
/// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. /// 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 /// Identifies the target parameter of a <see cref="SourceTemplateAttribute">source template</see> if the
/// <see cref="MacroAttribute"/> is applied on a template method. /// <see cref="MacroAttribute"/> is applied on a template method.
/// </summary> /// </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 sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute
{ {
public AspMvcAreaMasterLocationFormatAttribute(string format) public AspMvcAreaMasterLocationFormatAttribute([NotNull] string format)
{ {
Format = 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 sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute
{ {
public AspMvcAreaPartialViewLocationFormatAttribute(string format) public AspMvcAreaPartialViewLocationFormatAttribute([NotNull] string format)
{ {
Format = 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 sealed class AspMvcAreaViewLocationFormatAttribute : Attribute
{ {
public AspMvcAreaViewLocationFormatAttribute(string format) public AspMvcAreaViewLocationFormatAttribute([NotNull] string format)
{ {
Format = 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 sealed class AspMvcMasterLocationFormatAttribute : Attribute
{ {
public AspMvcMasterLocationFormatAttribute(string format) public AspMvcMasterLocationFormatAttribute([NotNull] string format)
{ {
Format = 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 sealed class AspMvcPartialViewLocationFormatAttribute : Attribute
{ {
public AspMvcPartialViewLocationFormatAttribute(string format) public AspMvcPartialViewLocationFormatAttribute([NotNull] string format)
{ {
Format = 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 sealed class AspMvcViewLocationFormatAttribute : Attribute
{ {
public AspMvcViewLocationFormatAttribute(string format) public AspMvcViewLocationFormatAttribute([NotNull] string format)
{ {
Format = format; Format = format;
} }
public string Format { get; private set; } [NotNull] public string Format { get; private set; }
} }
/// <summary> /// <summary>
@ -579,12 +657,13 @@ namespace Filtration.ObjectModel.Annotations
public sealed class AspMvcActionAttribute : Attribute public sealed class AspMvcActionAttribute : Attribute
{ {
public AspMvcActionAttribute() { } public AspMvcActionAttribute() { }
public AspMvcActionAttribute(string anonymousProperty)
public AspMvcActionAttribute([NotNull] string anonymousProperty)
{ {
AnonymousProperty = anonymousProperty; AnonymousProperty = anonymousProperty;
} }
public string AnonymousProperty { get; private set; } [CanBeNull] public string AnonymousProperty { get; private set; }
} }
/// <summary> /// <summary>
@ -596,12 +675,13 @@ namespace Filtration.ObjectModel.Annotations
public sealed class AspMvcAreaAttribute : Attribute public sealed class AspMvcAreaAttribute : Attribute
{ {
public AspMvcAreaAttribute() { } public AspMvcAreaAttribute() { }
public AspMvcAreaAttribute(string anonymousProperty)
public AspMvcAreaAttribute([NotNull] string anonymousProperty)
{ {
AnonymousProperty = anonymousProperty; AnonymousProperty = anonymousProperty;
} }
public string AnonymousProperty { get; private set; } [CanBeNull] public string AnonymousProperty { get; private set; }
} }
/// <summary> /// <summary>
@ -614,12 +694,13 @@ namespace Filtration.ObjectModel.Annotations
public sealed class AspMvcControllerAttribute : Attribute public sealed class AspMvcControllerAttribute : Attribute
{ {
public AspMvcControllerAttribute() { } public AspMvcControllerAttribute() { }
public AspMvcControllerAttribute(string anonymousProperty)
public AspMvcControllerAttribute([NotNull] string anonymousProperty)
{ {
AnonymousProperty = anonymousProperty; AnonymousProperty = anonymousProperty;
} }
public string AnonymousProperty { get; private set; } [CanBeNull] public string AnonymousProperty { get; private set; }
} }
/// <summary> /// <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. /// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method.
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class AspMvcSupressViewErrorAttribute : Attribute { } public sealed class AspMvcSuppressViewErrorAttribute : Attribute { }
/// <summary> /// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template. /// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template.
@ -677,13 +758,27 @@ namespace Filtration.ObjectModel.Annotations
/// <summary> /// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter /// 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 /// from the context. Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Controller.View(Object)</c>. /// <c>System.Web.Mvc.Controller.View(Object)</c>.
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcViewAttribute : Attribute { } 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> /// <summary>
/// ASP.NET MVC attribute. When applied to a parameter of an attribute, /// ASP.NET MVC attribute. When applied to a parameter of an attribute,
/// indicates that this parameter is an MVC action name. /// indicates that this parameter is an MVC action name.
@ -702,12 +797,13 @@ namespace Filtration.ObjectModel.Annotations
public sealed class HtmlElementAttributesAttribute : Attribute public sealed class HtmlElementAttributesAttribute : Attribute
{ {
public HtmlElementAttributesAttribute() { } public HtmlElementAttributesAttribute() { }
public HtmlElementAttributesAttribute(string name)
public HtmlElementAttributesAttribute([NotNull] string name)
{ {
Name = name; Name = name;
} }
public string Name { get; private set; } [CanBeNull] public string Name { get; private set; }
} }
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]
@ -730,9 +826,10 @@ namespace Filtration.ObjectModel.Annotations
public sealed class RazorSectionAttribute : Attribute { } public sealed class RazorSectionAttribute : Attribute { }
/// <summary> /// <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> /// </summary>
[AttributeUsage(AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)]
public sealed class CollectionAccessAttribute : Attribute public sealed class CollectionAccessAttribute : Attribute
{ {
public CollectionAccessAttribute(CollectionAccessType collectionAccessType) public CollectionAccessAttribute(CollectionAccessType collectionAccessType)
@ -824,6 +921,16 @@ namespace Filtration.ObjectModel.Annotations
[AttributeUsage(AttributeTargets.Parameter)] [AttributeUsage(AttributeTargets.Parameter)]
public sealed class RegexPatternAttribute : Attribute { } 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> /// <summary>
/// XAML attribute. Indicates the type that has <c>ItemsSource</c> property and should be treated /// 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. /// 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 { } public sealed class XamlItemsControlAttribute : Attribute { }
/// <summary> /// <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 /// 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. /// enable the <c>DataContext</c> type resolve for XAML bindings for such properties.
/// </summary> /// </summary>
@ -846,14 +953,15 @@ namespace Filtration.ObjectModel.Annotations
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class AspChildControlTypeAttribute : Attribute public sealed class AspChildControlTypeAttribute : Attribute
{ {
public AspChildControlTypeAttribute(string tagName, Type controlType) public AspChildControlTypeAttribute([NotNull] string tagName, [NotNull] Type controlType)
{ {
TagName = tagName; TagName = tagName;
ControlType = controlType; ControlType = controlType;
} }
public string TagName { get; private set; } [NotNull] public string TagName { get; private set; }
public Type ControlType { get; private set; }
[NotNull] public Type ControlType { get; private set; }
} }
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]
@ -873,7 +981,7 @@ namespace Filtration.ObjectModel.Annotations
Attribute = attribute; Attribute = attribute;
} }
public string Attribute { get; private set; } [NotNull] public string Attribute { get; private set; }
} }
[AttributeUsage(AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Property)]
@ -890,25 +998,37 @@ namespace Filtration.ObjectModel.Annotations
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class RazorImportNamespaceAttribute : Attribute public sealed class RazorImportNamespaceAttribute : Attribute
{ {
public RazorImportNamespaceAttribute(string name) public RazorImportNamespaceAttribute([NotNull] string name)
{ {
Name = name; Name = name;
} }
public string Name { get; private set; } [NotNull] public string Name { get; private set; }
} }
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class RazorInjectionAttribute : Attribute public sealed class RazorInjectionAttribute : Attribute
{ {
public RazorInjectionAttribute(string type, string fieldName) public RazorInjectionAttribute([NotNull] string type, [NotNull] string fieldName)
{ {
Type = type; Type = type;
FieldName = fieldName; FieldName = fieldName;
} }
public string Type { get; private set; } [NotNull] public string Type { get; private set; }
public string FieldName { 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)] [AttributeUsage(AttributeTargets.Method)]
@ -925,13 +1045,4 @@ namespace Filtration.ObjectModel.Annotations
[AttributeUsage(AttributeTargets.Parameter)] [AttributeUsage(AttributeTargets.Parameter)]
public sealed class RazorWriteMethodParameterAttribute : Attribute { } 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 { }
} }

View File

@ -1,4 +1,5 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // 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.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("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")]

View File

@ -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());
}
}
}

View File

@ -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());
}
}
}

View File

@ -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>

View File

@ -1,14 +1,16 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.ThemeEditor;
namespace Filtration.Parser.Interface.Services namespace Filtration.Parser.Interface.Services
{ {
public interface IItemFilterBlockTranslator public interface IItemFilterBlockTranslator
{ {
IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScript parentItemFilterScript, bool initialiseBlockGroupHierarchyBuilder = false);
ThemeComponentCollection masterComponentCollection); IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString, IItemFilterScript parentItemFilterScript);
string TranslateItemFilterBlockToString(IItemFilterBlock block); string TranslateItemFilterBlockToString(IItemFilterBlock block);
void ReplaceAudioVisualBlockItemsFromString(ObservableCollection<IItemFilterBlockItem> blockItems, string inputString); void ReplaceAudioVisualBlockItemsFromString(ObservableCollection<IItemFilterBlockItem> blockItems, string inputString);
string TranslateItemFilterCommentBlockToString(IItemFilterCommentBlock itemFilterCommentBlock);
string TranslateItemFilterBlockBaseToString(IItemFilterBlockBase itemFilterBlockBase);
} }
} }

View File

@ -4,7 +4,7 @@ namespace Filtration.Parser.Interface.Services
{ {
public interface IItemFilterScriptTranslator public interface IItemFilterScriptTranslator
{ {
ItemFilterScript TranslateStringToItemFilterScript(string inputString); IItemFilterScript TranslateStringToItemFilterScript(string inputString);
string TranslateItemFilterScriptToString(ItemFilterScript script); string TranslateItemFilterScriptToString(IItemFilterScript script);
} }
} }

View File

@ -40,21 +40,17 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="FluentAssertions, Version=4.13.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <Reference Include="FluentAssertions, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.13.1\lib\net45\FluentAssertions.dll</HintPath> <HintPath>..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="FluentAssertions.Core, Version=4.13.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <Reference Include="FluentAssertions.Core, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.13.1\lib\net45\FluentAssertions.Core.dll</HintPath> <HintPath>..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />
@ -113,6 +109,9 @@
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\testscript2.txt" />
</ItemGroup>
<Choose> <Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup> <ItemGroup>

View File

@ -91,6 +91,37 @@ namespace Filtration.Parser.Tests.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to #Script description
///#Script description
///#Script description
///#Script description
///
///#Comment
///#SomeComment
///
///#Blockdescription
///Show #Flasks - Endgame - Life/Mana - Divine/Eternal - Q10+ - Normal
/// Class &quot;Life Flasks&quot; &quot;Mana Flasks&quot;
/// Rarity Normal
/// DropLevel &gt;= 60
/// Quality &gt;= 10
/// SetFontSize 28
/// SetTextColor 240 240 240 #Normal Item Highlight
///
///#commentymccommentface
///
///Show #Flasks - Endgame - Life/Mana - Divine/Eternal - Q10+ - Normal
/// Class &quot;Life Flasks&quot; &quot;Mana Flasks&quot;
/// Rarity Normal
/// DropL [rest of string was truncated]&quot;;.
/// </summary>
public static string testscript2 {
get {
return ResourceManager.GetString("testscript2", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to ###BETA VERSION 1.0.0.1-8 /// Looks up a localized string similar to ###BETA VERSION 1.0.0.1-8
///#Please test and let me know via pm on reddit /u/brute_force or @Thiole in game if i am online ///#Please test and let me know via pm on reddit /u/brute_force or @Thiole in game if i am online

View File

@ -118,10 +118,13 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ThioleItemFilter" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ThioleItemFilter.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="testscript" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="testscript" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\testscript.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> <value>..\Resources\testscript.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data> </data>
<data name="testscript2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\testscript2.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="ThioleItemFilter" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ThioleItemFilter.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root> </root>

View File

@ -0,0 +1,31 @@
#Script description
#Script description
#Script description
#Script description
#Blockdescription
Show #Flasks - Endgame - Life/Mana - Divine/Eternal - Q10+ - Normal
Class "Life Flasks" "Mana Flasks"
Rarity Normal
SetFontSize 28
# commentymccommentface
Show
Class "Life Flasks" "Mana Flasks"
Rarity Normal
DropLevel >= 60
#commment
#morecomment
#blah
#anothercomment
#notpartofblockdescription
#blockdescription2
Show #TestBlock
Class "Life Flasks" "Mana Flasks"
Rarity Normal

View File

@ -26,6 +26,54 @@ namespace Filtration.Parser.Tests.Services
_testUtility = new ItemFilterBlockTranslatorTestUtility(); _testUtility = new ItemFilterBlockTranslatorTestUtility();
} }
[Test]
public void TranslateStringToItemFilterBlockComment_ReturnsItemFilterBlockCommentWithSpacesNotRemoved()
{
//Arrange
var testInputString = "# This is a comment\r\n# Line 2 \r\n # Test";
//Act
var result = _testUtility.Translator.TranslateStringToItemFilterCommentBlock(testInputString, Mock.Of<IItemFilterScript>());
//Assert
Assert.AreEqual(" This is a comment\r\n Line 2 \r\n Test", result.Comment);
}
[Test]
public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_ActionBlockItemCommentIsNull()
{
// Arrange
var inputString = "Show # Test - Test2 - Test3" + Environment.NewLine;
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
_testUtility.MockBlockGroupHierarchyBuilder
.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()))
.Returns(inputBlockGroup);
// Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
//Assert
Assert.IsTrue(string.IsNullOrEmpty(result.ActionBlockItem.Comment));
}
[Test]
public void TranslateStringToItemFilterBlock_BlockGroupsDisabled_ActionBlockItemCommentIsSetCorrectly()
{
// Arrange
var testInputExpectedComment = " this is a comment that should be preserved";
var inputString = $"Show #{testInputExpectedComment}" + Environment.NewLine;
// Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled == false));
//Assert
Assert.AreEqual(testInputExpectedComment, result.ActionBlockItem.Comment);
}
[Test] [Test]
public void TranslateStringToItemFilterBlock_NotDisabled_SetsBlockEnabledTrue() public void TranslateStringToItemFilterBlock_NotDisabled_SetsBlockEnabledTrue()
{ {
@ -34,7 +82,7 @@ namespace Filtration.Parser.Tests.Services
" ItemLevel >= 55"; " ItemLevel >= 55";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(true, result.Enabled); Assert.AreEqual(true, result.Enabled);
@ -48,7 +96,7 @@ namespace Filtration.Parser.Tests.Services
" ItemLevel >= 55"; " ItemLevel >= 55";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(2, result.BlockItems.Count); Assert.AreEqual(2, result.BlockItems.Count);
@ -64,7 +112,7 @@ namespace Filtration.Parser.Tests.Services
" ItemLevel >= 55"; " ItemLevel >= 55";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is ItemLevelBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is ItemLevelBlockItem));
@ -74,7 +122,7 @@ namespace Filtration.Parser.Tests.Services
} }
[Test] [Test]
public void TranslateStringToItemFilterBlock_BlockGroupComment_CallsBlockGroupHierarchyBuilder() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_ShowBlock_SetsBlockGroupIsCheckedCorrectly()
{ {
// Arrange // Arrange
var inputString = "Show # TestBlockGroup" + Environment.NewLine; var inputString = "Show # TestBlockGroup" + Environment.NewLine;
@ -82,29 +130,14 @@ namespace Filtration.Parser.Tests.Services
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert
_testUtility.MockBlockGroupHierarchyBuilder.Verify();
}
[Test]
public void TranslateStringToItemFilterBlock_ShowBlock_SetsBlockGroupIsCheckedCorrectly()
{
// Arrange
var inputString = "Show # TestBlockGroup" + Environment.NewLine;
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
// Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null);
// Assert // Assert
Assert.AreEqual(true, inputBlockGroup.IsChecked); Assert.AreEqual(true, inputBlockGroup.IsChecked);
} }
[Test] [Test]
public void TranslateStringToItemFilterBlock_HideBlock_SetsBlockGroupIsCheckedCorrectly() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_HideBlock_SetsBlockGroupIsCheckedCorrectly()
{ {
// Arrange // Arrange
var inputString = "Hide # TestBlockGroup" + Environment.NewLine; var inputString = "Hide # TestBlockGroup" + Environment.NewLine;
@ -112,56 +145,108 @@ namespace Filtration.Parser.Tests.Services
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
Assert.AreEqual(false, inputBlockGroup.IsChecked); Assert.AreEqual(false, inputBlockGroup.IsChecked);
} }
[Test] [Test]
public void TranslateStringToItemFilterBlock_NoBlockGroupComment_CallsBlockGroupHierarchyBuilder() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_BlockGroupComment_CallsBlockGroupHierarchyBuilder()
{
// Arrange
var inputString = "Show # TestBlockGroup" + Environment.NewLine;
var inputBlockGroup = new ItemFilterBlockGroup("TestBlockGroup", null);
// Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(inputBlockGroup).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert
_testUtility.MockBlockGroupHierarchyBuilder.Verify();
}
[Test]
public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_NoBlockGroupComment_DoesNotCallBlockGroupHierarchyBuilder()
{ {
// Arrange // Arrange
var inputString = "Show" + Environment.NewLine; var inputString = "Show" + Environment.NewLine;
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Verifiable();
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
_testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never); _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never);
} }
[Test] [Test]
public void TranslateStringToItemFilterBlock_BlockGroupCommentWithNoGroups_DoesNotThrow() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_BlockGroupCommentWithNoGroups_DoesNotThrow()
{ {
// Arrange // Arrange
var inputString = "Show #" + Environment.NewLine; var inputString = "Show #" + Environment.NewLine;
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Verifiable(); _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
_testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null);
// Assert // Assert
_testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never); _testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never);
} }
[Test] [Test]
public void TranslateStringToItemFilterBlock_BlockGroupComment_SetsBlockItemGroupCorrectly() public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_BlockGroupComment_SetsBlockItemGroupCorrectly()
{ {
// Arrange // Arrange
var inputString = "Show # Test Block Group - Test Sub Block Group - Test Another Block Group" + Environment.NewLine; var inputString = "Show # Test Block Group - Test Sub Block Group - Test Another Block Group" + Environment.NewLine;
var testBlockGroup = new ItemFilterBlockGroup("zzzzz", null); var testBlockGroup = new ItemFilterBlockGroup("zzzzz", null);
// Act // Act
_testUtility.MockBlockGroupHierarchyBuilder.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())).Returns(testBlockGroup).Verifiable(); _testUtility.MockBlockGroupHierarchyBuilder
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); .Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.Is<IEnumerable<string>>(s => s.Contains("Test Block Group") && s.Contains("Test Sub Block Group") && s.Contains("Test Another Block Group"))))
.Returns(testBlockGroup)
.Verifiable();
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert // Assert
Assert.AreEqual(testBlockGroup, result.BlockGroup); Assert.AreEqual(testBlockGroup, result.BlockGroup);
_testUtility.MockBlockGroupHierarchyBuilder.Verify(); _testUtility.MockBlockGroupHierarchyBuilder.Verify();
} }
[Test]
public void TranslateStringToItemFilterBlock_BlockGroupsEnabled_BlockGroupComment_NoSpacingAroundHyphens_SetsBlockItemGroupCorrectly()
{
// Arrange
var inputString = "Show # AAA-BBB-CCC" + Environment.NewLine;
var testBlockGroup = new ItemFilterBlockGroup("zzzzz", null);
// Act
_testUtility.MockBlockGroupHierarchyBuilder
.Setup(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.Is<IEnumerable<string>>(s => s.Contains("AAA-BBB-CCC"))))
.Returns(testBlockGroup)
.Verifiable();
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled));
// Assert
Assert.AreEqual(testBlockGroup, result.BlockGroup);
_testUtility.MockBlockGroupHierarchyBuilder.Verify();
}
[Test]
public void TranslateStringToItemFilterBlock_BlockGroupsDisabled_BlockGroupComment_DoesNotCallBlockGroupHierarchyBuilder()
{
// Arrange
var inputString = "Show # AAA - BBB - CCC" + Environment.NewLine;
// Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.BlockGroupsEnabled == false));
// Assert
Assert.IsNull(result.BlockGroup);
_testUtility.MockBlockGroupHierarchyBuilder.Verify(b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()), Times.Never);
}
[Test] [Test]
public void TranslateStringToItemFilterBlock_Hide_ReturnsCorrectObject() public void TranslateStringToItemFilterBlock_Hide_ReturnsCorrectObject()
{ {
@ -169,7 +254,7 @@ namespace Filtration.Parser.Tests.Services
var inputString = "Hide" + Environment.NewLine; var inputString = "Hide" + Environment.NewLine;
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem));
@ -185,7 +270,7 @@ namespace Filtration.Parser.Tests.Services
" ItemLevel >= 55"; " ItemLevel >= 55";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual("This is a test Block", result.Description); Assert.AreEqual("This is a test Block", result.Description);
@ -205,7 +290,7 @@ namespace Filtration.Parser.Tests.Services
" ItemLevel >= 55"; " ItemLevel >= 55";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual("Second Line", result.Description); Assert.AreEqual("Second Line", result.Description);
@ -223,7 +308,7 @@ namespace Filtration.Parser.Tests.Services
" DropLevel = 40"; " DropLevel = 40";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -241,7 +326,7 @@ namespace Filtration.Parser.Tests.Services
" Corrupted True"; " Corrupted True";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -258,7 +343,7 @@ namespace Filtration.Parser.Tests.Services
" Identified True"; " Identified True";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -275,7 +360,7 @@ namespace Filtration.Parser.Tests.Services
" Quality < 18"; " Quality < 18";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -293,7 +378,7 @@ namespace Filtration.Parser.Tests.Services
" Rarity > Normal"; " Rarity > Normal";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -311,7 +396,7 @@ namespace Filtration.Parser.Tests.Services
" Rarity Normal"; " Rarity Normal";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is RarityBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is RarityBlockItem));
@ -328,7 +413,7 @@ namespace Filtration.Parser.Tests.Services
@" Class ""Test Class 1"" ""TestOneWordClassInQuotes"" TestOneWordClassNotInQuotes ""Test Class 2"""; @" Class ""Test Class 1"" ""TestOneWordClassInQuotes"" TestOneWordClassNotInQuotes ""Test Class 2""";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is ClassBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is ClassBlockItem));
@ -347,7 +432,7 @@ namespace Filtration.Parser.Tests.Services
@" BaseType ""Test Base Type 1"" ""TestOneWordBaseTypeInQuotes"" TestOneWordBaseTypeNotInQuotes ""Test BaseType 2"""; @" BaseType ""Test Base Type 1"" ""TestOneWordBaseTypeInQuotes"" TestOneWordBaseTypeNotInQuotes ""Test BaseType 2""";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is BaseTypeBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is BaseTypeBlockItem));
@ -366,7 +451,7 @@ namespace Filtration.Parser.Tests.Services
" Sockets > 2"; " Sockets > 2";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -384,7 +469,7 @@ namespace Filtration.Parser.Tests.Services
" LinkedSockets > 1"; " LinkedSockets > 1";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -402,7 +487,7 @@ namespace Filtration.Parser.Tests.Services
" Width = 1"; " Width = 1";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -420,7 +505,7 @@ namespace Filtration.Parser.Tests.Services
" Height <= 3"; " Height <= 3";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
@ -438,7 +523,7 @@ namespace Filtration.Parser.Tests.Services
" Height <=3"; " Height <=3";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is HeightBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is HeightBlockItem));
@ -455,7 +540,7 @@ namespace Filtration.Parser.Tests.Services
" SocketGroup RRGB"; " SocketGroup RRGB";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is SocketGroupBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is SocketGroupBlockItem));
@ -473,7 +558,7 @@ namespace Filtration.Parser.Tests.Services
" SetTextColor 255 20 100"; " SetTextColor 255 20 100";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem));
@ -491,7 +576,7 @@ namespace Filtration.Parser.Tests.Services
" SetTextColor 65 0 255 12"; " SetTextColor 65 0 255 12";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem));
@ -510,7 +595,7 @@ namespace Filtration.Parser.Tests.Services
" SetBackgroundColor 255 20 100"; " SetBackgroundColor 255 20 100";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is BackgroundColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is BackgroundColorBlockItem));
@ -529,7 +614,7 @@ namespace Filtration.Parser.Tests.Services
" SetBorderColor 255 20 100"; " SetBorderColor 255 20 100";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem));
@ -548,8 +633,8 @@ namespace Filtration.Parser.Tests.Services
// Act // Act
Assert.DoesNotThrow(() => _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null)); Assert.DoesNotThrow(() => _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript));
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem));
@ -569,7 +654,7 @@ namespace Filtration.Parser.Tests.Services
var testInputThemeComponentCollection = new ThemeComponentCollection { testComponent }; var testInputThemeComponentCollection = new ThemeComponentCollection { testComponent };
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, testInputThemeComponentCollection); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.ThemeComponentCollection == testInputThemeComponentCollection));
// Assert // Assert
var blockItem = result.BlockItems.OfType<TextColorBlockItem>().First(); var blockItem = result.BlockItems.OfType<TextColorBlockItem>().First();
@ -587,7 +672,7 @@ namespace Filtration.Parser.Tests.Services
" SetFontSize 15"; " SetFontSize 15";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is FontSizeBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is FontSizeBlockItem));
@ -604,7 +689,7 @@ namespace Filtration.Parser.Tests.Services
" PlayAlertSound 4"; " PlayAlertSound 4";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem));
@ -622,7 +707,7 @@ namespace Filtration.Parser.Tests.Services
" PlayAlertSound 2 95"; " PlayAlertSound 2 95";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem));
@ -631,21 +716,6 @@ namespace Filtration.Parser.Tests.Services
Assert.AreEqual(95, blockItem.SecondValue); Assert.AreEqual(95, blockItem.SecondValue);
} }
[Test]
public void TranslateStringToItemFilterBlock_SectionComment_ReturnsItemFilterSectionObjectWithCorrectDescription()
{
// Arrange
const string testInputSectionDescription = "Wonderful items that you definitely won't want to miss!";
var inputString = "# Section: " + testInputSectionDescription;
// Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null);
// Assert
Assert.IsInstanceOf<ItemFilterSection>(result);
Assert.AreEqual(testInputSectionDescription, result.Description);
}
[Test] [Test]
public void TranslateStringToItemFilterBlock_Everything_ReturnsCorrectObject() public void TranslateStringToItemFilterBlock_Everything_ReturnsCorrectObject()
{ {
@ -674,7 +744,7 @@ namespace Filtration.Parser.Tests.Services
" PlayAlertSound 3"; " PlayAlertSound 3";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual("Test filter with everything", result.Description); Assert.AreEqual("Test filter with everything", result.Description);
@ -762,7 +832,7 @@ namespace Filtration.Parser.Tests.Services
" Quality < 17"; " Quality < 17";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(2, result.BlockItems.Count(b => b is ItemLevelBlockItem)); Assert.AreEqual(2, result.BlockItems.Count(b => b is ItemLevelBlockItem));
@ -791,7 +861,7 @@ namespace Filtration.Parser.Tests.Services
" SetTextColor 255 20 100"; " SetTextColor 255 20 100";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is TextColorBlockItem));
@ -812,7 +882,7 @@ namespace Filtration.Parser.Tests.Services
" SetFontSize 27" + Environment.NewLine; " SetFontSize 27" + Environment.NewLine;
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is FontSizeBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is FontSizeBlockItem));
@ -831,7 +901,7 @@ namespace Filtration.Parser.Tests.Services
" PlayAlertSound 2" + Environment.NewLine; " PlayAlertSound 2" + Environment.NewLine;
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is SoundBlockItem));
@ -849,7 +919,7 @@ namespace Filtration.Parser.Tests.Services
" SetBackgroundColor 255 20 100"; " SetBackgroundColor 255 20 100";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is BackgroundColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is BackgroundColorBlockItem));
@ -868,7 +938,7 @@ namespace Filtration.Parser.Tests.Services
" SetBorderColor 255 20 100"; " SetBorderColor 255 20 100";
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is BorderColorBlockItem));
@ -896,7 +966,7 @@ namespace Filtration.Parser.Tests.Services
_testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4)); _testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4));
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is RarityBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is RarityBlockItem));
@ -923,7 +993,7 @@ namespace Filtration.Parser.Tests.Services
_testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4)); _testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4));
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem));
@ -958,7 +1028,7 @@ namespace Filtration.Parser.Tests.Services
_testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4)); _testUtility.TestBlock.BlockItems.Add(new WidthBlockItem(FilterPredicateOperator.Equal, 4));
// Act // Act
var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, null); var result = _testUtility.Translator.TranslateStringToItemFilterBlock(inputString, _testUtility.MockItemFilterScript);
// Assert // Assert
Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem)); Assert.AreEqual(1, result.BlockItems.Count(b => b is ActionBlockItem));
@ -1006,6 +1076,22 @@ namespace Filtration.Parser.Tests.Services
Assert.AreEqual(expectedResult, result); Assert.AreEqual(expectedResult, result);
} }
[Test]
public void TranslateItemFilterBlockToString_HasActionBlockComment_ReturnsCorrectString()
{
// Arrange
var testInputActionBlockComment = "this is a test";
var expectedResult = $"Show #{testInputActionBlockComment}";
_testUtility.TestBlock.BlockItems.OfType<ActionBlockItem>().First().Comment = testInputActionBlockComment;
// Act
var result = _testUtility.Translator.TranslateItemFilterBlockToString(_testUtility.TestBlock);
// Assert
Assert.AreEqual(expectedResult, result);
}
[Test] [Test]
public void TranslateItemFilterBlockToString_FilterTypeHide_ReturnsCorrectString() public void TranslateItemFilterBlockToString_FilterTypeHide_ReturnsCorrectString()
{ {
@ -1482,22 +1568,6 @@ namespace Filtration.Parser.Tests.Services
Assert.AreEqual(expectedResult, result); Assert.AreEqual(expectedResult, result);
} }
[Test]
public void TranslateItemFilterBlockToString_Section_ReturnsCorrectString()
{
// Arrange
const string testInputSectionText = "Ermagerd it's a section!";
var expectedResult = "# Section: " + testInputSectionText;
_testUtility.TestBlock = new ItemFilterSection { Description = testInputSectionText };
// Act
var result = _testUtility.Translator.TranslateItemFilterBlockToString(_testUtility.TestBlock);
// Assert
Assert.AreEqual(expectedResult, result);
}
[Test] [Test]
public void TranslateItemFilterBlockToString_DisabledBlock_ReturnsCorrectString() public void TranslateItemFilterBlockToString_DisabledBlock_ReturnsCorrectString()
{ {
@ -1789,6 +1859,7 @@ namespace Filtration.Parser.Tests.Services
// Assert // Assert
} }
private class ItemFilterBlockTranslatorTestUtility private class ItemFilterBlockTranslatorTestUtility
{ {
public ItemFilterBlockTranslatorTestUtility() public ItemFilterBlockTranslatorTestUtility()
@ -1798,6 +1869,7 @@ namespace Filtration.Parser.Tests.Services
// Mock setups // Mock setups
MockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>(); MockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
MockItemFilterScript = Mock.Of<IItemFilterScript>(i => i.ItemFilterScriptSettings.ThemeComponentCollection == new ThemeComponentCollection());
// Class under test instantiation // Class under test instantiation
Translator = new ItemFilterBlockTranslator(MockBlockGroupHierarchyBuilder.Object); Translator = new ItemFilterBlockTranslator(MockBlockGroupHierarchyBuilder.Object);
@ -1806,6 +1878,8 @@ namespace Filtration.Parser.Tests.Services
public ItemFilterBlock TestBlock { get; set; } public ItemFilterBlock TestBlock { get; set; }
public Mock<IBlockGroupHierarchyBuilder> MockBlockGroupHierarchyBuilder { get; } public Mock<IBlockGroupHierarchyBuilder> MockBlockGroupHierarchyBuilder { get; }
public ItemFilterBlockTranslator Translator { get; } public ItemFilterBlockTranslator Translator { get; }
public IItemFilterScript MockItemFilterScript { get; }
} }
} }
} }

View File

@ -1,14 +1,17 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.BlockItemTypes;
using Filtration.ObjectModel.Enums; using Filtration.ObjectModel.Enums;
using Filtration.ObjectModel.Factories;
using Filtration.ObjectModel.ThemeEditor; using Filtration.ObjectModel.ThemeEditor;
using Filtration.Parser.Interface.Services; using Filtration.Parser.Interface.Services;
using Filtration.Parser.Services; using Filtration.Parser.Services;
using Filtration.Parser.Tests.Properties; using Filtration.Parser.Tests.Properties;
using Filtration.Properties; using Filtration.Properties;
using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -17,12 +20,9 @@ namespace Filtration.Parser.Tests.Services
[TestFixture] [TestFixture]
public class TestItemFilterScriptTranslator public class TestItemFilterScriptTranslator
{ {
private ItemFilterScriptTranslatorTestUtility _testUtility;
[SetUp] [SetUp]
public void ItemFilterScriptTranslatorTestSetup() public void ItemFilterScriptTranslatorTestSetup()
{ {
_testUtility = new ItemFilterScriptTranslatorTestUtility();
Settings.Default.Reset(); Settings.Default.Reset();
} }
@ -32,14 +32,15 @@ namespace Filtration.Parser.Tests.Services
// Arrange // Arrange
var testInput = Resources.testscript; var testInput = Resources.testscript;
_testUtility.MockItemFilterBlockTranslator.Setup(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>(), It.IsAny<ThemeComponentCollection>())).Verifiable(); var mockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>();
var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: mockItemFilterBlockTranslator.Object);
// Act // Act
var script = _testUtility.ScriptTranslator.TranslateStringToItemFilterScript(testInput); var script = translator.TranslateStringToItemFilterScript(testInput);
// Assert // Assert
Assert.AreEqual(5, script.ItemFilterBlocks.Count); Assert.AreEqual(5, script.ItemFilterBlocks.Count);
_testUtility.MockItemFilterBlockTranslator.Verify(); mockItemFilterBlockTranslator.Verify(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>(), It.IsAny<IItemFilterScript>(), false));
} }
[Test] [Test]
@ -54,11 +55,10 @@ namespace Filtration.Parser.Tests.Services
Environment.NewLine + Environment.NewLine +
"End Script Description"; "End Script Description";
var mockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>(); var translator = CreateItemFilterScriptTranslator();
mockItemFilterBlockTranslator.Setup(t => t.TranslateStringToItemFilterBlock(It.IsAny<string>(), It.IsAny<ThemeComponentCollection>())).Verifiable();
// Act // Act
var script = _testUtility.ScriptTranslator.TranslateStringToItemFilterScript(testInput); var script = translator.TranslateStringToItemFilterScript(testInput);
// Assert // Assert
Assert.AreEqual(expectedDescription, script.Description); Assert.AreEqual(expectedDescription, script.Description);
@ -70,8 +70,8 @@ namespace Filtration.Parser.Tests.Services
// Arrange // Arrange
var testInput = Resources.ThioleItemFilter; var testInput = Resources.ThioleItemFilter;
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, _testUtility.MockBlockGroupHierarchyBuilder.Object); var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
// Act // Act
translator.TranslateStringToItemFilterScript(testInput); translator.TranslateStringToItemFilterScript(testInput);
@ -80,6 +80,36 @@ namespace Filtration.Parser.Tests.Services
// Not crashing out when loading a huge script means this integration test has passed! // Not crashing out when loading a huge script means this integration test has passed!
} }
[Test]
public void TranslateStringToItemFilterScript_Blah()
{
// Arrange
var testInput = Resources.testscript2;
var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
// Act
var result = translator.TranslateStringToItemFilterScript(testInput);
// Assert
var expectedResult = Mock.Of<IItemFilterScript>(s => s.ItemFilterBlocks == new ObservableCollection<IItemFilterBlockBase>
{
Mock.Of<IItemFilterBlock>(c => c.Description == "Blockdescription"),
Mock.Of<IItemFilterCommentBlock>(c => c.Comment == " commentymccommentface"),
Mock.Of<IItemFilterBlock>(),
Mock.Of<IItemFilterCommentBlock>(c => c.Comment == "commment\r\nmorecomment\r\nblah"),
Mock.Of<IItemFilterCommentBlock>(c => c.Comment == "anothercomment"),
Mock.Of<IItemFilterCommentBlock>(c => c.Comment == "notpartofblockdescription "),
Mock.Of<IItemFilterBlock>(c => c.Description == "blockdescription2")
} && s.ItemFilterBlockGroups == new ObservableCollection<ItemFilterBlockGroup> { new ItemFilterBlockGroup("Root", null, false) }
&& s.ThemeComponents == new ThemeComponentCollection()
&& s.ItemFilterScriptSettings == new ItemFilterScriptSettings(new ThemeComponentCollection())
&& s.Description == "Script description\r\nScript description\r\nScript description\r\nScript description");
result.ShouldBeEquivalentTo(expectedResult);
}
[Test] [Test]
public void TranslateItemFilterScriptToString_OneBlock_CallsTranslator() public void TranslateItemFilterScriptToString_OneBlock_CallsTranslator()
{ {
@ -93,14 +123,19 @@ namespace Filtration.Parser.Tests.Services
testScript.ItemFilterBlocks.Add(testBlock); testScript.ItemFilterBlocks.Add(testBlock);
_testUtility.MockItemFilterBlockTranslator.Setup(t => t.TranslateItemFilterBlockToString(testBlock)).Returns(blockOutput).Verifiable(); var mockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>();
mockItemFilterBlockTranslator
.Setup(t => t.TranslateItemFilterBlockToString(testBlock))
.Returns(blockOutput)
.Verifiable();
var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: mockItemFilterBlockTranslator.Object);
// Act // Act
_testUtility.ScriptTranslator.TranslateItemFilterScriptToString(testScript); translator.TranslateItemFilterScriptToString(testScript);
// Assert // Assert
_testUtility.MockItemFilterBlockTranslator.Verify(); mockItemFilterBlockTranslator.Verify();
} }
[Test] [Test]
@ -129,9 +164,8 @@ namespace Filtration.Parser.Tests.Services
" Width = 3" + Environment.NewLine + " Width = 3" + Environment.NewLine +
" SetFontSize 7" + Environment.NewLine; " SetFontSize 7" + Environment.NewLine;
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act // Act
var result = translator.TranslateItemFilterScriptToString(script); var result = translator.TranslateItemFilterScriptToString(script);
@ -174,9 +208,8 @@ namespace Filtration.Parser.Tests.Services
" Width = 3" + Environment.NewLine + " Width = 3" + Environment.NewLine +
" SetFontSize 7" + Environment.NewLine + Environment.NewLine; " SetFontSize 7" + Environment.NewLine + Environment.NewLine;
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act // Act
var result = translator.TranslateItemFilterScriptToString(script); var result = translator.TranslateItemFilterScriptToString(script);
@ -198,40 +231,15 @@ namespace Filtration.Parser.Tests.Services
Environment.NewLine + Environment.NewLine +
"# Test script description" + Environment.NewLine + Environment.NewLine; "# Test script description" + Environment.NewLine + Environment.NewLine;
var translator = CreateItemFilterScriptTranslator();
// Act // Act
var result = _testUtility.ScriptTranslator.TranslateItemFilterScriptToString(script); var result = translator.TranslateItemFilterScriptToString(script);
// Assert // Assert
Assert.AreEqual(expectedOutput, result); Assert.AreEqual(expectedOutput, result);
} }
[Test]
public void TranslateStringToItemFilterScript_SectionDirectlyBeforeBlockWithoutDescription_ReturnsCorrectObject()
{
// Arrange
var testInputScript = "# My Script" + Environment.NewLine +
Environment.NewLine +
"# Section: Chance Bases" + Environment.NewLine +
"Show" + Environment.NewLine +
" BaseType \"Lapis Amulet\" \"Amber Amulet\"" + Environment.NewLine +
" SetBorderColor 255 0 255" + Environment.NewLine +
" SetFontSize 25";
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object);
var translator = new ItemFilterScriptTranslator(blockTranslator,
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act
var result = translator.TranslateStringToItemFilterScript(testInputScript);
// Assert
Assert.AreEqual(2, result.ItemFilterBlocks.Count);
var block = result.ItemFilterBlocks.First(l => l.GetType() != typeof(ItemFilterSection));
Assert.AreEqual(4, block.BlockItems.Count);
var baseTypeItem = block.BlockItems.OfType<BaseTypeBlockItem>().First();
Assert.AreEqual(2, baseTypeItem.Items.Count);
}
[Test] [Test]
public void TranslateStringToItemFilterScript_OneLineDescriptionNoBlockDescriptionAddsDescriptionToScript() public void TranslateStringToItemFilterScript_OneLineDescriptionNoBlockDescriptionAddsDescriptionToScript()
{ {
@ -240,16 +248,15 @@ namespace Filtration.Parser.Tests.Services
Environment.NewLine + Environment.NewLine +
"Show" + Environment.NewLine + "Show" + Environment.NewLine +
"BaseType \"Maelström Staff\"" + Environment.NewLine + Environment.NewLine; "BaseType \"Maelström Staff\"" + Environment.NewLine + Environment.NewLine;
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act // Act
var result = translator.TranslateStringToItemFilterScript(testInputScript); var result = translator.TranslateStringToItemFilterScript(testInputScript);
// Assert // Assert
Assert.AreEqual("Script edited with Filtration - https://github.com/ben-wallis/Filtration", result.Description); Assert.AreEqual("Script edited with Filtration - https://github.com/ben-wallis/Filtration", result.Description);
var firstBlock = result.ItemFilterBlocks.First(); var firstBlock = result.ItemFilterBlocks.OfType<ItemFilterBlock>().First();
Assert.IsNull(firstBlock.Description); Assert.IsNull(firstBlock.Description);
} }
@ -274,9 +281,8 @@ namespace Filtration.Parser.Tests.Services
" SetTextColor 255 255 0"; " SetTextColor 255 255 0";
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act // Act
var result = translator.TranslateStringToItemFilterScript(testInputScript); var result = translator.TranslateStringToItemFilterScript(testInputScript);
@ -306,9 +312,8 @@ namespace Filtration.Parser.Tests.Services
" SetTextColor 255 255 0"; " SetTextColor 255 255 0";
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act // Act
var result = translator.TranslateStringToItemFilterScript(testInputScript); var result = translator.TranslateStringToItemFilterScript(testInputScript);
@ -316,9 +321,9 @@ namespace Filtration.Parser.Tests.Services
// Assert // Assert
Assert.AreEqual(3, result.ItemFilterBlocks.Count); Assert.AreEqual(3, result.ItemFilterBlocks.Count);
var firstBlock = result.ItemFilterBlocks.First(); var firstBlock = result.ItemFilterBlocks.OfType<ItemFilterBlock>().First();
var secondBlock = result.ItemFilterBlocks.Skip(1).First(); var secondBlock = result.ItemFilterBlocks.OfType<ItemFilterBlock>().Skip(1).First();
var thirdBlock = result.ItemFilterBlocks.Skip(2).First(); var thirdBlock = result.ItemFilterBlocks.OfType<ItemFilterBlock>().Skip(2).First();
Assert.AreEqual(3, firstBlock.BlockItems.Count); Assert.AreEqual(3, firstBlock.BlockItems.Count);
Assert.AreEqual(5, secondBlock.BlockItems.Count); Assert.AreEqual(5, secondBlock.BlockItems.Count);
@ -340,19 +345,20 @@ namespace Filtration.Parser.Tests.Services
"#Disabled Block End"; "#Disabled Block End";
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var blockTranslator = new ItemFilterBlockTranslator(Mock.Of<IBlockGroupHierarchyBuilder>());
var translator = new ItemFilterScriptTranslator(blockTranslator, var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
// Act // Act
var result = translator.TranslateStringToItemFilterScript(testInputScript); var result = translator.TranslateStringToItemFilterScript(testInputScript);
// Assert // Assert
Assert.AreEqual(2, result.ItemFilterBlocks.Count); Assert.AreEqual(2, result.ItemFilterBlocks.Count);
var secondBlock = result.ItemFilterBlocks.Skip(1).First(); var secondBlock = result.ItemFilterBlocks.OfType<ItemFilterBlock>().Skip(1).First();
Assert.AreEqual("This is a disabled block", secondBlock.Description); Assert.AreEqual("This is a disabled block", secondBlock.Description);
} }
// TODO: Reinstate this test
[Ignore("Ignored until toggling block group parsing can be controlled from the filter script input")]
[Test] [Test]
public void TranslateStringToItemFilterScript_DisabledBlockWithBlockGroup_ReturnsCorrectBlock() public void TranslateStringToItemFilterScript_DisabledBlockWithBlockGroup_ReturnsCorrectBlock()
{ {
@ -368,39 +374,37 @@ namespace Filtration.Parser.Tests.Services
"#Disabled Block End"; "#Disabled Block End";
var blockTranslator = new ItemFilterBlockTranslator(_testUtility.MockBlockGroupHierarchyBuilder.Object); var mockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
_testUtility.MockBlockGroupHierarchyBuilder.Setup( mockBlockGroupHierarchyBuilder.Setup(
b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>())) b => b.IntegrateStringListIntoBlockGroupHierarchy(It.IsAny<IEnumerable<string>>()))
.Returns(new ItemFilterBlockGroup("My Block Group", null)); .Returns(new ItemFilterBlockGroup("My Block Group", null));
var translator = new ItemFilterScriptTranslator(blockTranslator, var blockTranslator = new ItemFilterBlockTranslator(mockBlockGroupHierarchyBuilder.Object);
_testUtility.MockBlockGroupHierarchyBuilder.Object);
var translator = CreateItemFilterScriptTranslator(itemFilterBlockTranslator: blockTranslator);
// Act // Act
var result = translator.TranslateStringToItemFilterScript(testInputScript); var result = translator.TranslateStringToItemFilterScript(testInputScript);
// Assert // Assert
Assert.AreEqual(2, result.ItemFilterBlocks.Count); Assert.AreEqual(2, result.ItemFilterBlocks.Count);
var secondBlock = result.ItemFilterBlocks.Skip(1).First(); var secondBlock = result.ItemFilterBlocks.OfType<ItemFilterBlock>().Skip(1).First();
Assert.AreEqual("This is a disabled block", secondBlock.Description); Assert.AreEqual("This is a disabled block", secondBlock.Description);
Assert.AreEqual("My Block Group", secondBlock.BlockGroup.GroupName); 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() var mockItemFilterScriptFactory = new Mock<IItemFilterScriptFactory>();
{ mockItemFilterScriptFactory
// Mock setups .Setup(i => i.Create())
MockItemFilterBlockTranslator = new Mock<IItemFilterBlockTranslator>(); .Returns(new ItemFilterScript());
MockBlockGroupHierarchyBuilder = new Mock<IBlockGroupHierarchyBuilder>();
// Class under test instantiation return new ItemFilterScriptTranslator(blockGroupHierarchyBuilder ?? new Mock<IBlockGroupHierarchyBuilder>().Object,
ScriptTranslator = new ItemFilterScriptTranslator(MockItemFilterBlockTranslator.Object, MockBlockGroupHierarchyBuilder.Object); itemFilterBlockTranslator ?? new Mock<IItemFilterBlockTranslator>().Object,
} itemFilterScriptFactory ?? mockItemFilterScriptFactory.Object);
public ItemFilterScriptTranslator ScriptTranslator { get; }
public Mock<IItemFilterBlockTranslator> MockItemFilterBlockTranslator { get; }
public Mock<IBlockGroupHierarchyBuilder> MockBlockGroupHierarchyBuilder { get; }
} }
} }
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="FluentAssertions" version="4.13.1" targetFramework="net461" /> <package id="FluentAssertions" version="4.19.2" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
</packages> </packages>

View File

@ -35,9 +35,8 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Windsor, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> <Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath> <HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />

View File

@ -29,64 +29,70 @@ namespace Filtration.Parser.Services
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder; _blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
} }
// Converts a string into an ItemFilterCommentBlock maintaining newlines and spaces but removing # characters
public IItemFilterCommentBlock TranslateStringToItemFilterCommentBlock(string inputString, IItemFilterScript parentItemFilterScript)
{
var itemFilterCommentBlock = new ItemFilterCommentBlock(parentItemFilterScript);
foreach (var line in new LineReader(() => new StringReader(inputString)))
{
var trimmedLine = line.TrimStart(' ').TrimStart('#');
itemFilterCommentBlock.Comment += trimmedLine + Environment.NewLine;
}
itemFilterCommentBlock.Comment = itemFilterCommentBlock.Comment.TrimEnd('\r', '\n');
return itemFilterCommentBlock;
}
// This method converts a string into a ItemFilterBlock. This is used for pasting ItemFilterBlocks // This method converts a string into a ItemFilterBlock. This is used for pasting ItemFilterBlocks
// and reading ItemFilterScripts from a file. // and reading ItemFilterScripts from a file.
public IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, ThemeComponentCollection masterComponentCollection) public IItemFilterBlock TranslateStringToItemFilterBlock(string inputString, IItemFilterScript parentItemFilterScript, bool initialiseBlockGroupHierarchyBuilder = false)
{ {
_masterComponentCollection = masterComponentCollection; if (initialiseBlockGroupHierarchyBuilder)
var block = new ItemFilterBlock(); {
_blockGroupHierarchyBuilder.Initialise(parentItemFilterScript.ItemFilterBlockGroups.First());
}
_masterComponentCollection = parentItemFilterScript.ItemFilterScriptSettings.ThemeComponentCollection;
var block = new ItemFilterBlock(parentItemFilterScript);
var showHideFound = false; var showHideFound = false;
foreach (var line in new LineReader(() => new StringReader(inputString))) foreach (var line in new LineReader(() => new StringReader(inputString)))
{ {
if (line.StartsWith(@"# Section:"))
{
var section = new ItemFilterSection
{
Description = line.Substring(line.IndexOf(":", StringComparison.Ordinal) + 1).Trim()
};
return section;
}
if (line.StartsWith(@"#") && !showHideFound) if (line.StartsWith(@"#") && !showHideFound)
{ {
block.Description = line.TrimStart('#').TrimStart(' '); block.Description = line.TrimStart('#').TrimStart(' ');
continue; continue;
} }
var adjustedLine = line.Replace("#", " # "); var trimmedLine = line.Trim();
var trimmedLine = adjustedLine.TrimStart(' ').TrimEnd(' ');
var spaceOrEndOfLinePos = trimmedLine.IndexOf(" ", StringComparison.Ordinal) > 0 ? trimmedLine.IndexOf(" ", StringComparison.Ordinal) : trimmedLine.Length; var spaceOrEndOfLinePos = trimmedLine.IndexOf(" ", StringComparison.Ordinal) > 0 ? trimmedLine.IndexOf(" ", StringComparison.Ordinal) : trimmedLine.Length;
var lineOption = trimmedLine.Substring(0, spaceOrEndOfLinePos); var lineOption = trimmedLine.Substring(0, spaceOrEndOfLinePos);
switch (lineOption) switch (lineOption)
{ {
case "Show": case "Show":
showHideFound = true;
block.Action = BlockAction.Show;
block.Enabled = true;
AddBlockGroupToBlock(block, trimmedLine);
break;
case "Hide": case "Hide":
showHideFound = true;
block.Action = BlockAction.Hide;
block.Enabled = true;
AddBlockGroupToBlock(block, trimmedLine);
break;
case "ShowDisabled": case "ShowDisabled":
showHideFound = true;
block.Action = BlockAction.Show;
block.Enabled = false;
AddBlockGroupToBlock(block, trimmedLine);
break;
case "HideDisabled": case "HideDisabled":
{
showHideFound = true; showHideFound = true;
block.Action = BlockAction.Hide; block.Action = lineOption.StartsWith("Show") ? BlockAction.Show : BlockAction.Hide;
block.Enabled = false; block.Enabled = !lineOption.EndsWith("Disabled");
// 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 (parentItemFilterScript.ItemFilterScriptSettings.BlockGroupsEnabled)
{
AddBlockGroupToBlock(block, trimmedLine); AddBlockGroupToBlock(block, trimmedLine);
}
else
{
block.ActionBlockItem.Comment = GetTextAfterFirstComment(trimmedLine);
}
break; break;
}
case "ItemLevel": case "ItemLevel":
{ {
AddNumericFilterPredicateItemToBlockItems<ItemLevelBlockItem>(block, trimmedLine); AddNumericFilterPredicateItemToBlockItems<ItemLevelBlockItem>(block, trimmedLine);
@ -210,6 +216,7 @@ namespace Filtration.Parser.Services
switch (matches.Count) switch (matches.Count)
{ {
case 1: case 1:
{
if (matches[0].Success) if (matches[0].Success)
{ {
var blockItemValue = new SoundBlockItem var blockItemValue = new SoundBlockItem
@ -220,7 +227,9 @@ namespace Filtration.Parser.Services
block.BlockItems.Add(blockItemValue); block.BlockItems.Add(blockItemValue);
} }
break; break;
}
case 2: case 2:
{
if (matches[0].Success && matches[1].Success) if (matches[0].Success && matches[1].Success)
{ {
var blockItemValue = new SoundBlockItem var blockItemValue = new SoundBlockItem
@ -232,6 +241,7 @@ namespace Filtration.Parser.Services
} }
break; break;
} }
}
break; break;
} }
} }
@ -391,11 +401,11 @@ namespace Filtration.Parser.Services
private void AddBlockGroupToBlock(IItemFilterBlock block, string inputString) private void AddBlockGroupToBlock(IItemFilterBlock block, string inputString)
{ {
var blockGroupStart = inputString.IndexOf("#", StringComparison.Ordinal); var blockGroupText = GetTextAfterFirstComment(inputString);
if (blockGroupStart <= 0) return; var blockGroups = blockGroupText.Split(new[] { " - " }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim())
.ToList();
var blockGroupText = inputString.Substring(blockGroupStart + 1);
var blockGroups = blockGroupText.Split('-').ToList();
if (blockGroups.Count(b => !string.IsNullOrEmpty(b.Trim())) > 0) if (blockGroups.Count(b => !string.IsNullOrEmpty(b.Trim())) > 0)
{ {
block.BlockGroup = _blockGroupHierarchyBuilder.IntegrateStringListIntoBlockGroupHierarchy(blockGroups); block.BlockGroup = _blockGroupHierarchyBuilder.IntegrateStringListIntoBlockGroupHierarchy(blockGroups);
@ -403,6 +413,14 @@ namespace Filtration.Parser.Services
} }
} }
private static string GetTextAfterFirstComment(string inputString)
{
var blockGroupStart = inputString.IndexOf("#", StringComparison.Ordinal);
if (blockGroupStart <= 0) return string.Empty;
return inputString.Substring(blockGroupStart + 1);
}
private static Color GetColorFromString(string inputString) private static Color GetColorFromString(string inputString)
{ {
var argbValues = Regex.Matches(inputString, @"\s+(\d+)"); var argbValues = Regex.Matches(inputString, @"\s+(\d+)");
@ -429,15 +447,31 @@ namespace Filtration.Parser.Services
return new Color(); return new Color();
} }
// This method converts an ItemFilterBlock object into a string. This is used for copying a ItemFilterBlock public string TranslateItemFilterBlockBaseToString(IItemFilterBlockBase itemFilterBlockBase)
// to the clipboard, and when saving a ItemFilterScript.
public string TranslateItemFilterBlockToString(IItemFilterBlock block)
{ {
if (block.GetType() == typeof (ItemFilterSection)) var itemFilterBlock = itemFilterBlockBase as IItemFilterBlock;
{ if (itemFilterBlock != null) return TranslateItemFilterBlockToString(itemFilterBlock);
return "# Section: " + block.Description;
var itemFilterCommentBlock = itemFilterBlockBase as IItemFilterCommentBlock;
if (itemFilterCommentBlock != null) return TranslateItemFilterCommentBlockToString(itemFilterCommentBlock);
throw new InvalidOperationException("Unable to translate unknown ItemFilterBlock type");
} }
// TODO: Private
public string TranslateItemFilterCommentBlockToString(IItemFilterCommentBlock itemFilterCommentBlock)
{
// TODO: Handle multi-line
// TODO: Tests
// TODO: # Section: text?
return $"#{itemFilterCommentBlock.Comment}";
}
// This method converts an ItemFilterBlock object into a string. This is used for copying a ItemFilterBlock
// to the clipboard, and when saving a ItemFilterScript.
// TODO: Private
public string TranslateItemFilterBlockToString(IItemFilterBlock block)
{
var outputString = string.Empty; var outputString = string.Empty;
if (!block.Enabled) if (!block.Enabled)
@ -456,6 +490,10 @@ namespace Filtration.Parser.Services
{ {
outputString += " # " + block.BlockGroup; outputString += " # " + block.BlockGroup;
} }
else if (!string.IsNullOrEmpty(block.ActionBlockItem?.Comment))
{
outputString += " #" + block.ActionBlockItem.Comment;
}
// ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once LoopCanBeConvertedToQuery
foreach (var blockItem in block.BlockItems.Where(b => b.GetType() != typeof(ActionBlockItem)).OrderBy(b => b.SortOrder)) foreach (var blockItem in block.BlockItems.Where(b => b.GetType() != typeof(ActionBlockItem)).OrderBy(b => b.SortOrder))

View File

@ -2,27 +2,53 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Filtration.Common.Utilities; using Filtration.Common.Utilities;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.Factories;
using Filtration.Parser.Interface.Services; using Filtration.Parser.Interface.Services;
using Filtration.Properties; using Filtration.Properties;
namespace Filtration.Parser.Services namespace Filtration.Parser.Services
{ {
internal class ItemFilterBlockBoundary
{
public ItemFilterBlockBoundary(int startLine, ItemFilterBlockBoundaryType itemFilterBlockBoundaryType)
{
StartLine = startLine;
BoundaryType = itemFilterBlockBoundaryType;
}
public int StartLine { get; set; }
public ItemFilterBlockBoundaryType BoundaryType { get; set; }
}
internal enum ItemFilterBlockBoundaryType
{
ScriptDescription,
ItemFilterBlock,
CommentBlock
}
internal class ItemFilterScriptTranslator : IItemFilterScriptTranslator internal class ItemFilterScriptTranslator : IItemFilterScriptTranslator
{ {
private readonly IItemFilterBlockTranslator _blockTranslator; private readonly IItemFilterBlockTranslator _blockTranslator;
private readonly IItemFilterScriptFactory _itemFilterScriptFactory;
private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder; private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder;
public ItemFilterScriptTranslator(IItemFilterBlockTranslator blockTranslator, public ItemFilterScriptTranslator(IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder,
IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder) IItemFilterBlockTranslator blockTranslator,
IItemFilterScriptFactory itemFilterScriptFactory)
{ {
_blockTranslator = blockTranslator;
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder; _blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
_blockTranslator = blockTranslator;
_itemFilterScriptFactory = itemFilterScriptFactory;
} }
public string PreprocessDisabledBlocks(string inputString) public static string PreprocessDisabledBlocks(string inputString)
{ {
bool inDisabledBlock = false; bool inDisabledBlock = false;
var showHideFound = false; var showHideFound = false;
@ -82,9 +108,9 @@ namespace Filtration.Parser.Services
return lines.Aggregate((c, n) => c + Environment.NewLine + n); 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()); _blockGroupHierarchyBuilder.Initialise(script.ItemFilterBlockGroups.First());
inputString = inputString.Replace("\t", ""); inputString = inputString.Replace("\t", "");
@ -98,7 +124,7 @@ namespace Filtration.Parser.Services
var lines = Regex.Split(inputString, "\r\n|\r|\n"); var lines = Regex.Split(inputString, "\r\n|\r|\n");
// Process the script header // Process the script header
for (var i = 0; i < conditionBoundaries.First.Value; i++) for (var i = 0; i < conditionBoundaries.Skip(1).First().StartLine; i++)
{ {
if (lines[i].StartsWith("#")) if (lines[i].StartsWith("#"))
{ {
@ -115,47 +141,94 @@ namespace Filtration.Parser.Services
// and add that object to the ItemFilterBlocks list // and add that object to the ItemFilterBlocks list
for (var boundary = conditionBoundaries.First; boundary != null; boundary = boundary.Next) for (var boundary = conditionBoundaries.First; boundary != null; boundary = boundary.Next)
{ {
var begin = boundary.Value; if (boundary.Value.BoundaryType == ItemFilterBlockBoundaryType.ScriptDescription)
var end = boundary.Next?.Value ?? lines.Length; {
continue;
}
var begin = boundary.Value.StartLine;
var end = boundary.Next?.Value.StartLine ?? lines.Length;
var block = new string[end - begin]; var block = new string[end - begin];
Array.Copy(lines, begin, block, 0, end - begin); Array.Copy(lines, begin, block, 0, end - begin);
var blockString = string.Join("\r\n", block); var blockString = string.Join("\r\n", block);
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString, script.ThemeComponents));
if (boundary.Value.BoundaryType == ItemFilterBlockBoundaryType.ItemFilterBlock)
{
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterBlock(blockString, script));
}
else
{
script.ItemFilterBlocks.Add(_blockTranslator.TranslateStringToItemFilterCommentBlock(blockString, script));
}
} }
_blockGroupHierarchyBuilder.Cleanup(); _blockGroupHierarchyBuilder.Cleanup();
return script; return script;
} }
private static LinkedList<int> IdentifyBlockBoundaries(string inputString) private static LinkedList<ItemFilterBlockBoundary> IdentifyBlockBoundaries(string inputString)
{ {
var blockBoundaries = new LinkedList<int>(); var blockBoundaries = new LinkedList<ItemFilterBlockBoundary>();
var previousLine = string.Empty; var previousLine = string.Empty;
var currentLine = 0; var currentLine = -1;
var currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(0, ItemFilterBlockBoundaryType.ScriptDescription);
foreach (var line in new LineReader(() => new StringReader(inputString))) foreach (var line in new LineReader(() => new StringReader(inputString)))
{ {
currentLine++; currentLine++;
var trimmedLine = line.TrimStart(' ').TrimEnd(' '); var trimmedLine = line.Trim(' ');
if (trimmedLine.StartsWith("Show") || trimmedLine.StartsWith("Hide") ||
trimmedLine.StartsWith("# Section:")) if (string.IsNullOrWhiteSpace(trimmedLine))
{
previousLine = line;
continue;
}
// A line starting with a comment when we're inside a ItemFilterBlock boundary represents the end of that block
// as ItemFilterBlocks cannot have comment lines after the block description
if (trimmedLine.StartsWith("#") && currentItemFilterBlockBoundary.BoundaryType == ItemFilterBlockBoundaryType.ItemFilterBlock)
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(currentLine, ItemFilterBlockBoundaryType.CommentBlock);
}
// A line starting with a comment where the previous line was null represents the start of a new comment (unless we're on the first
// line in which case it's not a new comment).
else if (trimmedLine.StartsWith("#") && string.IsNullOrWhiteSpace(previousLine) && currentItemFilterBlockBoundary.BoundaryType != ItemFilterBlockBoundaryType.ScriptDescription)
{
if (blockBoundaries.Count > 0)
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
}
currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(currentLine, ItemFilterBlockBoundaryType.CommentBlock);
}
else if (trimmedLine.StartsWith("Show") || trimmedLine.StartsWith("Hide"))
{ {
// If the line previous to the Show or Hide line is a comment then we should include that in the block // If the line previous to the Show or Hide line is a comment then we should include that in the block
// as it represents the block description. // as it represents the block description.
// currentLine > 2 caters for an edge case where the script description is a single line and the first // currentLine > 2 caters for an edge case where the script description is a single line and the first
// block has no description. This prevents the script description from being assigned to the first block's description. // block has no description. This prevents the script description from being assigned to the first block's description.
blockBoundaries.AddLast(previousLine.StartsWith("#") && !previousLine.StartsWith("# Section:") && if (!(currentItemFilterBlockBoundary.StartLine == currentLine - 1 && currentItemFilterBlockBoundary.BoundaryType == ItemFilterBlockBoundaryType.CommentBlock))
currentLine > 2 {
? currentLine - 2 blockBoundaries.AddLast(currentItemFilterBlockBoundary);
: currentLine - 1);
} }
currentItemFilterBlockBoundary = new ItemFilterBlockBoundary(previousLine.StartsWith("#") && currentLine > 2 ? currentLine - 1 : currentLine,
ItemFilterBlockBoundaryType.ItemFilterBlock);
}
previousLine = line; previousLine = line;
} }
if (blockBoundaries.Last.Value != currentItemFilterBlockBoundary)
{
blockBoundaries.AddLast(currentItemFilterBlockBoundary);
}
return blockBoundaries; return blockBoundaries;
} }
public string TranslateItemFilterScriptToString(ItemFilterScript script) public string TranslateItemFilterScriptToString(IItemFilterScript script)
{ {
var outputString = string.Empty; var outputString = string.Empty;
@ -178,7 +251,7 @@ namespace Filtration.Parser.Services
// ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once LoopCanBeConvertedToQuery
foreach (var block in script.ItemFilterBlocks) foreach (var block in script.ItemFilterBlocks)
{ {
outputString += _blockTranslator.TranslateItemFilterBlockToString(block) + Environment.NewLine; outputString += _blockTranslator.TranslateItemFilterBlockToString(block as ItemFilterBlock) + Environment.NewLine;
if (Settings.Default.ExtraLineBetweenBlocks) if (Settings.Default.ExtraLineBetweenBlocks)
{ {

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net461" /> <package id="Castle.Windsor" version="3.4.0" targetFramework="net461" />
</packages> </packages>

View File

@ -35,21 +35,17 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="FluentAssertions, Version=4.13.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <Reference Include="FluentAssertions, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.13.1\lib\net45\FluentAssertions.dll</HintPath> <HintPath>..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="FluentAssertions.Core, Version=4.13.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <Reference Include="FluentAssertions.Core, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.13.1\lib\net45\FluentAssertions.Core.dll</HintPath> <HintPath>..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />

View File

@ -2,9 +2,11 @@
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.Factories;
using Filtration.Repositories; using Filtration.Repositories;
using Filtration.Services; using Filtration.Services;
using Filtration.ViewModels; using Filtration.ViewModels;
using Filtration.ViewModels.Factories;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
@ -29,7 +31,8 @@ namespace Filtration.Tests.Repositories
var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>();
mockItemFilterScriptViewModelFactory.Setup(f => f.Create()).Returns(mockItemFilterScriptViewModel.Object); 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 // Act
var result = await repository.LoadScriptFromFileAsync(testInputPath); var result = await repository.LoadScriptFromFileAsync(testInputPath);
@ -50,7 +53,8 @@ namespace Filtration.Tests.Repositories
var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>();
var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object,
itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object);
// Act // Act
Func<Task<IItemFilterScriptViewModel>> result = async () => await repository.LoadScriptFromFileAsync(testInputPath); Func<Task<IItemFilterScriptViewModel>> result = async () => await repository.LoadScriptFromFileAsync(testInputPath);
@ -70,7 +74,8 @@ namespace Filtration.Tests.Repositories
var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>();
var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object,
itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object);
// Act // Act
repository.SetItemFilterScriptDirectory(testInputPath); repository.SetItemFilterScriptDirectory(testInputPath);
@ -90,7 +95,8 @@ namespace Filtration.Tests.Repositories
var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>();
var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); var repository = CreateItemFilterScriptRepository(itemFilterPersistenceService: mockPersistenceService.Object,
itemFilterScriptViewModelFactory: mockItemFilterScriptViewModelFactory.Object);
// Act // Act
string result = repository.GetItemFilterScriptDirectory(); string result = repository.GetItemFilterScriptDirectory();
@ -111,7 +117,8 @@ namespace Filtration.Tests.Repositories
var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>();
mockItemFilterScriptViewModelFactory.Setup(f => f.Create()).Returns(mockItemFilterScriptViewModel.Object); 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 // Act
IItemFilterScriptViewModel result = repository.NewScript(); IItemFilterScriptViewModel result = repository.NewScript();
@ -119,5 +126,14 @@ namespace Filtration.Tests.Repositories
// Assert // Assert
Assert.AreEqual(mockItemFilterScriptViewModel.Object, result); 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);
}
} }
} }

View File

@ -8,7 +8,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ControlzEx" publicKeyToken="f08b075e934b7045" culture="neutral" /> <assemblyIdentity name="ControlzEx" publicKeyToken="f08b075e934b7045" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.2.3" newVersion="2.1.2.3" /> <bindingRedirect oldVersion="0.0.0.0-2.2.0.4" newVersion="2.2.0.4" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="FluentAssertions" version="4.13.1" targetFramework="net461" /> <package id="FluentAssertions" version="4.19.2" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
</packages> </packages>

View File

@ -35,13 +35,11 @@
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> <Reference Include="Moq, Version=4.5.30.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath> <HintPath>..\packages\Moq.4.5.30\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net461" /> <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
<package id="Moq" version="4.5.21" targetFramework="net461" /> <package id="Moq" version="4.5.30" targetFramework="net461" />
<package id="NUnit" version="3.4.1" targetFramework="net461" /> <package id="NUnit" version="3.6.1" targetFramework="net461" />
</packages> </packages>

View File

@ -31,16 +31,15 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="AutoMapper, Version=4.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL"> <Reference Include="AutoMapper, Version=6.0.2.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll</HintPath> <HintPath>..\packages\AutoMapper.6.0.2\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> <Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Windsor"> <Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath> <HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath>
</Reference> </Reference>
<Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL"> <Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath> <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
@ -58,8 +57,7 @@
<HintPath>..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath> <HintPath>..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
</Reference> </Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.7\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.4.4.9\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />

View File

@ -11,8 +11,8 @@ namespace Filtration.ThemeEditor.Providers
{ {
public interface IThemeProvider public interface IThemeProvider
{ {
IThemeEditorViewModel NewThemeForScript(ItemFilterScript script); IThemeEditorViewModel NewThemeForScript(IItemFilterScript script);
IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script); IThemeEditorViewModel MasterThemeForScript(IItemFilterScript script);
Task<IThemeEditorViewModel> LoadThemeFromFile(string filePath); Task<IThemeEditorViewModel> LoadThemeFromFile(string filePath);
Task<Theme> LoadThemeModelFromFile(string filePath); Task<Theme> LoadThemeModelFromFile(string filePath);
Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath); Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath);
@ -29,7 +29,7 @@ namespace Filtration.ThemeEditor.Providers
_themePersistenceService = themePersistenceService; _themePersistenceService = themePersistenceService;
} }
public IThemeEditorViewModel NewThemeForScript(ItemFilterScript script) public IThemeEditorViewModel NewThemeForScript(IItemFilterScript script)
{ {
var themeComponentCollection = script.ThemeComponents.Aggregate(new ThemeComponentCollection(), var themeComponentCollection = script.ThemeComponents.Aggregate(new ThemeComponentCollection(),
(c, component) => (c, component) =>
@ -45,7 +45,7 @@ namespace Filtration.ThemeEditor.Providers
return themeViewModel; return themeViewModel;
} }
public IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script) public IThemeEditorViewModel MasterThemeForScript(IItemFilterScript script)
{ {
var themeViewModel = _themeViewModelFactory.Create(); var themeViewModel = _themeViewModelFactory.Create();
themeViewModel.InitialiseForMasterTheme(script); themeViewModel.InitialiseForMasterTheme(script);

View File

@ -12,7 +12,7 @@ namespace Filtration.ThemeEditor.Services
{ {
public interface IThemeService public interface IThemeService
{ {
void ApplyThemeToScript(Theme theme, ItemFilterScript script); void ApplyThemeToScript(Theme theme, IItemFilterScript script);
} }
public class ThemeService : IThemeService public class ThemeService : IThemeService
@ -24,7 +24,7 @@ namespace Filtration.ThemeEditor.Services
_messageBoxService = messageBoxService; _messageBoxService = messageBoxService;
} }
public void ApplyThemeToScript(Theme theme, ItemFilterScript script) public void ApplyThemeToScript(Theme theme, IItemFilterScript script)
{ {
var mismatchedComponents = false; var mismatchedComponents = false;
foreach (var component in theme.Components) foreach (var component in theme.Components)
@ -44,7 +44,7 @@ namespace Filtration.ThemeEditor.Services
break; break;
} }
foreach (var block in script.ItemFilterBlocks) foreach (var block in script.ItemFilterBlocks.OfType<ItemFilterBlock>())
{ {
foreach (var blockItem in block.BlockItems.Where(i => i.GetType() == targetType)) foreach (var blockItem in block.BlockItems.Where(i => i.GetType() == targetType))
{ {

View File

@ -26,9 +26,9 @@ namespace Filtration.ThemeEditor.ViewModels
RelayCommand CloseCommand { get; } RelayCommand CloseCommand { get; }
void InitialiseForNewTheme(ThemeComponentCollection themeComponentCollection); void InitialiseForNewTheme(ThemeComponentCollection themeComponentCollection);
void InitialiseForMasterTheme(ItemFilterScript script); void InitialiseForMasterTheme(IItemFilterScript script);
bool IsMasterTheme { get; } bool IsMasterTheme { get; }
ItemFilterScript IsMasterThemeForScript { get; } IItemFilterScript IsMasterThemeForScript { get; }
string Title { get; } string Title { get; }
string FilePath { get; set; } string FilePath { get; set; }
string Filename { get; } string Filename { get; }
@ -72,7 +72,7 @@ namespace Filtration.ThemeEditor.ViewModels
public bool IsMasterTheme => Components.IsMasterCollection; public bool IsMasterTheme => Components.IsMasterCollection;
public ItemFilterScript IsMasterThemeForScript { get; private set; } public IItemFilterScript IsMasterThemeForScript { get; private set; }
public void InitialiseForNewTheme(ThemeComponentCollection themeComponentCollection) public void InitialiseForNewTheme(ThemeComponentCollection themeComponentCollection)
{ {
@ -80,7 +80,7 @@ namespace Filtration.ThemeEditor.ViewModels
_filenameIsFake = true; _filenameIsFake = true;
} }
public void InitialiseForMasterTheme(ItemFilterScript script) public void InitialiseForMasterTheme(IItemFilterScript script)
{ {
Components = script.ThemeComponents; Components = script.ThemeComponents;
IsMasterThemeForScript = script; IsMasterThemeForScript = script;

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="AutoMapper" version="4.2.1" targetFramework="net461" /> <package id="AutoMapper" version="6.0.2" targetFramework="net461" />
<package id="Castle.Core" version="3.3.3" targetFramework="net451" /> <package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="Castle.Windsor" version="3.3.0" targetFramework="net451" /> <package id="Castle.Windsor" version="3.4.0" targetFramework="net461" />
<package id="CommonServiceLocator" version="1.3" targetFramework="net451" /> <package id="CommonServiceLocator" version="1.3" targetFramework="net451" />
<package id="Extended.Wpf.Toolkit" version="2.9" targetFramework="net461" /> <package id="Extended.Wpf.Toolkit" version="2.9" targetFramework="net461" />
<package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" /> <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" />
<package id="NLog" version="4.3.7" targetFramework="net461" /> <package id="NLog" version="4.4.9" targetFramework="net461" />
</packages> </packages>

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 15
VisualStudioVersion = 14.0.24720.0 VisualStudioVersion = 15.1
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Filtration", "Filtration\Filtration.csproj", "{55E0A34C-E039-43D7-A024-A4045401CDDA}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Filtration", "Filtration\Filtration.csproj", "{55E0A34C-E039-43D7-A024-A4045401CDDA}"
EndProject EndProject

View File

@ -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"> <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_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">&lt;data /&gt;</s:String> <s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String>
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Filtration.ItemFilterPreview.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ObjectModel.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ThemeEditor.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String></wpf:ResourceDictionary> <s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Filtration.ItemFilterPreview.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ObjectModel.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ThemeEditor.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String></wpf:ResourceDictionary>

View File

@ -41,7 +41,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ControlzEx" publicKeyToken="f08b075e934b7045" culture="neutral" /> <assemblyIdentity name="ControlzEx" publicKeyToken="f08b075e934b7045" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.2.3" newVersion="2.1.2.3" /> <bindingRedirect oldVersion="0.0.0.0-2.2.0.4" newVersion="2.2.0.4" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

View File

@ -45,6 +45,9 @@
<converters:BooleanToBlockActionInverseConverter x:Key="BooleanToBlockActionInverseConverter" /> <converters:BooleanToBlockActionInverseConverter x:Key="BooleanToBlockActionInverseConverter" />
<converters:AvailableThemeComponentsConverter x:Key="AvailableThemeComponentsConverter" /> <converters:AvailableThemeComponentsConverter x:Key="AvailableThemeComponentsConverter" />
</ResourceDictionary> </ResourceDictionary>
<ResourceDictionary>
<RoutedCommand x:Key="OpenScriptRoutedCommand" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>

View File

@ -41,29 +41,13 @@ namespace Filtration
_container.Install(FromAssembly.InThisApplication()); _container.Install(FromAssembly.InThisApplication());
_container.Install(FromAssembly.Named("Filtration.Parser")); // Not directly referenced so manually call its installers _container.Install(FromAssembly.Named("Filtration.Parser")); // Not directly referenced so manually call its installers
Mapper.Initialize(cfg =>
Mapper.Configuration.ConstructServicesUsing(_container.Resolve);
Mapper.CreateMap<ItemFilterBlockGroup, ItemFilterBlockGroupViewModel>()
.ForMember(destination => destination.ChildGroups, options => options.ResolveUsing(
delegate(ResolutionResult resolutionResult)
{ {
var context = resolutionResult.Context; cfg.ConstructServicesUsing(_container.Resolve);
var showAdvanced = (bool) context.Options.Items["showAdvanced"]; cfg.CreateMap<Theme, IThemeEditorViewModel>().ConstructUsingServiceLocator();
var group = (ItemFilterBlockGroup) context.SourceValue; cfg.CreateMap<ThemeComponent, ThemeComponentViewModel>().ReverseMap();
if (showAdvanced) cfg.CreateMap<IThemeEditorViewModel, Theme>();
return group.ChildGroups; });
else
return group.ChildGroups.Where(c => c.Advanced == false);
}))
.ForMember(dest => dest.SourceBlockGroup,
opts => opts.MapFrom(from => from))
.ForMember(dest => dest.IsExpanded,
opts => opts.UseValue(false));
Mapper.CreateMap<Theme, IThemeEditorViewModel>().ConstructUsingServiceLocator();
Mapper.CreateMap<ThemeComponent, ThemeComponentViewModel>().ReverseMap();
Mapper.CreateMap<IThemeEditorViewModel, Theme>();
Mapper.AssertConfigurationIsValid(); Mapper.AssertConfigurationIsValid();

View File

@ -42,20 +42,18 @@
<ApplicationIcon>Resources\filtration.ico</ApplicationIcon> <ApplicationIcon>Resources\filtration.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="AutoMapper, Version=4.2.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL"> <Reference Include="AutoMapper, Version=6.0.2.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll</HintPath> <HintPath>..\packages\AutoMapper.6.0.2\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> <Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath> <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Castle.Windsor"> <Reference Include="Castle.Windsor, Version=3.4.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll</HintPath> <HintPath>..\packages\Castle.Windsor.3.4.0\lib\net45\Castle.Windsor.dll</HintPath>
</Reference> </Reference>
<Reference Include="ControlzEx, Version=2.1.2.3, Culture=neutral, PublicKeyToken=f08b075e934b7045, processorArchitecture=MSIL"> <Reference Include="ControlzEx, Version=2.2.0.4, Culture=neutral, PublicKeyToken=f08b075e934b7045, processorArchitecture=MSIL">
<HintPath>..\packages\ControlzEx.2.1.2.3\lib\net45\ControlzEx.dll</HintPath> <HintPath>..\packages\ControlzEx.2.2.0.4\lib\net45\ControlzEx.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="Fluent, Version=4.0.3.394, Culture=neutral, PublicKeyToken=3e436e32a8c5546f, processorArchitecture=MSIL"> <Reference Include="Fluent, Version=4.0.3.394, Culture=neutral, PublicKeyToken=3e436e32a8c5546f, processorArchitecture=MSIL">
<HintPath>..\packages\Fluent.Ribbon.4.0.3.394\lib\net45\Fluent.dll</HintPath> <HintPath>..\packages\Fluent.Ribbon.4.0.3.394\lib\net45\Fluent.dll</HintPath>
@ -79,8 +77,7 @@
</Reference> </Reference>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.7\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.4.4.9\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
@ -94,8 +91,7 @@
</Reference> </Reference>
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\ControlzEx.2.1.2.3\lib\net45\System.Windows.Interactivity.dll</HintPath> <HintPath>..\packages\ControlzEx.2.2.0.4\lib\net45\System.Windows.Interactivity.dll</HintPath>
<Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@ -185,19 +181,23 @@
<Compile Include="UserControls\ThemeComponentSelectionControl.xaml.cs"> <Compile Include="UserControls\ThemeComponentSelectionControl.xaml.cs">
<DependentUpon>ThemeComponentSelectionControl.xaml</DependentUpon> <DependentUpon>ThemeComponentSelectionControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Utilities\AutoMapperHelpers.cs" /> <Compile Include="Utility\RoutedCommandHandler.cs" />
<Compile Include="Utilities\BlockGroupMapper.cs" /> <Compile Include="Utility\RoutedCommandHandlers.cs" />
<Compile Include="ViewModels\AvalonDockWorkspaceViewModel.cs" /> <Compile Include="ViewModels\AvalonDockWorkspaceViewModel.cs" />
<Compile Include="ViewModels\Factories\IItemFilterCommentBlockViewModelFactory.cs" />
<Compile Include="ViewModels\Factories\ItemFilterBlockBaseViewModelFactory.cs" />
<Compile Include="ViewModels\ItemFilterBlockViewModelBase.cs" />
<Compile Include="ViewModels\ItemFilterCommentBlockViewModel.cs" />
<Compile Include="ViewModels\SettingsPageViewModel.cs" /> <Compile Include="ViewModels\SettingsPageViewModel.cs" />
<Compile Include="ViewModels\ToolPanes\BlockGroupBrowserViewModel.cs" /> <Compile Include="ViewModels\ToolPanes\BlockGroupBrowserViewModel.cs" />
<Compile Include="ViewModels\IItemFilterScriptViewModelFactory.cs" /> <Compile Include="ViewModels\Factories\IItemFilterScriptViewModelFactory.cs" />
<Compile Include="ViewModels\IItemFilterBlockViewModelFactory.cs" /> <Compile Include="ViewModels\Factories\IItemFilterBlockViewModelFactory.cs" />
<Compile Include="ViewModels\ItemFilterBlockGroupViewModel.cs" /> <Compile Include="ViewModels\ItemFilterBlockGroupViewModel.cs" />
<Compile Include="ViewModels\ItemFilterBlockViewModel.cs" /> <Compile Include="ViewModels\ItemFilterBlockViewModel.cs" />
<Compile Include="ViewModels\ItemFilterScriptViewModel.cs" /> <Compile Include="ViewModels\ItemFilterScriptViewModel.cs" />
<Compile Include="ViewModels\ToolPanes\BlockOutputPreviewViewModel.cs" /> <Compile Include="ViewModels\ToolPanes\BlockOutputPreviewViewModel.cs" />
<Compile Include="ViewModels\ReplaceColorsViewModel.cs" /> <Compile Include="ViewModels\ReplaceColorsViewModel.cs" />
<Compile Include="ViewModels\ToolPanes\SectionBrowserViewModel.cs" /> <Compile Include="ViewModels\ToolPanes\CommentBlockBrowserViewModel.cs" />
<Compile Include="ViewModels\StartPageViewModel.cs" /> <Compile Include="ViewModels\StartPageViewModel.cs" />
<Compile Include="ViewModels\ToolPanes\ToolViewModel.cs" /> <Compile Include="ViewModels\ToolPanes\ToolViewModel.cs" />
<Compile Include="ViewModels\UpdateAvailableViewModel.cs" /> <Compile Include="ViewModels\UpdateAvailableViewModel.cs" />
@ -226,7 +226,6 @@
<Compile Include="Views\ToolPanes\BlockGroupBrowserView.xaml.cs"> <Compile Include="Views\ToolPanes\BlockGroupBrowserView.xaml.cs">
<DependentUpon>BlockGroupBrowserView.xaml</DependentUpon> <DependentUpon>BlockGroupBrowserView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\BlockTemplateSelector.cs" />
<Compile Include="Views\ItemFilterScriptView.xaml.cs"> <Compile Include="Views\ItemFilterScriptView.xaml.cs">
<DependentUpon>ItemFilterScriptView.xaml</DependentUpon> <DependentUpon>ItemFilterScriptView.xaml</DependentUpon>
</Compile> </Compile>
@ -236,8 +235,8 @@
<Compile Include="UserControls\NumericFilterPredicateControl.xaml.cs"> <Compile Include="UserControls\NumericFilterPredicateControl.xaml.cs">
<DependentUpon>NumericFilterPredicateControl.xaml</DependentUpon> <DependentUpon>NumericFilterPredicateControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\ItemFilterSectionView.xaml.cs"> <Compile Include="Views\ItemFilterCommentBlockView.xaml.cs">
<DependentUpon>ItemFilterSectionView.xaml</DependentUpon> <DependentUpon>ItemFilterCommentBlockView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\AboutWindow.xaml.cs"> <Compile Include="Views\AboutWindow.xaml.cs">
<DependentUpon>AboutWindow.xaml</DependentUpon> <DependentUpon>AboutWindow.xaml</DependentUpon>
@ -251,8 +250,8 @@
<Compile Include="Views\ToolPanes\BlockOutputPreviewView.xaml.cs"> <Compile Include="Views\ToolPanes\BlockOutputPreviewView.xaml.cs">
<DependentUpon>BlockOutputPreviewView.xaml</DependentUpon> <DependentUpon>BlockOutputPreviewView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\ToolPanes\SectionBrowserView.xaml.cs"> <Compile Include="Views\ToolPanes\CommentBlockBrowserView.xaml.cs">
<DependentUpon>SectionBrowserView.xaml</DependentUpon> <DependentUpon>CommentBlockBrowserView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\StartPageView.xaml.cs"> <Compile Include="Views\StartPageView.xaml.cs">
<DependentUpon>StartPageView.xaml</DependentUpon> <DependentUpon>StartPageView.xaml</DependentUpon>
@ -316,7 +315,7 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\ToolPanes\SectionBrowserView.xaml"> <Page Include="Views\ToolPanes\CommentBlockBrowserView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
@ -328,7 +327,7 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\ItemFilterSectionView.xaml"> <Page Include="Views\ItemFilterCommentBlockView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
@ -447,6 +446,8 @@
<Resource Include="Resources\Icons\ThemeComponentDelete.ico" /> <Resource Include="Resources\Icons\ThemeComponentDelete.ico" />
<Resource Include="Resources\Icons\standby_disabled_icon.png" /> <Resource Include="Resources\Icons\standby_disabled_icon.png" />
<Resource Include="Resources\Icons\standby_enabled_icon.png" /> <Resource Include="Resources\Icons\standby_enabled_icon.png" />
<Resource Include="Resources\Icons\redo_icon.png" />
<Resource Include="Resources\Icons\undo_icon.png" />
<Content Include="Resources\ItemBaseTypes.txt" /> <Content Include="Resources\ItemBaseTypes.txt" />
<Content Include="Resources\ItemClasses.txt" /> <Content Include="Resources\ItemClasses.txt" />
</ItemGroup> </ItemGroup>
@ -516,9 +517,7 @@
<Name>Filtration.ThemeEditor</Name> <Name>Filtration.ThemeEditor</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup />
<Folder Include="Translators\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(XamlSpyInstallPath)MSBuild\FirstFloor.XamlSpy.WPF.targets" Condition="'$(XamlSpyInstallPath)' != '' and '$(Configuration)' == 'DEBUG'" /> <Import Project="$(XamlSpyInstallPath)MSBuild\FirstFloor.XamlSpy.WPF.targets" Condition="'$(XamlSpyInstallPath)' != '' and '$(Configuration)' == 'DEBUG'" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.Factories;
using Filtration.Services; using Filtration.Services;
using Filtration.ViewModels; using Filtration.ViewModels;
using Filtration.ViewModels.Factories;
namespace Filtration.Repositories namespace Filtration.Repositories
{ {
@ -16,12 +18,15 @@ namespace Filtration.Repositories
internal class ItemFilterScriptRepository : IItemFilterScriptRepository internal class ItemFilterScriptRepository : IItemFilterScriptRepository
{ {
private readonly IItemFilterPersistenceService _itemFilterPersistenceService; private readonly IItemFilterPersistenceService _itemFilterPersistenceService;
private readonly IItemFilterScriptFactory _itemFilterScriptFactory;
private readonly IItemFilterScriptViewModelFactory _itemFilterScriptViewModelFactory; private readonly IItemFilterScriptViewModelFactory _itemFilterScriptViewModelFactory;
public ItemFilterScriptRepository(IItemFilterPersistenceService itemFilterPersistenceService, public ItemFilterScriptRepository(IItemFilterPersistenceService itemFilterPersistenceService,
IItemFilterScriptFactory itemFilterScriptFactory,
IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory) IItemFilterScriptViewModelFactory itemFilterScriptViewModelFactory)
{ {
_itemFilterPersistenceService = itemFilterPersistenceService; _itemFilterPersistenceService = itemFilterPersistenceService;
_itemFilterScriptFactory = itemFilterScriptFactory;
_itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory; _itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory;
} }
@ -37,7 +42,7 @@ namespace Filtration.Repositories
public IItemFilterScriptViewModel NewScript() public IItemFilterScriptViewModel NewScript()
{ {
var newScript = new ItemFilterScript(); var newScript = _itemFilterScriptFactory.Create();
var newViewModel = _itemFilterScriptViewModelFactory.Create(); var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(newScript, true); newViewModel.Initialise(newScript, true);

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

View File

@ -11,8 +11,8 @@ namespace Filtration.Services
{ {
void SetItemFilterScriptDirectory(string path); void SetItemFilterScriptDirectory(string path);
string ItemFilterScriptDirectory { get; } string ItemFilterScriptDirectory { get; }
Task<ItemFilterScript> LoadItemFilterScriptAsync(string filePath); Task<IItemFilterScript> LoadItemFilterScriptAsync(string filePath);
Task SaveItemFilterScriptAsync(ItemFilterScript script); Task SaveItemFilterScriptAsync(IItemFilterScript script);
string DefaultPathOfExileDirectory(); string DefaultPathOfExileDirectory();
} }
@ -59,9 +59,9 @@ namespace Filtration.Services
Settings.Default.DefaultFilterDirectory = path; 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(() => await Task.Run(() =>
{ {
loadedScript = _itemFilterScriptTranslator.TranslateStringToItemFilterScript( loadedScript = _itemFilterScriptTranslator.TranslateStringToItemFilterScript(
@ -76,7 +76,7 @@ namespace Filtration.Services
return loadedScript; return loadedScript;
} }
public async Task SaveItemFilterScriptAsync(ItemFilterScript script) public async Task SaveItemFilterScriptAsync(IItemFilterScript script)
{ {
await Task.Run(() => await Task.Run(() =>
{ {

View File

@ -2,10 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Windows;
using Filtration.Common.Services; using Filtration.Common.Services;
using Filtration.Common.Utilities; using Filtration.Common.Utilities;
using Filtration.Utilities;
namespace Filtration.Services namespace Filtration.Services
{ {

View File

@ -1,32 +0,0 @@
using System.Linq;
using Filtration.ViewModels;
namespace Filtration.Utilities
{
internal class AutoMapperHelpers
{
public static void ItemFilterBlockGroupViewModelPostMap(ItemFilterBlockGroupViewModel viewModel)
{
foreach (var childViewModel in viewModel.ChildGroups)
{
ItemFilterBlockGroupViewModelPostMap(childViewModel);
}
if (viewModel.ChildGroups.Count > 0)
{
if (viewModel.ChildGroups.All(g => g.IsChecked == true))
{
viewModel.IsChecked = true;
}
else if (viewModel.ChildGroups.Any(g => g.IsChecked == true || g.IsChecked == null))
{
viewModel.IsChecked = null;
}
else
{
viewModel.IsChecked = false;
}
}
}
}
}

View File

@ -1,26 +0,0 @@
using System.Collections.ObjectModel;
using System.Linq;
using AutoMapper;
using Filtration.ObjectModel;
using Filtration.ViewModels;
namespace Filtration.Utilities
{
internal interface IBlockGroupMapper
{
ObservableCollection<ItemFilterBlockGroupViewModel> MapBlockGroupsToViewModels(
ObservableCollection<ItemFilterBlockGroup> blockGroups, bool showAdvanced);
}
internal class BlockGroupMapper : IBlockGroupMapper
{
public ObservableCollection<ItemFilterBlockGroupViewModel> MapBlockGroupsToViewModels(
ObservableCollection<ItemFilterBlockGroup> blockGroups, bool showAdvanced)
{
var mappedViewModels = Mapper.Map<ObservableCollection<ItemFilterBlockGroupViewModel>>(blockGroups, opts => opts.Items["showAdvanced"] = showAdvanced);
AutoMapperHelpers.ItemFilterBlockGroupViewModelPostMap(mappedViewModels.First());
return mappedViewModels.First().ChildGroups;
}
}
}

View File

@ -0,0 +1,73 @@
using System.Windows;
using System.Windows.Input;
namespace Filtration.Utility
{
/// <summary>
/// Allows associated a routed command with a non-routed command. Used by
/// <see cref="RoutedCommandHandlers"/>.
/// </summary>
public class RoutedCommandHandler : Freezable
{
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
"Command",
typeof(ICommand),
typeof(RoutedCommandHandler),
new PropertyMetadata(default(ICommand)));
/// <summary> The command that should be executed when the RoutedCommand fires. </summary>
public ICommand Command
{
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(
"IsActive", typeof(bool), typeof(RoutedCommandHandler), new PropertyMetadata(default(bool)));
public bool IsActive
{
get { return (bool) GetValue(IsActiveProperty); }
set { SetValue(IsActiveProperty, value); }
}
/// <summary> The command that triggers <see cref="ICommand"/>. </summary>
public ICommand RoutedCommand { get; set; }
/// <inheritdoc />
protected override Freezable CreateInstanceCore()
{
return new RoutedCommandHandler();
}
/// <summary>
/// Register this handler to respond to the registered RoutedCommand for the
/// given element.
/// </summary>
/// <param name="owner"> The element for which we should register the command
/// binding for the current routed command. </param>
internal void Register(FrameworkElement owner)
{
var binding = new CommandBinding(RoutedCommand, HandleExecuted, HandleCanExecute);
owner.CommandBindings.Add(binding);
}
/// <summary> Proxy to the current Command.CanExecute(object). </summary>
private void HandleCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (!IsActive) return;
e.CanExecute = Command?.CanExecute(e.Parameter) != null;
e.Handled = true;
}
/// <summary> Proxy to the current Command.Execute(object). </summary>
private void HandleExecuted(object sender, ExecutedRoutedEventArgs e)
{
if (!IsActive) return;
Command?.Execute(e.Parameter);
e.Handled = true;
}
}
}

View File

@ -0,0 +1,79 @@
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
namespace Filtration.Utility
{
/// <summary>
/// Holds a collection of <see cref="RoutedCommandHandler"/> that should be
/// turned into CommandBindings.
/// </summary>
public class RoutedCommandHandlers : FreezableCollection<RoutedCommandHandler>
{
/// <summary>
/// Hide this from WPF so that it's forced to go through
/// <see cref="GetCommands"/> and we can auto-create the collection
/// if it doesn't already exist. This isn't strictly necessary but it makes
/// the XAML much nicer.
/// </summary>
private static readonly DependencyProperty CommandsProperty = DependencyProperty.RegisterAttached(
"CommandsPrivate",
typeof(RoutedCommandHandlers),
typeof(RoutedCommandHandlers),
new PropertyMetadata(default(RoutedCommandHandlers)));
/// <summary>
/// Gets the collection of RoutedCommandHandler for a given element, creating
/// it if it doesn't already exist.
/// </summary>
public static RoutedCommandHandlers GetCommands(FrameworkElement element)
{
RoutedCommandHandlers handlers = (RoutedCommandHandlers)element.GetValue(CommandsProperty);
if (handlers == null)
{
handlers = new RoutedCommandHandlers(element);
element.SetValue(CommandsProperty, handlers);
}
return handlers;
}
private readonly FrameworkElement _owner;
/// <summary> Each collection is tied to a specific element. </summary>
/// <param name="owner"> The element for which this collection is created. </param>
public RoutedCommandHandlers(FrameworkElement owner)
{
_owner = owner;
// because we auto-create the collection, we don't know when items will be
// added. So, we observe ourself for changes manually.
var self = (INotifyCollectionChanged)this;
self.CollectionChanged += (sender, args) =>
{
// note this does not handle deletions, that's left as an exercise for the
// reader, but most of the time, that's not needed!
((RoutedCommandHandlers)sender).HandleAdditions(args.NewItems);
};
}
/// <summary> Invoked when new items are added to the collection. </summary>
/// <param name="newItems"> The new items that were added. </param>
private void HandleAdditions(IList newItems)
{
if (newItems == null)
return;
foreach (RoutedCommandHandler routedHandler in newItems)
{
routedHandler.Register(_owner);
}
}
/// <inheritdoc />
protected override Freezable CreateInstanceCore()
{
return new RoutedCommandHandlers(_owner);
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Windows;
using Filtration.Common.ViewModels; using Filtration.Common.ViewModels;
using Filtration.Interface; using Filtration.Interface;
using Filtration.ThemeEditor.ViewModels; using Filtration.ThemeEditor.ViewModels;
@ -18,7 +19,7 @@ namespace Filtration.ViewModels
ReadOnlyObservableCollection<IDocument> OpenDocuments { get; } ReadOnlyObservableCollection<IDocument> OpenDocuments { get; }
IItemFilterScriptViewModel ActiveScriptViewModel { get; } IItemFilterScriptViewModel ActiveScriptViewModel { get; }
IThemeEditorViewModel ActiveThemeViewModel { get; } IThemeEditorViewModel ActiveThemeViewModel { get; }
ISectionBrowserViewModel SectionBrowserViewModel { get; } ICommentBlockBrowserViewModel CommentBlockBrowserViewModel { get; }
IBlockGroupBrowserViewModel BlockGroupBrowserViewModel { get; } IBlockGroupBrowserViewModel BlockGroupBrowserViewModel { get; }
IBlockOutputPreviewViewModel BlockOutputPreviewViewModel { get; } IBlockOutputPreviewViewModel BlockOutputPreviewViewModel { get; }
void AddDocument(IDocument document); void AddDocument(IDocument document);
@ -29,7 +30,7 @@ namespace Filtration.ViewModels
internal class AvalonDockWorkspaceViewModel : ViewModelBase, IAvalonDockWorkspaceViewModel internal class AvalonDockWorkspaceViewModel : ViewModelBase, IAvalonDockWorkspaceViewModel
{ {
private readonly ISectionBrowserViewModel _sectionBrowserViewModel; private readonly ICommentBlockBrowserViewModel _commentBlockBrowserViewModel;
private readonly IBlockGroupBrowserViewModel _blockGroupBrowserViewModel; private readonly IBlockGroupBrowserViewModel _blockGroupBrowserViewModel;
private readonly IBlockOutputPreviewViewModel _blockOutputPreviewViewModel; private readonly IBlockOutputPreviewViewModel _blockOutputPreviewViewModel;
@ -38,16 +39,16 @@ namespace Filtration.ViewModels
private IThemeEditorViewModel _activeThemeViewModel; private IThemeEditorViewModel _activeThemeViewModel;
private readonly ObservableCollection<IDocument> _openDocuments; private readonly ObservableCollection<IDocument> _openDocuments;
public AvalonDockWorkspaceViewModel(ISectionBrowserViewModel sectionBrowserViewModel, public AvalonDockWorkspaceViewModel(ICommentBlockBrowserViewModel commentBlockBrowserViewModel,
IBlockGroupBrowserViewModel blockGroupBrowserViewModel, IBlockGroupBrowserViewModel blockGroupBrowserViewModel,
IStartPageViewModel startPageViewModel, IStartPageViewModel startPageViewModel,
IBlockOutputPreviewViewModel blockOutputPreviewViewModel) IBlockOutputPreviewViewModel blockOutputPreviewViewModel)
{ {
_sectionBrowserViewModel = sectionBrowserViewModel; _commentBlockBrowserViewModel = commentBlockBrowserViewModel;
_blockGroupBrowserViewModel = blockGroupBrowserViewModel; _blockGroupBrowserViewModel = blockGroupBrowserViewModel;
_blockOutputPreviewViewModel = blockOutputPreviewViewModel; _blockOutputPreviewViewModel = blockOutputPreviewViewModel;
_sectionBrowserViewModel.Initialise(this); _commentBlockBrowserViewModel.Initialise(this);
_blockGroupBrowserViewModel.Initialise(this); _blockGroupBrowserViewModel.Initialise(this);
_blockOutputPreviewViewModel.Initialise(this); _blockOutputPreviewViewModel.Initialise(this);
@ -94,13 +95,13 @@ namespace Filtration.ViewModels
public IThemeEditorViewModel ActiveThemeViewModel => _activeThemeViewModel; public IThemeEditorViewModel ActiveThemeViewModel => _activeThemeViewModel;
public IBlockGroupBrowserViewModel BlockGroupBrowserViewModel => _blockGroupBrowserViewModel; public IBlockGroupBrowserViewModel BlockGroupBrowserViewModel => _blockGroupBrowserViewModel;
public IBlockOutputPreviewViewModel BlockOutputPreviewViewModel => _blockOutputPreviewViewModel; public IBlockOutputPreviewViewModel BlockOutputPreviewViewModel => _blockOutputPreviewViewModel;
public ISectionBrowserViewModel SectionBrowserViewModel => _sectionBrowserViewModel; public ICommentBlockBrowserViewModel CommentBlockBrowserViewModel => _commentBlockBrowserViewModel;
private List<IToolViewModel> _tools; private List<IToolViewModel> _tools;
public IEnumerable<IToolViewModel> Tools => _tools ?? (_tools = new List<IToolViewModel> public IEnumerable<IToolViewModel> Tools => _tools ?? (_tools = new List<IToolViewModel>
{ {
_sectionBrowserViewModel, _commentBlockBrowserViewModel,
_blockGroupBrowserViewModel, _blockGroupBrowserViewModel,
_blockOutputPreviewViewModel _blockOutputPreviewViewModel
}); });
@ -116,7 +117,7 @@ namespace Filtration.ViewModels
_activeThemeViewModel = (IThemeEditorViewModel) document; _activeThemeViewModel = (IThemeEditorViewModel) document;
} }
_openDocuments.Add(document); Application.Current.Dispatcher.Invoke(() => _openDocuments.Add(document));
ActiveDocument = document; ActiveDocument = document;
} }
@ -129,7 +130,7 @@ namespace Filtration.ViewModels
if (document.IsScript && ActiveDocument == document) if (document.IsScript && ActiveDocument == document)
{ {
_sectionBrowserViewModel.ClearDown(); _commentBlockBrowserViewModel.ClearDown();
_blockGroupBrowserViewModel.ClearDown(); _blockGroupBrowserViewModel.ClearDown();
_blockOutputPreviewViewModel.ClearDown(); _blockOutputPreviewViewModel.ClearDown();
} }

View File

@ -1,4 +1,4 @@
namespace Filtration.ViewModels namespace Filtration.ViewModels.Factories
{ {
internal interface IItemFilterBlockViewModelFactory internal interface IItemFilterBlockViewModelFactory
{ {

View File

@ -0,0 +1,8 @@
namespace Filtration.ViewModels.Factories
{
internal interface IItemFilterCommentBlockViewModelFactory
{
IItemFilterCommentBlockViewModel Create();
void Release(IItemFilterCommentBlockViewModel itemFilterCommentBlockViewModel);
}
}

View File

@ -1,4 +1,4 @@
namespace Filtration.ViewModels namespace Filtration.ViewModels.Factories
{ {
internal interface IItemFilterScriptViewModelFactory internal interface IItemFilterScriptViewModelFactory
{ {

View File

@ -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");
}
}
}

View File

@ -18,6 +18,42 @@ namespace Filtration.ViewModels
ChildGroups = new ObservableCollection<ItemFilterBlockGroupViewModel>(); ChildGroups = new ObservableCollection<ItemFilterBlockGroupViewModel>();
} }
public ItemFilterBlockGroupViewModel(ItemFilterBlockGroup itemFilterBlockGroup, bool showAdvanced, ItemFilterBlockGroupViewModel parent)
{
GroupName = itemFilterBlockGroup.GroupName;
ParentGroup = parent;
Advanced = itemFilterBlockGroup.Advanced;
SourceBlockGroup = itemFilterBlockGroup;
IsChecked = itemFilterBlockGroup.IsChecked;
ChildGroups = new ObservableCollection<ItemFilterBlockGroupViewModel>();
foreach (var childGroup in itemFilterBlockGroup.ChildGroups.Where(c => showAdvanced || !c.Advanced))
{
ChildGroups.Add(new ItemFilterBlockGroupViewModel(childGroup, showAdvanced, this));
}
if (ChildGroups.Any())
{
SetIsCheckedBasedOnChildGroups();
}
}
private void SetIsCheckedBasedOnChildGroups()
{
if (ChildGroups.All(g => g.IsChecked == true))
{
IsChecked = true;
}
else if (ChildGroups.Any(g => g.IsChecked == true || g.IsChecked == null))
{
IsChecked = null;
}
else
{
IsChecked = false;
}
}
public string GroupName { get; internal set; } public string GroupName { get; internal set; }
public ItemFilterBlockGroupViewModel ParentGroup { get; internal set; } public ItemFilterBlockGroupViewModel ParentGroup { get; internal set; }
public ObservableCollection<ItemFilterBlockGroupViewModel> ChildGroups { get; internal set; } public ObservableCollection<ItemFilterBlockGroupViewModel> ChildGroups { get; internal set; }

View File

@ -4,23 +4,18 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Windows.Media; using System.Windows.Media;
using Filtration.Common.ViewModels;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemBaseTypes; using Filtration.ObjectModel.BlockItemBaseTypes;
using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.BlockItemTypes;
using Filtration.Services; using Filtration.Services;
using Filtration.Views; using Filtration.Views;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using Xceed.Wpf.Toolkit; using Xceed.Wpf.Toolkit;
namespace Filtration.ViewModels namespace Filtration.ViewModels
{ {
internal interface IItemFilterBlockViewModel internal interface IItemFilterBlockViewModel : IItemFilterBlockViewModelBase
{ {
event EventHandler BlockBecameDirty;
void Initialise(IItemFilterBlock itemFilterBlock, ItemFilterScriptViewModel parentScriptViewModel);
bool IsDirty { get; set; }
bool IsExpanded { get; set; } bool IsExpanded { get; set; }
IItemFilterBlock Block { get; } IItemFilterBlock Block { get; }
bool BlockEnabled { get; set; } bool BlockEnabled { get; set; }
@ -28,17 +23,16 @@ namespace Filtration.ViewModels
void RefreshBlockPreview(); void RefreshBlockPreview();
} }
internal class ItemFilterBlockViewModel : ViewModelBase, IItemFilterBlockViewModel internal class ItemFilterBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterBlockViewModel
{ {
private readonly IStaticDataService _staticDataService; private readonly IStaticDataService _staticDataService;
private readonly IReplaceColorsViewModel _replaceColorsViewModel; private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private readonly MediaPlayer _mediaPlayer = new MediaPlayer(); private readonly MediaPlayer _mediaPlayer = new MediaPlayer();
private ItemFilterScriptViewModel _parentScriptViewModel; private IItemFilterScriptViewModel _parentScriptViewModel;
private bool _displaySettingsPopupOpen; private bool _displaySettingsPopupOpen;
private bool _isExpanded; private bool _isExpanded;
private bool _audioVisualBlockItemsGridVisible; private bool _audioVisualBlockItemsGridVisible;
private bool _isDirty;
public ItemFilterBlockViewModel(IStaticDataService staticDataService, IReplaceColorsViewModel replaceColorsViewModel) public ItemFilterBlockViewModel(IStaticDataService staticDataService, IReplaceColorsViewModel replaceColorsViewModel)
{ {
@ -64,10 +58,9 @@ namespace Filtration.ViewModels
PlaySoundCommand = new RelayCommand(OnPlaySoundCommand, () => HasSound); PlaySoundCommand = new RelayCommand(OnPlaySoundCommand, () => HasSound);
} }
public event EventHandler BlockBecameDirty; public override void Initialise(IItemFilterBlockBase itemFilterBlockBase, IItemFilterScriptViewModel parentScriptViewModel)
public void Initialise(IItemFilterBlock itemFilterBlock, ItemFilterScriptViewModel parentScriptViewModel)
{ {
var itemFilterBlock = itemFilterBlockBase as IItemFilterBlock;
if (itemFilterBlock == null || parentScriptViewModel == null) if (itemFilterBlock == null || parentScriptViewModel == null)
{ {
throw new ArgumentNullException(nameof(itemFilterBlock)); throw new ArgumentNullException(nameof(itemFilterBlock));
@ -76,51 +69,42 @@ namespace Filtration.ViewModels
_parentScriptViewModel = parentScriptViewModel; _parentScriptViewModel = parentScriptViewModel;
Block = itemFilterBlock; Block = itemFilterBlock;
itemFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged; itemFilterBlock.BlockItems.CollectionChanged += OnBlockItemsCollectionChanged;
foreach (var blockItem in itemFilterBlock.BlockItems) foreach (var blockItem in itemFilterBlock.BlockItems)
{ {
blockItem.PropertyChanged += OnBlockItemChanged; blockItem.PropertyChanged += OnBlockItemChanged;
} }
base.Initialise(itemFilterBlock, parentScriptViewModel);
} }
public RelayCommand CopyBlockCommand { get; private set; } public RelayCommand CopyBlockCommand { get; }
public RelayCommand PasteBlockCommand { get; private set; } public RelayCommand PasteBlockCommand { get; }
public RelayCommand CopyBlockStyleCommand { get; private set; } public RelayCommand CopyBlockStyleCommand { get; }
public RelayCommand PasteBlockStyleCommand { get; private set; } public RelayCommand PasteBlockStyleCommand { get; }
public RelayCommand AddBlockCommand { get; private set; } public RelayCommand AddBlockCommand { get; }
public RelayCommand AddSectionCommand { get; private set; } public RelayCommand AddSectionCommand { get; }
public RelayCommand DeleteBlockCommand { get; private set; } public RelayCommand DeleteBlockCommand { get; }
public RelayCommand MoveBlockUpCommand { get; private set; } public RelayCommand MoveBlockUpCommand { get; }
public RelayCommand MoveBlockDownCommand { get; private set; } public RelayCommand MoveBlockDownCommand { get; }
public RelayCommand MoveBlockToTopCommand { get; private set; } public RelayCommand MoveBlockToTopCommand { get; }
public RelayCommand MoveBlockToBottomCommand { get; private set; } public RelayCommand MoveBlockToBottomCommand { get; }
public RelayCommand ToggleBlockActionCommand { get; private set; } public RelayCommand ToggleBlockActionCommand { get; }
public RelayCommand ReplaceColorsCommand { get; private set; } public RelayCommand ReplaceColorsCommand { get; }
public RelayCommand<Type> AddFilterBlockItemCommand { get; private set; } public RelayCommand<Type> AddFilterBlockItemCommand { get; }
public RelayCommand<IItemFilterBlockItem> RemoveFilterBlockItemCommand { get; private set; } public RelayCommand<IItemFilterBlockItem> RemoveFilterBlockItemCommand { get; }
public RelayCommand PlaySoundCommand { get; private set; } public RelayCommand PlaySoundCommand { get; }
public RelayCommand SwitchBlockItemsViewCommand { get; private set; } public RelayCommand SwitchBlockItemsViewCommand { get; }
public IItemFilterBlock Block { get; private set; } public IItemFilterBlock Block { get; private set; }
public bool IsDirty
{
get { return _isDirty; }
set
{
if (value != _isDirty)
{
_isDirty = value;
RaisePropertyChanged();
BlockBecameDirty?.Invoke(this, EventArgs.Empty);
}
}
}
public bool IsExpanded public bool IsExpanded
{ {
get { return _isExpanded; } get => _isExpanded;
set set
{ {
_isExpanded = value; _isExpanded = value;
@ -305,7 +289,7 @@ namespace Filtration.ViewModels
private void OnAddSectionCommand() private void OnAddSectionCommand()
{ {
_parentScriptViewModel.AddSection(this); _parentScriptViewModel.AddCommentBlock(this);
} }
private void OnDeleteBlockCommand() private void OnDeleteBlockCommand()

View File

@ -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);
}
}
}
}
}

View File

@ -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;
}
}

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -14,8 +16,11 @@ using Filtration.Common.ViewModels;
using Filtration.Interface; using Filtration.Interface;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemBaseTypes; using Filtration.ObjectModel.BlockItemBaseTypes;
using Filtration.ObjectModel.Commands;
using Filtration.ObjectModel.Commands.ItemFilterScript;
using Filtration.Parser.Interface.Services; using Filtration.Parser.Interface.Services;
using Filtration.Services; using Filtration.Services;
using Filtration.ViewModels.Factories;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging; using GalaSoft.MvvmLight.Messaging;
using NLog; using NLog;
@ -24,17 +29,17 @@ namespace Filtration.ViewModels
{ {
internal interface IItemFilterScriptViewModel : IEditableDocument internal interface IItemFilterScriptViewModel : IEditableDocument
{ {
ItemFilterScript Script { get; } IItemFilterScript Script { get; }
IItemFilterBlockViewModel SelectedBlockViewModel { get; set; } IItemFilterBlockViewModelBase SelectedBlockViewModel { get; set; }
IItemFilterBlockViewModel SectionBrowserSelectedBlockViewModel { get; set; } IItemFilterCommentBlockViewModel CommentBlockBrowserBrowserSelectedBlockViewModel { get; set; }
IEnumerable<IItemFilterBlockViewModel> ItemFilterSectionViewModels { get; } IEnumerable<IItemFilterCommentBlockViewModel> ItemFilterCommentBlockViewModels { get; }
Predicate<IItemFilterBlockViewModel> BlockFilterPredicate { get; set; } Predicate<IItemFilterBlockViewModel> BlockFilterPredicate { get; set; }
bool ShowAdvanced { get; } bool ShowAdvanced { get; }
string Description { get; set; } string Description { get; set; }
string DisplayName { get; } string DisplayName { get; }
void Initialise(ItemFilterScript itemFilterScript, bool newScript); void Initialise(IItemFilterScript itemFilterScript, bool newScript);
void RemoveDirtyFlag(); void RemoveDirtyFlag();
void SetDirtyFlag(); void SetDirtyFlag();
bool HasSelectedEnabledBlock(); bool HasSelectedEnabledBlock();
@ -58,19 +63,24 @@ namespace Filtration.ViewModels
RelayCommand<bool> ToggleShowAdvancedCommand { get; } RelayCommand<bool> ToggleShowAdvancedCommand { get; }
RelayCommand ClearFilterCommand { get; } RelayCommand ClearFilterCommand { get; }
void AddSection(IItemFilterBlockViewModel targetBlockViewModel); void AddCommentBlock(IItemFilterBlockViewModelBase targetBlockViewModel);
void AddBlock(IItemFilterBlockViewModel targetBlockViewModel); void AddBlock(IItemFilterBlockViewModelBase targetBlockViewModel);
void CopyBlock(IItemFilterBlockViewModel targetBlockViewModel); void CopyBlock(IItemFilterBlockViewModelBase targetBlockViewModel);
void CopyBlockStyle(IItemFilterBlockViewModel targetBlockViewModel); void CopyBlockStyle(IItemFilterBlockViewModel targetBlockViewModel);
void PasteBlock(IItemFilterBlockViewModel targetBlockViewModel); void PasteBlock(IItemFilterBlockViewModelBase targetBlockViewModel);
void PasteBlockStyle(IItemFilterBlockViewModel 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 internal class ItemFilterScriptViewModel : PaneViewModel, IItemFilterScriptViewModel
{ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IItemFilterBlockViewModelFactory _itemFilterBlockViewModelFactory; private readonly IItemFilterBlockBaseViewModelFactory _itemFilterBlockBaseViewModelFactory;
private readonly IItemFilterBlockTranslator _blockTranslator; private readonly IItemFilterBlockTranslator _blockTranslator;
private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel; private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
private readonly IItemFilterPersistenceService _persistenceService; private readonly IItemFilterPersistenceService _persistenceService;
@ -79,13 +89,14 @@ namespace Filtration.ViewModels
private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder; private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder;
private bool _isDirty; private bool _isDirty;
private IItemFilterBlockViewModel _selectedBlockViewModel; private IItemFilterBlockViewModelBase _selectedBlockViewModel;
private IItemFilterBlockViewModel _sectionBrowserSelectedBlockViewModel; private IItemFilterCommentBlockViewModel _sectionBrowserSelectedBlockViewModel;
private readonly ObservableCollection<IItemFilterBlockViewModel> _itemFilterBlockViewModels; private readonly ObservableCollection<IItemFilterBlockViewModelBase> _itemFilterBlockViewModels;
private ICollectionView _itemFilterBlockViewModelsCollectionView; private ICollectionView _itemFilterBlockViewModelsCollectionView;
private Predicate<IItemFilterBlockViewModel> _blockFilterPredicate; private Predicate<IItemFilterBlockViewModel> _blockFilterPredicate;
private ICommandManager _scriptCommandManager;
public ItemFilterScriptViewModel(IItemFilterBlockViewModelFactory itemFilterBlockViewModelFactory, public ItemFilterScriptViewModel(IItemFilterBlockBaseViewModelFactory itemFilterBlockBaseViewModelFactory,
IItemFilterBlockTranslator blockTranslator, IItemFilterBlockTranslator blockTranslator,
IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel, IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel,
IItemFilterPersistenceService persistenceService, IItemFilterPersistenceService persistenceService,
@ -93,7 +104,7 @@ namespace Filtration.ViewModels
IClipboardService clipboardService, IClipboardService clipboardService,
IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder) IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder)
{ {
_itemFilterBlockViewModelFactory = itemFilterBlockViewModelFactory; _itemFilterBlockBaseViewModelFactory = itemFilterBlockBaseViewModelFactory;
_blockTranslator = blockTranslator; _blockTranslator = blockTranslator;
_avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel; _avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel;
_avalonDockWorkspaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged; _avalonDockWorkspaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged;
@ -101,18 +112,23 @@ namespace Filtration.ViewModels
_messageBoxService = messageBoxService; _messageBoxService = messageBoxService;
_clipboardService = clipboardService; _clipboardService = clipboardService;
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder; _blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
_itemFilterBlockViewModels = new ObservableCollection<IItemFilterBlockViewModel>(); _itemFilterBlockViewModels = new ObservableCollection<IItemFilterBlockViewModelBase>();
_avalonDockWorkspaceViewModel.ActiveDocumentChanged += (s, e) =>
{
RaisePropertyChanged(nameof(IsActiveDocument));
};
ToggleShowAdvancedCommand = new RelayCommand<bool>(OnToggleShowAdvancedCommand); ToggleShowAdvancedCommand = new RelayCommand<bool>(OnToggleShowAdvancedCommand);
ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null); ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null);
CloseCommand = new RelayCommand(async () => await OnCloseCommand()); CloseCommand = new RelayCommand(async () => await OnCloseCommand());
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null); DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null); MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) > 0);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null); MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) > 0);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => SelectedBlockViewModel != null); MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) < ItemFilterBlockViewModels.Count);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => SelectedBlockViewModel != null); MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => SelectedBlockViewModel != null && ItemFilterBlockViewModels.IndexOf(SelectedBlockViewModel) < ItemFilterBlockViewModels.Count);
AddBlockCommand = new RelayCommand(OnAddBlockCommand); AddBlockCommand = new RelayCommand(OnAddBlockCommand);
AddSectionCommand = new RelayCommand(OnAddSectionCommand, () => SelectedBlockViewModel != null); AddSectionCommand = new RelayCommand(OnAddCommentBlockCommand, () => SelectedBlockViewModel != null);
DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, HasSelectedEnabledBlock); DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, HasSelectedEnabledBlock);
EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, HasSelectedDisabledBlock); EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, HasSelectedDisabledBlock);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null); CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null);
@ -129,6 +145,94 @@ namespace Filtration.ViewModels
IconSource = icon; 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<IItemFilterBlockBase>(), notifyCollectionChangedEventArgs.NewStartingIndex);
break;
}
case NotifyCollectionChangedAction.Remove:
{
RemoveItemFilterBlockviewModels(notifyCollectionChangedEventArgs.OldItems.Cast<IItemFilterBlockBase>());
break;
}
default:
{
Debugger.Break(); // Unhandled NotifyCollectionChangedAction
break;
}
}
}
private void AddItemFilterBlockViewModels(IEnumerable<IItemFilterBlockBase> 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<IItemFilterBlockBase> 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<bool> ToggleShowAdvancedCommand { get; } public RelayCommand<bool> ToggleShowAdvancedCommand { get; }
public RelayCommand ClearFilterCommand { get; } public RelayCommand ClearFilterCommand { get; }
public RelayCommand CloseCommand { get; } public RelayCommand CloseCommand { get; }
@ -148,7 +252,19 @@ namespace Filtration.ViewModels
public RelayCommand ExpandAllBlocksCommand { get; } public RelayCommand ExpandAllBlocksCommand { get; }
public RelayCommand CollapseAllBlocksCommand { get; } public RelayCommand CollapseAllBlocksCommand { get; }
public ObservableCollection<IItemFilterBlockViewModel> ItemFilterBlockViewModels public bool IsActiveDocument
{
get
{
var isActiveDocument = _avalonDockWorkspaceViewModel.ActiveScriptViewModel == this;
Debug.WriteLine($"IsActiveDocument: {isActiveDocument}");
return isActiveDocument;
}
}
public ObservableCollection<IItemFilterBlockViewModelBase> ItemFilterBlockViewModels
{ {
get get
{ {
@ -162,6 +278,8 @@ namespace Filtration.ViewModels
private bool BlockFilter(object item) private bool BlockFilter(object item)
{ {
if (!(item is IItemFilterBlockViewModelBase)) return false;
if (item is IItemFilterCommentBlockViewModel) return true;
var blockViewModel = item as IItemFilterBlockViewModel; var blockViewModel = item as IItemFilterBlockViewModel;
if (BlockFilterPredicate != null) if (BlockFilterPredicate != null)
@ -190,62 +308,60 @@ namespace Filtration.ViewModels
public Predicate<IItemFilterBlockViewModel> BlockFilterPredicate public Predicate<IItemFilterBlockViewModel> BlockFilterPredicate
{ {
get { return _blockFilterPredicate; } get => _blockFilterPredicate;
set set
{ {
_blockFilterPredicate = value; _blockFilterPredicate = value;
RaisePropertyChanged("ItemFilterBlockViewModels"); RaisePropertyChanged(nameof(ItemFilterBlockViewModels));
} }
} }
public IEnumerable<IItemFilterBlockViewModel> ItemFilterSectionViewModels public IEnumerable<IItemFilterCommentBlockViewModel> ItemFilterCommentBlockViewModels => ItemFilterBlockViewModels.OfType<IItemFilterCommentBlockViewModel>();
{
get { return ItemFilterBlockViewModels.Where(b => b.Block.GetType() == typeof (ItemFilterSection)); }
}
public bool IsScript => true; public bool IsScript => true;
public bool IsTheme => false; public bool IsTheme => false;
public string Description public string Description
{ {
get { return Script.Description; } get => Script.Description;
set set => _scriptCommandManager.ExecuteCommand(new SetScriptDescriptionCommand(Script, value));
{
Script.Description = value;
IsDirty = true;
RaisePropertyChanged();
}
} }
public bool ShowAdvanced public bool ShowAdvanced
{ {
get { return _showAdvanced; } get => _showAdvanced;
private set private set
{ {
_showAdvanced = value; _showAdvanced = value;
RaisePropertyChanged(); RaisePropertyChanged();
RaisePropertyChanged("ItemFilterBlockViewModels"); RaisePropertyChanged(nameof(ItemFilterBlockViewModels));
} }
} }
public bool HasSelectedBlock()
{
return SelectedBlockViewModel != null;
}
public bool HasSelectedEnabledBlock() public bool HasSelectedEnabledBlock()
{ {
return HasSelectedBlock() && !(SelectedBlockViewModel.Block is ItemFilterSection) && SelectedBlockViewModel.BlockEnabled; var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
if (selectedBlockViewModel == null) return false;
return HasSelectedBlock() && selectedBlockViewModel.BlockEnabled;
} }
public bool HasSelectedDisabledBlock() public bool HasSelectedDisabledBlock()
{ {
return HasSelectedBlock() && !(SelectedBlockViewModel.Block is ItemFilterSection) && !SelectedBlockViewModel.BlockEnabled; var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
if (selectedBlockViewModel == null) return false;
return HasSelectedBlock() && !selectedBlockViewModel.BlockEnabled;
} }
public IItemFilterBlockViewModel SelectedBlockViewModel private bool HasSelectedBlock()
{ {
get { return _selectedBlockViewModel; } return SelectedBlockViewModel != null;
}
public IItemFilterBlockViewModelBase SelectedBlockViewModel
{
get => _selectedBlockViewModel;
set set
{ {
if (value != _selectedBlockViewModel) if (value != _selectedBlockViewModel)
@ -257,9 +373,9 @@ namespace Filtration.ViewModels
} }
} }
public IItemFilterBlockViewModel SectionBrowserSelectedBlockViewModel public IItemFilterCommentBlockViewModel CommentBlockBrowserBrowserSelectedBlockViewModel
{ {
get { return _sectionBrowserSelectedBlockViewModel; } get => _sectionBrowserSelectedBlockViewModel;
set set
{ {
_sectionBrowserSelectedBlockViewModel = value; _sectionBrowserSelectedBlockViewModel = value;
@ -268,11 +384,11 @@ namespace Filtration.ViewModels
} }
} }
public ItemFilterScript Script { get; private set; } public IItemFilterScript Script { get; private set; }
public bool IsDirty public bool IsDirty
{ {
get { return _isDirty || HasDirtyChildren; } get => _isDirty || HasDirtyChildren;
set set
{ {
if (_isDirty != value) if (_isDirty != value)
@ -295,15 +411,15 @@ namespace Filtration.ViewModels
{ {
CleanChildren(); CleanChildren();
IsDirty = false; IsDirty = false;
RaisePropertyChanged("Filename"); RaisePropertyChanged(nameof(Filename));
RaisePropertyChanged("DisplayName"); RaisePropertyChanged(nameof(DisplayName));
} }
public void SetDirtyFlag() public void SetDirtyFlag()
{ {
IsDirty = true; IsDirty = true;
RaisePropertyChanged("Filename"); RaisePropertyChanged(nameof(Filename));
RaisePropertyChanged("DisplayName"); RaisePropertyChanged(nameof(DisplayName));
} }
public string DisplayName => !string.IsNullOrEmpty(Filename) ? Filename : Description; public string DisplayName => !string.IsNullOrEmpty(Filename) ? Filename : Description;
@ -315,35 +431,6 @@ namespace Filtration.ViewModels
private bool _filenameIsFake; private bool _filenameIsFake;
private bool _showAdvanced; private bool _showAdvanced;
public void Initialise(ItemFilterScript itemFilterScript, bool newScript)
{
ItemFilterBlockViewModels.Clear();
Script = itemFilterScript;
foreach (var block in Script.ItemFilterBlocks)
{
var vm = _itemFilterBlockViewModelFactory.Create();
vm.Initialise(block, this);
vm.BlockBecameDirty += OnBlockBecameDirty;
ItemFilterBlockViewModels.Add(vm);
}
_filenameIsFake = newScript;
if (newScript)
{
Script.FilePath = "Untitled.filter";
}
if (ItemFilterBlockViewModels.Count > 0)
{
SelectedBlockViewModel = ItemFilterBlockViewModels.First();
}
Title = Filename;
ContentId = "ScriptContentId";
}
public async Task SaveAsync() public async Task SaveAsync()
{ {
if (!ValidateScript()) return; if (!ValidateScript()) return;
@ -426,7 +513,7 @@ namespace Filtration.ViewModels
var unusedThemeComponents = var unusedThemeComponents =
Script.ThemeComponents.Where( Script.ThemeComponents.Where(
t => t =>
Script.ItemFilterBlocks.Count( Script.ItemFilterBlocks.OfType<ItemFilterBlock>().Count(
b => b.BlockItems.OfType<ColorBlockItem>().Count(i => i.ThemeComponent == t) > 0) == 0).ToList(); b => b.BlockItems.OfType<ColorBlockItem>().Count(i => i.ThemeComponent == t) > 0) == 0).ToList();
if (unusedThemeComponents.Count <= 0) return true; if (unusedThemeComponents.Count <= 0) return true;
@ -550,23 +637,25 @@ namespace Filtration.ViewModels
CopyBlock(SelectedBlockViewModel); CopyBlock(SelectedBlockViewModel);
} }
public void CopyBlock(IItemFilterBlockViewModel targetBlockViewModel) public void CopyBlock(IItemFilterBlockViewModelBase targetBlockViewModel)
{ {
try try
{ {
_clipboardService.SetClipboardText( _clipboardService.SetClipboardText(_blockTranslator.TranslateItemFilterBlockBaseToString(SelectedBlockViewModel.BaseBlock));
_blockTranslator.TranslateItemFilterBlockToString(SelectedBlockViewModel.Block));
} }
catch catch
{ {
_messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.", _messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
private void OnCopyBlockStyleCommand() private void OnCopyBlockStyleCommand()
{ {
CopyBlockStyle(SelectedBlockViewModel); var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
if (selectedBlockViewModel != null)
{
CopyBlockStyle(selectedBlockViewModel);
}
} }
public void CopyBlockStyle(IItemFilterBlockViewModel targetBlockViewModel) public void CopyBlockStyle(IItemFilterBlockViewModel targetBlockViewModel)
@ -594,7 +683,11 @@ namespace Filtration.ViewModels
private void OnPasteBlockStyleCommand() private void OnPasteBlockStyleCommand()
{ {
PasteBlockStyle(SelectedBlockViewModel); var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
if (selectedBlockViewModel != null)
{
PasteBlockStyle(selectedBlockViewModel);
}
} }
public void PasteBlockStyle(IItemFilterBlockViewModel targetBlockViewModel) public void PasteBlockStyle(IItemFilterBlockViewModel targetBlockViewModel)
@ -614,45 +707,24 @@ namespace Filtration.ViewModels
PasteBlock(SelectedBlockViewModel); PasteBlock(SelectedBlockViewModel);
} }
public void PasteBlock(IItemFilterBlockViewModel targetBlockViewModel) public void PasteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{ {
try try
{ {
var clipboardText = _clipboardService.GetClipboardText(); var clipboardText = _clipboardService.GetClipboardText();
if (string.IsNullOrEmpty(clipboardText)) return; if (string.IsNullOrEmpty(clipboardText)) return;
_blockGroupHierarchyBuilder.Initialise(Script.ItemFilterBlockGroups.First());
var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script.ThemeComponents); var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script, true); // TODO: Doesn't handle pasting comment blocks?
if (translatedBlock == null) return; if (translatedBlock == null) return;
var vm = _itemFilterBlockViewModelFactory.Create(); _scriptCommandManager.ExecuteCommand(new PasteBlockCommand(Script, translatedBlock, targetBlockViewModelBase.BaseBlock));
vm.Initialise(translatedBlock, this);
if (ItemFilterBlockViewModels.Count > 0)
{
Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1,
translatedBlock);
ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
}
else
{
Script.ItemFilterBlocks.Add(translatedBlock);
ItemFilterBlockViewModels.Add(vm);
}
vm.BlockBecameDirty += OnBlockBecameDirty;
SelectedBlockViewModel = vm;
IsDirty = true;
} }
catch (Exception e) catch (Exception e)
{ {
Logger.Error(e); Logger.Error(e);
var innerException = e.InnerException?.Message ?? string.Empty; var innerException = e.InnerException?.Message ?? string.Empty;
_messageBoxService.Show("Paste Error", _messageBoxService.Show("Paste Error", e.Message + Environment.NewLine + innerException, MessageBoxButton.OK, MessageBoxImage.Error);
e.Message + Environment.NewLine + innerException, MessageBoxButton.OK,
MessageBoxImage.Error);
} }
} }
@ -661,40 +733,14 @@ namespace Filtration.ViewModels
MoveBlockToTop(SelectedBlockViewModel); MoveBlockToTop(SelectedBlockViewModel);
} }
public void MoveBlockToTop(IItemFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex > 0)
{
var block = targetBlockViewModel.Block;
Script.ItemFilterBlocks.Remove(block);
Script.ItemFilterBlocks.Insert(0, block);
ItemFilterBlockViewModels.Move(currentIndex, 0);
IsDirty = true;
RaisePropertyChanged(nameof(ItemFilterSectionViewModels));
}
}
private void OnMoveBlockUpCommand() private void OnMoveBlockUpCommand()
{ {
MoveBlockUp(SelectedBlockViewModel); MoveBlockUp(SelectedBlockViewModel);
} }
public void MoveBlockUp(IItemFilterBlockViewModel targetBlockViewModel) public void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{ {
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel); _scriptCommandManager.ExecuteCommand(new MoveBlockUpCommand(Script, targetBlockViewModelBase?.BaseBlock));
if (currentIndex > 0)
{
var block = targetBlockViewModel.Block;
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(ItemFilterSectionViewModels));
}
} }
private void OnMoveBlockDownCommand() private void OnMoveBlockDownCommand()
@ -702,20 +748,9 @@ namespace Filtration.ViewModels
MoveBlockDown(SelectedBlockViewModel); MoveBlockDown(SelectedBlockViewModel);
} }
public void MoveBlockDown(IItemFilterBlockViewModel targetBlockViewModel) public void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{ {
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel); _scriptCommandManager.ExecuteCommand(new MoveBlockDownCommand(Script, targetBlockViewModelBase?.BaseBlock));
if (currentIndex < ItemFilterBlockViewModels.Count - 1)
{
var block = targetBlockViewModel.Block;
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(ItemFilterSectionViewModels));
}
} }
private void OnMoveBlockToBottomCommand() private void OnMoveBlockToBottomCommand()
@ -723,47 +758,35 @@ namespace Filtration.ViewModels
MoveBlockToBottom(SelectedBlockViewModel); MoveBlockToBottom(SelectedBlockViewModel);
} }
public void MoveBlockToBottom(IItemFilterBlockViewModel targetBlockViewModel)
{
var currentIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModel);
if (currentIndex < ItemFilterBlockViewModels.Count - 1)
{
var block = targetBlockViewModel.Block;
Script.ItemFilterBlocks.Remove(block);
Script.ItemFilterBlocks.Add(block);
ItemFilterBlockViewModels.Move(currentIndex, ItemFilterBlockViewModels.Count - 1);
IsDirty = true;
RaisePropertyChanged(nameof(ItemFilterSectionViewModels));
}
}
private void OnAddBlockCommand() private void OnAddBlockCommand()
{ {
AddBlock(SelectedBlockViewModel); AddBlock(SelectedBlockViewModel);
} }
public void AddBlock(IItemFilterBlockViewModel targetBlockViewModel) public void AddBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{ {
var vm = _itemFilterBlockViewModelFactory.Create(); _scriptCommandManager.ExecuteCommand(new AddBlockCommand(Script, targetBlockViewModelBase?.BaseBlock));
var newBlock = new ItemFilterBlock(); // TODO: Expand new viewmodel
vm.Initialise(newBlock, this);
if (targetBlockViewModel != null)
{
Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModel.Block) + 1, newBlock);
ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModel) + 1, vm);
}
else
{
Script.ItemFilterBlocks.Add(newBlock);
ItemFilterBlockViewModels.Add(vm);
} }
vm.BlockBecameDirty += OnBlockBecameDirty; public void AddCommentBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase)
SelectedBlockViewModel = vm; {
vm.IsExpanded = true; _scriptCommandManager.ExecuteCommand(new AddCommentBlockCommand(Script, targetBlockViewModelBase.BaseBlock));
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) private void OnBlockBecameDirty(object sender, EventArgs e)
@ -771,28 +794,14 @@ namespace Filtration.ViewModels
SetDirtyFlag(); SetDirtyFlag();
} }
private void OnAddSectionCommand() private void OnAddCommentBlockCommand()
{ {
AddSection(SelectedBlockViewModel); AddCommentBlock(SelectedBlockViewModel);
}
public void AddSection(IItemFilterBlockViewModel targetBlockViewModel)
{
var vm = _itemFilterBlockViewModelFactory.Create();
var newSection = new ItemFilterSection { Description = "New Section" };
vm.Initialise(newSection, this);
Script.ItemFilterBlocks.Insert(Script.ItemFilterBlocks.IndexOf(targetBlockViewModel.Block), newSection);
ItemFilterBlockViewModels.Insert(ItemFilterBlockViewModels.IndexOf(targetBlockViewModel), vm);
IsDirty = true;
SelectedBlockViewModel = vm;
RaisePropertyChanged(nameof(ItemFilterSectionViewModels));
Messenger.Default.Send(new NotificationMessage("SectionsChanged"));
} }
private void OnExpandAllBlocksCommand() private void OnExpandAllBlocksCommand()
{ {
foreach (var blockViewModel in ItemFilterBlockViewModels) foreach (var blockViewModel in ItemFilterBlockViewModels.OfType<IItemFilterBlockViewModel>())
{ {
blockViewModel.IsExpanded = true; blockViewModel.IsExpanded = true;
} }
@ -800,7 +809,7 @@ namespace Filtration.ViewModels
private void OnCollapseAllBlocksCommand() private void OnCollapseAllBlocksCommand()
{ {
foreach (var blockViewModel in ItemFilterBlockViewModels) foreach (var blockViewModel in ItemFilterBlockViewModels.OfType<IItemFilterBlockViewModel>())
{ {
blockViewModel.IsExpanded = false; blockViewModel.IsExpanded = false;
} }
@ -811,49 +820,22 @@ namespace Filtration.ViewModels
DeleteBlock(SelectedBlockViewModel); DeleteBlock(SelectedBlockViewModel);
} }
public void DeleteBlock(IItemFilterBlockViewModel targetBlockViewModel)
{
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 = targetBlockViewModel.Block is ItemFilterSection;
Script.ItemFilterBlocks.Remove(targetBlockViewModel.Block);
ItemFilterBlockViewModels.Remove(targetBlockViewModel);
IsDirty = true;
targetBlockViewModel.BlockBecameDirty -= OnBlockBecameDirty;
if (isSection)
{
Messenger.Default.Send(new NotificationMessage("SectionsChanged"));
}
}
SelectedBlockViewModel = null;
}
private void OnDisableBlockCommand() private void OnDisableBlockCommand()
{ {
DisableBlock(SelectedBlockViewModel); var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
} if (selectedBlockViewModel != null)
private void DisableBlock(IItemFilterBlockViewModel targetBlockViewModel)
{ {
targetBlockViewModel.BlockEnabled = false; selectedBlockViewModel.BlockEnabled = false;
}
} }
private void OnEnableBlockCommand() private void OnEnableBlockCommand()
{ {
EnableBlock(SelectedBlockViewModel); var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
} if (selectedBlockViewModel != null)
private void EnableBlock(IItemFilterBlockViewModel targetBlockViewModel)
{ {
targetBlockViewModel.BlockEnabled = true; selectedBlockViewModel.BlockEnabled = true;
}
} }
} }
} }

View File

@ -85,6 +85,11 @@ namespace Filtration.ViewModels
PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); PasteCommand = new RelayCommand(OnPasteCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
PasteBlockStyleCommand = new RelayCommand(OnPasteBlockStyleCommand, () => 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); MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
@ -191,6 +196,9 @@ namespace Filtration.ViewModels
public RelayCommand OpenAboutWindowCommand { get; } public RelayCommand OpenAboutWindowCommand { get; }
public RelayCommand ReplaceColorsCommand { get; } public RelayCommand ReplaceColorsCommand { get; }
public RelayCommand UndoCommand { get;}
public RelayCommand RedoCommand { get; }
public RelayCommand EditMasterThemeCommand { get; } public RelayCommand EditMasterThemeCommand { get; }
public RelayCommand CreateThemeCommand { get; } public RelayCommand CreateThemeCommand { get; }
public RelayCommand ApplyThemeToScriptCommand { get; } public RelayCommand ApplyThemeToScriptCommand { get; }
@ -334,7 +342,7 @@ namespace Filtration.ViewModels
return; return;
} }
await LoadScriptAsync(filePath); await LoadScriptAsync(filePath); // TODO: fix crash
} }
private async Task LoadScriptAsync(string scriptFilename) private async Task LoadScriptAsync(string scriptFilename)
@ -346,20 +354,19 @@ namespace Filtration.ViewModels
{ {
loadedViewModel = await _itemFilterScriptRepository.LoadScriptFromFileAsync(scriptFilename); loadedViewModel = await _itemFilterScriptRepository.LoadScriptFromFileAsync(scriptFilename);
} }
catch (IOException e) catch (Exception e)
{
Messenger.Default.Send(new NotificationMessage("HideLoadingBanner"));
if (Logger.IsErrorEnabled)
{ {
Logger.Error(e); Logger.Error(e);
}
_messageBoxService.Show("Script Load Error", "Error loading filter script - " + e.Message, _messageBoxService.Show("Script Load Error", "Error loading filter script - " + e.Message,
MessageBoxButton.OK, MessageBoxButton.OK,
MessageBoxImage.Error); MessageBoxImage.Error);
return; return;
} }
finally
{
Messenger.Default.Send(new NotificationMessage("HideLoadingBanner")); Messenger.Default.Send(new NotificationMessage("HideLoadingBanner"));
}
_avalonDockWorkspaceViewModel.AddDocument(loadedViewModel); _avalonDockWorkspaceViewModel.AddDocument(loadedViewModel);
} }
@ -382,12 +389,9 @@ namespace Filtration.ViewModels
{ {
loadedViewModel = await _themeProvider.LoadThemeFromFile(themeFilename); loadedViewModel = await _themeProvider.LoadThemeFromFile(themeFilename);
} }
catch (IOException e) catch (Exception e)
{
if (Logger.IsErrorEnabled)
{ {
Logger.Error(e); Logger.Error(e);
}
_messageBoxService.Show("Theme Load Error", "Error loading filter theme - " + e.Message, _messageBoxService.Show("Theme Load Error", "Error loading filter theme - " + e.Message,
MessageBoxButton.OK, MessageBoxButton.OK,
MessageBoxImage.Error); MessageBoxImage.Error);
@ -525,6 +529,16 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.PasteBlockStyleCommand.Execute(null); _avalonDockWorkspaceViewModel.ActiveScriptViewModel.PasteBlockStyleCommand.Execute(null);
} }
private void OnUndoCommand()
{
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.CommandManager.Undo();
}
private void OnRedoCommand()
{
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.CommandManager.Redo();
}
private void OnNewScriptCommand() private void OnNewScriptCommand()
{ {
var newViewModel = _itemFilterScriptRepository.NewScript(); var newViewModel = _itemFilterScriptRepository.NewScript();

View File

@ -1,7 +1,6 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Windows.Media; using System.Windows.Media;
using Filtration.Common.ViewModels;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemTypes; using Filtration.ObjectModel.BlockItemTypes;
using Filtration.Views; using Filtration.Views;
@ -13,13 +12,13 @@ namespace Filtration.ViewModels
{ {
internal interface IReplaceColorsViewModel internal interface IReplaceColorsViewModel
{ {
void Initialise(ItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock); void Initialise(IItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock);
void Initialise(ItemFilterScript itemFilterScript); void Initialise(IItemFilterScript itemFilterScript);
} }
internal class ReplaceColorsViewModel : ViewModelBase, IReplaceColorsViewModel internal class ReplaceColorsViewModel : ViewModelBase, IReplaceColorsViewModel
{ {
private ItemFilterScript _itemFilterScript; private IItemFilterScript _itemFilterScript;
private ReplaceColorsParameterSet _replaceColorsParameterSet; private ReplaceColorsParameterSet _replaceColorsParameterSet;
public ReplaceColorsViewModel() public ReplaceColorsViewModel()
@ -29,7 +28,7 @@ namespace Filtration.ViewModels
public RelayCommand ReplaceColorsCommand { get; private set; } public RelayCommand ReplaceColorsCommand { get; private set; }
public void Initialise(ItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock) public void Initialise(IItemFilterScript itemFilterScript, IItemFilterBlock initialiseFromBlock)
{ {
_replaceColorsParameterSet = new ReplaceColorsParameterSet(); _replaceColorsParameterSet = new ReplaceColorsParameterSet();
@ -67,7 +66,7 @@ namespace Filtration.ViewModels
public Color NewTextColor public Color NewTextColor
{ {
get { return _replaceColorsParameterSet.NewTextColor; } get => _replaceColorsParameterSet.NewTextColor;
set set
{ {
_replaceColorsParameterSet.NewTextColor = value; _replaceColorsParameterSet.NewTextColor = value;
@ -82,7 +81,7 @@ namespace Filtration.ViewModels
public bool ReplaceTextColor public bool ReplaceTextColor
{ {
get { return _replaceColorsParameterSet.ReplaceTextColor; } get => _replaceColorsParameterSet.ReplaceTextColor;
set set
{ {
_replaceColorsParameterSet.ReplaceTextColor = value; _replaceColorsParameterSet.ReplaceTextColor = value;
@ -92,7 +91,7 @@ namespace Filtration.ViewModels
public Color NewBackgroundColor public Color NewBackgroundColor
{ {
get { return _replaceColorsParameterSet.NewBackgroundColor; } get => _replaceColorsParameterSet.NewBackgroundColor;
set set
{ {
_replaceColorsParameterSet.NewBackgroundColor = value; _replaceColorsParameterSet.NewBackgroundColor = value;
@ -107,7 +106,7 @@ namespace Filtration.ViewModels
public bool ReplaceBackgroundColor public bool ReplaceBackgroundColor
{ {
get { return _replaceColorsParameterSet.ReplaceBackgroundColor; } get => _replaceColorsParameterSet.ReplaceBackgroundColor;
set set
{ {
_replaceColorsParameterSet.ReplaceBackgroundColor = value; _replaceColorsParameterSet.ReplaceBackgroundColor = value;
@ -117,7 +116,7 @@ namespace Filtration.ViewModels
public Color NewBorderColor public Color NewBorderColor
{ {
get { return _replaceColorsParameterSet.NewBorderColor; } get => _replaceColorsParameterSet.NewBorderColor;
set set
{ {
_replaceColorsParameterSet.NewBorderColor = value; _replaceColorsParameterSet.NewBorderColor = value;
@ -132,7 +131,7 @@ namespace Filtration.ViewModels
public bool ReplaceBorderColor public bool ReplaceBorderColor
{ {
get { return _replaceColorsParameterSet.ReplaceBorderColor; } get => _replaceColorsParameterSet.ReplaceBorderColor;
set set
{ {
_replaceColorsParameterSet.ReplaceBorderColor = value; _replaceColorsParameterSet.ReplaceBorderColor = value;
@ -142,7 +141,7 @@ namespace Filtration.ViewModels
public ReplaceColorsParameterSet ReplaceColorsParameterSet => _replaceColorsParameterSet; public ReplaceColorsParameterSet ReplaceColorsParameterSet => _replaceColorsParameterSet;
public void Initialise(ItemFilterScript itemFilterScript) public void Initialise(IItemFilterScript itemFilterScript)
{ {
_replaceColorsParameterSet = new ReplaceColorsParameterSet(); _replaceColorsParameterSet = new ReplaceColorsParameterSet();
_itemFilterScript = itemFilterScript; _itemFilterScript = itemFilterScript;

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Filtration.Utilities;
using GalaSoft.MvvmLight.Command; using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging; using GalaSoft.MvvmLight.Messaging;
@ -15,13 +15,11 @@ namespace Filtration.ViewModels.ToolPanes
internal class BlockGroupBrowserViewModel : ToolViewModel, IBlockGroupBrowserViewModel internal class BlockGroupBrowserViewModel : ToolViewModel, IBlockGroupBrowserViewModel
{ {
private readonly IBlockGroupMapper _blockGroupMapper;
private ObservableCollection<ItemFilterBlockGroupViewModel> _blockGroupViewModelViewModels; private ObservableCollection<ItemFilterBlockGroupViewModel> _blockGroupViewModelViewModels;
private ItemFilterBlockGroupViewModel _selectedBlockGroupViewModel; private ItemFilterBlockGroupViewModel _selectedBlockGroupViewModel;
public BlockGroupBrowserViewModel(IBlockGroupMapper blockGroupMapper) : base("Block Group Browser") public BlockGroupBrowserViewModel() : base("Block Group Browser")
{ {
_blockGroupMapper = blockGroupMapper;
FilterToSelectedBlockGroupCommand = new RelayCommand(OnFilterToSelectedBlockGroupCommand, () => SelectedBlockGroupViewModel != null); FilterToSelectedBlockGroupCommand = new RelayCommand(OnFilterToSelectedBlockGroupCommand, () => SelectedBlockGroupViewModel != null);
ContentId = ToolContentId; ContentId = ToolContentId;
@ -60,7 +58,7 @@ namespace Filtration.ViewModels.ToolPanes
public ItemFilterBlockGroupViewModel SelectedBlockGroupViewModel public ItemFilterBlockGroupViewModel SelectedBlockGroupViewModel
{ {
get { return _selectedBlockGroupViewModel; } get => _selectedBlockGroupViewModel;
set set
{ {
_selectedBlockGroupViewModel = value; _selectedBlockGroupViewModel = value;
@ -73,7 +71,7 @@ namespace Filtration.ViewModels.ToolPanes
public ObservableCollection<ItemFilterBlockGroupViewModel> BlockGroupViewModels public ObservableCollection<ItemFilterBlockGroupViewModel> BlockGroupViewModels
{ {
get { return _blockGroupViewModelViewModels; } get => _blockGroupViewModelViewModels;
private set private set
{ {
_blockGroupViewModelViewModels = value; _blockGroupViewModelViewModels = value;
@ -94,9 +92,11 @@ namespace Filtration.ViewModels.ToolPanes
private ObservableCollection<ItemFilterBlockGroupViewModel> RebuildBlockGroupViewModels(bool showAdvanced) private ObservableCollection<ItemFilterBlockGroupViewModel> RebuildBlockGroupViewModels(bool showAdvanced)
{ {
return // This assumes that there will only ever be a single root node.
_blockGroupMapper.MapBlockGroupsToViewModels( return new ObservableCollection<ItemFilterBlockGroupViewModel>
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.ItemFilterBlockGroups, showAdvanced); (
new ItemFilterBlockGroupViewModel(AvalonDockWorkspaceViewModel.ActiveScriptViewModel.Script.ItemFilterBlockGroups.First(), showAdvanced, null).ChildGroups
);
} }
private void OnFilterToSelectedBlockGroupCommand() private void OnFilterToSelectedBlockGroupCommand()

View File

@ -73,8 +73,8 @@ namespace Filtration.ViewModels.ToolPanes
} }
PreviewText = PreviewText =
_itemFilterBlockTranslator.TranslateItemFilterBlockToString( _itemFilterBlockTranslator.TranslateItemFilterBlockBaseToString(
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel.Block); AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel.BaseBlock);
} }
} }
} }

View File

@ -5,18 +5,18 @@ using GalaSoft.MvvmLight.Messaging;
namespace Filtration.ViewModels.ToolPanes namespace Filtration.ViewModels.ToolPanes
{ {
internal interface ISectionBrowserViewModel : IToolViewModel internal interface ICommentBlockBrowserViewModel : IToolViewModel
{ {
void ClearDown(); void ClearDown();
bool IsVisible { get; set; } bool IsVisible { get; set; }
} }
internal class SectionBrowserViewModel : ToolViewModel, ISectionBrowserViewModel internal class CommentBlockBrowserViewModel : ToolViewModel, ICommentBlockBrowserViewModel
{ {
private IEnumerable<IItemFilterBlockViewModel> _sectionBlockViewModels; private IEnumerable<IItemFilterCommentBlockViewModel> _itemFilterCommentBlockViewModels;
private IItemFilterBlockViewModel _selectedSectionBlockViewModel; private IItemFilterCommentBlockViewModel _selectedItemFilterCommentBlockViewModel;
public SectionBrowserViewModel() : base("Section Browser") public CommentBlockBrowserViewModel() : base("Section Browser")
{ {
ContentId = ToolContentId; ContentId = ToolContentId;
var icon = new BitmapImage(); var icon = new BitmapImage();
@ -40,25 +40,25 @@ namespace Filtration.ViewModels.ToolPanes
public const string ToolContentId = "SectionBrowserTool"; public const string ToolContentId = "SectionBrowserTool";
public IEnumerable<IItemFilterBlockViewModel> SectionBlockViewModels public IEnumerable<IItemFilterCommentBlockViewModel> ItemFilterCommentBlockViewModels
{ {
get { return _sectionBlockViewModels; } get => _itemFilterCommentBlockViewModels;
private set private set
{ {
_sectionBlockViewModels = value; _itemFilterCommentBlockViewModels = value;
RaisePropertyChanged(); RaisePropertyChanged();
} }
} }
public IItemFilterBlockViewModel SelectedSectionBlockViewModel public IItemFilterCommentBlockViewModel SelectedItemFilterCommentBlockViewModel
{ {
get { return _selectedSectionBlockViewModel; } get => _selectedItemFilterCommentBlockViewModel;
set set
{ {
_selectedSectionBlockViewModel = value; _selectedItemFilterCommentBlockViewModel = value;
if (AvalonDockWorkspaceViewModel.ActiveDocument.IsScript) if (AvalonDockWorkspaceViewModel.ActiveDocument.IsScript)
{ {
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SectionBrowserSelectedBlockViewModel = value; AvalonDockWorkspaceViewModel.ActiveScriptViewModel.CommentBlockBrowserBrowserSelectedBlockViewModel = value;
} }
RaisePropertyChanged(); RaisePropertyChanged();
} }
@ -68,7 +68,7 @@ namespace Filtration.ViewModels.ToolPanes
{ {
if (AvalonDockWorkspaceViewModel.ActiveScriptViewModel != null && AvalonDockWorkspaceViewModel.ActiveDocument.IsScript) if (AvalonDockWorkspaceViewModel.ActiveScriptViewModel != null && AvalonDockWorkspaceViewModel.ActiveDocument.IsScript)
{ {
SectionBlockViewModels = AvalonDockWorkspaceViewModel.ActiveScriptViewModel.ItemFilterSectionViewModels; ItemFilterCommentBlockViewModels = AvalonDockWorkspaceViewModel.ActiveScriptViewModel.ItemFilterCommentBlockViewModels;
} }
else else
{ {
@ -78,8 +78,8 @@ namespace Filtration.ViewModels.ToolPanes
public void ClearDown() public void ClearDown()
{ {
SectionBlockViewModels = null; ItemFilterCommentBlockViewModels = null;
SelectedSectionBlockViewModel = null; SelectedItemFilterCommentBlockViewModel = null;
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More