-
Notifications
You must be signed in to change notification settings - Fork 804
Feature: Firewall app #3378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Firewall app #3378
Changes from all commits
66c672f
fcddf1b
4525d29
d6fdd8f
39a6c6a
c9e73e5
f58adf9
9023d2d
42530bd
5e2411c
34e7047
80a33d0
53ea911
9064595
99fe27b
adb2920
3d29a0b
65969a5
be56e92
f92d09b
ef95654
86a013a
b61a90f
e24e3cf
1ab5284
3877c87
1cdcd85
05a8484
620172b
d9874ac
e278f2c
339c00b
4acd64d
47ac311
70402b2
65edb6b
002e2e8
d2ab9b4
d3385d8
ac54782
2bd1ea5
233819e
1a17ee9
49589ab
bade2cc
5a30d37
e6098c0
9d29586
3113c7c
3c9071c
f1e46f5
47579fe
98c32ea
5b7c406
1f98439
9732cc5
2f7e59d
ef2bc36
8c845cb
8e1694b
28860d5
78cc251
2bfed92
0f866f3
e4cb7eb
cdf2ca7
8dd4613
facc504
8bde342
b665322
fdf5b06
8a3f550
059b0d4
c091724
4436522
6586af1
60e1332
baf2f9d
1beef14
c0017ea
c18114b
e78e03a
cc44d76
e3cef76
709210d
b854cbe
b227470
a3d56c7
7258cef
b1a4cf2
02b94cd
cc5c8bd
ffa0c2d
163c844
54136da
a76cd00
2d3364d
83b6f2c
82322d1
ea787f8
0d4e7ef
5ce349f
804e874
9d7fd69
7af4428
9024e98
9b5cb11
65d15cd
9146e0b
da4aca8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| using System; | ||
| using System.Globalization; | ||
| using System.Linq; | ||
| using System.Windows.Data; | ||
| using NETworkManager.Models.Network; | ||
| using NETworkManager.Localization.Resources; | ||
|
|
||
|
|
||
| namespace NETworkManager.Converters; | ||
|
|
||
| public class BoolArrayToFwRuleCategoriesConverter : IValueConverter | ||
| { | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| if (targetType != typeof(string)) return null; | ||
| const int expectedLength = 3; | ||
| var fallback = GetTranslation(Enum.GetName(NetworkProfiles.NotConfigured), false); | ||
| if (value is not bool[] { Length: expectedLength } boolArray) | ||
| return fallback; | ||
| var result = string.Empty; | ||
| var numSelected = boolArray.CountAny(true); | ||
| switch (numSelected) | ||
| { | ||
| case 0: | ||
| return fallback; | ||
| case < 2: | ||
| return GetTranslation(Enum.GetName(typeof(NetworkProfiles), | ||
| Array.FindIndex(boolArray, b => b)), false); | ||
| } | ||
|
|
||
| if (boolArray.All(b => b)) | ||
| return Strings.All; | ||
|
|
||
| for (var i = 0; i < expectedLength; i++) | ||
| { | ||
| if (boolArray[i]) | ||
| result += $", {GetTranslation(Enum.GetName(typeof(NetworkProfiles), i), true)}"; | ||
| } | ||
|
|
||
| return result[2..]; | ||
|
|
||
| } | ||
|
|
||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| private static string GetTranslation(string key, bool trimmed) | ||
| { | ||
| return Strings.ResourceManager.GetString(trimmed ? $"{key}_Short3" : key, Strings.Culture); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| using System; | ||
| using System.Collections.Concurrent; | ||
| using System.Collections.Generic; | ||
| using System.Globalization; | ||
| using System.Reflection; | ||
| using System.Windows.Data; | ||
| using NETworkManager.Interfaces.ViewModels; | ||
|
|
||
| namespace NETworkManager.Converters | ||
| { | ||
| /// <summary> | ||
| /// A generic converter that checks a property of items in a collection. | ||
| /// If ANY item's property is considered "present" (not null, not empty), it returns Visible. | ||
| /// </summary> | ||
| /// <typeparam name="T">The type of item in the collection.</typeparam> | ||
| public class CollectionPropertyBooleanOrConverter<T> : IValueConverter | ||
| { | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| // 1. Validate inputs | ||
| if (value is not IEnumerable<T> collection) | ||
| return false; | ||
|
|
||
| if (parameter is not string propertyName || string.IsNullOrEmpty(propertyName)) | ||
| return false; | ||
|
|
||
| // 2. Get PropertyInfo via Reflection or cache. | ||
| if (!Cache.TryGetValue(propertyName, out var propertyInfo)) | ||
| { | ||
| propertyInfo = typeof(T).GetProperty(propertyName); | ||
| Cache.TryAdd(propertyName, propertyInfo); | ||
| } | ||
|
|
||
| if (propertyInfo == null) | ||
| return false; | ||
|
|
||
| // 3. Iterate collection and check property | ||
| foreach (var item in collection) | ||
| { | ||
| if (item == null) continue; | ||
|
|
||
| var propValue = propertyInfo.GetValue(item); | ||
|
|
||
| if (propValue is true) | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
|
|
||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| private ConcurrentDictionary<string, PropertyInfo> Cache { get; } = new(); | ||
| } | ||
|
|
||
| // Concrete implementation for XAML usage | ||
| public class FirewallRuleViewModelBooleanOrConverter : CollectionPropertyBooleanOrConverter<IFirewallRuleViewModel>; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Concurrent; | ||
| using System.Collections.Generic; | ||
| using System.Globalization; | ||
| using System.Reflection; | ||
| using System.Windows; | ||
| using System.Windows.Data; | ||
| using NETworkManager.Interfaces.ViewModels; | ||
|
|
||
| namespace NETworkManager.Converters | ||
| { | ||
| /// <summary> | ||
| /// A generic converter that checks a property of items in a collection. | ||
| /// If ANY item's property is considered "present" (not null, not empty), it returns Visible. | ||
| /// </summary> | ||
| /// <typeparam name="T">The type of item in the collection.</typeparam> | ||
| public class CollectionPropertyVisibilityConverter<T> : IValueConverter | ||
| { | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| // 1. Validate inputs | ||
| if (value is not IEnumerable<T> collection) | ||
| return Visibility.Collapsed; | ||
|
|
||
| if (parameter is not string propertyName || string.IsNullOrEmpty(propertyName)) | ||
| return Visibility.Collapsed; | ||
|
|
||
| // 2. Get PropertyInfo via Reflection or cache. | ||
| if (!Cache.TryGetValue(propertyName, out var propertyInfo)) | ||
| { | ||
| propertyInfo = typeof(T).GetProperty(propertyName); | ||
| Cache.TryAdd(propertyName, propertyInfo); | ||
| } | ||
|
|
||
| if (propertyInfo == null) | ||
| return Visibility.Collapsed; | ||
|
|
||
| // 3. Iterate collection and check property | ||
| foreach (var item in collection) | ||
| { | ||
| if (item == null) continue; | ||
|
|
||
| var propValue = propertyInfo.GetValue(item); | ||
|
|
||
| if (HasContent(propValue)) | ||
| { | ||
| return Visibility.Visible; | ||
| } | ||
| } | ||
|
|
||
| return Visibility.Collapsed; | ||
| } | ||
|
|
||
| private static bool HasContent(object value) | ||
| { | ||
| if (value == null) return false; | ||
|
|
||
| // Handle Strings | ||
| if (value is string str) | ||
| return !string.IsNullOrWhiteSpace(str); | ||
|
|
||
| // Handle Collections (Lists, Arrays, etc.) | ||
| if (value is ICollection col) | ||
| return col.Count > 0; | ||
|
|
||
| // Handle Generic Enumerable (fallback) | ||
| if (value is IEnumerable enumValue) | ||
| { | ||
| var enumerator = enumValue.GetEnumerator(); | ||
| var result = enumerator.MoveNext(); // Has at least one item | ||
| (enumerator as IDisposable)?.Dispose(); | ||
| return result; | ||
| } | ||
|
|
||
| // Default: If it's an object and not null, it's "True" | ||
| return true; | ||
| } | ||
|
|
||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| throw new NotImplementedException(); | ||
| } | ||
|
|
||
| private ConcurrentDictionary<string, PropertyInfo> Cache { get; } = new(); | ||
| } | ||
|
|
||
| // Concrete implementation for XAML usage | ||
| public class FirewallRuleViewModelVisibilityConverter : CollectionPropertyVisibilityConverter<IFirewallRuleViewModel>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| using System; | ||
| using System.Globalization; | ||
| using System.Windows.Data; | ||
|
|
||
| namespace NETworkManager.Converters; | ||
|
|
||
| public class EmptyToIntMaxValueConverter : IValueConverter | ||
| { | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| const int fallback = int.MaxValue; | ||
| if (targetType == typeof(int)) | ||
| { | ||
| if (value is not string strValue) | ||
| return fallback; | ||
| if (string.IsNullOrWhiteSpace(strValue)) | ||
| return fallback; | ||
| if (!int.TryParse(strValue, out int parsedIntValue)) | ||
| return fallback; | ||
| return parsedIntValue; | ||
| } | ||
|
|
||
| if (targetType != typeof(string)) | ||
| return null; | ||
| if (value is not int intValue) | ||
| return null; | ||
| return intValue is fallback ? string.Empty : intValue.ToString(); | ||
| } | ||
|
|
||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| return Convert(value, targetType, parameter, culture); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| using System; | ||
| using System.Globalization; | ||
| using System.Windows.Data; | ||
|
|
||
|
|
||
| namespace NETworkManager.Converters; | ||
|
|
||
| /// <summary> | ||
| /// A value converter that facilitates the conversion between enumeration values and their corresponding integer indices or string names. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// This converter is designed to either: | ||
| /// - Convert an enumeration value to its integer index within the enumeration. | ||
| /// - Convert an enumeration value to its string representation. | ||
| /// When converting back, the same logic is applied to handle appropriate conversion. | ||
| /// </remarks> | ||
| public class EnumToIntConverter : IValueConverter | ||
| { | ||
| /// <summary> | ||
| /// Converts an Enum value to its corresponding integer index or string representation | ||
| /// based on the target type. If the target type is an Enum, the method attempts | ||
| /// to return the name of the enum value. If the provided value is an Enum, it | ||
| /// returns the integer index of the value within the Enum's definition. | ||
| /// </summary> | ||
| /// <param name="value">The value to convert. This can be an Enum instance or null.</param> | ||
| /// <param name="targetType">The target type for the conversion. Typically either Enum or int.</param> | ||
| /// <param name="parameter">An optional parameter for additional input, not used in this method.</param> | ||
| /// <param name="culture">The culture information for the conversion process.</param> | ||
| /// <returns> | ||
| /// If the targetType is an Enum, a string representation of the Enum name is returned. | ||
| /// If the value is an Enum, the integer index of the Enum value is returned. | ||
| /// If neither condition is met, null is returned. | ||
| /// </returns> | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| if (targetType.IsEnum) | ||
| { | ||
| return value is null ? string.Empty : | ||
| Enum.GetName(targetType, value); | ||
| } | ||
| if (value is Enum enumVal) | ||
| { | ||
| return Array.IndexOf(Enum.GetValues(enumVal.GetType()), enumVal); | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
|
|
||
| /// Converts a value back into its corresponding enumeration value or integer representation. | ||
| /// This method is typically used in two-way data bindings where an integer or string needs | ||
| /// to be converted back to the corresponding enum value. | ||
| /// <param name="value">The value to be converted back. This can be an integer or a string representation of an enumeration value.</param> | ||
| /// <param name="targetType">The type of the target object, typically the type of the enumeration.</param> | ||
| /// <param name="parameter">An optional parameter for the conversion. Not used in this implementation.</param> | ||
| /// <param name="culture">The culture information to use during the conversion process.</param> | ||
| /// <return>The enumeration value corresponding to the input value.</return> | ||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| return Convert(value, targetType, parameter, culture); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Globalization; | ||
| using System.Resources; | ||
| using System.Windows.Data; | ||
| using NETworkManager.Localization.Resources; | ||
|
|
||
| namespace NETworkManager.Converters; | ||
|
|
||
| /// <summary> | ||
| /// A converter used to transform an <see cref="Enum"/> value into its corresponding string, | ||
| /// using localization resources for string mapping. Also provides functionality to convert | ||
| /// localized or raw string values back to the corresponding <see cref="Enum"/> value. | ||
| /// </summary> | ||
| /// <threadsafety> | ||
| /// This class is not guaranteed to be thread-safe. It should be used only in the context of the application’s | ||
| /// UI thread or with proper synchronization for shared use cases. | ||
| /// </threadsafety> | ||
| /// <seealso cref="IValueConverter"/> | ||
| public sealed class EnumToStringConverter : IValueConverter | ||
| { | ||
| /// Converts an enumeration value to its localized string representation and vice versa. | ||
| /// <param name="value"> | ||
| /// The value to convert. This can be an enumeration value or a string. | ||
| /// </param> | ||
| /// <param name="targetType"> | ||
| /// The expected type of the target binding, typically the type of the enumeration being converted. | ||
| /// </param> | ||
| /// <param name="parameter"> | ||
| /// An optional parameter to use in the conversion process, if applicable. | ||
| /// </param> | ||
| /// <param name="culture"> | ||
| /// The culture information to use during the conversion, affecting localization. | ||
| /// </param> | ||
| /// <return> | ||
| /// A string representing the localized name of the enumeration, or the enumeration corresponding | ||
| /// to the given string. If the conversion fails, a fallback enumeration value or string is returned. | ||
| /// </return> | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| if (value is not Enum enumValue) | ||
| { | ||
| string fallback = Enum.ToObject(targetType, 255) as string; | ||
| if (value is not string strVal) | ||
| return fallback; | ||
|
Comment on lines
+41
to
+45
|
||
| fallback = strVal; | ||
| ResourceSet resourceSet = Strings.ResourceManager.GetResourceSet(Strings.Culture, | ||
| false, true); | ||
| string foundKey = null; | ||
| if (resourceSet is null) | ||
| return fallback; | ||
| foreach (DictionaryEntry item in resourceSet) | ||
| { | ||
| if (item.Value as string != strVal && item.Key as string != strVal) | ||
| continue; | ||
| foundKey = item.Key as string; | ||
| break; | ||
| } | ||
|
|
||
| if (foundKey is null || !Enum.TryParse(targetType, foundKey, out var result)) | ||
| return fallback; | ||
| return result; | ||
| } | ||
|
Comment on lines
+60
to
+63
|
||
|
|
||
| var enumString = Enum.GetName(enumValue.GetType(), value); | ||
| if (enumString is null) | ||
| return string.Empty; | ||
| return Strings.ResourceManager.GetString(enumString, Strings.Culture) ?? enumString; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Converts a value back from a string representation to its corresponding enumeration value. | ||
| /// </summary> | ||
| /// <param name="value">The value to be converted back. Expected to be a string representation of an enumeration.</param> | ||
| /// <param name="targetType">The type of the enumeration to which the value will be converted.</param> | ||
| /// <param name="parameter">An optional parameter that can be used for custom conversion logic.</param> | ||
| /// <param name="culture">The culture information to use during the conversion process.</param> | ||
| /// <returns> | ||
| /// Returns the enumeration value corresponding to the string representation. If the conversion fails, | ||
| /// a default value of the enumeration is returned. | ||
| /// </returns> | ||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| { | ||
| return Convert(value, targetType, parameter, culture); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With
ConvertBackcallingConvert, converting an int back to an enum will hittargetType.IsEnumand return a string enum name rather than an enum value. This will break two-way bindings. ConvertBack should map an index/name back to an enum value (e.g., Enum.GetValues(targetType).GetValue(index) or Enum.Parse) and return the enum instance.