Skip to content

Commit

Permalink
[RegistryPreview]Copy context menu, data tooltip, MULTI_SZ fix (#36631)
Browse files Browse the repository at this point in the history
* add context menus

* string resources for contextmenu

* fix line break parsing for MULTI_SZ

* better presentation of multiline values and value tooltip

* cleanup
  • Loading branch information
htcfreek authored Jan 17, 2025
1 parent e7abd34 commit 44f170d
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;

namespace RegistryPreviewUILib
{
/// <summary>
/// Helper class to centralize clipboard actions
/// </summary>
internal static class ClipboardHelper
{
internal static void CopyToClipboardAction(string text)
{
try
{
var data = new DataPackage();
data.SetText(text);
Clipboard.SetContent(data);
Clipboard.Flush();
}
catch
{
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using Windows.ApplicationModel.DataTransfer;

namespace RegistryPreviewUILib
{
/// <summary>
Expand All @@ -28,5 +32,19 @@ public RegistryKey(string name, string fullPath, string image, string toolTipTex
this.Image = image;
this.ToolTipText = toolTipText;
}

public ICommand CopyToClipboardName_Click => new RelayCommand(CopyToClipboardName);

public ICommand CopyToClipboardKeyPath_Click => new RelayCommand(CopyToClipboardKeyPath);

private void CopyToClipboardName()
{
ClipboardHelper.CopyToClipboardAction(Name);
}

private void CopyToClipboardKeyPath()
{
ClipboardHelper.CopyToClipboardAction(FullPath);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace RegistryPreviewUILib
public sealed partial class RegistryPreviewMainPage : Page
{
private static SemaphoreSlim _dialogSemaphore = new(1);
private string lastKeyPath;

public delegate void UpdateWindowTitleFunction(string title);

Expand Down Expand Up @@ -261,6 +262,7 @@ private bool ParseRegistryFile(string filenameText)
registryLine = StripFirstAndLast(registryLine);

treeViewNode = AddTextToTree(registryLine, imageName);
lastKeyPath = registryLine;
}
else if (registryLine.StartsWith('"') && registryLine.EndsWith("=-", StringComparison.InvariantCulture))
{
Expand All @@ -271,7 +273,7 @@ private bool ParseRegistryFile(string filenameText)
registryLine = StripFirstAndLast(registryLine);

// Create a new listview item that will be used to display the delete value and store it
registryValue = new RegistryValue(registryLine, string.Empty, string.Empty);
registryValue = new RegistryValue(registryLine, string.Empty, string.Empty, lastKeyPath);
SetValueToolTip(registryValue);

// store the ListViewItem, if we have a valid Key to attach to
Expand Down Expand Up @@ -310,7 +312,7 @@ private bool ParseRegistryFile(string filenameText)
value = value.Trim();

// Create a new listview item that will be used to display the value
registryValue = new RegistryValue(name, "REG_SZ", string.Empty);
registryValue = new RegistryValue(name, "REG_SZ", string.Empty, lastKeyPath);

// if the first character is a " then this is a string value, so find the last most " which will avoid comments
if (value.StartsWith('"'))
Expand Down Expand Up @@ -553,19 +555,10 @@ private bool ParseRegistryFile(string filenameText)
var bytes = value.Split(',').Select(
c => c.Length == 2 ? byte.Parse(c, NumberStyles.HexNumber, CultureInfo.InvariantCulture) : throw null).ToArray();

if (registryValue.Type == "REG_MULTI_SZ")
{
// Replace zeros (00,00) with spaces
for (int i = 0; i < bytes.Length; i += 2)
{
if (bytes[i] == 0 && bytes[i + 1] == 0)
{
bytes[i] = 0x20;
}
}
}

value = Encoding.Unicode.GetString(bytes);

// Correctly format line breaks and remove trailing line breaks. (GitHub PowerToys #36629)
value = value.Replace('\0', '\r').TrimEnd('\r');
}
catch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@
IsTabStop="False"
Orientation="Horizontal"
Spacing="8">
<StackPanel.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="ContextMenu_CopyName" Command="{Binding Content.CopyToClipboardName_Click}" />
<MenuFlyoutItem x:Uid="ContextMenu_CopyKeyPath" Command="{Binding Content.CopyToClipboardKeyPath_Click}" />
</MenuFlyout>
</StackPanel.ContextFlyout>
<Image
MaxWidth="16"
MaxHeight="16"
Expand Down Expand Up @@ -208,6 +214,14 @@
VerticalAlignment="Center"
Orientation="Horizontal"
Spacing="8">
<StackPanel.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="ContextMenu_CopyName" Command="{Binding CopyToClipboardName_Click}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem x:Uid="ContextMenu_CopyValue" Command="{Binding CopyToClipboardEntry_Click}" />
<MenuFlyoutItem x:Uid="ContextMenu_CopyValueWithPath" Command="{Binding CopyToClipboardWithPath_Click}" />
</MenuFlyout>
</StackPanel.ContextFlyout>
<Image
MaxWidth="16"
MaxHeight="16"
Expand All @@ -226,12 +240,49 @@
x:Uid="TypeColumn"
Width="Auto"
Binding="{Binding Type}"
FontSize="{StaticResource CaptionTextBlockFontSize}" />
<tk7controls:DataGridTextColumn
FontSize="{StaticResource CaptionTextBlockFontSize}">
<tk7controls:DataGridTextColumn.CellStyle>
<Style TargetType="tk7controls:DataGridCell">
<Setter Property="ContextFlyout">
<Setter.Value>
<MenuFlyout>
<MenuFlyoutItem x:Uid="ContextMenu_CopyType" Command="{Binding CopyToClipboardType_Click}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem x:Uid="ContextMenu_CopyValue" Command="{Binding CopyToClipboardEntry_Click}" />
<MenuFlyoutItem x:Uid="ContextMenu_CopyValueWithPath" Command="{Binding CopyToClipboardWithPath_Click}" />
</MenuFlyout>
</Setter.Value>
</Setter>
</Style>
</tk7controls:DataGridTextColumn.CellStyle>
</tk7controls:DataGridTextColumn>
<tk7controls:DataGridTemplateColumn
x:Uid="ValueColumn"
Width="Auto"
Binding="{Binding Value}"
FontSize="{StaticResource CaptionTextBlockFontSize}" />
IsReadOnly="True">
<tk7controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel
Margin="4"
VerticalAlignment="Center"
Orientation="Horizontal">
<StackPanel.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="ContextMenu_CopyData" Command="{Binding CopyToClipboardData_Click}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem x:Uid="ContextMenu_CopyValue" Command="{Binding CopyToClipboardEntry_Click}" />
<MenuFlyoutItem x:Uid="ContextMenu_CopyValueWithPath" Command="{Binding CopyToClipboardWithPath_Click}" />
</MenuFlyout>
</StackPanel.ContextFlyout>
<TextBlock
IsTabStop="False"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding ValueOneLine}"
ToolTipService.ToolTip="{Binding Value}" />
</StackPanel>
</DataTemplate>
</tk7controls:DataGridTemplateColumn.CellTemplate>
</tk7controls:DataGridTemplateColumn>
</tk7controls:DataGrid.Columns>
</tk7controls:DataGrid>
</Border>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Windows.ApplicationModel.Resources;
using Windows.ApplicationModel.DataTransfer;

namespace RegistryPreviewUILib
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using Microsoft.UI.Xaml;
using Windows.ApplicationModel.DataTransfer;

namespace RegistryPreviewUILib
{
Expand All @@ -17,12 +21,16 @@ public class RegistryValue
private static Uri uriDeleteValue = new Uri("ms-appx:///Assets/RegistryPreview/deleted-value32.png");
private static Uri uriErrorValue = new Uri("ms-appx:///Assets/RegistryPreview/error32.png");

public string Key { get; set; }

public string Name { get; set; }

public string Type { get; set; }

public string Value { get; set; }

public string ValueOneLine => Value.Replace('\r', ' ');

public string ToolTipText { get; set; }

public Uri ImageUri
Expand All @@ -46,12 +54,49 @@ public Uri ImageUri
}
}

public RegistryValue(string name, string type, string value)
public RegistryValue(string name, string type, string value, string key)
{
this.Name = name;
this.Type = type;
this.Value = value;
this.ToolTipText = string.Empty;
this.Key = key;
}

// Commands
public ICommand CopyToClipboardEntry_Click => new RelayCommand(CopyToClipboardEntry);

public ICommand CopyToClipboardWithPath_Click => new RelayCommand(CopyToClipboardEntryWithPath);

public ICommand CopyToClipboardName_Click => new RelayCommand(CopyToClipboardName);

public ICommand CopyToClipboardType_Click => new RelayCommand(CopyToClipboardType);

public ICommand CopyToClipboardData_Click => new RelayCommand(CopyToClipboardData);

private void CopyToClipboardEntry()
{
ClipboardHelper.CopyToClipboardAction($"{Name}\r\n{Type}\r\n{Value}");
}

private void CopyToClipboardEntryWithPath()
{
ClipboardHelper.CopyToClipboardAction($"{Key}\r\n{Name}\r\n{Type}\r\n{Value}");
}

private void CopyToClipboardName()
{
ClipboardHelper.CopyToClipboardAction(Name);
}

private void CopyToClipboardType()
{
ClipboardHelper.CopyToClipboardAction(Type);
}

private void CopyToClipboardData()
{
ClipboardHelper.CopyToClipboardAction(Value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,28 @@
<data name="ZeroLength" xml:space="preserve">
<value>(zero-length binary value)</value>
</data>
<data name="ContextMenu_CopyKeyPath.Text" xml:space="preserve">
<value>Copy path</value>
<comment>Like "Copy item"</comment>
</data>
<data name="ContextMenu_CopyName.Text" xml:space="preserve">
<value>Copy name</value>
<comment>Like "Copy item"</comment>
</data>
<data name="ContextMenu_CopyType.Text" xml:space="preserve">
<value>Copy type</value>
<comment>Like "Copy item"</comment>
</data>
<data name="ContextMenu_CopyData.Text" xml:space="preserve">
<value>Copy data</value>
<comment>Like "Copy item"</comment>
</data>
<data name="ContextMenu_CopyValue.Text" xml:space="preserve">
<value>Copy value</value>
<comment>Like "Copy item"</comment>
</data>
<data name="ContextMenu_CopyValueWithPath.Text" xml:space="preserve">
<value>Copy value with key path</value>
<comment>Like "Copy item"</comment>
</data>
</root>

0 comments on commit 44f170d

Please sign in to comment.