diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs index 15787344ee61..1f69b895f42f 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs @@ -41,6 +41,8 @@ public ProviderSettingsViewModel( BuildFallbackViewModels(); } + public string ProviderId => _provider.ProviderId; + public string DisplayName => _provider.DisplayName; public string ExtensionName => _provider.Extension?.ExtensionDisplayName ?? Resources.builtin_extension_name; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/CommandPaletteContextMenuFactory.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/CommandPaletteContextMenuFactory.cs index 2f15e4b2135f..fb6d3b01e82c 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/CommandPaletteContextMenuFactory.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/CommandPaletteContextMenuFactory.cs @@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.Messaging; using ManagedCommon; +using Microsoft.CmdPal.UI.Messages; using Microsoft.CmdPal.UI.ViewModels; using Microsoft.CmdPal.UI.ViewModels.Messages; using Microsoft.CmdPal.UI.ViewModels.Settings; @@ -127,9 +128,30 @@ public void AddMoreCommandsToTopLevel( List moreCommands = []; var commandItem = topLevelItem.ItemViewModel; + // Replace settings content page context items with commands that + // open the settings window for this provider. + var providerId = providerContext.ProviderId; + for (var i = 0; i < contextItems.Count; i++) + { + if (contextItems[i] is ICommandContextItem cci) + { + try + { + if (cci.Command is IContentPage) + { + var replacement = new OpenExtensionSettingsCommand(providerId, cci); + contextItems[i] = new CommandContextItem(replacement); + } + } + catch + { + // Extension object may be unavailable + } + } + } + // Add pin/unpin commands for pinning items to the top-level or to // the dock. - var providerId = providerContext.ProviderId; if (_topLevelCommandManager.LookupProvider(providerId) is CommandProviderWrapper provider) { var providerSettings = _settingsModel.GetProviderSettings(provider); @@ -321,4 +343,45 @@ private void UnpinFromDock() WeakReferenceMessenger.Default.Send(message); } } + + private sealed partial class OpenExtensionSettingsCommand : InvokableCommand + { + private readonly string _providerId; + + public OpenExtensionSettingsCommand(string providerId, ICommandContextItem original) + { + _providerId = providerId; + Name = "Settings"; + Icon = new IconInfo("\uE713"); + + // Preserve original name and icon when available + try + { + if (!string.IsNullOrEmpty(original.Command?.Name)) + { + Name = original.Command.Name; + } + } + catch + { + } + + try + { + if (original.Command?.Icon is IconInfo icon) + { + Icon = icon; + } + } + catch + { + } + } + + public override CommandResult Invoke() + { + WeakReferenceMessenger.Default.Send(new OpenSettingsMessage(_providerId)); + return CommandResult.KeepOpen(); + } + } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Pages/ShellPage.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Pages/ShellPage.xaml.cs index 69ba8b0befb3..fc2ccd4d7cdd 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Pages/ShellPage.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Pages/ShellPage.xaml.cs @@ -281,7 +281,30 @@ public void OpenSettings(string pageTag) _settingsWindow.Activate(); _settingsWindow.BringToFront(); - _settingsWindow.Navigate(pageTag); + + // Check if pageTag is a provider ID for extension deep-linking + var topLevelCommandManager = App.Current.Services.GetService()!; + CommandProviderWrapper? matchingWrapper = null; + foreach (var provider in topLevelCommandManager.CommandProviders) + { + if (provider.ProviderId == pageTag) + { + matchingWrapper = provider; + break; + } + } + + if (matchingWrapper is not null) + { + var settings = App.Current.Services.GetService()!; + var providerSettings = settings.GetProviderSettings(matchingWrapper); + var providerVM = new ProviderSettingsViewModel(matchingWrapper, providerSettings, settings); + _settingsWindow.NavigateToExtension(providerVM); + } + else + { + _settingsWindow.Navigate(pageTag); + } } public void Receive(ShowDetailsMessage message) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/SettingsWindow.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/SettingsWindow.xaml.cs index de3664641d2c..0003bac187ab 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/SettingsWindow.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Settings/SettingsWindow.xaml.cs @@ -159,6 +159,11 @@ internal void Navigate(string page) } } + internal void NavigateToExtension(ProviderSettingsViewModel extension) + { + NavFrame.Navigate(typeof(ExtensionPage), extension); + } + private void Navigate(ProviderSettingsViewModel extension) { NavFrame.Navigate(typeof(ExtensionPage), extension);