From 693ea29600926170671bd4c6aab41d48ba661639 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 21 Sep 2020 20:22:11 +0200 Subject: [PATCH] Conditions - Finished list support --- .../Abstract/DataModelConditionPart.cs | 1 - .../Conditions/DataModelConditionList.cs | 41 +++- .../DataModelConditionListPredicate.cs | 212 ++++++------------ .../Utilities/DeserializationLogger.cs | 1 - .../DataModelConditionListPredicateEntity.cs | 5 +- .../Input/DataModelDynamicViewModel.cs | 13 +- .../Screens/Modules/ModuleRootViewModel.cs | 4 +- .../DataModelConditionGroupView.xaml | 40 +++- .../DataModelConditionGroupViewModel.cs | 11 +- ...ataModelConditionListPredicateViewModel.cs | 37 +-- .../DataModelConditionListView.xaml | 24 +- 11 files changed, 192 insertions(+), 197 deletions(-) diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs index 50ddcd6dc..dd6d8425b 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPart.cs @@ -84,6 +84,5 @@ namespace Artemis.Core } #endregion - } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs index e650a9b85..7c634c0aa 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionList.cs @@ -43,6 +43,16 @@ namespace Artemis.Core /// public ListOperator ListOperator { get; set; } + /// + /// Gets the type of the content of the list this predicate is evaluated on + /// + public Type ListType { get; set; } + + /// + /// Gets whether the list contains primitives + /// + public bool IsPrimitiveList { get; set; } + /// /// Gets the currently used instance of the list data model /// @@ -87,19 +97,21 @@ namespace Artemis.Core if (dataModel != null) { - if (!dataModel.ContainsPath(path)) - throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'"); - if (dataModel.GetListTypeAtPath(path) == null) - throw new ArtemisCoreException($"The path '{path}' does not contain a list"); + var listType = dataModel.GetListTypeAtPath(path); + if (listType == null) + throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a list at path '{path}'"); + + ListType = listType; + IsPrimitiveList = listType.IsPrimitive || listType.IsEnum || listType == typeof(string); + + ListDataModel = dataModel; + ListPropertyPath = path; } // Remove the old root group that was tied to the old data model while (Children.Any()) RemoveChild(Children[0]); - ListDataModel = dataModel; - ListPropertyPath = path; - if (dataModel == null) return; @@ -178,16 +190,25 @@ namespace Artemis.Core if (Entity.ListDataModelGuid == null) return; - // Get the data model and ensure the path is valid + // Get the data model ... var dataModel = DataModelStore.Get(Entity.ListDataModelGuid.Value)?.DataModel; - if (dataModel == null || !dataModel.ContainsPath(Entity.ListPropertyPath)) + if (dataModel == null) + return; + // ... and ensure the path is valid + var listType = dataModel.GetListTypeAtPath(Entity.ListPropertyPath); + if (listType == null) return; - // Populate properties and create the accessor expression + ListType = listType; + IsPrimitiveList = listType.IsPrimitive || listType.IsEnum || listType == typeof(string); ListDataModel = dataModel; ListPropertyPath = Entity.ListPropertyPath; + CreateExpression(); + if (ListDataModel == null) + return; + // There should only be one child and it should be a group if (Entity.Children.SingleOrDefault() is DataModelConditionGroupEntity rootGroup) AddChild(new DataModelConditionGroup(this, rootGroup)); diff --git a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs index 6c95c6538..db9b7778a 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DataModelConditionListPredicate.cs @@ -51,24 +51,9 @@ namespace Artemis.Core public ConditionOperator Operator { get; private set; } /// - /// Gets the type of the content of the list this predicate is evaluated on + /// Gets the data model condition list this predicate belongs to /// - public Type ListType { get; private set; } - - /// - /// Gets whether the list contains primitives - /// - public bool IsPrimitiveList { get; private set; } - - /// - /// Gets the currently used instance of the list data model - /// - public DataModel ListDataModel { get; private set; } - - /// - /// Gets the path of the list property in the - /// - public string ListPropertyPath { get; private set; } + public DataModelConditionList DataModelConditionList { get; private set; } /// /// Gets the path of the left property in the @@ -108,10 +93,10 @@ namespace Artemis.Core /// The path pointing to the left side value inside the list public void UpdateLeftSide(string path) { - if (IsPrimitiveList) + if (DataModelConditionList.IsPrimitiveList) throw new ArtemisCoreException("Cannot apply a left side to a predicate inside a primitive list"); if (!ListContainsInnerPath(path)) - throw new ArtemisCoreException($"List type {ListType.Name} does not contain path {path}"); + throw new ArtemisCoreException($"List type {DataModelConditionList.ListType.Name} does not contain path {path}"); LeftPropertyPath = path; @@ -128,9 +113,9 @@ namespace Artemis.Core public void UpdateRightSideDynamic(string path) { if (!ListContainsInnerPath(path)) - throw new ArtemisCoreException($"List type {ListType.Name} does not contain path {path}"); + throw new ArtemisCoreException($"List type {DataModelConditionList.ListType.Name} does not contain path {path}"); - PredicateType = ListRightSideType.Dynamic; + PredicateType = ListRightSideType.DynamicList; RightPropertyPath = path; CreateExpression(); @@ -155,7 +140,7 @@ namespace Artemis.Core throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'"); } - PredicateType = ListRightSideType.DynamicExternal; + PredicateType = ListRightSideType.Dynamic; RightDataModel = dataModel; RightPropertyPath = path; @@ -214,11 +199,11 @@ namespace Artemis.Core /// The path to evaluate public bool ListContainsInnerPath(string path) { - if (ListType == null) + if (DataModelConditionList.ListType == null) return false; var parts = path.Split('.'); - var current = ListType; + var current = DataModelConditionList.ListType; foreach (var part in parts) { var property = current.GetProperty(part); @@ -236,8 +221,6 @@ namespace Artemis.Core /// protected override void Dispose(bool disposing) { - DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded; - DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved; ConditionOperatorStore.ConditionOperatorAdded -= ConditionOperatorStoreOnConditionOperatorAdded; ConditionOperatorStore.ConditionOperatorRemoved -= ConditionOperatorStoreOnConditionOperatorRemoved; @@ -246,70 +229,13 @@ namespace Artemis.Core #endregion - internal void ApplyParentList() - { - var current = Parent; - while (current != null) - { - if (current is DataModelConditionList parentList) - { - UpdateList(parentList.ListDataModel, parentList.ListPropertyPath); - return; - } - - current = current.Parent; - } - } - - internal void UpdateList(DataModel dataModel, string path) - { - if (dataModel != null && path == null) - throw new ArtemisCoreException("If a data model is provided, a path is also required"); - if (dataModel == null && path != null) - throw new ArtemisCoreException("If path is provided, a data model is also required"); - - if (dataModel != null) - { - var listType = dataModel.GetListTypeAtPath(path); - if (listType == null) - throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a list at path '{path}'"); - - ListType = listType; - IsPrimitiveList = listType.IsPrimitive || listType.IsEnum || listType == typeof(string); - } - else - { - ListType = null; - IsPrimitiveList = true; - } - - - ListDataModel = dataModel; - ListPropertyPath = path; - - if (LeftPropertyPath != null && !ListContainsInnerPath(LeftPropertyPath)) - LeftPropertyPath = null; - if (RightPropertyPath != null && !ListContainsInnerPath(RightPropertyPath)) - RightPropertyPath = null; - - CreateExpression(); - } - - - /// - /// Evaluates the condition part on the given target - /// - /// - /// An instance of the list described in and - /// - /// internal override bool EvaluateObject(object target) { if (PredicateType == ListRightSideType.Static && CompiledListPredicate != null) return CompiledListPredicate(target); - if (PredicateType == ListRightSideType.Dynamic && CompiledListPredicate != null) + if (PredicateType == ListRightSideType.DynamicList && CompiledListPredicate != null) return CompiledListPredicate(target); - if (PredicateType == ListRightSideType.DynamicExternal && CompiledExternalListPredicate != null) + if (PredicateType == ListRightSideType.Dynamic && CompiledExternalListPredicate != null) return CompiledExternalListPredicate(target, RightDataModel); return false; @@ -321,7 +247,7 @@ namespace Artemis.Core return null; var parts = path.Split('.'); - var current = ListType; + var current = DataModelConditionList.ListType; Type result = null; foreach (var part in parts) @@ -337,12 +263,6 @@ namespace Artemis.Core internal override void Save() { Entity.PredicateType = (int) PredicateType; - if (ListDataModel != null) - { - Entity.ListDataModelGuid = ListDataModel.PluginInfo.Guid; - Entity.ListPropertyPath = ListPropertyPath; - } - Entity.LeftPropertyPath = LeftPropertyPath; Entity.RightDataModelGuid = RightDataModel?.PluginInfo?.Guid; @@ -361,10 +281,33 @@ namespace Artemis.Core return Entity; } + private void ApplyParentList() + { + var current = Parent; + + while (current != null) + { + if (current is DataModelConditionList parentList) + { + DataModelConditionList = parentList; + + if (LeftPropertyPath != null && !ListContainsInnerPath(LeftPropertyPath)) + LeftPropertyPath = null; + if (RightPropertyPath != null && !ListContainsInnerPath(RightPropertyPath)) + RightPropertyPath = null; + + return; + } + + current = current.Parent; + } + + if (DataModelConditionList == null) + throw new ArtemisCoreException("This data model condition list predicate does not belong to a data model condition list"); + } + private void Initialize() { - DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded; - DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved; ConditionOperatorStore.ConditionOperatorAdded += ConditionOperatorStoreOnConditionOperatorAdded; ConditionOperatorStore.ConditionOperatorRemoved += ConditionOperatorStoreOnConditionOperatorRemoved; @@ -381,18 +324,18 @@ namespace Artemis.Core } // Right side dynamic - if (PredicateType == ListRightSideType.Dynamic && Entity.RightPropertyPath != null) - { - if (ListContainsInnerPath(Entity.RightPropertyPath)) - UpdateRightSideDynamic(Entity.RightPropertyPath); - } - // Right side dynamic using an external data model - else if (PredicateType == ListRightSideType.Dynamic && Entity.RightDataModelGuid != null && Entity.RightPropertyPath != null) + if (PredicateType == ListRightSideType.Dynamic && Entity.RightDataModelGuid != null && Entity.RightPropertyPath != null) { var dataModel = DataModelStore.Get(Entity.RightDataModelGuid.Value)?.DataModel; if (dataModel != null && dataModel.ContainsPath(Entity.RightPropertyPath)) UpdateRightSideDynamic(dataModel, Entity.RightPropertyPath); } + // Right side dynamic inside the list + else if (PredicateType == ListRightSideType.DynamicList && Entity.RightPropertyPath != null) + { + if (ListContainsInnerPath(Entity.RightPropertyPath)) + UpdateRightSideDynamic(Entity.RightPropertyPath); + } // Right side static else if (PredicateType == ListRightSideType.Static && Entity.RightStaticValue != null) { @@ -438,10 +381,10 @@ namespace Artemis.Core return; // If the operator does not support a right side, create a static expression because the right side will simply be null - if (PredicateType == ListRightSideType.Dynamic && Operator.SupportsRightSide) + if (PredicateType == ListRightSideType.DynamicList && Operator.SupportsRightSide) + CreateDynamicListExpression(); + else if (PredicateType == ListRightSideType.Dynamic && Operator.SupportsRightSide) CreateDynamicExpression(); - else if (PredicateType == ListRightSideType.DynamicExternal && Operator.SupportsRightSide) - CreateDynamicExternalExpression(); else CreateStaticExpression(); } @@ -460,15 +403,6 @@ namespace Artemis.Core { var leftSideType = GetTypeAtInnerPath(LeftPropertyPath); if (PredicateType == ListRightSideType.Dynamic) - { - if (RightPropertyPath == null) - return; - - var rightSideType = GetTypeAtInnerPath(RightPropertyPath); - if (!leftSideType.IsCastableFrom(rightSideType)) - UpdateRightSideDynamic(null); - } - else if (PredicateType == ListRightSideType.DynamicExternal) { if (RightDataModel == null) return; @@ -477,6 +411,15 @@ namespace Artemis.Core if (!leftSideType.IsCastableFrom(rightSideType)) UpdateRightSideDynamic(null, null); } + else if (PredicateType == ListRightSideType.DynamicList) + { + if (RightPropertyPath == null) + return; + + var rightSideType = GetTypeAtInnerPath(RightPropertyPath); + if (!leftSideType.IsCastableFrom(rightSideType)) + UpdateRightSideDynamic(null); + } else { if (RightStaticValue != null && leftSideType.IsCastableFrom(RightStaticValue.GetType())) @@ -509,7 +452,7 @@ namespace Artemis.Core RightStaticValue = null; } - private void CreateDynamicExpression() + private void CreateDynamicListExpression() { if (LeftPropertyPath == null || RightPropertyPath == null || Operator == null) return; @@ -529,7 +472,7 @@ namespace Artemis.Core CompiledListPredicate = lambda.Compile(); } - private void CreateDynamicExternalExpression() + private void CreateDynamicExpression() { if (LeftPropertyPath == null || RightPropertyPath == null || RightDataModel == null || Operator == null) return; @@ -551,12 +494,14 @@ namespace Artemis.Core private void CreateStaticExpression() { - if (!IsPrimitiveList && LeftPropertyPath == null || Operator == null) + if (!DataModelConditionList.IsPrimitiveList && LeftPropertyPath == null || Operator == null) return; // List accessors share the same parameter because a list always contains one item per entry var leftSideParameter = Expression.Parameter(typeof(object), "listItem"); - var leftSideAccessor = IsPrimitiveList ? Expression.Convert(leftSideParameter, ListType) : CreateListAccessor(LeftPropertyPath, leftSideParameter); + var leftSideAccessor = DataModelConditionList.IsPrimitiveList + ? Expression.Convert(leftSideParameter, DataModelConditionList.ListType) + : CreateListAccessor(LeftPropertyPath, leftSideParameter); // If the left side is a value type but the input is empty, this isn't a valid expression if (leftSideAccessor.Type.IsValueType && RightStaticValue == null) @@ -575,7 +520,7 @@ namespace Artemis.Core private Expression CreateListAccessor(string path, ParameterExpression listParameter) { return path.Split('.').Aggregate( - Expression.Convert(listParameter, ListType), // Cast to the appropriate type + Expression.Convert(listParameter, DataModelConditionList.ListType), // Cast to the appropriate type Expression.Property ); } @@ -595,31 +540,6 @@ namespace Artemis.Core #region Event handlers - private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e) - { - var dataModel = e.Registration.DataModel; - if (dataModel.PluginInfo.Guid == Entity.ListDataModelGuid && dataModel.ContainsPath(Entity.ListPropertyPath)) - UpdateList(dataModel, Entity.LeftPropertyPath); - if (dataModel.PluginInfo.Guid == Entity.RightDataModelGuid && dataModel.ContainsPath(Entity.RightPropertyPath)) - UpdateRightSideDynamic(dataModel, Entity.RightPropertyPath); - } - - private void DataModelStoreOnDataModelRemoved(object sender, DataModelStoreEvent e) - { - if (ListDataModel == e.Registration.DataModel) - { - CompiledListPredicate = null; - CompiledExternalListPredicate = null; - ListDataModel = null; - } - - if (RightDataModel == e.Registration.DataModel) - { - CompiledExternalListPredicate = null; - RightDataModel = null; - } - } - private void ConditionOperatorStoreOnConditionOperatorAdded(object sender, ConditionOperatorStoreEvent e) { var conditionOperator = e.Registration.ConditionOperator; @@ -649,13 +569,13 @@ namespace Artemis.Core Static, /// - /// A dynamic right side value based on a path in the list + /// A dynamic right side value based on a path in a data model /// Dynamic, /// - /// A dynamic right side value based on a path in a data model + /// A dynamic right side value based on a path in the list /// - DynamicExternal + DynamicList } } \ No newline at end of file diff --git a/src/Artemis.Core/Utilities/DeserializationLogger.cs b/src/Artemis.Core/Utilities/DeserializationLogger.cs index 01e9bc6b2..e0c762c2d 100644 --- a/src/Artemis.Core/Utilities/DeserializationLogger.cs +++ b/src/Artemis.Core/Utilities/DeserializationLogger.cs @@ -29,7 +29,6 @@ namespace Artemis.Core _logger.Warning( exception, "Failed to deserialize display condition list predicate {list} => {left} {operator} {right}", - dataModelConditionPredicate.Entity.ListPropertyPath, dataModelConditionPredicate.Entity.LeftPropertyPath, dataModelConditionPredicate.Entity.OperatorType, dataModelConditionPredicate.Entity.RightPropertyPath diff --git a/src/Artemis.Storage/Entities/Profile/Conditions/DataModelConditionListPredicateEntity.cs b/src/Artemis.Storage/Entities/Profile/Conditions/DataModelConditionListPredicateEntity.cs index 32429c83c..025541f30 100644 --- a/src/Artemis.Storage/Entities/Profile/Conditions/DataModelConditionListPredicateEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Conditions/DataModelConditionListPredicateEntity.cs @@ -6,10 +6,7 @@ namespace Artemis.Storage.Entities.Profile.Conditions public class DataModelConditionListPredicateEntity : DataModelConditionPartEntity { public int PredicateType { get; set; } - - public Guid? ListDataModelGuid { get; set; } - public string ListPropertyPath { get; set; } - + public string LeftPropertyPath { get; set; } public Guid? RightDataModelGuid { get; set; } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs index 4416b773f..71474d996 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs @@ -24,6 +24,7 @@ namespace Artemis.UI.Shared.Input private bool _isEnabled = true; private string _placeholder = "Select a property"; private DataModelVisualizationViewModel _selectedPropertyViewModel; + private Type[] _filterTypes; internal DataModelDynamicViewModel(Module module, ISettingsService settingsService, IDataModelUIService dataModelUIService) { @@ -43,7 +44,6 @@ namespace Artemis.UI.Shared.Input set => SetAndNotify(ref _buttonBrush, value); } - public string Placeholder { get => _placeholder; @@ -56,7 +56,16 @@ namespace Artemis.UI.Shared.Input set => SetAndNotify(ref _isEnabled, value); } - public Type[] FilterTypes { get; set; } + public Type[] FilterTypes + { + get => _filterTypes; + set + { + if (!SetAndNotify(ref _filterTypes, value)) return; + DataModelViewModel?.ApplyTypeFilter(true, FilterTypes); + } + } + public DelegateCommand SelectPropertyCommand { get; } public PluginSetting ShowDataModelValues { get; } diff --git a/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs b/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs index 6437a5cd5..402c3412c 100644 --- a/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs +++ b/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs @@ -24,10 +24,10 @@ namespace Artemis.UI.Screens.Modules public Module Module { get; } - protected override void OnActivate() + protected override void OnInitialActivate() { AddTabs(); - base.OnActivate(); + base.OnInitialActivate(); } private void AddTabs() diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml index 8b30b8ff0..d248102ac 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml @@ -45,7 +45,7 @@ @@ -90,7 +102,7 @@ @@ -98,18 +110,28 @@ - + + + + + + + Visibility="{Binding Data.IsListGroup, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Source={StaticResource DataContextProxy}}"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs index c207f0a93..960b49d56 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs @@ -25,6 +25,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions : base(dataModelConditionGroup) { IsListGroup = isListGroup; + if (IsListGroup) + DynamicListConditionSupported = !((DataModelConditionList) dataModelConditionGroup.Parent).IsPrimitiveList; + else + DynamicListConditionSupported = false; + _profileEditorService = profileEditorService; _dataModelConditionsVmFactory = dataModelConditionsVmFactory; @@ -38,7 +43,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions } public bool IsListGroup { get; } - + public bool DynamicListConditionSupported { get; } public DataModelConditionGroup DataModelConditionGroup => (DataModelConditionGroup) Model; public bool IsRootGroup @@ -81,8 +86,8 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions else DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ListRightSideType.Dynamic)); } - else if (type == "DynamicExternal" && IsListGroup) - DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ListRightSideType.DynamicExternal)); + else if (type == "DynamicList" && IsListGroup) + DataModelConditionGroup.AddChild(new DataModelConditionListPredicate(DataModelConditionGroup, ListRightSideType.DynamicList)); else if (type == "List" && !IsListGroup) DataModelConditionGroup.AddChild(new DataModelConditionList(DataModelConditionGroup)); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs index 25a20d0e3..604c8ee86 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListPredicateViewModel.cs @@ -126,7 +126,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public override void Update() { - var listDataModelGuid = DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid; + var listDataModelGuid = DataModelConditionListPredicate.DataModelConditionList.ListDataModel.PluginInfo.Guid; if (!_isPrimitiveList) { LeftSideSelectionViewModel.FilterTypes = _supportedInputTypes.ToArray(); @@ -137,7 +137,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions } var leftSideType = _isPrimitiveList - ? DataModelConditionListPredicate.ListType + ? DataModelConditionListPredicate.DataModelConditionList.ListType : LeftSideSelectionViewModel.SelectedPropertyViewModel?.PropertyInfo?.PropertyType; // Get the supported operators @@ -148,7 +148,8 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions SelectedOperator = DataModelConditionListPredicate.Operator; // Ensure the right side has the proper VM - if (DataModelConditionListPredicate.PredicateType == ListRightSideType.Dynamic || DataModelConditionListPredicate.PredicateType == ListRightSideType.DynamicExternal) + if (DataModelConditionListPredicate.PredicateType == ListRightSideType.Dynamic || + DataModelConditionListPredicate.PredicateType == ListRightSideType.DynamicList) { DisposeRightSideStatic(); if (RightSideSelectionViewModel == null) @@ -156,17 +157,25 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions RightSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); RightSideSelectionViewModel.ButtonBrush = (Brush) Application.Current.FindResource("PrimaryHueMidBrush"); RightSideSelectionViewModel.PropertySelected += RightSideOnPropertySelected; + + if (DataModelConditionListPredicate.PredicateType == ListRightSideType.DynamicList) + RightSideSelectionViewModel.ChangeDataModel((DataModelPropertiesViewModel) GetListDataModel()); } RightSideSelectionViewModel.FilterTypes = new[] {leftSideType}; if (DataModelConditionListPredicate.PredicateType == ListRightSideType.Dynamic) + { + RightSideSelectionViewModel.PopulateSelectedPropertyViewModel( + DataModelConditionListPredicate.RightDataModel, + DataModelConditionListPredicate.RightPropertyPath + ); + } + else { RightSideSelectionViewModel.SelectedPropertyViewModel = RightSideSelectionViewModel.DataModelViewModel.GetChildByPath( listDataModelGuid, DataModelConditionListPredicate.RightPropertyPath ); } - else - RightSideSelectionViewModel.PopulateSelectedPropertyViewModel(DataModelConditionListPredicate.RightDataModel, DataModelConditionListPredicate.RightPropertyPath); } else { @@ -195,16 +204,19 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public void ApplyRightSideDynamic() { - if (DataModelConditionListPredicate.ListContainsInnerPath(RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath)) - DataModelConditionListPredicate.UpdateRightSideDynamic(RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath); - else + if (DataModelConditionListPredicate.PredicateType == ListRightSideType.Dynamic) + { DataModelConditionListPredicate.UpdateRightSideDynamic( RightSideSelectionViewModel.SelectedPropertyViewModel.DataModel, RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath ); + } + else if (DataModelConditionListPredicate.PredicateType == ListRightSideType.DynamicList) + { + DataModelConditionListPredicate.UpdateRightSideDynamic(RightSideSelectionViewModel.SelectedPropertyViewModel.PropertyPath); + } _profileEditorService.UpdateSelectedProfileElement(); - Update(); } @@ -226,13 +238,10 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions private DataModelVisualizationViewModel GetListDataModel() { - if (DataModelConditionListPredicate.ListDataModel == null || DataModelConditionListPredicate.ListPropertyPath == null) - throw new ArtemisUIException("Cannot create a list predicate without first selecting a target list"); - var dataModel = _dataModelUIService.GetPluginDataModelVisualization(_profileEditorService.GetCurrentModule(), true); var listDataModel = (DataModelListViewModel) dataModel.GetChildByPath( - DataModelConditionListPredicate.ListDataModel.PluginInfo.Guid, - DataModelConditionListPredicate.ListPropertyPath + DataModelConditionListPredicate.DataModelConditionList.ListDataModel.PluginInfo.Guid, + DataModelConditionListPredicate.DataModelConditionList.ListPropertyPath ); return listDataModel.GetListTypeViewModel(_dataModelUIService); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml index 32c09a1c4..1b6bd4a81 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListView.xaml @@ -54,13 +54,27 @@ BorderBrush="#7B7B7B" Content="{Binding SelectedListOperator}" Click="PropertyButton_OnClick" - HorizontalAlignment="Left"> + HorizontalAlignment="Left" + ToolTip="Change the list operator, determining how the list contents should match"> - - - - + + + +