From 1b27500231b0bc14aa362e03786dd8ef7e6cdca1 Mon Sep 17 00:00:00 2001 From: Ahmada Yusril Date: Tue, 23 Jul 2024 00:31:32 +0900 Subject: [PATCH] [PTRun][ValueGenerator]Add result entries showing how to use (#33490) ## Summary of the Pull Request Added usage suggestion in PTRun Value Generator. ## Detailed Description of the Pull Request / Additional comments Added dropdown and give a basic description about the usage of value generator ![image](https://github.com/microsoft/PowerToys/assets/24465401/2f9e01d1-1f5a-42b5-9234-f768b27124db) Using fuzzy match to filter relevant queries ![image](https://github.com/microsoft/PowerToys/assets/24465401/dd0594bb-328a-4a8d-9d7c-e3b5732a8573) --------- Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com> --- .github/actions/spell-check/expect.txt | 1 + .../GeneratorData.cs | 15 ++ .../Helper/QueryHelper.cs | 173 ++++++++++++++++++ .../InputParser.cs | 6 +- .../Main.cs | 81 +++++++- .../Properties/Resources.Designer.cs | 153 ++++++++++++++++ .../Properties/Resources.resx | 54 ++++++ 7 files changed, 477 insertions(+), 6 deletions(-) create mode 100644 src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GeneratorData.cs create mode 100644 src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Helper/QueryHelper.cs diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index e8e400bf59..27bfb943ab 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1686,6 +1686,7 @@ USESHOWWINDOW USESTDHANDLES USRDLL UType +uuidv uwp uxtheme vabdq diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GeneratorData.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GeneratorData.cs new file mode 100644 index 0000000000..207a32ee23 --- /dev/null +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GeneratorData.cs @@ -0,0 +1,15 @@ +// 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. + +namespace Community.PowerToys.Run.Plugin.ValueGenerator +{ + internal sealed class GeneratorData + { + public string Keyword { get; set; } + + public string Description { get; set; } + + public string Example { get; set; } + } +} diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Helper/QueryHelper.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Helper/QueryHelper.cs new file mode 100644 index 0000000000..36289fb402 --- /dev/null +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Helper/QueryHelper.cs @@ -0,0 +1,173 @@ +// 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.Collections.Generic; +using System.Globalization; +using System.Text; +using Community.PowerToys.Run.Plugin.ValueGenerator.Properties; + +namespace Community.PowerToys.Run.Plugin.ValueGenerator.Helper +{ + /// + /// Helper class to easier work with queries + /// + internal static class QueryHelper + { + /// + /// a list of all value generator descriptions + /// + private static readonly string GeneratorDescriptionUuid = Resources.generator_description_uuid; + private static readonly string GeneratorDescriptionUuidv1 = Resources.generator_description_uuidv1; + private static readonly string GeneratorDescriptionUuidv3 = Resources.generator_description_uuidv3; + private static readonly string GeneratorDescriptionUuidv4 = Resources.generator_description_uuidv4; + private static readonly string GeneratorDescriptionUuidv5 = Resources.generator_description_uuidv5; + private static readonly string GeneratorDescriptionHash = Resources.generator_description_hash; + private static readonly string GeneratorDescriptionBase64 = Resources.generator_description_base64; + private static readonly string GeneratorDescriptionBase64d = Resources.generator_description_base64d; + private static readonly string GeneratorDescriptionUrl = Resources.generator_description_url; + private static readonly string GeneratorDescriptionUrld = Resources.generator_description_urld; + private static readonly string GeneratorDescriptionEscData = Resources.generator_description_esc_data; + private static readonly string GeneratorDescriptionUescData = Resources.generator_description_uesc_data; + private static readonly string GeneratorDescriptionEscHex = Resources.generator_description_esc_hex; + private static readonly string GeneratorDescriptionUescHex = Resources.generator_description_uesc_hex; + private static readonly string GeneratorDescriptionYourInput = Resources.generator_description_your_input; + private static readonly string GeneratorExample = Resources.generator_example; + private static readonly string Or = Resources.or; + + private static string GetStringFormat(string value, string arg) + { + return string.Format(CultureInfo.CurrentCulture, value, arg); + } + + private static string GetStringFormat(string value) + { + return string.Format(CultureInfo.CurrentCulture, value); + } + + internal static string GetResultTitle(GeneratorData generatorData) + { + return $"{generatorData.Keyword} - {generatorData.Description}"; + } + + internal static string GetResultSubtitle(GeneratorData generatorData) + { + return GetStringFormat(GeneratorExample, generatorData.Example); + } + + /// + /// A list that contain all of the value generators and its descriptions + /// + internal static readonly List GeneratorDataList = + [ + new() + { + Keyword = "uuid", + Description = GetStringFormat(GeneratorDescriptionUuid), + Example = $"uuid {GetStringFormat(Or)} guid", + }, + new() + { + Keyword = "uuidv1", + Description = GetStringFormat(GeneratorDescriptionUuidv1), + Example = $"uuidv1 {GetStringFormat(Or)} uuid1", + }, + new() + { + Keyword = "uuidv3", + Description = GetStringFormat(GeneratorDescriptionUuidv3), + Example = $"uuidv3 ns: <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "uuidv4", + Description = GetStringFormat(GeneratorDescriptionUuidv4), + Example = $"uuidv4 {GetStringFormat(Or)} uuid4", + }, + new() + { + Keyword = "uuidv5", + Description = GetStringFormat(GeneratorDescriptionUuidv5), + Example = $"uuidv5 ns: <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "md5", + Description = GetStringFormat(GeneratorDescriptionHash, "MD5"), + Example = $"md5 <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "sha1", + Description = GetStringFormat(GeneratorDescriptionHash, "SHA1"), + Example = $"sha1 <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "sha256", + Description = GetStringFormat(GeneratorDescriptionHash, "SHA256"), + Example = $"sha256 <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "sha384", + Description = GetStringFormat(GeneratorDescriptionHash, "SHA384"), + Example = $"sha384 <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "sha512", + Description = GetStringFormat(GeneratorDescriptionHash, "SHA512"), + Example = $"sha512 <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "base64", + Description = GetStringFormat(GeneratorDescriptionBase64), + Example = $"base64 <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "base64d", + Description = GetStringFormat(GeneratorDescriptionBase64d), + Example = $"base64d <{GetStringFormat(GeneratorDescriptionYourInput)}>", + }, + new() + { + Keyword = "url", + Description = GetStringFormat(GeneratorDescriptionUrl), + Example = "url https://bing.com/?q=My Test query", + }, + new() + { + Keyword = "urld", + Description = GetStringFormat(GeneratorDescriptionUrld), + Example = "urld https://bing.com/?q=My+Test+query", + }, + new() + { + Keyword = "esc:data", + Description = GetStringFormat(GeneratorDescriptionEscData), + Example = "esc:data C:\\Program Files\\PowerToys\\PowerToys.exe", + }, + new() + { + Keyword = "uesc:data", + Description = GetStringFormat(GeneratorDescriptionUescData), + Example = "uesc:data C%3A%5CProgram%20Files%5CPowerToys%5CPowerToys.exe", + }, + new() + { + Keyword = "esc:hex", + Description = GetStringFormat(GeneratorDescriptionEscHex), + Example = "esc:hex z", + }, + new() + { + Keyword = "uesc:hex", + Description = GetStringFormat(GeneratorDescriptionUescHex), + Example = "uesc:hex %7A", + }, + ]; + } +} diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs index 929366f597..514717a8f6 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs @@ -64,7 +64,7 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator algorithmName = HashAlgorithmName.SHA512; break; default: - throw new ArgumentException("Unknown SHA variant. Supported variants: SHA1, SHA256, SHA384, SHA512"); + throw new FormatException("Unknown SHA variant. Supported variants: SHA1, SHA256, SHA384, SHA512"); } if (content == string.Empty) @@ -93,7 +93,7 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator if (!int.TryParse(versionQuery, null, out version)) { - throw new ArgumentException("Could not determine requested GUID version"); + throw new FormatException("Could not determine requested GUID version. Supported versions are 1, 3, 4 and 5"); } } @@ -103,7 +103,7 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator if (sParameters.Length != 2) { - throw new ArgumentException("GUID versions 3 and 5 require 2 parameters - a namespace GUID and a name"); + throw new ArgumentException($"GUID version {version} require 2 parameters - a namespace GUID and a name.\nExample: uuidv{version} ns: "); } string namespaceParameter = sParameters[0]; diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Main.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Main.cs index 1ed2186063..4886a8db17 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Main.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Main.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; using System.Windows; +using Community.PowerToys.Run.Plugin.ValueGenerator.Helper; using Community.PowerToys.Run.Plugin.ValueGenerator.Properties; using ManagedCommon; +using Wox.Infrastructure; using Wox.Plugin; using Wox.Plugin.Logger; @@ -59,6 +61,19 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator } } + private static string GetIcoPath(bool isWarning = false) + { + var imageName = isWarning ? "Warning" : "ValueGenerator"; + if (_isLightTheme) + { + return $"Images/{imageName}.light.png"; + } + else + { + return $"Images/{imageName}.dark.png"; + } + } + protected virtual void Dispose(bool disposing) { if (!_disposed) @@ -90,6 +105,11 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator ArgumentNullException.ThrowIfNull(query); var results = new List(); + if (string.IsNullOrWhiteSpace(query?.Search) && !string.IsNullOrEmpty(query?.ActionKeyword)) + { + return GetSuggestionResults(query, results); + } + try { IComputeRequest computeRequest = _inputParser.ParseInput(query); @@ -110,7 +130,33 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator } catch (FormatException e) { - Log.Debug(GetTranslatedPluginTitle() + ": " + e.Message, GetType()); + Log.Debug(GetTranslatedPluginTitle() + ": " + e.Message, GetType()); + if (!string.IsNullOrEmpty(query.ActionKeyword)) + { + return GetSuggestionFuzzyResults(query, results); + } + } + + return results; + } + + private List GetSuggestionResults(Query query, List results) + { + foreach (var generatorData in QueryHelper.GeneratorDataList) + { + results.Add(new Result + { + Title = QueryHelper.GetResultTitle(generatorData), + SubTitle = QueryHelper.GetResultSubtitle(generatorData), + IcoPath = GetIcoPath(), + ToolTipData = new ToolTipData(QueryHelper.GetResultTitle(generatorData), QueryHelper.GetResultSubtitle(generatorData)), + QueryTextDisplay = generatorData.Keyword + " ", + Action = c => + { + _context.API.ChangeQuery($"{query.ActionKeyword} {generatorData.Keyword} ", true); + return false; + }, + }); } return results; @@ -124,7 +170,7 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator { ContextData = request.Result, Title = request.ResultToString(), - IcoPath = _isLightTheme ? "Images/ValueGenerator.light.png" : "Images/ValueGenerator.dark.png", + IcoPath = GetIcoPath(), Score = 300, SubTitle = request.Description, Action = c => @@ -150,13 +196,42 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator }; } + private List GetSuggestionFuzzyResults(Query query, List results) + { + foreach (var generatorData in QueryHelper.GeneratorDataList) + { + var matchScore = StringMatcher.FuzzySearch(query.Search.Trim(), generatorData.Keyword).Score; + + if (matchScore > 0) + { + results.Add(new Result + { + Title = QueryHelper.GetResultTitle(generatorData), + SubTitle = QueryHelper.GetResultSubtitle(generatorData), + IcoPath = GetIcoPath(), + Score = matchScore, + ToolTipData = new ToolTipData(QueryHelper.GetResultTitle(generatorData), QueryHelper.GetResultSubtitle(generatorData)), + QueryTextDisplay = generatorData.Keyword + " ", + Action = c => + { + _context.API.ChangeQuery($"{query.ActionKeyword} {generatorData.Keyword} ", true); + return false; + }, + }); + } + } + + return results; + } + private Result GetErrorResult(string errorMessage) { return new Result { Title = Resources.error_title, SubTitle = errorMessage, - IcoPath = _isLightTheme ? "Images/Warning.light.png" : "Images/Warning.dark.png", + ToolTipData = new ToolTipData(Resources.error_title, errorMessage), + IcoPath = GetIcoPath(isWarning: true), Action = _ => { return true; }, }; } diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.Designer.cs index 9cb1595c27..90c3adeff5 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.Designer.cs @@ -87,6 +87,159 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator.Properties { } } + /// + /// Looks up a localized string similar to Encode a string with Base64. + /// + public static string generator_description_base64 { + get { + return ResourceManager.GetString("generator_description_base64", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Decode a string with Base64. + /// + public static string generator_description_base64d { + get { + return ResourceManager.GetString("generator_description_base64d", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Escape a data string. + /// + public static string generator_description_esc_data { + get { + return ResourceManager.GetString("generator_description_esc_data", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Escape a single hex character. + /// + public static string generator_description_esc_hex { + get { + return ResourceManager.GetString("generator_description_esc_hex", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hash a string with {0}. + /// + public static string generator_description_hash { + get { + return ResourceManager.GetString("generator_description_hash", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unescape a data string. + /// + public static string generator_description_uesc_data { + get { + return ResourceManager.GetString("generator_description_uesc_data", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unescape a single hex character. + /// + public static string generator_description_uesc_hex { + get { + return ResourceManager.GetString("generator_description_uesc_hex", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Encode a URL. + /// + public static string generator_description_url { + get { + return ResourceManager.GetString("generator_description_url", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Decode a URL. + /// + public static string generator_description_urld { + get { + return ResourceManager.GetString("generator_description_urld", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate a random UUID. + /// + public static string generator_description_uuid { + get { + return ResourceManager.GetString("generator_description_uuid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate a version 1: Time based UUID. + /// + public static string generator_description_uuidv1 { + get { + return ResourceManager.GetString("generator_description_uuidv1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate a version 3 (MD5): Namespace and name based UUID. + /// + public static string generator_description_uuidv3 { + get { + return ResourceManager.GetString("generator_description_uuidv3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate a version 4: Randomly generated UUID. + /// + public static string generator_description_uuidv4 { + get { + return ResourceManager.GetString("generator_description_uuidv4", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate a version 5 (SHA1): Namespace and name based UUID. + /// + public static string generator_description_uuidv5 { + get { + return ResourceManager.GetString("generator_description_uuidv5", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to your input. + /// + public static string generator_description_your_input { + get { + return ResourceManager.GetString("generator_description_your_input", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Example: {0}. + /// + public static string generator_example { + get { + return ResourceManager.GetString("generator_example", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to or. + /// + public static string or { + get { + return ResourceManager.GetString("or", resourceCulture); + } + } + /// /// Looks up a localized string similar to Calculates hashes and generate values. /// diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.resx b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.resx index d7ae6bd97c..1daf99ab71 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.resx @@ -126,6 +126,60 @@ Value Generator Error + + Encode a string with Base64 + + + Decode a string with Base64 + + + Escape a data string + + + Escape a single hex character + + + Hash a string with {0} + + + Unescape a data string + + + Unescape a single hex character + + + Encode a URL + + + Decode a URL + + + Generate a random UUID + + + Generate a version 1: Time based UUID + + + Generate a version 3 (MD5): Namespace and name based UUID + + + Generate a version 4: Randomly generated UUID + + + Generate a version 5 (SHA1): Namespace and name based UUID + + + your input + Usage example: "md5 <your input>" + + + Example: {0} + The arg following is the usage example + + + or + Used to indicate alternatives or options available + Calculates hashes and generate values