mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
CmdPal: Add filter by Terminal channel (#41582)
## Summary of the Pull Request - Introduces a new filter on the Profiles page to filter by Terminal channel. - Adds a new option to remember the last select Terminal channel (or automatically reset to All Channels). - Adds new classes `AppSettings` and `AppSettingsManager` to hold non-user settings. Pictures? Pictures! <img width="1485" height="931" alt="image" src="https://github.com/user-attachments/assets/2cec7a8d-efe6-4692-a7ba-9608fb181624" /> <img width="1730" height="1014" alt="image" src="https://github.com/user-attachments/assets/87984b82-e085-42a5-b71c-5ddc71ff52ec" /> <img width="1722" height="1063" alt="image" src="https://github.com/user-attachments/assets/97baff23-3db0-404b-8a8d-622f841b344b" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #41432 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
This commit is contained in:
@@ -2,40 +2,73 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Commands;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
|
||||
using Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Pages;
|
||||
|
||||
internal sealed partial class ProfilesListPage : ListPage
|
||||
internal sealed partial class ProfilesListPage : ListPage, INotifyItemsChanged
|
||||
{
|
||||
event TypedEventHandler<object, IItemsChangedEventArgs> INotifyItemsChanged.ItemsChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
ItemsChanged += value;
|
||||
EnsureInitialized();
|
||||
SelectTerminalFilter();
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
ItemsChanged -= value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly TerminalQuery _terminalQuery = new();
|
||||
private readonly SettingsManager _terminalSettings;
|
||||
private readonly AppSettingsManager _appSettingsManager;
|
||||
|
||||
private bool showHiddenProfiles;
|
||||
private bool openNewTab;
|
||||
private bool openQuake;
|
||||
|
||||
public ProfilesListPage(SettingsManager terminalSettings)
|
||||
private bool initialized;
|
||||
private TerminalChannelFilters? terminalFilters;
|
||||
|
||||
public ProfilesListPage(SettingsManager terminalSettings, AppSettingsManager appSettingsManager)
|
||||
{
|
||||
Icon = Icons.TerminalIcon;
|
||||
Name = Resources.profiles_list_page_name;
|
||||
_terminalSettings = terminalSettings;
|
||||
_appSettingsManager = appSettingsManager;
|
||||
}
|
||||
|
||||
#pragma warning disable SA1108
|
||||
public List<ListItem> Query()
|
||||
private List<ListItem> Query()
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
showHiddenProfiles = _terminalSettings.ShowHiddenProfiles;
|
||||
openNewTab = _terminalSettings.OpenNewTab;
|
||||
openQuake = _terminalSettings.OpenQuake;
|
||||
|
||||
var profiles = _terminalQuery.GetProfiles();
|
||||
|
||||
if (terminalFilters?.IsAllSelected == false)
|
||||
{
|
||||
profiles = profiles.Where(profile => profile.Terminal.AppUserModelId == terminalFilters.CurrentFilterId);
|
||||
}
|
||||
|
||||
var result = new List<ListItem>();
|
||||
|
||||
foreach (var profile in profiles)
|
||||
@@ -52,12 +85,66 @@ internal sealed partial class ProfilesListPage : ListPage
|
||||
MoreCommands = [
|
||||
new CommandContextItem(new LaunchProfileAsAdminCommand(profile.Terminal.AppUserModelId, profile.Name, openNewTab, openQuake)),
|
||||
],
|
||||
#pragma warning restore SA1108
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override IListItem[] GetItems() => Query().ToArray();
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var terminals = _terminalQuery.GetTerminals();
|
||||
terminalFilters = new TerminalChannelFilters(terminals);
|
||||
terminalFilters.PropChanged += TerminalFiltersOnPropChanged;
|
||||
SelectTerminalFilter();
|
||||
Filters = terminalFilters;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private void SelectTerminalFilter()
|
||||
{
|
||||
Trace.Assert(terminalFilters != null);
|
||||
|
||||
// Select the preferred channel if it exists; we always select the preferred channel,
|
||||
// but user have an option to save the preferred channel when he changes the filter
|
||||
if (_terminalSettings.SaveLastSelectedChannel)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_appSettingsManager.Current.LastSelectedChannel) &&
|
||||
terminalFilters.ContainsFilter(_appSettingsManager.Current.LastSelectedChannel))
|
||||
{
|
||||
terminalFilters.CurrentFilterId = _appSettingsManager.Current.LastSelectedChannel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
terminalFilters.CurrentFilterId = TerminalChannelFilters.AllTerminalsFilterId;
|
||||
}
|
||||
}
|
||||
|
||||
private void TerminalFiltersOnPropChanged(object sender, IPropChangedEventArgs args)
|
||||
{
|
||||
Trace.Assert(terminalFilters != null);
|
||||
|
||||
RaiseItemsChanged();
|
||||
_appSettingsManager.Current.LastSelectedChannel = terminalFilters.CurrentFilterId;
|
||||
_appSettingsManager.Save();
|
||||
}
|
||||
|
||||
public override IListItem[] GetItems()
|
||||
{
|
||||
try
|
||||
{
|
||||
return [.. Query()];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Failed to list Windows Terminal profiles", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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 Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Pages;
|
||||
|
||||
internal sealed partial class TerminalChannelFilters : Filters
|
||||
{
|
||||
internal const string AllTerminalsFilterId = "all";
|
||||
|
||||
private readonly List<TerminalPackage> _terminals;
|
||||
|
||||
public bool IsAllSelected => CurrentFilterId == AllTerminalsFilterId;
|
||||
|
||||
public TerminalChannelFilters(IEnumerable<TerminalPackage> terminals, string preselectedFilterId = AllTerminalsFilterId)
|
||||
{
|
||||
CurrentFilterId = preselectedFilterId;
|
||||
_terminals = [.. terminals];
|
||||
}
|
||||
|
||||
public override IFilterItem[] GetFilters()
|
||||
{
|
||||
var items = new List<IFilterItem>
|
||||
{
|
||||
new Filter()
|
||||
{
|
||||
Id = AllTerminalsFilterId,
|
||||
Name = Resources.all_channels,
|
||||
Icon = Icons.FilterIcon,
|
||||
},
|
||||
new Separator(),
|
||||
};
|
||||
|
||||
foreach (var terminalPackage in _terminals)
|
||||
{
|
||||
items.Add(new Filter()
|
||||
{
|
||||
Id = terminalPackage.AppUserModelId,
|
||||
Name = terminalPackage.DisplayName,
|
||||
Icon = new IconInfo(terminalPackage.LogoPath),
|
||||
});
|
||||
}
|
||||
|
||||
return [.. items];
|
||||
}
|
||||
|
||||
public bool ContainsFilter(string id)
|
||||
{
|
||||
return _terminals.FindIndex(terminal => terminal.AppUserModelId == id) > -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user