[PowerToys Run] Plugin manager (#9872)
This commit is contained in:
parent
f839a408de
commit
4a9e920a1c
|
@ -15,7 +15,7 @@ using Wox.Plugin;
|
|||
|
||||
namespace Microsoft.Plugin.Folder
|
||||
{
|
||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable, IContextMenu, IDisposable
|
||||
public class Main : IPlugin, IPluginI18n, ISavable, IContextMenu, IDisposable
|
||||
{
|
||||
public const string FolderImagePath = "Images\\folder.dark.png";
|
||||
public const string FileImagePath = "Images\\file.dark.png";
|
||||
|
@ -38,6 +38,10 @@ namespace Microsoft.Plugin.Folder
|
|||
private IContextMenu _contextMenuLoader;
|
||||
private bool _disposed;
|
||||
|
||||
public string Name => Properties.Resources.wox_plugin_folder_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.wox_plugin_folder_plugin_description;
|
||||
|
||||
public void Save()
|
||||
{
|
||||
_storage.Save();
|
||||
|
@ -119,10 +123,6 @@ namespace Microsoft.Plugin.Folder
|
|||
return _contextMenuLoader.LoadContextMenus(selectedResult);
|
||||
}
|
||||
|
||||
public void UpdateSettings(PowerLauncherSettings settings)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace Microsoft.Plugin.Folder.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Open favorite folder from PowerToys Run directly.
|
||||
/// Looks up a localized string similar to Navigates folders starting from a drive letter 'C:\' or from the user home '~'..
|
||||
/// </summary>
|
||||
public static string wox_plugin_folder_plugin_description {
|
||||
get {
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
<value>Folder</value>
|
||||
</data>
|
||||
<data name="wox_plugin_folder_plugin_description" xml:space="preserve">
|
||||
<value>Open favorite folder from PowerToys Run directly</value>
|
||||
<value>Navigates folders starting from a drive letter 'C:\' or from the user home '~'.</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_folder_copy_path" xml:space="preserve">
|
||||
<value>Copy path (Ctrl+C)</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "",
|
||||
"IsGlobal": true,
|
||||
"Name": "Folder",
|
||||
"Description": "Search and open folders",
|
||||
"Author": "qianlifeng",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Microsoft.Plugin.Indexer
|
|||
{
|
||||
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin
|
||||
{
|
||||
private const string DisableDriveDetectionWarning = nameof(DisableDriveDetectionWarning);
|
||||
private static readonly IFileSystem _fileSystem = new FileSystem();
|
||||
|
||||
// This variable contains metadata about the Plugin
|
||||
|
@ -46,6 +47,20 @@ namespace Microsoft.Plugin.Indexer
|
|||
|
||||
private string WarningIconPath { get; set; }
|
||||
|
||||
public string Name => Properties.Resources.Microsoft_plugin_indexer_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.Microsoft_plugin_indexer_plugin_description;
|
||||
|
||||
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
|
||||
{
|
||||
new PluginAdditionalOption()
|
||||
{
|
||||
Key = DisableDriveDetectionWarning,
|
||||
DisplayLabel = Properties.Resources.disable_drive_detection_warning,
|
||||
Value = false,
|
||||
},
|
||||
};
|
||||
|
||||
private IContextMenu _contextMenuLoader;
|
||||
private bool disposedValue;
|
||||
|
||||
|
@ -210,9 +225,10 @@ namespace Microsoft.Plugin.Indexer
|
|||
return _contextMenuLoader.LoadContextMenus(selectedResult);
|
||||
}
|
||||
|
||||
public void UpdateSettings(PowerLauncherSettings settings)
|
||||
public void UpdateSettings(PowerLauncherPluginSettings settings)
|
||||
{
|
||||
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = settings.Properties.DisableDriveDetectionWarning;
|
||||
var option = settings.AdditionalOptions.FirstOrDefault(x => x.Key == DisableDriveDetectionWarning);
|
||||
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = option == null ? false : option.Value;
|
||||
}
|
||||
|
||||
public Control CreateSettingPanel()
|
||||
|
|
|
@ -60,6 +60,15 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Disable drive detection warning.
|
||||
/// </summary>
|
||||
public static string disable_drive_detection_warning {
|
||||
get {
|
||||
return ResourceManager.GetString("disable_drive_detection_warning", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Fail to set text in clipboard.
|
||||
/// </summary>
|
||||
|
@ -151,7 +160,7 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Returns files and folders.
|
||||
/// Looks up a localized string similar to Searches files and folders..
|
||||
/// </summary>
|
||||
public static string Microsoft_plugin_indexer_plugin_description {
|
||||
get {
|
||||
|
@ -160,7 +169,7 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Windows Indexer.
|
||||
/// Looks up a localized string similar to Windows Search.
|
||||
/// </summary>
|
||||
public static string Microsoft_plugin_indexer_plugin_name {
|
||||
get {
|
||||
|
|
|
@ -151,12 +151,15 @@
|
|||
<value>Fail to open folder at</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_indexer_plugin_description" xml:space="preserve">
|
||||
<value>Returns files and folders</value>
|
||||
<value>Searches files and folders.</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_indexer_plugin_name" xml:space="preserve">
|
||||
<value>Windows Indexer</value>
|
||||
<value>Windows Search</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_indexer_subtitle_header" xml:space="preserve">
|
||||
<value>Search</value>
|
||||
</data>
|
||||
<data name="disable_drive_detection_warning" xml:space="preserve">
|
||||
<value>Disable drive detection warning</value>
|
||||
</data>
|
||||
</root>
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "?",
|
||||
"IsGlobal": true,
|
||||
"Name": "Windows Indexer",
|
||||
"Description": "Search for files and folders",
|
||||
"Author": "Microsoft",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -32,10 +32,7 @@ namespace Microsoft.Plugin.Program.UnitTests.ProgramArgumentParser
|
|||
new NoArgumentsArgumentParser(),
|
||||
};
|
||||
|
||||
// basic version of the Quey parser which can be found at Wox.Core.Plugin.QueryBuilder but did not want to create a project reference
|
||||
var splittedSearchString = inputQuery?.Split(Query.TermSeparator, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
var cleanQuery = string.Join(Query.TermSeparator, splittedSearchString);
|
||||
var query = new Query(cleanQuery, cleanQuery, new ReadOnlyCollection<string>(splittedSearchString), string.Empty);
|
||||
var query = new Query(inputQuery);
|
||||
|
||||
// Act
|
||||
string program = null, programArguments = null;
|
||||
|
|
|
@ -32,6 +32,10 @@ namespace Microsoft.Plugin.Program
|
|||
|
||||
internal static ProgramPluginSettings Settings { get; set; }
|
||||
|
||||
public string Name => Properties.Resources.wox_plugin_program_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.wox_plugin_program_plugin_description;
|
||||
|
||||
private static PluginInitContext _context;
|
||||
private readonly PluginJsonStorage<ProgramPluginSettings> _settingsStorage;
|
||||
private bool _disposed;
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace Microsoft.Plugin.Program.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Search programs in PowerToys Run.
|
||||
/// Looks up a localized string similar to Searches programs..
|
||||
/// </summary>
|
||||
public static string wox_plugin_program_plugin_description {
|
||||
get {
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
<value>Program</value>
|
||||
</data>
|
||||
<data name="wox_plugin_program_plugin_description" xml:space="preserve">
|
||||
<value>Search programs in PowerToys Run</value>
|
||||
<value>Searches programs.</value>
|
||||
</data>
|
||||
<data name="powertoys_run_plugin_program_win32_application" xml:space="preserve">
|
||||
<value>Application</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": ".",
|
||||
"IsGlobal": true,
|
||||
"Name": "Program",
|
||||
"Description": "Search for programs",
|
||||
"Author": "qianlifeng",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -22,7 +22,7 @@ using Control = System.Windows.Controls.Control;
|
|||
|
||||
namespace Microsoft.Plugin.Shell
|
||||
{
|
||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
|
||||
public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable
|
||||
{
|
||||
private static readonly IFileSystem FileSystem = new FileSystem();
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
|
@ -34,6 +34,10 @@ namespace Microsoft.Plugin.Shell
|
|||
|
||||
private string IconPath { get; set; }
|
||||
|
||||
public string Name => Properties.Resources.wox_plugin_cmd_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.wox_plugin_cmd_plugin_description;
|
||||
|
||||
private PluginInitContext _context;
|
||||
|
||||
public Main()
|
||||
|
@ -331,9 +335,5 @@ namespace Microsoft.Plugin.Shell
|
|||
|
||||
return resultlist;
|
||||
}
|
||||
|
||||
public void UpdateSettings(PowerLauncherSettings settings)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace Microsoft.Plugin.Shell.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Allows to execute system commands from PowerToys Run. Commands should start with >.
|
||||
/// Looks up a localized string similar to Executes commands (e.g 'ping', 'cmd')..
|
||||
/// </summary>
|
||||
public static string wox_plugin_cmd_plugin_description {
|
||||
get {
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
<value>Shell</value>
|
||||
</data>
|
||||
<data name="wox_plugin_cmd_plugin_description" xml:space="preserve">
|
||||
<value>Allows to execute system commands from PowerToys Run. Commands should start with ></value>
|
||||
<value>Executes commands (e.g 'ping', 'cmd').</value>
|
||||
</data>
|
||||
<data name="wox_plugin_cmd_cmd_has_been_executed_times" xml:space="preserve">
|
||||
<value>this command has been executed {0} times</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": ">",
|
||||
"IsGlobal": false,
|
||||
"Name": "Shell",
|
||||
"Description": "Provide executing commands. Commands should start with >",
|
||||
"Author": "qianlifeng",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -43,6 +43,10 @@ namespace Microsoft.Plugin.Uri
|
|||
|
||||
public PluginInitContext Context { get; protected set; }
|
||||
|
||||
public string Name => Properties.Resources.Microsoft_plugin_uri_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.Microsoft_plugin_uri_plugin_description;
|
||||
|
||||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
|
||||
{
|
||||
return new List<ContextMenuResult>(0);
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Microsoft.Plugin.Uri.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Handles urls.
|
||||
/// Looks up a localized string similar to Opens URLs and UNC network shares..
|
||||
/// </summary>
|
||||
public static string Microsoft_plugin_uri_plugin_description {
|
||||
get {
|
||||
|
@ -79,7 +79,7 @@ namespace Microsoft.Plugin.Uri.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Url Handler.
|
||||
/// Looks up a localized string similar to URI Handler.
|
||||
/// </summary>
|
||||
public static string Microsoft_plugin_uri_plugin_name {
|
||||
get {
|
||||
|
|
|
@ -121,10 +121,10 @@
|
|||
<value>Failed to open URL</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_uri_plugin_description" xml:space="preserve">
|
||||
<value>Handles urls</value>
|
||||
<value>Opens URLs and UNC network shares.</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_uri_plugin_name" xml:space="preserve">
|
||||
<value>Url Handler</value>
|
||||
<value>URI Handler</value>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_uri_website" xml:space="preserve">
|
||||
<value>Open in browser</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "//",
|
||||
"IsGlobal": true,
|
||||
"Name": "Windows Uri Handler",
|
||||
"Description": "Handles urls",
|
||||
"Author": "Microsoft",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace Microsoft.Plugin.WindowWalker
|
|||
|
||||
private PluginInitContext Context { get; set; }
|
||||
|
||||
public string Name => Properties.Resources.wox_plugin_windowwalker_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.wox_plugin_windowwalker_plugin_description;
|
||||
|
||||
static Main()
|
||||
{
|
||||
SearchController.Instance.OnSearchResultUpdateEventHandler += SearchResultUpdated;
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace Microsoft.Plugin.WindowWalker.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Alt-Tab alternative enabling searching through your windows..
|
||||
/// Looks up a localized string similar to Switches between open windows..
|
||||
/// </summary>
|
||||
public static string wox_plugin_windowwalker_plugin_description {
|
||||
get {
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
<value>Window Walker</value>
|
||||
</data>
|
||||
<data name="wox_plugin_windowwalker_plugin_description" xml:space="preserve">
|
||||
<value>Alt-Tab alternative enabling searching through your windows.</value>
|
||||
<value>Switches between open windows.</value>
|
||||
</data>
|
||||
<data name="wox_plugin_windowwalker_running" xml:space="preserve">
|
||||
<value>Running</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "<",
|
||||
"IsGlobal": true,
|
||||
"Name": "Window Walker",
|
||||
"Description": "Alt-Tab alternative enabling searching through your windows.",
|
||||
"Author": "betadele",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
|
|||
|
||||
private string IconPath { get; set; }
|
||||
|
||||
public string Name => Properties.Resources.wox_plugin_calculator_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.wox_plugin_calculator_plugin_description;
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
|
@ -20,15 +23,15 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
[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>
|
||||
|
@ -42,7 +45,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
|
@ -56,7 +59,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy failed, please try later.
|
||||
/// </summary>
|
||||
|
@ -65,7 +68,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
return ResourceManager.GetString("wox_plugin_calculator_copy_failed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Copy this number to the clipboard.
|
||||
/// </summary>
|
||||
|
@ -74,7 +77,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
return ResourceManager.GetString("wox_plugin_calculator_copy_number_to_clipboard", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Expression wrong or incomplete (Did you forget some parentheses?).
|
||||
/// </summary>
|
||||
|
@ -83,7 +86,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
return ResourceManager.GetString("wox_plugin_calculator_expression_not_complete", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not a number (NaN).
|
||||
/// </summary>
|
||||
|
@ -92,16 +95,16 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
|||
return ResourceManager.GetString("wox_plugin_calculator_not_a_number", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Allows you to do mathematical calculations. (Try 5*3-2 in PowerToys Run).
|
||||
/// Looks up a localized string similar to Does mathematical calculations (e.g. 5*3-2)..
|
||||
/// </summary>
|
||||
public static string wox_plugin_calculator_plugin_description {
|
||||
get {
|
||||
return ResourceManager.GetString("wox_plugin_calculator_plugin_description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Calculator.
|
||||
/// </summary>
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
<value>Calculator</value>
|
||||
</data>
|
||||
<data name="wox_plugin_calculator_plugin_description" xml:space="preserve">
|
||||
<value>Allows you to do mathematical calculations. (Try 5*3-2 in PowerToys Run)</value>
|
||||
<value>Does mathematical calculations (e.g. 5*3-2).</value>
|
||||
</data>
|
||||
<data name="wox_plugin_calculator_not_a_number" xml:space="preserve">
|
||||
<value>Not a number (NaN)</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "=",
|
||||
"IsGlobal": true,
|
||||
"Name": "Calculator",
|
||||
"Description": "Provide mathematical calculations.(Try 5*3-2 in PowerToys)",
|
||||
"Author": "cxfksword",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -42,6 +42,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry
|
|||
/// </summary>
|
||||
private bool _disposed;
|
||||
|
||||
public string Name => Resources.PluginTitle;
|
||||
|
||||
public string Description => Resources.PluginDescription;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Main"/> class.
|
||||
/// </summary>
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Search inside the Windows Registry.
|
||||
/// Looks up a localized string similar to Navigates inside the Windows Registry..
|
||||
/// </summary>
|
||||
internal static string PluginDescription {
|
||||
get {
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
<value>Registry Plugin</value>
|
||||
</data>
|
||||
<data name="PluginDescription" xml:space="preserve">
|
||||
<value>Search inside the Windows Registry</value>
|
||||
<value>Navigates inside the Windows Registry.</value>
|
||||
<comment>"this built into Windows the OS. translate accordingly, https://docs.microsoft.com/de-de/troubleshoot/windows-server/performance/windows-registry-advanced-users is an example of it translated in German"</comment>
|
||||
</data>
|
||||
<data name="CopyKeyNamePath" xml:space="preserve">
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": ":",
|
||||
"IsGlobal": false,
|
||||
"Name": "Registry",
|
||||
"Description": "Search inside the Windows Registry",
|
||||
"Author": "TobiasSekan",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Service
|
|||
private PluginInitContext _context;
|
||||
private string _icoPath;
|
||||
|
||||
public string Name => Resources.wox_plugin_service_plugin_name;
|
||||
|
||||
public string Description => Resources.wox_plugin_service_plugin_description;
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Manages Windows services.
|
||||
/// Looks up a localized string similar to Manages Windows services..
|
||||
/// </summary>
|
||||
internal static string wox_plugin_service_plugin_description {
|
||||
get {
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
<value>Pausing</value>
|
||||
</data>
|
||||
<data name="wox_plugin_service_plugin_description" xml:space="preserve">
|
||||
<value>Manages Windows services</value>
|
||||
<value>Manages Windows services.</value>
|
||||
</data>
|
||||
<data name="wox_plugin_service_plugin_name" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "!",
|
||||
"IsGlobal": false,
|
||||
"Name": "Service",
|
||||
"Description": "Manages Windows services",
|
||||
"Author": "davidegiacometti",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -32,8 +32,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests
|
|||
// Setup
|
||||
Mock<Main> main = new Mock<Main>();
|
||||
main.Object.IconTheme = "dark";
|
||||
string[] terms = { typedString };
|
||||
Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection<string>(terms), string.Empty);
|
||||
Query expectedQuery = new Query(typedString);
|
||||
|
||||
// Act
|
||||
var result = main.Object.Query(expectedQuery).FirstOrDefault().IcoPath;
|
||||
|
@ -54,8 +53,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests
|
|||
// Setup
|
||||
Mock<Main> main = new Mock<Main>();
|
||||
main.Object.IconTheme = "light";
|
||||
string[] terms = { typedString };
|
||||
Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection<string>(terms), string.Empty);
|
||||
Query expectedQuery = new Query(typedString);
|
||||
|
||||
// Act
|
||||
var result = main.Object.Query(expectedQuery).FirstOrDefault().IcoPath;
|
||||
|
|
|
@ -30,8 +30,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests
|
|||
{
|
||||
// Setup
|
||||
Mock<Main> main = new Mock<Main>();
|
||||
string[] terms = { typedString };
|
||||
Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection<string>(terms), string.Empty);
|
||||
Query expectedQuery = new Query(typedString);
|
||||
|
||||
// Act
|
||||
var result = main.Object.Query(expectedQuery).FirstOrDefault().SubTitle;
|
||||
|
|
|
@ -26,6 +26,10 @@ namespace Microsoft.PowerToys.Run.Plugin.System
|
|||
|
||||
public string IconTheme { get; set; }
|
||||
|
||||
public string Name => Properties.Resources.Microsoft_plugin_sys_plugin_name;
|
||||
|
||||
public string Description => Properties.Resources.Microsoft_plugin_sys_plugin_description;
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
this._context = context;
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Provides Windows related commands, shutdown, lock, sleep .....
|
||||
/// Looks up a localized string similar to Executes system commands (e.g. 'shutdown', 'lock', 'sleep')..
|
||||
/// </summary>
|
||||
internal static string Microsoft_plugin_sys_plugin_description {
|
||||
get {
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
<comment>This should align to the action in Windows of a locking your computer.</comment>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_sys_plugin_description" xml:space="preserve">
|
||||
<value>Provides Windows related commands, shutdown, lock, sleep ....</value>
|
||||
<value>Executes system commands (e.g. 'shutdown', 'lock', 'sleep').</value>
|
||||
<comment>This should align to the actions in Windows relating to shutting down, signing out, locking, sleeping, restarting, emptying the recycle bin, and hibernating your computer. </comment>
|
||||
</data>
|
||||
<data name="Microsoft_plugin_sys_plugin_name" xml:space="preserve">
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"ActionKeyword": "",
|
||||
"IsGlobal": true,
|
||||
"Name": "System Commands",
|
||||
"Description": "Provide System related commands. e.g. shutdown,lock,setting etc.",
|
||||
"Author": "Wox",
|
||||
"Version": "1.0.0",
|
||||
"Language": "csharp",
|
||||
|
|
|
@ -12,7 +12,6 @@ using System.Reflection;
|
|||
using System.Threading.Tasks;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Wox.Infrastructure.UserSettings;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
|
@ -62,15 +61,11 @@ namespace PowerLauncher.Plugin
|
|||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, PluginPair> NonGlobalPlugins
|
||||
public static IEnumerable<PluginPair> NonGlobalPlugins
|
||||
{
|
||||
get
|
||||
{
|
||||
return AllPlugins
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x.Metadata.ActionKeyword))
|
||||
.GroupBy(x => x.Metadata.ActionKeyword)
|
||||
.Select(x => x.First())
|
||||
.ToDictionary(x => x.Metadata.ActionKeyword);
|
||||
return AllPlugins.Where(x => !string.IsNullOrWhiteSpace(x.Metadata.ActionKeyword));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,66 +4,34 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mono.Collections.Generic;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace PowerLauncher.Plugin
|
||||
{
|
||||
public static class QueryBuilder
|
||||
{
|
||||
public static Dictionary<PluginPair, Query> Build(ref string text)
|
||||
public static Dictionary<PluginPair, Query> Build(string text)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
// replace multiple white spaces with one white space
|
||||
var terms = text.Split(new[] { Query.TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (terms.Length == 0)
|
||||
{ // nothing was typed
|
||||
return null;
|
||||
}
|
||||
text = text.Trim();
|
||||
|
||||
// This Dictionary contains the corresponding query for each plugin
|
||||
Dictionary<PluginPair, Query> pluginQueryPair = new Dictionary<PluginPair, Query>();
|
||||
|
||||
var rawQuery = string.Join(Query.TermSeparator, terms);
|
||||
|
||||
// This is the query on removing extra spaces which would be executed by global Plugins
|
||||
text = rawQuery;
|
||||
|
||||
string possibleActionKeyword = terms[0];
|
||||
|
||||
foreach (string pluginActionKeyword in PluginManager.NonGlobalPlugins.Keys)
|
||||
foreach (var plugin in PluginManager.NonGlobalPlugins)
|
||||
{
|
||||
// Using Ordinal since this is used internally
|
||||
if (possibleActionKeyword.StartsWith(pluginActionKeyword, StringComparison.Ordinal))
|
||||
var pluginActionKeyword = plugin.Metadata.ActionKeyword;
|
||||
if (plugin.Metadata.Disabled || !text.StartsWith(pluginActionKeyword, StringComparison.Ordinal))
|
||||
{
|
||||
if (PluginManager.NonGlobalPlugins.TryGetValue(pluginActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
|
||||
{
|
||||
// The search string is the raw query excluding the action keyword
|
||||
string search = rawQuery.Substring(pluginActionKeyword.Length).Trim();
|
||||
|
||||
// To set the terms of the query after removing the action keyword
|
||||
if (possibleActionKeyword.Length > pluginActionKeyword.Length)
|
||||
{
|
||||
// If the first term contains the action keyword, then set the remaining string to be the first term
|
||||
terms[0] = possibleActionKeyword.Substring(pluginActionKeyword.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the first term is the action keyword, then skip it.
|
||||
terms = terms.Skip(1).ToArray();
|
||||
}
|
||||
|
||||
// A new query is constructed for each plugin as they have different action keywords
|
||||
var query = new Query(rawQuery, search, new ReadOnlyCollection<string>(terms), pluginActionKeyword);
|
||||
|
||||
pluginQueryPair.TryAdd(pluginPair, query);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// A new query is constructed for each plugin
|
||||
var query = new Query(text, pluginActionKeyword);
|
||||
pluginQueryPair.TryAdd(plugin, query);
|
||||
}
|
||||
|
||||
// If the user has specified a matching action keyword, then do not
|
||||
|
@ -72,9 +40,9 @@ namespace PowerLauncher.Plugin
|
|||
{
|
||||
foreach (PluginPair globalPlugin in PluginManager.GlobalPlugins)
|
||||
{
|
||||
if (!pluginQueryPair.ContainsKey(globalPlugin))
|
||||
if (!globalPlugin.Metadata.Disabled && !pluginQueryPair.ContainsKey(globalPlugin))
|
||||
{
|
||||
var query = new Query(rawQuery, rawQuery, new ReadOnlyCollection<string>(terms), string.Empty);
|
||||
var query = new Query(text);
|
||||
pluginQueryPair.Add(globalPlugin, query);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace PowerLauncher
|
|||
Log.Info("PT Run settings.json was missing, creating a new one", GetType());
|
||||
|
||||
var defaultSettings = new PowerLauncherSettings();
|
||||
defaultSettings.Plugins = GetPluginsSettings();
|
||||
defaultSettings.Plugins = GetDefaultPluginsSettings();
|
||||
defaultSettings.Save(_settingsUtils);
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ namespace PowerLauncher
|
|||
if (overloadSettings.Plugins == null || !overloadSettings.Plugins.Any())
|
||||
{
|
||||
// Needed to be consistent with old settings
|
||||
overloadSettings.Plugins = GetPluginsSettings();
|
||||
overloadSettings.Plugins = GetDefaultPluginsSettings();
|
||||
_settingsUtils.SaveSettings(overloadSettings.ToJsonString(), PowerLauncherSettings.ModuleName);
|
||||
}
|
||||
else
|
||||
|
@ -91,6 +91,10 @@ namespace PowerLauncher
|
|||
plugin.Metadata.Disabled = setting.Disabled;
|
||||
plugin.Metadata.ActionKeyword = setting.ActionKeyword;
|
||||
plugin.Metadata.IsGlobal = setting.IsGlobal;
|
||||
if (plugin.Plugin is ISettingProvider)
|
||||
{
|
||||
(plugin.Plugin as ISettingProvider).UpdateSettings(setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,13 +105,6 @@ namespace PowerLauncher
|
|||
_settings.Hotkey = openPowerlauncher;
|
||||
}
|
||||
|
||||
var shell = PluginManager.AllPlugins.Find(pp => pp.Metadata.Name == "Shell");
|
||||
if (shell != null)
|
||||
{
|
||||
var shellSettings = shell.Plugin as ISettingProvider;
|
||||
shellSettings.UpdateSettings(overloadSettings);
|
||||
}
|
||||
|
||||
if (_settings.MaxResultsToShow != overloadSettings.Properties.MaximumNumberOfResults)
|
||||
{
|
||||
_settings.MaxResultsToShow = overloadSettings.Properties.MaximumNumberOfResults;
|
||||
|
@ -118,14 +115,6 @@ namespace PowerLauncher
|
|||
_settings.IgnoreHotkeysOnFullscreen = overloadSettings.Properties.IgnoreHotkeysInFullscreen;
|
||||
}
|
||||
|
||||
// Using OrdinalIgnoreCase since this is internal
|
||||
var indexer = PluginManager.AllPlugins.Find(p => p.Metadata.Name.Equals("Windows Indexer", StringComparison.OrdinalIgnoreCase));
|
||||
if (indexer != null)
|
||||
{
|
||||
var indexerSettings = indexer.Plugin as ISettingProvider;
|
||||
indexerSettings.UpdateSettings(overloadSettings);
|
||||
}
|
||||
|
||||
if (_settings.ClearInputOnLaunch != overloadSettings.Properties.ClearInputOnLaunch)
|
||||
{
|
||||
_settings.ClearInputOnLaunch = overloadSettings.Properties.ClearInputOnLaunch;
|
||||
|
@ -184,19 +173,20 @@ namespace PowerLauncher
|
|||
return model.ToString();
|
||||
}
|
||||
|
||||
private static IEnumerable<PowerLauncherPluginSettings> GetPluginsSettings()
|
||||
private static IEnumerable<PowerLauncherPluginSettings> GetDefaultPluginsSettings()
|
||||
{
|
||||
return PluginManager.AllPlugins.Select(x => x.Metadata).Select(x => new PowerLauncherPluginSettings
|
||||
return PluginManager.AllPlugins.Select(x => new PowerLauncherPluginSettings()
|
||||
{
|
||||
Id = x.ID,
|
||||
Name = x.Name,
|
||||
Description = x.Description,
|
||||
Author = x.Author,
|
||||
Disabled = x.Disabled,
|
||||
IsGlobal = x.IsGlobal,
|
||||
ActionKeyword = x.ActionKeyword,
|
||||
IconPathDark = x.IcoPathDark,
|
||||
IconPathLight = x.IcoPathLight,
|
||||
Id = x.Metadata.ID,
|
||||
Name = x.Plugin.Name,
|
||||
Description = x.Plugin.Description,
|
||||
Author = x.Metadata.Author,
|
||||
Disabled = x.Metadata.Disabled,
|
||||
IsGlobal = x.Metadata.IsGlobal,
|
||||
ActionKeyword = x.Metadata.ActionKeyword,
|
||||
IconPathDark = x.Metadata.IcoPathDark,
|
||||
IconPathLight = x.Metadata.IcoPathLight,
|
||||
AdditionalOptions = x.Plugin is ISettingProvider ? (x.Plugin as ISettingProvider).AdditionalOptions : new List<PluginAdditionalOption>(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -493,7 +493,7 @@ namespace PowerLauncher.ViewModel
|
|||
Title = string.Format(CultureInfo.InvariantCulture, title, h.Query),
|
||||
SubTitle = string.Format(CultureInfo.InvariantCulture, time, h.ExecutedDateTime),
|
||||
IcoPath = "Images\\history.png",
|
||||
OriginQuery = new Query { RawQuery = h.Query },
|
||||
OriginQuery = new Query(h.Query),
|
||||
Action = _ =>
|
||||
{
|
||||
SelectedResults = Results;
|
||||
|
@ -531,9 +531,10 @@ namespace PowerLauncher.ViewModel
|
|||
_updateToken = currentCancellationToken;
|
||||
var queryText = QueryText.Trim();
|
||||
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref queryText);
|
||||
var pluginQueryPairs = QueryBuilder.Build(queryText);
|
||||
if (pluginQueryPairs != null && pluginQueryPairs.Count > 0)
|
||||
{
|
||||
queryText = pluginQueryPairs.Values.First().RawQuery;
|
||||
_currentQuery = queryText;
|
||||
Task.Run(
|
||||
() =>
|
||||
|
@ -557,13 +558,9 @@ namespace PowerLauncher.ViewModel
|
|||
{
|
||||
var plugin = pluginQueryItem.Key;
|
||||
var query = pluginQueryItem.Value;
|
||||
|
||||
if (!plugin.Metadata.Disabled)
|
||||
{
|
||||
var results = PluginManager.QueryForPlugin(plugin, query);
|
||||
resultPluginPair.Add((results, plugin.Metadata));
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
var results = PluginManager.QueryForPlugin(plugin, query);
|
||||
resultPluginPair.Add((results, plugin.Metadata));
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
lock (_addResultsLock)
|
||||
|
@ -595,39 +592,36 @@ namespace PowerLauncher.ViewModel
|
|||
{
|
||||
try
|
||||
{
|
||||
if (!plugin.Metadata.Disabled)
|
||||
Query query;
|
||||
pluginQueryPairs.TryGetValue(plugin, out query);
|
||||
|
||||
var results = PluginManager.QueryForPlugin(plugin, query, true);
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
if ((results?.Count ?? 0) != 0)
|
||||
{
|
||||
Query query;
|
||||
pluginQueryPairs.TryGetValue(plugin, out query);
|
||||
|
||||
var results = PluginManager.QueryForPlugin(plugin, query, true);
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
if ((results?.Count ?? 0) != 0)
|
||||
lock (_addResultsLock)
|
||||
{
|
||||
lock (_addResultsLock)
|
||||
// Using CurrentCultureIgnoreCase since this is user facing
|
||||
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
// Using CurrentCultureIgnoreCase since this is user facing
|
||||
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Remove the original results from the plugin
|
||||
Results.Results.RemoveAll(r => r.Result.PluginID == plugin.Metadata.ID);
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
// Remove the original results from the plugin
|
||||
Results.Results.RemoveAll(r => r.Result.PluginID == plugin.Metadata.ID);
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Add the new results from the plugin
|
||||
UpdateResultView(results, queryText, currentCancellationToken);
|
||||
// Add the new results from the plugin
|
||||
UpdateResultView(results, queryText, currentCancellationToken);
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
numResults = Results.Results.Count;
|
||||
Results.Sort();
|
||||
Results.SelectedItem = Results.Results.FirstOrDefault();
|
||||
}
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
numResults = Results.Results.Count;
|
||||
Results.Sort();
|
||||
Results.SelectedItem = Results.Results.FirstOrDefault();
|
||||
}
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
UpdateResultsListViewAfterQuery(queryText, true);
|
||||
}
|
||||
|
||||
currentCancellationToken.ThrowIfCancellationRequested();
|
||||
UpdateResultsListViewAfterQuery(queryText, true);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
|
@ -875,9 +869,8 @@ namespace PowerLauncher.ViewModel
|
|||
Results.Clear();
|
||||
MainWindowVisibility = System.Windows.Visibility.Collapsed;
|
||||
|
||||
// Fix Cold start for plugins
|
||||
string s = "m";
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref s);
|
||||
// Fix Cold start for plugins, "m" is just a random string needed to query results
|
||||
var pluginQueryPairs = QueryBuilder.Build("m");
|
||||
|
||||
// To execute a query corresponding to each plugin
|
||||
foreach (KeyValuePair<PluginPair, Query> pluginQueryItem in pluginQueryPairs)
|
||||
|
|
|
@ -11,5 +11,11 @@ namespace Wox.Plugin
|
|||
List<Result> Query(Query query);
|
||||
|
||||
void Init(PluginInitContext context);
|
||||
|
||||
// Localized name
|
||||
string Name { get; }
|
||||
|
||||
// Localized description
|
||||
string Description { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +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 System.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
|
@ -11,6 +12,8 @@ namespace Wox.Plugin
|
|||
{
|
||||
Control CreateSettingPanel();
|
||||
|
||||
void UpdateSettings(PowerLauncherSettings settings);
|
||||
void UpdateSettings(PowerLauncherPluginSettings settings);
|
||||
|
||||
IEnumerable<PluginAdditionalOption> AdditionalOptions { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@ namespace Wox.Plugin
|
|||
|
||||
public string Language { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string Website { get; set; }
|
||||
|
||||
public bool Disabled { get; set; }
|
||||
|
|
|
@ -19,19 +19,32 @@ namespace Wox.Plugin
|
|||
/// Initializes a new instance of the <see cref="Query"/> class.
|
||||
/// to allow unit tests for plug ins
|
||||
/// </summary>
|
||||
public Query(string rawQuery, string search, ReadOnlyCollection<string> terms, string actionKeyword = "")
|
||||
public Query(string query, string actionKeyword = "")
|
||||
{
|
||||
Search = search;
|
||||
RawQuery = rawQuery;
|
||||
Terms = terms;
|
||||
_query = query;
|
||||
ActionKeyword = actionKeyword;
|
||||
}
|
||||
|
||||
private string _rawQuery;
|
||||
|
||||
/// <summary>
|
||||
/// Gets raw query, this includes action keyword if it has
|
||||
/// We didn't recommend use this property directly. You should always use Search property.
|
||||
/// </summary>
|
||||
public string RawQuery { get; internal set; }
|
||||
public string RawQuery
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rawQuery == null)
|
||||
{
|
||||
_rawQuery = string.Join(Query.TermSeparator, _query.Split(new[] { TermSeparator }, StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
|
||||
return _rawQuery;
|
||||
}
|
||||
}
|
||||
|
||||
private string _search;
|
||||
|
||||
/// <summary>
|
||||
/// Gets search part of a query.
|
||||
|
@ -39,12 +52,41 @@ namespace Wox.Plugin
|
|||
/// Since we allow user to switch a exclusive plugin to generic plugin,
|
||||
/// so this property will always give you the "real" query part of the query
|
||||
/// </summary>
|
||||
public string Search { get; internal set; }
|
||||
public string Search
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_search == null)
|
||||
{
|
||||
_search = RawQuery.Substring(ActionKeyword.Length).Trim();
|
||||
}
|
||||
|
||||
return _search;
|
||||
}
|
||||
}
|
||||
|
||||
private ReadOnlyCollection<string> _terms;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw query splited into a string array.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<string> Terms { get; private set; }
|
||||
public ReadOnlyCollection<string> Terms
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_terms == null)
|
||||
{
|
||||
var terms = _query
|
||||
.Trim()
|
||||
.Substring(ActionKeyword.Length)
|
||||
.Split(new[] { TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
_terms = new ReadOnlyCollection<string>(terms);
|
||||
}
|
||||
|
||||
return _terms;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Query can be splited into multiple terms by whitespace
|
||||
|
@ -102,6 +144,8 @@ namespace Wox.Plugin
|
|||
}
|
||||
}
|
||||
|
||||
private string _query;
|
||||
|
||||
public override string ToString() => RawQuery;
|
||||
|
||||
[Obsolete("Use Search instead, this method will be removed in v1.3.0")]
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mono.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using PowerLauncher.Plugin;
|
||||
|
@ -36,25 +37,8 @@ namespace Wox.Test
|
|||
string searchQuery = "> file.txt file2 file3";
|
||||
|
||||
// Act
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual("> file.txt file2 file3", searchQuery);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void QueryBuilderShouldRemoveExtraSpacesForDisabledNonGlobalPlugin()
|
||||
{
|
||||
// Arrange
|
||||
PluginManager.SetAllPlugins(new List<PluginPair>()
|
||||
{
|
||||
new PluginPair { Metadata = new PluginMetadata() { Disabled = true, ActionKeyword = ">" } },
|
||||
});
|
||||
|
||||
string searchQuery = "> file.txt file2 file3";
|
||||
|
||||
// Act
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
|
||||
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
|
||||
searchQuery = pluginQueryPairs.Values.First().RawQuery;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual("> file.txt file2 file3", searchQuery);
|
||||
|
@ -65,9 +49,14 @@ namespace Wox.Test
|
|||
{
|
||||
// Arrange
|
||||
string searchQuery = "file.txt file2 file3";
|
||||
PluginManager.SetAllPlugins(new List<PluginPair>()
|
||||
{
|
||||
new PluginPair { Metadata = new PluginMetadata() { Disabled = false, IsGlobal = true } },
|
||||
});
|
||||
|
||||
// Act
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
|
||||
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
|
||||
searchQuery = pluginQueryPairs.Values.First().RawQuery;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual("file.txt file2 file3", searchQuery);
|
||||
|
@ -87,10 +76,10 @@ namespace Wox.Test
|
|||
var secondQueryText = "a search";
|
||||
|
||||
// Act
|
||||
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText);
|
||||
var firstPluginQueryPair = QueryBuilder.Build(firstQueryText);
|
||||
var firstQuery = firstPluginQueryPair.GetValueOrDefault(plugin);
|
||||
|
||||
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText);
|
||||
var secondPluginQueryPairs = QueryBuilder.Build(secondQueryText);
|
||||
var secondQuery = secondPluginQueryPairs.GetValueOrDefault(plugin);
|
||||
|
||||
// Assert
|
||||
|
@ -113,14 +102,14 @@ namespace Wox.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
|
||||
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
|
||||
|
||||
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
|
||||
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(AreEqual(firstQuery, new Query { RawQuery = searchQuery, Search = searchQuery.Substring(firstPlugin.Metadata.ActionKeyword.Length), ActionKeyword = firstPlugin.Metadata.ActionKeyword } ));
|
||||
Assert.IsTrue(AreEqual(secondQuery, new Query { RawQuery = searchQuery, Search = searchQuery.Substring(secondPlugin.Metadata.ActionKeyword.Length), ActionKeyword = secondPlugin.Metadata.ActionKeyword }));
|
||||
Assert.IsTrue(AreEqual(firstQuery, new Query(searchQuery, firstPlugin.Metadata.ActionKeyword)));
|
||||
Assert.IsTrue(AreEqual(secondQuery, new Query(searchQuery, secondPlugin.Metadata.ActionKeyword)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -137,7 +126,7 @@ namespace Wox.Test
|
|||
});
|
||||
|
||||
// Act
|
||||
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
|
||||
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
|
||||
|
||||
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
|
||||
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
|
||||
|
@ -147,5 +136,25 @@ namespace Wox.Test
|
|||
Assert.IsTrue(firstQuery.Terms[0].Equals("cd", StringComparison.Ordinal) && firstQuery.Terms[1].Equals("efgh", StringComparison.Ordinal) && firstQuery.Terms.Count == 2);
|
||||
Assert.IsTrue(secondQuery.Terms[0].Equals("efgh", StringComparison.Ordinal) && secondQuery.Terms.Count == 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void QueryBuilderShouldReturnAllPluginsWithTheActionWord()
|
||||
{
|
||||
// Arrange
|
||||
string searchQuery = "!efgh";
|
||||
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "!", ID = "plugin1" } };
|
||||
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "!", ID = "plugin2" } };
|
||||
PluginManager.SetAllPlugins(new List<PluginPair>()
|
||||
{
|
||||
firstPlugin,
|
||||
secondPlugin,
|
||||
});
|
||||
|
||||
// Act
|
||||
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, pluginQueryPairs.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// 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.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PluginAdditionalOption
|
||||
{
|
||||
public string Key { get; set; }
|
||||
|
||||
public string DisplayLabel { get; set; }
|
||||
|
||||
public bool Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
{
|
||||
public class PowerLauncherPluginSettings
|
||||
|
@ -23,5 +25,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
public string IconPathDark { get; set; }
|
||||
|
||||
public string IconPathLight { get; set; }
|
||||
|
||||
public IEnumerable<PluginAdditionalOption> AdditionalOptions { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
[JsonPropertyName("ignore_hotkeys_in_fullscreen")]
|
||||
public bool IgnoreHotkeysInFullscreen { get; set; }
|
||||
|
||||
[JsonPropertyName("disable_drive_detection_warning")]
|
||||
public bool DisableDriveDetectionWarning { get; set; }
|
||||
|
||||
[JsonPropertyName("clear_input_on_launch")]
|
||||
public bool ClearInputOnLaunch { get; set; }
|
||||
|
||||
|
@ -57,7 +54,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
SearchResultPreference = "most_recently_used";
|
||||
SearchTypePreference = "application_name";
|
||||
IgnoreHotkeysInFullscreen = false;
|
||||
DisableDriveDetectionWarning = false;
|
||||
ClearInputOnLaunch = false;
|
||||
MaximumNumberOfResults = 4;
|
||||
Theme = Theme.System;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
public PowerLauncherProperties Properties { get; set; }
|
||||
|
||||
[JsonPropertyName("plugins")]
|
||||
public IEnumerable<PowerLauncherPluginSettings> Plugins { get; set; }
|
||||
public IEnumerable<PowerLauncherPluginSettings> Plugins { get; set; } = new List<PowerLauncherPluginSettings>();
|
||||
|
||||
public PowerLauncherSettings()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
// 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.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
{
|
||||
public class PluginAdditionalOptionViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private PluginAdditionalOption _additionalOption;
|
||||
|
||||
internal PluginAdditionalOptionViewModel(PluginAdditionalOption additionalOption)
|
||||
{
|
||||
_additionalOption = additionalOption;
|
||||
}
|
||||
|
||||
public string DisplayLabel { get => _additionalOption.DisplayLabel; }
|
||||
|
||||
public bool Value
|
||||
{
|
||||
get => _additionalOption.Value;
|
||||
set
|
||||
{
|
||||
if (value != _additionalOption.Value)
|
||||
{
|
||||
_additionalOption.Value = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
{
|
||||
public class PowerLauncherPluginViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private readonly PowerLauncherPluginSettings settings;
|
||||
private readonly Func<bool> isDark;
|
||||
|
||||
public PowerLauncherPluginViewModel(PowerLauncherPluginSettings settings, Func<bool> isDark)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settings), "PowerLauncherPluginSettings object is null");
|
||||
}
|
||||
|
||||
this.settings = settings;
|
||||
this.isDark = isDark;
|
||||
foreach (var item in AdditionalOptions)
|
||||
{
|
||||
item.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
|
||||
{
|
||||
NotifyPropertyChanged(nameof(AdditionalOptions));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get => settings.Id; }
|
||||
|
||||
public string Name { get => settings.Name; }
|
||||
|
||||
public string Description { get => settings.Description; }
|
||||
|
||||
public string Author { get => settings.Author; }
|
||||
|
||||
public bool Disabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.Disabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.Disabled != value)
|
||||
{
|
||||
settings.Disabled = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ShowNotAccessibleWarning));
|
||||
NotifyPropertyChanged(nameof(ShowNotAllowedKeywordWarning));
|
||||
NotifyPropertyChanged(nameof(Enabled));
|
||||
NotifyPropertyChanged(nameof(DisabledOpacity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Enabled => !Disabled;
|
||||
|
||||
public double DisabledOpacity => Disabled ? 0.5 : 1;
|
||||
|
||||
public bool IsGlobal
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.IsGlobal;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.IsGlobal != value)
|
||||
{
|
||||
settings.IsGlobal = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ShowNotAccessibleWarning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ActionKeyword
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.ActionKeyword;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.ActionKeyword != value)
|
||||
{
|
||||
settings.ActionKeyword = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(ShowNotAccessibleWarning));
|
||||
NotifyPropertyChanged(nameof(ShowNotAllowedKeywordWarning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<PluginAdditionalOptionViewModel> _additionalOptions;
|
||||
|
||||
public IEnumerable<PluginAdditionalOptionViewModel> AdditionalOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_additionalOptions == null)
|
||||
{
|
||||
_additionalOptions = settings.AdditionalOptions.Select(x => new PluginAdditionalOptionViewModel(x)).ToList();
|
||||
}
|
||||
|
||||
return _additionalOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAdditionalOptions
|
||||
{
|
||||
get => AdditionalOptions.Any();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name}. {Description}";
|
||||
}
|
||||
|
||||
public string IconPath { get => isDark() ? settings.IconPathDark : settings.IconPathLight; }
|
||||
|
||||
private bool _showAdditionalInfoPanel;
|
||||
|
||||
public bool ShowAdditionalInfoPanel
|
||||
{
|
||||
get => _showAdditionalInfoPanel;
|
||||
set
|
||||
{
|
||||
if (value != _showAdditionalInfoPanel)
|
||||
{
|
||||
_showAdditionalInfoPanel = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public bool ShowNotAccessibleWarning
|
||||
{
|
||||
get => !Disabled && !IsGlobal && string.IsNullOrWhiteSpace(ActionKeyword);
|
||||
}
|
||||
|
||||
private static readonly List<string> NotAllowedKeywords = new List<string>()
|
||||
{
|
||||
"~", @"\", @"\\",
|
||||
};
|
||||
|
||||
public bool ShowNotAllowedKeywordWarning
|
||||
{
|
||||
get => !Disabled && NotAllowedKeywords.Contains(ActionKeyword);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,11 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using ManagedCommon;
|
||||
|
@ -28,11 +32,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
|
||||
private readonly SendCallback callback;
|
||||
|
||||
private readonly Func<bool> isDark;
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
|
||||
public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, int defaultKeyCode)
|
||||
public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc, int defaultKeyCode, Func<bool> isDark)
|
||||
{
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
this.isDark = isDark;
|
||||
|
||||
// To obtain the general Settings configurations of PowerToys
|
||||
if (settingsRepository == null)
|
||||
|
@ -81,6 +88,17 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
_isSystemThemeRadioButtonChecked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var plugin in Plugins)
|
||||
{
|
||||
plugin.PropertyChanged += OnPluginInfoChange;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPluginInfoChange(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
OnPropertyChanged(nameof(ShowAllPluginsDisabledWarning));
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
public PowerLauncherViewModel(PowerLauncherSettings settings, SendCallback callback)
|
||||
|
@ -110,6 +128,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
{
|
||||
GeneralSettingsConfig.Enabled.PowerLauncher = value;
|
||||
OnPropertyChanged(nameof(EnablePowerLauncher));
|
||||
OnPropertyChanged(nameof(ShowAllPluginsDisabledWarning));
|
||||
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
||||
SendConfigMSG(outgoing.ToString());
|
||||
}
|
||||
|
@ -343,21 +362,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public bool DisableDriveDetectionWarning
|
||||
private ObservableCollection<PowerLauncherPluginViewModel> _plugins;
|
||||
|
||||
public ObservableCollection<PowerLauncherPluginViewModel> Plugins
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.Properties.DisableDriveDetectionWarning;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.Properties.DisableDriveDetectionWarning != value)
|
||||
if (_plugins == null)
|
||||
{
|
||||
settings.Properties.DisableDriveDetectionWarning = value;
|
||||
UpdateSettings();
|
||||
_plugins = new ObservableCollection<PowerLauncherPluginViewModel>(settings.Plugins.Select(x => new PowerLauncherPluginViewModel(x, isDark)));
|
||||
}
|
||||
|
||||
return _plugins;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowAllPluginsDisabledWarning
|
||||
{
|
||||
get => EnablePowerLauncher && Plugins.All(x => x.Disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,13 +66,12 @@ namespace ViewModelTests
|
|||
|
||||
// Initialise View Model with test Config files
|
||||
Func<string, int> sendMockIPCConfigMSG = msg => { return 0; };
|
||||
PowerLauncherViewModel viewModel = new PowerLauncherViewModel(mockSettingsUtils, generalSettingsRepository, sendMockIPCConfigMSG, 32);
|
||||
PowerLauncherViewModel viewModel = new PowerLauncherViewModel(mockSettingsUtils, generalSettingsRepository, sendMockIPCConfigMSG, 32, () => true);
|
||||
|
||||
// Verify that the old settings persisted
|
||||
Assert.AreEqual(originalGeneralSettings.Enabled.PowerLauncher, viewModel.EnablePowerLauncher);
|
||||
Assert.AreEqual(originalSettings.Properties.ClearInputOnLaunch, viewModel.ClearInputOnLaunch);
|
||||
Assert.AreEqual(originalSettings.Properties.CopyPathLocation.ToString(), viewModel.CopyPathLocation.ToString());
|
||||
Assert.AreEqual(originalSettings.Properties.DisableDriveDetectionWarning, viewModel.DisableDriveDetectionWarning);
|
||||
Assert.AreEqual(originalSettings.Properties.IgnoreHotkeysInFullscreen, viewModel.IgnoreHotkeysInFullScreen);
|
||||
Assert.AreEqual(originalSettings.Properties.MaximumNumberOfResults, viewModel.MaximumNumberOfResults);
|
||||
Assert.AreEqual(originalSettings.Properties.OpenPowerLauncher.ToString(), viewModel.OpenPowerLauncher.ToString());
|
||||
|
@ -173,16 +172,5 @@ namespace ViewModelTests
|
|||
Assert.IsTrue(mockSettings.Properties.OverrideWinkeyR);
|
||||
Assert.IsFalse(mockSettings.Properties.OverrideWinkeyS);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DriveDetectionViewModelWhenSetMustUpdateOverrides()
|
||||
{
|
||||
// Act
|
||||
viewModel.DisableDriveDetectionWarning = true;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, sendCallbackMock.TimesSent);
|
||||
Assert.IsTrue(mockSettings.Properties.DisableDriveDetectionWarning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
</ResourceDictionary.MergedDictionaries>
|
||||
<converters:ModuleEnabledToForegroundConverter x:Key="ModuleEnabledToForegroundConverter"/>
|
||||
|
||||
|
||||
<SolidColorBrush x:Key="DarkForegroundDisabledBrush">#66FFFFFF</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="DarkForegroundBrush">#FFFFFFFF</SolidColorBrush>
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
// 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.Globalization;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.Toolkit.Win32.UI.XamlHost;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI
|
||||
|
@ -18,5 +20,15 @@ namespace Microsoft.PowerToys.Settings.UI
|
|||
var coreWindowInterop = Interop.GetInterop(coreWindow);
|
||||
NativeMethods.ShowWindow(coreWindowInterop.WindowHandle, Interop.SW_HIDE);
|
||||
}
|
||||
|
||||
public static bool IsDarkTheme()
|
||||
{
|
||||
var selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture);
|
||||
var defaultTheme = new Windows.UI.ViewManagement.UISettings();
|
||||
var uiTheme = defaultTheme.GetColorValue(Windows.UI.ViewManagement.UIColorType.Background).ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000");
|
||||
}
|
||||
|
||||
private static ISettingsUtils settingsUtils = new SettingsUtils();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,23 +13,11 @@ namespace Microsoft.PowerToys.Settings.UI.Converters
|
|||
{
|
||||
public sealed class ModuleEnabledToForegroundConverter : IValueConverter
|
||||
{
|
||||
private readonly ISettingsUtils settingsUtils = new SettingsUtils();
|
||||
|
||||
private string selectedTheme = string.Empty;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
bool isEnabled = (bool)value;
|
||||
|
||||
var defaultTheme = new Windows.UI.ViewManagement.UISettings();
|
||||
|
||||
// Using InvariantCulture as this is an internal string and expected to be in hexadecimal
|
||||
var uiTheme = defaultTheme.GetColorValue(Windows.UI.ViewManagement.UIColorType.Background).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
// Normalize strings to uppercase according to Fxcop
|
||||
selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpperInvariant();
|
||||
|
||||
if (selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000"))
|
||||
if (App.IsDarkTheme())
|
||||
{
|
||||
// DARK
|
||||
if (isEnabled)
|
||||
|
|
|
@ -291,9 +291,6 @@
|
|||
<data name="PowerLauncher_IgnoreHotkeysInFullScreen.Content" xml:space="preserve">
|
||||
<value>Ignore shortcuts in fullscreen mode</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_DisableDriveDetectionWarning.Content" xml:space="preserve">
|
||||
<value>Disable drive detection warning for the file search plugin</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_ClearInputOnLaunch.Content" xml:space="preserve">
|
||||
<value>Clear the previous query on launch</value>
|
||||
</data>
|
||||
|
@ -949,4 +946,35 @@
|
|||
<data name="FancyZones_OverlappingZonesLabel.Text" xml:space="preserve">
|
||||
<value>When multiple zones overlap:</value>
|
||||
</data>
|
||||
</root>
|
||||
<data name="PowerLauncher_Plugins.Text" xml:space="preserve">
|
||||
<value>Plugins</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_ActionKeyword.Text" xml:space="preserve">
|
||||
<value>Direct activation phrase</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_AuthoredBy.Text" xml:space="preserve">
|
||||
<value>Authored by</value>
|
||||
<comment>example: Authored by Microsoft</comment>
|
||||
</data>
|
||||
<data name="PowerLauncher_IncludeInGlobalResult.Content" xml:space="preserve">
|
||||
<value>Include in global result</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_EnablePluginToggle.AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Enable plugin</value>
|
||||
</data>
|
||||
<data name="Run_AdditionalOptions.Text" xml:space="preserve">
|
||||
<value>Additional options</value>
|
||||
</data>
|
||||
<data name="Run_NotAccessibleWarning.Text" xml:space="preserve">
|
||||
<value>Please define an activation phrase or allow this plugin for the global results to use it.</value>
|
||||
</data>
|
||||
<data name="Run_AllPluginsDisabled.Text" xml:space="preserve">
|
||||
<value>PowerToys Run can't provide any results without plugins. Please enable at least one plugin.</value>
|
||||
</data>
|
||||
<data name="Run_NotAllowedActionKeyword.Text" xml:space="preserve">
|
||||
<value>This activation phrase overrides the behavior of other plugins. Please change it to something else.</value>
|
||||
</data>
|
||||
<data name="Run_PluginUseDescription.Text" xml:space="preserve">
|
||||
<value>You can include or remove each plugin from the global results, change the direct activation phrase and configure additional options.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
<Page
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Views"
|
||||
xmlns:ViewModels="using:Microsoft.PowerToys.Settings.UI.Library.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.Views.PowerLauncherPage"
|
||||
xmlns:viewModel="using:Microsoft.PowerToys.Settings.UI.ViewModels"
|
||||
xmlns:CustomControls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
AutomationProperties.LandmarkType="Main">
|
||||
<Page.Resources>
|
||||
<converters:BoolToObjectConverter x:Key="BoolToVisibilityConverter" TrueValue="Visible" FalseValue="Collapsed"/>
|
||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid RowSpacing="{StaticResource DefaultRowSpacing}">
|
||||
<Grid RowSpacing="{StaticResource DefaultRowSpacing}" >
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="LayoutVisualStates">
|
||||
<VisualState x:Name="WideLayout">
|
||||
|
@ -144,15 +148,9 @@
|
|||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
|
||||
/>
|
||||
|
||||
<CheckBox x:Uid="PowerLauncher_DisableDriveDetectionWarning"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.DisableDriveDetectionWarning}"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
|
||||
/>
|
||||
<TextBlock x:Uid="Appearance_GroupSettings"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}" />
|
||||
|
||||
<!-- We cannot navigate to all the radio buttons using the arrow keys because of an XYNavigation issue in the RadioButtons control.
|
||||
The screen reader does not read the heading when we tab into a radio button, even though the LabeledBy automation property is set.
|
||||
Link to the issue in the winui repository - https://github.com/microsoft/microsoft-ui-xaml/issues/3156 -->
|
||||
|
@ -176,6 +174,158 @@
|
|||
<TextBlock x:Uid="Windows_Color_Settings" />
|
||||
</HyperlinkButton>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock x:Uid="PowerLauncher_Plugins"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Foreground="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher, Converter={StaticResource ModuleEnabledToForegroundConverter}}"/>
|
||||
|
||||
<TextBlock x:Uid="Run_PluginUseDescription"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
TextWrapping="Wrap"/>
|
||||
|
||||
<TextBlock x:Uid="Run_AllPluginsDisabled"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{x:Bind ViewModel.ShowAllPluginsDisabledWarning, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
TextWrapping="Wrap"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<ListView ItemsSource="{x:Bind Path=ViewModel.Plugins, Mode=OneWay}"
|
||||
IsItemClickEnabled="True"
|
||||
SelectionChanged="PluginsListView_SelectionChanged"
|
||||
x:Name="PluginsListView"
|
||||
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}"
|
||||
Margin="-12,12,0,0">
|
||||
<ListView.Resources>
|
||||
<SolidColorBrush x:Key="ListViewItemBackgroundSelected"
|
||||
Color="{ThemeResource SystemChromeLowColor}" />
|
||||
<SolidColorBrush x:Key="ListViewItemBackgroundSelectedPointerOver"
|
||||
Color="{ThemeResource SystemChromeLowColor}" />
|
||||
<SolidColorBrush x:Key="ListViewItemBackgroundSelectedPressed"
|
||||
Color="{ThemeResource SystemChromeLowColor}" />
|
||||
</ListView.Resources>
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="Padding"
|
||||
Value="0,0,0,0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="ViewModels:PowerLauncherPluginViewModel" x:DefaultBindMode="OneWay">
|
||||
<StackPanel Orientation="Vertical" Background="Transparent"
|
||||
Padding="0,12,0,12">
|
||||
<Grid ColumnSpacing="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="60" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="52" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Source="{x:Bind IconPath}"
|
||||
Width="36"
|
||||
Opacity="{x:Bind DisabledOpacity, Mode=OneWay}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Margin="12,0,12,0"
|
||||
Height="36" />
|
||||
|
||||
<StackPanel Orientation="Vertical"
|
||||
Grid.Column="1" Margin="0,0,12,0">
|
||||
<TextBlock FontSize="18"
|
||||
Text="{x:Bind Path=Name}"
|
||||
Opacity="{x:Bind DisabledOpacity}"/>
|
||||
<TextBlock FontSize="12"
|
||||
Opacity="{x:Bind DisabledOpacity}"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
Text="{x:Bind Description}"
|
||||
TextWrapping="Wrap"/>
|
||||
<TextBlock
|
||||
x:Uid="Run_NotAccessibleWarning"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{x:Bind ShowNotAccessibleWarning, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock
|
||||
x:Uid="Run_NotAllowedActionKeyword"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{x:Bind ShowNotAllowedKeywordWarning, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
|
||||
<ToggleSwitch x:Uid="PowerLauncher_EnablePluginToggle"
|
||||
x:Name="ToggleSwitch"
|
||||
HorizontalAlignment="Center"
|
||||
IsOn="{x:Bind Path=Disabled, Converter={StaticResource BoolNegationConverter}, Mode=TwoWay}"
|
||||
Grid.Column="2" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel Margin="60,24,0,24"
|
||||
x:Name="AdditionalInfoPanel"
|
||||
Visibility="{x:Bind ShowAdditionalInfoPanel, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<CheckBox x:Uid="PowerLauncher_IncludeInGlobalResult"
|
||||
IsChecked="{x:Bind Path=IsGlobal, Mode=TwoWay}"
|
||||
IsEnabled="{x:Bind Enabled, Mode=OneWay}"/>
|
||||
|
||||
<TextBlock x:Uid="PowerLauncher_ActionKeyword"
|
||||
x:Name="ActionKeywordHeaderTextBlock"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Opacity="{x:Bind DisabledOpacity}"/>
|
||||
<TextBox x:Uid="PowerLauncher_ActionKeyword"
|
||||
Text="{x:Bind Path=ActionKeyword, Mode=TwoWay}"
|
||||
Width="86"
|
||||
Margin="0,6,0,0"
|
||||
AutomationProperties.LabeledBy="{Binding ElementName=ActionKeywordHeaderTextBlock}"
|
||||
HorizontalAlignment="Left"
|
||||
IsEnabled="{x:Bind Enabled, Mode=OneWay}"/>
|
||||
|
||||
<TextBlock x:Name="AdditionalOptionsTextBlock"
|
||||
x:Uid="Run_AdditionalOptions"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Visibility="{x:Bind ShowAdditionalOptions, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"
|
||||
Opacity="{x:Bind DisabledOpacity}"/>
|
||||
|
||||
<ListView ItemsSource="{x:Bind Path=AdditionalOptions}"
|
||||
SelectionMode="None"
|
||||
IsEnabled="{x:Bind Enabled, Mode=OneWay}">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment"
|
||||
Value="Stretch" />
|
||||
<Setter Property="Padding"
|
||||
Value="0,0,0,0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="ViewModels:PluginAdditionalOptionViewModel">
|
||||
<CheckBox Content="{x:Bind Path=DisplayLabel}"
|
||||
IsChecked="{x:Bind Path=Value, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<TextBlock FontSize="12"
|
||||
Opacity="{x:Bind DisabledOpacity}"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,12,0">
|
||||
<Run x:Uid="PowerLauncher_AuthoredBy" />
|
||||
<Run FontWeight="SemiBold" Text="{x:Bind Author}" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
|
||||
<RelativePanel x:Name="SidePanel"
|
||||
|
@ -229,4 +379,4 @@
|
|||
</StackPanel>
|
||||
</RelativePanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
</Page>
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
|
@ -22,7 +24,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
|||
{
|
||||
InitializeComponent();
|
||||
var settingsUtils = new SettingsUtils();
|
||||
ViewModel = new PowerLauncherViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, (int)Windows.System.VirtualKey.Space);
|
||||
ViewModel = new PowerLauncherViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, (int)Windows.System.VirtualKey.Space, App.IsDarkTheme);
|
||||
DataContext = ViewModel;
|
||||
|
||||
var loader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
|
||||
|
@ -43,6 +45,15 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
|||
Helpers.StartProcessHelper.Start(Helpers.StartProcessHelper.ColorsSettings);
|
||||
}
|
||||
|
||||
private void PluginsListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var selectedPlugin = (sender as ListView)?.SelectedItem;
|
||||
foreach (var plugin in ViewModel.Plugins)
|
||||
{
|
||||
plugin.ShowAdditionalInfoPanel = plugin == selectedPlugin;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public Tuple<string, string> SelectedSearchResultPreference
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue