From 4a9e920a1c0b222eceb76c9dd0f65febed96e7d6 Mon Sep 17 00:00:00 2001 From: Mykhailo Pylyp Date: Fri, 26 Feb 2021 13:21:58 +0200 Subject: [PATCH] [PowerToys Run] Plugin manager (#9872) --- .../Plugins/Microsoft.Plugin.Folder/Main.cs | 10 +- .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../Microsoft.Plugin.Folder/plugin.json | 1 - .../Plugins/Microsoft.Plugin.Indexer/Main.cs | 20 ++- .../Properties/Resources.Designer.cs | 13 +- .../Properties/Resources.resx | 7 +- .../Microsoft.Plugin.Indexer/plugin.json | 1 - .../ProgramArgumentParserTests.cs | 5 +- .../Plugins/Microsoft.Plugin.Program/Main.cs | 4 + .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../Microsoft.Plugin.Program/plugin.json | 1 - .../Plugins/Microsoft.Plugin.Shell/Main.cs | 10 +- .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../Microsoft.Plugin.Shell/plugin.json | 1 - .../Plugins/Microsoft.Plugin.Uri/Main.cs | 4 + .../Properties/Resources.Designer.cs | 4 +- .../Properties/Resources.resx | 4 +- .../Plugins/Microsoft.Plugin.Uri/plugin.json | 1 - .../Microsoft.Plugin.WindowWalker/Main.cs | 4 + .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../Microsoft.Plugin.WindowWalker/plugin.json | 1 - .../Main.cs | 4 + .../Properties/Resources.Designer.cs | 27 +-- .../Properties/Resources.resx | 2 +- .../plugin.json | 1 - .../Main.cs | 4 + .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../plugin.json | 1 - .../Main.cs | 4 + .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../plugin.json | 1 - .../ImageTests.cs | 6 +- .../QueryTests.cs | 3 +- .../Main.cs | 4 + .../Properties/Resources.Designer.cs | 2 +- .../Properties/Resources.resx | 2 +- .../plugin.json | 1 - .../PowerLauncher/Plugin/PluginManager.cs | 9 +- .../PowerLauncher/Plugin/QueryBuilder.cs | 56 ++---- .../launcher/PowerLauncher/SettingsWatcher.cs | 46 ++--- .../PowerLauncher/ViewModel/MainViewModel.cs | 67 ++++--- src/modules/launcher/Wox.Plugin/IPlugin.cs | 6 + .../launcher/Wox.Plugin/ISettingProvider.cs | 5 +- .../launcher/Wox.Plugin/PluginMetadata.cs | 2 - src/modules/launcher/Wox.Plugin/Query.cs | 58 +++++- .../launcher/Wox.Test/QueryBuilderTest.cs | 61 ++++--- .../PluginAdditionalOption.cs | 15 ++ .../PowerLauncherPluginSettings.cs | 4 + .../PowerLauncherProperties.cs | 4 - .../PowerLauncherSettings.cs | 2 +- .../PluginAdditionalOptionViewModel.cs | 41 +++++ .../PowerLauncherPluginViewModel.cs | 170 ++++++++++++++++++ .../ViewModels/PowerLauncherViewModel.cs | 42 +++-- .../PowerLauncherViewModelTest.cs | 14 +- .../Microsoft.PowerToys.Settings.UI/App.xaml | 1 - .../App.xaml.cs | 12 ++ .../ModuleEnabledToForegroundConverter.cs | 14 +- .../Strings/en-us/Resources.resw | 36 +++- .../Views/PowerLauncherPage.xaml | 170 ++++++++++++++++-- .../Views/PowerLauncherPage.xaml.cs | 13 +- 66 files changed, 749 insertions(+), 276 deletions(-) create mode 100644 src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PluginAdditionalOption.cs create mode 100644 src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs create mode 100644 src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Main.cs index 802461cd8..26348d121 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Main.cs @@ -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); diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.Designer.cs index 8e429befb..73ff8c79c 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.Designer.cs @@ -124,7 +124,7 @@ namespace Microsoft.Plugin.Folder.Properties { } /// - /// 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 '~'.. /// public static string wox_plugin_folder_plugin_description { get { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx index 0889f3193..452d6d257 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx @@ -121,7 +121,7 @@ Folder - Open favorite folder from PowerToys Run directly + Navigates folders starting from a drive letter 'C:\' or from the user home '~'. Copy path (Ctrl+C) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json index 41ecec040..b806f8294 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json @@ -3,7 +3,6 @@ "ActionKeyword": "", "IsGlobal": true, "Name": "Folder", - "Description": "Search and open folders", "Author": "qianlifeng", "Version": "1.0.0", "Language": "csharp", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Main.cs index f7adf252f..7f000e028 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Main.cs @@ -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 AdditionalOptions => new List() + { + 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() diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.Designer.cs index ce29d12cb..5bb2c1b32 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.Designer.cs @@ -60,6 +60,15 @@ namespace Microsoft.Plugin.Indexer.Properties { } } + /// + /// Looks up a localized string similar to Disable drive detection warning. + /// + public static string disable_drive_detection_warning { + get { + return ResourceManager.GetString("disable_drive_detection_warning", resourceCulture); + } + } + /// /// Looks up a localized string similar to Fail to set text in clipboard. /// @@ -151,7 +160,7 @@ namespace Microsoft.Plugin.Indexer.Properties { } /// - /// Looks up a localized string similar to Returns files and folders. + /// Looks up a localized string similar to Searches files and folders.. /// public static string Microsoft_plugin_indexer_plugin_description { get { @@ -160,7 +169,7 @@ namespace Microsoft.Plugin.Indexer.Properties { } /// - /// Looks up a localized string similar to Windows Indexer. + /// Looks up a localized string similar to Windows Search. /// public static string Microsoft_plugin_indexer_plugin_name { get { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.resx index dfa4703b1..74e7eb5c6 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.resx @@ -151,12 +151,15 @@ Fail to open folder at - Returns files and folders + Searches files and folders. - Windows Indexer + Windows Search Search + + Disable drive detection warning + \ No newline at end of file diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json index 8c74ccc20..b98d4d08e 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json @@ -3,7 +3,6 @@ "ActionKeyword": "?", "IsGlobal": true, "Name": "Windows Indexer", - "Description": "Search for files and folders", "Author": "Microsoft", "Version": "1.0.0", "Language": "csharp", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs index 8420568d5..aa8178ddc 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs @@ -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(splittedSearchString), string.Empty); + var query = new Query(inputQuery); // Act string program = null, programArguments = null; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs index 722b973f8..f2d573786 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs @@ -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 _settingsStorage; private bool _disposed; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.Designer.cs index d80fc7f98..8e5eb9d98 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.Designer.cs @@ -178,7 +178,7 @@ namespace Microsoft.Plugin.Program.Properties { } /// - /// Looks up a localized string similar to Search programs in PowerToys Run. + /// Looks up a localized string similar to Searches programs.. /// public static string wox_plugin_program_plugin_description { get { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.resx index 01a5d1cd8..76792e555 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.resx @@ -130,7 +130,7 @@ Program - Search programs in PowerToys Run + Searches programs. Application diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json index f52f8f0b8..3b7fa88c8 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json @@ -3,7 +3,6 @@ "ActionKeyword": ".", "IsGlobal": true, "Name": "Program", - "Description": "Search for programs", "Author": "qianlifeng", "Version": "1.0.0", "Language": "csharp", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs index b63a907f4..b0173a37b 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs @@ -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) - { - } } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.Designer.cs index 3f697994e..84a65186d 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.Designer.cs @@ -97,7 +97,7 @@ namespace Microsoft.Plugin.Shell.Properties { } /// - /// 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').. /// public static string wox_plugin_cmd_plugin_description { get { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.resx index 1380d9ec3..7f76e408d 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.resx @@ -121,7 +121,7 @@ Shell - Allows to execute system commands from PowerToys Run. Commands should start with > + Executes commands (e.g 'ping', 'cmd'). this command has been executed {0} times diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/plugin.json index c8782912b..d38d25985 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/plugin.json @@ -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", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Main.cs index ab20682d8..39688d3bc 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Main.cs @@ -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 LoadContextMenus(Result selectedResult) { return new List(0); diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.Designer.cs index b261dfcda..83bde72d7 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.Designer.cs @@ -70,7 +70,7 @@ namespace Microsoft.Plugin.Uri.Properties { } /// - /// Looks up a localized string similar to Handles urls. + /// Looks up a localized string similar to Opens URLs and UNC network shares.. /// public static string Microsoft_plugin_uri_plugin_description { get { @@ -79,7 +79,7 @@ namespace Microsoft.Plugin.Uri.Properties { } /// - /// Looks up a localized string similar to Url Handler. + /// Looks up a localized string similar to URI Handler. /// public static string Microsoft_plugin_uri_plugin_name { get { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.resx index d67444de7..567a259c9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.resx @@ -121,10 +121,10 @@ Failed to open URL - Handles urls + Opens URLs and UNC network shares. - Url Handler + URI Handler Open in browser diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json index 2e6179188..f6b619e34 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json @@ -3,7 +3,6 @@ "ActionKeyword": "//", "IsGlobal": true, "Name": "Windows Uri Handler", - "Description": "Handles urls", "Author": "Microsoft", "Version": "1.0.0", "Language": "csharp", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs index d89a0a234..3463fafdd 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs @@ -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; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.Designer.cs index 10aa9a217..490951c71 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.Designer.cs @@ -61,7 +61,7 @@ namespace Microsoft.Plugin.WindowWalker.Properties { } /// - /// 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.. /// public static string wox_plugin_windowwalker_plugin_description { get { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.resx index 91d5b0b8a..6df18426c 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.resx @@ -121,7 +121,7 @@ Window Walker - Alt-Tab alternative enabling searching through your windows. + Switches between open windows. Running diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json index 585c3e64f..c12c91732 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json @@ -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", diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs index 4b8957d0c..87d60488c 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs @@ -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 Query(Query query) diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs index e8def7b22..50464bdb7 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.Designer.cs @@ -9,6 +9,9 @@ //------------------------------------------------------------------------------ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -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() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// @@ -42,7 +45,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties { return resourceMan; } } - + /// /// 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; } } - + /// /// Looks up a localized string similar to Copy failed, please try later. /// @@ -65,7 +68,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties { return ResourceManager.GetString("wox_plugin_calculator_copy_failed", resourceCulture); } } - + /// /// Looks up a localized string similar to Copy this number to the clipboard. /// @@ -74,7 +77,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties { return ResourceManager.GetString("wox_plugin_calculator_copy_number_to_clipboard", resourceCulture); } } - + /// /// Looks up a localized string similar to Expression wrong or incomplete (Did you forget some parentheses?). /// @@ -83,7 +86,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties { return ResourceManager.GetString("wox_plugin_calculator_expression_not_complete", resourceCulture); } } - + /// /// Looks up a localized string similar to Not a number (NaN). /// @@ -92,16 +95,16 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties { return ResourceManager.GetString("wox_plugin_calculator_not_a_number", resourceCulture); } } - + /// - /// 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).. /// public static string wox_plugin_calculator_plugin_description { get { return ResourceManager.GetString("wox_plugin_calculator_plugin_description", resourceCulture); } } - + /// /// Looks up a localized string similar to Calculator. /// diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx index a14e94328..c118d804a 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx @@ -121,7 +121,7 @@ Calculator - Allows you to do mathematical calculations. (Try 5*3-2 in PowerToys Run) + Does mathematical calculations (e.g. 5*3-2). Not a number (NaN) diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/plugin.json b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/plugin.json index 616bf7be4..3c78e8c18 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/plugin.json @@ -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", diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Main.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Main.cs index 7a1310d55..2e5cc81bf 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Main.cs @@ -42,6 +42,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry /// private bool _disposed; + public string Name => Resources.PluginTitle; + + public string Description => Resources.PluginDescription; + /// /// Initializes a new instance of the class. /// diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.Designer.cs index 60f6e5aa3..27a74cc21 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.Designer.cs @@ -133,7 +133,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Properties { } /// - /// Looks up a localized string similar to Search inside the Windows Registry. + /// Looks up a localized string similar to Navigates inside the Windows Registry.. /// internal static string PluginDescription { get { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.resx index 7a97ac5ec..2eea1a107 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.resx @@ -121,7 +121,7 @@ Registry Plugin - Search inside the Windows Registry + Navigates inside the Windows Registry. "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" diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/plugin.json b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/plugin.json index 5e9c6fe67..082e47b56 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/plugin.json @@ -3,7 +3,6 @@ "ActionKeyword": ":", "IsGlobal": false, "Name": "Registry", - "Description": "Search inside the Windows Registry", "Author": "TobiasSekan", "Version": "1.0.0", "Language": "csharp", diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Main.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Main.cs index 5a05b7836..77400479a 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Main.cs @@ -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; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs index b1344a056..c20f760c0 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs @@ -97,7 +97,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Properties { } /// - /// Looks up a localized string similar to Manages Windows services. + /// Looks up a localized string similar to Manages Windows services.. /// internal static string wox_plugin_service_plugin_description { get { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx index 42efb3e05..9114d7bcb 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx @@ -130,7 +130,7 @@ Pausing - Manages Windows services + Manages Windows services. Service diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/plugin.json b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/plugin.json index 215001033..6833dc8a9 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/plugin.json @@ -3,7 +3,6 @@ "ActionKeyword": "!", "IsGlobal": false, "Name": "Service", - "Description": "Manages Windows services", "Author": "davidegiacometti", "Version": "1.0.0", "Language": "csharp", diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs index 953e90283..33464e280 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs @@ -32,8 +32,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests // Setup Mock
main = new Mock
(); main.Object.IconTheme = "dark"; - string[] terms = { typedString }; - Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection(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 = new Mock
(); main.Object.IconTheme = "light"; - string[] terms = { typedString }; - Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection(terms), string.Empty); + Query expectedQuery = new Query(typedString); // Act var result = main.Object.Query(expectedQuery).FirstOrDefault().IcoPath; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs index 17d94cbd1..75dd2d9ab 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs @@ -30,8 +30,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests { // Setup Mock
main = new Mock
(); - string[] terms = { typedString }; - Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection(terms), string.Empty); + Query expectedQuery = new Query(typedString); // Act var result = main.Object.Query(expectedQuery).FirstOrDefault().SubTitle; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs index 0c618544d..137924648 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs @@ -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; diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.Designer.cs index f33c0e500..32a2f9506 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.Designer.cs @@ -115,7 +115,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.Properties { } /// - /// 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').. /// internal static string Microsoft_plugin_sys_plugin_description { get { diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.resx index 874a6540d..0e64ff766 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.resx @@ -142,7 +142,7 @@ This should align to the action in Windows of a locking your computer. - Provides Windows related commands, shutdown, lock, sleep .... + Executes system commands (e.g. 'shutdown', 'lock', 'sleep'). 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. diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/plugin.json b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/plugin.json index c294a2194..30811cbad 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/plugin.json @@ -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", diff --git a/src/modules/launcher/PowerLauncher/Plugin/PluginManager.cs b/src/modules/launcher/PowerLauncher/Plugin/PluginManager.cs index 9b0d55aef..8280527ab 100644 --- a/src/modules/launcher/PowerLauncher/Plugin/PluginManager.cs +++ b/src/modules/launcher/PowerLauncher/Plugin/PluginManager.cs @@ -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 NonGlobalPlugins + public static IEnumerable 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)); } } diff --git a/src/modules/launcher/PowerLauncher/Plugin/QueryBuilder.cs b/src/modules/launcher/PowerLauncher/Plugin/QueryBuilder.cs index 72bcac327..54b03d428 100644 --- a/src/modules/launcher/PowerLauncher/Plugin/QueryBuilder.cs +++ b/src/modules/launcher/PowerLauncher/Plugin/QueryBuilder.cs @@ -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 Build(ref string text) + public static Dictionary 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 pluginQueryPair = new Dictionary(); - - 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(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(terms), string.Empty); + var query = new Query(text); pluginQueryPair.Add(globalPlugin, query); } } diff --git a/src/modules/launcher/PowerLauncher/SettingsWatcher.cs b/src/modules/launcher/PowerLauncher/SettingsWatcher.cs index ed56fffdd..3c8deb5b1 100644 --- a/src/modules/launcher/PowerLauncher/SettingsWatcher.cs +++ b/src/modules/launcher/PowerLauncher/SettingsWatcher.cs @@ -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 GetPluginsSettings() + private static IEnumerable 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(), }); } } diff --git a/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs index 98277540f..ee5ca761d 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs @@ -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 pluginQueryItem in pluginQueryPairs) diff --git a/src/modules/launcher/Wox.Plugin/IPlugin.cs b/src/modules/launcher/Wox.Plugin/IPlugin.cs index 0af80e079..464480c06 100644 --- a/src/modules/launcher/Wox.Plugin/IPlugin.cs +++ b/src/modules/launcher/Wox.Plugin/IPlugin.cs @@ -11,5 +11,11 @@ namespace Wox.Plugin List Query(Query query); void Init(PluginInitContext context); + + // Localized name + string Name { get; } + + // Localized description + string Description { get; } } } diff --git a/src/modules/launcher/Wox.Plugin/ISettingProvider.cs b/src/modules/launcher/Wox.Plugin/ISettingProvider.cs index d4fd3559c..a2802a4d4 100644 --- a/src/modules/launcher/Wox.Plugin/ISettingProvider.cs +++ b/src/modules/launcher/Wox.Plugin/ISettingProvider.cs @@ -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 AdditionalOptions { get; } } } diff --git a/src/modules/launcher/Wox.Plugin/PluginMetadata.cs b/src/modules/launcher/Wox.Plugin/PluginMetadata.cs index 9d0a1c550..5407459f3 100644 --- a/src/modules/launcher/Wox.Plugin/PluginMetadata.cs +++ b/src/modules/launcher/Wox.Plugin/PluginMetadata.cs @@ -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; } diff --git a/src/modules/launcher/Wox.Plugin/Query.cs b/src/modules/launcher/Wox.Plugin/Query.cs index dc7f4e860..99d850eba 100644 --- a/src/modules/launcher/Wox.Plugin/Query.cs +++ b/src/modules/launcher/Wox.Plugin/Query.cs @@ -19,19 +19,32 @@ namespace Wox.Plugin /// Initializes a new instance of the class. /// to allow unit tests for plug ins /// - public Query(string rawQuery, string search, ReadOnlyCollection terms, string actionKeyword = "") + public Query(string query, string actionKeyword = "") { - Search = search; - RawQuery = rawQuery; - Terms = terms; + _query = query; ActionKeyword = actionKeyword; } + private string _rawQuery; + /// /// Gets raw query, this includes action keyword if it has /// We didn't recommend use this property directly. You should always use Search property. /// - 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; /// /// 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 /// - public string Search { get; internal set; } + public string Search + { + get + { + if (_search == null) + { + _search = RawQuery.Substring(ActionKeyword.Length).Trim(); + } + + return _search; + } + } + + private ReadOnlyCollection _terms; /// /// Gets the raw query splited into a string array. /// - public ReadOnlyCollection Terms { get; private set; } + public ReadOnlyCollection Terms + { + get + { + if (_terms == null) + { + var terms = _query + .Trim() + .Substring(ActionKeyword.Length) + .Split(new[] { TermSeparator }, StringSplitOptions.RemoveEmptyEntries); + + _terms = new ReadOnlyCollection(terms); + } + + return _terms; + } + } /// /// 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")] diff --git a/src/modules/launcher/Wox.Test/QueryBuilderTest.cs b/src/modules/launcher/Wox.Test/QueryBuilderTest.cs index 1729fa65e..fee875690 100644 --- a/src/modules/launcher/Wox.Test/QueryBuilderTest.cs +++ b/src/modules/launcher/Wox.Test/QueryBuilderTest.cs @@ -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() - { - 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() + { + 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() + { + firstPlugin, + secondPlugin, + }); + + // Act + var pluginQueryPairs = QueryBuilder.Build(searchQuery); + + // Assert + Assert.AreEqual(2, pluginQueryPairs.Count); + } } } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PluginAdditionalOption.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PluginAdditionalOption.cs new file mode 100644 index 000000000..81987e5db --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PluginAdditionalOption.cs @@ -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; } + } +} diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherPluginSettings.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherPluginSettings.cs index edbb0ff24..4d4145738 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherPluginSettings.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherPluginSettings.cs @@ -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 AdditionalOptions { get; set; } } } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherProperties.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherProperties.cs index 4bc5a774e..6723300b2 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherProperties.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherProperties.cs @@ -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; diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherSettings.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherSettings.cs index b7bb48597..b1e4cec04 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherSettings.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerLauncherSettings.cs @@ -18,7 +18,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library public PowerLauncherProperties Properties { get; set; } [JsonPropertyName("plugins")] - public IEnumerable Plugins { get; set; } + public IEnumerable Plugins { get; set; } = new List(); public PowerLauncherSettings() { diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs new file mode 100644 index 000000000..8fb7ca525 --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PluginAdditionalOptionViewModel.cs @@ -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)); + } + } +} diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs new file mode 100644 index 000000000..feb1bf9b6 --- /dev/null +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherPluginViewModel.cs @@ -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 isDark; + + public PowerLauncherPluginViewModel(PowerLauncherPluginSettings settings, Func 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 _additionalOptions; + + public IEnumerable 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 NotAllowedKeywords = new List() + { + "~", @"\", @"\\", + }; + + public bool ShowNotAllowedKeywordWarning + { + get => !Disabled && NotAllowedKeywords.Contains(ActionKeyword); + } + } +} diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs index 44e66ffb1..668fe902e 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerLauncherViewModel.cs @@ -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 isDark; + private Func SendConfigMSG { get; } - public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, int defaultKeyCode) + public PowerLauncherViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, int defaultKeyCode, Func 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 _plugins; + + public ObservableCollection Plugins { get { - return settings.Properties.DisableDriveDetectionWarning; - } - - set - { - if (settings.Properties.DisableDriveDetectionWarning != value) + if (_plugins == null) { - settings.Properties.DisableDriveDetectionWarning = value; - UpdateSettings(); + _plugins = new ObservableCollection(settings.Plugins.Select(x => new PowerLauncherPluginViewModel(x, isDark))); } + + return _plugins; } } + + public bool ShowAllPluginsDisabledWarning + { + get => EnablePowerLauncher && Plugins.All(x => x.Disabled); + } } } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs index edbc50a4e..5ae17e606 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerLauncherViewModelTest.cs @@ -66,13 +66,12 @@ namespace ViewModelTests // Initialise View Model with test Config files Func 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); - } } } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml b/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml index ed95d11c6..2055310eb 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml @@ -18,7 +18,6 @@ - #66FFFFFF #FFFFFFFF diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml.cs index e54e7f6a4..2d786308a 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/App.xaml.cs @@ -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.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(); } } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Converters/ModuleEnabledToForegroundConverter.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Converters/ModuleEnabledToForegroundConverter.cs index e35908e09..2b1c72a76 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Converters/ModuleEnabledToForegroundConverter.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Converters/ModuleEnabledToForegroundConverter.cs @@ -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.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpperInvariant(); - - if (selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000")) + if (App.IsDarkTheme()) { // DARK if (isEnabled) diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index 8af1c6b2d..8339b2de8 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -291,9 +291,6 @@ Ignore shortcuts in fullscreen mode - - Disable drive detection warning for the file search plugin - Clear the previous query on launch @@ -949,4 +946,35 @@ When multiple zones overlap: - \ No newline at end of file + + Plugins + + + Direct activation phrase + + + Authored by + example: Authored by Microsoft + + + Include in global result + + + Enable plugin + + + Additional options + + + Please define an activation phrase or allow this plugin for the global results to use it. + + + PowerToys Run can't provide any results without plugins. Please enable at least one plugin. + + + This activation phrase overrides the behavior of other plugins. Please change it to something else. + + + You can include or remove each plugin from the global results, change the direct activation phrase and configure additional options. + + diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml index b5f37419e..810a0a1cb 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml @@ -1,18 +1,22 @@ + + + + - + @@ -144,15 +148,9 @@ IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.EnablePowerLauncher}" /> - - @@ -176,6 +174,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml.cs index f47fbe88e..89410e35e 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerLauncherPage.xaml.cs @@ -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.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, (int)Windows.System.VirtualKey.Space); + ViewModel = new PowerLauncherViewModel(settingsUtils, SettingsRepository.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 SelectedSearchResultPreference {