mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 17:56:44 +02:00
Adding fallback command for Windows Settings extension (#40331)
Two changes: - Added a new fallback command for Windows Settings extension. If only one setting or one exact match for the query was found, display that setting in the list and open that setting on <Enter>. If more than one setting was found, display a message to open Windows Settings to see the search results for your query.    - Modified the titles/subtitles of the extension to pull from Resources to aid in internationalization. Closes: #38548 and possibly #40308
This commit is contained in:
@@ -22,8 +22,7 @@ namespace Microsoft.CmdPal.Ext.WindowsSettings;
|
||||
internal static class ResultHelper
|
||||
{
|
||||
internal static List<ListItem> GetResultList(
|
||||
in IEnumerable<Classes.WindowsSetting> list,
|
||||
string query)
|
||||
in IEnumerable<Classes.WindowsSetting> list)
|
||||
{
|
||||
var resultList = new List<ListItem>(list.Count());
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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 Microsoft.CmdPal.Ext.WindowsSettings.Classes;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
|
||||
|
||||
internal static class ScoringHelper
|
||||
{
|
||||
// Rank settings by how they matched the search query. Order is:
|
||||
// 1. Exact Name (10 points)
|
||||
// 2. Name Starts With (8 points)
|
||||
// 3. Name (5 points)
|
||||
// 4. Area (4 points)
|
||||
// 5. AltName (2 points)
|
||||
// 6. Settings path (1 point)
|
||||
internal static (WindowsSetting Setting, int Score) SearchScoringPredicate(string query, WindowsSetting setting)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
// If no search string is entered skip query comparison.
|
||||
return (setting, 0);
|
||||
}
|
||||
|
||||
if (string.Equals(setting.Name, query, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return (setting, 10);
|
||||
}
|
||||
|
||||
if (setting.Name.StartsWith(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 8);
|
||||
}
|
||||
|
||||
if (setting.Name.Contains(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 5);
|
||||
}
|
||||
|
||||
if (!(setting.Areas is null))
|
||||
{
|
||||
foreach (var area in setting.Areas)
|
||||
{
|
||||
// Search for areas on normal queries.
|
||||
if (area.Contains(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 4);
|
||||
}
|
||||
|
||||
// Search for Area only on queries with action char.
|
||||
if (area.Contains(query.Replace(":", string.Empty), StringComparison.CurrentCultureIgnoreCase)
|
||||
&& query.EndsWith(":", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(setting.AltNames is null))
|
||||
{
|
||||
foreach (var altName in setting.AltNames)
|
||||
{
|
||||
if (altName.Contains(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search by key char '>' for app name and settings path
|
||||
if (query.Contains('>') && ResultHelper.FilterBySettingsPath(setting, query))
|
||||
{
|
||||
return (setting, 1);
|
||||
}
|
||||
|
||||
return (setting, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Classes;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Commands;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Properties;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsSettings.Pages;
|
||||
|
||||
internal sealed partial class FallbackWindowsSettingsItem : FallbackCommandItem
|
||||
{
|
||||
private readonly Classes.WindowsSettings _windowsSettings;
|
||||
|
||||
private readonly string _title = Resources.settings_fallback_title;
|
||||
private readonly string _subtitle = Resources.settings_fallback_subtitle;
|
||||
|
||||
public FallbackWindowsSettingsItem(Classes.WindowsSettings windowsSettings)
|
||||
: base(new NoOpCommand(), Resources.settings_title)
|
||||
{
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\WindowsSettings.svg");
|
||||
_windowsSettings = windowsSettings;
|
||||
}
|
||||
|
||||
public override void UpdateQuery(string query)
|
||||
{
|
||||
Command = new NoOpCommand();
|
||||
Title = string.Empty;
|
||||
Subtitle = string.Empty;
|
||||
Icon = null;
|
||||
MoreCommands = null;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(query) ||
|
||||
_windowsSettings?.Settings is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var filteredList = _windowsSettings.Settings
|
||||
.Select(setting => ScoringHelper.SearchScoringPredicate(query, setting))
|
||||
.Where(scoredSetting => scoredSetting.Score > 0)
|
||||
.OrderByDescending(scoredSetting => scoredSetting.Score);
|
||||
|
||||
if (!filteredList.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (filteredList.Count() == 1 ||
|
||||
filteredList.Any(a => a.Score == 10))
|
||||
{
|
||||
var setting = filteredList.First().Setting;
|
||||
|
||||
Title = setting.Name;
|
||||
Subtitle = setting.JoinedFullSettingsPath;
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\WindowsSettings.svg");
|
||||
Command = new OpenSettingsCommand(setting)
|
||||
{
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\WindowsSettings.svg"),
|
||||
Name = setting.Name,
|
||||
};
|
||||
|
||||
// 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.
|
||||
// These results have mmc.exe as command and their note property is filled.
|
||||
if (setting.Command == "mmc.exe" && !string.IsNullOrEmpty(setting.Note))
|
||||
{
|
||||
Subtitle += $"\u0020\u0020\u002D\u0020\u0020{Resources.Note}: {setting.Note}"; // "\u0020\u0020\u002D\u0020\u0020" = "<space><space><minus><space><space>"
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We found more than one result. Make our command take
|
||||
// us to the Windows Settings search page, prepopulated with this search.
|
||||
var settingsPage = new WindowsSettingsListPage(_windowsSettings, query);
|
||||
Title = string.Format(CultureInfo.CurrentCulture, _title, query);
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\WindowsSettings.svg");
|
||||
Subtitle = _subtitle;
|
||||
Command = settingsPage;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Classes;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
@@ -18,11 +20,17 @@ internal sealed partial class WindowsSettingsListPage : DynamicListPage
|
||||
public WindowsSettingsListPage(Classes.WindowsSettings windowsSettings)
|
||||
{
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\WindowsSettings.svg");
|
||||
Name = "Windows Settings";
|
||||
Name = Resources.settings_title;
|
||||
Id = "com.microsoft.cmdpal.windowsSettings";
|
||||
_windowsSettings = windowsSettings;
|
||||
}
|
||||
|
||||
public WindowsSettingsListPage(Classes.WindowsSettings windowsSettings, string query)
|
||||
: this(windowsSettings)
|
||||
{
|
||||
SearchText = query;
|
||||
}
|
||||
|
||||
public List<ListItem> Query(string query)
|
||||
{
|
||||
if (_windowsSettings?.Settings is null)
|
||||
@@ -31,87 +39,21 @@ internal sealed partial class WindowsSettingsListPage : DynamicListPage
|
||||
}
|
||||
|
||||
var filteredList = _windowsSettings.Settings
|
||||
.Select(SearchScoringPredicate)
|
||||
.Select(setting => ScoringHelper.SearchScoringPredicate(query, setting))
|
||||
.Where(scoredSetting => scoredSetting.Score > 0)
|
||||
.OrderByDescending(scoredSetting => scoredSetting.Score)
|
||||
.Select(scoredSetting => scoredSetting.Setting);
|
||||
|
||||
var newList = ResultHelper.GetResultList(filteredList, query);
|
||||
var newList = ResultHelper.GetResultList(filteredList);
|
||||
return newList;
|
||||
|
||||
// Rank settings by how they matched the search query. Order is:
|
||||
// 1. Exact Name (10 points)
|
||||
// 2. Name Starts With (8 points)
|
||||
// 3. Name (5 points)
|
||||
// 4. Area (4 points)
|
||||
// 5. AltName (2 points)
|
||||
// 6. Settings path (1 point)
|
||||
(WindowsSetting Setting, int Score) SearchScoringPredicate(WindowsSetting setting)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
// If no search string is entered skip query comparison.
|
||||
return (setting, 0);
|
||||
}
|
||||
|
||||
if (string.Equals(setting.Name, query, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return (setting, 10);
|
||||
}
|
||||
|
||||
if (setting.Name.StartsWith(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 8);
|
||||
}
|
||||
|
||||
if (setting.Name.Contains(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 5);
|
||||
}
|
||||
|
||||
if (!(setting.Areas is null))
|
||||
{
|
||||
foreach (var area in setting.Areas)
|
||||
{
|
||||
// Search for areas on normal queries.
|
||||
if (area.Contains(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 4);
|
||||
}
|
||||
|
||||
// Search for Area only on queries with action char.
|
||||
if (area.Contains(query.Replace(":", string.Empty), StringComparison.CurrentCultureIgnoreCase)
|
||||
&& query.EndsWith(":", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(setting.AltNames is null))
|
||||
{
|
||||
foreach (var altName in setting.AltNames)
|
||||
{
|
||||
if (altName.Contains(query, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return (setting, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search by key char '>' for app name and settings path
|
||||
if (query.Contains('>') && ResultHelper.FilterBySettingsPath(setting, query))
|
||||
{
|
||||
return (setting, 1);
|
||||
}
|
||||
|
||||
return (setting, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateSearchText(string oldSearch, string newSearch)
|
||||
{
|
||||
RaiseItemsChanged(0);
|
||||
if (oldSearch != newSearch)
|
||||
{
|
||||
RaiseItemsChanged(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override IListItem[] GetItems()
|
||||
|
||||
@@ -3840,6 +3840,42 @@ namespace Microsoft.CmdPal.Ext.WindowsSettings.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Search Windows settings for this device.
|
||||
/// </summary>
|
||||
internal static string settings_fallback_subtitle {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_fallback_subtitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Search for "{0}" in Windows settings.
|
||||
/// </summary>
|
||||
internal static string settings_fallback_title {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_fallback_title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Navigate to specific Windows settings.
|
||||
/// </summary>
|
||||
internal static string settings_subtitle {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_subtitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Windows Settings.
|
||||
/// </summary>
|
||||
internal static string settings_title {
|
||||
get {
|
||||
return ResourceManager.GetString("settings_title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings app.
|
||||
/// </summary>
|
||||
|
||||
@@ -2085,4 +2085,16 @@
|
||||
<data name="WindowsSettingsProvider_DisplayName" xml:space="preserve">
|
||||
<value>Windows Settings</value>
|
||||
</data>
|
||||
<data name="settings_title" xml:space="preserve">
|
||||
<value>Windows Settings</value>
|
||||
</data>
|
||||
<data name="settings_subtitle" xml:space="preserve">
|
||||
<value>Navigate to specific Windows settings</value>
|
||||
</data>
|
||||
<data name="settings_fallback_title" xml:space="preserve">
|
||||
<value>Search for "{0}" in Windows settings</value>
|
||||
</data>
|
||||
<data name="settings_fallback_subtitle" xml:space="preserve">
|
||||
<value>Search Windows settings for this device</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Pages;
|
||||
using Microsoft.CmdPal.Ext.WindowsSettings.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
@@ -17,6 +18,8 @@ public partial class WindowsSettingsCommandsProvider : CommandProvider
|
||||
private readonly WindowsSettings.Classes.WindowsSettings? _windowsSettings;
|
||||
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
|
||||
|
||||
private readonly FallbackWindowsSettingsItem _fallback;
|
||||
|
||||
public WindowsSettingsCommandsProvider()
|
||||
{
|
||||
Id = "Windows.Settings";
|
||||
@@ -26,9 +29,10 @@ public partial class WindowsSettingsCommandsProvider : CommandProvider
|
||||
_windowsSettings = JsonSettingsListHelper.ReadAllPossibleSettings();
|
||||
_searchSettingsListItem = new CommandItem(new WindowsSettingsListPage(_windowsSettings))
|
||||
{
|
||||
Title = "Windows Settings",
|
||||
Subtitle = "Navigate to specific Windows settings",
|
||||
Title = Resources.settings_title,
|
||||
Subtitle = Resources.settings_subtitle,
|
||||
};
|
||||
_fallback = new(_windowsSettings);
|
||||
|
||||
UnsupportedSettingsHelper.FilterByBuild(_windowsSettings);
|
||||
|
||||
@@ -42,4 +46,6 @@ public partial class WindowsSettingsCommandsProvider : CommandProvider
|
||||
_searchSettingsListItem
|
||||
];
|
||||
}
|
||||
|
||||
public override IFallbackCommandItem[] FallbackCommands() => [_fallback];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user