From df0f310ddda3d177c93148ba06db4dda1921b84f Mon Sep 17 00:00:00 2001 From: bao-qian Date: Wed, 4 Nov 2015 21:35:04 +0000 Subject: [PATCH 1/9] Replace Dispose with Lambda 1. Faster 2. Fix #361 --- Plugins/Wox.Plugin.Program/Programs.cs | 11 +++--- Wox.Core/Plugin/PluginManager.cs | 37 ++++++++++--------- Wox.Infrastructure/Timeit.cs | 50 ++++++++++++++------------ Wox/App.xaml.cs | 4 +-- Wox/ImageLoader/ImageLoader.cs | 18 +++++----- Wox/SettingWindow.xaml.cs | 4 +-- 6 files changed, 67 insertions(+), 57 deletions(-) diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 8e2349e43..45b31e0a1 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -70,15 +70,12 @@ namespace Wox.Plugin.Program { this.context = context; this.context.API.ResultItemDropEvent += API_ResultItemDropEvent; - using (new Timeit("Preload programs")) + Timeit.StopwatchDebug("Preload programs", () => { programs = ProgramCacheStorage.Instance.Programs; - } - Debug.WriteLine(string.Format("Preload {0} programs from cache", programs.Count)); - using (new Timeit("Program Index")) - { - IndexPrograms(); - } + }); + Debug.WriteLine($"Preload {programs.Count} programs from cache"); + Timeit.StopwatchDebug("Program Index", IndexPrograms); } void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs e) diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 56b8693c6..5413d2465 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; @@ -91,7 +92,7 @@ namespace Wox.Core.Plugin PluginPair pair = pluginPair; ThreadPool.QueueUserWorkItem(o => { - using (var time = new Timeit($"Plugin init: {pair.Metadata.Name}")) + var milliseconds = Timeit.Stopwatch($"Plugin init: {pair.Metadata.Name}", () => { pair.Plugin.Init(new PluginInitContext { @@ -99,8 +100,8 @@ namespace Wox.Core.Plugin Proxy = HttpProxy.Instance, API = API }); - pair.InitTime = time.Current; - } + }); + pair.InitTime = milliseconds; InternationalizationManager.Instance.UpdatePluginMetadataTranslations(pair); }); } @@ -138,9 +139,13 @@ namespace Wox.Core.Plugin } return new Query { - Terms = terms, RawQuery = rawQuery, ActionKeyword = actionKeyword, Search = search, + Terms = terms, + RawQuery = rawQuery, + ActionKeyword = actionKeyword, + Search = search, // Obsolete value initialisation - ActionName = actionKeyword, ActionParameters = actionParameters.ToList() + ActionName = actionKeyword, + ActionParameters = actionParameters.ToList() }; } @@ -155,10 +160,10 @@ namespace Wox.Core.Plugin if (customizedPluginConfig != null && customizedPluginConfig.Disabled) continue; if (IsInstantQueryPlugin(plugin)) { - using (new Timeit($"Plugin {plugin.Metadata.Name} is executing instant search")) + Timeit.StopwatchDebug($"Instant Query for {plugin.Metadata.Name}", () => { QueryForPlugin(plugin, query); - } + }); } else { @@ -174,15 +179,15 @@ namespace Wox.Core.Plugin { try { - using (var time = new Timeit($"Query For {pair.Metadata.Name}")) - { - var results = pair.Plugin.Query(query) ?? new List(); - results.ForEach(o => { o.PluginID = pair.Metadata.ID; }); - var seconds = time.Current; - pair.QueryCount += 1; - pair.AvgQueryTime = pair.QueryCount == 1 ? seconds : (pair.AvgQueryTime + seconds) / 2; - API.PushResults(query, pair.Metadata, results); - } + List results = new List(); + var milliseconds = Timeit.Stopwatch($"Query for {pair.Metadata.Name}", () => + { + results = pair.Plugin.Query(query) ?? results; + results.ForEach(o => { o.PluginID = pair.Metadata.ID; }); + }); + pair.QueryCount += 1; + pair.AvgQueryTime = pair.QueryCount == 1 ? milliseconds : (pair.AvgQueryTime + milliseconds) / 2; + API.PushResults(query, pair.Metadata, results); } catch (System.Exception e) { diff --git a/Wox.Infrastructure/Timeit.cs b/Wox.Infrastructure/Timeit.cs index 1e804fc2b..425821ecc 100644 --- a/Wox.Infrastructure/Timeit.cs +++ b/Wox.Infrastructure/Timeit.cs @@ -4,35 +4,41 @@ using Wox.Infrastructure.Logger; namespace Wox.Infrastructure { - public class Timeit : IDisposable + public static class Timeit { - private readonly Stopwatch _stopwatch = new Stopwatch(); - private readonly string _name; - - public Timeit(string name) + /// + /// This stopwatch will appear only in Debug mode + /// + public static void StopwatchDebug(string name, Action action) { - _name = name; - _stopwatch.Start(); +#if DEBUG + Stopwatch(name, action); +#else + action(); +#endif } - public long Current + [Conditional("DEBUG")] + private static void WriteTimeInfo(string name, long milliseconds) { - get - { - _stopwatch.Stop(); - long seconds = _stopwatch.ElapsedMilliseconds; - _stopwatch.Start(); - return seconds; - } - } - - - public void Dispose() - { - _stopwatch.Stop(); - string info = _name + " : " + _stopwatch.ElapsedMilliseconds + "ms"; + string info = $"{name} : {milliseconds}ms"; Debug.WriteLine(info); Log.Info(info); } + + /// + /// This stopwatch will also appear only in Debug mode + /// + public static long Stopwatch(string name, Action action) + { + var stopWatch = new Stopwatch(); + stopWatch.Start(); + action(); + stopWatch.Stop(); + var milliseconds = stopWatch.ElapsedMilliseconds; + WriteTimeInfo(name, milliseconds); + return milliseconds; + } + } } diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs index 3e5f2b3f1..ae75a5310 100644 --- a/Wox/App.xaml.cs +++ b/Wox/App.xaml.cs @@ -29,7 +29,7 @@ namespace Wox protected override void OnStartup(StartupEventArgs e) { - using (new Timeit("Startup Time")) + Timeit.StopwatchDebug("Startup Time", () => { base.OnStartup(e); DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException; @@ -39,7 +39,7 @@ namespace Wox Window = new MainWindow(); PluginManager.Init(Window); CommandArgsFactory.Execute(e.Args.ToList()); - } + }); } diff --git a/Wox/ImageLoader/ImageLoader.cs b/Wox/ImageLoader/ImageLoader.cs index 18a5a91d0..daf83cabe 100644 --- a/Wox/ImageLoader/ImageLoader.cs +++ b/Wox/ImageLoader/ImageLoader.cs @@ -48,7 +48,7 @@ namespace Wox.ImageLoader new Int32Rect(0, 0, icon.Width, icon.Height), BitmapSizeOptions.FromEmptyOptions()); } } - catch{} + catch { } return null; } @@ -57,7 +57,7 @@ namespace Wox.ImageLoader { //ImageCacheStroage.Instance.TopUsedImages can be changed during foreach, so we need to make a copy var imageList = new Dictionary(ImageCacheStroage.Instance.TopUsedImages); - using (new Timeit(string.Format("Preload {0} images", imageList.Count))) + Timeit.StopwatchDebug($"Preload {imageList.Count} images", () => { foreach (var image in imageList) { @@ -75,20 +75,22 @@ namespace Wox.ImageLoader } } } - } + }); } public static ImageSource Load(string path, bool addToCache = true) { - using (new Timeit($"Loading image path: {path}")) + if (string.IsNullOrEmpty(path)) return null; + ImageSource img = null; + Timeit.StopwatchDebug($"Loading image path: {path}", () => { - if (string.IsNullOrEmpty(path)) return null; + if (addToCache) { ImageCacheStroage.Instance.Add(path); } - ImageSource img = null; + if (imageCache.ContainsKey(path)) { img = imageCache[path]; @@ -119,8 +121,8 @@ namespace Wox.ImageLoader } } } - return img; - } + }); + return img; } // http://blogs.msdn.com/b/oldnewthing/archive/2011/01/27/10120844.aspx diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index e78ce1b40..60b3d10a4 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -329,10 +329,10 @@ namespace Wox private void OnThemeTabSelected() { - using (new Timeit("theme load")) + Timeit.StopwatchDebug("theme load", () => { var s = Fonts.SystemFontFamilies; - } + }); if (themeTabLoaded) return; From 59a4abff7c8676ac615f90dac5b871167b897577 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Wed, 4 Nov 2015 21:49:36 +0000 Subject: [PATCH 2/9] Better name Timeit.Stopwatch -> Stopwatch.Normal Timeit.StopwatchDebug -> Stopwatch.Debug --- Plugins/Wox.Plugin.Program/Programs.cs | 5 +++-- Wox.Core/Plugin/PluginManager.cs | 7 ++++--- Wox.Infrastructure/{Timeit.cs => Stopwatch.cs} | 12 ++++++------ Wox.Infrastructure/Wox.Infrastructure.csproj | 2 +- Wox/App.xaml.cs | 2 +- Wox/ImageLoader/ImageLoader.cs | 5 +++-- Wox/SettingWindow.xaml.cs | 3 ++- 7 files changed, 20 insertions(+), 16 deletions(-) rename Wox.Infrastructure/{Timeit.cs => Stopwatch.cs} (73%) diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 45b31e0a1..7f9819864 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -8,6 +8,7 @@ using System.Windows; using IWshRuntimeLibrary; using Wox.Infrastructure; using Wox.Plugin.Program.ProgramSources; +using Stopwatch = Wox.Infrastructure.Stopwatch; namespace Wox.Plugin.Program { @@ -70,12 +71,12 @@ namespace Wox.Plugin.Program { this.context = context; this.context.API.ResultItemDropEvent += API_ResultItemDropEvent; - Timeit.StopwatchDebug("Preload programs", () => + Stopwatch.Debug("Preload programs", () => { programs = ProgramCacheStorage.Instance.Programs; }); Debug.WriteLine($"Preload {programs.Count} programs from cache"); - Timeit.StopwatchDebug("Program Index", IndexPrograms); + Stopwatch.Debug("Program Index", IndexPrograms); } void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs e) diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 5413d2465..aba4299a5 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -13,6 +13,7 @@ using Wox.Core.UserSettings; using Wox.Infrastructure; using Wox.Infrastructure.Logger; using Wox.Plugin; +using Stopwatch = Wox.Infrastructure.Stopwatch; namespace Wox.Core.Plugin { @@ -92,7 +93,7 @@ namespace Wox.Core.Plugin PluginPair pair = pluginPair; ThreadPool.QueueUserWorkItem(o => { - var milliseconds = Timeit.Stopwatch($"Plugin init: {pair.Metadata.Name}", () => + var milliseconds = Stopwatch.Normal($"Plugin init: {pair.Metadata.Name}", () => { pair.Plugin.Init(new PluginInitContext { @@ -160,7 +161,7 @@ namespace Wox.Core.Plugin if (customizedPluginConfig != null && customizedPluginConfig.Disabled) continue; if (IsInstantQueryPlugin(plugin)) { - Timeit.StopwatchDebug($"Instant Query for {plugin.Metadata.Name}", () => + Stopwatch.Debug($"Instant Query for {plugin.Metadata.Name}", () => { QueryForPlugin(plugin, query); }); @@ -180,7 +181,7 @@ namespace Wox.Core.Plugin try { List results = new List(); - var milliseconds = Timeit.Stopwatch($"Query for {pair.Metadata.Name}", () => + var milliseconds = Stopwatch.Normal($"Query for {pair.Metadata.Name}", () => { results = pair.Plugin.Query(query) ?? results; results.ForEach(o => { o.PluginID = pair.Metadata.ID; }); diff --git a/Wox.Infrastructure/Timeit.cs b/Wox.Infrastructure/Stopwatch.cs similarity index 73% rename from Wox.Infrastructure/Timeit.cs rename to Wox.Infrastructure/Stopwatch.cs index 425821ecc..c0d828854 100644 --- a/Wox.Infrastructure/Timeit.cs +++ b/Wox.Infrastructure/Stopwatch.cs @@ -4,15 +4,15 @@ using Wox.Infrastructure.Logger; namespace Wox.Infrastructure { - public static class Timeit + public static class Stopwatch { /// /// This stopwatch will appear only in Debug mode /// - public static void StopwatchDebug(string name, Action action) + public static void Debug(string name, Action action) { #if DEBUG - Stopwatch(name, action); + Normal(name, action); #else action(); #endif @@ -22,16 +22,16 @@ namespace Wox.Infrastructure private static void WriteTimeInfo(string name, long milliseconds) { string info = $"{name} : {milliseconds}ms"; - Debug.WriteLine(info); + System.Diagnostics.Debug.WriteLine(info); Log.Info(info); } /// /// This stopwatch will also appear only in Debug mode /// - public static long Stopwatch(string name, Action action) + public static long Normal(string name, Action action) { - var stopWatch = new Stopwatch(); + var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); action(); stopWatch.Stop(); diff --git a/Wox.Infrastructure/Wox.Infrastructure.csproj b/Wox.Infrastructure/Wox.Infrastructure.csproj index a5ef083e7..e3740ee2c 100644 --- a/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -53,11 +53,11 @@ + - diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs index ae75a5310..3c6ea28ab 100644 --- a/Wox/App.xaml.cs +++ b/Wox/App.xaml.cs @@ -29,7 +29,7 @@ namespace Wox protected override void OnStartup(StartupEventArgs e) { - Timeit.StopwatchDebug("Startup Time", () => + Stopwatch.Debug("Startup Time", () => { base.OnStartup(e); DispatcherUnhandledException += ErrorReporting.DispatcherUnhandledException; diff --git a/Wox/ImageLoader/ImageLoader.cs b/Wox/ImageLoader/ImageLoader.cs index daf83cabe..63b30514e 100644 --- a/Wox/ImageLoader/ImageLoader.cs +++ b/Wox/ImageLoader/ImageLoader.cs @@ -8,6 +8,7 @@ using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using Wox.Infrastructure; +using Stopwatch = Wox.Infrastructure.Stopwatch; namespace Wox.ImageLoader { @@ -57,7 +58,7 @@ namespace Wox.ImageLoader { //ImageCacheStroage.Instance.TopUsedImages can be changed during foreach, so we need to make a copy var imageList = new Dictionary(ImageCacheStroage.Instance.TopUsedImages); - Timeit.StopwatchDebug($"Preload {imageList.Count} images", () => + Stopwatch.Debug($"Preload {imageList.Count} images", () => { foreach (var image in imageList) { @@ -82,7 +83,7 @@ namespace Wox.ImageLoader { if (string.IsNullOrEmpty(path)) return null; ImageSource img = null; - Timeit.StopwatchDebug($"Loading image path: {path}", () => + Stopwatch.Debug($"Loading image path: {path}", () => { if (addToCache) diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 60b3d10a4..e8f316a57 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -20,6 +20,7 @@ using Wox.Helper; using Wox.Infrastructure; using Wox.Plugin; using Application = System.Windows.Forms.Application; +using Stopwatch = Wox.Infrastructure.Stopwatch; namespace Wox { @@ -329,7 +330,7 @@ namespace Wox private void OnThemeTabSelected() { - Timeit.StopwatchDebug("theme load", () => + Stopwatch.Debug("theme load", () => { var s = Fonts.SystemFontFamilies; }); From a07d6aa1e7616063f93e7dc23f5c802c300ac96d Mon Sep 17 00:00:00 2001 From: bao-qian Date: Wed, 4 Nov 2015 22:49:40 +0000 Subject: [PATCH 3/9] Enable multiple action keywords See issue #352 --- Plugins/Wox.Plugin.CMD/CMD.cs | 7 +---- .../Wox.Plugin.WebSearch/Languages/en.xaml | 2 +- Plugins/Wox.Plugin.WebSearch/WebSearch.cs | 2 +- .../{WebQueryPlugin.cs => WebSearchPlugin.cs} | 20 ++----------- .../WebSearchSetting.xaml.cs | 10 +++---- .../Wox.Plugin.WebSearch/WebSearchStorage.cs | 6 ++-- .../WebSearchesSetting.xaml | 2 +- .../Wox.Plugin.WebSearch.csproj | 5 ++-- Plugins/Wox.Plugin.WebSearch/plugin.json | 2 +- Wox.Core/Plugin/PluginConfig.cs | 9 ++++-- Wox.Core/Plugin/PluginManager.cs | 29 +++++-------------- .../UserSettings/CustomizedPluginConfig.cs | 3 +- Wox.Plugin/Feature.cs | 2 ++ Wox.Plugin/PluginMetadata.cs | 4 +++ Wox.Plugin/Query.cs | 16 +++++----- ...ActionKeyword.xaml => ActionKeywords.xaml} | 6 ++-- ...Keyword.xaml.cs => ActionKeywords.xaml.cs} | 20 ++++++++----- Wox/App.xaml.cs | 2 +- Wox/Languages/en.xaml | 8 ++--- Wox/Languages/ru.xaml | 8 ++--- Wox/Languages/zh-cn.xaml | 8 ++--- Wox/Languages/zh-tw.xaml | 8 ++--- Wox/SettingWindow.xaml | 4 +-- Wox/SettingWindow.xaml.cs | 15 +++++----- Wox/Wox.csproj | 9 +++--- 25 files changed, 95 insertions(+), 112 deletions(-) rename Plugins/Wox.Plugin.WebSearch/{WebQueryPlugin.cs => WebSearchPlugin.cs} (87%) rename Wox/{ActionKeyword.xaml => ActionKeywords.xaml} (94%) rename Wox/{ActionKeyword.xaml.cs => ActionKeywords.xaml.cs} (71%) diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index de76413c5..0cd255bc3 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -12,7 +12,7 @@ using Control = System.Windows.Controls.Control; namespace Wox.Plugin.CMD { - public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery, IContextMenu + public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IContextMenu { private PluginInitContext context; private bool WinRStroked; @@ -202,11 +202,6 @@ namespace Wox.Plugin.CMD public bool IsInstantQuery(string query) => false; - public bool IsExclusiveQuery(Query query) - { - return query.Search.StartsWith(">"); - } - public List LoadContextMenus(Result selectedResult) { return new List() diff --git a/Plugins/Wox.Plugin.WebSearch/Languages/en.xaml b/Plugins/Wox.Plugin.WebSearch/Languages/en.xaml index 5d8eae569..65fadfbc2 100644 --- a/Plugins/Wox.Plugin.WebSearch/Languages/en.xaml +++ b/Plugins/Wox.Plugin.WebSearch/Languages/en.xaml @@ -23,7 +23,7 @@ Please input title Please input action keyword Please input URL - ActionWord has existed, please input a new one + ActionKeyword has existed, please input a new one Succeed Web Searches diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearch.cs b/Plugins/Wox.Plugin.WebSearch/WebSearch.cs index b05870cb0..f92c580c7 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearch.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearch.cs @@ -6,7 +6,7 @@ namespace Wox.Plugin.WebSearch public class WebSearch { public string Title { get; set; } - public string ActionWord { get; set; } + public string ActionKeyword { get; set; } public string IconPath { get; set; } public string Url { get; set; } public bool Enabled { get; set; } diff --git a/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs b/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs similarity index 87% rename from Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs rename to Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs index 9fc1b9ec4..d4ee840df 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs @@ -8,7 +8,7 @@ using Wox.Plugin.WebSearch.SuggestionSources; namespace Wox.Plugin.WebSearch { - public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery + public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery { private PluginInitContext context; private IDisposable suggestionTimer; @@ -16,17 +16,12 @@ namespace Wox.Plugin.WebSearch public List Query(Query query) { List results = new List(); - if (!query.Search.Contains(' ')) - { - return results; - } - WebSearch webSearch = - WebSearchStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionWord == query.FirstSearch.Trim() && o.Enabled); + WebSearchStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionKeyword == query.ActionKeyword && o.Enabled); if (webSearch != null) { - string keyword = query.SecondToEndSearch; + string keyword = query.ActionKeyword; string title = keyword; string subtitle = context.API.GetTranslation("wox_plugin_websearch_search") + " " + webSearch.Title; if (string.IsNullOrEmpty(keyword)) @@ -122,14 +117,5 @@ namespace Wox.Plugin.WebSearch public bool IsInstantQuery(string query) => false; - public bool IsExclusiveQuery(Query query) - { - var strings = query.RawQuery.Split(' '); - if (strings.Length > 1) - { - return WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == strings[0] && o.Enabled); - } - return false; - } } } diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs b/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs index 7573689dc..e0a8eea54 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs @@ -42,7 +42,7 @@ namespace Wox.Plugin.WebSearch cbEnable.IsChecked = webSearch.Enabled; tbTitle.Text = webSearch.Title; tbUrl.Text = webSearch.Url; - tbActionword.Text = webSearch.ActionWord; + tbActionword.Text = webSearch.ActionKeyword; } private void ShowIcon(string path) @@ -90,7 +90,7 @@ namespace Wox.Plugin.WebSearch if (!update) { - if (WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == action)) + if (WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionKeyword == action)) { string warning = context.API.GetTranslation("wox_plugin_websearch_action_keyword_exist"); MessageBox.Show(warning); @@ -98,7 +98,7 @@ namespace Wox.Plugin.WebSearch } WebSearchStorage.Instance.WebSearches.Add(new WebSearch() { - ActionWord = action, + ActionKeyword = action, Enabled = cbEnable.IsChecked ?? false, IconPath = tbIconPath.Text, Url = url, @@ -109,13 +109,13 @@ namespace Wox.Plugin.WebSearch } else { - if (WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == action && o != updateWebSearch)) + if (WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionKeyword == action && o != updateWebSearch)) { string warning = context.API.GetTranslation("wox_plugin_websearch_action_keyword_exist"); MessageBox.Show(warning); return; } - updateWebSearch.ActionWord = action; + updateWebSearch.ActionKeyword = action; updateWebSearch.IconPath = tbIconPath.Text; updateWebSearch.Enabled = cbEnable.IsChecked ?? false; updateWebSearch.Url = url; diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchStorage.cs b/Plugins/Wox.Plugin.WebSearch/WebSearchStorage.cs index a91a59198..db5d0616b 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchStorage.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchStorage.cs @@ -40,7 +40,7 @@ namespace Wox.Plugin.WebSearch WebSearch googleWebSearch = new WebSearch() { Title = "Google", - ActionWord = "g", + ActionKeyword = "g", IconPath = @"Images\websearch\google.png", Url = "https://www.google.com/search?q={q}", Enabled = true @@ -51,7 +51,7 @@ namespace Wox.Plugin.WebSearch WebSearch wikiWebSearch = new WebSearch() { Title = "Wikipedia", - ActionWord = "wiki", + ActionKeyword = "wiki", IconPath = @"Images\websearch\wiki.png", Url = "http://en.wikipedia.org/wiki/{q}", Enabled = true @@ -61,7 +61,7 @@ namespace Wox.Plugin.WebSearch WebSearch findIcon = new WebSearch() { Title = "FindIcon", - ActionWord = "findicon", + ActionKeyword = "findicon", IconPath = @"Images\websearch\pictures.png", Url = "http://findicons.com/search/{q}", Enabled = true diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchesSetting.xaml b/Plugins/Wox.Plugin.WebSearch/WebSearchesSetting.xaml index 0a823dc7c..8b3de73c8 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchesSetting.xaml +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchesSetting.xaml @@ -22,7 +22,7 @@ - + diff --git a/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj b/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj index 905e83a14..32a1b26e4 100644 --- a/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj +++ b/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj @@ -59,7 +59,7 @@ WebSearchesSetting.xaml - + WebSearchSetting.xaml @@ -135,5 +135,4 @@ --> - - + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.WebSearch/plugin.json b/Plugins/Wox.Plugin.WebSearch/plugin.json index 5132ec9e4..6b0182734 100644 --- a/Plugins/Wox.Plugin.WebSearch/plugin.json +++ b/Plugins/Wox.Plugin.WebSearch/plugin.json @@ -1,6 +1,6 @@ { "ID":"565B73353DBF4806919830B9202EE3BF", - "ActionKeyword":"*", + "ActionKeywords": ["g", "wiki", "findicon"], "Name":"Web Searches", "Description":"Provide the web search ability", "Author":"qianlifeng", diff --git a/Wox.Core/Plugin/PluginConfig.cs b/Wox.Core/Plugin/PluginConfig.cs index 2b89a9653..128d19249 100644 --- a/Wox.Core/Plugin/PluginConfig.cs +++ b/Wox.Core/Plugin/PluginConfig.cs @@ -72,6 +72,10 @@ namespace Wox.Core.Plugin { metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; + // for plugins which doesn't has ActionKeywords key + metadata.ActionKeywords = metadata.ActionKeywords ?? new[] {metadata.ActionKeyword}; + // for plugin still use old ActionKeyword + metadata.ActionKeyword = metadata.ActionKeywords?[0]; } catch (System.Exception) { @@ -112,9 +116,10 @@ namespace Wox.Core.Plugin //replace action keyword if user customized it. var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadata.ID); - if (customizedPluginConfig != null && !string.IsNullOrEmpty(customizedPluginConfig.Actionword)) + if (customizedPluginConfig?.ActionKeywords?.Length > 0) { - metadata.ActionKeyword = customizedPluginConfig.Actionword; + metadata.ActionKeywords = customizedPluginConfig.ActionKeywords; + metadata.ActionKeyword = customizedPluginConfig.ActionKeywords[0]; //todo reenable } return metadata; diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index aba4299a5..6ae8492b2 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Threading; -using System.Windows.Documents; using Wox.Core.Exception; using Wox.Core.i18n; using Wox.Core.UI; @@ -110,7 +108,6 @@ namespace Wox.Core.Plugin ThreadPool.QueueUserWorkItem(o => { instantQueryPlugins = GetPlugins(); - exclusiveSearchPlugins = GetPlugins(); contextMenuPlugins = GetPlugins(); }); } @@ -123,8 +120,8 @@ namespace Wox.Core.Plugin public static Query QueryInit(string text) //todo is that possible to move it into type Query? { // replace multiple white spaces with one white space - var terms = text.Split(new[] { Query.Seperater }, StringSplitOptions.RemoveEmptyEntries); - var rawQuery = string.Join(Query.Seperater, terms.ToArray()); + var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries); + var rawQuery = string.Join(Query.TermSeperater, terms.ToArray()); var actionKeyword = string.Empty; var search = rawQuery; IEnumerable actionParameters = terms; @@ -136,7 +133,7 @@ namespace Wox.Core.Plugin if (!string.IsNullOrEmpty(actionKeyword)) { actionParameters = terms.Skip(1); - search = string.Join(Query.Seperater, actionParameters.ToArray()); + search = string.Join(Query.TermSeperater, actionParameters.ToArray()); } return new Query { @@ -204,7 +201,7 @@ namespace Wox.Core.Plugin private static bool IsVailldActionKeyword(string actionKeyword) { if (string.IsNullOrEmpty(actionKeyword) || actionKeyword == Query.WildcardSign) return false; - PluginPair pair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == actionKeyword); + PluginPair pair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeywords.Contains(actionKeyword)); if (pair == null) return false; var customizedPluginConfig = UserSettingStorage.Instance. CustomizedPluginConfigs.FirstOrDefault(o => o.ID == pair.Metadata.ID); @@ -213,7 +210,7 @@ namespace Wox.Core.Plugin public static bool IsSystemPlugin(PluginMetadata metadata) { - return metadata.ActionKeyword == Query.WildcardSign; + return metadata.ActionKeywords.Contains(Query.WildcardSign); } private static bool IsInstantQueryPlugin(PluginPair plugin) @@ -239,21 +236,11 @@ namespace Wox.Core.Plugin return AllPlugins.Where(p => p.Plugin is T); } - private static PluginPair GetExclusivePlugin(Query query) - { - return exclusiveSearchPlugins.FirstOrDefault(p => ((IExclusiveQuery)p.Plugin).IsExclusiveQuery(query)); - } - - private static PluginPair GetActionKeywordPlugin(Query query) - { - //if a query doesn't contain a vaild action keyword, it should not be a action keword plugin query - if (string.IsNullOrEmpty(query.ActionKeyword)) return null; - return AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.ActionKeyword); - } - private static PluginPair GetNonSystemPlugin(Query query) { - return GetExclusivePlugin(query) ?? GetActionKeywordPlugin(query); + //if a query doesn't contain a vaild action keyword, it should be a query for system plugin + if (string.IsNullOrEmpty(query.ActionKeyword)) return null; + return AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeywords.Contains(query.ActionKeyword)); } private static List GetSystemPlugins() diff --git a/Wox.Core/UserSettings/CustomizedPluginConfig.cs b/Wox.Core/UserSettings/CustomizedPluginConfig.cs index c8e224f89..7bb40c60e 100644 --- a/Wox.Core/UserSettings/CustomizedPluginConfig.cs +++ b/Wox.Core/UserSettings/CustomizedPluginConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Wox.Core.UserSettings { @@ -9,7 +10,7 @@ namespace Wox.Core.UserSettings public string Name { get; set; } - public string Actionword { get; set; } + public string[] ActionKeywords { get; set; } public bool Disabled { get; set; } } diff --git a/Wox.Plugin/Feature.cs b/Wox.Plugin/Feature.cs index 6a1e75368..3a1cbff22 100644 --- a/Wox.Plugin/Feature.cs +++ b/Wox.Plugin/Feature.cs @@ -10,8 +10,10 @@ namespace Wox.Plugin List LoadContextMenus(Result selectedResult); } + [Obsolete("If a plugin has a action keyword, then it is exclusive. This interface will be remove in v1.3.0")] public interface IExclusiveQuery : IFeatures { + [Obsolete("If a plugin has a action keyword, then it is exclusive. This method will be remove in v1.3.0")] bool IsExclusiveQuery(Query query); } diff --git a/Wox.Plugin/PluginMetadata.cs b/Wox.Plugin/PluginMetadata.cs index 7607fda04..ad27a8ea3 100644 --- a/Wox.Plugin/PluginMetadata.cs +++ b/Wox.Plugin/PluginMetadata.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Collections.Generic; namespace Wox.Plugin { @@ -23,8 +24,11 @@ namespace Wox.Plugin public string PluginDirectory { get; set; } + [Obsolete("Use ActionKeywords instead, because Wox now support multiple action keywords. This will be remove in v1.3.0")] public string ActionKeyword { get; set; } + public string[] ActionKeywords { get; set; } + public string IcoPath { get; set; } public override string ToString() diff --git a/Wox.Plugin/Query.cs b/Wox.Plugin/Query.cs index 08422896f..89d8030a0 100644 --- a/Wox.Plugin/Query.cs +++ b/Wox.Plugin/Query.cs @@ -25,14 +25,15 @@ namespace Wox.Plugin /// internal string[] Terms { private get; set; } - public const string Seperater = " "; + public const string TermSeperater = " "; + public const string ActionKeywordSeperater = ";"; /// /// * is used for System Plugin /// public const string WildcardSign = "*"; - internal string ActionKeyword { get; set; } + public string ActionKeyword { get; set; } /// /// Return first search split by space if it has @@ -46,8 +47,8 @@ namespace Wox.Plugin { get { - var index = String.IsNullOrEmpty(ActionKeyword) ? 1 : 2; - return String.Join(Seperater, Terms.Skip(index).ToArray()); + var index = string.IsNullOrEmpty(ActionKeyword) ? 1 : 2; + return string.Join(TermSeperater, Terms.Skip(index).ToArray()); } } @@ -65,18 +66,17 @@ namespace Wox.Plugin { try { - return String.IsNullOrEmpty(ActionKeyword) ? Terms[index] : Terms[index + 1]; + return string.IsNullOrEmpty(ActionKeyword) ? Terms[index] : Terms[index + 1]; } catch (IndexOutOfRangeException) { - return String.Empty; + return string.Empty; } } public override string ToString() => RawQuery; - [Obsolete("Use Search instead, A plugin developer shouldn't care about action name, as it may changed by users. " + - "this property will be removed in v1.3.0")] + [Obsolete("Use ActionKeyword, this property will be removed in v1.3.0")] public string ActionName { get; internal set; } [Obsolete("Use Search instead, this property will be removed in v1.3.0")] diff --git a/Wox/ActionKeyword.xaml b/Wox/ActionKeywords.xaml similarity index 94% rename from Wox/ActionKeyword.xaml rename to Wox/ActionKeywords.xaml index bdc7b6000..6f505062e 100644 --- a/Wox/ActionKeyword.xaml +++ b/Wox/ActionKeywords.xaml @@ -1,7 +1,7 @@ - - Old ActionKeyword: + Old ActionKeywords: diff --git a/Wox/ActionKeyword.xaml.cs b/Wox/ActionKeywords.xaml.cs similarity index 71% rename from Wox/ActionKeyword.xaml.cs rename to Wox/ActionKeywords.xaml.cs index 03beac0ee..25a11c992 100644 --- a/Wox/ActionKeyword.xaml.cs +++ b/Wox/ActionKeywords.xaml.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Windows; using Wox.Core.i18n; using Wox.Core.Plugin; @@ -7,11 +8,11 @@ using Wox.Plugin; namespace Wox { - public partial class ActionKeyword : Window + public partial class ActionKeywords : Window { private PluginMetadata pluginMetadata; - public ActionKeyword(string pluginId) + public ActionKeywords(string pluginId) { InitializeComponent(); PluginPair plugin = PluginManager.GetPlugin(pluginId); @@ -27,7 +28,7 @@ namespace Wox private void ActionKeyword_OnLoaded(object sender, RoutedEventArgs e) { - tbOldActionKeyword.Text = pluginMetadata.ActionKeyword; + tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, pluginMetadata.ActionKeywords); tbAction.Focus(); } @@ -44,15 +45,18 @@ namespace Wox return; } + var actionKeywords = tbAction.Text.Trim().Split(new[] { Query.ActionKeywordSeperater }, StringSplitOptions.RemoveEmptyEntries).ToArray(); //check new action keyword didn't used by other plugin - if (tbAction.Text.Trim() != Query.WildcardSign && PluginManager.AllPlugins.Any(o => o.Metadata.ActionKeyword == tbAction.Text.Trim())) + if (actionKeywords[0] != Query.WildcardSign && PluginManager.AllPlugins. + SelectMany(p => p.Metadata.ActionKeywords). + Any(k => actionKeywords.Contains(k))) { MessageBox.Show(InternationalizationManager.Instance.GetTranslation("newActionKeywordHasBeenAssigned")); return; } - pluginMetadata.ActionKeyword = tbAction.Text.Trim(); + pluginMetadata.ActionKeywords = actionKeywords; var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == pluginMetadata.ID); if (customizedPluginConfig == null) { @@ -61,12 +65,12 @@ namespace Wox Disabled = false, ID = pluginMetadata.ID, Name = pluginMetadata.Name, - Actionword = tbAction.Text.Trim() + ActionKeywords = actionKeywords }); } else { - customizedPluginConfig.Actionword = tbAction.Text.Trim(); + customizedPluginConfig.ActionKeywords = actionKeywords; } UserSettingStorage.Instance.Save(); MessageBox.Show(InternationalizationManager.Instance.GetTranslation("succeed")); diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs index 3c6ea28ab..dc9d15946 100644 --- a/Wox/App.xaml.cs +++ b/Wox/App.xaml.cs @@ -6,7 +6,7 @@ using System.Windows; using Wox.CommandArgs; using Wox.Core.Plugin; using Wox.Helper; -using Wox.Infrastructure; +using Stopwatch = Wox.Infrastructure.Stopwatch; namespace Wox { diff --git a/Wox/Languages/en.xaml b/Wox/Languages/en.xaml index fe252ebb9..28e0a4830 100644 --- a/Wox/Languages/en.xaml +++ b/Wox/Languages/en.xaml @@ -77,13 +77,13 @@ You have activated Wox {0} times - Old Action Keyword - New Action Keyword + Old Action Keyword + New Action Keyword Cancel Done Can't find specified plugin - New Action Keyword can't be empty - New ActionKeyword has been assigned to other plugin, please assign another new action keyword + New Action Keyword can't be empty + New ActionKeywords has been assigned to other plugin, please assign another new action keyword Succeed Use * if you don't want to specify a action keyword diff --git a/Wox/Languages/ru.xaml b/Wox/Languages/ru.xaml index e09aa9bc7..a5f552047 100644 --- a/Wox/Languages/ru.xaml +++ b/Wox/Languages/ru.xaml @@ -77,13 +77,13 @@ Вы воспользовались Wox уже {0} раз - Текущая горячая клавиша - Новая горячая клавиша + Текущая горячая клавиша + Новая горячая клавиша Отменить Подтвердить Не удалось найти заданный плагин - Новая горячая клавиша не может быть пустой - Новая горячая клавиша уже используется другим плагином. Пожалуйста, зайдайте новую + Новая горячая клавиша не может быть пустой + Новая горячая клавиша уже используется другим плагином. Пожалуйста, зайдайте новую Сохранено Используйте * в случае, если вы не хотите задавать конкретную горячую клавишу diff --git a/Wox/Languages/zh-cn.xaml b/Wox/Languages/zh-cn.xaml index 7e0054760..d75714e9f 100644 --- a/Wox/Languages/zh-cn.xaml +++ b/Wox/Languages/zh-cn.xaml @@ -77,13 +77,13 @@ 你已经激活了Wox {0} 次 - 旧触发关键字 - 新触发关键字 + 旧触发关键字 + 新触发关键字 取消 确定 找不到指定的插件 - 新触发关键字不能为空 - 新触发关键字已经被指派给其他插件了,请重新选择一个关键字 + 新触发关键字不能为空 + 新触发关键字已经被指派给其他插件了,请重新选择一个关键字 成功 如果你不想设置触发关键字,可以使用*代替 diff --git a/Wox/Languages/zh-tw.xaml b/Wox/Languages/zh-tw.xaml index 0f1ab8f9c..22562e170 100644 --- a/Wox/Languages/zh-tw.xaml +++ b/Wox/Languages/zh-tw.xaml @@ -77,13 +77,13 @@ 你已經激活了Wox {0} 次 - 舊觸發關鍵字 - 新觸發關鍵字 + 舊觸發關鍵字 + 新觸發關鍵字 取消 確定 找不到指定的插件 - 新觸發關鍵字不能為空 - 新觸發關鍵字已經被指派給其他插件了,請重新選擇一個關鍵字 + 新觸發關鍵字不能為空 + 新觸發關鍵字已經被指派給其他插件了,請重新選擇一個關鍵字 成功 如果你不想設置觸發關鍵字,可以使用*代替 diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index b322cf16d..5d5384101 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -109,7 +109,7 @@ - + @@ -234,7 +234,7 @@ - + diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index e8f316a57..297d9bb6d 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -527,7 +527,7 @@ namespace Wox { provider = pair.Plugin as ISettingProvider; pluginAuthor.Visibility = Visibility.Visible; - pluginActionKeyword.Visibility = Visibility.Visible; + pluginActionKeywords.Visibility = Visibility.Visible; pluginInitTime.Text = string.Format(InternationalizationManager.Instance.GetTranslation("plugin_init_time"), pair.InitTime); pluginQueryTime.Text = @@ -536,7 +536,7 @@ namespace Wox tbOpenPluginDirecoty.Visibility = Visibility.Visible; pluginTitle.Text = pair.Metadata.Name; pluginTitle.Cursor = Cursors.Hand; - pluginActionKeyword.Text = pair.Metadata.ActionKeyword; + pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords); pluginAuthor.Text = InternationalizationManager.Instance.GetTranslation("author") + ": " + pair.Metadata.Author; pluginSubTitle.Text = pair.Metadata.Description; pluginId = pair.Metadata.ID; @@ -578,12 +578,13 @@ namespace Wox var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == id); if (customizedPluginConfig == null) { + // todo when this part will be invoked UserSettingStorage.Instance.CustomizedPluginConfigs.Add(new CustomizedPluginConfig() { Disabled = cbDisabled.IsChecked ?? true, ID = id, Name = name, - Actionword = string.Empty + ActionKeywords = null }); } else @@ -593,7 +594,7 @@ namespace Wox UserSettingStorage.Instance.Save(); } - private void PluginActionKeyword_OnMouseUp(object sender, MouseButtonEventArgs e) + private void PluginActionKeywords_OnMouseUp(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) { @@ -602,10 +603,10 @@ namespace Wox { //third-party plugin string id = pair.Metadata.ID; - ActionKeyword changeKeywordWindow = new ActionKeyword(id); - changeKeywordWindow.ShowDialog(); + ActionKeywords changeKeywordsWindow = new ActionKeywords(id); + changeKeywordsWindow.ShowDialog(); PluginPair plugin = PluginManager.GetPlugin(id); - if (plugin != null) pluginActionKeyword.Text = plugin.Metadata.ActionKeyword; + if (plugin != null) pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords); } } } diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index bcf2772d7..ff6ac6882 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -126,8 +126,8 @@ MSBuild:Compile Designer - - ActionKeyword.xaml + + ActionKeywords.xaml @@ -160,7 +160,7 @@ SettingWindow.xaml - + Designer MSBuild:Compile @@ -374,5 +374,4 @@ cd "$(TargetDir)Plugins" & del /s /q WindowsInput.dll --> - - + \ No newline at end of file From 99d9d14d3b0c20bfdb6e129731e0bcc1a18cda26 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Thu, 5 Nov 2015 20:44:14 +0000 Subject: [PATCH 4/9] Misc 1. Rename 2. Fix progress bar: progress bar should not be loaded when only white spaces typed --- .../PluginIndicator.cs | 2 +- Wox.Core/Plugin/PluginInstaller.cs | 2 +- Wox.Core/Plugin/PluginManager.cs | 86 +++++++++---------- Wox.Core/UI/ResourceMerger.cs | 2 +- Wox.Plugin/Query.cs | 10 ++- Wox/ActionKeywords.xaml.cs | 4 +- Wox/MainWindow.xaml.cs | 6 +- Wox/SettingWindow.xaml.cs | 2 +- 8 files changed, 60 insertions(+), 54 deletions(-) diff --git a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs index e247436eb..d0ad7b9a6 100644 --- a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs +++ b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs @@ -17,7 +17,7 @@ namespace Wox.Plugin.PluginIndicator List results = new List(); if (allPlugins.Count == 0) { - allPlugins = context.API.GetAllPlugins().Where(o => !PluginManager.IsSystemPlugin(o.Metadata)).ToList(); + allPlugins = context.API.GetAllPlugins().Where(o => !PluginManager.IsGlobalPlugin(o.Metadata)).ToList(); } foreach (PluginMetadata metadata in allPlugins.Select(o => o.Metadata)) diff --git a/Wox.Core/Plugin/PluginInstaller.cs b/Wox.Core/Plugin/PluginInstaller.cs index b26254576..ce6318a81 100644 --- a/Wox.Core/Plugin/PluginInstaller.cs +++ b/Wox.Core/Plugin/PluginInstaller.cs @@ -51,7 +51,7 @@ namespace Wox.Core.Plugin string content = string.Format( "Do you want to install following plugin?\r\n\r\nName: {0}\r\nVersion: {1}\r\nAuthor: {2}", plugin.Name, plugin.Version, plugin.Author); - PluginPair existingPlugin = PluginManager.GetPlugin(plugin.ID); + PluginPair existingPlugin = PluginManager.GetPluginForId(plugin.ID); if (existingPlugin != null) { diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 6ae8492b2..749a91f30 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -8,7 +8,6 @@ using Wox.Core.Exception; using Wox.Core.i18n; using Wox.Core.UI; using Wox.Core.UserSettings; -using Wox.Infrastructure; using Wox.Infrastructure.Logger; using Wox.Plugin; using Stopwatch = Wox.Infrastructure.Stopwatch; @@ -21,23 +20,19 @@ namespace Wox.Core.Plugin public static class PluginManager { public const string DirectoryName = "Plugins"; - private static List pluginMetadatas; - private static IEnumerable instantQueryPlugins; - private static IEnumerable exclusiveSearchPlugins; private static IEnumerable contextMenuPlugins; - private static List plugins; /// /// Directories that will hold Wox plugin directory /// private static List pluginDirectories = new List(); - public static IEnumerable AllPlugins - { - get { return plugins; } - private set { plugins = value.OrderBy(o => o.Metadata.Name).ToList(); } - } + public static IEnumerable AllPlugins { get; private set; } + private static List GlobalPlugins { get; set; } + private static List NonGlobalPlugins { get; set; } + + private static IEnumerable InstantQueryPlugins { get; set; } public static IPublicAPI API { private set; get; } public static string PluginDirectory @@ -79,9 +74,9 @@ namespace Wox.Core.Plugin SetupPluginDirectories(); API = api; - pluginMetadatas = PluginConfig.Parse(pluginDirectories); - AllPlugins = (new CSharpPluginLoader().LoadPlugin(pluginMetadatas)). - Concat(new JsonRPCPluginLoader().LoadPlugin(pluginMetadatas)); + var metadatas = PluginConfig.Parse(pluginDirectories); + AllPlugins = (new CSharpPluginLoader().LoadPlugin(metadatas)). + Concat(new JsonRPCPluginLoader().LoadPlugin(metadatas)); //load plugin i18n languages ResourceMerger.ApplyPluginLanguages(); @@ -107,8 +102,21 @@ namespace Wox.Core.Plugin ThreadPool.QueueUserWorkItem(o => { - instantQueryPlugins = GetPlugins(); - contextMenuPlugins = GetPlugins(); + InstantQueryPlugins = GetPluginsForInterface(); + contextMenuPlugins = GetPluginsForInterface(); + GlobalPlugins = new List(); + NonGlobalPlugins = new List(); + foreach (var plugin in AllPlugins) + { + if (IsGlobalPlugin(plugin.Metadata)) + { + GlobalPlugins.Add(plugin); + } + else + { + NonGlobalPlugins.Add(plugin); + } + } }); } @@ -121,18 +129,15 @@ namespace Wox.Core.Plugin { // replace multiple white spaces with one white space var terms = text.Split(new[] { Query.TermSeperater }, StringSplitOptions.RemoveEmptyEntries); - var rawQuery = string.Join(Query.TermSeperater, terms.ToArray()); + var rawQuery = string.Join(Query.TermSeperater, terms); var actionKeyword = string.Empty; var search = rawQuery; - IEnumerable actionParameters = terms; + List actionParameters = terms.ToList(); if (terms.Length == 0) return null; if (IsVailldActionKeyword(terms[0])) { actionKeyword = terms[0]; - } - if (!string.IsNullOrEmpty(actionKeyword)) - { - actionParameters = terms.Skip(1); + actionParameters = terms.Skip(1).ToList(); search = string.Join(Query.TermSeperater, actionParameters.ToArray()); } return new Query @@ -143,14 +148,14 @@ namespace Wox.Core.Plugin Search = search, // Obsolete value initialisation ActionName = actionKeyword, - ActionParameters = actionParameters.ToList() + ActionParameters = actionParameters }; } public static void QueryForAllPlugins(Query query) { - var pluginPairs = GetNonSystemPlugin(query) != null ? - new List { GetNonSystemPlugin(query) } : GetSystemPlugins(); + var pluginPairs = GetPluginForActionKeyword(query.ActionKeyword) != null ? + new List { GetPluginForActionKeyword(query.ActionKeyword) } : GlobalPlugins; foreach (var plugin in pluginPairs) { var customizedPluginConfig = UserSettingStorage.Instance. @@ -200,7 +205,7 @@ namespace Wox.Core.Plugin /// private static bool IsVailldActionKeyword(string actionKeyword) { - if (string.IsNullOrEmpty(actionKeyword) || actionKeyword == Query.WildcardSign) return false; + if (string.IsNullOrEmpty(actionKeyword) || actionKeyword == Query.GlobalPluginWildcardSign) return false; PluginPair pair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeywords.Contains(actionKeyword)); if (pair == null) return false; var customizedPluginConfig = UserSettingStorage.Instance. @@ -208,9 +213,9 @@ namespace Wox.Core.Plugin return customizedPluginConfig == null || !customizedPluginConfig.Disabled; } - public static bool IsSystemPlugin(PluginMetadata metadata) + public static bool IsGlobalPlugin(PluginMetadata metadata) { - return metadata.ActionKeywords.Contains(Query.WildcardSign); + return metadata.ActionKeywords.Contains(Query.GlobalPluginWildcardSign); } private static bool IsInstantQueryPlugin(PluginPair plugin) @@ -218,7 +223,7 @@ namespace Wox.Core.Plugin //any plugin that takes more than 200ms for AvgQueryTime won't be treated as IInstantQuery plugin anymore. return plugin.AvgQueryTime < 200 && plugin.Plugin is IInstantQuery && - instantQueryPlugins.Any(p => p.Metadata.ID == plugin.Metadata.ID); + InstantQueryPlugins.Any(p => p.Metadata.ID == plugin.Metadata.ID); } /// @@ -226,29 +231,24 @@ namespace Wox.Core.Plugin /// /// /// - public static PluginPair GetPlugin(string id) + public static PluginPair GetPluginForId(string id) { return AllPlugins.FirstOrDefault(o => o.Metadata.ID == id); } - public static IEnumerable GetPlugins() where T : IFeatures + private static PluginPair GetPluginForActionKeyword(string actionKeyword) + { + //if a query doesn't contain a vaild action keyword, it should be a query for system plugin + if (string.IsNullOrEmpty(actionKeyword) || actionKeyword == Query.GlobalPluginWildcardSign) return null; + return NonGlobalPlugins.FirstOrDefault(o => o.Metadata.ActionKeywords.Contains(actionKeyword)); + } + + public static IEnumerable GetPluginsForInterface() where T : IFeatures { return AllPlugins.Where(p => p.Plugin is T); } - private static PluginPair GetNonSystemPlugin(Query query) - { - //if a query doesn't contain a vaild action keyword, it should be a query for system plugin - if (string.IsNullOrEmpty(query.ActionKeyword)) return null; - return AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeywords.Contains(query.ActionKeyword)); - } - - private static List GetSystemPlugins() - { - return AllPlugins.Where(o => IsSystemPlugin(o.Metadata)).ToList(); - } - - public static List GetPluginContextMenus(Result result) + public static List GetContextMenusForPlugin(Result result) { var pluginPair = contextMenuPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); var plugin = (IContextMenu)pluginPair?.Plugin; diff --git a/Wox.Core/UI/ResourceMerger.cs b/Wox.Core/UI/ResourceMerger.cs index 818f3073b..2be07e50c 100644 --- a/Wox.Core/UI/ResourceMerger.cs +++ b/Wox.Core/UI/ResourceMerger.cs @@ -39,7 +39,7 @@ namespace Wox.Core.UI internal static void ApplyPluginLanguages() { RemoveResource(PluginManager.DirectoryName); - foreach (var languageFile in PluginManager.GetPlugins(). + foreach (var languageFile in PluginManager.GetPluginsForInterface(). Select(plugin => InternationalizationManager.Instance.GetLanguageFile(((IPluginI18n)plugin.Plugin).GetLanguagesFolder())). Where(file => !string.IsNullOrEmpty(file))) { diff --git a/Wox.Plugin/Query.cs b/Wox.Plugin/Query.cs index 89d8030a0..f5c4145eb 100644 --- a/Wox.Plugin/Query.cs +++ b/Wox.Plugin/Query.cs @@ -25,13 +25,19 @@ namespace Wox.Plugin /// internal string[] Terms { private get; set; } + /// + /// Query can be splited into multiple terms by whitespace + /// public const string TermSeperater = " "; + /// + /// User can set multiple action keywords seperated by ';' + /// public const string ActionKeywordSeperater = ";"; /// - /// * is used for System Plugin + /// '*' is used for System Plugin /// - public const string WildcardSign = "*"; + public const string GlobalPluginWildcardSign = "*"; public string ActionKeyword { get; set; } diff --git a/Wox/ActionKeywords.xaml.cs b/Wox/ActionKeywords.xaml.cs index 25a11c992..9fc60979f 100644 --- a/Wox/ActionKeywords.xaml.cs +++ b/Wox/ActionKeywords.xaml.cs @@ -15,7 +15,7 @@ namespace Wox public ActionKeywords(string pluginId) { InitializeComponent(); - PluginPair plugin = PluginManager.GetPlugin(pluginId); + PluginPair plugin = PluginManager.GetPluginForId(pluginId); if (plugin == null) { MessageBox.Show(InternationalizationManager.Instance.GetTranslation("cannotFindSpecifiedPlugin")); @@ -47,7 +47,7 @@ namespace Wox var actionKeywords = tbAction.Text.Trim().Split(new[] { Query.ActionKeywordSeperater }, StringSplitOptions.RemoveEmptyEntries).ToArray(); //check new action keyword didn't used by other plugin - if (actionKeywords[0] != Query.WildcardSign && PluginManager.AllPlugins. + if (actionKeywords[0] != Query.GlobalPluginWildcardSign && PluginManager.AllPlugins. SelectMany(p => p.Metadata.ActionKeywords). Any(k => actionKeywords.Contains(k))) { diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 5ba8a6f20..1792eafae 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -464,7 +464,7 @@ namespace Wox Query(tbQuery.Text); Dispatcher.DelayInvoke("ShowProgressbar", () => { - if (!queryHasReturn && !string.IsNullOrEmpty(tbQuery.Text) && tbQuery.Text != lastQuery) + if (!string.IsNullOrEmpty(tbQuery.Text.Trim()) && tbQuery.Text != lastQuery && !queryHasReturn) { StartProgress(); } @@ -873,10 +873,10 @@ namespace Wox private void ShowContextMenu(Result result) { - List results = PluginManager.GetPluginContextMenus(result); + List results = PluginManager.GetContextMenusForPlugin(result); results.ForEach(o => { - o.PluginDirectory = PluginManager.GetPlugin(result.PluginID).Metadata.PluginDirectory; + o.PluginDirectory = PluginManager.GetPluginForId(result.PluginID).Metadata.PluginDirectory; o.PluginID = result.PluginID; o.OriginQuery = result.OriginQuery; }); diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 297d9bb6d..a38791465 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -605,7 +605,7 @@ namespace Wox string id = pair.Metadata.ID; ActionKeywords changeKeywordsWindow = new ActionKeywords(id); changeKeywordsWindow.ShowDialog(); - PluginPair plugin = PluginManager.GetPlugin(id); + PluginPair plugin = PluginManager.GetPluginForId(id); if (plugin != null) pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords); } } From 178710dabc11302921efe57c7ea6b0c7d39c3af7 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Thu, 5 Nov 2015 22:47:28 +0000 Subject: [PATCH 5/9] Fix PluginIndicator for multiple action keywords 1. Fixup, part of #352 2. Refactoring --- .../PluginIndicator.cs | 57 +++++++------------ Wox.Core/Plugin/PluginConfig.cs | 2 +- Wox.Core/Plugin/PluginManager.cs | 19 ++----- Wox.Plugin/Query.cs | 2 +- 4 files changed, 27 insertions(+), 53 deletions(-) diff --git a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs index d0ad7b9a6..f7b2bd031 100644 --- a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs +++ b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs @@ -7,47 +7,32 @@ using Wox.Core.UserSettings; namespace Wox.Plugin.PluginIndicator { - public class PluginIndicator : IPlugin,IPluginI18n + public class PluginIndicator : IPlugin, IPluginI18n { - private List allPlugins = new List(); private PluginInitContext context; public List Query(Query query) { - List results = new List(); - if (allPlugins.Count == 0) - { - allPlugins = context.API.GetAllPlugins().Where(o => !PluginManager.IsGlobalPlugin(o.Metadata)).ToList(); - } - - foreach (PluginMetadata metadata in allPlugins.Select(o => o.Metadata)) - { - if (metadata.ActionKeyword.StartsWith(query.Search)) - { - PluginMetadata metadataCopy = metadata; - var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadataCopy.ID); - if (customizedPluginConfig != null && customizedPluginConfig.Disabled) - { - continue; - } - - Result result = new Result - { - Title = metadata.ActionKeyword, - SubTitle = string.Format("Activate {0} plugin", metadata.Name), - Score = 100, - IcoPath = metadata.FullIcoPath, - Action = (c) => - { - context.API.ChangeQuery(metadataCopy.ActionKeyword + " "); - return false; - }, - }; - results.Add(result); - } - } - - return results; + var results = from plugin in PluginManager.NonGlobalPlugins + select plugin.Metadata into metadata + from keyword in metadata.ActionKeywords + where keyword.StartsWith(query.Terms[0]) + let customizedPluginConfig = + UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadata.ID) + where customizedPluginConfig == null || !customizedPluginConfig.Disabled + select new Result + { + Title = keyword, + SubTitle = $"Activate {metadata.Name} plugin", + Score = 100, + IcoPath = metadata.FullIcoPath, + Action = (c) => + { + context.API.ChangeQuery($"{keyword}{Plugin.Query.TermSeperater}"); + return false; + }, + }; + return results.ToList(); } public void Init(PluginInitContext context) diff --git a/Wox.Core/Plugin/PluginConfig.cs b/Wox.Core/Plugin/PluginConfig.cs index 128d19249..a2f34fd79 100644 --- a/Wox.Core/Plugin/PluginConfig.cs +++ b/Wox.Core/Plugin/PluginConfig.cs @@ -119,7 +119,7 @@ namespace Wox.Core.Plugin if (customizedPluginConfig?.ActionKeywords?.Length > 0) { metadata.ActionKeywords = customizedPluginConfig.ActionKeywords; - metadata.ActionKeyword = customizedPluginConfig.ActionKeywords[0]; //todo reenable + metadata.ActionKeyword = customizedPluginConfig.ActionKeywords[0]; } return metadata; diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 749a91f30..ab237af39 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -29,8 +29,8 @@ namespace Wox.Core.Plugin public static IEnumerable AllPlugins { get; private set; } - private static List GlobalPlugins { get; set; } - private static List NonGlobalPlugins { get; set; } + public static IEnumerable GlobalPlugins { get; private set; } + public static IEnumerable NonGlobalPlugins { get; private set; } private static IEnumerable InstantQueryPlugins { get; set; } public static IPublicAPI API { private set; get; } @@ -104,19 +104,8 @@ namespace Wox.Core.Plugin { InstantQueryPlugins = GetPluginsForInterface(); contextMenuPlugins = GetPluginsForInterface(); - GlobalPlugins = new List(); - NonGlobalPlugins = new List(); - foreach (var plugin in AllPlugins) - { - if (IsGlobalPlugin(plugin.Metadata)) - { - GlobalPlugins.Add(plugin); - } - else - { - NonGlobalPlugins.Add(plugin); - } - } + GlobalPlugins = AllPlugins.Where(p => IsGlobalPlugin(p.Metadata)); + NonGlobalPlugins = AllPlugins.Where(p => !IsGlobalPlugin(p.Metadata)); }); } diff --git a/Wox.Plugin/Query.cs b/Wox.Plugin/Query.cs index f5c4145eb..400ae741f 100644 --- a/Wox.Plugin/Query.cs +++ b/Wox.Plugin/Query.cs @@ -23,7 +23,7 @@ namespace Wox.Plugin /// /// The raw query splited into a string array. /// - internal string[] Terms { private get; set; } + public string[] Terms { get; set; } /// /// Query can be splited into multiple terms by whitespace From 00543bca172ea71f745fd8f9790c1f99e736382f Mon Sep 17 00:00:00 2001 From: bao-qian Date: Fri, 6 Nov 2015 01:03:41 +0000 Subject: [PATCH 6/9] Fix PluginManagement plugin for multiple action keyword 1. Fixup, part of #352 2. Windows.Form -> WPF 3. Refactoring --- Plugins/Wox.Plugin.PluginManagement/Main.cs | 187 ++++++++---------- .../Wox.Plugin.PluginManagement.csproj | 6 +- 2 files changed, 84 insertions(+), 109 deletions(-) diff --git a/Plugins/Wox.Plugin.PluginManagement/Main.cs b/Plugins/Wox.Plugin.PluginManagement/Main.cs index a02e44f2c..4e7a68c42 100644 --- a/Plugins/Wox.Plugin.PluginManagement/Main.cs +++ b/Plugins/Wox.Plugin.PluginManagement/Main.cs @@ -7,134 +7,109 @@ using System.Net; using System.Reflection; using System.Text; using System.Threading; -using System.Windows.Forms; +using System.Windows; using Newtonsoft.Json; namespace Wox.Plugin.PluginManagement { - public class Main : IPlugin,IPluginI18n + public class Main : IPlugin, IPluginI18n { private static string APIBASE = "https://api.getwox.com"; private static string PluginConfigName = "plugin.json"; private static string pluginSearchUrl = APIBASE + "/plugin/search/"; + private const string ListCommand = "list"; + private const string InstallCommand = "install"; + private const string UninstallCommand = "uninstall"; private PluginInitContext context; public List Query(Query query) { List results = new List(); + if (string.IsNullOrEmpty(query.Search)) { - results.Add(new Result("install ", "Images\\plugin.png", "search and install wox plugins") - { - Action = e => ChangeToInstallCommand() - }); - results.Add(new Result("uninstall ", "Images\\plugin.png", "uninstall plugin") - { - Action = e => ChangeToUninstallCommand() - }); - results.Add(new Result("list", "Images\\plugin.png", "list plugins installed") - { - Action = e => ChangeToListCommand() - }); + results.Add(ResultForListCommandAutoComplete(query)); + results.Add(ResultForInstallCommandAutoComplete(query)); + results.Add(ResultForUninstallCommandAutoComplete(query)); return results; } - if (!string.IsNullOrEmpty(query.FirstSearch)) + string command = query.FirstSearch.ToLower(); + if (string.IsNullOrEmpty(command)) return results; + + if (command == ListCommand) { - bool hit = false; - switch (query.FirstSearch.ToLower()) - { - case "list": - hit = true; - results = ListInstalledPlugins(); - break; + return ResultForListInstalledPlugins(); + } + if (command == UninstallCommand) + { + return ResultForUnInstallPlugin(query); + } + if (command == InstallCommand) + { + return ResultForInstallPlugin(query); + } - case "uninstall": - hit = true; - results = UnInstallPlugins(query); - break; - - case "install": - hit = true; - if (!string.IsNullOrEmpty(query.SecondSearch)) - { - results = InstallPlugin(query.SecondSearch); - } - break; - } - - if (!hit) - { - if ("install".Contains(query.FirstSearch.ToLower())) - { - results.Add(new Result("install ", "Images\\plugin.png", "search and install wox plugins") - { - Action = e => ChangeToInstallCommand() - }); - } - if ("uninstall".Contains(query.FirstSearch.ToLower())) - { - results.Add(new Result("uninstall ", "Images\\plugin.png", "uninstall plugin") - { - Action = e => ChangeToUninstallCommand() - }); - } - if ("list".Contains(query.FirstSearch.ToLower())) - { - results.Add(new Result("list", "Images\\plugin.png", "list plugins installed") - { - Action = e => ChangeToListCommand() - }); - } - } + if (InstallCommand.Contains(command)) + { + results.Add(ResultForInstallCommandAutoComplete(query)); + } + if (UninstallCommand.Contains(command)) + { + results.Add(ResultForUninstallCommandAutoComplete(query)); + } + if (ListCommand.Contains(command)) + { + results.Add(ResultForListCommandAutoComplete(query)); } return results; } - private bool ChangeToListCommand() + private Result ResultForListCommandAutoComplete(Query query) { - if (context.CurrentPluginMetadata.ActionKeyword == "*") - { - context.API.ChangeQuery("list "); - } - else - { - context.API.ChangeQuery(string.Format("{0} list ", context.CurrentPluginMetadata.ActionKeyword)); - } - return false; + string title = ListCommand; + string subtitle = "list installed plugins"; + return ResultForCommand(query, ListCommand, title, subtitle); } - private bool ChangeToUninstallCommand() + private Result ResultForInstallCommandAutoComplete(Query query) { - if (context.CurrentPluginMetadata.ActionKeyword == "*") - { - context.API.ChangeQuery("uninstall "); - } - else - { - context.API.ChangeQuery(string.Format("{0} uninstall ", context.CurrentPluginMetadata.ActionKeyword)); - } - return false; + string title = $"{InstallCommand} "; + string subtitle = "list installed plugins"; + return ResultForCommand(query, InstallCommand, title, subtitle); } - private bool ChangeToInstallCommand() + private Result ResultForUninstallCommandAutoComplete(Query query) { - if (context.CurrentPluginMetadata.ActionKeyword == "*") - { - context.API.ChangeQuery("install "); - } - else - { - context.API.ChangeQuery(string.Format("{0} install ", context.CurrentPluginMetadata.ActionKeyword)); - } - return false; + string title = $"{UninstallCommand} "; + string subtitle = "list installed plugins"; + return ResultForCommand(query, UninstallCommand, title, subtitle); } - private List InstallPlugin(string queryPluginName) + private Result ResultForCommand(Query query, string command, string title, string subtitle) + { + const string seperater = Plugin.Query.TermSeperater; + var result = new Result + { + Title = title, + IcoPath = "Images\\plugin.png", + SubTitle = subtitle, + Action = e => + { + context.API.ChangeQuery($"{query.ActionKeyword}{seperater}{command}{seperater}"); + return false; + } + }; + return result; + } + + private List ResultForInstallPlugin(Query query) { List results = new List(); - HttpWebResponse response = HttpRequest.CreateGetHttpResponse(pluginSearchUrl + queryPluginName, context.Proxy); + string pluginName = query.SecondSearch; + if (string.IsNullOrEmpty(pluginName)) return results; + HttpWebResponse response = HttpRequest.CreateGetHttpResponse(pluginSearchUrl + pluginName, context.Proxy); Stream s = response.GetResponseStream(); if (s != null) { @@ -154,17 +129,17 @@ namespace Wox.Plugin.PluginManagement foreach (WoxPluginResult r in searchedPlugins) { WoxPluginResult r1 = r; - results.Add(new Result() + results.Add(new Result { Title = r.name, SubTitle = r.description, IcoPath = "Images\\plugin.png", Action = e => { - DialogResult result = MessageBox.Show("Are your sure to install " + r.name + " plugin", - "Install plugin", MessageBoxButtons.YesNo); + MessageBoxResult result = MessageBox.Show("Are your sure to install " + r.name + " plugin", + "Install plugin", MessageBoxButton.YesNo); - if (result == DialogResult.Yes) + if (result == MessageBoxResult.Yes) { string folder = Path.Combine(Path.GetTempPath(), "WoxPluginDownload"); if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); @@ -201,7 +176,7 @@ namespace Wox.Plugin.PluginManagement return results; } - private List UnInstallPlugins(Query query) + private List ResultForUnInstallPlugin(Query query) { List results = new List(); List allInstalledPlugins = context.API.GetAllPlugins().Select(o => o.Metadata).ToList(); @@ -213,15 +188,14 @@ namespace Wox.Plugin.PluginManagement foreach (PluginMetadata plugin in allInstalledPlugins) { - var plugin1 = plugin; - results.Add(new Result() + results.Add(new Result { Title = plugin.Name, SubTitle = plugin.Description, IcoPath = plugin.FullIcoPath, Action = e => { - UnInstallPlugin(plugin1); + UnInstallPlugin(plugin); return false; } }); @@ -232,16 +206,16 @@ namespace Wox.Plugin.PluginManagement private void UnInstallPlugin(PluginMetadata plugin) { string content = string.Format("Do you want to uninstall following plugin?\r\n\r\nName: {0}\r\nVersion: {1}\r\nAuthor: {2}", plugin.Name, plugin.Version, plugin.Author); - if (MessageBox.Show(content, "Wox", MessageBoxButtons.YesNo) == DialogResult.Yes) + if (MessageBox.Show(content, "Wox", MessageBoxButton.YesNo) == MessageBoxResult.Yes) { File.Create(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")).Close(); if (MessageBox.Show( "You have uninstalled plugin " + plugin.Name + " successfully.\r\n Restart Wox to take effect?", "Install plugin", - MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { ProcessStartInfo Info = new ProcessStartInfo(); - Info.Arguments = "/C ping 127.0.0.1 -n 1 && \"" + Application.ExecutablePath + "\""; + Info.Arguments = "/C ping 127.0.0.1 -n 1 && \"" + Assembly.GetExecutingAssembly().Location + "\""; Info.WindowStyle = ProcessWindowStyle.Hidden; Info.CreateNoWindow = true; Info.FileName = "cmd.exe"; @@ -251,14 +225,15 @@ namespace Wox.Plugin.PluginManagement } } - private List ListInstalledPlugins() + private List ResultForListInstalledPlugins() { List results = new List(); foreach (PluginMetadata plugin in context.API.GetAllPlugins().Select(o => o.Metadata)) { - results.Add(new Result() + string actionKeywordString = string.Join(" or ", plugin.ActionKeywords); + results.Add(new Result { - Title = plugin.Name + " - " + plugin.ActionKeyword, + Title = $"{plugin.Name} - Action Keywords: {actionKeywordString}", SubTitle = plugin.Description, IcoPath = plugin.FullIcoPath }); diff --git a/Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj b/Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj index 8508c4e31..f88fb7d91 100644 --- a/Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj +++ b/Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj @@ -38,9 +38,10 @@ ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll True + - + @@ -98,5 +99,4 @@ --> - - + \ No newline at end of file From 7b50febba3ffb8fa9e7dd7212bb42ad4ef40e626 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Fri, 6 Nov 2015 01:19:13 +0000 Subject: [PATCH 7/9] Misc --- Wox.Core/Plugin/PluginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index ab237af39..6123508c3 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -202,7 +202,7 @@ namespace Wox.Core.Plugin return customizedPluginConfig == null || !customizedPluginConfig.Disabled; } - public static bool IsGlobalPlugin(PluginMetadata metadata) + private static bool IsGlobalPlugin(PluginMetadata metadata) { return metadata.ActionKeywords.Contains(Query.GlobalPluginWildcardSign); } From af7beb2c344c9d76881ce8c3c2d890ba113542b8 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Fri, 6 Nov 2015 02:29:32 +0000 Subject: [PATCH 8/9] Improve UI for multiple action keywords See #352 --- Plugins/Wox.Plugin.PluginManagement/Main.cs | 2 +- .../WebSearchSetting.xaml.cs | 3 ++ Wox.Core/Plugin/PluginConfig.cs | 4 +-- .../UserSettings/CustomizedPluginConfig.cs | 2 +- Wox.Plugin/PluginMetadata.cs | 2 +- Wox/ActionKeywords.xaml.cs | 4 +-- Wox/Languages/en.xaml | 2 +- Wox/Languages/ru.xaml | 2 +- Wox/Languages/zh-cn.xaml | 2 +- Wox/Languages/zh-tw.xaml | 2 +- Wox/SettingWindow.xaml | 6 ++-- Wox/SettingWindow.xaml.cs | 36 ++++++++++++++++--- 12 files changed, 48 insertions(+), 19 deletions(-) diff --git a/Plugins/Wox.Plugin.PluginManagement/Main.cs b/Plugins/Wox.Plugin.PluginManagement/Main.cs index 4e7a68c42..934caea04 100644 --- a/Plugins/Wox.Plugin.PluginManagement/Main.cs +++ b/Plugins/Wox.Plugin.PluginManagement/Main.cs @@ -230,7 +230,7 @@ namespace Wox.Plugin.PluginManagement List results = new List(); foreach (PluginMetadata plugin in context.API.GetAllPlugins().Select(o => o.Metadata)) { - string actionKeywordString = string.Join(" or ", plugin.ActionKeywords); + string actionKeywordString = string.Join(" or ", plugin.ActionKeywords.ToArray()); results.Add(new Result { Title = $"{plugin.Name} - Action Keywords: {actionKeywordString}", diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs b/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs index e0a8eea54..d91577d4b 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs @@ -104,6 +104,7 @@ namespace Wox.Plugin.WebSearch Url = url, Title = title }); + context.CurrentPluginMetadata.ActionKeywords.Add(action); string msg = context.API.GetTranslation("wox_plugin_websearch_succeed"); MessageBox.Show(msg); } @@ -120,10 +121,12 @@ namespace Wox.Plugin.WebSearch updateWebSearch.Enabled = cbEnable.IsChecked ?? false; updateWebSearch.Url = url; updateWebSearch.Title= title; + context.CurrentPluginMetadata.ActionKeywords.Add(action); string msg = context.API.GetTranslation("wox_plugin_websearch_succeed"); MessageBox.Show(msg); } WebSearchStorage.Instance.Save(); + settingWindow.ReloadWebSearchView(); Close(); } diff --git a/Wox.Core/Plugin/PluginConfig.cs b/Wox.Core/Plugin/PluginConfig.cs index a2f34fd79..63abe41ff 100644 --- a/Wox.Core/Plugin/PluginConfig.cs +++ b/Wox.Core/Plugin/PluginConfig.cs @@ -73,7 +73,7 @@ namespace Wox.Core.Plugin metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; // for plugins which doesn't has ActionKeywords key - metadata.ActionKeywords = metadata.ActionKeywords ?? new[] {metadata.ActionKeyword}; + metadata.ActionKeywords = metadata.ActionKeywords ?? new List {metadata.ActionKeyword}; // for plugin still use old ActionKeyword metadata.ActionKeyword = metadata.ActionKeywords?[0]; } @@ -116,7 +116,7 @@ namespace Wox.Core.Plugin //replace action keyword if user customized it. var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadata.ID); - if (customizedPluginConfig?.ActionKeywords?.Length > 0) + if (customizedPluginConfig?.ActionKeywords?.Count > 0) { metadata.ActionKeywords = customizedPluginConfig.ActionKeywords; metadata.ActionKeyword = customizedPluginConfig.ActionKeywords[0]; diff --git a/Wox.Core/UserSettings/CustomizedPluginConfig.cs b/Wox.Core/UserSettings/CustomizedPluginConfig.cs index 7bb40c60e..bce1fd9bc 100644 --- a/Wox.Core/UserSettings/CustomizedPluginConfig.cs +++ b/Wox.Core/UserSettings/CustomizedPluginConfig.cs @@ -10,7 +10,7 @@ namespace Wox.Core.UserSettings public string Name { get; set; } - public string[] ActionKeywords { get; set; } + public List ActionKeywords { get; set; } public bool Disabled { get; set; } } diff --git a/Wox.Plugin/PluginMetadata.cs b/Wox.Plugin/PluginMetadata.cs index ad27a8ea3..0aa27f6ea 100644 --- a/Wox.Plugin/PluginMetadata.cs +++ b/Wox.Plugin/PluginMetadata.cs @@ -27,7 +27,7 @@ namespace Wox.Plugin [Obsolete("Use ActionKeywords instead, because Wox now support multiple action keywords. This will be remove in v1.3.0")] public string ActionKeyword { get; set; } - public string[] ActionKeywords { get; set; } + public List ActionKeywords { get; set; } public string IcoPath { get; set; } diff --git a/Wox/ActionKeywords.xaml.cs b/Wox/ActionKeywords.xaml.cs index 9fc60979f..06a70fdfb 100644 --- a/Wox/ActionKeywords.xaml.cs +++ b/Wox/ActionKeywords.xaml.cs @@ -28,7 +28,7 @@ namespace Wox private void ActionKeyword_OnLoaded(object sender, RoutedEventArgs e) { - tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, pluginMetadata.ActionKeywords); + tbOldActionKeyword.Text = string.Join(Query.ActionKeywordSeperater, pluginMetadata.ActionKeywords.ToArray()); tbAction.Focus(); } @@ -45,7 +45,7 @@ namespace Wox return; } - var actionKeywords = tbAction.Text.Trim().Split(new[] { Query.ActionKeywordSeperater }, StringSplitOptions.RemoveEmptyEntries).ToArray(); + var actionKeywords = tbAction.Text.Trim().Split(new[] { Query.ActionKeywordSeperater }, StringSplitOptions.RemoveEmptyEntries).ToList(); //check new action keyword didn't used by other plugin if (actionKeywords[0] != Query.GlobalPluginWildcardSign && PluginManager.AllPlugins. SelectMany(p => p.Metadata.ActionKeywords). diff --git a/Wox/Languages/en.xaml b/Wox/Languages/en.xaml index 28e0a4830..71b8cccf6 100644 --- a/Wox/Languages/en.xaml +++ b/Wox/Languages/en.xaml @@ -29,7 +29,7 @@ Plugin Browse more plugins Disable - Action keyword + Action keywords Plugin Directory Author Init time: {0}ms diff --git a/Wox/Languages/ru.xaml b/Wox/Languages/ru.xaml index a5f552047..13a7be86c 100644 --- a/Wox/Languages/ru.xaml +++ b/Wox/Languages/ru.xaml @@ -29,7 +29,7 @@ Плагины Найти больше плагинов Отключить - Ключевое слово + Ключевое слово Папка Автор Инициализация: {0}ms diff --git a/Wox/Languages/zh-cn.xaml b/Wox/Languages/zh-cn.xaml index d75714e9f..0823b5f3e 100644 --- a/Wox/Languages/zh-cn.xaml +++ b/Wox/Languages/zh-cn.xaml @@ -29,7 +29,7 @@ 插件 浏览更多插件 禁用 - 触发关键字 + 触发关键字 插件目录 作者 加载耗时 {0}ms diff --git a/Wox/Languages/zh-tw.xaml b/Wox/Languages/zh-tw.xaml index 22562e170..5d8907fe7 100644 --- a/Wox/Languages/zh-tw.xaml +++ b/Wox/Languages/zh-tw.xaml @@ -29,7 +29,7 @@ 插件 瀏覽更多插件 禁用 - 觸發關鍵字 + 觸發關鍵字 插件目錄 作者 加載耗時:{0}ms diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index 5d5384101..3d94b8fd5 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -106,10 +106,10 @@ - - + + - + diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index a38791465..e96720ae2 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -117,7 +117,8 @@ namespace Wox cbEnableProxy.Unchecked += (o, e) => DisableProxy(); cbEnableProxy.IsChecked = UserSettingStorage.Instance.ProxyEnabled; tbProxyServer.Text = UserSettingStorage.Instance.ProxyServer; - if (UserSettingStorage.Instance.ProxyPort != 0) { + if (UserSettingStorage.Instance.ProxyPort != 0) + { tbProxyPort.Text = UserSettingStorage.Instance.ProxyPort.ToString(); } tbProxyUserName.Text = UserSettingStorage.Instance.ProxyUserName; @@ -187,6 +188,23 @@ namespace Wox { OnHotkeyTabSelected(); } + + // save multiple action keywords settings, todo: this hack is ugly + var tab = e.RemovedItems.Count > 0 ? e.RemovedItems[0] : null; + if (ReferenceEquals(tab, tabPlugin)) + { + var metadata = (lbPlugins.SelectedItem as PluginPair)?.Metadata; + if (metadata != null) + { + var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == metadata.ID); + if (customizedPluginConfig != null && !customizedPluginConfig.Disabled) + { + customizedPluginConfig.ActionKeywords = metadata.ActionKeywords; + UserSettingStorage.Instance.Save(); + } + + } + } } #region General @@ -527,16 +545,24 @@ namespace Wox { provider = pair.Plugin as ISettingProvider; pluginAuthor.Visibility = Visibility.Visible; - pluginActionKeywords.Visibility = Visibility.Visible; pluginInitTime.Text = string.Format(InternationalizationManager.Instance.GetTranslation("plugin_init_time"), pair.InitTime); pluginQueryTime.Text = string.Format(InternationalizationManager.Instance.GetTranslation("plugin_query_time"), pair.AvgQueryTime); - pluginActionKeywordTitle.Visibility = Visibility.Visible; + if (pair.Metadata.ActionKeywords.Count > 0) + { + pluginActionKeywordsTitle.Visibility = Visibility.Collapsed; + pluginActionKeywords.Visibility = Visibility.Collapsed; + } + else + { + pluginActionKeywordsTitle.Visibility = Visibility.Visible; + pluginActionKeywords.Visibility = Visibility.Visible; + } tbOpenPluginDirecoty.Visibility = Visibility.Visible; pluginTitle.Text = pair.Metadata.Name; pluginTitle.Cursor = Cursors.Hand; - pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords); + pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords.ToArray()); pluginAuthor.Text = InternationalizationManager.Instance.GetTranslation("author") + ": " + pair.Metadata.Author; pluginSubTitle.Text = pair.Metadata.Description; pluginId = pair.Metadata.ID; @@ -606,7 +632,7 @@ namespace Wox ActionKeywords changeKeywordsWindow = new ActionKeywords(id); changeKeywordsWindow.ShowDialog(); PluginPair plugin = PluginManager.GetPluginForId(id); - if (plugin != null) pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords); + if (plugin != null) pluginActionKeywords.Text = string.Join(Query.ActionKeywordSeperater, pair.Metadata.ActionKeywords.ToArray()); } } } From 7c889e352398078bf12685cf7acd3547a1779f77 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Fri, 6 Nov 2015 02:34:50 +0000 Subject: [PATCH 9/9] Add more comments See #352 --- Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs b/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs index d91577d4b..a08eb6337 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebSearchSetting.xaml.cs @@ -104,7 +104,10 @@ namespace Wox.Plugin.WebSearch Url = url, Title = title }); + + //save the action keywords, the order is not metters. Wox will read this metadata when save settings. context.CurrentPluginMetadata.ActionKeywords.Add(action); + string msg = context.API.GetTranslation("wox_plugin_websearch_succeed"); MessageBox.Show(msg); } @@ -121,7 +124,10 @@ namespace Wox.Plugin.WebSearch updateWebSearch.Enabled = cbEnable.IsChecked ?? false; updateWebSearch.Url = url; updateWebSearch.Title= title; + + //save the action keywords, the order is not metters. Wox will read this metadata when save settings. context.CurrentPluginMetadata.ActionKeywords.Add(action); + string msg = context.API.GetTranslation("wox_plugin_websearch_succeed"); MessageBox.Show(msg); }