mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 17:56:44 +02:00
Functionally, no differences. - Removed Core projects. - Core.Common => Microsoft.CmdPal.Common - Core.ViewModels => Microsoft.CmdPal.UI.ViewModels --------- Co-authored-by: Jiří Polášek <me@jiripolasek.com>
221 lines
7.5 KiB
C#
221 lines
7.5 KiB
C#
// 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.Diagnostics.CodeAnalysis;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Messaging;
|
|
using Microsoft.CmdPal.Common.Services;
|
|
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
|
using Microsoft.CmdPal.UI.ViewModels.Properties;
|
|
|
|
namespace Microsoft.CmdPal.UI.ViewModels;
|
|
|
|
public partial class ProviderSettingsViewModel : ObservableObject
|
|
{
|
|
private static readonly IconInfoViewModel EmptyIcon = new(null);
|
|
private static readonly CompositeFormat ExtensionSubtextFormat = CompositeFormat.Parse(Resources.builtin_extension_subtext);
|
|
private static readonly CompositeFormat ExtensionSubtextWithFallbackFormat = CompositeFormat.Parse(Resources.builtin_extension_subtext_with_fallback);
|
|
private static readonly CompositeFormat ExtensionSubtextDisabledFormat = CompositeFormat.Parse(Resources.builtin_extension_subtext_disabled);
|
|
|
|
private readonly CommandProviderWrapper _provider;
|
|
private readonly ProviderSettings _providerSettings;
|
|
private readonly SettingsModel _settings;
|
|
private readonly Lock _initializeSettingsLock = new();
|
|
|
|
private Task? _initializeSettingsTask;
|
|
|
|
public ProviderSettingsViewModel(
|
|
CommandProviderWrapper provider,
|
|
ProviderSettings providerSettings,
|
|
SettingsModel settings)
|
|
{
|
|
_provider = provider;
|
|
_providerSettings = providerSettings;
|
|
_settings = settings;
|
|
|
|
LoadingSettings = _provider.Settings?.HasSettings ?? false;
|
|
|
|
BuildFallbackViewModels();
|
|
}
|
|
|
|
public string DisplayName => _provider.DisplayName;
|
|
|
|
public string ExtensionName => _provider.Extension?.ExtensionDisplayName ?? Resources.builtin_extension_name;
|
|
|
|
public string ExtensionSubtext => IsEnabled ?
|
|
HasFallbackCommands ?
|
|
string.Format(CultureInfo.CurrentCulture, ExtensionSubtextWithFallbackFormat, ExtensionName, TopLevelCommands.Count, _provider.FallbackItems?.Length ?? 0) :
|
|
string.Format(CultureInfo.CurrentCulture, ExtensionSubtextFormat, ExtensionName, TopLevelCommands.Count) :
|
|
string.Format(CultureInfo.CurrentCulture, ExtensionSubtextDisabledFormat, ExtensionName, Resources.builtin_disabled_extension);
|
|
|
|
[MemberNotNullWhen(true, nameof(Extension))]
|
|
public bool IsFromExtension => _provider.Extension is not null;
|
|
|
|
public IExtensionWrapper? Extension => _provider.Extension;
|
|
|
|
public string ExtensionVersion => IsFromExtension ? $"{Extension.Version.Major}.{Extension.Version.Minor}.{Extension.Version.Build}.{Extension.Version.Revision}" : string.Empty;
|
|
|
|
public IconInfoViewModel Icon => IsEnabled ? _provider.Icon : EmptyIcon;
|
|
|
|
[ObservableProperty]
|
|
public partial bool LoadingSettings { get; set; }
|
|
|
|
public bool IsEnabled
|
|
{
|
|
get => _providerSettings.IsEnabled;
|
|
set
|
|
{
|
|
if (value != _providerSettings.IsEnabled)
|
|
{
|
|
_providerSettings.IsEnabled = value;
|
|
Save();
|
|
WeakReferenceMessenger.Default.Send<ReloadCommandsMessage>(new());
|
|
OnPropertyChanged(nameof(IsEnabled));
|
|
OnPropertyChanged(nameof(ExtensionSubtext));
|
|
OnPropertyChanged(nameof(Icon));
|
|
}
|
|
|
|
if (value == true)
|
|
{
|
|
_provider.CommandsChanged -= Provider_CommandsChanged;
|
|
_provider.CommandsChanged += Provider_CommandsChanged;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether returns true if we have a settings page
|
|
/// that's initialized, or we are still working on initializing that
|
|
/// settings page. If we don't have a settings object, or that settings
|
|
/// object doesn't have a settings page, then we'll return false.
|
|
/// </summary>
|
|
public bool HasSettings
|
|
{
|
|
get
|
|
{
|
|
if (_provider.Settings is null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (_provider.Settings.Initialized)
|
|
{
|
|
return _provider.Settings.HasSettings;
|
|
}
|
|
|
|
// settings still need to be loaded.
|
|
return LoadingSettings;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets will return the settings page, if we have one, and have initialized it.
|
|
/// If we haven't initialized it, this will kick off a thread to start
|
|
/// initializing it.
|
|
/// </summary>
|
|
public ContentPageViewModel? SettingsPage
|
|
{
|
|
get
|
|
{
|
|
if (_provider.Settings is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (_provider.Settings.Initialized)
|
|
{
|
|
LoadingSettings = false;
|
|
return _provider.Settings.SettingsPage;
|
|
}
|
|
|
|
// Don't load the settings if we're already working on it
|
|
lock (_initializeSettingsLock)
|
|
{
|
|
_initializeSettingsTask ??= Task.Run(InitializeSettingsPage);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
[field: AllowNull]
|
|
public List<TopLevelViewModel> TopLevelCommands
|
|
{
|
|
get
|
|
{
|
|
if (field is null)
|
|
{
|
|
field = BuildTopLevelViewModels();
|
|
}
|
|
|
|
return field;
|
|
}
|
|
}
|
|
|
|
private List<TopLevelViewModel> BuildTopLevelViewModels()
|
|
{
|
|
var thisProvider = _provider;
|
|
var providersCommands = thisProvider.TopLevelItems;
|
|
|
|
// Remember! This comes in on the UI thread!
|
|
return [.. providersCommands];
|
|
}
|
|
|
|
[field: AllowNull]
|
|
public List<FallbackSettingsViewModel> FallbackCommands { get; set; } = [];
|
|
|
|
public bool HasFallbackCommands => _provider.FallbackItems?.Length > 0;
|
|
|
|
private void BuildFallbackViewModels()
|
|
{
|
|
var thisProvider = _provider;
|
|
var providersFallbackCommands = thisProvider.FallbackItems;
|
|
|
|
List<FallbackSettingsViewModel> fallbackViewModels = new(providersFallbackCommands.Length);
|
|
foreach (var fallbackItem in providersFallbackCommands)
|
|
{
|
|
if (_providerSettings.FallbackCommands.TryGetValue(fallbackItem.Id, out var fallbackSettings))
|
|
{
|
|
fallbackViewModels.Add(new FallbackSettingsViewModel(fallbackItem, fallbackSettings, _settings, this));
|
|
}
|
|
else
|
|
{
|
|
fallbackViewModels.Add(new FallbackSettingsViewModel(fallbackItem, new(), _settings, this));
|
|
}
|
|
}
|
|
|
|
FallbackCommands = fallbackViewModels;
|
|
}
|
|
|
|
private void Save() => SettingsModel.SaveSettings(_settings);
|
|
|
|
private void InitializeSettingsPage()
|
|
{
|
|
if (_provider.Settings is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_provider.Settings.SafeInitializeProperties();
|
|
_provider.Settings.DoOnUiThread(() =>
|
|
{
|
|
// Changing these properties will try to update XAML, and that has
|
|
// to be handled on the UI thread, so we need to raise them on the
|
|
// UI thread
|
|
LoadingSettings = false;
|
|
OnPropertyChanged(nameof(HasSettings));
|
|
OnPropertyChanged(nameof(LoadingSettings));
|
|
OnPropertyChanged(nameof(SettingsPage));
|
|
});
|
|
}
|
|
|
|
private void Provider_CommandsChanged(CommandProviderWrapper sender, CommandPalette.Extensions.IItemsChangedEventArgs args)
|
|
{
|
|
OnPropertyChanged(nameof(ExtensionSubtext));
|
|
OnPropertyChanged(nameof(TopLevelCommands));
|
|
}
|
|
}
|