Skip to content

Commit 220d37e

Browse files
authored
Policies Library color tagging for AppControl Manager (#1118)
You can now tag policies in the library with colors to help with easy recognition or categorization of them. You can choose from a pre-defined set of colors or use the color picker to select any color you like.
1 parent c4cbc33 commit 220d37e

5 files changed

Lines changed: 296 additions & 1 deletion

File tree

AppControl Manager/MainWindow.xaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,47 @@
527527
</MenuFlyoutItem.Icon>
528528
</MenuFlyoutItem>
529529

530+
<MenuFlyoutSubItem x:Uid="SetColorMenuFlyoutSubItem">
531+
<MenuFlyoutSubItem.Icon>
532+
<FontIcon Glyph="&#xE8EC;" />
533+
</MenuFlyoutSubItem.Icon>
534+
<MenuFlyoutItem Text="Lavender" Tag="#FFFF64F7" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
535+
<MenuFlyoutItem.Icon>
536+
<FontIcon Glyph="&#xE8EC;" Foreground="#FFFF64F7"/>
537+
</MenuFlyoutItem.Icon>
538+
</MenuFlyoutItem>
539+
<MenuFlyoutItem Text="Teal" Tag="#FF3AFFD9" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
540+
<MenuFlyoutItem.Icon>
541+
<FontIcon Glyph="&#xE8EC;" Foreground="#FF3AFFD9"/>
542+
</MenuFlyoutItem.Icon>
543+
</MenuFlyoutItem>
544+
<MenuFlyoutItem Text="Gold" Tag="#FFFFD453" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
545+
<MenuFlyoutItem.Icon>
546+
<FontIcon Glyph="&#xE8EC;" Foreground="#FFFFD453"/>
547+
</MenuFlyoutItem.Icon>
548+
</MenuFlyoutItem>
549+
<MenuFlyoutItem Text="Rose" Tag="#FFFF5E91" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
550+
<MenuFlyoutItem.Icon>
551+
<FontIcon Glyph="&#xE8EC;" Foreground="#FFFF5E91"/>
552+
</MenuFlyoutItem.Icon>
553+
</MenuFlyoutItem>
554+
<MenuFlyoutItem Text="Aqua" Tag="#FFC0FFF3" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
555+
<MenuFlyoutItem.Icon>
556+
<FontIcon Glyph="&#xE8EC;" Foreground="#FFC0FFF3"/>
557+
</MenuFlyoutItem.Icon>
558+
</MenuFlyoutItem>
559+
<MenuFlyoutItem Text="Custom..." Tag="Custom" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
560+
<MenuFlyoutItem.Icon>
561+
<FontIcon Glyph="&#xE790;"/>
562+
</MenuFlyoutItem.Icon>
563+
</MenuFlyoutItem>
564+
<MenuFlyoutSeparator />
565+
<MenuFlyoutItem Text="None" Tag="Transparent" Click="OnSetPolicyColorClicked" DataContext="{x:Bind}">
566+
<MenuFlyoutItem.Icon>
567+
<FontIcon Glyph="&#xE894;"/>
568+
</MenuFlyoutItem.Icon>
569+
</MenuFlyoutItem>
570+
</MenuFlyoutSubItem>
530571
</MenuFlyout>
531572
</Grid.ContextFlyout>
532573

@@ -601,6 +642,7 @@
601642
<MenuFlyoutItem HorizontalAlignment="Stretch" Text="{x:Bind vm:ViewModelProvider.SidebarVM.SidebarPolicyConnect7Content, Mode=OneWay}" Visibility="{x:Bind vm:ViewModelProvider.SidebarVM.SidebarPolicyConnect7Visibility, Mode=OneWay}" Command="{x:Bind vm:ViewModelProvider.SidebarVM.SidebarPolicyConnect7Command, Mode=OneWay}" CommandParameter="{x:Bind}" />
602643

603644
</MenuFlyoutSubItem>
645+
604646
</MenuFlyout>
605647
</Button.Flyout>
606648

@@ -609,6 +651,7 @@
609651
<Grid.ColumnDefinitions>
610652
<ColumnDefinition Width="Auto"/>
611653
<ColumnDefinition Width="*"/>
654+
<ColumnDefinition Width="Auto"/>
612655
</Grid.ColumnDefinitions>
613656
<FontIcon Glyph="&#xEB51;" FontSize="14" VerticalAlignment="Center" />
614657
<TextBlock Grid.Column="1"
@@ -617,6 +660,13 @@
617660
TextWrapping="NoWrap"
618661
VerticalAlignment="Center"
619662
Style="{ThemeResource BodyStrongTextBlockStyle}"/>
663+
<!-- The Color Tag Indicator -->
664+
<FontIcon Grid.Column="2"
665+
Glyph="&#xE8EC;"
666+
Foreground="{x:Bind TagColorBrush, Mode=OneWay}"
667+
Visibility="{x:Bind IsTagVisible, Mode=OneWay}"
668+
FontSize="14"
669+
VerticalAlignment="Center"/>
620670
</Grid>
621671

622672
<Grid ColumnSpacing="5" HorizontalAlignment="Center">

AppControl Manager/MainWindow.xaml.cs

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,13 +1343,16 @@ private async Task ExecuteRemove(PolicyFileRepresent policyContext)
13431343
// If the library should be persistent
13441344
if (ViewModel.AppSettings.PersistentPoliciesLibrary)
13451345
{
1346-
await Task.Run(() =>
1346+
await Task.Run(async () =>
13471347
{
13481348
IEnumerable<string> currentFiles = Directory.EnumerateFiles(ViewModel.GetSidebarPoliciesLibraryCacheLocation(), $"{policyContext.UniqueObjID}.xml", enumerationOptionsForPoliciesLibraryRemoval);
13491349
foreach (string file in currentFiles)
13501350
{
13511351
File.Delete(file);
13521352
}
1353+
1354+
// Clean up the color tag cache to prevent orphaned entries
1355+
await ViewModel.RemoveColorFromCacheInternalAsync(policyContext.UniqueObjID);
13531356
});
13541357
}
13551358
}
@@ -1413,6 +1416,13 @@ await Task.Run(() =>
14131416
}
14141417
}
14151418
}
1419+
1420+
// Safely delete the entire color cache file since all policies are cleared
1421+
string cachePath = Path.Combine(ViewModel.GetSidebarPoliciesLibraryCacheLocation(), "PolicyColors.json");
1422+
if (File.Exists(cachePath))
1423+
{
1424+
File.Delete(cachePath);
1425+
}
14161426
});
14171427
}
14181428

@@ -1509,6 +1519,77 @@ private void OnCopyBasePolicyID(object sender, RoutedEventArgs e)
15091519
}
15101520
}
15111521

1522+
/// <summary>
1523+
/// Event handler for setting the tag color of a policy in the sidebar library.
1524+
/// </summary>
1525+
/// <param name="sender"></param>
1526+
/// <param name="e"></param>
1527+
private async void OnSetPolicyColorClicked(object sender, RoutedEventArgs e)
1528+
{
1529+
if (sender is MenuFlyoutItem { Tag: string colorTag, DataContext: PolicyFileRepresent policyContext })
1530+
{
1531+
// For None
1532+
if (string.Equals(colorTag, "Transparent", StringComparison.OrdinalIgnoreCase))
1533+
{
1534+
policyContext.TagColorBrush = new SolidColorBrush(Colors.Transparent);
1535+
policyContext.IsTagVisible = Visibility.Collapsed;
1536+
await ViewModel.UpdatePolicyColorAsync(policyContext.UniqueObjID, "Transparent");
1537+
}
1538+
// For Custom colors from the picker
1539+
else if (string.Equals(colorTag, "Custom", StringComparison.OrdinalIgnoreCase))
1540+
{
1541+
ColorPicker picker = new()
1542+
{
1543+
ColorSpectrumShape = ColorSpectrumShape.Ring,
1544+
IsMoreButtonVisible = true,
1545+
IsColorSliderVisible = true,
1546+
IsColorChannelTextInputVisible = true,
1547+
IsHexInputVisible = true,
1548+
IsAlphaEnabled = true,
1549+
IsAlphaSliderVisible = true,
1550+
IsAlphaTextInputVisible = true,
1551+
Opacity = 100,
1552+
Color = policyContext.TagColorBrush?.Color ?? Colors.White
1553+
};
1554+
1555+
// ScrollViewer for the content
1556+
ScrollViewer scrollViewer = new()
1557+
{
1558+
Content = picker,
1559+
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
1560+
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
1561+
Padding = new Thickness(16, 0, 16, 0)
1562+
};
1563+
1564+
using ContentDialogV2 dialog = new()
1565+
{
1566+
Title = "Select Custom Color",
1567+
Content = scrollViewer,
1568+
PrimaryButtonText = "Apply",
1569+
CloseButtonText = "Cancel",
1570+
};
1571+
1572+
if (await dialog.ShowAsync() == ContentDialogResult.Primary)
1573+
{
1574+
Windows.UI.Color selectedColor = picker.Color;
1575+
policyContext.TagColorBrush = new SolidColorBrush(selectedColor);
1576+
policyContext.IsTagVisible = Visibility.Visible;
1577+
1578+
string hexColor = $"#{selectedColor.A:X2}{selectedColor.R:X2}{selectedColor.G:X2}{selectedColor.B:X2}";
1579+
await ViewModel.UpdatePolicyColorAsync(policyContext.UniqueObjID, hexColor);
1580+
}
1581+
}
1582+
// For the pre-defined colors
1583+
else
1584+
{
1585+
Windows.UI.Color parsedColor = MainWindowVM.ParseColor(colorTag);
1586+
policyContext.TagColorBrush = new SolidColorBrush(parsedColor);
1587+
policyContext.IsTagVisible = Visibility.Visible;
1588+
await ViewModel.UpdatePolicyColorAsync(policyContext.UniqueObjID, colorTag);
1589+
}
1590+
}
1591+
}
1592+
15121593
/// <summary>
15131594
/// Event handler for when policies are dragged over the Sidebar's policies library.
15141595
/// </summary>

AppControl Manager/SiPolicy/PolicyFileRepresent.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
using System.Threading.Tasks;
2121
using AppControlManager.XMLOps;
2222
using Windows.System;
23+
using Microsoft.UI.Xaml.Media;
24+
using Microsoft.UI.Xaml;
25+
using System.Text.Json.Serialization;
26+
using System.Collections.Generic;
2327

2428
namespace AppControlManager.SiPolicy;
2529

@@ -61,6 +65,16 @@ internal SiPolicy PolicyObj
6165
/// </summary>
6266
internal string? FileName { get; set; }
6367

68+
/// <summary>
69+
/// The brush used to display the policy color tag indicator.
70+
/// </summary>
71+
internal SolidColorBrush? TagColorBrush { get; set => SP(ref field, value); }
72+
73+
/// <summary>
74+
/// The visibility of the policy color tag indicator.
75+
/// </summary>
76+
internal Visibility IsTagVisible { get; set => SP(ref field, value); } = Visibility.Collapsed;
77+
6478
/// <summary>
6579
/// Helper method to generate the identifier string.
6680
/// </summary>
@@ -121,3 +135,12 @@ internal enum PolicyFileRepresentKind
121135
P7B,
122136
BIN
123137
}
138+
139+
/// <summary>
140+
/// Source generator context for JSON serialization and deserialization of the Policies Library color tags.
141+
/// </summary>
142+
[JsonSourceGenerationOptions(WriteIndented = true)]
143+
[JsonSerializable(typeof(Dictionary<Guid, string>))]
144+
internal sealed partial class PolicyColorsJsonContext : JsonSerializerContext
145+
{
146+
}

AppControl Manager/Strings/en-US/Resources.resw

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7119,4 +7119,13 @@ NOTE: This option is always enforced if any App Control UMCI policy enables it.
71197119
<data name="DenyMenuFlyoutSubItem.ToolTipService.ToolTip" xml:space="preserve">
71207120
<value>Create Deny rules for the selected items and add them to the selected policy.</value>
71217121
</data>
7122+
<data name="SetColorMenuFlyoutSubItem.Text" xml:space="preserve">
7123+
<value>Set Color</value>
7124+
</data>
7125+
<data name="SetColorMenuFlyoutSubItem.AutomationProperties.HelpText" xml:space="preserve">
7126+
<value>Set a color to the policy in the library as a way of tagging it.</value>
7127+
</data>
7128+
<data name="SetColorMenuFlyoutSubItem.ToolTipService.ToolTip" xml:space="preserve">
7129+
<value>Set a color to the policy in the library as a way of tagging it.</value>
7130+
</data>
71227131
</root>

0 commit comments

Comments
 (0)