From 072afa67ebfaef4b41a9aa216a43c3a058bfd25e Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Tue, 16 Jul 2024 23:34:43 +0200 Subject: [PATCH] added mechanism for applying changes --- Core/Abstracts/AbstractFilter.cs | 243 ++++++++++++++---- Core/Core.csproj | 3 +- Core/Data/DataManager.cs | 16 +- Core/Data/DataTypeGeneric.cs | 2 +- Core/Data/GenericDataStructure.cs | 22 +- Core/Filtering/Filter.cs.template | 25 +- Core/Filtering/FilterManager.cs | 69 +++-- ...nSelectionFilter.cs => TransposeFilter.cs} | 20 +- Core/Filtering/ValueSelectionFilter.cs | 60 ----- Core/GUI/MenubarWindow.cs | 4 +- Core/GUI/Windows/WindowLeaf.cs | 2 +- .../Abstracts/AbstractSciChartParallel.cs | 2 +- .../Abstracts/AbstractSciChartSeries.cs | 2 +- .../Data/DataTypeSciChartParallel.cs | 2 +- .../Data/DataTypeSciChartSeries.cs | 2 +- .../Visualizations/WPF_FilterEditor.cs | 13 +- .../Visualizations/WPF_LogConsole.cs | 2 +- 17 files changed, 318 insertions(+), 171 deletions(-) rename Core/Filtering/{ColumnSelectionFilter.cs => TransposeFilter.cs} (70%) delete mode 100644 Core/Filtering/ValueSelectionFilter.cs diff --git a/Core/Abstracts/AbstractFilter.cs b/Core/Abstracts/AbstractFilter.cs index 96d41d5..c115d1f 100644 --- a/Core/Abstracts/AbstractFilter.cs +++ b/Core/Abstracts/AbstractFilter.cs @@ -14,7 +14,6 @@ using System.Runtime.Remoting.Contexts; using System.Windows.Input; using System.Windows.Data; -using System.Drawing.Printing; @@ -22,6 +21,11 @@ * Abstract data filter * */ + +/// considered, list modification, original data of content +using ChangedContentApplyData_Type = System.Tuple; + + namespace Core { namespace Abstracts @@ -76,14 +80,14 @@ public enum ListModification public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_data_callback, DataManager.UpdateSelectedDataCallback_Delegate update_selected_data_callback, - FilterManager.ModifyUIFilterList_Delegate modify_ui_filter_list_callback, +FilterManager.FilterChanged_Delegate filter_changed_callback, FilterManager.DeleteFilterCallback_Delegate delete_self_callback) { if (_initialized) { Terminate(); } - if ((get_selected_data_callback == null) || (update_selected_data_callback == null) || (modify_ui_filter_list_callback == null) || (delete_self_callback == null)) + if ((get_selected_data_callback == null) || (update_selected_data_callback == null) || (filter_changed_callback == null) || (delete_self_callback == null)) { Log.Default.Msg(Log.Level.Error, "Missing callback(s)"); } @@ -92,9 +96,12 @@ public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_ _update_selected_data_callback = update_selected_data_callback; _get_selected_data_callback = get_selected_data_callback; - _modify_ui_filter_list_callback = modify_ui_filter_list_callback; + _filter_changed_callback = filter_changed_callback; _delete_self_callback = delete_self_callback; + _checked_content_changes = new Dictionary(); + + _timer.Stop(); _initialized = true; if (_initialized) @@ -108,7 +115,14 @@ public override bool Terminate() { if (_initialized) { - _modify_ui_filter_list_callback(_content, ListModification.DELETE); + // Notify subsequent filters that this filter has changed (= will be deleted) + _filter_changed_callback(_UID, _get_checked_content_list()); + + // Revert all data changes + foreach (int key in _checked_content_changes.Keys.ToList()) + { + _update_selected_data_callback(key, _checked_content_changes[key].Item3); + } _content = null; _filter_caption = null; @@ -117,7 +131,11 @@ public override bool Terminate() _update_selected_data_callback = null; _get_selected_data_callback = null; - _modify_ui_filter_list_callback = null; + _filter_changed_callback = null; + _delete_self_callback = null; + + _checked_content_changes.Clear(); + _checked_content_changes = null; _created = false; _initialized = false; @@ -154,8 +172,9 @@ public virtual bool CreateUI() _apply_button.Content = " Apply "; _apply_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); - _apply_button.Click += _apply_button_click; - set_filter_dirty(); + _apply_button.Click += _event_apply_button; + _apply_button_default_background = _apply_button.Background; + _apply_button.IsEnabled = false; var button_column = new ColumnDefinition(); button_column.Width = new GridLength(0.0, GridUnitType.Auto); @@ -179,16 +198,6 @@ public virtual bool CreateUI() Grid.SetColumn(rename_button, 1); button_grid.Children.Add(rename_button); - var disable_button = new Button(); - disable_button.Content = " Disable "; - disable_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); - disable_button.IsEnabled = false; - button_column = new ColumnDefinition(); - button_column.Width = new GridLength(0.0, GridUnitType.Auto); - button_grid.ColumnDefinitions.Add(button_column); - Grid.SetColumn(disable_button, 2); - button_grid.Children.Add(disable_button); - var delete_button = new Button(); delete_button.Content = " Delete "; delete_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); @@ -206,7 +215,7 @@ public virtual bool CreateUI() button_column = new ColumnDefinition(); button_column.Width = new GridLength(0.0, GridUnitType.Auto); button_grid.ColumnDefinitions.Add(button_column); - Grid.SetColumn(delete_button, 3); + Grid.SetColumn(delete_button, 2); button_grid.Children.Add(delete_button); var apply_grid = new Grid(); @@ -223,10 +232,10 @@ public virtual bool CreateUI() var hrule = new Border(); hrule.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); hrule.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); - hrule.BorderThickness = new Thickness(2.0, 2.0, 2.0, 2.0); - hrule.Margin = new Thickness(_margin, _margin, _margin, _margin); + hrule.BorderThickness = new Thickness(_border_thickness); + hrule.Margin = new Thickness(_margin); hrule.CornerRadius = new CornerRadius(0); - hrule.Height = 2.0; + hrule.Height = _border_thickness; hrule.VerticalAlignment = VerticalAlignment.Bottom; hrule.HorizontalAlignment = HorizontalAlignment.Stretch; var apply_rule_column = new ColumnDefinition(); @@ -267,9 +276,9 @@ public virtual bool CreateUI() var child_border = new Border(); child_border.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); child_border.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); - child_border.BorderThickness = new Thickness(2.0, 2.0, 2.0, 2.0); + child_border.BorderThickness = new Thickness(_border_thickness); child_border.CornerRadius = new CornerRadius(0); - child_border.Margin = new Thickness(_margin, _margin, _margin, _margin); + child_border.Margin = new Thickness(_margin); child_border.Child = child; var filter_row = new RowDefinition(); @@ -279,16 +288,13 @@ public virtual bool CreateUI() content_grid.Children.Add(child_border); _content.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); - _content.BorderThickness = new Thickness(2.0, 2.0, 2.0, 2.0); + _content.BorderThickness = new Thickness(_border_thickness); _content.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); _content.CornerRadius = new CornerRadius(0); - _content.Margin = new Thickness(_margin, _margin, _margin, _margin); + _content.Margin = new Thickness(_margin); _content.Child = content_grid; - _modify_ui_filter_list_callback(_content, ListModification.ADD); - - _timer.Stop(); _created = true; return _created; @@ -324,15 +330,47 @@ public void ContentMetadataListCallback(List content_metadata) check.SetBinding(CheckBox.ContentProperty, metadata.NameBinding); check.Margin = new Thickness(_margin, _margin, 0.0, 0.0); check.Tag = metadata.DataUID; - check.Click += click_dirty; + check.Click += _event_content_checked; check.SetResourceReference(CheckBox.ForegroundProperty, "Brush_Foreground"); _visualizations_list.Children.Add(check); } } - private void click_dirty(object sender, RoutedEventArgs e) + /// + /// + /// + public void SetDirty(List data_uids = null) { - set_filter_dirty(); + bool checked_content = false; + if (data_uids == null) + { + // If not data_uids are given, set all checked content "not considered" = false ... + foreach (int key in _checked_content_changes.Keys.ToList()) + { + if (_checked_content_changes[key].Item2 == ListModification.ADD) + { + _checked_content_changes[key] = new ChangedContentApplyData_Type(false, ListModification.ADD, _checked_content_changes[key].Item3); + checked_content = true; + } + } + } + else + { + // ... else set only checked content "not considered" = false + foreach (var data_uid in data_uids) + { + if (_checked_content_changes.ContainsKey(data_uid) && (_checked_content_changes[data_uid].Item2 == ListModification.ADD)) + { + _checked_content_changes[data_uid] = new ChangedContentApplyData_Type(false, ListModification.ADD, _checked_content_changes[data_uid].Item3); + checked_content = true; + } + } + } + + if (checked_content) + { + _set_dirty(true); + } } #endregion @@ -345,7 +383,60 @@ protected virtual UIElement create_ui() throw new InvalidOperationException("Should be implemented by inheriting class."); } - private void _apply_button_click(object sender, RoutedEventArgs e) + protected virtual void apply_filter(GenericDataStructure in_out_data) + { + throw new InvalidOperationException("Should be implemented by inheriting class."); + } + + #endregion + + /* ------------------------------------------------------------------*/ + #region private functions + + private void _event_content_checked(object sender, RoutedEventArgs e) + { + var checkbox = sender as CheckBox; + if (checkbox == null) + { + Log.Default.Msg(Log.Level.Error, "Unexpected sender"); + return; + } + var data_uid = (int)checkbox.Tag; + var is_checked = (bool)checkbox.IsChecked; + + if (_checked_content_changes.ContainsKey(data_uid)) + { + bool content_considered = _checked_content_changes[data_uid].Item1; + + if ((is_checked && (_checked_content_changes[data_uid].Item2 == ListModification.DELETE)) || + (!is_checked && (_checked_content_changes[data_uid].Item2 == ListModification.ADD))) + { + var mod = (_checked_content_changes[data_uid].Item2 == ListModification.ADD) ? (ListModification.DELETE) : (ListModification.ADD); + if (content_considered) + { + _checked_content_changes[data_uid] = new ChangedContentApplyData_Type(false, mod, _checked_content_changes[data_uid].Item3); + } + else + { + // Ignore changes reverted before having been applied + _checked_content_changes.Remove(data_uid); + } + } + } + else if (is_checked) + { + _checked_content_changes[data_uid] = new ChangedContentApplyData_Type(false, ListModification.ADD, null); + } + + bool considered = true; + foreach (var content_tuple in _checked_content_changes) + { + considered &= content_tuple.Value.Item1; + } + _set_dirty(!considered); + } + + private void _event_apply_button(object sender, RoutedEventArgs e) { var sender_button = sender as Button; if (sender_button == null) @@ -353,25 +444,79 @@ private void _apply_button_click(object sender, RoutedEventArgs e) Log.Default.Msg(Log.Level.Error, "Unexpected sender"); return; } - sender_button.IsEnabled = false; - _apply_button.SetResourceReference(Button.BackgroundProperty, "Brush_Background"); + + bool filter_changed = false; + + foreach (int key in _checked_content_changes.Keys.ToList()) + { + var data_uid = key; + + if (!_checked_content_changes[data_uid].Item1) + { + if (_checked_content_changes[data_uid].Item2 == ListModification.ADD) + { + var original_data = _get_selected_data_callback(data_uid); + original_data = original_data.DeepCopy(); /// XXX Required? + + var filter_data = original_data.DeepCopy(); + apply_filter(filter_data); + _update_selected_data_callback(data_uid, filter_data); + + // Add original data only for the first time the filter is applied + var kept_original_data = _checked_content_changes[data_uid].Item3; + _checked_content_changes[data_uid] = new ChangedContentApplyData_Type(true, ListModification.ADD, ((kept_original_data == null) ? (original_data) : (kept_original_data))); + filter_changed = true; + } + else if (_checked_content_changes[data_uid].Item2 == ListModification.DELETE) + { + // Undo changes applied by the filter + if (_checked_content_changes[data_uid].Item3 != null) + { + _update_selected_data_callback(data_uid, _checked_content_changes[data_uid].Item3); + _checked_content_changes.Remove(data_uid); + filter_changed = true; + } + else + { + Log.Default.Msg(Log.Level.Error, "Missing original data"); + } + } + } + } + + // Notify filter manager on change + if (filter_changed) + { + _filter_changed_callback(_UID, _get_checked_content_list()); + } + _set_dirty(false); } - protected void set_filter_dirty() + private void _set_dirty(bool dirty) { - _apply_button.IsEnabled = true; - _apply_button.SetResourceReference(Button.BackgroundProperty, "Brush_ApplyDirtyBackground"); + _apply_button.IsEnabled = dirty; + if (dirty) + { + _apply_button.SetResourceReference(Button.BackgroundProperty, "Brush_ApplyDirtyBackground"); + } + else + { + _apply_button.Background = _apply_button_default_background; + } } - #endregion - - /* ------------------------------------------------------------------*/ - #region private functions - - private void event_apply_filter() + private List _get_checked_content_list() { + var checked_content_lsit = new List(); - // call _get_selected_data_callback, modify all data and the call _update_selected_data_callback for all selected contents + foreach (int key in _checked_content_changes.Keys.ToList()) + { + if (_checked_content_changes[key].Item2 == ListModification.ADD) + { + checked_content_lsit.Add(key); + } + } + return checked_content_lsit; } #endregion @@ -380,7 +525,7 @@ private void event_apply_filter() #region private variables private const double _margin = 5.0; - + private const double _border_thickness = 2.0; private bool _created = false; @@ -388,12 +533,16 @@ private void event_apply_filter() private RenameLabel _filter_caption = null; private StackPanel _visualizations_list = null; private Button _apply_button = null; + private Brush _apply_button_default_background = null; private DataManager.UpdateSelectedDataCallback_Delegate _update_selected_data_callback = null; private DataManager.GetGenericDataCallback_Delegate _get_selected_data_callback = null; - private FilterManager.ModifyUIFilterList_Delegate _modify_ui_filter_list_callback = null; + private FilterManager.FilterChanged_Delegate _filter_changed_callback = null; private FilterManager.DeleteFilterCallback_Delegate _delete_self_callback = null; + // Track content selection changes + private Dictionary _checked_content_changes = null; + #endregion } } diff --git a/Core/Core.csproj b/Core/Core.csproj index fb84f74..0f53efd 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -116,8 +116,7 @@ - - + Component diff --git a/Core/Data/DataManager.cs b/Core/Data/DataManager.cs index 937fc3f..fb3331e 100644 --- a/Core/Data/DataManager.cs +++ b/Core/Data/DataManager.cs @@ -35,7 +35,7 @@ public class DataManager : AbstractService public delegate void SetDataCallback_Delegate(GenericDataStructure ouput_data); public delegate GenericDataStructure GetGenericDataCallback_Delegate(int data_uid); - public delegate void UpdateSelectedDataCallback_Delegate(GenericDataStructure input_data, List data_uids); + public delegate void UpdateSelectedDataCallback_Delegate(int data_uid, GenericDataStructure input_data); public delegate int RegisterDataCallback_Delegate(Type data_type, UpdateVisualizationCallback_Delegate update_callback); public delegate void UnregisterUpdateCallback_Delegate(int data_uid); @@ -121,7 +121,7 @@ public void UpdateAllDataCallback(GenericDataStructure input_data) /// Callback to propagate new input data to selected data types in the data manager. /// /// The new input data. - public void UpdateSelectedDataCallback(GenericDataStructure input_data, List data_uids) + public void UpdateSelectedDataCallback(int data_uid, GenericDataStructure input_data) { if (!_initialized) { @@ -134,16 +134,12 @@ public void UpdateSelectedDataCallback(GenericDataStructure input_data, List diff --git a/Core/Data/DataTypeGeneric.cs b/Core/Data/DataTypeGeneric.cs index 75363b4..1a482e2 100644 --- a/Core/Data/DataTypeGeneric.cs +++ b/Core/Data/DataTypeGeneric.cs @@ -38,7 +38,7 @@ public override void UpdateData(GenericDataStructure data) _Dimension = data.GetDimension(); - _data_generic = data.DeepCopy(_update_metadata_handler); + _data_generic = data.DeepCopy(); _data_specific = _data_generic; init_metadata(_data_specific); diff --git a/Core/Data/GenericDataStructure.cs b/Core/Data/GenericDataStructure.cs index 7281d29..b23e724 100644 --- a/Core/Data/GenericDataStructure.cs +++ b/Core/Data/GenericDataStructure.cs @@ -33,6 +33,17 @@ public class GenericDataStructure /* ------------------------------------------------------------------*/ #region public functions + /// DEBUG + public GenericDataStructure() + { + Log.Default.Msg(Log.Level.Debug, " ----> Created new instance of GenericDataStructure"); + } + ~GenericDataStructure() + { + Log.Default.Msg(Log.Level.Debug, " ----< Deleted instance of GenericDataStructure"); + } + /// DEBUG + public void AddBranch(GenericDataStructure branch) { _Branches.Add(branch); } public void AddEntry(GenericDataEntry entry) { _Entries.Add(entry); } @@ -140,13 +151,13 @@ public bool Transpose() return true; } - public GenericDataStructure DeepCopy(PropertyChangedEventHandler update_metadata_handler) + public GenericDataStructure DeepCopy() { var branch_clone = new GenericDataStructure(); foreach (var branch in _Branches) { - branch_clone.AddBranch(branch.DeepCopy(update_metadata_handler)); + branch_clone.AddBranch(branch.DeepCopy()); } foreach (var entry in _Entries) { @@ -160,11 +171,8 @@ public GenericDataStructure DeepCopy(PropertyChangedEventHandler update_metadata { entry_clone._Types.Add(type); } - entry_clone._Metadata._Index = entry._Metadata._Index; - entry_clone._Metadata._Label = entry._Metadata._Label; - entry_clone._Metadata._Dimension = entry._Metadata._Dimension; - entry_clone._Metadata._Selected = entry._Metadata._Selected; - entry_clone._Metadata.PropertyChanged += update_metadata_handler; + // Do not clone metadata since this should be shared even with deep copies + entry_clone._Metadata = entry._Metadata; branch_clone.AddEntry(entry_clone); } branch_clone._Label = _Label; diff --git a/Core/Filtering/Filter.cs.template b/Core/Filtering/Filter.cs.template index 5a7ca32..8060cad 100644 --- a/Core/Filtering/Filter.cs.template +++ b/Core/Filtering/Filter.cs.template @@ -10,7 +10,7 @@ using Core.Abstracts; INSTRUCTIONS for creating own custom data filter: -see https://github.com/IntCDC/VisuAlFroG/blob/main/docs/developer-uide.md +see https://github.com/IntCDC/VisuAlFroG/blob/main/docs/developer-guide.md */ @@ -31,10 +31,12 @@ namespace Core /// /// Class defining the configuration required for restoring content. /// + /* public class Configuration : AbstractFilter.Configuration { - //TODO Add additional information required to restore the filter + /// XXX TODO Add additional information required to restore the filter } +* */ #endregion @@ -42,7 +44,6 @@ namespace Core #region public functions - #endregion /* ------------------------------------------------------------------*/ @@ -50,14 +51,26 @@ namespace Core protected override UIElement create_ui() { - var ui = new Grid(); + _Name = "Transpose"; + + var ui = new TextBlock(); + ui.Text = "Filter description ..."; + + + // Call when value has changed and filter should be applied with changes + // set_apply_dirty(); - // Place the UI stuff of your filter here... return ui; } + protected override void apply_filter(GenericDataStructure in_out_data) + { + // Change in_out_data accodingly... + + } + #endregion } } -} +} \ No newline at end of file diff --git a/Core/Filtering/FilterManager.cs b/Core/Filtering/FilterManager.cs index 0850844..d9e4fd7 100644 --- a/Core/Filtering/FilterManager.cs +++ b/Core/Filtering/FilterManager.cs @@ -46,6 +46,7 @@ public class FilterListMetadata public delegate bool CreateFilterCallback_Delegate(Type filter_type); public delegate bool DeleteFilterCallback_Delegate(int filter_uid); public delegate void ModifyUIFilterList_Delegate(UIElement element, AbstractFilter.ListModification mod); + public delegate void FilterChanged_Delegate(int filter_uid, List data_uids); #endregion @@ -65,13 +66,13 @@ public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_ _timer.Start(); - _content_metadata = new List(); + _contents_metadata = new List(); + _ordered_filter_list = new List(); _get_selected_data_callback = get_selected_data_callback; _update_selected_data_callback = update_selected_data_callback; - register_content(typeof(ColumnSelectionFilter)); - register_content(typeof(ValueSelectionFilter)); + register_content(typeof(TransposeFilter)); _timer.Stop(); @@ -83,7 +84,9 @@ public override bool Terminate() { if (_initialized) { - _content_metadata = null; + _contents_metadata = null; + _ordered_filter_list.Clear(); + _ordered_filter_list = null; _update_selected_data_callback = null; _get_selected_data_callback = null; _modify_ui_filter_list_callback = null; @@ -100,7 +103,7 @@ public List GetFilterTypeList() foreach (var filter_data in _contents) { var filter_metadata = new FilterListMetadata(); - ///filter_metadata.ID = id; // for enumeration in combobox + ///filter_metadata.ID = id; /// required for enumeration in combobox? filter_metadata.Name = filter_data.Key.Name; filter_metadata.Type = filter_data.Key; list.Add(filter_metadata); @@ -112,13 +115,6 @@ public List GetFilterTypeList() public void SetModifyUIFilterList(ModifyUIFilterList_Delegate modify_ui_filter_list_callback) { _modify_ui_filter_list_callback = modify_ui_filter_list_callback; - foreach (var filter_data in _contents) - { - foreach (var filter in filter_data.Value) - { - _modify_ui_filter_list_callback(filter.Value.GetUI(), AbstractFilter.ListModification.ADD); - } - } } public bool CreateFilterCallback(Type filter_type) @@ -137,12 +133,15 @@ public bool CreateFilterCallback(Type filter_type) if (_contents.ContainsKey(filter_type)) { var filter = (AbstractFilter)Activator.CreateInstance(filter_type); - if (filter.Initialize(_get_selected_data_callback, _update_selected_data_callback, _modify_ui_filter_list_callback, DeleteFilterCallback)) + if (filter.Initialize(_get_selected_data_callback, _update_selected_data_callback, this.filter_changed, DeleteFilterCallback)) { if (filter.CreateUI()) { - filter.ContentMetadataListCallback(_content_metadata); + filter.ContentMetadataListCallback(_contents_metadata); _contents[filter_type].Add(filter._UID, filter); + _ordered_filter_list.Add(filter._UID); + // Add filter to UI list + _modify_ui_filter_list_callback(filter.GetUI(), ListModification.ADD); return true; } else @@ -169,7 +168,11 @@ public bool DeleteFilterCallback(int filter_uid) { if (filter_types.Value.ContainsKey(filter_uid)) { + // Remove filter from UI list + _modify_ui_filter_list_callback(filter_types.Value[filter_uid].GetUI(), ListModification.DELETE); filter_types.Value[filter_uid].Terminate(); + // Call after terminate + _ordered_filter_list.Remove(filter_types.Value[filter_uid]._UID); return filter_types.Value.Remove(filter_uid); } } @@ -211,24 +214,24 @@ public bool ApplyConfigurations(string configurations) public void AddContentMetadataCallback(AbstractFilter.ContentMetadata content_metadata) { - _content_metadata.Add(content_metadata); + _contents_metadata.Add(content_metadata); foreach (var filter_type in _contents) { foreach (var filter in filter_type.Value) { - filter.Value.ContentMetadataListCallback(_content_metadata); + filter.Value.ContentMetadataListCallback(_contents_metadata); } } } public void DeleteContentMetadataCallback(int data_uid) { - foreach (var cm in _content_metadata) + foreach (var cm in _contents_metadata) { if (cm.DataUID == data_uid) { - _content_metadata.Remove(cm); + _contents_metadata.Remove(cm); break; } } @@ -236,7 +239,7 @@ public void DeleteContentMetadataCallback(int data_uid) { foreach (var filter in filter_type.Value) { - filter.Value.ContentMetadataListCallback(_content_metadata); + filter.Value.ContentMetadataListCallback(_contents_metadata); } } } @@ -261,6 +264,30 @@ protected override bool reset_content(AbstractFilter filter_value) /* ------------------------------------------------------------------*/ #region private functions + void filter_changed(int filter_uid, List data_uids) + { + // Notify all subsequent filters that previous filter has changed and that their original data has changed + if (!_ordered_filter_list.Contains(filter_uid)) + { + Log.Default.Msg(Log.Level.Error, "Missing filter UID"); + + } + + var index = _ordered_filter_list.FindIndex(f => (f == filter_uid)); + for (int i = index+1; i < _ordered_filter_list.Count; i++) + { + foreach (var filter_type in _contents) + { + foreach (var filter in filter_type.Value) + { + if (filter.Value._UID == _ordered_filter_list[i]) + { + filter.Value.SetDirty(data_uids); + } + } + } + } + } #endregion @@ -268,7 +295,9 @@ protected override bool reset_content(AbstractFilter filter_value) #region private variables // Required to provide new filters with content metadata - private List _content_metadata = null; + private List _contents_metadata = null; + + private List _ordered_filter_list = null; private DataManager.UpdateSelectedDataCallback_Delegate _update_selected_data_callback = null; private DataManager.GetGenericDataCallback_Delegate _get_selected_data_callback = null; diff --git a/Core/Filtering/ColumnSelectionFilter.cs b/Core/Filtering/TransposeFilter.cs similarity index 70% rename from Core/Filtering/ColumnSelectionFilter.cs rename to Core/Filtering/TransposeFilter.cs index 56a86db..7551909 100644 --- a/Core/Filtering/ColumnSelectionFilter.cs +++ b/Core/Filtering/TransposeFilter.cs @@ -18,7 +18,7 @@ namespace Core { namespace Filter { - public class ColumnSelectionFilter : AbstractFilter + public class TransposeFilter : AbstractFilter { /* ------------------------------------------------------------------*/ #region public classes @@ -26,10 +26,12 @@ public class ColumnSelectionFilter : AbstractFilter /// /// Class defining the configuration required for restoring content. /// + /* public class Configuration : AbstractFilter.Configuration { /// XXX TODO Add additional information required to restore the filter } +* */ #endregion @@ -37,7 +39,6 @@ public class Configuration : AbstractFilter.Configuration #region public functions - #endregion /* ------------------------------------------------------------------*/ @@ -45,15 +46,24 @@ public class Configuration : AbstractFilter.Configuration protected override UIElement create_ui() { - var ui = new Grid(); - _Name = "Column Selection"; + _Name = "Transpose"; + + var ui = new TextBlock(); + ui.Text = "Transpose tabular 2D data"; + - ui.Height = 150; + // Call when filter option has changed and filter should be applied again + // SetDirty(); return ui; } + protected override void apply_filter(GenericDataStructure in_out_data) + { + in_out_data.Transpose(); + } + #endregion } } diff --git a/Core/Filtering/ValueSelectionFilter.cs b/Core/Filtering/ValueSelectionFilter.cs deleted file mode 100644 index cd1a479..0000000 --- a/Core/Filtering/ValueSelectionFilter.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.Windows; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Controls; -using System.Threading.Tasks; -using Core.Data; -using Core.Utilities; -using Core.Abstracts; - - - -/* - * - * - */ -namespace Core -{ - namespace Filter - { - public class ValueSelectionFilter : AbstractFilter - { - /* ------------------------------------------------------------------*/ - #region public classes - - /// - /// Class defining the configuration required for restoring content. - /// - public class Configuration : AbstractFilter.Configuration - { - /// XXX TODO Add additional information required to restore the filter - } - - #endregion - - /* ------------------------------------------------------------------*/ - #region public functions - - - - #endregion - - /* ------------------------------------------------------------------*/ - #region protected functions - - protected override UIElement create_ui() - { - var ui = new Grid(); - _Name = "Value Selection"; - - ui.Height = 150; - - - return ui; - } - - #endregion - } - } -} diff --git a/Core/GUI/MenubarWindow.cs b/Core/GUI/MenubarWindow.cs index 48dffb5..17ce498 100644 --- a/Core/GUI/MenubarWindow.cs +++ b/Core/GUI/MenubarWindow.cs @@ -23,7 +23,7 @@ public class MenubarWindow : AbstractMenuBar public enum PredefinedMenuOption { VIEW, - CONTENT, + OPTIONS, DATA, } @@ -37,7 +37,7 @@ public override bool Initialize() if (base.Initialize()) { add_main_menu("View", PredefinedMenuOption.VIEW); - add_main_menu("Content", PredefinedMenuOption.CONTENT); + add_main_menu("Options", PredefinedMenuOption.OPTIONS); add_main_menu("Data", PredefinedMenuOption.DATA); } diff --git a/Core/GUI/Windows/WindowLeaf.cs b/Core/GUI/Windows/WindowLeaf.cs index f212569..3584514 100644 --- a/Core/GUI/Windows/WindowLeaf.cs +++ b/Core/GUI/Windows/WindowLeaf.cs @@ -131,7 +131,7 @@ public void CreateContent(int uid, string content_type) // Set content caption _Name = content_metadata.Item2; - _menu.Clear(MenubarWindow.PredefinedMenuOption.CONTENT); + _menu.Clear(MenubarWindow.PredefinedMenuOption.OPTIONS); _menu.Clear(MenubarWindow.PredefinedMenuOption.DATA); /// XXX Exclude some content from having the following menu --- Find better solution... Check if DataUID=Invalid but not available here diff --git a/SciChartInterface/Abstracts/AbstractSciChartParallel.cs b/SciChartInterface/Abstracts/AbstractSciChartParallel.cs index 44457f6..618abef 100644 --- a/SciChartInterface/Abstracts/AbstractSciChartParallel.cs +++ b/SciChartInterface/Abstracts/AbstractSciChartParallel.cs @@ -134,7 +134,7 @@ public override void AttachMenu(MenubarWindow menubar) clue_item.InputGestureText = "Right Mouse"; clue_item.IsEnabled = false; option_hint.Items.Add(clue_item); - menubar.AddMenu(MenubarWindow.PredefinedMenuOption.CONTENT, option_hint); + menubar.AddMenu(MenubarWindow.PredefinedMenuOption.OPTIONS, option_hint); } #endregion diff --git a/SciChartInterface/Abstracts/AbstractSciChartSeries.cs b/SciChartInterface/Abstracts/AbstractSciChartSeries.cs index fb996c2..e96ba2c 100644 --- a/SciChartInterface/Abstracts/AbstractSciChartSeries.cs +++ b/SciChartInterface/Abstracts/AbstractSciChartSeries.cs @@ -143,7 +143,7 @@ public override void AttachMenu(MenubarWindow menubar) clue_item.InputGestureText = "Right Mouse"; clue_item.IsEnabled = false; option_hint.Items.Add(clue_item); - menubar.AddMenu(MenubarWindow.PredefinedMenuOption.CONTENT, option_hint); + menubar.AddMenu(MenubarWindow.PredefinedMenuOption.OPTIONS, option_hint); } #endregion diff --git a/SciChartInterface/Data/DataTypeSciChartParallel.cs b/SciChartInterface/Data/DataTypeSciChartParallel.cs index bd5f987..909b607 100644 --- a/SciChartInterface/Data/DataTypeSciChartParallel.cs +++ b/SciChartInterface/Data/DataTypeSciChartParallel.cs @@ -45,7 +45,7 @@ public override void UpdateData(GenericDataStructure data) _Dimension = data.GetDimension(); - _data_generic = data.DeepCopy(_update_metadata_handler); + _data_generic = data.DeepCopy(); // Create value - property name pairs List value_series = new List(); diff --git a/SciChartInterface/Data/DataTypeSciChartSeries.cs b/SciChartInterface/Data/DataTypeSciChartSeries.cs index a4ed657..96966bf 100644 --- a/SciChartInterface/Data/DataTypeSciChartSeries.cs +++ b/SciChartInterface/Data/DataTypeSciChartSeries.cs @@ -44,7 +44,7 @@ public override void UpdateData(GenericDataStructure data) _loaded = false; _Dimension = data.GetDimension(); - _data_generic = data.DeepCopy(_update_metadata_handler); + _data_generic = data.DeepCopy(); specificdata_conversion(data); _loaded = true; } diff --git a/Visualizations/Visualizations/WPF_FilterEditor.cs b/Visualizations/Visualizations/WPF_FilterEditor.cs index ff3b3c5..c595961 100644 --- a/Visualizations/Visualizations/WPF_FilterEditor.cs +++ b/Visualizations/Visualizations/WPF_FilterEditor.cs @@ -56,12 +56,12 @@ public override bool CreateUI() _add_filter_list.IsEditable = false; _add_filter_list.DisplayMemberPath = "Name"; _add_filter_list.SelectedIndex = 0; - _add_filter_list.Margin = new Thickness(0.0, 2.0, 2.0, 2.0); + _add_filter_list.Margin = new Thickness(0.0, _margin, _margin, _margin); var add_button = new Button(); add_button.Content = " Add Filter "; add_button.Click += event_apply_button; - add_button.Margin = new Thickness(2.0, 4.0, 2.0, 4.0); + add_button.Margin = new Thickness(_margin, _margin/2.0, _margin, _margin/2.0); _list_scrolling = new ScrollViewer(); _list_scrolling.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; @@ -77,16 +77,16 @@ public override bool CreateUI() note.Text = "Filters are applied sequentially from top to bottom."; note.SetResourceReference(TextBlock.BackgroundProperty, "Brush_Background"); note.SetResourceReference(TextBlock.ForegroundProperty, "Brush_Foreground"); - note.Margin = new Thickness(5.0, 5.0, 5.0, 5.0); + note.Margin = new Thickness(_margin); var note_border = new Border(); note_border.Child = note; note_border.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); - note_border.BorderThickness = new Thickness(0.0, 0.0, 0.0, 2.0); + note_border.BorderThickness = new Thickness(0.0, 0.0, 0.0, _border_thickness); note_border.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); note_border.CornerRadius = new CornerRadius(0); - note_border.Margin = new Thickness(0.0, 0.0, 0.0, 5.0); + note_border.Margin = new Thickness(0.0, 0.0, 0.0, _margin); var caption_grid = new Grid(); @@ -236,6 +236,9 @@ private void event_scrollviewer_mousewheel(object sender, System.Windows.Input.M /* ------------------------------------------------------------------*/ #region private variables + private const double _margin = 5.0; + private const double _border_thickness = 2.0; + private ComboBox _add_filter_list = null; private ScrollViewer _list_scrolling = null; private StackPanel _filter_list = null; diff --git a/Visualizations/Visualizations/WPF_LogConsole.cs b/Visualizations/Visualizations/WPF_LogConsole.cs index 196c7eb..8219ec5 100644 --- a/Visualizations/Visualizations/WPF_LogConsole.cs +++ b/Visualizations/Visualizations/WPF_LogConsole.cs @@ -127,7 +127,7 @@ public void LogListener(List msglist) public override void AttachMenu(MenubarWindow menubar) { base.AttachMenu(menubar); - menubar.AddMenu(MenubarWindow.PredefinedMenuOption.CONTENT, MenubarMain.GetDefaultMenuItem("Copy to Clipboard", clipboard_content_click)); + menubar.AddMenu(MenubarWindow.PredefinedMenuOption.OPTIONS, MenubarMain.GetDefaultMenuItem("Copy to Clipboard", clipboard_content_click)); } #endregion