From 39ccc8e1759ba341c324146a6268e55dd6d340a3 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 12 Feb 2023 10:01:51 +0100 Subject: [PATCH] fix: make no profile working correctly, changing to no profile on change --- .../Converters/EnumToBooleanConverter.cs | 28 +++++++ .../Models/Filters/FilterProfiles.cs | 7 +- .../Filters/FilterChooseViewModel.cs | 84 +++++++++++++------ .../Filters/FilterConfigViewModel.cs | 4 +- .../Filters/FilterEntryViewModel.cs | 74 +++++++++++++++- .../ViewModels/Log/PacketLogViewModel.cs | 14 ++-- .../ViewModels/MainWindowViewModel.cs | 2 +- .../Views/Filters/FilterEntryView.axaml | 27 ++++-- 8 files changed, 197 insertions(+), 43 deletions(-) create mode 100644 src/PacketLogger/Converters/EnumToBooleanConverter.cs diff --git a/src/PacketLogger/Converters/EnumToBooleanConverter.cs b/src/PacketLogger/Converters/EnumToBooleanConverter.cs new file mode 100644 index 0000000..42080ac --- /dev/null +++ b/src/PacketLogger/Converters/EnumToBooleanConverter.cs @@ -0,0 +1,28 @@ +// +// EnumToBooleanConverter.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Globalization; +using Avalonia.Data; +using Avalonia.Data.Converters; + +namespace PacketLogger.Converters; + +/// +public class EnumToBooleanConverter : IValueConverter +{ + /// + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return value?.Equals(parameter); + } + + /// + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return value?.Equals(true) == true ? parameter : BindingOperations.DoNothing; + } +} \ No newline at end of file diff --git a/src/PacketLogger/Models/Filters/FilterProfiles.cs b/src/PacketLogger/Models/Filters/FilterProfiles.cs index 67d1b5a..81d834c 100644 --- a/src/PacketLogger/Models/Filters/FilterProfiles.cs +++ b/src/PacketLogger/Models/Filters/FilterProfiles.cs @@ -29,7 +29,7 @@ public class FilterProfiles AllProfiles = new ObservableCollection(); SelectableProfiles = new ObservableCollection(); - SelectableProfiles.Add(new FilterProfile(false) + SelectableProfiles.Add(NoProfile = new FilterProfile(false) { Name = "No profile" }); @@ -73,6 +73,11 @@ public class FilterProfiles /// public ObservableCollection AllProfiles { get; } + /// + /// Gets or sets the profile used as no profile. + /// + public FilterProfile NoProfile { get; set; } + /// /// Add the given profile. /// diff --git a/src/PacketLogger/ViewModels/Filters/FilterChooseViewModel.cs b/src/PacketLogger/ViewModels/Filters/FilterChooseViewModel.cs index 79014f6..1903fa5 100644 --- a/src/PacketLogger/ViewModels/Filters/FilterChooseViewModel.cs +++ b/src/PacketLogger/ViewModels/Filters/FilterChooseViewModel.cs @@ -7,6 +7,8 @@ using System; using System.Collections.Generic; using System.Reactive.Disposables; +using System.Reflection.Metadata.Ecma335; +using Avalonia.Controls.Notifications; using DynamicData; using DynamicData.Binding; using PacketLogger.Models.Filters; @@ -20,22 +22,26 @@ namespace PacketLogger.ViewModels.Filters; public class FilterChooseViewModel : ViewModelBase, IDisposable { private FilterProfile _currentProfile = null!; + private FilterProfile _currentRealProfile = null!; private IDisposable? _cleanUp; private FilterProfile _noProfile; + private FilterProfile _noRealProfile; /// /// Initializes a new instance of the class. /// /// The current filter profile. - public FilterChooseViewModel(FilterProfile currentProfile) + /// The real no profile. + public FilterChooseViewModel(FilterProfile currentProfile, FilterProfile noProfile) { - RecvFilterSelected = true; - CurrentProfile = currentProfile; - CurrentFilter = CreateSendRecvFilter(); _noProfile = new FilterProfile(false) { Name = "No profile" }; + _noRealProfile = noProfile; + RecvFilterSelected = true; + CurrentProfile = currentProfile; + CurrentFilter = CreateSendRecvFilter(); } /// @@ -51,10 +57,25 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable return; } - if (value.Name == "No profile" && value != _noProfile) + var setCurrentProfile = value; + if (value.Name == "No profile") { - CurrentProfile = _noProfile; - return; + if (value != _noProfile) + { + value = _noProfile; + } + else + { + setCurrentProfile = _noRealProfile; + } + + CopyCurrentToNoProfile(_currentProfile); + } + + var cleanUp = new CompositeDisposable(); + if (RecvEntryViewModel is not null) + { + cleanUp = new CompositeDisposable(RecvEntryViewModel, SendEntryViewModel); } var lastProfile = value; @@ -65,15 +86,19 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable value.RecvFilterEntry, (data) => { - CopyCurrentToNoProfile(lastProfile); - _noProfile.RecvFilterEntry.Filters.Add(data); CurrentProfile = _noProfile; + _noProfile.RecvFilterEntry.Filters.Add(data); }, (data) => { - CopyCurrentToNoProfile(lastProfile); + CurrentProfile = _noProfile; _noProfile.RecvFilterEntry.Filters.Remove(data); + }, + (data) => + { CurrentProfile = _noProfile; + _noProfile.RecvFilterEntry.Active = data.Active; + _noProfile.RecvFilterEntry.Whitelist = data.Whitelist; } ); SendEntryViewModel = new FilterEntryViewModel @@ -81,45 +106,56 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable value.SendFilterEntry, (data) => { - CopyCurrentToNoProfile(lastProfile); - _noProfile.SendFilterEntry.Filters.Add(data); CurrentProfile = _noProfile; + _noProfile.SendFilterEntry.Filters.Add(data); }, (data) => { - CopyCurrentToNoProfile(lastProfile); + CurrentProfile = _noProfile; _noProfile.SendFilterEntry.Filters.Remove(data); + }, + (data) => + { CurrentProfile = _noProfile; + _noProfile.SendFilterEntry.Active = data.Active; + _noProfile.SendFilterEntry.Whitelist = data.Whitelist; } ); } else { - RecvEntryViewModel = new FilterEntryViewModel(value.RecvFilterEntry, null, null); - SendEntryViewModel = new FilterEntryViewModel(value.SendFilterEntry, null, null); + RecvEntryViewModel = new FilterEntryViewModel(value.RecvFilterEntry); + SendEntryViewModel = new FilterEntryViewModel(value.SendFilterEntry); } - _currentProfile = value; - var recvWhenAny = _currentProfile.RecvFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist") + _currentRealProfile = value; + _currentProfile = setCurrentProfile; + + var recvWhenAny = _currentRealProfile.RecvFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist") .Subscribe((e) => OnChange()); - var sendWhenAny = _currentProfile.SendFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist") + var sendWhenAny = _currentRealProfile.SendFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist") .Subscribe((e) => OnChange()); - var recvFilters = _currentProfile.RecvFilterEntry.Filters.ObserveCollectionChanges() + var recvFilters = _currentRealProfile.RecvFilterEntry.Filters.ObserveCollectionChanges() .Subscribe((e) => OnChange()); - var sendFilters = _currentProfile.SendFilterEntry.Filters.ObserveCollectionChanges() + var sendFilters = _currentRealProfile.SendFilterEntry.Filters.ObserveCollectionChanges() .Subscribe((e) => OnChange()); _cleanUp?.Dispose(); - _cleanUp = new CompositeDisposable(recvWhenAny, sendWhenAny, recvFilters, sendFilters); + _cleanUp = new CompositeDisposable(recvWhenAny, sendWhenAny, recvFilters, sendFilters, cleanUp); OnChange(); } } - private void CopyCurrentToNoProfile(FilterProfile lastProfile) + private void CopyCurrentToNoProfile(FilterProfile? lastProfile) { + if (lastProfile is null) + { + return; + } + _noProfile.RecvFilterEntry.Filters.Clear(); _noProfile.RecvFilterEntry.Filters.AddRange(lastProfile.RecvFilterEntry.Filters); @@ -168,8 +204,8 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable /// The created filter. public IFilter CreateSendRecvFilter() { - IFilter recvFilter = CreateCompound(RecvEntryViewModel.Entry); - IFilter sendFilter = CreateCompound(SendEntryViewModel.Entry); + IFilter recvFilter = CreateCompound(_currentRealProfile.RecvFilterEntry); + IFilter sendFilter = CreateCompound(_currentRealProfile.SendFilterEntry); return new SendRecvFilter(sendFilter, recvFilter); } diff --git a/src/PacketLogger/ViewModels/Filters/FilterConfigViewModel.cs b/src/PacketLogger/ViewModels/Filters/FilterConfigViewModel.cs index 4c25ad6..089e506 100644 --- a/src/PacketLogger/ViewModels/Filters/FilterConfigViewModel.cs +++ b/src/PacketLogger/ViewModels/Filters/FilterConfigViewModel.cs @@ -22,8 +22,8 @@ public class FilterConfigViewModel : ViewModelBase public FilterConfigViewModel(FilterProfile filterProfile) { _filterProfile = filterProfile; - RecvEntryViewModel = new FilterEntryViewModel(filterProfile.RecvFilterEntry, null, null); - SendEntryViewModel = new FilterEntryViewModel(filterProfile.SendFilterEntry, null, null); + RecvEntryViewModel = new FilterEntryViewModel(filterProfile.RecvFilterEntry); + SendEntryViewModel = new FilterEntryViewModel(filterProfile.SendFilterEntry); } /// diff --git a/src/PacketLogger/ViewModels/Filters/FilterEntryViewModel.cs b/src/PacketLogger/ViewModels/Filters/FilterEntryViewModel.cs index 391f7ea..d0c0d24 100644 --- a/src/PacketLogger/ViewModels/Filters/FilterEntryViewModel.cs +++ b/src/PacketLogger/ViewModels/Filters/FilterEntryViewModel.cs @@ -6,6 +6,7 @@ using System; using System.Reactive; +using System.Reactive.Disposables; using PacketLogger.Models.Filters; using ReactiveUI; @@ -14,17 +15,27 @@ namespace PacketLogger.ViewModels.Filters; /// /// A view model for FilterEntryView. /// -public class FilterEntryViewModel : ViewModelBase +public class FilterEntryViewModel : ViewModelBase, IDisposable { + private readonly Action<(bool Active, bool Whitelist)>? _whitelistActiveChanged; + private readonly IDisposable _cleanUp; + /// /// Initializes a new instance of the class. /// /// The profile entry. /// The action called upon adding new. /// The action called upon removing the given filter data. + /// Called when whitelist or active has been changed. public FilterEntryViewModel - (FilterProfileEntry entry, Action? addNew, Action? remove) + ( + FilterProfileEntry entry, + Action? addNew = default, + Action? remove = default, + Action<(bool Active, bool Whitelist)>? whitelistActiveChanged = default + ) { + _whitelistActiveChanged = whitelistActiveChanged; NewFilterType = FilterCreator.FilterType.PacketHeader; Entry = entry; RemoveCurrent = ReactiveCommand.Create @@ -77,6 +88,52 @@ public class FilterEntryViewModel : ViewModelBase } } ); + + var whitelistChanged = Entry.WhenAnyValue(x => x.Whitelist) + .Subscribe(_ => this.RaisePropertyChanged("Whitelist")); + + var activeChanged = Entry.WhenAnyValue(x => x.Active) + .Subscribe(_ => this.RaisePropertyChanged("Active")); + + _cleanUp = new CompositeDisposable(whitelistChanged, activeChanged); + } + + /// + /// Gets or sets whether whitelist or blacklist. + /// + public bool Whitelist + { + get => Entry.Whitelist; + set + { + if (_whitelistActiveChanged is not null) + { + _whitelistActiveChanged((Entry.Active, value)); + } + else + { + Entry.Whitelist = value; + } + } + } + + /// + /// Gets or sets whether the filter entry is active. + /// + public bool Active + { + get => Entry.Active; + set + { + if (_whitelistActiveChanged is not null) + { + _whitelistActiveChanged((value, Entry.Whitelist)); + } + else + { + Entry.Active = value; + } + } } /// @@ -108,4 +165,17 @@ public class FilterEntryViewModel : ViewModelBase /// Gets the command to add new filter. /// public ReactiveCommand AddNew { get; } + + /// + /// Gets radio group. + /// + public string RadioGroup { get; } = Guid.NewGuid().ToString(); + + /// + public void Dispose() + { + _cleanUp.Dispose(); + RemoveCurrent.Dispose(); + AddNew.Dispose(); + } } \ No newline at end of file diff --git a/src/PacketLogger/ViewModels/Log/PacketLogViewModel.cs b/src/PacketLogger/ViewModels/Log/PacketLogViewModel.cs index 626d32f..1549ef6 100644 --- a/src/PacketLogger/ViewModels/Log/PacketLogViewModel.cs +++ b/src/PacketLogger/ViewModels/Log/PacketLogViewModel.cs @@ -40,13 +40,13 @@ public class PacketLogViewModel : ViewModelBase, IDisposable public PacketLogViewModel(IPacketProvider packetProvider, FilterProfiles filterProfiles) { _filterProfiles = filterProfiles; - FilterChoose = new FilterChooseViewModel(new FilterProfile(false)); - FilterChoose.CurrentProfile = filterProfiles.DefaultFilterEnabled - ? filterProfiles.DefaultProfile - : new FilterProfile(false) - { - Name = "No profile" - }; + FilterChoose = new FilterChooseViewModel + ( + filterProfiles.DefaultFilterEnabled + ? filterProfiles.DefaultProfile + : filterProfiles.NoProfile, + filterProfiles.SelectableProfiles.Last() + ); Provider = packetProvider; var dynamicFilter = FilterChoose.WhenValueChanged(x => x.CurrentFilter) diff --git a/src/PacketLogger/ViewModels/MainWindowViewModel.cs b/src/PacketLogger/ViewModels/MainWindowViewModel.cs index 7362969..fe85e6d 100644 --- a/src/PacketLogger/ViewModels/MainWindowViewModel.cs +++ b/src/PacketLogger/ViewModels/MainWindowViewModel.cs @@ -35,7 +35,7 @@ using ReactiveUI; namespace PacketLogger.ViewModels; /// -public class MainWindowViewModel : ViewModelBase, INotifyPropertyChanged +public class MainWindowViewModel : ViewModelBase { private readonly DockFactory _factory; private readonly NostaleProcesses _processes; diff --git a/src/PacketLogger/Views/Filters/FilterEntryView.axaml b/src/PacketLogger/Views/Filters/FilterEntryView.axaml index 64a84df..3301360 100644 --- a/src/PacketLogger/Views/Filters/FilterEntryView.axaml +++ b/src/PacketLogger/Views/Filters/FilterEntryView.axaml @@ -3,16 +3,26 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:filters="clr-namespace:PacketLogger.ViewModels.Filters" + xmlns:converters="clr-namespace:PacketLogger.Converters" + xmlns:system="clr-namespace:System;assembly=System.Runtime" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="PacketLogger.Views.Filters.FilterEntryView"> + + + True + False + + + +