ResultHelper.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections.Generic; 7 using System.Diagnostics; 8 using System.Globalization; 9 using System.Linq; 10 using System.Text; 11 using Microsoft.CmdPal.Ext.WindowsSettings.Commands; 12 using Microsoft.CmdPal.Ext.WindowsSettings.Helpers; 13 using Microsoft.CmdPal.Ext.WindowsSettings.Properties; 14 using Microsoft.CommandPalette.Extensions.Toolkit; 15 16 namespace Microsoft.CmdPal.Ext.WindowsSettings; 17 18 /// <summary> 19 /// Helper class to easier work with List Items 20 /// </summary> 21 internal static class ResultHelper 22 { 23 internal static List<ListItem> GetResultList( 24 in IEnumerable<Classes.WindowsSetting> list) 25 { 26 var resultList = new List<ListItem>(list.Count()); 27 28 foreach (var entry in list) 29 { 30 var result = new ListItem(new OpenSettingsCommand(entry)) 31 { 32 Icon = Icons.WindowsSettingsIcon, 33 Subtitle = entry.JoinedFullSettingsPath, 34 Title = entry.Name, 35 MoreCommands = ContextMenuHelper.GetContextMenu(entry).ToArray(), 36 }; 37 38 // TODO GH #126 investigate tooltips 39 // AddOptionalToolTip(entry, result); 40 41 // There is a case with MMC snap-ins where we don't have .msc files fort them. Then we need to show the note for this results in subtitle too. 42 // These results have mmc.exe as command and their note property is filled. 43 if (entry.Command == "mmc.exe" && !string.IsNullOrEmpty(entry.Note)) 44 { 45 result.Subtitle += $"\u0020\u0020\u002D\u0020\u0020{Resources.Note}: {entry.Note}"; // "\u0020\u0020\u002D\u0020\u0020" = "<space><space><minus><space><space>" 46 } 47 48 // To not show duplicate entries we check the existing results on the list before adding the new entry. Example: Device Manager entry for Control Panel and Device Manager entry for MMC. 49 if (!resultList.Any(x => x.Title == result.Title)) 50 { 51 resultList.Add(result); 52 } 53 } 54 55 // TODO GH #127 --> Investigate scoring 56 57 // SetScores(resultList, query); 58 return resultList; 59 } 60 61 /// <summary> 62 /// Checks if a setting <see cref="WindowsSetting"/> matches the search string <see cref="Query.Search"/> to filter settings by settings path. 63 /// This method is called from the <see cref="Predicate{T}"/> method in <see cref="Main.Query(Query)"/> if the search string <see cref="Query.Search"/> contains the character ">". 64 /// </summary> 65 /// <param name="found">The WindowsSetting's result that should be checked.</param> 66 /// <param name="queryString">The searchString entered by the user <see cref="Query.Search"/>s.</param> 67 internal static bool FilterBySettingsPath(in Classes.WindowsSetting found, in string queryString) 68 { 69 if (!queryString.Contains('>')) 70 { 71 return false; 72 } 73 74 // Init vars 75 var queryElements = queryString.Split('>'); 76 77 List<string> settingsPath = new List<string>(); 78 settingsPath.Add(found.Type); 79 if (!(found.Areas is null)) 80 { 81 settingsPath.AddRange(found.Areas); 82 } 83 84 // Compare query and settings path 85 for (var i = 0; i < queryElements.Length; i++) 86 { 87 if (string.IsNullOrWhiteSpace(queryElements[i])) 88 { 89 // The queryElement is an WhiteSpace. Nothing to compare. 90 break; 91 } 92 93 if (i < settingsPath.Count) 94 { 95 if (!settingsPath[i].StartsWith(queryElements[i], StringComparison.CurrentCultureIgnoreCase)) 96 { 97 return false; 98 } 99 } 100 else 101 { 102 // The user has entered more query parts than existing elements in settings path. 103 return false; 104 } 105 } 106 107 // Return "true" if <found> matches <queryString>. 108 return true; 109 } 110 }