mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-30 16:07:29 +01:00
Compare commits
12 Commits
shawn/AddT
...
dev/mjolle
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa4bc0a397 | ||
|
|
303be86d86 | ||
|
|
ec423177da | ||
|
|
f78ec0c8e5 | ||
|
|
a1e8b6aca9 | ||
|
|
81aeb74fda | ||
|
|
b5ae2efc0d | ||
|
|
ba9585a663 | ||
|
|
5f273c7be6 | ||
|
|
ea43974287 | ||
|
|
0b3dc089ac | ||
|
|
4ba6fd2723 |
@@ -195,6 +195,10 @@
|
||||
<Folder Name="/modules/CommandPalette/">
|
||||
<Project Path="src/modules/cmdpal/CmdPalKeyboardService/CmdPalKeyboardService.vcxproj" Id="5f63c743-f6ce-4dba-a200-2b3f8a14e8c2" />
|
||||
<Project Path="src/modules/cmdpal/CmdPalModuleInterface/CmdPalModuleInterface.vcxproj" Id="0adeb797-c8c7-4ffa-acd5-2af6cad7ecd8" />
|
||||
<Project Path="src/modules/cmdpal/Microsoft.CmdPal.Common/Microsoft.CmdPal.Common.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
</Folder>
|
||||
<Folder Name="/modules/CommandPalette/Built-in Extensions/">
|
||||
<Project Path="src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Microsoft.CmdPal.Ext.Apps.csproj">
|
||||
@@ -270,16 +274,6 @@
|
||||
<Deploy />
|
||||
</Project>
|
||||
</Folder>
|
||||
<Folder Name="/modules/CommandPalette/Core/">
|
||||
<Project Path="src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Microsoft.CmdPal.Core.Common.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
<Project Path="src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/Microsoft.CmdPal.Core.ViewModels.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
</Folder>
|
||||
<Folder Name="/modules/CommandPalette/Extension SDK/">
|
||||
<Project Path="src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Microsoft.CommandPalette.Extensions.Toolkit.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
"src\\common\\version\\version.vcxproj",
|
||||
"src\\modules\\cmdpal\\CmdPalKeyboardService\\CmdPalKeyboardService.vcxproj",
|
||||
"src\\modules\\cmdpal\\CmdPalModuleInterface\\CmdPalModuleInterface.vcxproj",
|
||||
"src\\modules\\cmdpal\\Core\\Microsoft.CmdPal.Core.Common\\Microsoft.CmdPal.Core.Common.csproj",
|
||||
"src\\modules\\cmdpal\\Core\\Microsoft.CmdPal.Core.ViewModels\\Microsoft.CmdPal.Core.ViewModels.csproj",
|
||||
"src\\modules\\cmdpal\\Microsoft.CmdPal.Common\\Microsoft.CmdPal.Common.csproj",
|
||||
"src\\modules\\cmdpal\\Microsoft.CmdPal.UI.ViewModels\\Microsoft.CmdPal.UI.ViewModels.csproj",
|
||||
"src\\modules\\cmdpal\\Microsoft.CmdPal.UI\\Microsoft.CmdPal.UI.csproj",
|
||||
"src\\modules\\cmdpal\\Microsoft.Terminal.UI\\Microsoft.Terminal.UI.vcxproj",
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common;
|
||||
|
||||
public static class CoreLogger
|
||||
{
|
||||
public static void InitializeLogger(ILogger implementation)
|
||||
{
|
||||
_logger = implementation;
|
||||
}
|
||||
|
||||
private static ILogger? _logger;
|
||||
|
||||
public static void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogError(message, ex, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogError(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogWarning(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogInfo(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogDebug(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogTrace(memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ILogger
|
||||
{
|
||||
void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\CoreCommonProps.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>Microsoft.CmdPal.Core.Common</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Services;
|
||||
|
||||
public interface IExtensionService
|
||||
{
|
||||
Task<IEnumerable<IExtensionWrapper>> GetInstalledExtensionsAsync(bool includeDisabledExtensions = false);
|
||||
|
||||
// Task<IEnumerable<string>> GetInstalledHomeWidgetPackageFamilyNamesAsync(bool includeDisabledExtensions = false);
|
||||
Task<IEnumerable<IExtensionWrapper>> GetInstalledExtensionsAsync(Microsoft.CommandPalette.Extensions.ProviderType providerType, bool includeDisabledExtensions = false);
|
||||
|
||||
IExtensionWrapper? GetInstalledExtension(string extensionUniqueId);
|
||||
|
||||
Task SignalStopExtensionsAsync();
|
||||
|
||||
event TypedEventHandler<IExtensionService, IEnumerable<IExtensionWrapper>>? OnExtensionAdded;
|
||||
|
||||
event TypedEventHandler<IExtensionService, IEnumerable<IExtensionWrapper>>? OnExtensionRemoved;
|
||||
|
||||
void EnableExtension(string extensionUniqueId);
|
||||
|
||||
void DisableExtension(string extensionUniqueId);
|
||||
|
||||
///// <summary>
|
||||
///// Gets a boolean indicating whether the extension was disabled due to the corresponding Windows optional feature
|
||||
///// being absent from the machine or in an unknown state.
|
||||
///// </summary>
|
||||
///// <param name="extension">The out of proc extension object</param>
|
||||
///// <returns>True only if the extension was disabled. False otherwise.</returns>
|
||||
// public Task<bool> DisableExtensionIfWindowsFeatureNotAvailable(IExtensionWrapper extension);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\CoreCommonProps.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Common" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Core.Common\Microsoft.CmdPal.Core.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,72 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.CmdPal.Core.ViewModels.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show details.
|
||||
/// </summary>
|
||||
public static string ShowDetailsCommand {
|
||||
get {
|
||||
return ResourceManager.GetString("ShowDetailsCommand", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ShowDetailsCommand" xml:space="preserve">
|
||||
<value>Show details</value>
|
||||
<comment>Name for the command that shows details of an item</comment>
|
||||
</data>
|
||||
</root>
|
||||
167
src/modules/cmdpal/Microsoft.CmdPal.Common/CmdPalLogger.cs
Normal file
167
src/modules/cmdpal/Microsoft.CmdPal.Common/CmdPalLogger.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
// 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 ManagedCommon;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.CmdPal.Common;
|
||||
|
||||
// Adapter implementing Microsoft.Extensions.Logging.ILogger,
|
||||
// delegating to ManagedCommon.Logger.
|
||||
public sealed partial class CmdPalLogger : ILogger
|
||||
{
|
||||
private static readonly AsyncLocal<Stack<object>> _scopeStack = new();
|
||||
private readonly LogLevel _minLevel;
|
||||
|
||||
public string CurrentVersionLogDirectoryPath => Logger.CurrentVersionLogDirectoryPath;
|
||||
|
||||
public CmdPalLogger(LogLevel minLevel = LogLevel.Information)
|
||||
{
|
||||
_minLevel = minLevel;
|
||||
|
||||
// Ensure underlying logger initialized (idempotent if already done elsewhere).
|
||||
Logger.InitializeLogger("\\CmdPal\\Logs\\");
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None && logLevel >= _minLevel;
|
||||
|
||||
public IDisposable? BeginScope<TState>(TState state)
|
||||
where TState : notnull
|
||||
{
|
||||
var stack = _scopeStack.Value;
|
||||
if (stack is null)
|
||||
{
|
||||
stack = new Stack<object>();
|
||||
_scopeStack.Value = stack;
|
||||
}
|
||||
|
||||
stack.Push(state);
|
||||
return new Scope(stack);
|
||||
}
|
||||
|
||||
public void Log<TState>(
|
||||
LogLevel logLevel,
|
||||
EventId eventId,
|
||||
TState state,
|
||||
Exception? exception,
|
||||
Func<TState, Exception?, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ArgumentNullException.ThrowIfNull(formatter);
|
||||
var message = formatter(state, exception);
|
||||
if (string.IsNullOrEmpty(message) && exception is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var scopeSuffix = BuildScopeSuffix();
|
||||
var eventPrefix = eventId.Id != 0 ? $"[{eventId.Id}/{eventId.Name}] " : string.Empty;
|
||||
var finalMessage = $"{eventPrefix}{message}{scopeSuffix}";
|
||||
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.Trace:
|
||||
// Existing stack: Trace logs an empty line; append message via Debug.
|
||||
Logger.LogTrace();
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
Logger.LogDebug(finalMessage);
|
||||
}
|
||||
|
||||
if (exception is not null)
|
||||
{
|
||||
Logger.LogError(exception.Message, exception);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
Logger.LogDebug(finalMessage);
|
||||
|
||||
if (exception is not null)
|
||||
{
|
||||
Logger.LogError(exception.Message, exception);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LogLevel.Information:
|
||||
Logger.LogInfo(finalMessage);
|
||||
|
||||
if (exception is not null)
|
||||
{
|
||||
Logger.LogError(exception.Message, exception);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
Logger.LogWarning(finalMessage);
|
||||
|
||||
if (exception is not null)
|
||||
{
|
||||
Logger.LogError(exception.Message, exception);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LogLevel.Error:
|
||||
case LogLevel.Critical:
|
||||
if (exception is not null)
|
||||
{
|
||||
Logger.LogError(finalMessage, exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError(finalMessage);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LogLevel.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildScopeSuffix()
|
||||
{
|
||||
var stack = _scopeStack.Value;
|
||||
if (stack is null || stack.Count == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// Show most-recent first.
|
||||
return $" [Scopes: {string.Join(" => ", stack.ToArray())}]";
|
||||
}
|
||||
|
||||
private sealed partial class Scope : IDisposable
|
||||
{
|
||||
private readonly Stack<object> _stack;
|
||||
private bool _disposed;
|
||||
|
||||
public Scope(Stack<object> stack) => _stack = stack;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stack.Count > 0)
|
||||
{
|
||||
_stack.Pop();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Provides utility methods for building diagnostic and error messages.
|
||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common;
|
||||
namespace Microsoft.CmdPal.Common;
|
||||
|
||||
public partial class ExtensionHostInstance
|
||||
{
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Thread-safe boolean implementation using atomic operations
|
||||
@@ -7,7 +7,7 @@ using System.Threading;
|
||||
|
||||
using Microsoft.UI.Dispatching;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
public static partial class NativeEventWaiter
|
||||
{
|
||||
@@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Storage.FileSystem;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
public static class PathHelper
|
||||
{
|
||||
@@ -6,7 +6,7 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// An async gate that ensures only one operation runs at a time.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// An async gate that ensures only one value computation runs at a time.
|
||||
@@ -7,7 +7,7 @@ using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Helpers;
|
||||
namespace Microsoft.CmdPal.Common.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Well-known key chords used in the Command Palette and extensions.
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\CoreCommonProps.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>Microsoft.CmdPal.Common</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
164
src/modules/cmdpal/Microsoft.CmdPal.Common/PersistenceService.cs
Normal file
164
src/modules/cmdpal/Microsoft.CmdPal.Common/PersistenceService.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
// 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.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.CmdPal.Common;
|
||||
|
||||
public partial class PersistenceService
|
||||
{
|
||||
private static bool TryParseJsonObject(string json, ILogger logger, [NotNullWhen(true)] out JsonObject? obj)
|
||||
{
|
||||
obj = null;
|
||||
try
|
||||
{
|
||||
obj = JsonNode.Parse(json) as JsonObject;
|
||||
return obj is not null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log_PersistenceParseFailure(logger, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryReadSavedObject(string filePath, ILogger logger, [NotNullWhen(true)] out JsonObject? saved)
|
||||
{
|
||||
saved = null;
|
||||
|
||||
string oldContent;
|
||||
try
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
saved = new JsonObject();
|
||||
return true;
|
||||
}
|
||||
|
||||
oldContent = File.ReadAllText(filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log_PersistenceReadFileFailure(logger, filePath, ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(oldContent))
|
||||
{
|
||||
Log_FileEmpty(logger, filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryParseJsonObject(oldContent, logger, out saved);
|
||||
}
|
||||
|
||||
public static T LoadObject<T>(string filePath, JsonTypeInfo<T> typeInfo, ILogger logger)
|
||||
where T : new()
|
||||
{
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
throw new InvalidOperationException($"You must set a valid file path before loading {typeof(T).Name}");
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Log_FileDoesntExist(logger, typeof(T).Name, filePath);
|
||||
return new T();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var jsonContent = File.ReadAllText(filePath);
|
||||
var loaded = JsonSerializer.Deserialize(jsonContent, typeInfo);
|
||||
return loaded ?? new T();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log_PersistenceReadFailure(logger, typeof(T).Name, filePath, ex);
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveObject<T>(
|
||||
T model,
|
||||
string filePath,
|
||||
JsonTypeInfo<T> typeInfo,
|
||||
JsonSerializerOptions optionsForWrite,
|
||||
Action<JsonObject>? beforeWriteMutation,
|
||||
Action<T>? afterWriteCallback,
|
||||
ILogger logger)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
throw new InvalidOperationException($"You must set a valid file path before saving {typeof(T).Name}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var json = JsonSerializer.Serialize(model, typeInfo);
|
||||
|
||||
if (!TryParseJsonObject(json, logger, out var newObj))
|
||||
{
|
||||
Log_SerializationError(logger, typeof(T).Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryReadSavedObject(filePath, logger, out var savedObj))
|
||||
{
|
||||
savedObj = new JsonObject();
|
||||
}
|
||||
|
||||
foreach (var kvp in newObj)
|
||||
{
|
||||
savedObj[kvp.Key] = kvp.Value?.DeepClone();
|
||||
}
|
||||
|
||||
beforeWriteMutation?.Invoke(savedObj);
|
||||
|
||||
var serialized = savedObj.ToJsonString(optionsForWrite);
|
||||
File.WriteAllText(filePath, serialized);
|
||||
|
||||
afterWriteCallback?.Invoke(model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log_PersistenceSaveFailure(logger, typeof(T).Name, filePath, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static string SettingsJsonPath(string fileName)
|
||||
{
|
||||
var directory = Utilities.BaseSettingsPath("Microsoft.CommandPalette");
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
// now, the settings is just next to the exe
|
||||
return Path.Combine(directory, fileName);
|
||||
}
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to save {typeName} to '{filePath}'.")]
|
||||
static partial void Log_PersistenceSaveFailure(ILogger logger, string typeName, string filePath, Exception exception);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to read {typeName} from '{filePath}'.")]
|
||||
static partial void Log_PersistenceReadFailure(ILogger logger, string typeName, string filePath, Exception exception);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "Failed to serialize {typeName} to JsonObject.")]
|
||||
static partial void Log_SerializationError(ILogger logger, string typeName);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "The provided {typeName} file does not exist ({filePath})")]
|
||||
static partial void Log_FileDoesntExist(ILogger logger, string typeName, string filePath);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "The file at '{filePath}' is empty.")]
|
||||
static partial void Log_FileEmpty(ILogger logger, string filePath);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to read file at '{filePath}'.")]
|
||||
static partial void Log_PersistenceReadFileFailure(ILogger logger, string filePath, Exception exception);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to parse persisted JSON.")]
|
||||
static partial void Log_PersistenceParseFailure(ILogger logger, Exception exception);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Common.Services;
|
||||
namespace Microsoft.CmdPal.Common.Services;
|
||||
|
||||
public interface IRunHistoryService
|
||||
{
|
||||
@@ -4,33 +4,34 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class AliasManager : ObservableObject
|
||||
{
|
||||
private readonly TopLevelCommandManager _topLevelCommandManager;
|
||||
private readonly SettingsService _settingsService;
|
||||
|
||||
// REMEMBER, CommandAlias.SearchPrefix is what we use as keys
|
||||
private readonly Dictionary<string, CommandAlias> _aliases;
|
||||
private Dictionary<string, CommandAlias> Aliases => _settingsService.CurrentSettings.Aliases;
|
||||
|
||||
public AliasManager(TopLevelCommandManager tlcManager, SettingsModel settings)
|
||||
public AliasManager(TopLevelCommandManager tlcManager, SettingsService settingsService)
|
||||
{
|
||||
_topLevelCommandManager = tlcManager;
|
||||
_aliases = settings.Aliases;
|
||||
_settingsService = settingsService;
|
||||
|
||||
if (_aliases.Count == 0)
|
||||
if (Aliases.Count == 0)
|
||||
{
|
||||
PopulateDefaultAliases();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAlias(CommandAlias a) => _aliases.Add(a.SearchPrefix, a);
|
||||
private void AddAlias(CommandAlias a) => Aliases.Add(a.SearchPrefix, a);
|
||||
|
||||
public bool CheckAlias(string searchText)
|
||||
{
|
||||
if (_aliases.TryGetValue(searchText, out var alias))
|
||||
if (Aliases.TryGetValue(searchText, out var alias))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -65,7 +66,7 @@ public partial class AliasManager : ObservableObject
|
||||
|
||||
public string? KeysFromId(string commandId)
|
||||
{
|
||||
return _aliases
|
||||
return Aliases
|
||||
.Where(kv => kv.Value.CommandId == commandId)
|
||||
.Select(kv => kv.Value.Alias)
|
||||
.FirstOrDefault();
|
||||
@@ -73,7 +74,7 @@ public partial class AliasManager : ObservableObject
|
||||
|
||||
public CommandAlias? AliasFromId(string commandId)
|
||||
{
|
||||
return _aliases
|
||||
return Aliases
|
||||
.Where(kv => kv.Value.CommandId == commandId)
|
||||
.Select(kv => kv.Value)
|
||||
.FirstOrDefault();
|
||||
@@ -89,7 +90,7 @@ public partial class AliasManager : ObservableObject
|
||||
|
||||
// If we already have _this exact alias_, do nothing
|
||||
if (newAlias is not null &&
|
||||
_aliases.TryGetValue(newAlias.SearchPrefix, out var existingAlias))
|
||||
Aliases.TryGetValue(newAlias.SearchPrefix, out var existingAlias))
|
||||
{
|
||||
if (existingAlias.CommandId == commandId)
|
||||
{
|
||||
@@ -98,7 +99,7 @@ public partial class AliasManager : ObservableObject
|
||||
}
|
||||
|
||||
List<CommandAlias> toRemove = [];
|
||||
foreach (var kv in _aliases)
|
||||
foreach (var kv in Aliases)
|
||||
{
|
||||
// Look for the old aliases for the command, and remove it
|
||||
if (kv.Value.CommandId == commandId)
|
||||
@@ -123,7 +124,7 @@ public partial class AliasManager : ObservableObject
|
||||
foreach (var alias in toRemove)
|
||||
{
|
||||
// REMEMBER, SearchPrefix is what we use as keys
|
||||
_aliases.Remove(alias.SearchPrefix);
|
||||
Aliases.Remove(alias.SearchPrefix);
|
||||
}
|
||||
|
||||
if (newAlias is not null)
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.CmdPal.Core.Common;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public abstract partial class AppExtensionHost : IExtensionHost
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private static readonly GlobalLogPageContext _globalLogPageContext = new();
|
||||
|
||||
private static ulong _hostingHwnd;
|
||||
@@ -27,6 +29,11 @@ public abstract partial class AppExtensionHost : IExtensionHost
|
||||
|
||||
public static void SetHostHwnd(ulong hostHwnd) => _hostingHwnd = hostHwnd;
|
||||
|
||||
public AppExtensionHost(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void DebugLog(string message)
|
||||
{
|
||||
#if DEBUG
|
||||
@@ -60,7 +67,7 @@ public abstract partial class AppExtensionHost : IExtensionHost
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
CoreLogger.LogDebug(message.Message);
|
||||
Log_Message(message.Message);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
@@ -158,6 +165,9 @@ public abstract partial class AppExtensionHost : IExtensionHost
|
||||
}
|
||||
|
||||
public abstract string? GetExtensionDisplayName();
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "{message}")]
|
||||
partial void Log_Message(string message);
|
||||
}
|
||||
|
||||
public interface IAppHostService
|
||||
@@ -2,25 +2,12 @@
|
||||
// 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;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class AppStateModel : ObservableObject
|
||||
{
|
||||
[JsonIgnore]
|
||||
public static readonly string FilePath;
|
||||
|
||||
public event TypedEventHandler<AppStateModel, object?>? StateChanged;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// STATE HERE
|
||||
// Make sure that you make the setters public (JsonSerializer.Deserialize will fail silently otherwise)!
|
||||
@@ -28,144 +15,4 @@ public partial class AppStateModel : ObservableObject
|
||||
public RecentCommandsManager RecentCommands { get; set; } = new();
|
||||
|
||||
public List<string> RunHistory { get; set; } = [];
|
||||
|
||||
// END SETTINGS
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static AppStateModel()
|
||||
{
|
||||
FilePath = StateJsonPath();
|
||||
}
|
||||
|
||||
public static AppStateModel LoadState()
|
||||
{
|
||||
if (string.IsNullOrEmpty(FilePath))
|
||||
{
|
||||
throw new InvalidOperationException($"You must set a valid {nameof(FilePath)} before calling {nameof(LoadState)}");
|
||||
}
|
||||
|
||||
if (!File.Exists(FilePath))
|
||||
{
|
||||
Debug.WriteLine("The provided settings file does not exist");
|
||||
return new();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Read the JSON content from the file
|
||||
var jsonContent = File.ReadAllText(FilePath);
|
||||
|
||||
var loaded = JsonSerializer.Deserialize<AppStateModel>(jsonContent, JsonSerializationContext.Default.AppStateModel);
|
||||
|
||||
Debug.WriteLine(loaded is not null ? "Loaded settings file" : "Failed to parse");
|
||||
|
||||
return loaded ?? new();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
return new();
|
||||
}
|
||||
|
||||
public static void SaveState(AppStateModel model)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FilePath))
|
||||
{
|
||||
throw new InvalidOperationException($"You must set a valid {nameof(FilePath)} before calling {nameof(SaveState)}");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Serialize the main dictionary to JSON and save it to the file
|
||||
var settingsJson = JsonSerializer.Serialize(model, JsonSerializationContext.Default.AppStateModel!);
|
||||
|
||||
// validate JSON
|
||||
if (JsonNode.Parse(settingsJson) is not JsonObject newSettings)
|
||||
{
|
||||
Logger.LogError("Failed to parse app state as a JsonObject.");
|
||||
return;
|
||||
}
|
||||
|
||||
// read previous settings
|
||||
if (!TryReadSavedState(out var savedSettings))
|
||||
{
|
||||
savedSettings = new JsonObject();
|
||||
}
|
||||
|
||||
// merge new settings into old ones
|
||||
foreach (var item in newSettings)
|
||||
{
|
||||
savedSettings[item.Key] = item.Value?.DeepClone();
|
||||
}
|
||||
|
||||
var serialized = savedSettings.ToJsonString(JsonSerializationContext.Default.AppStateModel!.Options);
|
||||
File.WriteAllText(FilePath, serialized);
|
||||
|
||||
// TODO: Instead of just raising the event here, we should
|
||||
// have a file change watcher on the settings file, and
|
||||
// reload the settings then
|
||||
model.StateChanged?.Invoke(model, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Failed to save application state to {FilePath}:", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryReadSavedState([NotNullWhen(true)] out JsonObject? savedSettings)
|
||||
{
|
||||
savedSettings = null;
|
||||
|
||||
// read existing content from the file
|
||||
string oldContent;
|
||||
try
|
||||
{
|
||||
if (File.Exists(FilePath))
|
||||
{
|
||||
oldContent = File.ReadAllText(FilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// file doesn't exist (might not have been created yet), so consider this a success
|
||||
// and return empty settings
|
||||
savedSettings = new JsonObject();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning($"Failed to read app state file {FilePath}:\n{ex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// detect empty file, just for sake of logging
|
||||
if (string.IsNullOrWhiteSpace(oldContent))
|
||||
{
|
||||
Logger.LogInfo($"App state file is empty: {FilePath}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// is it valid JSON?
|
||||
try
|
||||
{
|
||||
savedSettings = JsonNode.Parse(oldContent) as JsonObject;
|
||||
return savedSettings != null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning($"Failed to parse app state from {FilePath}:\n{ex}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string StateJsonPath()
|
||||
{
|
||||
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
// now, the settings is just next to the exe
|
||||
return Path.Combine(directory, "state.json");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// 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 Microsoft.CmdPal.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class AppStateService
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly string _filePath;
|
||||
private AppStateModel _appStateModel;
|
||||
|
||||
public event TypedEventHandler<AppStateModel, object?>? StateChanged;
|
||||
|
||||
public AppStateModel CurrentSettings => _appStateModel;
|
||||
|
||||
public AppStateService(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_filePath = PersistenceService.SettingsJsonPath("state.json");
|
||||
_appStateModel = LoadState();
|
||||
}
|
||||
|
||||
private AppStateModel LoadState()
|
||||
{
|
||||
return PersistenceService.LoadObject<AppStateModel>(_filePath, JsonSerializationContext.Default.AppStateModel!, _logger);
|
||||
}
|
||||
|
||||
public void SaveSettings(AppStateModel model)
|
||||
{
|
||||
PersistenceService.SaveObject(
|
||||
model,
|
||||
_filePath,
|
||||
JsonSerializationContext.Default.AppStateModel,
|
||||
JsonSerializationContext.Default.Options,
|
||||
null,
|
||||
afterWriteCallback: m => FinalizeStateSave(m),
|
||||
_logger);
|
||||
}
|
||||
|
||||
private void FinalizeStateSave(AppStateModel model)
|
||||
{
|
||||
_appStateModel = model;
|
||||
StateChanged?.Invoke(model, null);
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
Color.FromArgb(255, 126, 115, 95), // #7e735f
|
||||
];
|
||||
|
||||
private readonly SettingsModel _settings;
|
||||
private readonly SettingsService _settingsService;
|
||||
private readonly UISettings _uiSettings;
|
||||
private readonly IThemeService _themeService;
|
||||
private readonly DispatcherQueueTimer _saveTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
|
||||
@@ -94,22 +94,24 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
private ElementTheme? _elementThemeOverride;
|
||||
private Color _currentSystemAccentColor;
|
||||
|
||||
private SettingsModel Settings => _settingsService.CurrentSettings;
|
||||
|
||||
public ObservableCollection<Color> Swatches => WindowsColorSwatches;
|
||||
|
||||
public int ThemeIndex
|
||||
{
|
||||
get => (int)_settings.Theme;
|
||||
get => (int)Settings.Theme;
|
||||
set => Theme = (UserTheme)value;
|
||||
}
|
||||
|
||||
public UserTheme Theme
|
||||
{
|
||||
get => _settings.Theme;
|
||||
get => Settings.Theme;
|
||||
set
|
||||
{
|
||||
if (_settings.Theme != value)
|
||||
if (Settings.Theme != value)
|
||||
{
|
||||
_settings.Theme = value;
|
||||
Settings.Theme = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(ThemeIndex));
|
||||
Save();
|
||||
@@ -119,12 +121,12 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public ColorizationMode ColorizationMode
|
||||
{
|
||||
get => _settings.ColorizationMode;
|
||||
get => Settings.ColorizationMode;
|
||||
set
|
||||
{
|
||||
if (_settings.ColorizationMode != value)
|
||||
if (Settings.ColorizationMode != value)
|
||||
{
|
||||
_settings.ColorizationMode = value;
|
||||
Settings.ColorizationMode = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(ColorizationModeIndex));
|
||||
OnPropertyChanged(nameof(IsCustomTintVisible));
|
||||
@@ -147,18 +149,18 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public int ColorizationModeIndex
|
||||
{
|
||||
get => (int)_settings.ColorizationMode;
|
||||
get => (int)Settings.ColorizationMode;
|
||||
set => ColorizationMode = (ColorizationMode)value;
|
||||
}
|
||||
|
||||
public Color ThemeColor
|
||||
{
|
||||
get => _settings.CustomThemeColor;
|
||||
get => Settings.CustomThemeColor;
|
||||
set
|
||||
{
|
||||
if (_settings.CustomThemeColor != value)
|
||||
if (Settings.CustomThemeColor != value)
|
||||
{
|
||||
_settings.CustomThemeColor = value;
|
||||
Settings.CustomThemeColor = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
|
||||
@@ -174,10 +176,10 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public int ColorIntensity
|
||||
{
|
||||
get => _settings.CustomThemeColorIntensity;
|
||||
get => Settings.CustomThemeColorIntensity;
|
||||
set
|
||||
{
|
||||
_settings.CustomThemeColorIntensity = value;
|
||||
Settings.CustomThemeColorIntensity = value;
|
||||
OnPropertyChanged();
|
||||
Save();
|
||||
}
|
||||
@@ -185,12 +187,12 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public string BackgroundImagePath
|
||||
{
|
||||
get => _settings.BackgroundImagePath ?? string.Empty;
|
||||
get => Settings.BackgroundImagePath ?? string.Empty;
|
||||
set
|
||||
{
|
||||
if (_settings.BackgroundImagePath != value)
|
||||
if (Settings.BackgroundImagePath != value)
|
||||
{
|
||||
_settings.BackgroundImagePath = value;
|
||||
Settings.BackgroundImagePath = value;
|
||||
OnPropertyChanged();
|
||||
|
||||
if (BackgroundImageOpacity == 0)
|
||||
@@ -205,12 +207,12 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public int BackgroundImageOpacity
|
||||
{
|
||||
get => _settings.BackgroundImageOpacity;
|
||||
get => Settings.BackgroundImageOpacity;
|
||||
set
|
||||
{
|
||||
if (_settings.BackgroundImageOpacity != value)
|
||||
if (Settings.BackgroundImageOpacity != value)
|
||||
{
|
||||
_settings.BackgroundImageOpacity = value;
|
||||
Settings.BackgroundImageOpacity = value;
|
||||
OnPropertyChanged();
|
||||
Save();
|
||||
}
|
||||
@@ -219,12 +221,12 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public int BackgroundImageBrightness
|
||||
{
|
||||
get => _settings.BackgroundImageBrightness;
|
||||
get => Settings.BackgroundImageBrightness;
|
||||
set
|
||||
{
|
||||
if (_settings.BackgroundImageBrightness != value)
|
||||
if (Settings.BackgroundImageBrightness != value)
|
||||
{
|
||||
_settings.BackgroundImageBrightness = value;
|
||||
Settings.BackgroundImageBrightness = value;
|
||||
OnPropertyChanged();
|
||||
Save();
|
||||
}
|
||||
@@ -233,12 +235,12 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public int BackgroundImageBlurAmount
|
||||
{
|
||||
get => _settings.BackgroundImageBlurAmount;
|
||||
get => Settings.BackgroundImageBlurAmount;
|
||||
set
|
||||
{
|
||||
if (_settings.BackgroundImageBlurAmount != value)
|
||||
if (Settings.BackgroundImageBlurAmount != value)
|
||||
{
|
||||
_settings.BackgroundImageBlurAmount = value;
|
||||
Settings.BackgroundImageBlurAmount = value;
|
||||
OnPropertyChanged();
|
||||
Save();
|
||||
}
|
||||
@@ -247,12 +249,12 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
public BackgroundImageFit BackgroundImageFit
|
||||
{
|
||||
get => _settings.BackgroundImageFit;
|
||||
get => Settings.BackgroundImageFit;
|
||||
set
|
||||
{
|
||||
if (_settings.BackgroundImageFit != value)
|
||||
if (Settings.BackgroundImageFit != value)
|
||||
{
|
||||
_settings.BackgroundImageFit = value;
|
||||
Settings.BackgroundImageFit = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(BackgroundImageFitIndex));
|
||||
Save();
|
||||
@@ -282,15 +284,15 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
[ObservableProperty]
|
||||
public partial bool IsColorizationDetailsExpanded { get; set; }
|
||||
|
||||
public bool IsCustomTintVisible => _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.Image;
|
||||
public bool IsCustomTintVisible => Settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.Image;
|
||||
|
||||
public bool IsCustomTintIntensityVisible => _settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image;
|
||||
public bool IsCustomTintIntensityVisible => Settings.ColorizationMode is ColorizationMode.CustomColor or ColorizationMode.WindowsAccentColor or ColorizationMode.Image;
|
||||
|
||||
public bool IsBackgroundControlsVisible => _settings.ColorizationMode is ColorizationMode.Image;
|
||||
public bool IsBackgroundControlsVisible => Settings.ColorizationMode is ColorizationMode.Image;
|
||||
|
||||
public bool IsNoBackgroundVisible => _settings.ColorizationMode is ColorizationMode.None;
|
||||
public bool IsNoBackgroundVisible => Settings.ColorizationMode is ColorizationMode.None;
|
||||
|
||||
public bool IsAccentColorControlsVisible => _settings.ColorizationMode is ColorizationMode.WindowsAccentColor;
|
||||
public bool IsAccentColorControlsVisible => Settings.ColorizationMode is ColorizationMode.WindowsAccentColor;
|
||||
|
||||
public AcrylicBackdropParameters EffectiveBackdrop { get; private set; } = new(Colors.Black, Colors.Black, 0.5f, 0.5f);
|
||||
|
||||
@@ -315,11 +317,11 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
? new Microsoft.UI.Xaml.Media.Imaging.BitmapImage(uri)
|
||||
: null;
|
||||
|
||||
public AppearanceSettingsViewModel(IThemeService themeService, SettingsModel settings)
|
||||
public AppearanceSettingsViewModel(IThemeService themeService, SettingsService settingsService)
|
||||
{
|
||||
_themeService = themeService;
|
||||
_themeService.ThemeChanged += ThemeServiceOnThemeChanged;
|
||||
_settings = settings;
|
||||
_settingsService = settingsService;
|
||||
|
||||
_uiSettings = new UISettings();
|
||||
_uiSettings.ColorValuesChanged += UiSettingsOnColorValuesChanged;
|
||||
@@ -327,7 +329,7 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
Reapply();
|
||||
|
||||
IsColorizationDetailsExpanded = _settings.ColorizationMode != ColorizationMode.None;
|
||||
IsColorizationDetailsExpanded = Settings.ColorizationMode != ColorizationMode.None;
|
||||
}
|
||||
|
||||
private void UiSettingsOnColorValuesChanged(UISettings sender, object args) => _uiDispatcher.TryEnqueue(() => UpdateAccentColor(sender));
|
||||
@@ -348,7 +350,7 @@ public sealed partial class AppearanceSettingsViewModel : ObservableObject, IDis
|
||||
|
||||
private void Save()
|
||||
{
|
||||
SettingsModel.SaveSettings(_settings);
|
||||
_settingsService.SaveSettings(Settings);
|
||||
_saveTimer.Debounce(Reapply, TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates a navigation request within Command Palette view models.
|
||||
@@ -4,15 +4,18 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class CommandBarViewModel : ObservableObject,
|
||||
IRecipient<UpdateCommandBarMessage>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ICommandBarContext? SelectedItem
|
||||
{
|
||||
get => field;
|
||||
@@ -48,8 +51,9 @@ public partial class CommandBarViewModel : ObservableObject,
|
||||
[ObservableProperty]
|
||||
public partial PageViewModel? CurrentPage { get; set; }
|
||||
|
||||
public CommandBarViewModel()
|
||||
public CommandBarViewModel(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
WeakReferenceMessenger.Default.Register<UpdateCommandBarMessage>(this);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
public partial class CommandContextItemViewModel(ICommandContextItem contextItem, WeakReference<IPageContext> context) : CommandItemViewModel(new(contextItem), context), IContextItemViewModel
|
||||
@@ -3,18 +3,22 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CmdPal.Core.Common;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBarContext
|
||||
{
|
||||
// Local logger field required for [LoggerMessage] source generator
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ExtensionObject<ICommandItem> Model => _commandItemModel;
|
||||
|
||||
private ExtensionObject<IExtendedAttributesProvider>? ExtendedAttributesProvider { get; set; }
|
||||
@@ -91,9 +95,10 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
|
||||
_errorIcon.InitializeProperties();
|
||||
}
|
||||
|
||||
public CommandItemViewModel(ExtensionObject<ICommandItem> item, WeakReference<IPageContext> errorContext)
|
||||
public CommandItemViewModel(ExtensionObject<ICommandItem> item, WeakReference<IPageContext> errorContext, ILogger? logger = null)
|
||||
: base(errorContext)
|
||||
{
|
||||
_logger = logger ?? NullLogger.Instance;
|
||||
_commandItemModel = item;
|
||||
Command = new(null, errorContext);
|
||||
}
|
||||
@@ -243,7 +248,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError("error fast initializing CommandItemViewModel", ex);
|
||||
Log_FastInitError(ex);
|
||||
Command = new(null, PageContext);
|
||||
_itemTitle = "Error";
|
||||
Subtitle = "Item failed to load";
|
||||
@@ -265,7 +270,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
|
||||
catch (Exception ex)
|
||||
{
|
||||
Initialized |= InitializedState.Error;
|
||||
CoreLogger.LogError("error slow initializing CommandItemViewModel", ex);
|
||||
Log_SlowInitError(ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -280,7 +285,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError("error initializing CommandItemViewModel", ex);
|
||||
Log_InitError(ex);
|
||||
Command = new(null, PageContext);
|
||||
_itemTitle = "Error";
|
||||
Subtitle = "Item failed to load";
|
||||
@@ -489,6 +494,15 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
|
||||
base.SafeCleanup();
|
||||
Initialized |= InitializedState.CleanedUp;
|
||||
}
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Error fast initializing CommandItemViewModel")]
|
||||
partial void Log_FastInitError(Exception ex);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Error slow initializing CommandItemViewModel")]
|
||||
partial void Log_SlowInitError(Exception ex);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Error initializing CommandItemViewModel")]
|
||||
partial void Log_InitError(Exception ex);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
@@ -2,32 +2,26 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.Common.Services;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public sealed partial class CommandPaletteHost : AppExtensionHost, IExtensionHost
|
||||
{
|
||||
// Static singleton, so that we can access this from anywhere
|
||||
// Post MVVM - this should probably be like, a dependency injection thing.
|
||||
public static CommandPaletteHost Instance { get; } = new();
|
||||
|
||||
public IExtensionWrapper? Extension { get; }
|
||||
|
||||
private readonly ICommandProvider? _builtInProvider;
|
||||
|
||||
private CommandPaletteHost()
|
||||
{
|
||||
}
|
||||
|
||||
public CommandPaletteHost(IExtensionWrapper source)
|
||||
public CommandPaletteHost(IExtensionWrapper source, ILogger logger)
|
||||
: base(logger)
|
||||
{
|
||||
Extension = source;
|
||||
}
|
||||
|
||||
public CommandPaletteHost(ICommandProvider builtInProvider)
|
||||
public CommandPaletteHost(ICommandProvider builtInProvider, ILogger logger)
|
||||
: base(logger)
|
||||
{
|
||||
_builtInProvider = builtInProvider;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.Common.Services;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public sealed class CommandProviderWrapper
|
||||
public sealed partial class CommandProviderWrapper
|
||||
{
|
||||
public bool IsExtension => Extension is not null;
|
||||
|
||||
private readonly bool isValid;
|
||||
|
||||
private readonly ExtensionObject<ICommandProvider> _commandProvider;
|
||||
|
||||
private readonly TaskScheduler _taskScheduler;
|
||||
private readonly ILogger _logger;
|
||||
private readonly HotkeyManager _hotkeyManager;
|
||||
private readonly AliasManager _aliasManager;
|
||||
|
||||
public TopLevelViewModel[] TopLevelItems { get; private set; } = [];
|
||||
|
||||
@@ -51,15 +51,19 @@ public sealed class CommandProviderWrapper
|
||||
}
|
||||
}
|
||||
|
||||
public CommandProviderWrapper(ICommandProvider provider, TaskScheduler mainThread)
|
||||
public CommandProviderWrapper(ICommandProvider provider, TaskScheduler mainThread, HotkeyManager hotkeyManager, AliasManager aliasManager, ILogger logger)
|
||||
{
|
||||
_hotkeyManager = hotkeyManager;
|
||||
_aliasManager = aliasManager;
|
||||
|
||||
// This ctor is only used for in-proc builtin commands. So the Unsafe!
|
||||
// calls are pretty dang safe actually.
|
||||
_commandProvider = new(provider);
|
||||
_taskScheduler = mainThread;
|
||||
_logger = logger;
|
||||
|
||||
// Hook the extension back into us
|
||||
ExtensionHost = new CommandPaletteHost(provider);
|
||||
ExtensionHost = new CommandPaletteHost(provider, logger);
|
||||
_commandProvider.Unsafe!.InitializeWithHost(ExtensionHost);
|
||||
|
||||
_commandProvider.Unsafe!.ItemsChanged += CommandProvider_ItemsChanged;
|
||||
@@ -74,14 +78,22 @@ public sealed class CommandProviderWrapper
|
||||
// we do that, then we'd regress GH #38321
|
||||
Settings = new(provider.Settings, this, _taskScheduler);
|
||||
|
||||
Logger.LogDebug($"Initialized command provider {ProviderId}");
|
||||
Log_InitializedCommandProvider(ProviderId);
|
||||
}
|
||||
|
||||
public CommandProviderWrapper(IExtensionWrapper extension, TaskScheduler mainThread)
|
||||
public CommandProviderWrapper(
|
||||
IExtensionWrapper extension,
|
||||
TaskScheduler mainThread,
|
||||
HotkeyManager hotkeyManager,
|
||||
AliasManager aliasManager,
|
||||
ILogger logger)
|
||||
{
|
||||
_taskScheduler = mainThread;
|
||||
_logger = logger;
|
||||
_hotkeyManager = hotkeyManager;
|
||||
_aliasManager = aliasManager;
|
||||
Extension = extension;
|
||||
ExtensionHost = new CommandPaletteHost(extension);
|
||||
ExtensionHost = new CommandPaletteHost(extension, logger);
|
||||
if (!Extension.IsRunning())
|
||||
{
|
||||
throw new ArgumentException("You forgot to start the extension. This is a CmdPal error - we need to make sure to call StartExtensionAsync");
|
||||
@@ -106,13 +118,11 @@ public sealed class CommandProviderWrapper
|
||||
|
||||
isValid = true;
|
||||
|
||||
Logger.LogDebug($"Initialized extension command provider {Extension.PackageFamilyName}:{Extension.ExtensionUniqueId}");
|
||||
Log_InitializedExtensionCommandProvider(Extension.PackageFamilyName, Extension.ExtensionUniqueId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError("Failed to initialize CommandProvider for extension.");
|
||||
Logger.LogError($"Extension was {Extension!.PackageFamilyName}");
|
||||
Logger.LogError(e.ToString());
|
||||
Log_FailedToInitializeCommandProvider(Extension!.PackageFamilyName, e);
|
||||
}
|
||||
|
||||
isValid = true;
|
||||
@@ -123,7 +133,7 @@ public sealed class CommandProviderWrapper
|
||||
return settings.GetProviderSettings(this);
|
||||
}
|
||||
|
||||
public async Task LoadTopLevelCommands(IServiceProvider serviceProvider, WeakReference<IPageContext> pageContext)
|
||||
public async Task LoadTopLevelCommands(SettingsService settingsService, WeakReference<IPageContext> pageContext)
|
||||
{
|
||||
if (!isValid)
|
||||
{
|
||||
@@ -131,7 +141,7 @@ public sealed class CommandProviderWrapper
|
||||
return;
|
||||
}
|
||||
|
||||
var settings = serviceProvider.GetService<SettingsModel>()!;
|
||||
var settings = settingsService.CurrentSettings;
|
||||
|
||||
IsActive = GetProviderSettings(settings).IsEnabled;
|
||||
if (!IsActive)
|
||||
@@ -168,27 +178,25 @@ public sealed class CommandProviderWrapper
|
||||
Settings = new(model.Settings, this, _taskScheduler);
|
||||
|
||||
// We do need to explicitly initialize commands though
|
||||
InitializeCommands(commands, fallbacks, serviceProvider, pageContext);
|
||||
InitializeCommands(commands, fallbacks, settingsService, pageContext);
|
||||
|
||||
Logger.LogDebug($"Loaded commands from {DisplayName} ({ProviderId})");
|
||||
Log_LoadedCommands(DisplayName, ProviderId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError("Failed to load commands from extension");
|
||||
Logger.LogError($"Extension was {Extension!.PackageFamilyName}");
|
||||
Logger.LogError(e.ToString());
|
||||
Log_FailedToLoadCommands(Extension!.PackageFamilyName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeCommands(ICommandItem[] commands, IFallbackCommandItem[] fallbacks, IServiceProvider serviceProvider, WeakReference<IPageContext> pageContext)
|
||||
private void InitializeCommands(ICommandItem[] commands, IFallbackCommandItem[] fallbacks, SettingsService settingsService, WeakReference<IPageContext> pageContext)
|
||||
{
|
||||
var settings = serviceProvider.GetService<SettingsModel>()!;
|
||||
var settings = settingsService.CurrentSettings;
|
||||
var providerSettings = GetProviderSettings(settings);
|
||||
|
||||
Func<ICommandItem?, bool, TopLevelViewModel> makeAndAdd = (ICommandItem? i, bool fallback) =>
|
||||
{
|
||||
CommandItemViewModel commandItemViewModel = new(new(i), pageContext);
|
||||
TopLevelViewModel topLevelViewModel = new(commandItemViewModel, fallback, ExtensionHost, ProviderId, settings, providerSettings, serviceProvider, i);
|
||||
TopLevelViewModel topLevelViewModel = new(commandItemViewModel, fallback, ExtensionHost, ProviderId, settingsService, providerSettings, _hotkeyManager, _aliasManager, i);
|
||||
topLevelViewModel.InitializeProperties();
|
||||
|
||||
return topLevelViewModel;
|
||||
@@ -212,12 +220,12 @@ public sealed class CommandProviderWrapper
|
||||
private void UnsafePreCacheApiAdditions(ICommandProvider2 provider)
|
||||
{
|
||||
var apiExtensions = provider.GetApiExtensionStubs();
|
||||
Logger.LogDebug($"Provider supports {apiExtensions.Length} extensions");
|
||||
Log_ProviderSupportsExtensions(apiExtensions.Length);
|
||||
foreach (var a in apiExtensions)
|
||||
{
|
||||
if (a is IExtendedAttributesProvider command2)
|
||||
{
|
||||
Logger.LogDebug($"{ProviderId}: Found an IExtendedAttributesProvider");
|
||||
Log_FoundExtendedAttributesProvider(ProviderId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,4 +243,25 @@ public sealed class CommandProviderWrapper
|
||||
// In handling this, a call will be made to `LoadTopLevelCommands` to
|
||||
// retrieve the new items.
|
||||
this.CommandsChanged?.Invoke(this, args);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "Initialized command provider {providerId}")]
|
||||
private partial void Log_InitializedCommandProvider(string providerId);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "Initialized extension command provider {packageFamilyName}:{extensionUniqueId}")]
|
||||
private partial void Log_InitializedExtensionCommandProvider(string? packageFamilyName, string? extensionUniqueId);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to initialize CommandProvider for extension {packageFamilyName}")]
|
||||
private partial void Log_FailedToInitializeCommandProvider(string? packageFamilyName, Exception ex);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "Loaded commands from {displayName} ({providerId})")]
|
||||
private partial void Log_LoadedCommands(string displayName, string providerId);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to load commands from extension {packageFamilyName}")]
|
||||
private partial void Log_FailedToLoadCommands(string? packageFamilyName, Exception ex);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "Provider supports {extensionCount} extensions")]
|
||||
private partial void Log_ProviderSupportsExtensions(int extensionCount);
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "{providerId}: Found an IExtendedAttributesProvider")]
|
||||
private partial void Log_FoundExtendedAttributesProvider(string providerId);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.Common;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings, CommandProviderWrapper provider, TaskScheduler mainThread)
|
||||
public partial class CommandSettingsViewModel
|
||||
{
|
||||
private readonly ExtensionObject<ICommandSettings> _model = new(_unsafeSettings);
|
||||
private readonly ILogger _logger;
|
||||
private readonly ExtensionObject<ICommandSettings> _model;
|
||||
private readonly CommandProviderWrapper _provider;
|
||||
private readonly TaskScheduler _mainThread;
|
||||
|
||||
public CommandSettingsViewModel(ICommandSettings? unsafeSettings, CommandProviderWrapper provider, TaskScheduler mainThread, ILogger? logger = null)
|
||||
{
|
||||
_model = new(unsafeSettings);
|
||||
_provider = provider;
|
||||
_mainThread = mainThread;
|
||||
_logger = logger ?? NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ContentPageViewModel? SettingsPage { get; private set; }
|
||||
|
||||
@@ -31,7 +43,7 @@ public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings,
|
||||
|
||||
if (model.SettingsPage is not null)
|
||||
{
|
||||
SettingsPage = new CommandPaletteContentPageViewModel(model.SettingsPage, mainThread, provider.ExtensionHost);
|
||||
SettingsPage = new CommandPaletteContentPageViewModel(model.SettingsPage, _mainThread, _provider.ExtensionHost);
|
||||
SettingsPage.InitializeProperties();
|
||||
}
|
||||
}
|
||||
@@ -44,7 +56,7 @@ public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings,
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError($"Failed to load settings page", ex: ex);
|
||||
Log_FailedToLoadSettingsPage(ex);
|
||||
}
|
||||
|
||||
Initialized = true;
|
||||
@@ -56,6 +68,9 @@ public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings,
|
||||
action,
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
mainThread);
|
||||
_mainThread);
|
||||
}
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to load settings page")]
|
||||
partial void Log_FailedToLoadSettingsPage(Exception ex);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class CommandViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.Common;
|
||||
using Microsoft.CmdPal.Common;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.Specialized;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
@@ -7,14 +7,14 @@ using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.Common.Helpers;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Common.Helpers;
|
||||
using Microsoft.CmdPal.Ext.Apps;
|
||||
using Microsoft.CmdPal.Ext.Apps.Programs;
|
||||
using Microsoft.CmdPal.Ext.Apps.State;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Commands;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Properties;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Services;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
@@ -30,11 +30,13 @@ public partial class MainListPage : DynamicListPage,
|
||||
{
|
||||
private readonly TopLevelCommandManager _tlcManager;
|
||||
private readonly AliasManager _aliasManager;
|
||||
private readonly SettingsModel _settings;
|
||||
private readonly AppStateModel _appStateModel;
|
||||
private readonly SettingsService _settingsService;
|
||||
private readonly AppStateService _appStateService;
|
||||
private List<Scored<IListItem>>? _filteredItems;
|
||||
private List<Scored<IListItem>>? _filteredApps;
|
||||
|
||||
private SettingsModel Settings => _settingsService.CurrentSettings;
|
||||
|
||||
// Keep as IEnumerable for deferred execution. Fallback item titles are updated
|
||||
// asynchronously, so scoring must happen lazily when GetItems is called.
|
||||
private IEnumerable<Scored<IListItem>>? _scoredFallbackItems;
|
||||
@@ -48,15 +50,17 @@ public partial class MainListPage : DynamicListPage,
|
||||
|
||||
private CancellationTokenSource? _cancellationTokenSource;
|
||||
|
||||
public MainListPage(TopLevelCommandManager topLevelCommandManager, SettingsModel settings, AliasManager aliasManager, AppStateModel appStateModel)
|
||||
private AppStateModel AppState => _appStateService.CurrentSettings;
|
||||
|
||||
public MainListPage(TopLevelCommandManager topLevelCommandManager, SettingsService settingsService, AliasManager aliasManager, AppStateService appStateService)
|
||||
{
|
||||
Title = Resources.builtin_home_name;
|
||||
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.scale-200.png");
|
||||
PlaceholderText = Properties.Resources.builtin_main_list_page_searchbar_placeholder;
|
||||
|
||||
_settings = settings;
|
||||
_settingsService = settingsService;
|
||||
_aliasManager = aliasManager;
|
||||
_appStateModel = appStateModel;
|
||||
_appStateService = appStateService;
|
||||
_tlcManager = topLevelCommandManager;
|
||||
_tlcManager.PropertyChanged += TlcManager_PropertyChanged;
|
||||
_tlcManager.TopLevelCommands.CollectionChanged += Commands_CollectionChanged;
|
||||
@@ -75,8 +79,8 @@ public partial class MainListPage : DynamicListPage,
|
||||
WeakReferenceMessenger.Default.Register<ClearSearchMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<UpdateFallbackItemsMessage>(this);
|
||||
|
||||
settings.SettingsChanged += SettingsChangedHandler;
|
||||
HotReloadSettings(settings);
|
||||
_settingsService.SettingsChanged += SettingsChangedHandler;
|
||||
HotReloadSettings(Settings);
|
||||
_includeApps = _tlcManager.IsProviderActive(AllAppsCommandProvider.WellKnownId);
|
||||
|
||||
IsLoading = true;
|
||||
@@ -242,7 +246,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
}
|
||||
|
||||
// prefilter fallbacks
|
||||
var globalFallbacks = _settings.GetGlobalFallbacks();
|
||||
var globalFallbacks = Settings.GetGlobalFallbacks();
|
||||
var specialFallbacks = new List<TopLevelViewModel>(globalFallbacks.Length);
|
||||
var commonFallbacks = new List<TopLevelViewModel>();
|
||||
|
||||
@@ -376,7 +380,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
}
|
||||
}
|
||||
|
||||
var history = _appStateModel.RecentCommands!;
|
||||
var history = AppState.RecentCommands!;
|
||||
Func<string, IListItem, int> scoreItem = (a, b) => { return ScoreTopLevelItem(a, b, history); };
|
||||
|
||||
// Produce a list of everything that matches the current filter.
|
||||
@@ -401,7 +405,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
return;
|
||||
}
|
||||
|
||||
Func<string, IListItem, int> scoreFallbackItem = (a, b) => { return ScoreFallbackItem(a, b, _settings.FallbackRanks); };
|
||||
Func<string, IListItem, int> scoreFallbackItem = (a, b) => { return ScoreFallbackItem(a, b, Settings.FallbackRanks); };
|
||||
_fallbackItems = [.. ListHelpers.FilterListWithScores<IListItem>(newFallbacks ?? [], SearchText, scoreFallbackItem)];
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
@@ -594,9 +598,9 @@ public partial class MainListPage : DynamicListPage,
|
||||
public void UpdateHistory(IListItem topLevelOrAppItem)
|
||||
{
|
||||
var id = IdForTopLevelOrAppItem(topLevelOrAppItem);
|
||||
var history = _appStateModel.RecentCommands;
|
||||
var history = AppState.RecentCommands;
|
||||
history.AddHistoryItem(id);
|
||||
AppStateModel.SaveState(_appStateModel);
|
||||
_appStateService.SaveSettings(AppState);
|
||||
}
|
||||
|
||||
private static string IdForTopLevelOrAppItem(IListItem topLevelOrAppItem)
|
||||
@@ -628,10 +632,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
_tlcManager.PropertyChanged -= TlcManager_PropertyChanged;
|
||||
_tlcManager.TopLevelCommands.CollectionChanged -= Commands_CollectionChanged;
|
||||
|
||||
if (_settings is not null)
|
||||
{
|
||||
_settings.SettingsChanged -= SettingsChangedHandler;
|
||||
}
|
||||
_settingsService.SettingsChanged -= SettingsChangedHandler;
|
||||
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO.Compression;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class ConfirmResultViewModel(IConfirmationArgs _args, WeakReference<IPageContext> context) :
|
||||
ExtensionObjectViewModel(context)
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
@@ -7,10 +7,9 @@ using System.Text.Json;
|
||||
using AdaptiveCards.ObjectModel.WinUI3;
|
||||
using AdaptiveCards.Templating;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Windows.Data.Json;
|
||||
|
||||
@@ -52,7 +51,7 @@ public partial class ContentFormViewModel(IFormContent _form, WeakReference<IPag
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Error building card from template", ex);
|
||||
// Error is returned via output parameter for caller to handle
|
||||
error = ex;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
@@ -7,12 +7,12 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
|
||||
{
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ObjectModel;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public abstract partial class ContentViewModel(WeakReference<IPageContext> context) :
|
||||
ExtensionObjectViewModel(context)
|
||||
@@ -1,21 +1,23 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.Common;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class ContextMenuViewModel : ObservableObject,
|
||||
IRecipient<UpdateCommandBarMessage>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ICommandBarContext? SelectedItem
|
||||
{
|
||||
get => field;
|
||||
@@ -39,8 +41,9 @@ public partial class ContextMenuViewModel : ObservableObject,
|
||||
|
||||
private string _lastSearchText = string.Empty;
|
||||
|
||||
public ContextMenuViewModel()
|
||||
public ContextMenuViewModel(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
WeakReferenceMessenger.Default.Register<UpdateCommandBarMessage>(this);
|
||||
}
|
||||
|
||||
@@ -141,7 +144,7 @@ public partial class ContextMenuViewModel : ObservableObject,
|
||||
var added = result.TryAdd(key, cmd);
|
||||
if (!added)
|
||||
{
|
||||
CoreLogger.LogWarning($"Ignoring duplicate keyboard shortcut {KeyChordHelpers.FormatForDebug(key)} on command '{cmd.Title ?? cmd.Name ?? "(unknown)"}'");
|
||||
Log_DuplicateKeyboardShortcut(KeyChordHelpers.FormatForDebug(key), cmd.Title ?? cmd.Name ?? "(unknown)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,4 +226,7 @@ public partial class ContextMenuViewModel : ObservableObject,
|
||||
return ContextKeybindingResult.Hide;
|
||||
}
|
||||
}
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Warning, Message = "Ignoring duplicate keyboard shortcut {KeyChord} on command '{CommandName}'")]
|
||||
partial void Log_DuplicateKeyboardShortcut(string keyChord, string commandName);
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class DetailsCommandsViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public abstract partial class DetailsDataViewModel(IPageContext context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public abstract partial class DetailsElementViewModel(IDetailsElement _detailsElement, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -3,11 +3,11 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class DetailsLinkViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class DetailsSeparatorViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class DetailsTagsViewModel(
|
||||
IDetailsElement _detailsElement,
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class DetailsViewModel(IDetails _details, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
|
||||
{
|
||||
@@ -3,12 +3,24 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.CmdPal.Core.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public abstract partial class ExtensionObjectViewModel : ObservableObject
|
||||
{
|
||||
private ILogger _logger = NullLogger.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logger for this ViewModel. Subclasses can set this in their constructor.
|
||||
/// </summary>
|
||||
protected ILogger Logger
|
||||
{
|
||||
get => _logger;
|
||||
set => _logger = value;
|
||||
}
|
||||
|
||||
public WeakReference<IPageContext> PageContext { get; set; }
|
||||
|
||||
internal ExtensionObjectViewModel(IPageContext? context)
|
||||
@@ -114,7 +126,10 @@ public abstract partial class ExtensionObjectViewModel : ObservableObject
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogDebug(ex.ToString());
|
||||
Log_CleanupException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[LoggerMessage(Level = LogLevel.Debug, Message = "Exception during cleanup")]
|
||||
partial void Log_CleanupException(Exception ex);
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class FallbackSettingsViewModel : ObservableObject
|
||||
{
|
||||
private readonly SettingsModel _settings;
|
||||
private readonly SettingsService _settingsService;
|
||||
private readonly FallbackSettings _fallbackSettings;
|
||||
|
||||
private SettingsModel Settings => _settingsService.CurrentSettings;
|
||||
|
||||
public string DisplayName { get; private set; } = string.Empty;
|
||||
|
||||
public IconInfoViewModel Icon { get; private set; } = new(null);
|
||||
@@ -63,10 +65,10 @@ public partial class FallbackSettingsViewModel : ObservableObject
|
||||
public FallbackSettingsViewModel(
|
||||
TopLevelViewModel fallback,
|
||||
FallbackSettings fallbackSettings,
|
||||
SettingsModel settingsModel,
|
||||
SettingsService settingsService,
|
||||
ProviderSettingsViewModel providerSettings)
|
||||
{
|
||||
_settings = settingsModel;
|
||||
_settingsService = settingsService;
|
||||
_fallbackSettings = fallbackSettings;
|
||||
|
||||
Id = fallback.Id;
|
||||
@@ -80,7 +82,7 @@ public partial class FallbackSettingsViewModel : ObservableObject
|
||||
|
||||
private void Save()
|
||||
{
|
||||
SettingsModel.SaveSettings(_settings);
|
||||
_settingsService.SaveSettings(Settings);
|
||||
WeakReferenceMessenger.Default.Send<ReloadCommandsMessage>(new());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class FilterItemViewModel : ExtensionObjectViewModel, IFilterItemViewModel
|
||||
{
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class FiltersViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public class GalleryGridPropertiesViewModel : IGridPropertiesViewModel
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public class GlobalLogPageContext : IPageContext
|
||||
{
|
||||
@@ -9,19 +9,19 @@ namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class HotkeyManager : ObservableObject
|
||||
{
|
||||
private readonly TopLevelCommandManager _topLevelCommandManager;
|
||||
private readonly List<TopLevelHotkey> _commandHotkeys;
|
||||
private readonly SettingsService _settingsService;
|
||||
|
||||
public HotkeyManager(TopLevelCommandManager tlcManager, SettingsModel settings)
|
||||
private List<TopLevelHotkey> CommandHotkeys => _settingsService.CurrentSettings.CommandHotkeys;
|
||||
|
||||
public HotkeyManager(SettingsService settingsService)
|
||||
{
|
||||
_topLevelCommandManager = tlcManager;
|
||||
_commandHotkeys = settings.CommandHotkeys;
|
||||
_settingsService = settingsService;
|
||||
}
|
||||
|
||||
public void UpdateHotkey(string commandId, HotkeySettings? hotkey)
|
||||
{
|
||||
// If any of the commands were already bound to this hotkey, remove that
|
||||
foreach (var item in _commandHotkeys)
|
||||
foreach (var item in CommandHotkeys)
|
||||
{
|
||||
if (item.Hotkey == hotkey)
|
||||
{
|
||||
@@ -29,17 +29,17 @@ public partial class HotkeyManager : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
_commandHotkeys.RemoveAll(item => item.Hotkey is null);
|
||||
CommandHotkeys.RemoveAll(item => item.Hotkey is null);
|
||||
|
||||
foreach (var item in _commandHotkeys)
|
||||
foreach (var item in CommandHotkeys)
|
||||
{
|
||||
if (item.CommandId == commandId)
|
||||
{
|
||||
_commandHotkeys.Remove(item);
|
||||
CommandHotkeys.Remove(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_commandHotkeys.Add(new(hotkey, commandId));
|
||||
CommandHotkeys.Add(new(hotkey, commandId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
public interface IContextItemViewModel
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public interface IFilterItemViewModel
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public interface IGridPropertiesViewModel
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public interface IRootPageService
|
||||
{
|
||||
@@ -3,12 +3,12 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class IconDataViewModel : ObservableObject, IIconData
|
||||
{
|
||||
@@ -3,10 +3,10 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class IconInfoViewModel : ObservableObject, IIconInfo
|
||||
{
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
[JsonSerializable(typeof(float))]
|
||||
[JsonSerializable(typeof(int))]
|
||||
[JsonSerializable(typeof(string))]
|
||||
[JsonSerializable(typeof(bool))]
|
||||
[JsonSerializable(typeof(HistoryItem))]
|
||||
[JsonSerializable(typeof(SettingsModel))]
|
||||
[JsonSerializable(typeof(WindowPosition))]
|
||||
[JsonSerializable(typeof(AppStateModel))]
|
||||
[JsonSerializable(typeof(RecentCommandsManager))]
|
||||
[JsonSerializable(typeof(List<string>), TypeInfoPropertyName = "StringList")]
|
||||
[JsonSerializable(typeof(List<HistoryItem>), TypeInfoPropertyName = "HistoryList")]
|
||||
[JsonSerializable(typeof(Dictionary<string, object>), TypeInfoPropertyName = "Dictionary")]
|
||||
[JsonSourceGenerationOptions(UseStringEnumConverter = true, WriteIndented = true, IncludeFields = true, PropertyNameCaseInsensitive = true, AllowTrailingCommas = true)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Just used here")]
|
||||
internal sealed partial class JsonSerializationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
@@ -3,12 +3,12 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Commands;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Commands;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class ListItemViewModel : CommandItemViewModel
|
||||
{
|
||||
@@ -6,14 +6,14 @@ using System.Collections.ObjectModel;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.Common.Helpers;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.Common.Helpers;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class ListViewModel : PageViewModel, IDisposable
|
||||
{
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class LoadingPageViewModel : PageViewModel
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public partial class LogMessageViewModel : ExtensionObjectViewModel
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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 Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels;
|
||||
|
||||
public class MediumGridPropertiesViewModel : IGridPropertiesViewModel
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to perform a list item's secondary command when the user presses ctrl+enter in the search box
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to perform a list item's command when the user presses enter in the search box
|
||||
@@ -2,6 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record BeginInvokeMessage;
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record ClearSearchMessage()
|
||||
{
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// 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.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to announce that a context menu should close
|
||||
@@ -2,6 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record CmdPalInvokeResultMessage(Microsoft.CommandPalette.Extensions.CommandResultKind Kind);
|
||||
@@ -2,6 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record DismissMessage(bool ForceGoHome = false);
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Message sent when an error occurs during command execution.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Message sent when an extension command or page is invoked.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record FocusSearchBoxMessage()
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record GoBackMessage(bool WithAnimation = true, bool FocusSearch = true)
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
// TODO! sticking these properties here feels like leaking the UI into the models
|
||||
public record GoHomeMessage(bool WithAnimation = true, bool FocusSearch = true)
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record HandleCommandResultMessage(ExtensionObject<ICommandResult> Result)
|
||||
{
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record HideDetailsMessage()
|
||||
{
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record LaunchUriMessage(Uri Uri)
|
||||
{
|
||||
@@ -2,6 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record NavigateBackMessage(bool FromBackspace = false);
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate left in a grid view when pressing the Left arrow key in the SearchBox.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Commands;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate to the next command in the page when pressing the Down key in the SearchBox.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate down one page in the page when pressing the PageDown key in the SearchBox.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate up one page in the page when pressing the PageUp key in the SearchBox.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate to the previous command in the page when pressing the Down key in the SearchBox.
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to navigate right in a grid view when pressing the Right arrow key in the SearchBox.
|
||||
@@ -2,6 +2,6 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
public record NavigateToPageMessage(PageViewModel Page, bool WithAnimation, CancellationToken CancellationToken);
|
||||
@@ -2,7 +2,7 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Message containing the current navigation depth (BackStack count) when navigating to a page.
|
||||
@@ -2,10 +2,10 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CmdPal.UI.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
|
||||
|
||||
/// <summary>
|
||||
/// Used to do a command - navigate to a page or invoke it
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user