From 95e468c90a9f20b8431fbe649877387e91a68598 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 2 Feb 2015 23:28:40 +0800 Subject: [PATCH 01/26] Add drop event [WIP] --- Plugins/Wox.Plugin.Program/Images/folder.png | Bin 0 -> 4260 bytes .../ProgramSources/FileSystemProgramSource.cs | 15 +- Plugins/Wox.Plugin.Program/Programs.cs | 6 + .../Wox.Plugin.Program.csproj | 289 +++++++++--------- Wox.Core/Updater/UpdaterManager.cs | 4 +- Wox.Plugin/EventHandler.cs | 3 + Wox.Plugin/IPublicAPI.cs | 5 + Wox/MainWindow.xaml.cs | 16 + Wox/ResultPanel.xaml | 2 +- Wox/ResultPanel.xaml.cs | 16 + 10 files changed, 199 insertions(+), 157 deletions(-) create mode 100644 Plugins/Wox.Plugin.Program/Images/folder.png diff --git a/Plugins/Wox.Plugin.Program/Images/folder.png b/Plugins/Wox.Plugin.Program/Images/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..330cb2e4bf8ac344014dd3d22910de1ae884343a GIT binary patch literal 4260 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 literal 0 HcmV?d00001 diff --git a/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs b/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs index cb62dc831..f4997615e 100644 --- a/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs +++ b/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs @@ -16,7 +16,8 @@ namespace Wox.Plugin.Program.ProgramSources this.baseDirectory = baseDirectory; } - public FileSystemProgramSource(ProgramSource source):this(source.Location) + public FileSystemProgramSource(ProgramSource source) + : this(source.Location) { this.BonusPoints = source.BonusPoints; } @@ -50,17 +51,9 @@ namespace Wox.Plugin.Program.ProgramSources GetAppFromDirectory(subDirectory, list); } } - catch (UnauthorizedAccessException e) + catch (Exception e) { - Log.Warn(string.Format("Can't access to directory {0}", path)); - } - catch (DirectoryNotFoundException e) - { - Log.Warn(string.Format("Directory {0} doesn't exist", path)); - } - catch (PathTooLongException e) - { - Log.Warn(string.Format("File path too long: {0}", e.Message)); + Log.Warn(string.Format("GetAppFromDirectory failed: {0} - {1}", path, e.Message)); } } diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 7028848b8..92da2c195 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -103,6 +103,7 @@ namespace Wox.Plugin.Program public void Init(PluginInitContext context) { this.context = context; + this.context.API.ResultItemDropEvent += API_ResultItemDropEvent; using (new Timeit("Preload programs")) { programs = ProgramCacheStorage.Instance.Programs; @@ -114,6 +115,11 @@ namespace Wox.Plugin.Program } } + void API_ResultItemDropEvent(Result result, IDataObject dropObject) + { + + } + public static void IndexPrograms() { lock (lockObject) diff --git a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj index a517e1407..0f357736f 100644 --- a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj +++ b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj @@ -1,150 +1,153 @@ - - - - - Debug - AnyCPU - {FDB3555B-58EF-4AE6-B5F1-904719637AB4} - Library - Properties - Wox.Plugin.Program - Wox.Plugin.Program - v3.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.Program\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.Program\ - TRACE - prompt - 4 - false - - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - ProgramSetting.xaml - - - - - - - - - ProgramSuffixes.xaml - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} - 1 - 0 - 0 - tlbimp - False - True - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + + + Debug + AnyCPU + {FDB3555B-58EF-4AE6-B5F1-904719637AB4} + Library + Properties + Wox.Plugin.Program + Wox.Plugin.Program + v3.5 + 512 + ..\..\ + true + + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.Program\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.Program\ + TRACE + prompt + 4 + false + + + + False + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + ProgramSetting.xaml + + + + + + + + + ProgramSuffixes.xaml + + + + + + + + PreserveNewest + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + --> \ No newline at end of file diff --git a/Wox.Core/Updater/UpdaterManager.cs b/Wox.Core/Updater/UpdaterManager.cs index 258d3c0b6..21b43cfef 100644 --- a/Wox.Core/Updater/UpdaterManager.cs +++ b/Wox.Core/Updater/UpdaterManager.cs @@ -22,8 +22,8 @@ namespace Wox.Core.Updater { private static UpdaterManager instance; private const string VersionCheckURL = "https://api.getwox.com/release/latest/"; - //private const string UpdateFeedURL = "http://upgrade.getwox.com/update.xml"; - private const string UpdateFeedURL = "http://127.0.0.1:8888/update.xml"; + private const string UpdateFeedURL = "http://upgrade.getwox.com/update.xml"; + //private const string UpdateFeedURL = "http://127.0.0.1:8888/update.xml"; private static SemanticVersion currentVersion; public event EventHandler PrepareUpdateReady; diff --git a/Wox.Plugin/EventHandler.cs b/Wox.Plugin/EventHandler.cs index f3c6121f9..3aa31c938 100644 --- a/Wox.Plugin/EventHandler.cs +++ b/Wox.Plugin/EventHandler.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Windows; using System.Windows.Input; namespace Wox.Plugin @@ -9,6 +10,8 @@ namespace Wox.Plugin public delegate void WoxKeyDownEventHandler(WoxKeyDownEventArgs e); public delegate void AfterWoxQueryEventHandler(WoxQueryEventArgs e); + public delegate void ResultItemDropEventHandler(Result result, IDataObject dropObject); + /// /// Global keyboard events /// diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index 972d281f9..1e9ec5c05 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -119,5 +119,10 @@ namespace Wox.Plugin /// Fired before wox start to execute a query /// event AfterWoxQueryEventHandler BeforeWoxQueryEvent; + + /// + /// Fired after drop to result item of current plugin + /// + event ResultItemDropEventHandler ResultItemDropEvent; } } diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 1f408c20e..1e6cae46a 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -34,6 +34,7 @@ using MenuItem = System.Windows.Forms.MenuItem; using MessageBox = System.Windows.MessageBox; using ToolTip = System.Windows.Controls.ToolTip; using Wox.Infrastructure.Logger; +using IDataObject = System.Windows.IDataObject; namespace Wox { @@ -135,6 +136,7 @@ namespace Wox public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; public event AfterWoxQueryEventHandler AfterWoxQueryEvent; public event AfterWoxQueryEventHandler BeforeWoxQueryEvent; + public event ResultItemDropEventHandler ResultItemDropEvent; public void PushResults(Query query, PluginMetadata plugin, List results) { @@ -168,6 +170,7 @@ namespace Wox progressBar.ToolTip = toolTip; InitialTray(); pnlResult.LeftMouseClickEvent += SelectResult; + pnlResult.ItemDropEvent += pnlResult_ItemDropEvent; pnlContextMenu.LeftMouseClickEvent += SelectResult; pnlResult.RightMouseClickEvent += pnlResult_RightMouseClickEvent; @@ -192,6 +195,19 @@ namespace Wox }); } + void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject) + { + if (ResultItemDropEvent != null) + { + PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Plugin == ResultItemDropEvent.Target); + if (pluginPair != null) + { + //todo: + ResultItemDropEvent(result, dropDataObject); + } + } + } + private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) { if (GlobalKeyboardEvent != null) diff --git a/Wox/ResultPanel.xaml b/Wox/ResultPanel.xaml index a156d6fc1..a3ada3cd3 100644 --- a/Wox/ResultPanel.xaml +++ b/Wox/ResultPanel.xaml @@ -7,7 +7,7 @@ mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="100"> - + diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index 7274a8c54..18ddd7670 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -16,6 +16,7 @@ namespace Wox { public event Action LeftMouseClickEvent; public event Action RightMouseClickEvent; + public event Action ItemDropEvent; protected virtual void OnRightMouseClick(Result result) { @@ -208,5 +209,20 @@ namespace Wox } Select(index); } + + private void ListBoxItem_OnDrop(object sender, DragEventArgs e) + { + var item = ItemsControl.ContainerFromElement(lbResults, e.OriginalSource as DependencyObject) as ListBoxItem; + if (item != null) + { + OnItemDropEvent(item.DataContext as Result,e.Data); + } + } + + protected virtual void OnItemDropEvent(Result obj, IDataObject data) + { + var handler = ItemDropEvent; + if (handler != null) handler(obj,data); + } } } \ No newline at end of file From 30b6c8aa039ae166e1e62d32bb26fd69fdb6ba56 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Tue, 3 Feb 2015 12:27:59 +0800 Subject: [PATCH 02/26] Add hotkey for navigating result items. --- Wox/MainWindow.xaml.cs | 46 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 1f408c20e..a4c0ee783 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -508,6 +508,36 @@ namespace Wox e.Handled = true; break; + case Key.N: + case Key.J: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + SelectNextItem(); + } + break; + + case Key.P: + case Key.K: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + SelectPrevItem(); + } + break; + + case Key.O: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + if (IsInContextMenuMode) + { + BackToResultMode(); + } + else + { + ShowContextMenu(GetActiveResult()); + } + } + break; + case Key.Down: SelectNextItem(); e.Handled = true; @@ -518,15 +548,27 @@ namespace Wox e.Handled = true; break; + case Key.D: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + pnlResult.SelectNextPage(); + } + break; + case Key.PageDown: pnlResult.SelectNextPage(); - toolTip.IsOpen = false; e.Handled = true; break; + case Key.U: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + pnlResult.SelectPrevPage(); + } + break; + case Key.PageUp: pnlResult.SelectPrevPage(); - toolTip.IsOpen = false; e.Handled = true; break; From 38948053cce7a663f67cedb7c17a22c2a4ff91de Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Tue, 3 Feb 2015 12:29:58 +0800 Subject: [PATCH 03/26] Merge --- .../Wox.Plugin.Program.csproj | 292 +++++++++--------- 1 file changed, 146 insertions(+), 146 deletions(-) diff --git a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj index 0f357736f..1fa4ddf8c 100644 --- a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj +++ b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj @@ -1,153 +1,153 @@ - - - - - Debug - AnyCPU - {FDB3555B-58EF-4AE6-B5F1-904719637AB4} - Library - Properties - Wox.Plugin.Program - Wox.Plugin.Program - v3.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.Program\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.Program\ - TRACE - prompt - 4 - false - - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - ProgramSetting.xaml - - - - - - - - - ProgramSuffixes.xaml - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} - 1 - 0 - 0 - tlbimp - False - True - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + + + Debug + AnyCPU + {FDB3555B-58EF-4AE6-B5F1-904719637AB4} + Library + Properties + Wox.Plugin.Program + Wox.Plugin.Program + v3.5 + 512 + ..\..\ + true + + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.Program\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.Program\ + TRACE + prompt + 4 + false + + + + False + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + ProgramSetting.xaml + + + + + + + + + ProgramSuffixes.xaml + + + + + + + + PreserveNewest + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + --> \ No newline at end of file From 5d9a94466a976150ee7fed50cb7c3e8590d7d812 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Tue, 3 Feb 2015 18:32:16 +0800 Subject: [PATCH 04/26] Add drop event. --- Plugins/Wox.Plugin.Folder/FolderPlugin.cs | 6 ++++++ Plugins/Wox.Plugin.Program/Programs.cs | 4 ++-- Wox.Core/Plugin/JsonRPCPlugin.cs | 10 +++++----- Wox.CrashReporter/ReportWindow.xaml.cs | 10 ++++------ Wox.Plugin/EventHandler.cs | 2 +- Wox/MainWindow.xaml.cs | 14 ++++++++------ Wox/ResultPanel.xaml.cs | 8 ++++---- appveyor.yml | 1 - 8 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Plugins/Wox.Plugin.Folder/FolderPlugin.cs b/Plugins/Wox.Plugin.Folder/FolderPlugin.cs index ed9127509..da5525ffc 100644 --- a/Plugins/Wox.Plugin.Folder/FolderPlugin.cs +++ b/Plugins/Wox.Plugin.Folder/FolderPlugin.cs @@ -23,6 +23,7 @@ namespace Wox.Plugin.Folder { this.context = context; this.context.API.BackKeyDownEvent += ApiBackKeyDownEvent; + this.context.API.ResultItemDropEvent += API_ResultItemDropEvent; InitialDriverList(); if (FolderStorage.Instance.FolderLinks == null) { @@ -31,6 +32,11 @@ namespace Wox.Plugin.Folder } } + void API_ResultItemDropEvent(Result result, IDataObject dropObject,DragEventArgs e) + { + e.Handled = true; + } + private void ApiBackKeyDownEvent(WoxKeyDownEventArgs e) { string query = e.Query; diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 92da2c195..ded1fea3e 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -115,9 +115,9 @@ namespace Wox.Plugin.Program } } - void API_ResultItemDropEvent(Result result, IDataObject dropObject) + void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs args) { - + args.Handled = true; } public static void IndexPrograms() diff --git a/Wox.Core/Plugin/JsonRPCPlugin.cs b/Wox.Core/Plugin/JsonRPCPlugin.cs index fd0514af3..877ff10e9 100644 --- a/Wox.Core/Plugin/JsonRPCPlugin.cs +++ b/Wox.Core/Plugin/JsonRPCPlugin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using Newtonsoft.Json; using Wox.Infrastructure.Logger; using Wox.Plugin; +using Wox.Core.Exception; namespace Wox.Core.Plugin { @@ -83,7 +84,7 @@ namespace Wox.Core.Plugin private void ExecuteWoxAPI(string method, object[] parameters) { MethodInfo methodInfo = PluginManager.API.GetType().GetMethod(method); - if (methodInfo != null) + if (methodInfo != null) { try { @@ -141,8 +142,7 @@ namespace Wox.Core.Plugin string error = errorReader.ReadToEnd(); if (!string.IsNullOrEmpty(error)) { - //todo: - // ErrorReporting.TryShowErrorMessageBox(error, new WoxJsonRPCException(error)); + throw new WoxJsonRPCException(error); } } } @@ -151,9 +151,9 @@ namespace Wox.Core.Plugin } } } - catch + catch(System.Exception e) { - return null; + throw new WoxJsonRPCException(e.Message); } return null; } diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index 7a6ec983c..05612cd9c 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -19,6 +19,7 @@ using Wox.Core.UI; using Wox.Core.Updater; using Wox.Core.UserSettings; using Wox.Infrastructure.Http; +using Wox.Infrastructure.Logger; namespace Wox.CrashReporter { @@ -53,15 +54,12 @@ namespace Wox.CrashReporter private void SendReport() { + Hide(); string error = string.Format("{{\"data\":{0}}}", ExceptionFormatter.FormatExcpetion(exception)); string response = HttpRequest.Post(APIServer.ErrorReportURL, error, HttpProxy.Instance); - if (response.ToLower() == "ok") + if (response.ToLower() != "ok") { - MessageBox.Show(InternationalizationManager.Instance.GetTranslation("reportWindow_report_succeed")); - } - else - { - MessageBox.Show(InternationalizationManager.Instance.GetTranslation("reportWindow_report_failed")); + Log.Warn("sending crash report failed: " + response); } Dispatcher.Invoke(new Action(Close)); } diff --git a/Wox.Plugin/EventHandler.cs b/Wox.Plugin/EventHandler.cs index 3aa31c938..1bbe950a4 100644 --- a/Wox.Plugin/EventHandler.cs +++ b/Wox.Plugin/EventHandler.cs @@ -10,7 +10,7 @@ namespace Wox.Plugin public delegate void WoxKeyDownEventHandler(WoxKeyDownEventArgs e); public delegate void AfterWoxQueryEventHandler(WoxQueryEventArgs e); - public delegate void ResultItemDropEventHandler(Result result, IDataObject dropObject); + public delegate void ResultItemDropEventHandler(Result result, IDataObject dropObject, DragEventArgs e); /// /// Global keyboard events diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 7c200fbe2..fb7c1789f 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -195,15 +195,17 @@ namespace Wox }); } - void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject) + void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject, DragEventArgs args) { - if (ResultItemDropEvent != null) + PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); + if (ResultItemDropEvent != null && pluginPair != null) { - PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Plugin == ResultItemDropEvent.Target); - if (pluginPair != null) + foreach (var delegateHandler in ResultItemDropEvent.GetInvocationList()) { - //todo: - ResultItemDropEvent(result, dropDataObject); + if (delegateHandler.Target == pluginPair.Plugin) + { + delegateHandler.DynamicInvoke(result, dropDataObject, args); + } } } } diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index 18ddd7670..2a1d21717 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -16,7 +16,7 @@ namespace Wox { public event Action LeftMouseClickEvent; public event Action RightMouseClickEvent; - public event Action ItemDropEvent; + public event Action ItemDropEvent; protected virtual void OnRightMouseClick(Result result) { @@ -215,14 +215,14 @@ namespace Wox var item = ItemsControl.ContainerFromElement(lbResults, e.OriginalSource as DependencyObject) as ListBoxItem; if (item != null) { - OnItemDropEvent(item.DataContext as Result,e.Data); + OnItemDropEvent(item.DataContext as Result, e.Data, e); } } - protected virtual void OnItemDropEvent(Result obj, IDataObject data) + protected virtual void OnItemDropEvent(Result obj, IDataObject data, DragEventArgs e) { var handler = ItemDropEvent; - if (handler != null) handler(obj,data); + if (handler != null) handler(obj, data, e); } } } \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 76871e145..429a0011e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,6 @@ build: after_test: - ps: .\deploy\nuget\pack.ps1 - cmd: .\deploy\UpdateGenerator\build.bat - #- cmd: .\deploy\Cleanup.bat deploy: provider: NuGet From 1d3f1fd7d0414887f1d2fb1c1ccf4871b721f268 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Wed, 4 Feb 2015 23:16:41 +0800 Subject: [PATCH 05/26] Improve instant search ue --- Plugins/Wox.Plugin.CMD/CMD.cs | 6 + .../ControlPanelList.cs | 2 - Plugins/Wox.Plugin.Folder/FolderPlugin.cs | 40 ++- .../FolderPluginSettings.xaml.cs | 12 +- Plugins/Wox.Plugin.Folder/Images/copy.png | Bin 0 -> 898 bytes .../Wox.Plugin.Folder.csproj | 241 ++++++++------- .../Wox.Plugin.Program/FileChangeWatcher.cs | 3 +- Plugins/Wox.Plugin.Program/Programs.cs | 7 +- .../Wox.Plugin.Program.csproj | 292 +++++++++--------- Wox.Core/Plugin/PluginManager.cs | 41 ++- .../QueryDispatcher/BaseQueryDispatcher.cs | 39 +++ .../SystemPluginQueryDispatcher.cs | 30 +- .../UserPluginQueryDispatcher.cs | 33 +- Wox.Core/Wox.Core.csproj | 1 + Wox.Infrastructure/DebugHelper.cs | 16 + Wox.Infrastructure/Logger/NLog.xsd | 2 +- Wox.Infrastructure/Timeit.cs | 2 +- Wox.Infrastructure/Wox.Infrastructure.csproj | 1 + Wox.Plugin/IPublicAPI.cs | 10 +- Wox.Plugin/Query.cs | 2 + Wox.Plugin/Result.cs | 5 + Wox/ImageLoader/ImageLoader.cs | 50 +-- Wox/MainWindow.xaml.cs | 35 ++- 23 files changed, 503 insertions(+), 367 deletions(-) create mode 100644 Plugins/Wox.Plugin.Folder/Images/copy.png create mode 100644 Wox.Core/Plugin/QueryDispatcher/BaseQueryDispatcher.cs create mode 100644 Wox.Infrastructure/DebugHelper.cs diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index bb0a21272..16e3777f7 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; @@ -20,6 +21,9 @@ namespace Wox.Plugin.CMD public List Query(Query query) { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + List results = new List(); List pushedResults = new List(); if (query.Search == ">") @@ -76,6 +80,8 @@ namespace Wox.Plugin.CMD catch (Exception) { } } + stopwatch.Stop(); + DebugHelper.WriteLine("CMD:" + stopwatch.ElapsedMilliseconds + "ms"); return results; } diff --git a/Plugins/Wox.Plugin.ControlPanel/ControlPanelList.cs b/Plugins/Wox.Plugin.ControlPanel/ControlPanelList.cs index 724688e4e..68f11a52c 100644 --- a/Plugins/Wox.Plugin.ControlPanel/ControlPanelList.cs +++ b/Plugins/Wox.Plugin.ControlPanel/ControlPanelList.cs @@ -326,8 +326,6 @@ namespace Wox.Plugin.ControlPanel private static bool EnumRes(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam) { - //Debug.WriteLine("Type: " + GET_RESOURCE_NAME(lpszType)); - //Debug.WriteLine("Name: " + GET_RESOURCE_NAME(lpszName)); defaultIconPtr = lpszName; return false; } diff --git a/Plugins/Wox.Plugin.Folder/FolderPlugin.cs b/Plugins/Wox.Plugin.Folder/FolderPlugin.cs index da5525ffc..7e7c64102 100644 --- a/Plugins/Wox.Plugin.Folder/FolderPlugin.cs +++ b/Plugins/Wox.Plugin.Folder/FolderPlugin.cs @@ -9,14 +9,14 @@ using Control = System.Windows.Controls.Control; namespace Wox.Plugin.Folder { - public class FolderPlugin : IPlugin, ISettingProvider,IPluginI18n + public class FolderPlugin : IPlugin, ISettingProvider, IPluginI18n { private static List driverNames; private PluginInitContext context; public Control CreateSettingPanel() { - return new FileSystemSettings(context); + return new FileSystemSettings(context.API); } public void Init(PluginInitContext context) @@ -32,11 +32,38 @@ namespace Wox.Plugin.Folder } } - void API_ResultItemDropEvent(Result result, IDataObject dropObject,DragEventArgs e) + void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs e) { + if (dropObject.GetDataPresent(DataFormats.FileDrop)) + { + HanldeFilesDrop(result, dropObject); + } e.Handled = true; } + private void HanldeFilesDrop(Result targetResult, IDataObject dropObject) + { + List files = ((string[])dropObject.GetData(DataFormats.FileDrop, false)).ToList(); + context.API.ShowContextMenu(context.CurrentPluginMetadata, GetContextMenusForFileDrop(targetResult, files)); + } + + private static List GetContextMenusForFileDrop(Result targetResult, List files) + { + List contextMenus = new List(); + string folderPath = ((FolderLink) targetResult.ContextData).Path; + contextMenus.Add(new Result() + { + Title = "Copy to this folder", + IcoPath = "Images/copy.png", + Action = _ => + { + MessageBox.Show("Copy"); + return true; + } + }); + return contextMenus; + } + private void ApiBackKeyDownEvent(WoxKeyDownEventArgs e) { string query = e.Query; @@ -84,7 +111,8 @@ namespace Wox.Plugin.Folder } context.API.ChangeQuery(item.Path); return false; - } + }, + ContextData = item }).ToList(); if (driverNames != null && !driverNames.Any(input.StartsWith)) @@ -98,9 +126,7 @@ namespace Wox.Plugin.Folder results.AddRange(QueryInternal_Directory_Exists(input)); return results; - } - - private void InitialDriverList() + } private void InitialDriverList() { if (driverNames == null) { diff --git a/Plugins/Wox.Plugin.Folder/FolderPluginSettings.xaml.cs b/Plugins/Wox.Plugin.Folder/FolderPluginSettings.xaml.cs index 64845005e..0b0c655a7 100644 --- a/Plugins/Wox.Plugin.Folder/FolderPluginSettings.xaml.cs +++ b/Plugins/Wox.Plugin.Folder/FolderPluginSettings.xaml.cs @@ -13,11 +13,11 @@ namespace Wox.Plugin.Folder /// public partial class FileSystemSettings : UserControl { - PluginInitContext context; + private IPublicAPI woxAPI; - public FileSystemSettings(PluginInitContext context) + public FileSystemSettings(IPublicAPI woxAPI) { - this.context = context; + this.woxAPI = woxAPI; InitializeComponent(); lbxFolders.ItemsSource = FolderStorage.Instance.FolderLinks; } @@ -27,7 +27,7 @@ namespace Wox.Plugin.Folder var selectedFolder = lbxFolders.SelectedItem as FolderLink; if (selectedFolder != null) { - string msg = string.Format(context.API.GetTranslation("wox_plugin_folder_delete_folder_link"), selectedFolder.Path); + string msg = string.Format(woxAPI.GetTranslation("wox_plugin_folder_delete_folder_link"), selectedFolder.Path); if (MessageBox.Show(msg, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) { @@ -37,7 +37,7 @@ namespace Wox.Plugin.Folder } else { - string warning = context.API.GetTranslation("wox_plugin_folder_select_folder_link_warning"); + string warning = woxAPI.GetTranslation("wox_plugin_folder_select_folder_link_warning"); MessageBox.Show(warning); } } @@ -61,7 +61,7 @@ namespace Wox.Plugin.Folder } else { - string warning = context.API.GetTranslation("wox_plugin_folder_select_folder_link_warning"); + string warning = woxAPI.GetTranslation("wox_plugin_folder_select_folder_link_warning"); MessageBox.Show(warning); } } diff --git a/Plugins/Wox.Plugin.Folder/Images/copy.png b/Plugins/Wox.Plugin.Folder/Images/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..91f0647e736f23063e1011c1fd9bf49b783adfc7 GIT binary patch literal 898 zcmV-|1AY97P)yr?kapuiD3{9{ z^YimBr>3TU0jELMlCsA348xFNQYaK;KA)E}Gc#W@nM^Mb4=SK~i69GkMO9Ve@i>~M z^=Gr$xlAT=n}8y!L?S>@6ck0Fudk0(D%F?GX6JwoLJ$#&0Dwdyfu?Dui0SF+H$XdZ zEy%i&3219;LkNMUY4rE^)6>&4s_Xh&0*Z*)4H||aM@B{*CoL>2kW421KGT+BvFO>Q ztS;2z=V8fYlEJ}2KT~Zf7K;cW28M@+-|y_~jLy!^e#fKLMpi;@BoYZ)T3UR$R6_`8 zZEdAesrYiKh7b^o#gJ0^a;b(8AcR0s6kjgoxruY1zMAp%K-;w^9zUxVAq1VBo%Hth z0*vXp&cwvTD_|ceU!3PT11}!+m{&cp+OiOWj*bqxySwS?>KfB^{T&XO@MWX*Ae~NA zC=@t4I^yu~klo!~N~IF1R0>=&(J%rOMIoI|pBt-GDjXafaD04BsZ<&RUITxCqv|~k z(*t%0Ay8EnRaMF5asVn&#E$@L?XRr-4sVwp+1lEIv;CfX{RypvtQiV}i)P{UEi5zv z^>U|LG;|Mm!Bv1YZOgxXD zdf_TSh=w@0bH!DFqA0GDom?smo($abbf2w&y}dmqCnqVFFP-E8Ff=p-IJ;CB1o|8p zA0JnN8=RfPTw-~7c`4ZTyi=>soJ!~f*am(ESv(B<+UO}Be&UHjfZq&wA_|uZ^g&jO zS}qj@z65M;ZnC(z=;%^W;+`L8+HrBIIIeV)Pt<8 literal 0 HcmV?d00001 diff --git a/Plugins/Wox.Plugin.Folder/Wox.Plugin.Folder.csproj b/Plugins/Wox.Plugin.Folder/Wox.Plugin.Folder.csproj index 5551d5c2a..162c2a12b 100644 --- a/Plugins/Wox.Plugin.Folder/Wox.Plugin.Folder.csproj +++ b/Plugins/Wox.Plugin.Folder/Wox.Plugin.Folder.csproj @@ -1,120 +1,123 @@ - - - - - Debug - AnyCPU - {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} - Library - Properties - Wox.Plugin.Folder - Wox.Plugin.Folder - v3.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.Folder\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.Folder\ - TRACE - prompt - 4 - false - - - - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - True - - - - - - - - - - - - - - - - - - FolderPluginSettings.xaml - - - - - - - - PreserveNewest - - - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - PreserveNewest - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - + + + + + Debug + AnyCPU + {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} + Library + Properties + Wox.Plugin.Folder + Wox.Plugin.Folder + v3.5 + 512 + ..\..\ + true + + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.Folder\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.Folder\ + TRACE + prompt + 4 + false + + + + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + True + + + + + + + + + + + + + + + + + + FolderPluginSettings.xaml + + + + + + + + PreserveNewest + + + + + MSBuild:Compile + Designer + + + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + PreserveNewest + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/FileChangeWatcher.cs b/Plugins/Wox.Plugin.Program/FileChangeWatcher.cs index 303970fd3..c6f6ec546 100644 --- a/Plugins/Wox.Plugin.Program/FileChangeWatcher.cs +++ b/Plugins/Wox.Plugin.Program/FileChangeWatcher.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.IO; using System.Threading; +using Wox.Infrastructure; namespace Wox.Plugin.Program { @@ -15,7 +16,7 @@ namespace Wox.Plugin.Program if (watchedPath.Contains(path)) return; if (!Directory.Exists(path)) { - Debug.WriteLine(string.Format("FileChangeWatcher: {0} doesn't exist", path),"WoxDebug"); + DebugHelper.WriteLine(string.Format("FileChangeWatcher: {0} doesn't exist", path)); return; } diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index ded1fea3e..4d888bd5b 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -108,16 +108,17 @@ namespace Wox.Plugin.Program { programs = ProgramCacheStorage.Instance.Programs; } - Debug.WriteLine(string.Format("Preload {0} programs from cache", programs.Count), "Wox"); + DebugHelper.WriteLine(string.Format("Preload {0} programs from cache", programs.Count)); using (new Timeit("Program Index")) { IndexPrograms(); } } - void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs args) + void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs e) { - args.Handled = true; + + e.Handled = true; } public static void IndexPrograms() diff --git a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj index 1fa4ddf8c..0f357736f 100644 --- a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj +++ b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj @@ -1,153 +1,153 @@ - - - - - Debug - AnyCPU - {FDB3555B-58EF-4AE6-B5F1-904719637AB4} - Library - Properties - Wox.Plugin.Program - Wox.Plugin.Program - v3.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.Program\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.Program\ - TRACE - prompt - 4 - false - - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - ProgramSetting.xaml - - - - - - - - - ProgramSuffixes.xaml - - - - - - - - PreserveNewest - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} - 1 - 0 - 0 - tlbimp - False - True - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + + + Debug + AnyCPU + {FDB3555B-58EF-4AE6-B5F1-904719637AB4} + Library + Properties + Wox.Plugin.Program + Wox.Plugin.Program + v3.5 + 512 + ..\..\ + true + + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.Program\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.Program\ + TRACE + prompt + 4 + false + + + + False + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + ProgramSetting.xaml + + + + + + + + + ProgramSuffixes.xaml + + + + + + + + PreserveNewest + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + --> \ No newline at end of file diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index c9d15ec0b..fabc450f2 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -21,7 +21,7 @@ namespace Wox.Core.Plugin { public const string ActionKeywordWildcardSign = "*"; private static List pluginMetadatas; - private static List instantSearches = new List(); + private static List> instantSearches; public static String DebuggerMode { get; private set; } @@ -98,7 +98,10 @@ namespace Wox.Core.Plugin }); } - LoadInstantSearches(); + ThreadPool.QueueUserWorkItem(o => + { + LoadInstantSearches(); + }); } public static void InstallPlugin(string path) @@ -146,12 +149,38 @@ namespace Wox.Core.Plugin public static bool IsInstantSearch(string query) { - return LoadInstantSearches().Any(o => o.IsInstantSearch(query)); + return LoadInstantSearches().Any(o => o.Value.IsInstantSearch(query)); } - private static List LoadInstantSearches() + public static bool IsInstantSearchPlugin(PluginMetadata pluginMetadata) { - if (instantSearches.Count > 0) return instantSearches; + //todo:to improve performance, any instant search plugin that takes long than 200ms will not consider a instant plugin anymore + return pluginMetadata.Language.ToUpper() == AllowedLanguage.CSharp && + LoadInstantSearches().Any(o => o.Key.ID == pluginMetadata.ID); + } + + internal static void ExecutePluginQuery(PluginPair pair, Query query) + { + try + { + List results = pair.Plugin.Query(query) ?? new List(); + results.ForEach(o => + { + o.PluginID = pair.Metadata.ID; + }); + API.PushResults(query, pair.Metadata, results); + } + catch (System.Exception e) + { + throw new WoxPluginException(pair.Metadata.Name, e); + } + } + + private static List> LoadInstantSearches() + { + if (instantSearches != null) return instantSearches; + + instantSearches = new List>(); List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); foreach (PluginMetadata metadata in CSharpPluginMetadatas) @@ -167,7 +196,7 @@ namespace Wox.Core.Plugin foreach (Type type in types) { - instantSearches.Add(Activator.CreateInstance(type) as IInstantSearch); + instantSearches.Add(new KeyValuePair(metadata,Activator.CreateInstance(type) as IInstantSearch)); } } catch (System.Exception e) diff --git a/Wox.Core/Plugin/QueryDispatcher/BaseQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/BaseQueryDispatcher.cs new file mode 100644 index 000000000..6c5c562c8 --- /dev/null +++ b/Wox.Core/Plugin/QueryDispatcher/BaseQueryDispatcher.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using Wox.Infrastructure; +using Wox.Plugin; + +namespace Wox.Core.Plugin.QueryDispatcher +{ + public abstract class BaseQueryDispatcher : IQueryDispatcher + { + protected abstract List GetPlugins(Query query); + + public void Dispatch(Query query) + { + foreach (PluginPair pair in GetPlugins(query)) + { + PluginPair localPair = pair; + if (query.IsIntantQuery && PluginManager.IsInstantSearchPlugin(pair.Metadata)) + { + DebugHelper.WriteLine(string.Format("Plugin {0} is executing instant search.", pair.Metadata.Name)); + using (new Timeit(" => instant search took: ")) + { + PluginManager.ExecutePluginQuery(localPair, query); + } + } + else + { + ThreadPool.QueueUserWorkItem(state => + { + PluginManager.ExecutePluginQuery(localPair, query); + }); + } + } + } + } +} diff --git a/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs index 5cda7d3e3..9a9948df0 100644 --- a/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs @@ -8,34 +8,14 @@ using Wox.Plugin; namespace Wox.Core.Plugin.QueryDispatcher { - public class SystemPluginQueryDispatcher : IQueryDispatcher + public class SystemPluginQueryDispatcher : BaseQueryDispatcher { - private IEnumerable allSytemPlugins = PluginManager.AllPlugins.Where(o => PluginManager.IsSystemPlugin(o.Metadata)); + private readonly List allSytemPlugins = + PluginManager.AllPlugins.Where(o => PluginManager.IsSystemPlugin(o.Metadata)).ToList(); - public void Dispatch(Query query) + protected override List GetPlugins(Query query) { - var queryPlugins = allSytemPlugins; - foreach (PluginPair pair in queryPlugins) - { - PluginPair pair1 = pair; - ThreadPool.QueueUserWorkItem(state => - { - try - { - List results = pair1.Plugin.Query(query); - results.ForEach(o => - { - o.PluginID = pair1.Metadata.ID; - }); - - PluginManager.API.PushResults(query, pair1.Metadata, results); - } - catch (System.Exception e) - { - throw new WoxPluginException(pair1.Metadata.Name,e); - } - }); - } + return allSytemPlugins; } } } \ No newline at end of file diff --git a/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs index c50344296..d3cebb88d 100644 --- a/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs @@ -9,38 +9,29 @@ using Wox.Plugin; namespace Wox.Core.Plugin.QueryDispatcher { - public class UserPluginQueryDispatcher : IQueryDispatcher + public class UserPluginQueryDispatcher : BaseQueryDispatcher { - public void Dispatch(Query query) + protected override List GetPlugins(Query query) { + List plugins = new List(); + //only first plugin that matches action keyword will get executed PluginPair userPlugin = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.GetActionKeyword()); - if (userPlugin != null && !string.IsNullOrEmpty(userPlugin.Metadata.ActionKeyword)) + if (userPlugin != null) { - var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == userPlugin.Metadata.ID); + var customizedPluginConfig = UserSettingStorage.Instance. + CustomizedPluginConfigs.FirstOrDefault(o => o.ID == userPlugin.Metadata.ID); if (customizedPluginConfig != null && customizedPluginConfig.Disabled) { //need to stop the loading animation PluginManager.API.StopLoadingBar(); - return; } - - ThreadPool.QueueUserWorkItem(t => + else { - try - { - List results = userPlugin.Plugin.Query(query) ?? new List(); - results.ForEach(o => - { - o.PluginID = userPlugin.Metadata.ID; - }); - PluginManager.API.PushResults(query, userPlugin.Metadata, results); - } - catch (System.Exception e) - { - throw new WoxPluginException(userPlugin.Metadata.Name, e); - } - }); + plugins.Add(userPlugin); + } } + + return plugins; } } } diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index 84940b303..92c63ae13 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -69,6 +69,7 @@ + diff --git a/Wox.Infrastructure/DebugHelper.cs b/Wox.Infrastructure/DebugHelper.cs new file mode 100644 index 000000000..5d5e11142 --- /dev/null +++ b/Wox.Infrastructure/DebugHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace Wox.Infrastructure +{ + public static class DebugHelper + { + public static void WriteLine(string msg) + { + Debug.WriteLine(msg); + } + } +} diff --git a/Wox.Infrastructure/Logger/NLog.xsd b/Wox.Infrastructure/Logger/NLog.xsd index 481702860..edf2b7087 100644 --- a/Wox.Infrastructure/Logger/NLog.xsd +++ b/Wox.Infrastructure/Logger/NLog.xsd @@ -855,7 +855,7 @@ - + diff --git a/Wox.Infrastructure/Timeit.cs b/Wox.Infrastructure/Timeit.cs index a29ea53ed..14dd1f62c 100644 --- a/Wox.Infrastructure/Timeit.cs +++ b/Wox.Infrastructure/Timeit.cs @@ -20,7 +20,7 @@ namespace Wox.Infrastructure public void Dispose() { stopwatch.Stop(); - Debug.WriteLine(name + ":" + stopwatch.ElapsedMilliseconds + "ms","Wox"); + DebugHelper.WriteLine(name + ":" + stopwatch.ElapsedMilliseconds + "ms"); } } } diff --git a/Wox.Infrastructure/Wox.Infrastructure.csproj b/Wox.Infrastructure/Wox.Infrastructure.csproj index ca13df96f..75a45afee 100644 --- a/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -58,6 +58,7 @@ + diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index 1e9ec5c05..b564480db 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -15,7 +15,13 @@ namespace Wox.Plugin /// /// /// - void PushResults(Query query,PluginMetadata plugin, List results); + void PushResults(Query query, PluginMetadata plugin, List results); + + /// + /// Show context menu with giving results + /// + /// + void ShowContextMenu(PluginMetadata plugin, List results); /// /// Execute command @@ -63,7 +69,7 @@ namespace Wox.Plugin /// Open setting dialog /// void OpenSettingDialog(); - + /// /// Show loading animation /// diff --git a/Wox.Plugin/Query.cs b/Wox.Plugin/Query.cs index 4a0119914..dee962877 100644 --- a/Wox.Plugin/Query.cs +++ b/Wox.Plugin/Query.cs @@ -33,6 +33,8 @@ namespace Wox.Plugin return string.Empty; } + internal bool IsIntantQuery { get; set; } + /// /// Return first search split by space if it has /// diff --git a/Wox.Plugin/Result.cs b/Wox.Plugin/Result.cs index 6c1938fa4..5248cbb57 100644 --- a/Wox.Plugin/Result.cs +++ b/Wox.Plugin/Result.cs @@ -73,6 +73,11 @@ namespace Wox.Plugin /// public List ContextMenu { get; set; } + /// + /// Additional data associate with this result + /// + public object ContextData { get; set; } + /// /// Plugin ID that generate this result /// diff --git a/Wox/ImageLoader/ImageLoader.cs b/Wox/ImageLoader/ImageLoader.cs index e0f87147e..8fa9f9c5d 100644 --- a/Wox/ImageLoader/ImageLoader.cs +++ b/Wox/ImageLoader/ImageLoader.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Runtime.InteropServices; @@ -79,42 +80,49 @@ namespace Wox.ImageLoader public static ImageSource Load(string path, bool addToCache = true) { + Stopwatch sw = new Stopwatch(); + sw.Start(); + if (string.IsNullOrEmpty(path)) return null; if (addToCache) { ImageCacheStroage.Instance.Add(path); } + ImageSource img = null; if (imageCache.ContainsKey(path)) { - return imageCache[path]; + img = imageCache[path]; } - - ImageSource img = null; - string ext = Path.GetExtension(path).ToLower(); - - if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) + else { - img = new BitmapImage(new Uri(path)); - } - else if (selfExts.Contains(ext) && File.Exists(path)) - { - img = GetIcon(path); - } - else if (!string.IsNullOrEmpty(path) && imageExts.Contains(ext) && File.Exists(path)) - { - img = new BitmapImage(new Uri(path)); - } + string ext = Path.GetExtension(path).ToLower(); - - if (img != null && addToCache) - { - if (!imageCache.ContainsKey(path)) + if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) { - imageCache.Add(path, img); + img = new BitmapImage(new Uri(path)); + } + else if (selfExts.Contains(ext) && File.Exists(path)) + { + img = GetIcon(path); + } + else if (!string.IsNullOrEmpty(path) && imageExts.Contains(ext) && File.Exists(path)) + { + img = new BitmapImage(new Uri(path)); + } + + + if (img != null && addToCache) + { + if (!imageCache.ContainsKey(path)) + { + imageCache.Add(path, img); + } } } + sw.Stop(); + DebugHelper.WriteLine(string.Format("Loading image path: {0} - {1}ms",path,sw.ElapsedMilliseconds)); return img; } diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index fb7c1789f..95a6e81bb 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -157,6 +157,23 @@ namespace Wox UpdateResultView(results); } + public void ShowContextMenu(PluginMetadata plugin, List results) + { + if (results != null && results.Count > 0) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + o.ContextMenu = null; + }); + pnlContextMenu.Clear(); + pnlContextMenu.AddResults(results); + pnlContextMenu.Visibility = Visibility.Visible; + pnlResult.Visibility = Visibility.Collapsed; + } + } + #endregion public MainWindow() @@ -226,7 +243,7 @@ namespace Wox void pnlResult_RightMouseClickEvent(Result result) { - ShowContextMenu(result); + ShowContextMenuFromResult(result); } void MainWindow_Closing(object sender, CancelEventArgs e) @@ -261,7 +278,7 @@ namespace Wox private void CheckUpdate() { - UpdaterManager.Instance.PrepareUpdateReady+=OnPrepareUpdateReady; + UpdaterManager.Instance.PrepareUpdateReady += OnPrepareUpdateReady; UpdaterManager.Instance.UpdateError += OnUpdateError; UpdaterManager.Instance.CheckUpdate(); } @@ -368,6 +385,8 @@ namespace Wox lastQuery = tbQuery.Text; toolTip.IsOpen = false; pnlResult.Dirty = true; + int searchDelay = GetSearchDelay(lastQuery); + Dispatcher.DelayInvoke("UpdateSearch", o => { @@ -381,6 +400,7 @@ namespace Wox }, TimeSpan.FromMilliseconds(100), null); queryHasReturn = false; Query query = new Query(lastQuery); + query.IsIntantQuery = searchDelay == 0; FireBeforeWoxQueryEvent(query); Query(query); Dispatcher.DelayInvoke("ShowProgressbar", originQuery => @@ -391,15 +411,18 @@ namespace Wox } }, TimeSpan.FromMilliseconds(150), tbQuery.Text); FireAfterWoxQueryEvent(query); - }, TimeSpan.FromMilliseconds(GetSearchDelay(lastQuery))); + }, TimeSpan.FromMilliseconds(searchDelay)); } private int GetSearchDelay(string query) { if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantSearch(query)) { + DebugHelper.WriteLine("execute query without delay"); return 0; } + + DebugHelper.WriteLine("execute query with 200ms delay"); return 200; } @@ -551,7 +574,7 @@ namespace Wox } else { - ShowContextMenu(GetActiveResult()); + ShowContextMenuFromResult(GetActiveResult()); } } break; @@ -609,7 +632,7 @@ namespace Wox Result activeResult = GetActiveResult(); if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) { - ShowContextMenu(activeResult); + ShowContextMenuFromResult(activeResult); } else { @@ -740,7 +763,7 @@ namespace Wox } } - private void ShowContextMenu(Result result) + private void ShowContextMenuFromResult(Result result) { if (result.ContextMenu != null && result.ContextMenu.Count > 0) { From fa53bce27afe063f0df8368f31f02bd5ddb0ad22 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 5 Feb 2015 00:03:35 +0800 Subject: [PATCH 06/26] Add init time and query time to setting view --- Plugins/Wox.Plugin.CMD/CMD.cs | 5 ---- Wox.Core/Plugin/PluginManager.cs | 40 ++++++++++++++++++++++---------- Wox.Plugin/PluginPair.cs | 6 +++++ Wox/Languages/en.xaml | 2 ++ Wox/Languages/zh-cn.xaml | 4 +++- Wox/Languages/zh-tw.xaml | 4 +++- Wox/SettingWindow.xaml | 4 +++- Wox/SettingWindow.xaml.cs | 4 ++++ 8 files changed, 49 insertions(+), 20 deletions(-) diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index 16e3777f7..b120c4f28 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -21,9 +21,6 @@ namespace Wox.Plugin.CMD public List Query(Query query) { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - List results = new List(); List pushedResults = new List(); if (query.Search == ">") @@ -80,8 +77,6 @@ namespace Wox.Plugin.CMD catch (Exception) { } } - stopwatch.Stop(); - DebugHelper.WriteLine("CMD:" + stopwatch.ElapsedMilliseconds + "ms"); return results; } diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index fabc450f2..af31c7a70 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; @@ -21,7 +22,7 @@ namespace Wox.Core.Plugin { public const string ActionKeywordWildcardSign = "*"; private static List pluginMetadatas; - private static List> instantSearches; + private static List> instantSearches; public static String DebuggerMode { get; private set; } @@ -86,15 +87,17 @@ namespace Wox.Core.Plugin PluginPair pair = pluginPair; ThreadPool.QueueUserWorkItem(o => { - using (new Timeit(string.Format("Init {0}", pair.Metadata.Name))) + Stopwatch sw = new Stopwatch(); + sw.Start(); + pair.Plugin.Init(new PluginInitContext() { - pair.Plugin.Init(new PluginInitContext() - { - CurrentPluginMetadata = pair.Metadata, - Proxy = HttpProxy.Instance, - API = API - }); - } + CurrentPluginMetadata = pair.Metadata, + Proxy = HttpProxy.Instance, + API = API + }); + sw.Stop(); + DebugHelper.WriteLine(string.Format("Plugin init:{0} - {1}", pair.Metadata.Name, sw.ElapsedMilliseconds)); + pair.InitTime = sw.ElapsedMilliseconds; }); } @@ -129,7 +132,7 @@ namespace Wox.Core.Plugin { if (string.IsNullOrEmpty(query.RawQuery)) return false; var strings = query.RawQuery.Split(' '); - if(strings.Length == 1) return false; + if (strings.Length == 1) return false; var actionKeyword = strings[0].Trim(); if (string.IsNullOrEmpty(actionKeyword)) return false; @@ -163,11 +166,24 @@ namespace Wox.Core.Plugin { try { + Stopwatch sw = new Stopwatch(); + sw.Start(); List results = pair.Plugin.Query(query) ?? new List(); results.ForEach(o => { o.PluginID = pair.Metadata.ID; }); + sw.Stop(); + DebugHelper.WriteLine(string.Format("Plugin query: {0} - {1}", pair.Metadata.Name, sw.ElapsedMilliseconds)); + pair.QueryCount += 1; + if (pair.QueryCount == 1) + { + pair.AvgQueryTime = sw.ElapsedMilliseconds; + } + else + { + pair.AvgQueryTime = (pair.AvgQueryTime + sw.ElapsedMilliseconds) / 2; + } API.PushResults(query, pair.Metadata, results); } catch (System.Exception e) @@ -176,7 +192,7 @@ namespace Wox.Core.Plugin } } - private static List> LoadInstantSearches() + private static List> LoadInstantSearches() { if (instantSearches != null) return instantSearches; @@ -196,7 +212,7 @@ namespace Wox.Core.Plugin foreach (Type type in types) { - instantSearches.Add(new KeyValuePair(metadata,Activator.CreateInstance(type) as IInstantSearch)); + instantSearches.Add(new KeyValuePair(metadata, Activator.CreateInstance(type) as IInstantSearch)); } } catch (System.Exception e) diff --git a/Wox.Plugin/PluginPair.cs b/Wox.Plugin/PluginPair.cs index b3053c057..03aa657ce 100644 --- a/Wox.Plugin/PluginPair.cs +++ b/Wox.Plugin/PluginPair.cs @@ -10,6 +10,12 @@ namespace Wox.Plugin public IPlugin Plugin { get; set; } public PluginMetadata Metadata { get; set; } + internal long InitTime { get; set; } + + internal long AvgQueryTime { get; set; } + + internal int QueryCount { get; set; } + public override string ToString() { return Metadata.Name; diff --git a/Wox/Languages/en.xaml b/Wox/Languages/en.xaml index 54ad62c9a..de368e59c 100644 --- a/Wox/Languages/en.xaml +++ b/Wox/Languages/en.xaml @@ -22,6 +22,8 @@ Action keyword Plugin Directory Author + Init time: {0}ms + Query time: {0}ms Theme diff --git a/Wox/Languages/zh-cn.xaml b/Wox/Languages/zh-cn.xaml index 39688d68f..131e333be 100644 --- a/Wox/Languages/zh-cn.xaml +++ b/Wox/Languages/zh-cn.xaml @@ -22,7 +22,9 @@ 触发关键字 插件目录 作者 - + 加载耗时:{0}ms + 查询耗时:{0}ms + 主题 浏览更多主题 diff --git a/Wox/Languages/zh-tw.xaml b/Wox/Languages/zh-tw.xaml index 694cd3175..e788226e7 100644 --- a/Wox/Languages/zh-tw.xaml +++ b/Wox/Languages/zh-tw.xaml @@ -22,7 +22,9 @@ 觸發關鍵字 插件目錄 作者 - + 加載耗時:{0}ms + 查詢耗時:{0}ms + 主題 瀏覽更多主題 diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index 99f0237d2..c44b71cc2 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -95,10 +95,12 @@ - + + + diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index b607281b0..8a33b19a3 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -477,6 +477,10 @@ namespace Wox provider = pair.Plugin as ISettingProvider; pluginAuthor.Visibility = Visibility.Visible; pluginActionKeyword.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; tbOpenPluginDirecoty.Visibility = Visibility.Visible; pluginTitle.Text = pair.Metadata.Name; From 7b0a643de339fb508d948a1691ff950125e04499 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 5 Feb 2015 18:43:05 +0800 Subject: [PATCH 07/26] Add IExclusiveSearch interface [WIP] --- Plugins/Wox.Plugin.CMD/CMD.cs | 8 ++- Wox.Core/Plugin/PluginManager.cs | 50 ++++++++++++++++++- .../Plugin/QueryDispatcher/QueryDispatcher.cs | 15 +++++- Wox.Plugin/Features/IExclusiveSearch.cs | 12 +++++ Wox.Plugin/IInstantSearch.cs | 1 + Wox.Plugin/Wox.Plugin.csproj | 1 + 6 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 Wox.Plugin/Features/IExclusiveSearch.cs diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index b120c4f28..cd522d56a 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -9,11 +9,12 @@ using WindowsInput; using WindowsInput.Native; using Wox.Infrastructure; using Wox.Infrastructure.Hotkey; +using Wox.Plugin.Features; using Control = System.Windows.Controls.Control; namespace Wox.Plugin.CMD { - public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantSearch + public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantSearch,IExclusiveSearch { private PluginInitContext context; private bool WinRStroked; @@ -217,5 +218,10 @@ namespace Wox.Plugin.CMD if (query.StartsWith(">")) return true; return false; } + + public bool IsExclusiveSearch(Query query) + { + return query.Search.StartsWith(">"); + } } } \ No newline at end of file diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index af31c7a70..9cf930c78 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -12,6 +12,7 @@ using Wox.Infrastructure; using Wox.Infrastructure.Http; using Wox.Infrastructure.Logger; using Wox.Plugin; +using Wox.Plugin.Features; namespace Wox.Core.Plugin { @@ -23,7 +24,7 @@ namespace Wox.Core.Plugin public const string ActionKeywordWildcardSign = "*"; private static List pluginMetadatas; private static List> instantSearches; - + private static List> exclusiveSearchPlugins; public static String DebuggerMode { get; private set; } public static IPublicAPI API { get; private set; } @@ -116,6 +117,7 @@ namespace Wox.Core.Plugin { if (!string.IsNullOrEmpty(query.RawQuery.Trim())) { + query.Search = IsUserPluginQuery(query) ? query.RawQuery.Substring(query.RawQuery.IndexOf(' ') + 1) : query.RawQuery; QueryDispatcher.QueryDispatcher.Dispatch(query); } } @@ -238,5 +240,51 @@ namespace Wox.Core.Plugin { return AllPlugins.FirstOrDefault(o => o.Metadata.ID == id); } + + internal static List> LoadExclusiveSearchPlugins() + { + if (exclusiveSearchPlugins != null) return exclusiveSearchPlugins; + + exclusiveSearchPlugins = new List>(); + List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); + + foreach (PluginMetadata metadata in CSharpPluginMetadatas) + { + try + { + Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); + List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IExclusiveSearch))).ToList(); + if (types.Count == 0) + { + continue; + } + + foreach (Type type in types) + { + exclusiveSearchPlugins.Add(new KeyValuePair(AllPlugins.First(o => o.Metadata.ID == metadata.ID), + Activator.CreateInstance(type) as IExclusiveSearch)); + } + } + catch (System.Exception e) + { + Log.Error(string.Format("Couldn't load plugin {0}: {1}", metadata.Name, e.Message)); +#if (DEBUG) + { + throw; + } +#endif + } + } + + return exclusiveSearchPlugins; + } + + internal static PluginPair GetExclusiveSearchPlugin(Query query) + { + KeyValuePair plugin = LoadExclusiveSearchPlugins().FirstOrDefault(o => o.Value.IsExclusiveSearch((query))); + if (plugin.Key != null) return plugin.Key; + + return null; + } } } diff --git a/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs index e5f5b76bf..3b4a4af55 100644 --- a/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs @@ -1,4 +1,7 @@  +using System.Threading; +using Wox.Plugin; + namespace Wox.Core.Plugin.QueryDispatcher { internal static class QueryDispatcher @@ -8,14 +11,22 @@ namespace Wox.Core.Plugin.QueryDispatcher public static void Dispatch(Wox.Plugin.Query query) { + PluginPair exclusiveSearchPlugin = PluginManager.GetExclusiveSearchPlugin(query); + if (exclusiveSearchPlugin != null) + { + ThreadPool.QueueUserWorkItem(state => + { + PluginManager.ExecutePluginQuery(exclusiveSearchPlugin, query); + }); + return; + } + if (PluginManager.IsUserPluginQuery(query)) { - query.Search = query.RawQuery.Substring(query.RawQuery.IndexOf(' ') + 1); UserPluginDispatcher.Dispatch(query); } else { - query.Search = query.RawQuery; SystemPluginDispatcher.Dispatch(query); } } diff --git a/Wox.Plugin/Features/IExclusiveSearch.cs b/Wox.Plugin/Features/IExclusiveSearch.cs new file mode 100644 index 000000000..0339b5094 --- /dev/null +++ b/Wox.Plugin/Features/IExclusiveSearch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Wox.Plugin.Features +{ + public interface IExclusiveSearch + { + bool IsExclusiveSearch(Query query); + } +} diff --git a/Wox.Plugin/IInstantSearch.cs b/Wox.Plugin/IInstantSearch.cs index 0799f45f4..553c6573b 100644 --- a/Wox.Plugin/IInstantSearch.cs +++ b/Wox.Plugin/IInstantSearch.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Wox.Plugin.Features; namespace Wox.Plugin { diff --git a/Wox.Plugin/Wox.Plugin.csproj b/Wox.Plugin/Wox.Plugin.csproj index 424272a20..665f70ff3 100644 --- a/Wox.Plugin/Wox.Plugin.csproj +++ b/Wox.Plugin/Wox.Plugin.csproj @@ -46,6 +46,7 @@ + From ad11ca0a87d17d2f69966bdcd191617e8cf027a9 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 5 Feb 2015 22:20:42 +0800 Subject: [PATCH 08/26] Add IExclusivePlugin --- Plugins/Wox.Plugin.CMD/CMD.cs | 6 +- .../PluginIndicator.cs | 15 +- .../{WebSearchPlugin.cs => WebQueryPlugin.cs} | 15 +- .../Wox.Plugin.WebSearch.csproj | 280 +++++++++--------- Wox.Core/Plugin/PluginConfig.cs | 1 - Wox.Core/Plugin/PluginInstaller.cs | 1 - Wox.Core/Plugin/PluginManager.cs | 64 ++-- .../ExclusiveQueryDispatcher.cs | 30 ++ ...ispatcher.cs => GenericQueryDispatcher.cs} | 7 +- .../Plugin/QueryDispatcher/QueryDispatcher.cs | 22 +- .../UserPluginQueryDispatcher.cs | 37 --- Wox.Core/Wox.Core.csproj | 4 +- Wox.Infrastructure/DebugHelper.cs | 1 + ...IExclusiveSearch.cs => IExclusiveQuery.cs} | 4 +- Wox.Plugin/Features/IInstantQuery.cs | 7 + Wox.Plugin/IInstantSearch.cs | 13 - Wox.Plugin/PluginMetadata.cs | 2 +- Wox.Plugin/PluginType.cs | 13 - Wox.Plugin/Wox.Plugin.csproj | 5 +- Wox.Test/QueryTest.cs | 4 +- Wox/MainWindow.xaml.cs | 2 +- 21 files changed, 254 insertions(+), 279 deletions(-) rename Plugins/Wox.Plugin.WebSearch/{WebSearchPlugin.cs => WebQueryPlugin.cs} (88%) create mode 100644 Wox.Core/Plugin/QueryDispatcher/ExclusiveQueryDispatcher.cs rename Wox.Core/Plugin/QueryDispatcher/{SystemPluginQueryDispatcher.cs => GenericQueryDispatcher.cs} (55%) delete mode 100644 Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs rename Wox.Plugin/Features/{IExclusiveSearch.cs => IExclusiveQuery.cs} (62%) create mode 100644 Wox.Plugin/Features/IInstantQuery.cs delete mode 100644 Wox.Plugin/IInstantSearch.cs delete mode 100644 Wox.Plugin/PluginType.cs diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index cd522d56a..da5877c67 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -14,7 +14,7 @@ using Control = System.Windows.Controls.Control; namespace Wox.Plugin.CMD { - public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantSearch,IExclusiveSearch + public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery { private PluginInitContext context; private bool WinRStroked; @@ -213,13 +213,13 @@ namespace Wox.Plugin.CMD return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } - public bool IsInstantSearch(string query) + public bool IsInstantQuery(string query) { if (query.StartsWith(">")) return true; return false; } - public bool IsExclusiveSearch(Query query) + public bool IsExclusiveQuery(Query query) { return query.Search.StartsWith(">"); } diff --git a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs index 645401339..0a4619826 100644 --- a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs +++ b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs @@ -15,7 +15,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.IsGenericPlugin(o.Metadata)).ToList(); } foreach (PluginMetadata metadata in allPlugins.Select(o => o.Metadata)) @@ -45,19 +45,6 @@ namespace Wox.Plugin.PluginIndicator } } - //results.AddRange(UserSettingStorage.Instance.WebSearches.Where(o => o.ActionWord.StartsWith(query.Search) && o.Enabled).Select(n => new Result() - //{ - // Title = n.ActionWord, - // SubTitle = string.Format("Activate {0} web search", n.ActionWord), - // Score = 100, - // IcoPath = "Images/work.png", - // Action = (c) => - // { - // context.API.ChangeQuery(n.ActionWord + " "); - // return false; - // } - //})); - return results; } diff --git a/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs b/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs similarity index 88% rename from Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs rename to Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs index 8a2a43011..41636b24f 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebSearchPlugin.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs @@ -5,11 +5,12 @@ using System.IO; using System.Linq; using System.Reflection; using Wox.Core.UserSettings; +using Wox.Plugin.Features; using Wox.Plugin.WebSearch.SuggestionSources; namespace Wox.Plugin.WebSearch { - public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantSearch + public class WebQueryPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery { private PluginInitContext context; @@ -18,7 +19,7 @@ namespace Wox.Plugin.WebSearch List results = new List(); WebSearch webSearch = - WebSearchStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionWord == query.FirstSearch.Trim() && o.Enabled); + WebSearchStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionWord == query.FirstSearch.Trim() && !string.IsNullOrEmpty(query.SecondSearch) && o.Enabled); if (webSearch != null) { @@ -98,15 +99,19 @@ namespace Wox.Plugin.WebSearch return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } - public bool IsInstantSearch(string query) + public bool IsInstantQuery(string query) { var strings = query.Split(' '); if (strings.Length > 1) { - return WebSearchStorage.Instance.EnableWebSearchSuggestion && - WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == strings[0] && o.Enabled); + return WebSearchStorage.Instance.WebSearches.Exists(o => o.ActionWord == strings[0] && o.Enabled); } return false; } + + public bool IsExclusiveQuery(Query query) + { + return IsInstantQuery(query.RawQuery); + } } } diff --git a/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj b/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj index 8c84b7b91..3f9a500eb 100644 --- a/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj +++ b/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj @@ -1,147 +1,147 @@ - - - - - Debug - AnyCPU - {403B57F2-1856-4FC7-8A24-36AB346B763E} - Library - Properties - Wox.Plugin.WebSearch - Wox.Plugin.WebSearch - v3.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.WebSearch\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.WebSearch\ - TRACE - prompt - 4 - false - - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - WebSearchesSetting.xaml - - - - WebSearchSetting.xaml - - - - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - - - - - - {B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} - Wox.Core - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + + + Debug + AnyCPU + {403B57F2-1856-4FC7-8A24-36AB346B763E} + Library + Properties + Wox.Plugin.WebSearch + Wox.Plugin.WebSearch + v3.5 + 512 + ..\..\ + true + + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.WebSearch\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.WebSearch\ + TRACE + prompt + 4 + false + + + + False + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + WebSearchesSetting.xaml + + + + WebSearchSetting.xaml + + + + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + + + + {B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} + Wox.Core + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + + PreserveNewest + + + + + PreserveNewest + + + + + PreserveNewest + + + + + PreserveNewest + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + --> \ No newline at end of file diff --git a/Wox.Core/Plugin/PluginConfig.cs b/Wox.Core/Plugin/PluginConfig.cs index 6c96ef777..f47e1dac0 100644 --- a/Wox.Core/Plugin/PluginConfig.cs +++ b/Wox.Core/Plugin/PluginConfig.cs @@ -78,7 +78,6 @@ namespace Wox.Core.Plugin try { metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); - metadata.PluginType = PluginType.User; metadata.PluginDirectory = pluginDirectory; } catch (System.Exception) diff --git a/Wox.Core/Plugin/PluginInstaller.cs b/Wox.Core/Plugin/PluginInstaller.cs index df9939aaf..77577aa9b 100644 --- a/Wox.Core/Plugin/PluginInstaller.cs +++ b/Wox.Core/Plugin/PluginInstaller.cs @@ -112,7 +112,6 @@ namespace Wox.Core.Plugin try { metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); - metadata.PluginType = PluginType.User; metadata.PluginDirectory = pluginDirectory; } catch (System.Exception) diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 9cf930c78..fb13b5781 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -23,8 +23,8 @@ namespace Wox.Core.Plugin { public const string ActionKeywordWildcardSign = "*"; private static List pluginMetadatas; - private static List> instantSearches; - private static List> exclusiveSearchPlugins; + private static List> instantSearches; + private static List> exclusiveSearchPlugins; public static String DebuggerMode { get; private set; } public static IPublicAPI API { get; private set; } @@ -117,7 +117,7 @@ namespace Wox.Core.Plugin { if (!string.IsNullOrEmpty(query.RawQuery.Trim())) { - query.Search = IsUserPluginQuery(query) ? query.RawQuery.Substring(query.RawQuery.IndexOf(' ') + 1) : query.RawQuery; + query.Search = IsActionKeywordQuery(query) ? query.RawQuery.Substring(query.RawQuery.IndexOf(' ') + 1) : query.RawQuery; QueryDispatcher.QueryDispatcher.Dispatch(query); } } @@ -130,7 +130,12 @@ namespace Wox.Core.Plugin } } - public static bool IsUserPluginQuery(Query query) + /// + /// Check if a query contains action keyword + /// + /// + /// + public static bool IsActionKeywordQuery(Query query) { if (string.IsNullOrEmpty(query.RawQuery)) return false; var strings = query.RawQuery.Split(' '); @@ -139,10 +144,10 @@ namespace Wox.Core.Plugin var actionKeyword = strings[0].Trim(); if (string.IsNullOrEmpty(actionKeyword)) return false; - return plugins.Any(o => o.Metadata.PluginType == PluginType.User && o.Metadata.ActionKeyword == actionKeyword); + return plugins.Any(o => o.Metadata.ActionKeyword == actionKeyword); } - public static bool IsSystemPlugin(PluginMetadata metadata) + public static bool IsGenericPlugin(PluginMetadata metadata) { return metadata.ActionKeyword == ActionKeywordWildcardSign; } @@ -152,9 +157,9 @@ namespace Wox.Core.Plugin DebuggerMode = path; } - public static bool IsInstantSearch(string query) + public static bool IsInstantQuery(string query) { - return LoadInstantSearches().Any(o => o.Value.IsInstantSearch(query)); + return LoadInstantSearches().Any(o => o.Value.IsInstantQuery(query)); } public static bool IsInstantSearchPlugin(PluginMetadata pluginMetadata) @@ -194,11 +199,11 @@ namespace Wox.Core.Plugin } } - private static List> LoadInstantSearches() + private static List> LoadInstantSearches() { if (instantSearches != null) return instantSearches; - instantSearches = new List>(); + instantSearches = new List>(); List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); foreach (PluginMetadata metadata in CSharpPluginMetadatas) @@ -206,7 +211,7 @@ namespace Wox.Core.Plugin try { Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); - List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IInstantSearch))).ToList(); + List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IInstantQuery))).ToList(); if (types.Count == 0) { continue; @@ -214,7 +219,7 @@ namespace Wox.Core.Plugin foreach (Type type in types) { - instantSearches.Add(new KeyValuePair(metadata, Activator.CreateInstance(type) as IInstantSearch)); + instantSearches.Add(new KeyValuePair(metadata, Activator.CreateInstance(type) as IInstantQuery)); } } catch (System.Exception e) @@ -241,11 +246,11 @@ namespace Wox.Core.Plugin return AllPlugins.FirstOrDefault(o => o.Metadata.ID == id); } - internal static List> LoadExclusiveSearchPlugins() + internal static List> LoadExclusiveSearchPlugins() { if (exclusiveSearchPlugins != null) return exclusiveSearchPlugins; - exclusiveSearchPlugins = new List>(); + exclusiveSearchPlugins = new List>(); List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); foreach (PluginMetadata metadata in CSharpPluginMetadatas) @@ -253,7 +258,7 @@ namespace Wox.Core.Plugin try { Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); - List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IExclusiveSearch))).ToList(); + List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IExclusiveQuery))).ToList(); if (types.Count == 0) { continue; @@ -261,8 +266,8 @@ namespace Wox.Core.Plugin foreach (Type type in types) { - exclusiveSearchPlugins.Add(new KeyValuePair(AllPlugins.First(o => o.Metadata.ID == metadata.ID), - Activator.CreateInstance(type) as IExclusiveSearch)); + exclusiveSearchPlugins.Add(new KeyValuePair(AllPlugins.First(o => o.Metadata.ID == metadata.ID), + Activator.CreateInstance(type) as IExclusiveQuery)); } } catch (System.Exception e) @@ -279,12 +284,31 @@ namespace Wox.Core.Plugin return exclusiveSearchPlugins; } - internal static PluginPair GetExclusiveSearchPlugin(Query query) + internal static PluginPair GetExclusivePlugin(Query query) { - KeyValuePair plugin = LoadExclusiveSearchPlugins().FirstOrDefault(o => o.Value.IsExclusiveSearch((query))); - if (plugin.Key != null) return plugin.Key; + KeyValuePair plugin = LoadExclusiveSearchPlugins().FirstOrDefault(o => o.Value.IsExclusiveQuery((query))); + return plugin.Key; + } + + internal static PluginPair GetActionKeywordPlugin(Query query) + { + PluginPair exclusivePluginPair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.GetActionKeyword()); + if (exclusivePluginPair != null) + { + var customizedPluginConfig = UserSettingStorage.Instance. + CustomizedPluginConfigs.FirstOrDefault(o => o.ID == exclusivePluginPair.Metadata.ID); + if (customizedPluginConfig != null && !customizedPluginConfig.Disabled) + { + return exclusivePluginPair; + } + } return null; } + + internal static bool IsExclusivePluginQuery(Query query) + { + return GetExclusivePlugin(query) != null || GetActionKeywordPlugin(query) != null; + } } } diff --git a/Wox.Core/Plugin/QueryDispatcher/ExclusiveQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/ExclusiveQueryDispatcher.cs new file mode 100644 index 000000000..d0923c34c --- /dev/null +++ b/Wox.Core/Plugin/QueryDispatcher/ExclusiveQueryDispatcher.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Wox.Core.Exception; +using Wox.Core.UserSettings; +using Wox.Infrastructure.Logger; +using Wox.Plugin; + +namespace Wox.Core.Plugin.QueryDispatcher +{ + public class ExclusiveQueryDispatcher : BaseQueryDispatcher + { + protected override List GetPlugins(Query query) + { + List pluginPairs = new List(); + var exclusivePluginPair = PluginManager.GetExclusivePlugin(query) ?? + PluginManager.GetActionKeywordPlugin(query); + if (exclusivePluginPair != null) + { + pluginPairs.Add(exclusivePluginPair); + } + + return pluginPairs; + } + + + + } +} diff --git a/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/GenericQueryDispatcher.cs similarity index 55% rename from Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs rename to Wox.Core/Plugin/QueryDispatcher/GenericQueryDispatcher.cs index 9a9948df0..5c53c556b 100644 --- a/Wox.Core/Plugin/QueryDispatcher/SystemPluginQueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/GenericQueryDispatcher.cs @@ -8,14 +8,11 @@ using Wox.Plugin; namespace Wox.Core.Plugin.QueryDispatcher { - public class SystemPluginQueryDispatcher : BaseQueryDispatcher + public class GenericQueryDispatcher : BaseQueryDispatcher { - private readonly List allSytemPlugins = - PluginManager.AllPlugins.Where(o => PluginManager.IsSystemPlugin(o.Metadata)).ToList(); - protected override List GetPlugins(Query query) { - return allSytemPlugins; + return PluginManager.AllPlugins.Where(o => PluginManager.IsGenericPlugin(o.Metadata)).ToList(); } } } \ No newline at end of file diff --git a/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs index 3b4a4af55..5d2062b48 100644 --- a/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs +++ b/Wox.Core/Plugin/QueryDispatcher/QueryDispatcher.cs @@ -6,28 +6,18 @@ namespace Wox.Core.Plugin.QueryDispatcher { internal static class QueryDispatcher { - private static readonly IQueryDispatcher UserPluginDispatcher = new UserPluginQueryDispatcher(); - private static readonly IQueryDispatcher SystemPluginDispatcher = new SystemPluginQueryDispatcher(); + private static readonly IQueryDispatcher exclusivePluginDispatcher = new ExclusiveQueryDispatcher(); + private static readonly IQueryDispatcher genericQueryDispatcher = new GenericQueryDispatcher(); - public static void Dispatch(Wox.Plugin.Query query) + public static void Dispatch(Query query) { - PluginPair exclusiveSearchPlugin = PluginManager.GetExclusiveSearchPlugin(query); - if (exclusiveSearchPlugin != null) + if (PluginManager.IsExclusivePluginQuery(query)) { - ThreadPool.QueueUserWorkItem(state => - { - PluginManager.ExecutePluginQuery(exclusiveSearchPlugin, query); - }); - return; - } - - if (PluginManager.IsUserPluginQuery(query)) - { - UserPluginDispatcher.Dispatch(query); + exclusivePluginDispatcher.Dispatch(query); } else { - SystemPluginDispatcher.Dispatch(query); + genericQueryDispatcher.Dispatch(query); } } } diff --git a/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs b/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs deleted file mode 100644 index d3cebb88d..000000000 --- a/Wox.Core/Plugin/QueryDispatcher/UserPluginQueryDispatcher.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Wox.Core.Exception; -using Wox.Core.UserSettings; -using Wox.Infrastructure.Logger; -using Wox.Plugin; - -namespace Wox.Core.Plugin.QueryDispatcher -{ - public class UserPluginQueryDispatcher : BaseQueryDispatcher - { - protected override List GetPlugins(Query query) - { - List plugins = new List(); - //only first plugin that matches action keyword will get executed - PluginPair userPlugin = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.GetActionKeyword()); - if (userPlugin != null) - { - var customizedPluginConfig = UserSettingStorage.Instance. - CustomizedPluginConfigs.FirstOrDefault(o => o.ID == userPlugin.Metadata.ID); - if (customizedPluginConfig != null && customizedPluginConfig.Disabled) - { - //need to stop the loading animation - PluginManager.API.StopLoadingBar(); - } - else - { - plugins.Add(userPlugin); - } - } - - return plugins; - } - } -} diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index 92c63ae13..9fc73a2c9 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -86,8 +86,8 @@ - - + + diff --git a/Wox.Infrastructure/DebugHelper.cs b/Wox.Infrastructure/DebugHelper.cs index 5d5e11142..e31636b7e 100644 --- a/Wox.Infrastructure/DebugHelper.cs +++ b/Wox.Infrastructure/DebugHelper.cs @@ -10,6 +10,7 @@ namespace Wox.Infrastructure { public static void WriteLine(string msg) { + return; Debug.WriteLine(msg); } } diff --git a/Wox.Plugin/Features/IExclusiveSearch.cs b/Wox.Plugin/Features/IExclusiveQuery.cs similarity index 62% rename from Wox.Plugin/Features/IExclusiveSearch.cs rename to Wox.Plugin/Features/IExclusiveQuery.cs index 0339b5094..6c6acbf5e 100644 --- a/Wox.Plugin/Features/IExclusiveSearch.cs +++ b/Wox.Plugin/Features/IExclusiveQuery.cs @@ -5,8 +5,8 @@ using System.Text; namespace Wox.Plugin.Features { - public interface IExclusiveSearch + public interface IExclusiveQuery { - bool IsExclusiveSearch(Query query); + bool IsExclusiveQuery(Query query); } } diff --git a/Wox.Plugin/Features/IInstantQuery.cs b/Wox.Plugin/Features/IInstantQuery.cs new file mode 100644 index 000000000..154f167e2 --- /dev/null +++ b/Wox.Plugin/Features/IInstantQuery.cs @@ -0,0 +1,7 @@ +namespace Wox.Plugin.Features +{ + public interface IInstantQuery + { + bool IsInstantQuery(string query); + } +} \ No newline at end of file diff --git a/Wox.Plugin/IInstantSearch.cs b/Wox.Plugin/IInstantSearch.cs deleted file mode 100644 index 553c6573b..000000000 --- a/Wox.Plugin/IInstantSearch.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Wox.Plugin.Features; - -namespace Wox.Plugin -{ - public interface IInstantSearch - { - bool IsInstantSearch(string query); - } -} diff --git a/Wox.Plugin/PluginMetadata.cs b/Wox.Plugin/PluginMetadata.cs index 406257f86..48e6c024f 100644 --- a/Wox.Plugin/PluginMetadata.cs +++ b/Wox.Plugin/PluginMetadata.cs @@ -24,10 +24,10 @@ namespace Wox.Plugin } public string ExecuteFileName { get; set; } + public string PluginDirectory { get; set; } public string ActionKeyword { get; set; } - public PluginType PluginType { get; set; } public string IcoPath { get; set; } diff --git a/Wox.Plugin/PluginType.cs b/Wox.Plugin/PluginType.cs deleted file mode 100644 index b8ffc6e12..000000000 --- a/Wox.Plugin/PluginType.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Wox.Plugin -{ - public enum PluginType - { - System, - User - } -} \ No newline at end of file diff --git a/Wox.Plugin/Wox.Plugin.csproj b/Wox.Plugin/Wox.Plugin.csproj index 665f70ff3..80f2a52a4 100644 --- a/Wox.Plugin/Wox.Plugin.csproj +++ b/Wox.Plugin/Wox.Plugin.csproj @@ -46,8 +46,8 @@ - - + + @@ -56,7 +56,6 @@ - diff --git a/Wox.Test/QueryTest.cs b/Wox.Test/QueryTest.cs index 061e7d59f..03c766d5c 100644 --- a/Wox.Test/QueryTest.cs +++ b/Wox.Test/QueryTest.cs @@ -11,7 +11,7 @@ namespace Wox.Test public class QueryTest { [Test] - public void UserPluginQueryTest() + public void ExclusivePluginQueryTest() { Query q = new Query("f file.txt file2 file3"); q.Search = "file.txt file2 file3"; @@ -23,7 +23,7 @@ namespace Wox.Test } [Test] - public void SystemPluginQueryTest() + public void GenericPluginQueryTest() { Query q = new Query("file.txt file2 file3"); q.Search = q.RawQuery; diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 95a6e81bb..ac5469e33 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -416,7 +416,7 @@ namespace Wox private int GetSearchDelay(string query) { - if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantSearch(query)) + if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantQuery(query)) { DebugHelper.WriteLine("execute query without delay"); return 0; From 02e22e5781c7337955d63763e2c87265cbeb7c85 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 5 Feb 2015 23:29:41 +0800 Subject: [PATCH 09/26] Add top most function. --- Wox/Images/topmost.png | Bin 0 -> 4304 bytes Wox/MainWindow.xaml.cs | 37 +++++++++++++++ Wox/ResultPanel.xaml.cs | 21 ++++++++- Wox/Storage/TopMostRecordStorage.cs | 70 ++++++++++++++++++++++++++++ Wox/Wox.csproj | 4 ++ 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 Wox/Images/topmost.png create mode 100644 Wox/Storage/TopMostRecordStorage.cs diff --git a/Wox/Images/topmost.png b/Wox/Images/topmost.png new file mode 100644 index 0000000000000000000000000000000000000000..50b68e6e2076c2b9f85fa562ff5340b9901c34a5 GIT binary patch literal 4304 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 yz2YbxrNBT;K-DK { o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; + if (o.ContextMenu == null) + { + o.ContextMenu = new List(); + } + HanleTopMost(o); }); List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); Dispatcher.Invoke(new Action(() => @@ -763,6 +770,36 @@ namespace Wox } } + private void HanleTopMost(Result result) + { + if (TopMostRecordStorage.Instance.IsTopMost(result)) + { + result.ContextMenu.Add(new Result("Remove top most in this query", "Images\\topmost.png") + { + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ => + { + TopMostRecordStorage.Instance.Remove(result); + ShowMsg("Succeed", "", ""); + return false; + } + }); + } + else + { + result.ContextMenu.Add(new Result("Set as top most in this query", "Images\\topmost.png") + { + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ => + { + TopMostRecordStorage.Instance.Add(result); + ShowMsg("Succeed", "", ""); + return false; + } + }); + } + } + private void ShowContextMenuFromResult(Result result) { if (result.ContextMenu != null && result.ContextMenu.Count > 0) diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index 2a1d21717..341c08e12 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -8,6 +8,7 @@ using System.Windows.Input; using System.Windows.Media; using Wox.Helper; using Wox.Plugin; +using Wox.Storage; using UserControl = System.Windows.Controls.UserControl; namespace Wox @@ -34,7 +35,6 @@ namespace Wox public void AddResults(List results) { - if (Dirty) { Dirty = false; @@ -42,13 +42,30 @@ namespace Wox } foreach (var result in results) { - int position = GetInsertLocation(result.Score); + int position = 0; + if (IsTopMostResult(result)) + { + result.Score = int.MaxValue; + } + else + { + if (result.Score >= int.MaxValue) + { + result.Score = int.MaxValue - 1; + } + position = GetInsertLocation(result.Score); + } lbResults.Items.Insert(position, result); } lbResults.Margin = lbResults.Items.Count > 0 ? new Thickness { Top = 8 } : new Thickness { Top = 0 }; SelectFirst(); } + private bool IsTopMostResult(Result result) + { + return TopMostRecordStorage.Instance.IsTopMost(result); + } + private int GetInsertLocation(int currentScore) { int location = lbResults.Items.Count; diff --git a/Wox/Storage/TopMostRecordStorage.cs b/Wox/Storage/TopMostRecordStorage.cs new file mode 100644 index 000000000..87e8feb86 --- /dev/null +++ b/Wox/Storage/TopMostRecordStorage.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using Wox.Infrastructure.Storage; + +namespace Wox.Storage +{ + public class TopMostRecordStorage : JsonStrorage + { + public Dictionary records = new Dictionary(); + + protected override string ConfigFolder + { + get { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Config"); } + } + + protected override string ConfigName + { + get { return "TopMostRecords"; } + } + + internal bool IsTopMost(Plugin.Result result) + { + return records.Any(o => o.Value.Title == result.Title + && o.Value.SubTitle == result.SubTitle + && o.Value.PluginID == result.PluginID); + } + + internal void Remove(Plugin.Result result) + { + if (records.ContainsKey(result.OriginQuery.RawQuery)) + { + records.Remove(result.OriginQuery.RawQuery); + Save(); + } + } + + internal void Add(Plugin.Result result) + { + if (records.ContainsKey(result.OriginQuery.RawQuery)) + { + records[result.OriginQuery.RawQuery].Title = result.Title; + records[result.OriginQuery.RawQuery].SubTitle = result.SubTitle; + records[result.OriginQuery.RawQuery].PluginID = result.PluginID; + } + else + { + records.Add(result.OriginQuery.RawQuery, new TopMostRecord() + { + PluginID = result.PluginID, + Title = result.Title, + SubTitle = result.SubTitle, + }); + } + + Save(); + } + } + + + public class TopMostRecord + { + public string Title { get; set; } + public string SubTitle { get; set; } + public string PluginID { get; set; } + } +} diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 5102805cd..c290bdc4a 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -115,6 +115,7 @@ + WoxUpdate.xaml @@ -179,6 +180,9 @@ PreserveNewest + + PreserveNewest + Designer MSBuild:Compile From 998eecb94d3532dbaf86f674276ea90a715a608b Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Fri, 6 Feb 2015 18:13:22 +0800 Subject: [PATCH 10/26] fix regressive issues --- .../Wox.Plugin.WebSearch/WebQueryPlugin.cs | 8 ++++-- .../Wox.Plugin.WebSearch.csproj | 3 ++ Wox.Core/Plugin/PluginManager.cs | 28 ++++++++++++++----- Wox.Plugin/Query.cs | 4 +-- Wox.Test/UrlPluginTest.cs | 1 + 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs b/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs index 41636b24f..10632094a 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs @@ -10,16 +10,20 @@ using Wox.Plugin.WebSearch.SuggestionSources; namespace Wox.Plugin.WebSearch { - public class WebQueryPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery + public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery { private PluginInitContext context; 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() && !string.IsNullOrEmpty(query.SecondSearch) && o.Enabled); + WebSearchStorage.Instance.WebSearches.FirstOrDefault(o => o.ActionWord == query.FirstSearch.Trim() && o.Enabled); if (webSearch != null) { diff --git a/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj b/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj index 3f9a500eb..90a2c3dcc 100644 --- a/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj +++ b/Plugins/Wox.Plugin.WebSearch/Wox.Plugin.WebSearch.csproj @@ -67,6 +67,9 @@ + + PreserveNewest + MSBuild:Compile Designer diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index fb13b5781..5e93bb010 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -131,7 +131,7 @@ namespace Wox.Core.Plugin } /// - /// Check if a query contains action keyword + /// Check if a query contains valid action keyword /// /// /// @@ -144,7 +144,19 @@ namespace Wox.Core.Plugin var actionKeyword = strings[0].Trim(); if (string.IsNullOrEmpty(actionKeyword)) return false; - return plugins.Any(o => o.Metadata.ActionKeyword == actionKeyword); + PluginPair pair = plugins.FirstOrDefault(o => o.Metadata.ActionKeyword == actionKeyword); + if (pair != null) + { + var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == pair.Metadata.ID); + if (customizedPluginConfig != null && customizedPluginConfig.Disabled) + { + return false; + } + + return true; + } + + return false; } public static bool IsGenericPlugin(PluginMetadata metadata) @@ -292,15 +304,17 @@ namespace Wox.Core.Plugin internal static PluginPair GetActionKeywordPlugin(Query query) { - PluginPair exclusivePluginPair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.GetActionKeyword()); - if (exclusivePluginPair != null) + PluginPair actionKeywordPluginPair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.GetActionKeyword()); + if (actionKeywordPluginPair != null) { var customizedPluginConfig = UserSettingStorage.Instance. - CustomizedPluginConfigs.FirstOrDefault(o => o.ID == exclusivePluginPair.Metadata.ID); - if (customizedPluginConfig != null && !customizedPluginConfig.Disabled) + CustomizedPluginConfigs.FirstOrDefault(o => o.ID == actionKeywordPluginPair.Metadata.ID); + if (customizedPluginConfig != null && customizedPluginConfig.Disabled) { - return exclusivePluginPair; + return null; } + + return actionKeywordPluginPair; } return null; diff --git a/Wox.Plugin/Query.cs b/Wox.Plugin/Query.cs index dee962877..79fe259be 100644 --- a/Wox.Plugin/Query.cs +++ b/Wox.Plugin/Query.cs @@ -13,8 +13,8 @@ namespace Wox.Plugin /// /// Search part of a query. - /// This will not include action keyword if regular plugin gets it, and if a system plugin gets it, it should be same as RawQuery. - /// Since we allow user to switch a regular plugin to system plugin, so this property will always give you the "real" query part of + /// This will not include action keyword if exclusive plugin gets it, otherwise it should be same as RawQuery. + /// 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; } diff --git a/Wox.Test/UrlPluginTest.cs b/Wox.Test/UrlPluginTest.cs index 79f95109a..daaa9641c 100644 --- a/Wox.Test/UrlPluginTest.cs +++ b/Wox.Test/UrlPluginTest.cs @@ -31,6 +31,7 @@ namespace Wox.Test Assert.IsFalse(urlPlugin.IsURL("wwww")); Assert.IsFalse(urlPlugin.IsURL("wwww.c")); + Assert.IsFalse(urlPlugin.IsURL("wwww.c")); } } } From 82d30c6e745925b4f5eb98bedc34a3493dbc7627 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sat, 7 Feb 2015 16:53:33 +0800 Subject: [PATCH 11/26] Allow searches in context menu --- .../ContextMenuStorage.cs | 24 +- .../Wox.Plugin.Everything/Languages/en.xaml | 11 + .../Languages/zh-cn.xaml | 11 + .../Languages/zh-tw.xaml | 11 + Plugins/Wox.Plugin.Everything/Main.cs | 59 +- .../Wox.Plugin.Everything.csproj | 267 +++--- Plugins/Wox.Plugin.Program/Languages/en.xaml | 3 + .../Wox.Plugin.Program/Languages/zh-cn.xaml | 49 +- .../Wox.Plugin.Program/Languages/zh-tw.xaml | 48 +- Plugins/Wox.Plugin.Program/Programs.cs | 8 +- Wox.Infrastructure/StringMatcher.cs | 33 + Wox.Infrastructure/Wox.Infrastructure.csproj | 1 + Wox.Plugin/IPublicAPI.cs | 8 +- Wox/Images/{topmost.png => down.png} | Bin 4304 -> 4187 bytes Wox/Images/up.png | Bin 0 -> 4132 bytes Wox/Languages/en.xaml | 2 + Wox/Languages/zh-cn.xaml | 2 + Wox/Languages/zh-tw.xaml | 3 +- Wox/MainWindow.xaml.cs | 72 +- Wox/Msg.xaml | 2 +- Wox/Msg.xaml.cs | 5 +- Wox/Wox.csproj | 5 +- Wox/ias03vpr.pm0 | 850 ++++++++++++++++++ Wox/su54u2mz.xrz | 850 ++++++++++++++++++ 24 files changed, 2103 insertions(+), 221 deletions(-) create mode 100644 Plugins/Wox.Plugin.Everything/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml create mode 100644 Wox.Infrastructure/StringMatcher.cs rename Wox/Images/{topmost.png => down.png} (63%) create mode 100644 Wox/Images/up.png create mode 100644 Wox/ias03vpr.pm0 create mode 100644 Wox/su54u2mz.xrz diff --git a/Plugins/Wox.Plugin.Everything/ContextMenuStorage.cs b/Plugins/Wox.Plugin.Everything/ContextMenuStorage.cs index f778bd96e..1970e39a7 100644 --- a/Plugins/Wox.Plugin.Everything/ContextMenuStorage.cs +++ b/Plugins/Wox.Plugin.Everything/ContextMenuStorage.cs @@ -11,13 +11,13 @@ namespace Wox.Plugin.Everything { public class ContextMenuStorage : JsonStrorage { - [JsonProperty] - public List ContextMenus = new List(); - + [JsonProperty] public List ContextMenus = new List(); [JsonProperty] public int MaxSearchCount { get; set; } + public IPublicAPI API { get; set; } + protected override string ConfigName { get { return "EverythingContextMenu"; } @@ -28,20 +28,14 @@ namespace Wox.Plugin.Everything get { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } } + protected override void OnAfterLoad(ContextMenuStorage obj) + { + + } + protected override ContextMenuStorage LoadDefault() { - ContextMenus = new List() - { - new ContextMenu() - { - Name = "Open Containing Folder", - Command = "explorer.exe", - Argument = " /select,\"{path}\"", - ImagePath ="Images\\folder.png" - } - }; MaxSearchCount = 100; - Save(); return this; } } @@ -60,4 +54,4 @@ namespace Wox.Plugin.Everything [JsonProperty] public string ImagePath { get; set; } } -} +} \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Languages/en.xaml b/Plugins/Wox.Plugin.Everything/Languages/en.xaml new file mode 100644 index 000000000..18c583ae0 --- /dev/null +++ b/Plugins/Wox.Plugin.Everything/Languages/en.xaml @@ -0,0 +1,11 @@ + + + Everything is not runnin + Everything plugin has an error (enter to copy error message) + Copied + Can't start {0} + Open containing folder + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml new file mode 100644 index 000000000..50d3f189c --- /dev/null +++ b/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml @@ -0,0 +1,11 @@ + + + Everything没有运行,我们将自动为您启动内置Everything,请稍后进行查询 + Everything插件发生了一个错误(回车拷贝具体错误信息) + 拷贝成功 + 不能启动 {0} + 打开所属文件夹 + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml new file mode 100644 index 000000000..c61e4ffec --- /dev/null +++ b/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml @@ -0,0 +1,11 @@ + + + Everything沒有運行,我們將自動為您啟動內置Everything,請稍後進行查詢 + Everything插件發生了一個錯誤(回車拷貝具體錯誤信息) + 拷貝成功 + 不能啟動 {0} + 打開所屬文件夾 + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs index 3322f2541..86862097c 100644 --- a/Plugins/Wox.Plugin.Everything/Main.cs +++ b/Plugins/Wox.Plugin.Everything/Main.cs @@ -9,7 +9,7 @@ using Wox.Plugin.Everything.Everything; namespace Wox.Plugin.Everything { - public class Main : IPlugin + public class Main : IPlugin, IPluginI18n { PluginInitContext context; EverythingAPI api = new EverythingAPI(); @@ -59,7 +59,7 @@ namespace Wox.Plugin.Everything StartEverything(); results.Add(new Result() { - Title = "Everything is not running, we already run it for you now. Try search again", + Title = context.API.GetTranslation("wox_plugin_everything_is_not_running"), IcoPath = "Images\\warning.png" }); } @@ -67,12 +67,12 @@ namespace Wox.Plugin.Everything { results.Add(new Result() { - Title = "Everything plugin has an error (enter to copy error message)", + Title = context.API.GetTranslation("wox_plugin_everything_query_error"), SubTitle = e.Message, Action = _ => { System.Windows.Clipboard.SetText(e.Message + "\r\n" + e.StackTrace); - context.API.ShowMsg("Copied", "Error message has copied to your clipboard", string.Empty); + context.API.ShowMsg(context.API.GetTranslation("wox_plugin_everything_copied"), null, string.Empty); return false; }, IcoPath = "Images\\error.png" @@ -114,9 +114,13 @@ namespace Wox.Plugin.Everything { List contextMenus = new List(); + List availableContextMenus = new List(); + availableContextMenus.AddRange(GetDefaultContextMenu()); + availableContextMenus.AddRange(ContextMenuStorage.Instance.ContextMenus); + if (record.Type == ResultType.File) { - foreach (ContextMenu contextMenu in ContextMenuStorage.Instance.ContextMenus) + foreach (ContextMenu contextMenu in availableContextMenus) { contextMenus.Add(new Result() { @@ -126,11 +130,11 @@ namespace Wox.Plugin.Everything string argument = contextMenu.Argument.Replace("{path}", record.FullPath); try { - System.Diagnostics.Process.Start(contextMenu.Command, argument); + Process.Start(contextMenu.Command, argument); } catch { - context.API.ShowMsg("Can't start " + record.FullPath, string.Empty, string.Empty); + context.API.ShowMsg(string.Format(context.API.GetTranslation("wox_plugin_everything_canot_start"), record.FullPath), string.Empty, string.Empty); return false; } return true; @@ -143,9 +147,25 @@ namespace Wox.Plugin.Everything return contextMenus; } + private List GetDefaultContextMenu() + { + List defaultContextMenus = new List(); + ContextMenu openFolderContextMenu = new ContextMenu() + { + Name = context.API.GetTranslation("wox_plugin_everything_open_containing_folder"), + Command = "explorer.exe", + Argument = " /select,\"{path}\"", + ImagePath = "Images\\folder.png" + }; + + defaultContextMenus.Add(openFolderContextMenu); + return defaultContextMenus; + } + public void Init(PluginInitContext context) { this.context = context; + ContextMenuStorage.Instance.API = context.API; LoadLibrary(Path.Combine( Path.Combine(context.CurrentPluginMetadata.PluginDirectory, (IntPtr.Size == 4) ? "x86" : "x64"), @@ -159,12 +179,20 @@ namespace Wox.Plugin.Everything { if (!CheckEverythingIsRunning()) { - Process p = new Process(); - p.StartInfo.Verb = "runas"; - p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - p.StartInfo.FileName = GetEverythingPath(); - p.StartInfo.UseShellExecute = true; - p.Start(); + try + { + Process p = new Process(); + p.StartInfo.Verb = "runas"; + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + p.StartInfo.FileName = GetEverythingPath(); + p.StartInfo.UseShellExecute = true; + p.Start(); + } + catch (Exception e) + { + context.API.ShowMsg("Start Everything failed"); + } + } } @@ -178,5 +206,10 @@ namespace Wox.Plugin.Everything string everythingFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "PortableEverything"); return Path.Combine(everythingFolder, "Everything.exe"); } + + public string GetLanguagesFolder() + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); + } } } diff --git a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj index e25b8e225..6eef11c31 100644 --- a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj +++ b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj @@ -1,130 +1,151 @@ - - - - - Debug - AnyCPU - {230AE83F-E92E-4E69-8355-426B305DA9C0} - Library - Properties - Wox.Plugin.Everything - Wox.Plugin.Everything - v3.5 - 512 - ..\Wox\ - true - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.Everything\ - DEBUG;TRACE - prompt - 4 - AnyCPU - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.Everything\ - TRACE - prompt - 4 - - - - - - - False - ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - PreserveNewest - - - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + + + Debug + AnyCPU + {230AE83F-E92E-4E69-8355-426B305DA9C0} + Library + Properties + Wox.Plugin.Everything + Wox.Plugin.Everything + v3.5 + 512 + ..\Wox\ + true + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.Everything\ + DEBUG;TRACE + prompt + 4 + AnyCPU + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.Everything\ + TRACE + prompt + 4 + + + + + + + False + ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + PreserveNewest + + + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + --> \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Languages/en.xaml b/Plugins/Wox.Plugin.Program/Languages/en.xaml index 3e9a4f1b6..c0b194f01 100644 --- a/Plugins/Wox.Plugin.Program/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Program/Languages/en.xaml @@ -19,5 +19,8 @@ (Each suffix should split by ;) Sucessfully update file suffixes File suffixes can't be empty + + Run As Administrator + Open containing folder \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml index 388734467..288e3ba13 100644 --- a/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml +++ b/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml @@ -1,24 +1,27 @@ - - - - 删除 - 编辑 - 增加 - 位置 - 索引文件后缀 - 重新索引 - 索引中 - - - 请先选择一项 - 你确定要删除{0}吗? - - 更新 - Wox仅索引下列后缀的文件: - (每个后缀以英文状态下的分号分隔) - 成功更新索引文件后缀 - 文件后缀不能为空 - + + + + 删除 + 编辑 + 增加 + 位置 + 索引文件后缀 + 重新索引 + 索引中 + + + 请先选择一项 + 你确定要删除{0}吗? + + 更新 + Wox仅索引下列后缀的文件: + (每个后缀以英文状态下的分号分隔) + 成功更新索引文件后缀 + 文件后缀不能为空 + + 以管理员身份运行 + 打开所属文件夹 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml index d56fc2d4c..36b4cb42f 100644 --- a/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml @@ -1,24 +1,26 @@ - - - - 刪除 - 編輯 - 增加 - 位置 - 索引文件後綴 - 重新索引 - 索引中 - - - 請先選擇一項 - 你確定要刪除{0}嗎? - - 更新 - Wox僅索引下列後綴的文件: - (每個後綴以英文狀態下的分號分隔) - 成功更新索引文件後綴 - 文件後綴不能為空 - + + + + 刪除 + 編輯 + 增加 + 位置 + 索引文件後綴 + 重新索引 + 索引中 + + + 請先選擇一項 + 你確定要刪除{0}嗎? + + 更新 + Wox僅索引下列後綴的文件: + (每個後綴以英文狀態下的分號分隔) + 成功更新索引文件後綴 + 文件後綴不能為空 + + 以管理員身份運行 + 打開所屬文件夾 \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 4d888bd5b..63280d12a 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -48,7 +48,7 @@ namespace Wox.Plugin.Program { new Result() { - Title = "Run As Administrator", + Title = context.API.GetTranslation("wox_plugin_program_run_as_administrator"), Action = _ => { context.API.HideApp(); @@ -59,7 +59,7 @@ namespace Wox.Plugin.Program }, new Result() { - Title = "Open Containing Folder", + Title = context.API.GetTranslation("wox_plugin_program_open_containing_folder"), Action = _ => { context.API.HideApp(); @@ -85,8 +85,8 @@ namespace Wox.Plugin.Program static string ResolveShortcut(string filePath) { // IWshRuntimeLibrary is in the COM library "Windows Script Host Object Model" - IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell(); - IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(filePath); + WshShell shell = new WshShell(); + IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(filePath); return shortcut.TargetPath; } diff --git a/Wox.Infrastructure/StringMatcher.cs b/Wox.Infrastructure/StringMatcher.cs new file mode 100644 index 000000000..4d3d9dd5a --- /dev/null +++ b/Wox.Infrastructure/StringMatcher.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Wox.Infrastructure +{ + public class StringMatcher + { + /// + /// Check if a candidate is match with the source + /// + /// + /// + /// Match score + public static int Match(string source, string candidate) + { + if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(candidate)) return 0; + + FuzzyMatcher matcher = FuzzyMatcher.Create(candidate); + int score = matcher.Evaluate(source).Score; + if (score > 0) return score; + + score = matcher.Evaluate(source.Unidecode()).Score; + return score; + } + + public static bool IsMatch(string source, string candidate) + { + return Match(source, candidate) > 0; + } + } +} diff --git a/Wox.Infrastructure/Wox.Infrastructure.csproj b/Wox.Infrastructure/Wox.Infrastructure.csproj index 75a45afee..80a96bc32 100644 --- a/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -66,6 +66,7 @@ + diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index b564480db..3b2691177 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -42,6 +42,12 @@ namespace Wox.Plugin /// void ChangeQuery(string query, bool requery = false); + /// + /// Just change the query text, this won't raise search + /// + /// + void ChangeQueryText(string query); + /// /// Close Wox /// @@ -63,7 +69,7 @@ namespace Wox.Plugin /// Message title /// Message subtitle /// Message icon path (relative path to your plugin folder) - void ShowMsg(string title, string subTitle, string iconPath); + void ShowMsg(string title, string subTitle = "", string iconPath = ""); /// /// Open setting dialog diff --git a/Wox/Images/topmost.png b/Wox/Images/down.png similarity index 63% rename from Wox/Images/topmost.png rename to Wox/Images/down.png index 50b68e6e2076c2b9f85fa562ff5340b9901c34a5..b993805091e42d10c759965cd952da744a6c4992 100644 GIT binary patch delta 1454 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 hotkey: {0} failed Could not start {0} Invalid wox plugin file format + Set as topmost in this query + Cancel topmost in this query diff --git a/Wox/Languages/zh-cn.xaml b/Wox/Languages/zh-cn.xaml index 131e333be..977c44799 100644 --- a/Wox/Languages/zh-cn.xaml +++ b/Wox/Languages/zh-cn.xaml @@ -5,6 +5,8 @@ 注册热键:{0} 失败 启动命令 {0} 失败 不是合法的Wox插件格式 + 在当前查询中置顶 + 取消置顶 diff --git a/Wox/Languages/zh-tw.xaml b/Wox/Languages/zh-tw.xaml index e788226e7..79cc35b51 100644 --- a/Wox/Languages/zh-tw.xaml +++ b/Wox/Languages/zh-tw.xaml @@ -5,7 +5,8 @@ 註冊熱鍵:{0} 失敗 啟動命令 {0} 失敗 不是合法的Wox插件格式 - + 在當前查詢中置頂 + 取消置頂 Wox設置 diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 3c710ccfd..482604f4a 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; using System.Net; using System.Reflection; @@ -11,7 +12,6 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Input; -using System.Windows.Interop; using System.Windows.Media.Animation; using NHotkey; using NHotkey.Wpf; @@ -25,18 +25,14 @@ using Wox.Infrastructure; using Wox.Infrastructure.Hotkey; using Wox.Plugin; using Wox.Storage; -using Brushes = System.Windows.Media.Brushes; -using Color = System.Windows.Media.Color; using ContextMenu = System.Windows.Forms.ContextMenu; using DataFormats = System.Windows.DataFormats; using DragEventArgs = System.Windows.DragEventArgs; +using IDataObject = System.Windows.IDataObject; using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MenuItem = System.Windows.Forms.MenuItem; using MessageBox = System.Windows.MessageBox; using ToolTip = System.Windows.Controls.ToolTip; -using Wox.Infrastructure.Logger; -using IDataObject = System.Windows.IDataObject; -using System.IO; namespace Wox { @@ -52,6 +48,8 @@ namespace Wox private ToolTip toolTip = new ToolTip(); private bool ignoreTextChange = false; + private List CurrentContextMenus = new List(); + private string textBeforeEnterContextMenuMode; #endregion @@ -70,6 +68,16 @@ namespace Wox })); } + public void ChangeQueryText(string query) + { + Dispatcher.Invoke(new Action(() => + { + ignoreTextChange = true; + tbQuery.Text = query; + tbQuery.CaretIndex = tbQuery.Text.Length; + })); + } + public void CloseApp() { Dispatcher.Invoke(new Action(() => @@ -380,13 +388,43 @@ namespace Wox notifyIcon.ContextMenu = new ContextMenu(childen); } + private void QueryContextMenu() + { + pnlContextMenu.Clear(); + var query = tbQuery.Text.ToLower(); + if (string.IsNullOrEmpty(query)) + { + pnlContextMenu.AddResults(CurrentContextMenus); + } + else + { + List filterResults = new List(); + foreach (Result contextMenu in CurrentContextMenus) + { + if (StringMatcher.IsMatch(contextMenu.Title, query) + || StringMatcher.IsMatch(contextMenu.SubTitle, query)) + { + filterResults.Add(contextMenu); + } + } + pnlContextMenu.AddResults(filterResults); + } + } + private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) { if (ignoreTextChange) { ignoreTextChange = false; return; } - lastQuery = tbQuery.Text; toolTip.IsOpen = false; pnlResult.Dirty = true; + + if (IsInContextMenuMode) + { + QueryContextMenu(); + return; + } + + lastQuery = tbQuery.Text; int searchDelay = GetSearchDelay(lastQuery); Dispatcher.DelayInvoke("UpdateSearch", @@ -464,11 +502,11 @@ namespace Wox { PluginManager.Query(q); StopProgress(); - BackToResultMode(); } private void BackToResultMode() { + ChangeQueryText(textBeforeEnterContextMenuMode); pnlResult.Visibility = Visibility.Visible; pnlContextMenu.Visibility = Visibility.Collapsed; } @@ -490,6 +528,7 @@ namespace Wox private void HideWox() { + BackToResultMode(); Hide(); } @@ -553,7 +592,7 @@ namespace Wox case Key.N: case Key.J: - if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) { SelectNextItem(); } @@ -561,14 +600,14 @@ namespace Wox case Key.P: case Key.K: - if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) { SelectPrevItem(); } break; case Key.O: - if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) { if (IsInContextMenuMode) { @@ -592,7 +631,7 @@ namespace Wox break; case Key.D: - if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) { pnlResult.SelectNextPage(); } @@ -604,7 +643,7 @@ namespace Wox break; case Key.U: - if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) { pnlResult.SelectPrevPage(); } @@ -774,7 +813,7 @@ namespace Wox { if (TopMostRecordStorage.Instance.IsTopMost(result)) { - result.ContextMenu.Add(new Result("Remove top most in this query", "Images\\topmost.png") + result.ContextMenu.Add(new Result(GetTranslation("cancelTopMostInThisQuery"), "Images\\down.png") { PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Action = _ => @@ -787,7 +826,7 @@ namespace Wox } else { - result.ContextMenu.Add(new Result("Set as top most in this query", "Images\\topmost.png") + result.ContextMenu.Add(new Result(GetTranslation("setAsTopMostInThisQuery"), "Images\\up.png") { PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Action = _ => @@ -804,8 +843,11 @@ namespace Wox { if (result.ContextMenu != null && result.ContextMenu.Count > 0) { + textBeforeEnterContextMenuMode = tbQuery.Text; + ChangeQueryText(""); pnlContextMenu.Clear(); pnlContextMenu.AddResults(result.ContextMenu); + CurrentContextMenus = result.ContextMenu; pnlContextMenu.Visibility = Visibility.Visible; pnlResult.Visibility = Visibility.Collapsed; } diff --git a/Wox/Msg.xaml b/Wox/Msg.xaml index f99c9d0bf..aa2474704 100644 --- a/Wox/Msg.xaml +++ b/Wox/Msg.xaml @@ -27,7 +27,7 @@ - + Title diff --git a/Wox/Msg.xaml.cs b/Wox/Msg.xaml.cs index bf61c06ab..9f9801cf3 100644 --- a/Wox/Msg.xaml.cs +++ b/Wox/Msg.xaml.cs @@ -57,8 +57,11 @@ namespace Wox { public void Show(string title, string subTitle, string icopath) { tbTitle.Text = title; tbSubTitle.Text = subTitle; + if (string.IsNullOrEmpty(subTitle)) + { + tbSubTitle.Visibility = Visibility.Collapsed; + } if (!File.Exists(icopath)) { - //icopath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Images\\app.png"); imgIco.Source = new BitmapImage(new Uri("Images\\app.png", UriKind.Relative)); } else { diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index c290bdc4a..4badbf06b 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -180,7 +180,10 @@ PreserveNewest - + + PreserveNewest + + PreserveNewest diff --git a/Wox/ias03vpr.pm0 b/Wox/ias03vpr.pm0 new file mode 100644 index 000000000..2bf2868f8 --- /dev/null +++ b/Wox/ias03vpr.pm0 @@ -0,0 +1,850 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Forms; +using System.Windows.Input; +using System.Windows.Media.Animation; +using NHotkey; +using NHotkey.Wpf; +using Wox.Core.i18n; +using Wox.Core.Plugin; +using Wox.Core.Theme; +using Wox.Core.Updater; +using Wox.Core.UserSettings; +using Wox.Helper; +using Wox.Infrastructure; +using Wox.Infrastructure.Hotkey; +using Wox.Plugin; +using Wox.Storage; +using ContextMenu = System.Windows.Forms.ContextMenu; +using DataFormats = System.Windows.DataFormats; +using DragEventArgs = System.Windows.DragEventArgs; +using IDataObject = System.Windows.IDataObject; +using KeyEventArgs = System.Windows.Input.KeyEventArgs; +using MenuItem = System.Windows.Forms.MenuItem; +using MessageBox = System.Windows.MessageBox; +using ToolTip = System.Windows.Controls.ToolTip; + +namespace Wox +{ + public partial class MainWindow : IPublicAPI + { + + #region Properties + + private readonly Storyboard progressBarStoryboard = new Storyboard(); + private NotifyIcon notifyIcon; + private bool queryHasReturn; + private string lastQuery; + private ToolTip toolTip = new ToolTip(); + + private bool ignoreTextChange = false; + + #endregion + + #region Public API + + public void ChangeQuery(string query, bool requery = false) + { + Dispatcher.Invoke(new Action(() => + { + tbQuery.Text = query; + tbQuery.CaretIndex = tbQuery.Text.Length; + if (requery) + { + TextBoxBase_OnTextChanged(null, null); + } + })); + } + + public void CloseApp() + { + Dispatcher.Invoke(new Action(() => + { + notifyIcon.Visible = false; + Close(); + Environment.Exit(0); + })); + } + + public void HideApp() + { + Dispatcher.Invoke(new Action(HideWox)); + } + + public void ShowApp() + { + Dispatcher.Invoke(new Action(() => ShowWox())); + } + + public void ShowMsg(string title, string subTitle, string iconPath) + { + Dispatcher.Invoke(new Action(() => + { + var m = new Msg { Owner = GetWindow(this) }; + m.Show(title, subTitle, iconPath); + })); + } + + public void OpenSettingDialog() + { + Dispatcher.Invoke(new Action(() => WindowOpener.Open(this))); + } + + public void StartLoadingBar() + { + Dispatcher.Invoke(new Action(StartProgress)); + } + + public void StopLoadingBar() + { + Dispatcher.Invoke(new Action(StopProgress)); + } + + public void InstallPlugin(string path) + { + Dispatcher.Invoke(new Action(() => PluginManager.InstallPlugin(path))); + } + + public void ReloadPlugins() + { + Dispatcher.Invoke(new Action(() => PluginManager.Init(this))); + } + + public string GetTranslation(string key) + { + return InternationalizationManager.Instance.GetTranslation(key); + } + + public List GetAllPlugins() + { + return PluginManager.AllPlugins; + } + + public event WoxKeyDownEventHandler BackKeyDownEvent; + public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; + public event AfterWoxQueryEventHandler AfterWoxQueryEvent; + public event AfterWoxQueryEventHandler BeforeWoxQueryEvent; + public event ResultItemDropEventHandler ResultItemDropEvent; + + public void PushResults(Query query, PluginMetadata plugin, List results) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + o.OriginQuery = query; + if (o.ContextMenu != null) + { + o.ContextMenu.ForEach(t => + { + t.PluginDirectory = plugin.PluginDirectory; + t.PluginID = plugin.ID; + }); + } + }); + UpdateResultView(results); + } + + public void ShowContextMenu(PluginMetadata plugin, List results) + { + if (results != null && results.Count > 0) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + o.ContextMenu = null; + }); + pnlContextMenu.Clear(); + pnlContextMenu.AddResults(results); + pnlContextMenu.Visibility = Visibility.Visible; + pnlResult.Visibility = Visibility.Collapsed; + } + } + + #endregion + + public MainWindow() + { + InitializeComponent(); + ThreadPool.SetMaxThreads(30, 10); + ThreadPool.SetMinThreads(10, 5); + + WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); + GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback; + progressBar.ToolTip = toolTip; + InitialTray(); + pnlResult.LeftMouseClickEvent += SelectResult; + pnlResult.ItemDropEvent += pnlResult_ItemDropEvent; + pnlContextMenu.LeftMouseClickEvent += SelectResult; + pnlResult.RightMouseClickEvent += pnlResult_RightMouseClickEvent; + + ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + InternationalizationManager.Instance.ChangeLanguage(UserSettingStorage.Instance.Language); + + SetHotkey(UserSettingStorage.Instance.Hotkey, OnHotkey); + SetCustomPluginHotkey(); + + Closing += MainWindow_Closing; + //since MainWIndow implement IPublicAPI, so we need to finish ctor MainWindow object before + //PublicAPI invoke in plugin init methods. E.g FolderPlugin + ThreadPool.QueueUserWorkItem(o => + { + Thread.Sleep(50); + PluginManager.Init(this); + }); + ThreadPool.QueueUserWorkItem(o => + { + Thread.Sleep(50); + PreLoadImages(); + }); + } + + void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject, DragEventArgs args) + { + PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); + if (ResultItemDropEvent != null && pluginPair != null) + { + foreach (var delegateHandler in ResultItemDropEvent.GetInvocationList()) + { + if (delegateHandler.Target == pluginPair.Plugin) + { + delegateHandler.DynamicInvoke(result, dropDataObject, args); + } + } + } + } + + private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) + { + if (GlobalKeyboardEvent != null) + { + return GlobalKeyboardEvent((int)keyevent, vkcode, state); + } + return true; + } + + private void PreLoadImages() + { + ImageLoader.ImageLoader.PreloadImages(); + } + + void pnlResult_RightMouseClickEvent(Result result) + { + ShowContextMenuFromResult(result); + } + + void MainWindow_Closing(object sender, CancelEventArgs e) + { + UserSettingStorage.Instance.WindowLeft = Left; + UserSettingStorage.Instance.WindowTop = Top; + UserSettingStorage.Instance.Save(); + this.HideWox(); + e.Cancel = true; + } + + private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) + { + if (UserSettingStorage.Instance.WindowLeft == 0 + && UserSettingStorage.Instance.WindowTop == 0) + { + Left = UserSettingStorage.Instance.WindowLeft + = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; + Top = UserSettingStorage.Instance.WindowTop + = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 5; + } + else + { + Left = UserSettingStorage.Instance.WindowLeft; + Top = UserSettingStorage.Instance.WindowTop; + } + + InitProgressbarAnimation(); + WindowIntelopHelper.DisableControlBox(this); + CheckUpdate(); + } + + private void CheckUpdate() + { + UpdaterManager.Instance.PrepareUpdateReady += OnPrepareUpdateReady; + UpdaterManager.Instance.UpdateError += OnUpdateError; + UpdaterManager.Instance.CheckUpdate(); + } + + void OnUpdateError(object sender, EventArgs e) + { + string updateError = InternationalizationManager.Instance.GetTranslation("update_wox_update_error"); + MessageBox.Show(updateError); + } + + private void OnPrepareUpdateReady(object sender, EventArgs e) + { + Dispatcher.Invoke(new Action(() => + { + new WoxUpdate().ShowDialog(); + })); + } + + public void SetHotkey(string hotkeyStr, EventHandler action) + { + var hotkey = new HotkeyModel(hotkeyStr); + try + { + HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action); + } + catch (Exception) + { + string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr); + MessageBox.Show(errorMsg); + } + } + + public void RemoveHotkey(string hotkeyStr) + { + if (!string.IsNullOrEmpty(hotkeyStr)) + { + HotkeyManager.Current.Remove(hotkeyStr); + } + } + + private void SetCustomPluginHotkey() + { + if (UserSettingStorage.Instance.CustomPluginHotkeys == null) return; + foreach (CustomPluginHotkey hotkey in UserSettingStorage.Instance.CustomPluginHotkeys) + { + CustomPluginHotkey hotkey1 = hotkey; + SetHotkey(hotkey.Hotkey, delegate + { + ShowApp(); + ChangeQuery(hotkey1.ActionKeyword, true); + }); + } + } + + private void OnHotkey(object sender, HotkeyEventArgs e) + { + ToggleWox(); + e.Handled = true; + } + + public void ToggleWox() + { + if (!IsVisible) + { + ShowWox(); + } + else + { + HideWox(); + } + } + + private void InitProgressbarAnimation() + { + var da = new DoubleAnimation(progressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + var da1 = new DoubleAnimation(progressBar.X1, ActualWidth, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); + Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); + progressBarStoryboard.Children.Add(da); + progressBarStoryboard.Children.Add(da1); + progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever; + progressBar.Visibility = Visibility.Hidden; + progressBar.BeginStoryboard(progressBarStoryboard); + } + + private void InitialTray() + { + notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; + notifyIcon.Click += (o, e) => ShowWox(); + var open = new MenuItem("Open"); + open.Click += (o, e) => ShowWox(); + var setting = new MenuItem("Settings"); + setting.Click += (o, e) => OpenSettingDialog(); + var exit = new MenuItem("Exit"); + exit.Click += (o, e) => CloseApp(); + MenuItem[] childen = { open, setting, exit }; + notifyIcon.ContextMenu = new ContextMenu(childen); + } + + private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) + { + if (ignoreTextChange) { ignoreTextChange = false; return; } + + lastQuery = tbQuery.Text; + toolTip.IsOpen = false; + pnlResult.Dirty = true; + int searchDelay = GetSearchDelay(lastQuery); + + Dispatcher.DelayInvoke("UpdateSearch", + o => + { + Dispatcher.DelayInvoke("ClearResults", i => + { + // first try to use clear method inside pnlResult, which is more closer to the add new results + // and this will not bring splash issues.After waiting 100ms, if there still no results added, we + // must clear the result. otherwise, it will be confused why the query changed, but the results + // didn't. + if (pnlResult.Dirty) pnlResult.Clear(); + }, TimeSpan.FromMilliseconds(100), null); + queryHasReturn = false; + Query query = new Query(lastQuery); + query.IsIntantQuery = searchDelay == 0; + FireBeforeWoxQueryEvent(query); + Query(query); + Dispatcher.DelayInvoke("ShowProgressbar", originQuery => + { + if (!queryHasReturn && originQuery == tbQuery.Text && !string.IsNullOrEmpty(lastQuery)) + { + StartProgress(); + } + }, TimeSpan.FromMilliseconds(150), tbQuery.Text); + FireAfterWoxQueryEvent(query); + }, TimeSpan.FromMilliseconds(searchDelay)); + } + + private int GetSearchDelay(string query) + { + if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantQuery(query)) + { + DebugHelper.WriteLine("execute query without delay"); + return 0; + } + + DebugHelper.WriteLine("execute query with 200ms delay"); + return 200; + } + + private void FireAfterWoxQueryEvent(Query q) + { + if (AfterWoxQueryEvent != null) + { + //We shouldn't let those events slow down real query + //so I put it in the new thread + ThreadPool.QueueUserWorkItem(o => + { + AfterWoxQueryEvent(new WoxQueryEventArgs() + { + Query = q + }); + }); + } + } + + private void FireBeforeWoxQueryEvent(Query q) + { + if (BeforeWoxQueryEvent != null) + { + //We shouldn't let those events slow down real query + //so I put it in the new thread + ThreadPool.QueueUserWorkItem(o => + { + BeforeWoxQueryEvent(new WoxQueryEventArgs() + { + Query = q + }); + }); + } + } + + private void Query(Query q) + { + PluginManager.Query(q); + StopProgress(); + BackToResultMode(); + } + + private void BackToResultMode() + { + pnlResult.Visibility = Visibility.Visible; + pnlContextMenu.Visibility = Visibility.Collapsed; + } + + private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left) DragMove(); + } + + private void StartProgress() + { + progressBar.Visibility = Visibility.Visible; + } + + private void StopProgress() + { + progressBar.Visibility = Visibility.Hidden; + } + + private void HideWox() + { + Hide(); + } + + private void ShowWox(bool selectAll = true) + { + UserSettingStorage.Instance.IncreaseActivateTimes(); + if (!double.IsNaN(Left) && !double.IsNaN(Top)) + { + var origScreen = Screen.FromRectangle(new Rectangle((int)Left, (int)Top, (int)ActualWidth, (int)ActualHeight)); + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var coordX = (Left - origScreen.WorkingArea.Left) / (origScreen.WorkingArea.Width - ActualWidth); + var coordY = (Top - origScreen.WorkingArea.Top) / (origScreen.WorkingArea.Height - ActualHeight); + Left = (screen.WorkingArea.Width - ActualWidth) * coordX + screen.WorkingArea.Left; + Top = (screen.WorkingArea.Height - ActualHeight) * coordY + screen.WorkingArea.Top; + } + + Show(); + Activate(); + Focus(); + tbQuery.Focus(); + if (selectAll) tbQuery.SelectAll(); + } + + private void MainWindow_OnDeactivated(object sender, EventArgs e) + { + if (UserSettingStorage.Instance.HideWhenDeactive) + { + HideWox(); + } + } + + private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) + { + //when alt is pressed, the real key should be e.SystemKey + Key key = (e.Key == Key.System ? e.SystemKey : e.Key); + switch (key) + { + case Key.Escape: + if (IsInContextMenuMode) + { + BackToResultMode(); + } + else + { + HideWox(); + } + e.Handled = true; + break; + + case Key.Tab: + if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) + { + SelectPrevItem(); + } + else + { + SelectNextItem(); + } + e.Handled = true; + break; + + case Key.N: + case Key.J: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + SelectNextItem(); + } + break; + + case Key.P: + case Key.K: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + SelectPrevItem(); + } + break; + + case Key.O: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + if (IsInContextMenuMode) + { + BackToResultMode(); + } + else + { + ShowContextMenuFromResult(GetActiveResult()); + } + } + break; + + case Key.Down: + SelectNextItem(); + e.Handled = true; + break; + + case Key.Up: + SelectPrevItem(); + e.Handled = true; + break; + + case Key.D: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + pnlResult.SelectNextPage(); + } + break; + + case Key.PageDown: + pnlResult.SelectNextPage(); + e.Handled = true; + break; + + case Key.U: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + pnlResult.SelectPrevPage(); + } + break; + + case Key.PageUp: + pnlResult.SelectPrevPage(); + e.Handled = true; + break; + + case Key.Back: + if (BackKeyDownEvent != null) + { + BackKeyDownEvent(new WoxKeyDownEventArgs() + { + Query = tbQuery.Text, + keyEventArgs = e + }); + } + break; + + case Key.F1: + Process.Start("http://doc.getwox.com"); + break; + + case Key.Enter: + Result activeResult = GetActiveResult(); + if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) + { + ShowContextMenuFromResult(activeResult); + } + else + { + SelectResult(activeResult); + } + e.Handled = true; + break; + + case Key.D1: + SelectItem(1); + break; + + case Key.D2: + SelectItem(2); + break; + + case Key.D3: + SelectItem(3); + break; + + case Key.D4: + SelectItem(4); + break; + + case Key.D5: + SelectItem(5); + break; + case Key.D6: + SelectItem(6); + break; + + } + } + + private void SelectItem(int index) + { + int zeroBasedIndex = index - 1; + SpecialKeyState keyState = GlobalHotkey.Instance.CheckModifiers(); + if (keyState.AltPressed || keyState.CtrlPressed) + { + List visibleResults = pnlResult.GetVisibleResults(); + if (zeroBasedIndex < visibleResults.Count) + { + SelectResult(visibleResults[zeroBasedIndex]); + } + } + } + + private bool IsInContextMenuMode + { + get { return pnlContextMenu.Visibility == Visibility.Visible; } + } + + private Result GetActiveResult() + { + if (IsInContextMenuMode) + { + return pnlContextMenu.GetActiveResult(); + } + else + { + return pnlResult.GetActiveResult(); + } + } + + private void SelectPrevItem() + { + if (IsInContextMenuMode) + { + pnlContextMenu.SelectPrev(); + } + else + { + pnlResult.SelectPrev(); + } + toolTip.IsOpen = false; + } + + private void SelectNextItem() + { + if (IsInContextMenuMode) + { + pnlContextMenu.SelectNext(); + } + else + { + pnlResult.SelectNext(); + } + toolTip.IsOpen = false; + } + + private void SelectResult(Result result) + { + if (result != null) + { + if (result.Action != null) + { + bool hideWindow = result.Action(new ActionContext() + { + SpecialKeyState = GlobalHotkey.Instance.CheckModifiers() + }); + if (hideWindow) + { + HideWox(); + } + UserSelectedRecordStorage.Instance.Add(result); + } + } + } + + private void UpdateResultView(List list) + { + queryHasReturn = true; + progressBar.Dispatcher.Invoke(new Action(StopProgress)); + if (list == null || list.Count == 0) return; + + if (list.Count > 0) + { + list.ForEach(o => + { + o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; + if (o.ContextMenu == null) + { + o.ContextMenu = new List(); + } + HanleTopMost(o); + }); + List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); + Dispatcher.Invoke(new Action(() => + { + pnlResult.AddResults(l); + })); + } + } + + private void HanleTopMost(Result result) + { + if (TopMostRecordStorage.Instance.IsTopMost(result)) + { + result.ContextMenu.Add(new Result("Remove top most in this query", "Images\\down.png") + { + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ => + { + TopMostRecordStorage.Instance.Remove(result); + ShowMsg("Succeed", "", ""); + return false; + } + }); + } + else + { + result.ContextMenu.Add(new Result("Set as top most in this query", "Images\\up.png") + { + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ => + { + TopMostRecordStorage.Instance.Add(result); + ShowMsg("Succeed", "", ""); + return false; + } + }); + } + } + + private void ShowContextMenuFromResult(Result result) + { + if (result.ContextMenu != null && result.ContextMenu.Count > 0) + { + pnlContextMenu.Clear(); + pnlContextMenu.AddResults(result.ContextMenu); + pnlContextMenu.Visibility = Visibility.Visible; + pnlResult.Visibility = Visibility.Collapsed; + } + } + + public bool ShellRun(string cmd, bool runAsAdministrator = false) + { + try + { + if (string.IsNullOrEmpty(cmd)) + throw new ArgumentNullException(); + + WindowsShellRun.Start(cmd, runAsAdministrator); + return true; + } + catch (Exception ex) + { + string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("couldnotStartCmd"), cmd); + ShowMsg(errorMsg, ex.Message, null); + } + return false; + } + + private void MainWindow_OnDrop(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + // Note that you can have more than one file. + string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); + if (files[0].ToLower().EndsWith(".wox")) + { + PluginManager.InstallPlugin(files[0]); + } + else + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("invalidWoxPluginFileFormat")); + } + } + } + + private void TbQuery_OnPreviewDragOver(object sender, DragEventArgs e) + { + e.Handled = true; + } + } +} \ No newline at end of file diff --git a/Wox/su54u2mz.xrz b/Wox/su54u2mz.xrz new file mode 100644 index 000000000..b83197e8f --- /dev/null +++ b/Wox/su54u2mz.xrz @@ -0,0 +1,850 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Threading; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Forms; +using System.Windows.Input; +using System.Windows.Media.Animation; +using NHotkey; +using NHotkey.Wpf; +using Wox.Core.i18n; +using Wox.Core.Plugin; +using Wox.Core.Theme; +using Wox.Core.Updater; +using Wox.Core.UserSettings; +using Wox.Helper; +using Wox.Infrastructure; +using Wox.Infrastructure.Hotkey; +using Wox.Plugin; +using Wox.Storage; +using ContextMenu = System.Windows.Forms.ContextMenu; +using DataFormats = System.Windows.DataFormats; +using DragEventArgs = System.Windows.DragEventArgs; +using IDataObject = System.Windows.IDataObject; +using KeyEventArgs = System.Windows.Input.KeyEventArgs; +using MenuItem = System.Windows.Forms.MenuItem; +using MessageBox = System.Windows.MessageBox; +using ToolTip = System.Windows.Controls.ToolTip; + +namespace Wox +{ + public partial class MainWindow : IPublicAPI + { + + #region Properties + + private readonly Storyboard progressBarStoryboard = new Storyboard(); + private NotifyIcon notifyIcon; + private bool queryHasReturn; + private string lastQuery; + private ToolTip toolTip = new ToolTip(); + + private bool ignoreTextChange = false; + + #endregion + + #region Public API + + public void ChangeQuery(string query, bool requery = false) + { + Dispatcher.Invoke(new Action(() => + { + tbQuery.Text = query; + tbQuery.CaretIndex = tbQuery.Text.Length; + if (requery) + { + TextBoxBase_OnTextChanged(null, null); + } + })); + } + + public void CloseApp() + { + Dispatcher.Invoke(new Action(() => + { + notifyIcon.Visible = false; + Close(); + Environment.Exit(0); + })); + } + + public void HideApp() + { + Dispatcher.Invoke(new Action(HideWox)); + } + + public void ShowApp() + { + Dispatcher.Invoke(new Action(() => ShowWox())); + } + + public void ShowMsg(string title, string subTitle, string iconPath) + { + Dispatcher.Invoke(new Action(() => + { + var m = new Msg { Owner = GetWindow(this) }; + m.Show(title, subTitle, iconPath); + })); + } + + public void OpenSettingDialog() + { + Dispatcher.Invoke(new Action(() => WindowOpener.Open(this))); + } + + public void StartLoadingBar() + { + Dispatcher.Invoke(new Action(StartProgress)); + } + + public void StopLoadingBar() + { + Dispatcher.Invoke(new Action(StopProgress)); + } + + public void InstallPlugin(string path) + { + Dispatcher.Invoke(new Action(() => PluginManager.InstallPlugin(path))); + } + + public void ReloadPlugins() + { + Dispatcher.Invoke(new Action(() => PluginManager.Init(this))); + } + + public string GetTranslation(string key) + { + return InternationalizationManager.Instance.GetTranslation(key); + } + + public List GetAllPlugins() + { + return PluginManager.AllPlugins; + } + + public event WoxKeyDownEventHandler BackKeyDownEvent; + public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; + public event AfterWoxQueryEventHandler AfterWoxQueryEvent; + public event AfterWoxQueryEventHandler BeforeWoxQueryEvent; + public event ResultItemDropEventHandler ResultItemDropEvent; + + public void PushResults(Query query, PluginMetadata plugin, List results) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + o.OriginQuery = query; + if (o.ContextMenu != null) + { + o.ContextMenu.ForEach(t => + { + t.PluginDirectory = plugin.PluginDirectory; + t.PluginID = plugin.ID; + }); + } + }); + UpdateResultView(results); + } + + public void ShowContextMenu(PluginMetadata plugin, List results) + { + if (results != null && results.Count > 0) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + o.ContextMenu = null; + }); + pnlContextMenu.Clear(); + pnlContextMenu.AddResults(results); + pnlContextMenu.Visibility = Visibility.Visible; + pnlResult.Visibility = Visibility.Collapsed; + } + } + + #endregion + + public MainWindow() + { + InitializeComponent(); + ThreadPool.SetMaxThreads(30, 10); + ThreadPool.SetMinThreads(10, 5); + + WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); + GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback; + progressBar.ToolTip = toolTip; + InitialTray(); + pnlResult.LeftMouseClickEvent += SelectResult; + pnlResult.ItemDropEvent += pnlResult_ItemDropEvent; + pnlContextMenu.LeftMouseClickEvent += SelectResult; + pnlResult.RightMouseClickEvent += pnlResult_RightMouseClickEvent; + + ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + InternationalizationManager.Instance.ChangeLanguage(UserSettingStorage.Instance.Language); + + SetHotkey(UserSettingStorage.Instance.Hotkey, OnHotkey); + SetCustomPluginHotkey(); + + Closing += MainWindow_Closing; + //since MainWIndow implement IPublicAPI, so we need to finish ctor MainWindow object before + //PublicAPI invoke in plugin init methods. E.g FolderPlugin + ThreadPool.QueueUserWorkItem(o => + { + Thread.Sleep(50); + PluginManager.Init(this); + }); + ThreadPool.QueueUserWorkItem(o => + { + Thread.Sleep(50); + PreLoadImages(); + }); + } + + void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject, DragEventArgs args) + { + PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); + if (ResultItemDropEvent != null && pluginPair != null) + { + foreach (var delegateHandler in ResultItemDropEvent.GetInvocationList()) + { + if (delegateHandler.Target == pluginPair.Plugin) + { + delegateHandler.DynamicInvoke(result, dropDataObject, args); + } + } + } + } + + private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) + { + if (GlobalKeyboardEvent != null) + { + return GlobalKeyboardEvent((int)keyevent, vkcode, state); + } + return true; + } + + private void PreLoadImages() + { + ImageLoader.ImageLoader.PreloadImages(); + } + + void pnlResult_RightMouseClickEvent(Result result) + { + ShowContextMenuFromResult(result); + } + + void MainWindow_Closing(object sender, CancelEventArgs e) + { + UserSettingStorage.Instance.WindowLeft = Left; + UserSettingStorage.Instance.WindowTop = Top; + UserSettingStorage.Instance.Save(); + this.HideWox(); + e.Cancel = true; + } + + private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) + { + if (UserSettingStorage.Instance.WindowLeft == 0 + && UserSettingStorage.Instance.WindowTop == 0) + { + Left = UserSettingStorage.Instance.WindowLeft + = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; + Top = UserSettingStorage.Instance.WindowTop + = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 5; + } + else + { + Left = UserSettingStorage.Instance.WindowLeft; + Top = UserSettingStorage.Instance.WindowTop; + } + + InitProgressbarAnimation(); + WindowIntelopHelper.DisableControlBox(this); + CheckUpdate(); + } + + private void CheckUpdate() + { + UpdaterManager.Instance.PrepareUpdateReady += OnPrepareUpdateReady; + UpdaterManager.Instance.UpdateError += OnUpdateError; + UpdaterManager.Instance.CheckUpdate(); + } + + void OnUpdateError(object sender, EventArgs e) + { + string updateError = InternationalizationManager.Instance.GetTranslation("update_wox_update_error"); + MessageBox.Show(updateError); + } + + private void OnPrepareUpdateReady(object sender, EventArgs e) + { + Dispatcher.Invoke(new Action(() => + { + new WoxUpdate().ShowDialog(); + })); + } + + public void SetHotkey(string hotkeyStr, EventHandler action) + { + var hotkey = new HotkeyModel(hotkeyStr); + try + { + HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action); + } + catch (Exception) + { + string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr); + MessageBox.Show(errorMsg); + } + } + + public void RemoveHotkey(string hotkeyStr) + { + if (!string.IsNullOrEmpty(hotkeyStr)) + { + HotkeyManager.Current.Remove(hotkeyStr); + } + } + + private void SetCustomPluginHotkey() + { + if (UserSettingStorage.Instance.CustomPluginHotkeys == null) return; + foreach (CustomPluginHotkey hotkey in UserSettingStorage.Instance.CustomPluginHotkeys) + { + CustomPluginHotkey hotkey1 = hotkey; + SetHotkey(hotkey.Hotkey, delegate + { + ShowApp(); + ChangeQuery(hotkey1.ActionKeyword, true); + }); + } + } + + private void OnHotkey(object sender, HotkeyEventArgs e) + { + ToggleWox(); + e.Handled = true; + } + + public void ToggleWox() + { + if (!IsVisible) + { + ShowWox(); + } + else + { + HideWox(); + } + } + + private void InitProgressbarAnimation() + { + var da = new DoubleAnimation(progressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + var da1 = new DoubleAnimation(progressBar.X1, ActualWidth, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); + Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); + progressBarStoryboard.Children.Add(da); + progressBarStoryboard.Children.Add(da1); + progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever; + progressBar.Visibility = Visibility.Hidden; + progressBar.BeginStoryboard(progressBarStoryboard); + } + + private void InitialTray() + { + notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; + notifyIcon.Click += (o, e) => ShowWox(); + var open = new MenuItem("Open"); + open.Click += (o, e) => ShowWox(); + var setting = new MenuItem("Settings"); + setting.Click += (o, e) => OpenSettingDialog(); + var exit = new MenuItem("Exit"); + exit.Click += (o, e) => CloseApp(); + MenuItem[] childen = { open, setting, exit }; + notifyIcon.ContextMenu = new ContextMenu(childen); + } + + private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) + { + if (ignoreTextChange) { ignoreTextChange = false; return; } + + lastQuery = tbQuery.Text; + toolTip.IsOpen = false; + pnlResult.Dirty = true; + int searchDelay = GetSearchDelay(lastQuery); + + Dispatcher.DelayInvoke("UpdateSearch", + o => + { + Dispatcher.DelayInvoke("ClearResults", i => + { + // first try to use clear method inside pnlResult, which is more closer to the add new results + // and this will not bring splash issues.After waiting 100ms, if there still no results added, we + // must clear the result. otherwise, it will be confused why the query changed, but the results + // didn't. + if (pnlResult.Dirty) pnlResult.Clear(); + }, TimeSpan.FromMilliseconds(100), null); + queryHasReturn = false; + Query query = new Query(lastQuery); + query.IsIntantQuery = searchDelay == 0; + FireBeforeWoxQueryEvent(query); + Query(query); + Dispatcher.DelayInvoke("ShowProgressbar", originQuery => + { + if (!queryHasReturn && originQuery == tbQuery.Text && !string.IsNullOrEmpty(lastQuery)) + { + StartProgress(); + } + }, TimeSpan.FromMilliseconds(150), tbQuery.Text); + FireAfterWoxQueryEvent(query); + }, TimeSpan.FromMilliseconds(searchDelay)); + } + + private int GetSearchDelay(string query) + { + if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantQuery(query)) + { + DebugHelper.WriteLine("execute query without delay"); + return 0; + } + + DebugHelper.WriteLine("execute query with 200ms delay"); + return 200; + } + + private void FireAfterWoxQueryEvent(Query q) + { + if (AfterWoxQueryEvent != null) + { + //We shouldn't let those events slow down real query + //so I put it in the new thread + ThreadPool.QueueUserWorkItem(o => + { + AfterWoxQueryEvent(new WoxQueryEventArgs() + { + Query = q + }); + }); + } + } + + private void FireBeforeWoxQueryEvent(Query q) + { + if (BeforeWoxQueryEvent != null) + { + //We shouldn't let those events slow down real query + //so I put it in the new thread + ThreadPool.QueueUserWorkItem(o => + { + BeforeWoxQueryEvent(new WoxQueryEventArgs() + { + Query = q + }); + }); + } + } + + private void Query(Query q) + { + PluginManager.Query(q); + StopProgress(); + BackToResultMode(); + } + + private void BackToResultMode() + { + pnlResult.Visibility = Visibility.Visible; + pnlContextMenu.Visibility = Visibility.Collapsed; + } + + private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left) DragMove(); + } + + private void StartProgress() + { + progressBar.Visibility = Visibility.Visible; + } + + private void StopProgress() + { + progressBar.Visibility = Visibility.Hidden; + } + + private void HideWox() + { + Hide(); + } + + private void ShowWox(bool selectAll = true) + { + UserSettingStorage.Instance.IncreaseActivateTimes(); + if (!double.IsNaN(Left) && !double.IsNaN(Top)) + { + var origScreen = Screen.FromRectangle(new Rectangle((int)Left, (int)Top, (int)ActualWidth, (int)ActualHeight)); + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var coordX = (Left - origScreen.WorkingArea.Left) / (origScreen.WorkingArea.Width - ActualWidth); + var coordY = (Top - origScreen.WorkingArea.Top) / (origScreen.WorkingArea.Height - ActualHeight); + Left = (screen.WorkingArea.Width - ActualWidth) * coordX + screen.WorkingArea.Left; + Top = (screen.WorkingArea.Height - ActualHeight) * coordY + screen.WorkingArea.Top; + } + + Show(); + Activate(); + Focus(); + tbQuery.Focus(); + if (selectAll) tbQuery.SelectAll(); + } + + private void MainWindow_OnDeactivated(object sender, EventArgs e) + { + if (UserSettingStorage.Instance.HideWhenDeactive) + { + HideWox(); + } + } + + private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) + { + //when alt is pressed, the real key should be e.SystemKey + Key key = (e.Key == Key.System ? e.SystemKey : e.Key); + switch (key) + { + case Key.Escape: + if (IsInContextMenuMode) + { + BackToResultMode(); + } + else + { + HideWox(); + } + e.Handled = true; + break; + + case Key.Tab: + if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) + { + SelectPrevItem(); + } + else + { + SelectNextItem(); + } + e.Handled = true; + break; + + case Key.N: + case Key.J: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + SelectNextItem(); + } + break; + + case Key.P: + case Key.K: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + SelectPrevItem(); + } + break; + + case Key.O: + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + if (IsInContextMenuMode) + { + BackToResultMode(); + } + else + { + ShowContextMenuFromResult(GetActiveResult()); + } + } + break; + + case Key.Down: + SelectNextItem(); + e.Handled = true; + break; + + case Key.Up: + SelectPrevItem(); + e.Handled = true; + break; + + case Key.D: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + pnlResult.SelectNextPage(); + } + break; + + case Key.PageDown: + pnlResult.SelectNextPage(); + e.Handled = true; + break; + + case Key.U: + if (GlobalHotkey.Instance.CheckModifiers().AltPressed) + { + pnlResult.SelectPrevPage(); + } + break; + + case Key.PageUp: + pnlResult.SelectPrevPage(); + e.Handled = true; + break; + + case Key.Back: + if (BackKeyDownEvent != null) + { + BackKeyDownEvent(new WoxKeyDownEventArgs() + { + Query = tbQuery.Text, + keyEventArgs = e + }); + } + break; + + case Key.F1: + Process.Start("http://doc.getwox.com"); + break; + + case Key.Enter: + Result activeResult = GetActiveResult(); + if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) + { + ShowContextMenuFromResult(activeResult); + } + else + { + SelectResult(activeResult); + } + e.Handled = true; + break; + + case Key.D1: + SelectItem(1); + break; + + case Key.D2: + SelectItem(2); + break; + + case Key.D3: + SelectItem(3); + break; + + case Key.D4: + SelectItem(4); + break; + + case Key.D5: + SelectItem(5); + break; + case Key.D6: + SelectItem(6); + break; + + } + } + + private void SelectItem(int index) + { + int zeroBasedIndex = index - 1; + SpecialKeyState keyState = GlobalHotkey.Instance.CheckModifiers(); + if (keyState.AltPressed || keyState.CtrlPressed) + { + List visibleResults = pnlResult.GetVisibleResults(); + if (zeroBasedIndex < visibleResults.Count) + { + SelectResult(visibleResults[zeroBasedIndex]); + } + } + } + + private bool IsInContextMenuMode + { + get { return pnlContextMenu.Visibility == Visibility.Visible; } + } + + private Result GetActiveResult() + { + if (IsInContextMenuMode) + { + return pnlContextMenu.GetActiveResult(); + } + else + { + return pnlResult.GetActiveResult(); + } + } + + private void SelectPrevItem() + { + if (IsInContextMenuMode) + { + pnlContextMenu.SelectPrev(); + } + else + { + pnlResult.SelectPrev(); + } + toolTip.IsOpen = false; + } + + private void SelectNextItem() + { + if (IsInContextMenuMode) + { + pnlContextMenu.SelectNext(); + } + else + { + pnlResult.SelectNext(); + } + toolTip.IsOpen = false; + } + + private void SelectResult(Result result) + { + if (result != null) + { + if (result.Action != null) + { + bool hideWindow = result.Action(new ActionContext() + { + SpecialKeyState = GlobalHotkey.Instance.CheckModifiers() + }); + if (hideWindow) + { + HideWox(); + } + UserSelectedRecordStorage.Instance.Add(result); + } + } + } + + private void UpdateResultView(List list) + { + queryHasReturn = true; + progressBar.Dispatcher.Invoke(new Action(StopProgress)); + if (list == null || list.Count == 0) return; + + if (list.Count > 0) + { + list.ForEach(o => + { + o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; + if (o.ContextMenu == null) + { + o.ContextMenu = new List(); + } + HanleTopMost(o); + }); + List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); + Dispatcher.Invoke(new Action(() => + { + pnlResult.AddResults(l); + })); + } + } + + private void HanleTopMost(Result result) + { + if (TopMostRecordStorage.Instance.IsTopMost(result)) + { + result.ContextMenu.Add(new Result("Remove top most in this query", "Images\\down.png") + { + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ => + { + TopMostRecordStorage.Instance.Remove(result); + ShowMsg("Succeed", "", ""); + return false; + } + }); + } + else + { + result.ContextMenu.Add(new Result("Set as top most in this query", "Images\\up.png") + { + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ => + { + TopMostRecordStorage.Instance.Add(result); + ShowMsg("Succeed", "", ""); + return false; + } + }); + } + } + + private void ShowContextMenuFromResult(Result result) + { + if (result.ContextMenu != null && result.ContextMenu.Count > 0) + { + pnlContextMenu.Clear(); + pnlContextMenu.AddResults(result.ContextMenu); + pnlContextMenu.Visibility = Visibility.Visible; + pnlResult.Visibility = Visibility.Collapsed; + } + } + + public bool ShellRun(string cmd, bool runAsAdministrator = false) + { + try + { + if (string.IsNullOrEmpty(cmd)) + throw new ArgumentNullException(); + + WindowsShellRun.Start(cmd, runAsAdministrator); + return true; + } + catch (Exception ex) + { + string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("couldnotStartCmd"), cmd); + ShowMsg(errorMsg, ex.Message, null); + } + return false; + } + + private void MainWindow_OnDrop(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + // Note that you can have more than one file. + string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); + if (files[0].ToLower().EndsWith(".wox")) + { + PluginManager.InstallPlugin(files[0]); + } + else + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("invalidWoxPluginFileFormat")); + } + } + } + + private void TbQuery_OnPreviewDragOver(object sender, DragEventArgs e) + { + e.Handled = true; + } + } +} \ No newline at end of file From 437c1a154caa857fd12f1d7cccdd3ffa5db2fd5b Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sat, 7 Feb 2015 20:17:49 +0800 Subject: [PATCH 12/26] Add plugin title translations --- Plugins/Wox.Plugin.CMD/CMD.cs | 10 +++ Plugins/Wox.Plugin.CMD/Languages/en.xaml | 2 + Plugins/Wox.Plugin.CMD/Languages/zh-cn.xaml | 16 ++-- Plugins/Wox.Plugin.CMD/Languages/zh-tw.xaml | 16 ++-- .../Wox.Plugin.Everything/Languages/en.xaml | 3 + .../Languages/zh-cn.xaml | 3 + .../Languages/zh-tw.xaml | 2 + Plugins/Wox.Plugin.Everything/Main.cs | 10 +++ .../Wox.Plugin.Everything.csproj | 1 + Plugins/Wox.Plugin.Folder/FolderPlugin.cs | 10 +++ Plugins/Wox.Plugin.Folder/Languages/en.xaml | 5 +- .../Wox.Plugin.Folder/Languages/zh-cn.xaml | 25 +++--- .../Wox.Plugin.Folder/Languages/zh-tw.xaml | 25 +++--- Plugins/Wox.Plugin.Folder/plugin.json | 2 +- Plugins/Wox.Plugin.Program/Languages/en.xaml | 5 +- .../Wox.Plugin.Program/Languages/zh-cn.xaml | 3 + .../Wox.Plugin.Program/Languages/zh-tw.xaml | 3 + Plugins/Wox.Plugin.Program/Programs.cs | 9 +++ Plugins/Wox.Plugin.Program/plugin.json | 2 +- Plugins/Wox.Plugin.Sys/Languages/en.xaml | 5 +- Plugins/Wox.Plugin.Sys/Languages/zh-cn.xaml | 31 ++++---- Plugins/Wox.Plugin.Sys/Languages/zh-tw.xaml | 31 ++++---- Plugins/Wox.Plugin.Sys/Sys.cs | 15 +++- Plugins/Wox.Plugin.Url/Images/url.png | Bin 3174 -> 3831 bytes Plugins/Wox.Plugin.Url/Languages/en.xaml | 11 +++ Plugins/Wox.Plugin.Url/Languages/zh-cn.xaml | 11 +++ Plugins/Wox.Plugin.Url/Languages/zh-tw.xaml | 11 +++ Plugins/Wox.Plugin.Url/UrlPlugin.cs | 26 ++++++- Plugins/Wox.Plugin.Url/Wox.Plugin.Url.csproj | 21 ++++++ Plugins/Wox.Plugin.Url/plugin.json | 4 +- .../Wox.Plugin.WebSearch/Languages/en.xaml | 5 +- .../Wox.Plugin.WebSearch/Languages/zh-cn.xaml | 57 +++++++------- .../Wox.Plugin.WebSearch/Languages/zh-tw.xaml | 57 +++++++------- .../Wox.Plugin.WebSearch/WebQueryPlugin.cs | 10 +++ Plugins/Wox.Plugin.WebSearch/plugin.json | 2 +- Wox.Core/AssemblyHelper.cs | 57 ++++++++++++++ Wox.Core/Plugin/PluginManager.cs | 71 ++---------------- Wox.Core/UI/ResourceMerger.cs | 28 +++---- Wox.Core/Wox.Core.csproj | 1 + Wox.Core/i18n/Internationalization.cs | 32 ++++++++ Wox.Plugin/IPluginI18n.cs | 6 +- Wox/MainWindow.xaml.cs | 2 +- Wox/Storage/TopMostRecordStorage.cs | 5 +- 43 files changed, 433 insertions(+), 218 deletions(-) create mode 100644 Plugins/Wox.Plugin.Url/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.Url/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.Url/Languages/zh-tw.xaml create mode 100644 Wox.Core/AssemblyHelper.cs diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index da5877c67..f2ed269ee 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -213,6 +213,16 @@ namespace Wox.Plugin.CMD return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_cmd_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_cmd_plugin_description"); + } + public bool IsInstantQuery(string query) { if (query.StartsWith(">")) return true; diff --git a/Plugins/Wox.Plugin.CMD/Languages/en.xaml b/Plugins/Wox.Plugin.CMD/Languages/en.xaml index 309a4867d..a37ee02a9 100644 --- a/Plugins/Wox.Plugin.CMD/Languages/en.xaml +++ b/Plugins/Wox.Plugin.CMD/Languages/en.xaml @@ -4,5 +4,7 @@ Replace Win+R Do not close Command Prompt after command execution + Shell + Provide executing commands from Wox. Commands should start with > \ No newline at end of file diff --git a/Plugins/Wox.Plugin.CMD/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.CMD/Languages/zh-cn.xaml index 0847dda6c..9693f5f3c 100644 --- a/Plugins/Wox.Plugin.CMD/Languages/zh-cn.xaml +++ b/Plugins/Wox.Plugin.CMD/Languages/zh-cn.xaml @@ -1,8 +1,10 @@ - - - 替换 Win+R - 执行后不关闭命令窗口 - + + + 替换 Win+R + 执行后不关闭命令窗口 + 命令行 + 提供从Wox中执行命令行的能力,命令应该以>开头 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.CMD/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.CMD/Languages/zh-tw.xaml index 8ac28c363..7d318ff0b 100644 --- a/Plugins/Wox.Plugin.CMD/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.CMD/Languages/zh-tw.xaml @@ -1,8 +1,10 @@ - - - 替換 Win+R - 執行後不關閉命令窗口 - + + + 替換 Win+R + 執行後不關閉命令窗口 + 命令行 + 提供從Wox中執行命令行的能力,命令應該以>開頭 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Languages/en.xaml b/Plugins/Wox.Plugin.Everything/Languages/en.xaml index 18c583ae0..abb592bb7 100644 --- a/Plugins/Wox.Plugin.Everything/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Everything/Languages/en.xaml @@ -7,5 +7,8 @@ Copied Can't start {0} Open containing folder + + Everything + Search disk files using Everything \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml index 50d3f189c..d9f3dd709 100644 --- a/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml +++ b/Plugins/Wox.Plugin.Everything/Languages/zh-cn.xaml @@ -8,4 +8,7 @@ 不能启动 {0} 打开所属文件夹 + Everything + 利用Everything搜索磁盘文件 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml index c61e4ffec..46aac0db9 100644 --- a/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.Everything/Languages/zh-tw.xaml @@ -8,4 +8,6 @@ 不能啟動 {0} 打開所屬文件夾 + Everything + 利用Everything搜索磁盤文件 \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs index 86862097c..8e36ec925 100644 --- a/Plugins/Wox.Plugin.Everything/Main.cs +++ b/Plugins/Wox.Plugin.Everything/Main.cs @@ -211,5 +211,15 @@ namespace Wox.Plugin.Everything { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_everything_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_everything_plugin_description"); + } } } diff --git a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj index 6eef11c31..0c677c0d2 100644 --- a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj +++ b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj @@ -41,6 +41,7 @@ ..\..\packages\Newtonsoft.Json.6.0.8\lib\net35\Newtonsoft.Json.dll + diff --git a/Plugins/Wox.Plugin.Folder/FolderPlugin.cs b/Plugins/Wox.Plugin.Folder/FolderPlugin.cs index 7e7c64102..622acac0d 100644 --- a/Plugins/Wox.Plugin.Folder/FolderPlugin.cs +++ b/Plugins/Wox.Plugin.Folder/FolderPlugin.cs @@ -220,5 +220,15 @@ namespace Wox.Plugin.Folder { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_folder_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_folder_plugin_description"); + } } } \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Folder/Languages/en.xaml b/Plugins/Wox.Plugin.Folder/Languages/en.xaml index f9bbd6b3b..cee4e4d80 100644 --- a/Plugins/Wox.Plugin.Folder/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Folder/Languages/en.xaml @@ -8,5 +8,8 @@ Folder Path Please select a folder link Are your sure to delete {0}? - + + Folder + Open favorite folder from wox directorily + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Folder/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Folder/Languages/zh-cn.xaml index 559b9f490..01b435ec4 100644 --- a/Plugins/Wox.Plugin.Folder/Languages/zh-cn.xaml +++ b/Plugins/Wox.Plugin.Folder/Languages/zh-cn.xaml @@ -1,12 +1,15 @@ - - - 删除 - 编辑 - 添加 - 文件夹路径 - 请选择一个文件夹 - 你确定要删除{0}吗? - + + + 删除 + 编辑 + 添加 + 文件夹路径 + 请选择一个文件夹 + 你确定要删除{0}吗? + + 文件夹 + 在Wox中直接打开收藏的文件夹 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Folder/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Folder/Languages/zh-tw.xaml index 27ac71914..c2f6cd8ed 100644 --- a/Plugins/Wox.Plugin.Folder/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.Folder/Languages/zh-tw.xaml @@ -1,12 +1,15 @@ - - - 刪除 - 編輯 - 添加 - 文件夾路徑 - 請選擇一個文件夾 - 你確認要刪除{0}嗎? - + + + 刪除 + 編輯 + 添加 + 文件夾路徑 + 請選擇一個文件夾 + 你確認要刪除{0}嗎? + + 文件夾 + 在Wox中直接打開收藏的文件夾 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Folder/plugin.json b/Plugins/Wox.Plugin.Folder/plugin.json index d9129e4d3..cd08d56e8 100644 --- a/Plugins/Wox.Plugin.Folder/plugin.json +++ b/Plugins/Wox.Plugin.Folder/plugin.json @@ -2,7 +2,7 @@ "ID":"B4D3B69656E14D44865C8D818EAE47C4", "ActionKeyword":"*", "Name":"Folder", - "Description":"Provide opening folder from wox directorily. You can add your favorite folders.", + "Description":"Open favorite folder from wox directorily", "Author":"qianlifeng", "Version":"1.0.0", "Language":"csharp", diff --git a/Plugins/Wox.Plugin.Program/Languages/en.xaml b/Plugins/Wox.Plugin.Program/Languages/en.xaml index c0b194f01..84a3e064f 100644 --- a/Plugins/Wox.Plugin.Program/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Program/Languages/en.xaml @@ -22,5 +22,8 @@ Run As Administrator Open containing folder - + + Program + Search programs in Wox + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml index 288e3ba13..39e5f3b32 100644 --- a/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml +++ b/Plugins/Wox.Plugin.Program/Languages/zh-cn.xaml @@ -24,4 +24,7 @@ 以管理员身份运行 打开所属文件夹 + 程序 + 在Wox中搜索程序 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml index 36b4cb42f..93cf54cb9 100644 --- a/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.Program/Languages/zh-tw.xaml @@ -23,4 +23,7 @@ 以管理員身份運行 打開所屬文件夾 + + 程序 + 在Wox中搜索程序 \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 63280d12a..8ec759941 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -223,5 +223,14 @@ namespace Wox.Plugin.Program { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_program_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_program_plugin_description"); + } } } diff --git a/Plugins/Wox.Plugin.Program/plugin.json b/Plugins/Wox.Plugin.Program/plugin.json index 9185aa7fe..9f374dded 100644 --- a/Plugins/Wox.Plugin.Program/plugin.json +++ b/Plugins/Wox.Plugin.Program/plugin.json @@ -2,7 +2,7 @@ "ID":"791FC278BA414111B8D1886DFE447410", "ActionKeyword":"*", "Name":"Program", - "Description":"Provide programs search for Wox.", + "Description":"Search programs in Wox", "Author":"qianlifeng", "Version":"1.0.0", "Language":"csharp", diff --git a/Plugins/Wox.Plugin.Sys/Languages/en.xaml b/Plugins/Wox.Plugin.Sys/Languages/en.xaml index 280d5ff50..a80f951b7 100644 --- a/Plugins/Wox.Plugin.Sys/Languages/en.xaml +++ b/Plugins/Wox.Plugin.Sys/Languages/en.xaml @@ -11,5 +11,8 @@ Close Wox Restart Wox Tweak this app - + + System Commands + Provide System related commands. e.g. shutdown,lock,setting etc. + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Sys/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Sys/Languages/zh-cn.xaml index 5abec64ce..ef7d49526 100644 --- a/Plugins/Wox.Plugin.Sys/Languages/zh-cn.xaml +++ b/Plugins/Wox.Plugin.Sys/Languages/zh-cn.xaml @@ -1,15 +1,18 @@ - - - 命令 - 描述 - - 关闭电脑 - 注销 - 锁定这台电脑 - 退出Wox - 重启Wox - 设置 - + + + 命令 + 描述 + + 关闭电脑 + 注销 + 锁定这台电脑 + 退出Wox + 重启Wox + 设置 + + 系统命令 + 系统系统相关的命令。例如,关机,锁定,设置等 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Sys/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Sys/Languages/zh-tw.xaml index e393f0d8b..55abdbf43 100644 --- a/Plugins/Wox.Plugin.Sys/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.Sys/Languages/zh-tw.xaml @@ -1,15 +1,18 @@ - - - 命令 - 描述 - - 關閉電腦 - 註銷 - 鎖定這臺電腦 - 退出Wox - 重啟Wox - 設置 - + + + 命令 + 描述 + + 關閉電腦 + 註銷 + 鎖定這臺電腦 + 退出Wox + 重啟Wox + 設置 + + 系統命令 + 系統系統相關的命令。例如,關機,鎖定,設置等 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Sys/Sys.cs b/Plugins/Wox.Plugin.Sys/Sys.cs index 80132b29e..1617772b0 100644 --- a/Plugins/Wox.Plugin.Sys/Sys.cs +++ b/Plugins/Wox.Plugin.Sys/Sys.cs @@ -4,6 +4,7 @@ using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; +using Wox.Infrastructure; namespace Wox.Plugin.Sys { @@ -42,7 +43,7 @@ namespace Wox.Plugin.Sys List results = new List(); foreach (Result availableResult in availableResults) { - if (availableResult.Title.ToLower().StartsWith(query.Search.ToLower())) + if (StringMatcher.IsMatch(availableResult.Title, query.Search) || StringMatcher.IsMatch(availableResult.SubTitle, query.Search)) { results.Add(availableResult); } @@ -142,5 +143,15 @@ namespace Wox.Plugin.Sys return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } - } + + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_sys_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_sys_plugin_description"); + } + } } diff --git a/Plugins/Wox.Plugin.Url/Images/url.png b/Plugins/Wox.Plugin.Url/Images/url.png index 3b86b637dac8432809fd41b685c56685294ec6b1..90634f7a0a30672620dea08857040249efdc6c66 100644 GIT binary patch literal 3831 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 M07*qoM6N<$f&fV!4FCWD diff --git a/Plugins/Wox.Plugin.Url/Languages/en.xaml b/Plugins/Wox.Plugin.Url/Languages/en.xaml new file mode 100644 index 000000000..eec48e692 --- /dev/null +++ b/Plugins/Wox.Plugin.Url/Languages/en.xaml @@ -0,0 +1,11 @@ + + + Open url:{0} + Can't open url:{0} + + URL + Open the typed URL from Wox + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Url/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Url/Languages/zh-cn.xaml new file mode 100644 index 000000000..4cab4182c --- /dev/null +++ b/Plugins/Wox.Plugin.Url/Languages/zh-cn.xaml @@ -0,0 +1,11 @@ + + + 打开链接:{0} + 无法打开链接:{0} + + URL + 从Wox打开链接 + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Url/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Url/Languages/zh-tw.xaml new file mode 100644 index 000000000..e4d45de1d --- /dev/null +++ b/Plugins/Wox.Plugin.Url/Languages/zh-tw.xaml @@ -0,0 +1,11 @@ + + + 打開鏈接:{0} + 無法打開鏈接:{0} + + URL + 從Wox打開鏈接 + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Url/UrlPlugin.cs b/Plugins/Wox.Plugin.Url/UrlPlugin.cs index b769a720b..ae871d2b2 100644 --- a/Plugins/Wox.Plugin.Url/UrlPlugin.cs +++ b/Plugins/Wox.Plugin.Url/UrlPlugin.cs @@ -1,15 +1,17 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; +using System.Reflection; using System.Text.RegularExpressions; using System.Windows; namespace Wox.Plugin.Url { - public class UrlPlugin : IPlugin + public class UrlPlugin : IPlugin, IPluginI18n { //based on https://gist.github.com/dperini/729294 - private const string urlPattern ="^" + + private const string urlPattern = "^" + // protocol identifier "(?:(?:https?|ftp)://|)" + // user:pass authentication @@ -42,6 +44,7 @@ namespace Wox.Plugin.Url "(?:/\\S*)?" + "$"; Regex reg = new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); + private PluginInitContext context; public List Query(Query query) { @@ -53,7 +56,7 @@ namespace Wox.Plugin.Url new Result { Title = raw, - SubTitle = "Open " + raw, + SubTitle = string.Format(context.API.GetTranslation("wox_plugin_url_open_url"),raw), IcoPath = "Images/url.png", Score = 8, Action = _ => @@ -69,7 +72,7 @@ namespace Wox.Plugin.Url } catch(Exception ex) { - MessageBox.Show(ex.Message, "Could not open " + raw); + context.API.ShowMsg(string.Format(context.API.GetTranslation("wox_plugin_url_canot_open_url"), raw)); return false; } } @@ -98,7 +101,22 @@ namespace Wox.Plugin.Url public void Init(PluginInitContext context) { + this.context = context; + } + public string GetLanguagesFolder() + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); + } + + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_url_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_url_plugin_description"); } } } \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Url/Wox.Plugin.Url.csproj b/Plugins/Wox.Plugin.Url/Wox.Plugin.Url.csproj index a35d32f5e..aabcb4525 100644 --- a/Plugins/Wox.Plugin.Url/Wox.Plugin.Url.csproj +++ b/Plugins/Wox.Plugin.Url/Wox.Plugin.Url.csproj @@ -64,6 +64,27 @@ PreserveNewest + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + - 标题 - 启用 - 图标 - 选择图标 - 取消 - 非法的网页搜索 - 请输入标题 - 请输入触发关键字 - 请输入URL - 触发关键字已经存在,请选择一个新的关键字 - 操作成功 - + + + 删除 + 编辑 + 添加 + 触发关键字 + URL + 启用搜索建议 + 请选择一项 + 你确定要删除 {0} 吗? + + + + 标题 + 启用 + 图标 + 选择图标 + 取消 + 非法的网页搜索 + 请输入标题 + 请输入触发关键字 + 请输入URL + 触发关键字已经存在,请选择一个新的关键字 + 操作成功 + + 网页搜索 + 提供网页搜索能力 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.WebSearch/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.WebSearch/Languages/zh-tw.xaml index def9146a8..ec1f620ab 100644 --- a/Plugins/Wox.Plugin.WebSearch/Languages/zh-tw.xaml +++ b/Plugins/Wox.Plugin.WebSearch/Languages/zh-tw.xaml @@ -1,28 +1,31 @@ - - - 刪除 - 編輯 - 添加 - 觸發關鍵字 - URL - 啟用搜索建議 - 請選擇一項 - 你確定要刪除 {0} 嗎? - - - - 標題 - 啟用 - 圖標 - 選擇圖標 - 取消 - 非法的網頁搜索 - 請輸入標題 - 請輸入觸發關鍵字 - 請輸入URL - 觸發關鍵字已經存在,請選擇一個新的關鍵字 - 操作成功 - + + + 刪除 + 編輯 + 添加 + 觸發關鍵字 + URL + 啟用搜索建議 + 請選擇一項 + 你確定要刪除 {0} 嗎? + + + + 標題 + 啟用 + 圖標 + 選擇圖標 + 取消 + 非法的網頁搜索 + 請輸入標題 + 請輸入觸發關鍵字 + 請輸入URL + 觸發關鍵字已經存在,請選擇一個新的關鍵字 + 操作成功 + + 網頁搜索 + 提供網頁搜索能力 + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs b/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs index 10632094a..6399a08f1 100644 --- a/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs +++ b/Plugins/Wox.Plugin.WebSearch/WebQueryPlugin.cs @@ -103,6 +103,16 @@ namespace Wox.Plugin.WebSearch return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); } + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_websearch_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_websearch_plugin_description"); + } + public bool IsInstantQuery(string query) { var strings = query.Split(' '); diff --git a/Plugins/Wox.Plugin.WebSearch/plugin.json b/Plugins/Wox.Plugin.WebSearch/plugin.json index e1bb0fb63..5132ec9e4 100644 --- a/Plugins/Wox.Plugin.WebSearch/plugin.json +++ b/Plugins/Wox.Plugin.WebSearch/plugin.json @@ -2,7 +2,7 @@ "ID":"565B73353DBF4806919830B9202EE3BF", "ActionKeyword":"*", "Name":"Web Searches", - "Description":"Provide the web search ability.", + "Description":"Provide the web search ability", "Author":"qianlifeng", "Version":"1.0.0", "Language":"csharp", diff --git a/Wox.Core/AssemblyHelper.cs b/Wox.Core/AssemblyHelper.cs new file mode 100644 index 000000000..f9c428178 --- /dev/null +++ b/Wox.Core/AssemblyHelper.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Wox.Core.Plugin; +using Wox.Infrastructure.Logger; +using Wox.Plugin; + +namespace Wox.Core +{ + internal class AssemblyHelper + { + public static List> LoadPluginInterfaces() where T : class + { + List CSharpPluginMetadatas = PluginManager.AllPlugins.Select(o => o.Metadata).Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); + List> plugins = new List>(); + foreach (PluginMetadata metadata in CSharpPluginMetadatas) + { + try + { + Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); + List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(T))).ToList(); + if (types.Count == 0) + { + continue; + } + + foreach (Type type in types) + { + plugins.Add(new KeyValuePair(PluginManager.AllPlugins.First(o => o.Metadata.ID == metadata.ID), + Activator.CreateInstance(type) as T)); + } + } + catch (System.Exception e) + { + Log.Error(string.Format("Couldn't load plugin {0}: {1}", metadata.Name, e.Message)); +#if (DEBUG) + { + throw; + } +#endif + } + } + + return plugins; + } + + public static List LoadInterfacesFromAppDomain() where T : class + { + var interfaceObjects = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(s => s.GetTypes()) + .Where(p => p.IsClass && !p.IsAbstract && p.GetInterfaces().Contains(typeof(T))); + + return interfaceObjects.Select(interfaceObject => (T) Activator.CreateInstance(interfaceObject)).ToList(); + } + } +} diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 5e93bb010..ff473061c 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Reflection; using System.Threading; using Wox.Core.Exception; +using Wox.Core.i18n; using Wox.Core.UI; using Wox.Core.UserSettings; using Wox.Infrastructure; @@ -23,7 +24,7 @@ namespace Wox.Core.Plugin { public const string ActionKeywordWildcardSign = "*"; private static List pluginMetadatas; - private static List> instantSearches; + private static List> instantSearches; private static List> exclusiveSearchPlugins; public static String DebuggerMode { get; private set; } @@ -99,6 +100,7 @@ namespace Wox.Core.Plugin sw.Stop(); DebugHelper.WriteLine(string.Format("Plugin init:{0} - {1}", pair.Metadata.Name, sw.ElapsedMilliseconds)); pair.InitTime = sw.ElapsedMilliseconds; + InternationalizationManager.Instance.UpdatePluginMetadataTranslations(pair); }); } @@ -178,7 +180,7 @@ namespace Wox.Core.Plugin { //todo:to improve performance, any instant search plugin that takes long than 200ms will not consider a instant plugin anymore return pluginMetadata.Language.ToUpper() == AllowedLanguage.CSharp && - LoadInstantSearches().Any(o => o.Key.ID == pluginMetadata.ID); + LoadInstantSearches().Any(o => o.Key.Metadata.ID == pluginMetadata.ID); } internal static void ExecutePluginQuery(PluginPair pair, Query query) @@ -211,39 +213,11 @@ namespace Wox.Core.Plugin } } - private static List> LoadInstantSearches() + private static List> LoadInstantSearches() { if (instantSearches != null) return instantSearches; - instantSearches = new List>(); - List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); - - foreach (PluginMetadata metadata in CSharpPluginMetadatas) - { - try - { - Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); - List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IInstantQuery))).ToList(); - if (types.Count == 0) - { - continue; - } - - foreach (Type type in types) - { - instantSearches.Add(new KeyValuePair(metadata, Activator.CreateInstance(type) as IInstantQuery)); - } - } - catch (System.Exception e) - { - Log.Error(string.Format("Couldn't load plugin {0}: {1}", metadata.Name, e.Message)); -#if (DEBUG) - { - throw; - } -#endif - } - } + instantSearches = AssemblyHelper.LoadPluginInterfaces(); return instantSearches; } @@ -261,38 +235,7 @@ namespace Wox.Core.Plugin internal static List> LoadExclusiveSearchPlugins() { if (exclusiveSearchPlugins != null) return exclusiveSearchPlugins; - - exclusiveSearchPlugins = new List>(); - List CSharpPluginMetadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); - - foreach (PluginMetadata metadata in CSharpPluginMetadatas) - { - try - { - Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); - List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IExclusiveQuery))).ToList(); - if (types.Count == 0) - { - continue; - } - - foreach (Type type in types) - { - exclusiveSearchPlugins.Add(new KeyValuePair(AllPlugins.First(o => o.Metadata.ID == metadata.ID), - Activator.CreateInstance(type) as IExclusiveQuery)); - } - } - catch (System.Exception e) - { - Log.Error(string.Format("Couldn't load plugin {0}: {1}", metadata.Name, e.Message)); -#if (DEBUG) - { - throw; - } -#endif - } - } - + exclusiveSearchPlugins = AssemblyHelper.LoadPluginInterfaces(); return exclusiveSearchPlugins; } diff --git a/Wox.Core/UI/ResourceMerger.cs b/Wox.Core/UI/ResourceMerger.cs index 6d7a89298..542200ede 100644 --- a/Wox.Core/UI/ResourceMerger.cs +++ b/Wox.Core/UI/ResourceMerger.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Windows; using Wox.Core.i18n; +using Wox.Core.Plugin; using Wox.Core.Theme; using Wox.Plugin; @@ -9,38 +11,28 @@ namespace Wox.Core.UI { public class ResourceMerger { - public static void ApplyResources() + internal static void ApplyResources() { Application.Current.Resources.MergedDictionaries.Clear(); ApplyPluginLanguages(); ApplyThemeAndLanguageResources(); } - private static void ApplyThemeAndLanguageResources() + internal static void ApplyThemeAndLanguageResources() { - var UIResourceType = typeof(IUIResource); - var UIResources = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(s => s.GetTypes()) - .Where(p => p.IsClass && !p.IsAbstract && UIResourceType.IsAssignableFrom(p)); - + var UIResources = AssemblyHelper.LoadInterfacesFromAppDomain(); foreach (var uiResource in UIResources) { - Application.Current.Resources.MergedDictionaries.Add( - ((IUIResource)Activator.CreateInstance(uiResource)).GetResourceDictionary()); + Application.Current.Resources.MergedDictionaries.Add(uiResource.GetResourceDictionary()); } } - public static void ApplyPluginLanguages() + internal static void ApplyPluginLanguages() { - var pluginI18nType = typeof(IPluginI18n); - var pluginI18ns = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(s => s.GetTypes()) - .Where(p => p.IsClass && !p.IsAbstract && pluginI18nType.IsAssignableFrom(p)); - + var pluginI18ns = AssemblyHelper.LoadInterfacesFromAppDomain(); foreach (var pluginI18n in pluginI18ns) { - string languageFile = InternationalizationManager.Instance.GetLanguageFile( - ((IPluginI18n)Activator.CreateInstance(pluginI18n)).GetLanguagesFolder()); + string languageFile = InternationalizationManager.Instance.GetLanguageFile(pluginI18n.GetLanguagesFolder()); if (!string.IsNullOrEmpty(languageFile)) { Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary @@ -50,5 +42,7 @@ namespace Wox.Core.UI } } } + + } } \ No newline at end of file diff --git a/Wox.Core/Wox.Core.csproj b/Wox.Core/Wox.Core.csproj index 9fc73a2c9..fa06e3840 100644 --- a/Wox.Core/Wox.Core.csproj +++ b/Wox.Core/Wox.Core.csproj @@ -69,6 +69,7 @@ + diff --git a/Wox.Core/i18n/Internationalization.cs b/Wox.Core/i18n/Internationalization.cs index d77232091..25981e89c 100644 --- a/Wox.Core/i18n/Internationalization.cs +++ b/Wox.Core/i18n/Internationalization.cs @@ -9,6 +9,7 @@ using Wox.Core.Exception; using Wox.Core.UI; using Wox.Core.UserSettings; using Wox.Infrastructure.Logger; +using Wox.Plugin; namespace Wox.Core.i18n { @@ -40,6 +41,7 @@ namespace Wox.Core.i18n { Language language = GetLanguageByLanguageCode(languageCode); ChangeLanguage(language); + UpdateAllPluginMetadataTranslations(); } private Language GetLanguageByLanguageCode(string languageCode) @@ -109,6 +111,36 @@ namespace Wox.Core.i18n return GetLanguagePath(language); } + + internal void UpdateAllPluginMetadataTranslations() + { + List> plugins = AssemblyHelper.LoadPluginInterfaces(); + foreach (var plugin in plugins) + { + UpdatePluginMetadataTranslations(plugin.Key); + } + } + + internal void UpdatePluginMetadataTranslations(PluginPair pluginPair) + { + var pluginI18n = pluginPair.Plugin as IPluginI18n; + if (pluginI18n == null) return; + try + { + pluginPair.Metadata.Name = pluginI18n.GetTranslatedPluginTitle(); + pluginPair.Metadata.Description = pluginI18n.GetTranslatedPluginDescription(); + } + catch (System.Exception e) + { + Log.Warn("Update Plugin metadata translation failed:" + e.Message); +#if (DEBUG) + { + throw; + } +#endif + } + } + private string GetLanguagePath(Language language) { string path = Path.Combine(DefaultLanguageDirectory, language.LanguageCode + ".xaml"); diff --git a/Wox.Plugin/IPluginI18n.cs b/Wox.Plugin/IPluginI18n.cs index cb13dd02b..c1068ccab 100644 --- a/Wox.Plugin/IPluginI18n.cs +++ b/Wox.Plugin/IPluginI18n.cs @@ -12,5 +12,9 @@ namespace Wox.Plugin public interface IPluginI18n { string GetLanguagesFolder(); + + string GetTranslatedPluginTitle(); + + string GetTranslatedPluginDescription(); } -} +} \ No newline at end of file diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 482604f4a..d55e678a3 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -831,7 +831,7 @@ namespace Wox PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Action = _ => { - TopMostRecordStorage.Instance.Add(result); + TopMostRecordStorage.Instance.AddOrUpdate(result); ShowMsg("Succeed", "", ""); return false; } diff --git a/Wox/Storage/TopMostRecordStorage.cs b/Wox/Storage/TopMostRecordStorage.cs index 87e8feb86..dc56ed550 100644 --- a/Wox/Storage/TopMostRecordStorage.cs +++ b/Wox/Storage/TopMostRecordStorage.cs @@ -26,7 +26,8 @@ namespace Wox.Storage { return records.Any(o => o.Value.Title == result.Title && o.Value.SubTitle == result.SubTitle - && o.Value.PluginID == result.PluginID); + && o.Value.PluginID == result.PluginID + && o.Key == result.OriginQuery.RawQuery); } internal void Remove(Plugin.Result result) @@ -38,7 +39,7 @@ namespace Wox.Storage } } - internal void Add(Plugin.Result result) + internal void AddOrUpdate(Plugin.Result result) { if (records.ContainsKey(result.OriginQuery.RawQuery)) { From 2d05ecc81fd0a9283e63332e4c53000b677d06e4 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sat, 7 Feb 2015 21:27:48 +0800 Subject: [PATCH 13/26] Add title translations --- Plugins/Wox.Plugin.Caculator/Calculator.cs | 19 +- .../Wox.Plugin.Caculator/Languages/en.xaml | 8 + .../Wox.Plugin.Caculator/Languages/zh-cn.xaml | 8 + .../Wox.Plugin.Caculator/Languages/zh-tw.xaml | 8 + .../Wox.Plugin.Caculator.csproj | 197 ++++---- Plugins/Wox.Plugin.Color/Color.cs | 21 +- Plugins/Wox.Plugin.Color/Languages/en.xaml | 8 + Plugins/Wox.Plugin.Color/Languages/zh-cn.xaml | 8 + Plugins/Wox.Plugin.Color/Languages/zh-tw.xaml | 7 + .../Wox.Plugin.Color/Wox.Plugin.Color.csproj | 22 + .../Wox.Plugin.ControlPanel/ControlPanel.cs | 18 +- .../Wox.Plugin.ControlPanel/Languages/en.xaml | 8 + .../Languages/zh-cn.xaml | 8 + .../Languages/zh-tw.xaml | 8 + .../Wox.Plugin.ControlPanel.csproj | 22 + .../Languages/en.xaml | 8 + .../Languages/zh-cn.xaml | 8 + .../Languages/zh-tw.xaml | 8 + .../PluginIndicator.cs | 19 +- .../Wox.Plugin.PluginIndicator.csproj | 22 + .../Wox.Plugin.PluginIndicator/plugin.json | 2 +- .../Languages/en.xaml | 8 + .../Languages/zh-cn.xaml | 8 + .../Languages/zh-tw.xaml | 8 + Plugins/Wox.Plugin.PluginManagement/Main.cs | 18 +- .../Wox.Plugin.PluginManagement.csproj | 192 +++---- .../Wox.Plugin.PluginManagement/plugin.json | 2 +- Wox/SettingWindow.xaml | 8 +- Wox/SettingWindow.xaml.cs | 468 ++++++++++-------- 29 files changed, 759 insertions(+), 390 deletions(-) create mode 100644 Plugins/Wox.Plugin.Caculator/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.Caculator/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.Caculator/Languages/zh-tw.xaml create mode 100644 Plugins/Wox.Plugin.Color/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.Color/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.Color/Languages/zh-tw.xaml create mode 100644 Plugins/Wox.Plugin.ControlPanel/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.ControlPanel/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.ControlPanel/Languages/zh-tw.xaml create mode 100644 Plugins/Wox.Plugin.PluginIndicator/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.PluginIndicator/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.PluginIndicator/Languages/zh-tw.xaml create mode 100644 Plugins/Wox.Plugin.PluginManagement/Languages/en.xaml create mode 100644 Plugins/Wox.Plugin.PluginManagement/Languages/zh-cn.xaml create mode 100644 Plugins/Wox.Plugin.PluginManagement/Languages/zh-tw.xaml diff --git a/Plugins/Wox.Plugin.Caculator/Calculator.cs b/Plugins/Wox.Plugin.Caculator/Calculator.cs index da5e580a7..0f6acdfcc 100644 --- a/Plugins/Wox.Plugin.Caculator/Calculator.cs +++ b/Plugins/Wox.Plugin.Caculator/Calculator.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; +using System.IO; +using System.Reflection; using System.Text.RegularExpressions; using System.Windows; using YAMP; namespace Wox.Plugin.Caculator { - public class Calculator : IPlugin + public class Calculator : IPlugin, IPluginI18n { private static Regex regValidExpressChar = new Regex( @"^(" + @@ -87,5 +89,20 @@ namespace Wox.Plugin.Caculator { this.context = context; } + + public string GetLanguagesFolder() + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); + } + + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_caculator_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_caculator_plugin_description"); + } } } diff --git a/Plugins/Wox.Plugin.Caculator/Languages/en.xaml b/Plugins/Wox.Plugin.Caculator/Languages/en.xaml new file mode 100644 index 000000000..a286f18f5 --- /dev/null +++ b/Plugins/Wox.Plugin.Caculator/Languages/en.xaml @@ -0,0 +1,8 @@ + + + Calculator + Provide mathematical calculations.(Try 5*3-2 in Wox) + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Caculator/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Caculator/Languages/zh-cn.xaml new file mode 100644 index 000000000..34d3fb24e --- /dev/null +++ b/Plugins/Wox.Plugin.Caculator/Languages/zh-cn.xaml @@ -0,0 +1,8 @@ + + + 计算器 + 为Wox提供数学计算能力。(试着在Wox输入 5*3-2) + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Caculator/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Caculator/Languages/zh-tw.xaml new file mode 100644 index 000000000..a0f1a68e7 --- /dev/null +++ b/Plugins/Wox.Plugin.Caculator/Languages/zh-tw.xaml @@ -0,0 +1,8 @@ + + + 計算器 + 為Wox提供數學計算能力。(試著在Wox輸入 5*3-2) + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Caculator/Wox.Plugin.Caculator.csproj b/Plugins/Wox.Plugin.Caculator/Wox.Plugin.Caculator.csproj index 0a3f8ef91..f56492528 100644 --- a/Plugins/Wox.Plugin.Caculator/Wox.Plugin.Caculator.csproj +++ b/Plugins/Wox.Plugin.Caculator/Wox.Plugin.Caculator.csproj @@ -1,95 +1,116 @@ - - - - - Debug - AnyCPU - {59BD9891-3837-438A-958D-ADC7F91F6F7E} - Library - Properties - Wox.Plugin.Caculator - Wox.Plugin.Caculator - v3.5 - 512 - ..\..\ - true - - - - true - full - false - ..\..\Output\Debug\Plugins\Wox.Plugin.Caculator\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\..\Output\Release\Plugins\Wox.Plugin.Caculator\ - TRACE - prompt - 4 - false - - - - - - - - - - - - False - ..\..\packages\YAMP.1.4.0\lib\net35\YAMP.dll - - - - - - - - - - PreserveNewest - - - - - {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} - Wox.Infrastructure - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - - PreserveNewest - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - - - - + + + + + Debug + AnyCPU + {59BD9891-3837-438A-958D-ADC7F91F6F7E} + Library + Properties + Wox.Plugin.Caculator + Wox.Plugin.Caculator + v3.5 + 512 + ..\..\ + true + + + + true + full + false + ..\..\Output\Debug\Plugins\Wox.Plugin.Caculator\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\..\Output\Release\Plugins\Wox.Plugin.Caculator\ + TRACE + prompt + 4 + false + + + + + + + + + + + + False + ..\..\packages\YAMP.1.4.0\lib\net35\YAMP.dll + + + + + + + + + + PreserveNewest + + + + + {4fd29318-a8ab-4d8f-aa47-60bc241b8da3} + Wox.Infrastructure + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + + + --> \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Color/Color.cs b/Plugins/Wox.Plugin.Color/Color.cs index 36581cca9..2dd5c6d83 100644 --- a/Plugins/Wox.Plugin.Color/Color.cs +++ b/Plugins/Wox.Plugin.Color/Color.cs @@ -4,13 +4,15 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; +using System.Reflection; using System.Windows; namespace Wox.Plugin.Color { - public sealed class ColorsPlugin : IPlugin + public sealed class ColorsPlugin : IPlugin, IPluginI18n { private string DIR_PATH = Path.Combine(Path.GetTempPath(), @"Plugins\Colors\"); + private PluginInitContext context; private const int IMG_SIZE = 32; private DirectoryInfo ColorsDirectory { get; set; } @@ -103,6 +105,23 @@ namespace Wox.Plugin.Color public void Init(PluginInitContext context) { + this.context = context; + } + + + public string GetLanguagesFolder() + { + return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Languages"); + } + + public string GetTranslatedPluginTitle() + { + return context.API.GetTranslation("wox_plugin_color_plugin_name"); + } + + public string GetTranslatedPluginDescription() + { + return context.API.GetTranslation("wox_plugin_color_plugin_description"); } } } \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Color/Languages/en.xaml b/Plugins/Wox.Plugin.Color/Languages/en.xaml new file mode 100644 index 000000000..b87a8ae8d --- /dev/null +++ b/Plugins/Wox.Plugin.Color/Languages/en.xaml @@ -0,0 +1,8 @@ + + + Colors + Provide hex color preview.(Try #000 in Wox) + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Color/Languages/zh-cn.xaml b/Plugins/Wox.Plugin.Color/Languages/zh-cn.xaml new file mode 100644 index 000000000..32aa83ae8 --- /dev/null +++ b/Plugins/Wox.Plugin.Color/Languages/zh-cn.xaml @@ -0,0 +1,8 @@ + + + 颜色 + 提供在Wox查询hex颜色。(尝试在Wox中输入#000) + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Color/Languages/zh-tw.xaml b/Plugins/Wox.Plugin.Color/Languages/zh-tw.xaml new file mode 100644 index 000000000..b76a9521a --- /dev/null +++ b/Plugins/Wox.Plugin.Color/Languages/zh-tw.xaml @@ -0,0 +1,7 @@ + + + 顏色 + 提供在Wox查詢hex顏色。(嘗試在Wox中輸入#000) + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Color/Wox.Plugin.Color.csproj b/Plugins/Wox.Plugin.Color/Wox.Plugin.Color.csproj index 81347e2f1..8a0428fad 100644 --- a/Plugins/Wox.Plugin.Color/Wox.Plugin.Color.csproj +++ b/Plugins/Wox.Plugin.Color/Wox.Plugin.Color.csproj @@ -34,6 +34,7 @@ + @@ -62,6 +63,27 @@ Wox.Plugin + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + + + MSBuild:Compile + Designer + PreserveNewest + + + --> \ No newline at end of file diff --git a/Plugins/Wox.Plugin.PluginManagement/plugin.json b/Plugins/Wox.Plugin.PluginManagement/plugin.json index 173598b66..f07dcf479 100644 --- a/Plugins/Wox.Plugin.PluginManagement/plugin.json +++ b/Plugins/Wox.Plugin.PluginManagement/plugin.json @@ -2,7 +2,7 @@ "ID":"D2D2C23B084D422DB66FE0C79D6C2A6A", "ActionKeyword":"wpm", "Name":"Wox Plugin Management", - "Description":"Manage your plugins in Wox", + "Description":"Install/Remove/Update wox plugins", "Author":"qianlifeng", "Version":"1.0", "Language":"csharp", diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index c44b71cc2..92f9eb8eb 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -19,7 +19,7 @@ - + @@ -37,7 +37,7 @@ - + @@ -113,7 +113,7 @@ - + @@ -210,7 +210,7 @@ - + diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 8a33b19a3..1e8b2190b 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -17,19 +17,25 @@ using Application = System.Windows.Forms.Application; using File = System.IO.File; using MessageBox = System.Windows.MessageBox; using System.Windows.Data; +using System.Windows.Forms; using Microsoft.Win32; using Wox.Core.i18n; using Wox.Core.Theme; using Wox.Core.Updater; using Wox.Core.UserSettings; +using CheckBox = System.Windows.Controls.CheckBox; +using Control = System.Windows.Controls.Control; +using Cursors = System.Windows.Input.Cursors; +using HorizontalAlignment = System.Windows.HorizontalAlignment; namespace Wox { public partial class SettingWindow : Window { - public MainWindow MainWindow; + public readonly MainWindow MainWindow; bool settingsLoaded = false; private Dictionary featureControls = new Dictionary(); + private bool themeTabLoaded = false; public SettingWindow(MainWindow mainWindow) { @@ -74,8 +80,208 @@ namespace Wox #endregion - #region Theme + #region Proxy + cbEnableProxy.Checked += (o, e) => EnableProxy(); + cbEnableProxy.Unchecked += (o, e) => DisableProxy(); + cbEnableProxy.IsChecked = UserSettingStorage.Instance.ProxyEnabled; + tbProxyServer.Text = UserSettingStorage.Instance.ProxyServer; + tbProxyPort.Text = UserSettingStorage.Instance.ProxyPort.ToString(); + tbProxyUserName.Text = UserSettingStorage.Instance.ProxyUserName; + tbProxyPassword.Password = UserSettingStorage.Instance.ProxyPassword; + if (UserSettingStorage.Instance.ProxyEnabled) + { + EnableProxy(); + } + else + { + DisableProxy(); + } + + #endregion + + #region About + + tbVersion.Text = UpdaterManager.Instance.CurrentVersion.ToString(); + string activateTimes = string.Format(InternationalizationManager.Instance.GetTranslation("about_activate_times"), + UserSettingStorage.Instance.ActivateTimes); + tbActivatedTimes.Text = activateTimes; + + #endregion + + settingsLoaded = true; + } + + #region General + + private void LoadLanguages() + { + cbLanguages.ItemsSource = InternationalizationManager.Instance.LoadAvailableLanguages(); + cbLanguages.DisplayMemberPath = "Display"; + cbLanguages.SelectedValuePath = "LanguageCode"; + cbLanguages.SelectedValue = UserSettingStorage.Instance.Language; + cbLanguages.SelectionChanged += cbLanguages_SelectionChanged; + } + + void cbLanguages_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + InternationalizationManager.Instance.ChangeLanguage(cbLanguages.SelectedItem as Language); + } + + private void CbStartWithWindows_OnChecked(object sender, RoutedEventArgs e) + { + AddApplicationToStartup(); + UserSettingStorage.Instance.StartWoxOnSystemStartup = true; + UserSettingStorage.Instance.Save(); + } + + private void CbStartWithWindows_OnUnchecked(object sender, RoutedEventArgs e) + { + RemoveApplicationFromStartup(); + UserSettingStorage.Instance.StartWoxOnSystemStartup = false; + UserSettingStorage.Instance.Save(); + } + + private void AddApplicationToStartup() + { + using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) + { + key.SetValue("Wox", "\"" + Application.ExecutablePath + "\" --hidestart"); + } + } + + private void RemoveApplicationFromStartup() + { + using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) + { + key.DeleteValue("Wox", false); + } + } + + private bool CheckApplicationIsStartupWithWindow() + { + using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) + { + return key.GetValue("Wox") != null; + } + } + + #endregion + + #region Hotkey + + void ctlHotkey_OnHotkeyChanged(object sender, System.EventArgs e) + { + if (ctlHotkey.CurrentHotkeyAvailable) + { + MainWindow.SetHotkey(ctlHotkey.CurrentHotkey.ToString(), delegate + { + if (!MainWindow.IsVisible) + { + MainWindow.ShowApp(); + } + else + { + MainWindow.HideApp(); + } + }); + MainWindow.RemoveHotkey(UserSettingStorage.Instance.Hotkey); + UserSettingStorage.Instance.Hotkey = ctlHotkey.CurrentHotkey.ToString(); + UserSettingStorage.Instance.Save(); + } + } + + + private void TabHotkey_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + var tabItem = sender as TabItem; + var clickingBody = (tabItem.Content as UIElement).IsMouseOver; + if (!clickingBody) + { + OnHotkeyTabSelected(); + } + } + + private void OnHotkeyTabSelected() + { + ctlHotkey.OnHotkeyChanged += ctlHotkey_OnHotkeyChanged; + ctlHotkey.SetHotkey(UserSettingStorage.Instance.Hotkey, false); + lvCustomHotkey.ItemsSource = UserSettingStorage.Instance.CustomPluginHotkeys; + } + + private void BtnDeleteCustomHotkey_OnClick(object sender, RoutedEventArgs e) + { + CustomPluginHotkey item = lvCustomHotkey.SelectedItem as CustomPluginHotkey; + if (item == null) + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); + return; + } + + string deleteWarning = string.Format(InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey); + if (MessageBox.Show(deleteWarning, InternationalizationManager.Instance.GetTranslation("delete"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) + { + UserSettingStorage.Instance.CustomPluginHotkeys.Remove(item); + lvCustomHotkey.Items.Refresh(); + UserSettingStorage.Instance.Save(); + MainWindow.RemoveHotkey(item.Hotkey); + } + } + + private void BtnEditCustomHotkey_OnClick(object sender, RoutedEventArgs e) + { + CustomPluginHotkey item = lvCustomHotkey.SelectedItem as CustomPluginHotkey; + if (item != null) + { + CustomQueryHotkeySetting window = new CustomQueryHotkeySetting(this); + window.UpdateItem(item); + window.ShowDialog(); + } + else + { + MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); + } + } + + private void BtnAddCustomeHotkey_OnClick(object sender, RoutedEventArgs e) + { + new CustomQueryHotkeySetting(this).ShowDialog(); + } + + public void ReloadCustomPluginHotkeyView() + { + lvCustomHotkey.Items.Refresh(); + } + + #endregion + + #region Theme + + private void tbMoreThemes_MouseUp(object sender, MouseButtonEventArgs e) + { + Process.Start("http://www.getwox.com/theme"); + } + + + private void CbOpacityMode_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + UserSettingStorage.Instance.OpacityMode = (OpacityMode)CbOpacityMode.SelectedItem; + UserSettingStorage.Instance.Save(); + + spOpacity.Visibility = UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow ? Visibility.Visible : Visibility.Collapsed; + + if (UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow) + PreviewMainPanel.Opacity = UserSettingStorage.Instance.Opacity; + else + PreviewMainPanel.Opacity = 1; + } + + + private void OnThemeTabSelected() + { + if (themeTabLoaded) return; + + themeTabLoaded = true; if (!string.IsNullOrEmpty(UserSettingStorage.Instance.QueryBoxFont) && Fonts.SystemFontFamilies.Count(o => o.FamilyNames.Values.Contains(UserSettingStorage.Instance.QueryBoxFont)) > 0) { @@ -175,196 +381,18 @@ namespace Wox //PreviewPanel ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); - #endregion + } - #region Plugin - - ctlHotkey.OnHotkeyChanged += ctlHotkey_OnHotkeyChanged; - ctlHotkey.SetHotkey(UserSettingStorage.Instance.Hotkey, false); - lvCustomHotkey.ItemsSource = UserSettingStorage.Instance.CustomPluginHotkeys; - - var plugins = new CompositeCollection + private void TabTheme_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + var tabItem = sender as TabItem; + var clickingBody = (tabItem.Content as UIElement).IsMouseOver; + if (!clickingBody) { - new CollectionContainer - { - Collection = PluginManager.AllPlugins - } - }; - lbPlugins.ItemsSource = plugins; - lbPlugins.SelectedIndex = 0; - - #endregion - - #region Proxy - - cbEnableProxy.Checked += (o, e) => EnableProxy(); - cbEnableProxy.Unchecked += (o, e) => DisableProxy(); - cbEnableProxy.IsChecked = UserSettingStorage.Instance.ProxyEnabled; - tbProxyServer.Text = UserSettingStorage.Instance.ProxyServer; - tbProxyPort.Text = UserSettingStorage.Instance.ProxyPort.ToString(); - tbProxyUserName.Text = UserSettingStorage.Instance.ProxyUserName; - tbProxyPassword.Password = UserSettingStorage.Instance.ProxyPassword; - if (UserSettingStorage.Instance.ProxyEnabled) - { - EnableProxy(); - } - else - { - DisableProxy(); - } - - #endregion - - #region About - - tbVersion.Text = UpdaterManager.Instance.CurrentVersion.ToString(); - string activateTimes = string.Format(InternationalizationManager.Instance.GetTranslation("about_activate_times"), - UserSettingStorage.Instance.ActivateTimes); - tbActivatedTimes.Text = activateTimes; - - #endregion - - settingsLoaded = true; - } - - private void LoadLanguages() - { - cbLanguages.ItemsSource = InternationalizationManager.Instance.LoadAvailableLanguages(); - cbLanguages.DisplayMemberPath = "Display"; - cbLanguages.SelectedValuePath = "LanguageCode"; - cbLanguages.SelectedValue = UserSettingStorage.Instance.Language; - cbLanguages.SelectionChanged += cbLanguages_SelectionChanged; - } - - void cbLanguages_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - InternationalizationManager.Instance.ChangeLanguage(cbLanguages.SelectedItem as Language); - } - - private void EnableProxy() - { - tbProxyPassword.IsEnabled = true; - tbProxyServer.IsEnabled = true; - tbProxyUserName.IsEnabled = true; - tbProxyPort.IsEnabled = true; - } - - private void DisableProxy() - { - tbProxyPassword.IsEnabled = false; - tbProxyServer.IsEnabled = false; - tbProxyUserName.IsEnabled = false; - tbProxyPort.IsEnabled = false; - } - - private void CbStartWithWindows_OnChecked(object sender, RoutedEventArgs e) - { - AddApplicationToStartup(); - UserSettingStorage.Instance.StartWoxOnSystemStartup = true; - UserSettingStorage.Instance.Save(); - } - - private void CbStartWithWindows_OnUnchecked(object sender, RoutedEventArgs e) - { - RemoveApplicationFromStartup(); - UserSettingStorage.Instance.StartWoxOnSystemStartup = false; - UserSettingStorage.Instance.Save(); - } - - private void AddApplicationToStartup() - { - using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) - { - key.SetValue("Wox", "\"" + Application.ExecutablePath + "\" --hidestart"); + OnThemeTabSelected(); } } - private void RemoveApplicationFromStartup() - { - using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) - { - key.DeleteValue("Wox", false); - } - } - - private bool CheckApplicationIsStartupWithWindow() - { - using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true)) - { - return key.GetValue("Wox") != null; - } - } - - void ctlHotkey_OnHotkeyChanged(object sender, System.EventArgs e) - { - if (ctlHotkey.CurrentHotkeyAvailable) - { - MainWindow.SetHotkey(ctlHotkey.CurrentHotkey.ToString(), delegate - { - if (!MainWindow.IsVisible) - { - MainWindow.ShowApp(); - } - else - { - MainWindow.HideApp(); - } - }); - MainWindow.RemoveHotkey(UserSettingStorage.Instance.Hotkey); - UserSettingStorage.Instance.Hotkey = ctlHotkey.CurrentHotkey.ToString(); - UserSettingStorage.Instance.Save(); - } - } - - #region Custom Plugin Hotkey - - private void BtnDeleteCustomHotkey_OnClick(object sender, RoutedEventArgs e) - { - CustomPluginHotkey item = lvCustomHotkey.SelectedItem as CustomPluginHotkey; - if (item == null) - { - MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); - return; - } - - string deleteWarning = string.Format(InternationalizationManager.Instance.GetTranslation("deleteCustomHotkeyWarning"), item.Hotkey); - if (MessageBox.Show(deleteWarning, InternationalizationManager.Instance.GetTranslation("delete"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) - { - UserSettingStorage.Instance.CustomPluginHotkeys.Remove(item); - lvCustomHotkey.Items.Refresh(); - UserSettingStorage.Instance.Save(); - MainWindow.RemoveHotkey(item.Hotkey); - } - } - - private void BtnEditCustomHotkey_OnClick(object sender, RoutedEventArgs e) - { - CustomPluginHotkey item = lvCustomHotkey.SelectedItem as CustomPluginHotkey; - if (item != null) - { - CustomQueryHotkeySetting window = new CustomQueryHotkeySetting(this); - window.UpdateItem(item); - window.ShowDialog(); - } - else - { - MessageBox.Show(InternationalizationManager.Instance.GetTranslation("pleaseSelectAnItem")); - } - } - - private void BtnAddCustomeHotkey_OnClick(object sender, RoutedEventArgs e) - { - new CustomQueryHotkeySetting(this).ShowDialog(); - } - - public void ReloadCustomPluginHotkeyView() - { - lvCustomHotkey.Items.Refresh(); - } - - #endregion - - #region Theme private void ThemeComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { string themeName = themeComboBox.SelectedItem.ToString(); @@ -452,18 +480,8 @@ namespace Wox } #endregion - private void CbOpacityMode_OnSelectionChanged(object sender, SelectionChangedEventArgs e) - { - UserSettingStorage.Instance.OpacityMode = (OpacityMode)CbOpacityMode.SelectedItem; - UserSettingStorage.Instance.Save(); + #region Plugin - spOpacity.Visibility = UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow ? Visibility.Visible : Visibility.Collapsed; - - if (UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow) - PreviewMainPanel.Opacity = UserSettingStorage.Instance.Opacity; - else - PreviewMainPanel.Opacity = 1; - } private void lbPlugins_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { @@ -473,7 +491,6 @@ namespace Wox if (pair != null) { - //third-party plugin provider = pair.Plugin as ISettingProvider; pluginAuthor.Visibility = Visibility.Visible; pluginActionKeyword.Visibility = Visibility.Visible; @@ -491,11 +508,6 @@ namespace Wox pluginId = pair.Metadata.ID; pluginIcon.Source = ImageLoader.ImageLoader.Load(pair.Metadata.FullIcoPath); } - else - { - //system plugin - provider = lbPlugins.SelectedItem as ISettingProvider; - } var customizedPluginConfig = UserSettingStorage.Instance.CustomizedPluginConfigs.FirstOrDefault(o => o.ID == pluginId); cbDisablePlugin.IsChecked = customizedPluginConfig != null && customizedPluginConfig.Disabled; @@ -611,11 +623,33 @@ namespace Wox Process.Start("http://www.getwox.com/plugin"); } - private void tbMoreThemes_MouseUp(object sender, MouseButtonEventArgs e) + private void OnPluginTabSelected() { - Process.Start("http://www.getwox.com/theme"); + var plugins = new CompositeCollection + { + new CollectionContainer + { + Collection = PluginManager.AllPlugins + } + }; + lbPlugins.ItemsSource = plugins; + lbPlugins.SelectedIndex = 0; } + private void TabPlugin_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + var tabItem = sender as TabItem; + var clickingBody = (tabItem.Content as UIElement).IsMouseOver; + if (!clickingBody) + { + OnPluginTabSelected(); + } + } + + + #endregion + + #region Proxy private void btnSaveProxy_Click(object sender, RoutedEventArgs e) { UserSettingStorage.Instance.ProxyEnabled = cbEnableProxy.IsChecked ?? false; @@ -698,9 +732,31 @@ namespace Wox } } + private void EnableProxy() + { + tbProxyPassword.IsEnabled = true; + tbProxyServer.IsEnabled = true; + tbProxyUserName.IsEnabled = true; + tbProxyPort.IsEnabled = true; + } + + private void DisableProxy() + { + tbProxyPassword.IsEnabled = false; + tbProxyServer.IsEnabled = false; + tbProxyUserName.IsEnabled = false; + tbProxyPort.IsEnabled = false; + } + + #endregion + + #region About + private void tbWebsite_MouseUp(object sender, MouseButtonEventArgs e) { Process.Start("http://www.getwox.com"); } + + #endregion } } From c24e216f265c032ee5682b80ea2123cfe3d25f44 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sat, 7 Feb 2015 21:40:25 +0800 Subject: [PATCH 14/26] fix #246 prompt restart wox after uninstall plugin --- Plugins/Wox.Plugin.PluginManagement/Main.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Plugins/Wox.Plugin.PluginManagement/Main.cs b/Plugins/Wox.Plugin.PluginManagement/Main.cs index 250f3df24..a02e44f2c 100644 --- a/Plugins/Wox.Plugin.PluginManagement/Main.cs +++ b/Plugins/Wox.Plugin.PluginManagement/Main.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net; @@ -234,7 +235,19 @@ namespace Wox.Plugin.PluginManagement if (MessageBox.Show(content, "Wox", MessageBoxButtons.YesNo) == DialogResult.Yes) { File.Create(Path.Combine(plugin.PluginDirectory, "NeedDelete.txt")).Close(); - MessageBox.Show("This plugin has been removed, restart Wox to take effect"); + 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) + { + ProcessStartInfo Info = new ProcessStartInfo(); + Info.Arguments = "/C ping 127.0.0.1 -n 1 && \"" + Application.ExecutablePath + "\""; + Info.WindowStyle = ProcessWindowStyle.Hidden; + Info.CreateNoWindow = true; + Info.FileName = "cmd.exe"; + Process.Start(Info); + context.API.CloseApp(); + } } } From bc7dce602609308d6f33552356e2059964b9c0c5 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sat, 7 Feb 2015 23:49:46 +0800 Subject: [PATCH 15/26] Add IContextMenu interface & lazy load context menus --- Plugins/Wox.Plugin.CMD/CMD.cs | 50 +++++++------- Plugins/Wox.Plugin.Everything/Main.cs | 84 ++++++++++++----------- Plugins/Wox.Plugin.Everything/plugin.json | 2 +- Plugins/Wox.Plugin.Program/Programs.cs | 84 +++++++++++++---------- Wox.Core/AssemblyHelper.cs | 35 +++------- Wox.Core/Plugin/PluginManager.cs | 30 ++++++++ Wox.Plugin/Features/IContextMenu.cs | 12 ++++ Wox.Plugin/Result.cs | 1 + Wox.Plugin/Wox.Plugin.csproj | 1 + Wox/MainWindow.xaml.cs | 63 ++++++++--------- 10 files changed, 196 insertions(+), 166 deletions(-) create mode 100644 Wox.Plugin/Features/IContextMenu.cs diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index f2ed269ee..b1e003d35 100644 --- a/Plugins/Wox.Plugin.CMD/CMD.cs +++ b/Plugins/Wox.Plugin.CMD/CMD.cs @@ -14,7 +14,7 @@ using Control = System.Windows.Controls.Control; namespace Wox.Plugin.CMD { - public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery + public class CMD : IPlugin, ISettingProvider, IPluginI18n, IInstantQuery, IExclusiveQuery,IContextMenu { private PluginInitContext context; private bool WinRStroked; @@ -70,8 +70,7 @@ namespace Wox.Plugin.CMD { ExecuteCmd(m); return true; - }, - ContextMenu = GetContextMenus(m) + } })); } } @@ -102,8 +101,7 @@ namespace Wox.Plugin.CMD { ExecuteCmd(m.Key); return true; - }, - ContextMenu = GetContextMenus(m.Key) + } }; return ret; }).Where(o => o != null).Take(4); @@ -122,8 +120,7 @@ namespace Wox.Plugin.CMD { ExecuteCmd(cmd); return true; - }, - ContextMenu = GetContextMenus(cmd) + } }; return result; @@ -141,30 +138,11 @@ namespace Wox.Plugin.CMD { ExecuteCmd(m.Key); return true; - }, - ContextMenu = GetContextMenus(m.Key) + } }).Take(5); return history.ToList(); } - private List GetContextMenus(string cmd) - { - return new List() - { - new Result() - { - Title = "Run As Administrator", - Action = c => - { - context.API.HideApp(); - ExecuteCmd(cmd, true); - return true; - }, - IcoPath = "Images/cmd.png" - } - }; - } - private void ExecuteCmd(string cmd, bool runAsAdministrator = false) { if (context.API.ShellRun(cmd, runAsAdministrator)) @@ -233,5 +211,23 @@ namespace Wox.Plugin.CMD { return query.Search.StartsWith(">"); } + + public List LoadContextMenus(Result selectedResult) + { + return new List() + { + new Result() + { + Title = "Run As Administrator", + Action = c => + { + context.API.HideApp(); + ExecuteCmd(selectedResult.Title, true); + return true; + }, + IcoPath = "Images/cmd.png" + } + }; + } } } \ No newline at end of file diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs index 8e36ec925..17a6b84a1 100644 --- a/Plugins/Wox.Plugin.Everything/Main.cs +++ b/Plugins/Wox.Plugin.Everything/Main.cs @@ -6,10 +6,11 @@ using System.Linq; using Wox.Infrastructure; using System.Reflection; using Wox.Plugin.Everything.Everything; +using Wox.Plugin.Features; namespace Wox.Plugin.Everything { - public class Main : IPlugin, IPluginI18n + public class Main : IPlugin, IPluginI18n,IContextMenu { PluginInitContext context; EverythingAPI api = new EverythingAPI(); @@ -24,7 +25,7 @@ namespace Wox.Plugin.Everything var keyword = query.Search; if (ContextMenuStorage.Instance.MaxSearchCount <= 0) { - ContextMenuStorage.Instance.MaxSearchCount = 100; + ContextMenuStorage.Instance.MaxSearchCount = 50; ContextMenuStorage.Instance.Save(); } @@ -50,7 +51,7 @@ namespace Wox.Plugin.Everything context.API.ShellRun(path); return true; }; - r.ContextMenu = GetContextMenu(s); + r.ContextData = s; results.Add(r); } } @@ -110,43 +111,6 @@ namespace Wox.Plugin.Everything [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern int LoadLibrary(string name); - private List GetContextMenu(SearchResult record) - { - List contextMenus = new List(); - - List availableContextMenus = new List(); - availableContextMenus.AddRange(GetDefaultContextMenu()); - availableContextMenus.AddRange(ContextMenuStorage.Instance.ContextMenus); - - if (record.Type == ResultType.File) - { - foreach (ContextMenu contextMenu in availableContextMenus) - { - contextMenus.Add(new Result() - { - Title = contextMenu.Name, - Action = _ => - { - string argument = contextMenu.Argument.Replace("{path}", record.FullPath); - try - { - Process.Start(contextMenu.Command, argument); - } - catch - { - context.API.ShowMsg(string.Format(context.API.GetTranslation("wox_plugin_everything_canot_start"), record.FullPath), string.Empty, string.Empty); - return false; - } - return true; - }, - IcoPath = contextMenu.ImagePath - }); - } - } - - return contextMenus; - } - private List GetDefaultContextMenu() { List defaultContextMenus = new List(); @@ -221,5 +185,45 @@ namespace Wox.Plugin.Everything { return context.API.GetTranslation("wox_plugin_everything_plugin_description"); } + + public List LoadContextMenus(Result selectedResult) + { + SearchResult record = selectedResult.ContextData as SearchResult; + List contextMenus = new List(); + if(record == null) return contextMenus; + + List availableContextMenus = new List(); + availableContextMenus.AddRange(GetDefaultContextMenu()); + availableContextMenus.AddRange(ContextMenuStorage.Instance.ContextMenus); + + if (record.Type == ResultType.File) + { + foreach (ContextMenu contextMenu in availableContextMenus) + { + var menu = contextMenu; + contextMenus.Add(new Result() + { + Title = contextMenu.Name, + Action = _ => + { + string argument = menu.Argument.Replace("{path}", record.FullPath); + try + { + Process.Start(menu.Command, argument); + } + catch + { + context.API.ShowMsg(string.Format(context.API.GetTranslation("wox_plugin_everything_canot_start"), record.FullPath), string.Empty, string.Empty); + return false; + } + return true; + }, + IcoPath = contextMenu.ImagePath + }); + } + } + + return contextMenus; + } } } diff --git a/Plugins/Wox.Plugin.Everything/plugin.json b/Plugins/Wox.Plugin.Everything/plugin.json index 0f7418f95..8eb78934e 100644 --- a/Plugins/Wox.Plugin.Everything/plugin.json +++ b/Plugins/Wox.Plugin.Everything/plugin.json @@ -1,6 +1,6 @@ { "ID":"D2D2C23B084D411DB66FE0C79D6C2A6E", - "ActionKeyword":"f", + "ActionKeyword":"*", "Name":"Everything", "Description":"Search Everything", "Author":"qianlifeng,orzfly", diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 8ec759941..fad46efa3 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -9,10 +9,11 @@ using System.Windows; using Wox.Infrastructure; using Wox.Plugin.Program.ProgramSources; using IWshRuntimeLibrary; +using Wox.Plugin.Features; namespace Wox.Plugin.Program { - public class Programs : ISettingProvider, IPlugin, IPluginI18n + public class Programs : ISettingProvider, IPlugin, IPluginI18n, IContextMenu { private static object lockObject = new object(); private static List programs = new List(); @@ -38,46 +39,12 @@ namespace Wox.Plugin.Program SubTitle = c.ExecutePath, IcoPath = c.IcoPath, Score = c.Score, + ContextData = c, Action = (e) => { context.API.HideApp(); context.API.ShellRun(c.ExecutePath); return true; - }, - ContextMenu = new List() - { - new Result() - { - Title = context.API.GetTranslation("wox_plugin_program_run_as_administrator"), - Action = _ => - { - context.API.HideApp(); - context.API.ShellRun(c.ExecutePath,true); - return true; - }, - IcoPath = "Images/cmd.png" - }, - new Result() - { - Title = context.API.GetTranslation("wox_plugin_program_open_containing_folder"), - Action = _ => - { - context.API.HideApp(); - String Path=c.ExecutePath; - //check if shortcut - if (Path.EndsWith(".lnk")) - { - //get location of shortcut - Path = ResolveShortcut(Path); - } - //get parent folder - Path=System.IO.Directory.GetParent(Path).FullName; - //open the folder - context.API.ShellRun("explorer.exe "+Path,false); - return true; - }, - IcoPath = "Images/folder.png" - } } }).ToList(); } @@ -117,7 +84,7 @@ namespace Wox.Plugin.Program void API_ResultItemDropEvent(Result result, IDataObject dropObject, DragEventArgs e) { - + e.Handled = true; } @@ -232,5 +199,46 @@ namespace Wox.Plugin.Program { return context.API.GetTranslation("wox_plugin_program_plugin_description"); } + + public List LoadContextMenus(Result selectedResult) + { + Program p = selectedResult.ContextData as Program; + List contextMenus = new List() + { + new Result() + { + Title = context.API.GetTranslation("wox_plugin_program_run_as_administrator"), + Action = _ => + { + context.API.HideApp(); + context.API.ShellRun(p.ExecutePath, true); + return true; + }, + IcoPath = "Images/cmd.png" + }, + new Result() + { + Title = context.API.GetTranslation("wox_plugin_program_open_containing_folder"), + Action = _ => + { + context.API.HideApp(); + String Path = p.ExecutePath; + //check if shortcut + if (Path.EndsWith(".lnk")) + { + //get location of shortcut + Path = ResolveShortcut(Path); + } + //get parent folder + Path = Directory.GetParent(Path).FullName; + //open the folder + context.API.ShellRun("explorer.exe " + Path, false); + return true; + }, + IcoPath = "Images/folder.png" + } + }; + return contextMenus; + } } -} +} \ No newline at end of file diff --git a/Wox.Core/AssemblyHelper.cs b/Wox.Core/AssemblyHelper.cs index f9c428178..ac972ff55 100644 --- a/Wox.Core/AssemblyHelper.cs +++ b/Wox.Core/AssemblyHelper.cs @@ -12,37 +12,18 @@ namespace Wox.Core { public static List> LoadPluginInterfaces() where T : class { - List CSharpPluginMetadatas = PluginManager.AllPlugins.Select(o => o.Metadata).Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList(); - List> plugins = new List>(); - foreach (PluginMetadata metadata in CSharpPluginMetadatas) + List> results = new List>(); + foreach (PluginPair pluginPair in PluginManager.AllPlugins) { - try + //need to load types from AllPlugins + //PluginInitContext is only available in this instance + T type = pluginPair.Plugin as T; + if (type != null) { - Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath)); - List types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(T))).ToList(); - if (types.Count == 0) - { - continue; - } - - foreach (Type type in types) - { - plugins.Add(new KeyValuePair(PluginManager.AllPlugins.First(o => o.Metadata.ID == metadata.ID), - Activator.CreateInstance(type) as T)); - } - } - catch (System.Exception e) - { - Log.Error(string.Format("Couldn't load plugin {0}: {1}", metadata.Name, e.Message)); -#if (DEBUG) - { - throw; - } -#endif + results.Add(new KeyValuePair(pluginPair,type)); } } - - return plugins; + return results; } public static List LoadInterfacesFromAppDomain() where T : class diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index ff473061c..75cd0203a 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -26,6 +26,7 @@ namespace Wox.Core.Plugin private static List pluginMetadatas; private static List> instantSearches; private static List> exclusiveSearchPlugins; + private static List> contextMenuPlugins; public static String DebuggerMode { get; private set; } public static IPublicAPI API { get; private set; } @@ -267,5 +268,34 @@ namespace Wox.Core.Plugin { return GetExclusivePlugin(query) != null || GetActionKeywordPlugin(query) != null; } + + public static List GetPluginContextMenus(Result result) + { + List contextContextMenus = new List(); + if (contextMenuPlugins == null) + { + contextMenuPlugins = AssemblyHelper.LoadPluginInterfaces(); + } + + var contextMenuPlugin = contextMenuPlugins.FirstOrDefault(o => o.Key.Metadata.ID == result.PluginID); + if (contextMenuPlugin.Value != null) + { + try + { + return contextMenuPlugin.Value.LoadContextMenus(result); + } + catch (System.Exception e) + { + Log.Error(string.Format("Couldn't load plugin context menus {0}: {1}", contextMenuPlugin.Key.Metadata.Name, e.Message)); +#if (DEBUG) + { + throw; + } +#endif + } + } + + return contextContextMenus; + } } } diff --git a/Wox.Plugin/Features/IContextMenu.cs b/Wox.Plugin/Features/IContextMenu.cs new file mode 100644 index 000000000..0fa42076b --- /dev/null +++ b/Wox.Plugin/Features/IContextMenu.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Wox.Plugin.Features +{ + public interface IContextMenu + { + List LoadContextMenus(Result selectedResult); + } +} \ No newline at end of file diff --git a/Wox.Plugin/Result.cs b/Wox.Plugin/Result.cs index 5248cbb57..8e5523036 100644 --- a/Wox.Plugin/Result.cs +++ b/Wox.Plugin/Result.cs @@ -68,6 +68,7 @@ namespace Wox.Plugin this.SubTitle = SubTitle; } + [Obsolete("Use IContextMenu instead")] /// /// Context menus associate with this result /// diff --git a/Wox.Plugin/Wox.Plugin.csproj b/Wox.Plugin/Wox.Plugin.csproj index 80f2a52a4..25c14f4bd 100644 --- a/Wox.Plugin/Wox.Plugin.csproj +++ b/Wox.Plugin/Wox.Plugin.csproj @@ -46,6 +46,7 @@ + diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index d55e678a3..7cea6f4a7 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -155,14 +155,6 @@ namespace Wox o.PluginDirectory = plugin.PluginDirectory; o.PluginID = plugin.ID; o.OriginQuery = query; - if (o.ContextMenu != null) - { - o.ContextMenu.ForEach(t => - { - t.PluginDirectory = plugin.PluginDirectory; - t.PluginID = plugin.ID; - }); - } }); UpdateResultView(results); } @@ -253,7 +245,7 @@ namespace Wox void pnlResult_RightMouseClickEvent(Result result) { - ShowContextMenuFromResult(result); + ShowContextMenu(result); } void MainWindow_Closing(object sender, CancelEventArgs e) @@ -401,7 +393,7 @@ namespace Wox List filterResults = new List(); foreach (Result contextMenu in CurrentContextMenus) { - if (StringMatcher.IsMatch(contextMenu.Title, query) + if (StringMatcher.IsMatch(contextMenu.Title, query) || StringMatcher.IsMatch(contextMenu.SubTitle, query)) { filterResults.Add(contextMenu); @@ -528,7 +520,10 @@ namespace Wox private void HideWox() { - BackToResultMode(); + if (IsInContextMenuMode) + { + BackToResultMode(); + } Hide(); } @@ -615,7 +610,7 @@ namespace Wox } else { - ShowContextMenuFromResult(GetActiveResult()); + ShowContextMenu(GetActiveResult()); } } break; @@ -673,7 +668,7 @@ namespace Wox Result activeResult = GetActiveResult(); if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) { - ShowContextMenuFromResult(activeResult); + ShowContextMenu(activeResult); } else { @@ -795,11 +790,6 @@ namespace Wox list.ForEach(o => { o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; - if (o.ContextMenu == null) - { - o.ContextMenu = new List(); - } - HanleTopMost(o); }); List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); Dispatcher.Invoke(new Action(() => @@ -809,11 +799,11 @@ namespace Wox } } - private void HanleTopMost(Result result) + private Result GetTopMostContextMenu(Result result) { if (TopMostRecordStorage.Instance.IsTopMost(result)) { - result.ContextMenu.Add(new Result(GetTranslation("cancelTopMostInThisQuery"), "Images\\down.png") + return new Result(GetTranslation("cancelTopMostInThisQuery"), "Images\\down.png") { PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Action = _ => @@ -822,11 +812,11 @@ namespace Wox ShowMsg("Succeed", "", ""); return false; } - }); + }; } else { - result.ContextMenu.Add(new Result(GetTranslation("setAsTopMostInThisQuery"), "Images\\up.png") + return new Result(GetTranslation("setAsTopMostInThisQuery"), "Images\\up.png") { PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Action = _ => @@ -835,22 +825,29 @@ namespace Wox ShowMsg("Succeed", "", ""); return false; } - }); + }; } } - private void ShowContextMenuFromResult(Result result) + private void ShowContextMenu(Result result) { - if (result.ContextMenu != null && result.ContextMenu.Count > 0) + List results = PluginManager.GetPluginContextMenus(result); + results.ForEach(o => { - textBeforeEnterContextMenuMode = tbQuery.Text; - ChangeQueryText(""); - pnlContextMenu.Clear(); - pnlContextMenu.AddResults(result.ContextMenu); - CurrentContextMenus = result.ContextMenu; - pnlContextMenu.Visibility = Visibility.Visible; - pnlResult.Visibility = Visibility.Collapsed; - } + o.PluginDirectory = PluginManager.GetPlugin(result.PluginID).Metadata.PluginDirectory; + o.PluginID = result.PluginID; + o.OriginQuery = result.OriginQuery; + }); + + results.Add(GetTopMostContextMenu(result)); + + textBeforeEnterContextMenuMode = tbQuery.Text; + ChangeQueryText(""); + pnlContextMenu.Clear(); + pnlContextMenu.AddResults(results); + CurrentContextMenus = results; + pnlContextMenu.Visibility = Visibility.Visible; + pnlResult.Visibility = Visibility.Collapsed; } public bool ShellRun(string cmd, bool runAsAdministrator = false) From 877ad53eadf455d528e42fbde7e96c91e75d98a4 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 8 Feb 2015 00:06:22 +0800 Subject: [PATCH 16/26] fix a plugin query issue --- Plugins/Wox.Plugin.Everything/plugin.json | 2 +- Wox.Core/Plugin/PluginManager.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Plugins/Wox.Plugin.Everything/plugin.json b/Plugins/Wox.Plugin.Everything/plugin.json index 8eb78934e..0f7418f95 100644 --- a/Plugins/Wox.Plugin.Everything/plugin.json +++ b/Plugins/Wox.Plugin.Everything/plugin.json @@ -1,6 +1,6 @@ { "ID":"D2D2C23B084D411DB66FE0C79D6C2A6E", - "ActionKeyword":"*", + "ActionKeyword":"f", "Name":"Everything", "Description":"Search Everything", "Author":"qianlifeng,orzfly", diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs index 75cd0203a..b681463f4 100644 --- a/Wox.Core/Plugin/PluginManager.cs +++ b/Wox.Core/Plugin/PluginManager.cs @@ -248,6 +248,9 @@ namespace Wox.Core.Plugin internal static PluginPair GetActionKeywordPlugin(Query query) { + //if a query doesn't contain at least one space, it should not be a action keword plugin query + if (!query.RawQuery.Contains(" ")) return null; + PluginPair actionKeywordPluginPair = AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == query.GetActionKeyword()); if (actionKeywordPluginPair != null) { From dc2f3cd16696c7b70dc92480e93340d7ffaf9742 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 8 Feb 2015 10:38:32 +0800 Subject: [PATCH 17/26] Improve setting window performance (theme). --- Wox.Core/i18n/Internationalization.cs | 2 +- Wox/SettingWindow.xaml | 17 -------- Wox/SettingWindow.xaml.cs | 62 +++++++++------------------ 3 files changed, 22 insertions(+), 59 deletions(-) diff --git a/Wox.Core/i18n/Internationalization.cs b/Wox.Core/i18n/Internationalization.cs index 25981e89c..bf2157603 100644 --- a/Wox.Core/i18n/Internationalization.cs +++ b/Wox.Core/i18n/Internationalization.cs @@ -41,7 +41,6 @@ namespace Wox.Core.i18n { Language language = GetLanguageByLanguageCode(languageCode); ChangeLanguage(language); - UpdateAllPluginMetadataTranslations(); } private Language GetLanguageByLanguageCode(string languageCode) @@ -72,6 +71,7 @@ namespace Wox.Core.i18n UserSettingStorage.Instance.Language = language.LanguageCode; UserSettingStorage.Instance.Save(); ResourceMerger.ApplyResources(); + UpdateAllPluginMetadataTranslations(); } public ResourceDictionary GetResourceDictionary() diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index 92f9eb8eb..29043715d 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -188,23 +188,6 @@ - - - - Normal - LayeredWindow - DWM - - - - - - - - - - - diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index 1e8b2190b..019f80593 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Net; +using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -23,6 +24,7 @@ using Wox.Core.i18n; using Wox.Core.Theme; using Wox.Core.Updater; using Wox.Core.UserSettings; +using Wox.Infrastructure; using CheckBox = System.Windows.Controls.CheckBox; using Control = System.Windows.Controls.Control; using Cursors = System.Windows.Input.Cursors; @@ -262,23 +264,13 @@ namespace Wox Process.Start("http://www.getwox.com/theme"); } - - private void CbOpacityMode_OnSelectionChanged(object sender, SelectionChangedEventArgs e) - { - UserSettingStorage.Instance.OpacityMode = (OpacityMode)CbOpacityMode.SelectedItem; - UserSettingStorage.Instance.Save(); - - spOpacity.Visibility = UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow ? Visibility.Visible : Visibility.Collapsed; - - if (UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow) - PreviewMainPanel.Opacity = UserSettingStorage.Instance.Opacity; - else - PreviewMainPanel.Opacity = 1; - } - - private void OnThemeTabSelected() { + using (new Timeit("theme load")) + { + var s = Fonts.SystemFontFamilies; + } + if (themeTabLoaded) return; themeTabLoaded = true; @@ -304,6 +296,7 @@ namespace Wox UserSettingStorage.Instance.ResultItemFontStretch )); } + resultPanelPreview.AddResults(new List() { new Result() @@ -363,8 +356,6 @@ namespace Wox } themeComboBox.SelectedItem = UserSettingStorage.Instance.Theme; - slOpacity.Value = UserSettingStorage.Instance.Opacity; - CbOpacityMode.SelectedItem = UserSettingStorage.Instance.OpacityMode; var wallpaper = WallpaperPathRetrieval.GetWallpaperPath(); if (wallpaper != null && File.Exists(wallpaper)) @@ -379,8 +370,6 @@ namespace Wox PreviewPanel.Background = new SolidColorBrush(wallpaperColor); } - //PreviewPanel - ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); } private void TabTheme_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) @@ -396,8 +385,8 @@ namespace Wox private void ThemeComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { string themeName = themeComboBox.SelectedItem.ToString(); - ThemeManager.Theme.ChangeTheme(themeName); UserSettingStorage.Instance.Theme = themeName; + DelayChangeTheme(); UserSettingStorage.Instance.Save(); } @@ -407,9 +396,16 @@ namespace Wox string queryBoxFontName = cbQueryBoxFont.SelectedItem.ToString(); UserSettingStorage.Instance.QueryBoxFont = queryBoxFontName; this.cbQueryBoxFontFaces.SelectedItem = ((FontFamily)cbQueryBoxFont.SelectedItem).ChooseRegularFamilyTypeface(); - + DelayChangeTheme(); UserSettingStorage.Instance.Save(); - ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + } + + private void DelayChangeTheme() + { + Dispatcher.DelayInvoke("delayChangeTheme", o => + { + ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + }, TimeSpan.FromMilliseconds(100)); } private void CbQueryBoxFontFaces_OnSelectionChanged(object sender, SelectionChangedEventArgs e) @@ -429,7 +425,7 @@ namespace Wox UserSettingStorage.Instance.QueryBoxFontWeight = typeface.Weight.ToString(); UserSettingStorage.Instance.QueryBoxFontStyle = typeface.Style.ToString(); UserSettingStorage.Instance.Save(); - ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + DelayChangeTheme(); } } @@ -441,7 +437,7 @@ namespace Wox this.cbResultItemFontFaces.SelectedItem = ((FontFamily)cbResultItemFont.SelectedItem).ChooseRegularFamilyTypeface(); UserSettingStorage.Instance.Save(); - ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + DelayChangeTheme(); } private void CbResultItemFontFaces_OnSelectionChanged(object sender, SelectionChangedEventArgs e) @@ -459,30 +455,14 @@ namespace Wox UserSettingStorage.Instance.ResultItemFontWeight = typeface.Weight.ToString(); UserSettingStorage.Instance.ResultItemFontStyle = typeface.Style.ToString(); UserSettingStorage.Instance.Save(); - ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); + DelayChangeTheme(); } } - private void slOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) - { - UserSettingStorage.Instance.Opacity = slOpacity.Value; - - if (UserSettingStorage.Instance.OpacityMode == OpacityMode.LayeredWindow) - PreviewMainPanel.Opacity = UserSettingStorage.Instance.Opacity; - else - PreviewMainPanel.Opacity = 1; - - ThemeManager.Theme.ChangeTheme(UserSettingStorage.Instance.Theme); - Dispatcher.DelayInvoke("delaySaveUserSetting", o => - { - UserSettingStorage.Instance.Save(); - }, TimeSpan.FromMilliseconds(1000)); - } #endregion #region Plugin - private void lbPlugins_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { ISettingProvider provider = null; From 6c731f50a95b179af7cf0ec7431fc4bbac37ade8 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 8 Feb 2015 16:27:41 +0800 Subject: [PATCH 18/26] Improve Everything plugin user experience --- Plugins/Wox.Plugin.Everything/Main.cs | 73 ++- .../PortableEverything/Everything.ini | 485 ++++++++++++++++++ .../Wox.Plugin.Everything.csproj | 1 + Plugins/Wox.Plugin.Everything/plugin.json | 2 +- .../PluginIndicator.cs | 2 +- Wox.CrashReporter/Properties/AssemblyInfo.cs | 55 +- Wox.CrashReporter/ReportWindow.xaml | 2 +- Wox.CrashReporter/ReportWindow.xaml.cs | 18 +- Wox.CrashReporter/Wox.CrashReporter.csproj | 225 ++++---- Wox.CrashReporter/packages.config | 4 + Wox.Infrastructure/Properties/AssemblyInfo.cs | 21 +- Wox/App.config | 12 +- Wox/Helper/ErrorReporting.cs | 1 - Wox/Properties/AssemblyInfo.cs | 3 +- Wox/Wox.csproj | 8 + Wox/packages.config | 1 + 16 files changed, 717 insertions(+), 196 deletions(-) create mode 100644 Plugins/Wox.Plugin.Everything/PortableEverything/Everything.ini create mode 100644 Wox.CrashReporter/packages.config diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs index 17a6b84a1..58a41644f 100644 --- a/Plugins/Wox.Plugin.Everything/Main.cs +++ b/Plugins/Wox.Plugin.Everything/Main.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.ServiceProcess; using Wox.Infrastructure; using System.Reflection; using Wox.Plugin.Everything.Everything; @@ -10,7 +11,7 @@ using Wox.Plugin.Features; namespace Wox.Plugin.Everything { - public class Main : IPlugin, IPluginI18n,IContextMenu + public class Main : IPlugin, IPluginI18n, IContextMenu { PluginInitContext context; EverythingAPI api = new EverythingAPI(); @@ -141,23 +142,67 @@ namespace Wox.Plugin.Everything private void StartEverything() { - if (!CheckEverythingIsRunning()) + if (!CheckEverythingSericeRunning()) { - try + if (InstallAndRunEverythingService()) { - Process p = new Process(); - p.StartInfo.Verb = "runas"; - p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - p.StartInfo.FileName = GetEverythingPath(); - p.StartInfo.UseShellExecute = true; - p.Start(); - } - catch (Exception e) - { - context.API.ShowMsg("Start Everything failed"); + StartEverythingClient(); } + } + else + { + StartEverythingClient(); + } + } + + private bool InstallAndRunEverythingService() + { + try + { + Process p = new Process(); + p.StartInfo.Verb = "runas"; + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + p.StartInfo.FileName = GetEverythingPath(); + p.StartInfo.UseShellExecute = true; + p.StartInfo.Arguments = "-install-service"; + p.Start(); + return true; + } + catch (Exception e) + { + return false; + } + } + + private void StartEverythingClient() + { + try + { + Process p = new Process(); + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + p.StartInfo.FileName = GetEverythingPath(); + p.StartInfo.UseShellExecute = true; + p.StartInfo.Arguments = "-startup"; + p.Start(); + } + catch (Exception e) + { + context.API.ShowMsg("Start Everything failed"); + } + } + + private bool CheckEverythingSericeRunning() + { + try + { + ServiceController sc = new ServiceController("Everything"); + return sc.Status == ServiceControllerStatus.Running; + } + catch + { } + return false; } private bool CheckEverythingIsRunning() @@ -190,7 +235,7 @@ namespace Wox.Plugin.Everything { SearchResult record = selectedResult.ContextData as SearchResult; List contextMenus = new List(); - if(record == null) return contextMenus; + if (record == null) return contextMenus; List availableContextMenus = new List(); availableContextMenus.AddRange(GetDefaultContextMenu()); diff --git a/Plugins/Wox.Plugin.Everything/PortableEverything/Everything.ini b/Plugins/Wox.Plugin.Everything/PortableEverything/Everything.ini new file mode 100644 index 000000000..c3769fe5c --- /dev/null +++ b/Plugins/Wox.Plugin.Everything/PortableEverything/Everything.ini @@ -0,0 +1,485 @@ +[Everything] +app_data=0 +run_as_admin=0 +window_x=75 +window_y=37 +window_wide=1097 +window_high=664 +maximized=0 +minimized=0 +fullscreen=0 +ontop=0 +match_whole_word=0 +match_path=0 +match_case=0 +match_diacritics=0 +match_regex=0 +selection_mask_right_bottom_inclusive=1 +allow_multiple_windows=0 +allow_multiple_instances=0 +run_in_background=1 +show_tray_icon=0 +alternate_row_color=0 +show_mouseover=0 +check_for_updates_on_startup=0 +beta_updates=0 +show_highlighted_search_terms=1 +text_size=0 +hide_empty_search_results=0 +clear_selection_on_search=1 +new_window_key=0 +show_window_key=0 +toggle_window_key=0 +language=0 +show_selected_item_in_statusbar=0 +open_folder_command2= +open_file_command2= +open_path_command2= +explore_command2= +explore_path_command2= +window_title_format= +taskbar_notification_title_format= +instance_name= +translucent_selection_rectangle_alpha=70 +min_zoom=-6 +max_zoom=27 +context_menu_type=0 +auto_include_fixed_volumes=1 +auto_include_removable_volumes=0 +last_export_type=0 +max_threads=0 +reuse_threads=1 +single_parent_context_menu=0 +auto_size_1=512 +auto_size_2=640 +auto_size_3=768 +auto_size_aspect_ratio_x=9 +auto_size_aspect_ratio_y=7 +auto_size_path_x=1 +auto_size_path_y=2 +sticky_vscroll_bottom=1 +last_options_page=0 +draw_focus_rect=1 +date_format= +time_format= +invert_layout=0 +listview_item_high=0 +debug=0 +home_match_case=0 +home_match_whole_word=0 +home_match_path=0 +home_match_diacritics=0 +home_regex=0 +home_search=1 +home_filter=0 +home_sort=0 +home_index=1 +allow_multiple_windows_from_tray=0 +single_click_tray=0 +close_on_execute=0 +double_click_path=0 +update_display_after_scroll=0 +update_display_after_mask=1 +auto_scroll_view=0 +double_quote_copy_as_path=0 +snap=0 +snaplen=10 +rename_select_filepart_only=0 +rename_move_caret_to_selection_end=0 +search_edit_move_caret_to_selection_end=0 +select_search_on_mouse_click=1 +focus_search_on_activate=0 +reset_vscroll_on_search=1 +wrap_focus=0 +load_icon_priority=0 +load_fileinfo_priority=0 +header_high=0 +hide_on_close=0 +winmm=0 +menu_escape_amp=1 +fast_ascii_search=1 +match_path_when_search_contains_path_separator=1 +allow_literal_operators=0 +allow_round_bracket_parenthesis=0 +expand_environment_variables=0 +search_as_you_type=1 +convert_forward_slash_to_backslash=0 +match_whole_filename_when_using_wildcards=1 +double_buffer=1 +search= +show_number_of_results_with_selection=0 +date_descending_first=0 +size_descending_first=1 +size_format=2 +alpha_select=0 +tooltips=1 +rtl_listview_edit=0 +bookmark_remember_case=1 +bookmark_remember_wholeword=1 +bookmark_remember_path=1 +bookmark_remember_diacritic=1 +bookmark_remember_regex=1 +bookmark_remember_sort=1 +bookmark_remember_filter=1 +bookmark_remember_index=1 +exclude_list_enabled=1 +exclude_hidden_files_and_folders=0 +exclude_system_files_and_folders=0 +include_only_files= +exclude_files= +db_location= +db_multi_user_filename=0 +db_compress=0 +extended_information_cache_monitor=1 +keep_missing_indexes=0 +editor_x=0 +editor_y=0 +editor_wide=0 +editor_high=0 +editor_maximized=0 +file_list_relative_paths=1 +max_recv_size=8388608 +display_full_path_name=0 +size_tiny=10240 +size_small=102400 +size_medium=1048576 +size_large=16777216 +size_huge=134217728 +themed_toolbar=1 +show_copy_path=2 +show_copy_full_name=2 +show_open_path=2 +show_explore=2 +show_explore_path=2 +copy_path_folder_append_backslash=0 +custom_verb01= +custom_verb02= +custom_verb03= +custom_verb04= +custom_verb05= +custom_verb06= +custom_verb07= +custom_verb08= +custom_verb09= +custom_verb10= +custom_verb11= +custom_verb12= +filters_visible=0 +filters_wide=128 +filters_right_align=1 +filters_tab_stop=0 +filter= +filter_everything_name= +sort=Name +sort_ascending=1 +always_keep_sort=0 +index=0 +index_file_list= +index_etp_server= +index_link_type=1 +status_bar_visible=1 +select_search_on_focus_mode=1 +select_search_on_set_mode=2 +search_history_enabled=0 +run_history_enabled=0 +search_history_days_to_keep=90 +run_history_days_to_keep=90 +search_history_always_suggest=0 +search_history_max_results=24 +search_history_show_above=0 +service_port=15485 +etp_server_enabled=0 +etp_server_bindings= +etp_server_port=21 +etp_server_username= +etp_server_password= +etp_server_welcome_message= +etp_server_log_file_name= +etp_server_logging_enabled=1 +etp_server_log_max_size=4194304 +etp_server_log_delta_size=524288 +etp_server_allow_file_download=1 +http_server_enabled=0 +http_server_bindings= +http_title_format= +http_server_port=80 +http_server_username= +http_server_password= +http_server_home= +http_server_default_page= +http_server_log_file_name= +http_server_logging_enabled=1 +http_server_log_max_size=4194304 +http_server_log_delta_size=524288 +http_server_allow_file_download=1 +name_column_pos=0 +name_column_width=256 +path_column_visible=1 +path_column_pos=1 +path_column_width=559 +size_column_visible=1 +size_column_pos=2 +size_column_width=96 +extension_column_visible=0 +extension_column_pos=3 +extension_column_width=96 +type_column_visible=0 +type_column_pos=4 +type_column_width=96 +last_write_time_column_visible=1 +last_write_time_column_pos=3 +last_write_time_column_width=153 +creation_time_column_visible=0 +creation_time_column_pos=6 +creation_time_column_width=140 +date_accessed_column_visible=0 +date_accessed_column_pos=7 +date_accessed_column_width=140 +attribute_column_visible=0 +attribute_column_pos=8 +attribute_column_width=70 +date_recently_changed_column_visible=0 +date_recently_changed_column_pos=9 +date_recently_changed_column_width=96 +run_count_column_visible=0 +run_count_column_pos=10 +run_count_column_width=96 +date_run_column_visible=0 +date_run_column_pos=11 +date_run_column_width=140 +file_list_filename_column_visible=0 +file_list_filename_column_pos=12 +file_list_filename_column_width=96 +translucent_selection_rectangle_background_color= +translucent_selection_rectangle_border_color= +ntfs_volume_paths="C:" +ntfs_volume_includes=1 +ntfs_volume_load_recent_changes=0 +ntfs_volume_include_onlys="" +ntfs_volume_monitors=1 +filelists= +folders= +folder_monitor_changes= +folder_update_types= +folder_update_days= +folder_update_ats= +folder_update_intervals= +folder_update_interval_types= +exclude_folders= +connect_history_hosts= +connect_history_ports= +connect_history_usernames= +connect_history_link_types= +file_new_search_window_keys=334 +file_open_file_list_keys=335 +file_close_file_list_keys= +file_close_keys=343,27 +file_export_keys=339 +file_copy_full_name_to_clipboard_keys=9539 +file_copy_path_to_clipboard_keys= +file_set_run_count_keys= +file_create_shortcut_keys= +file_delete_keys=8238 +file_delete_permanently_keys=9262 +file_edit_keys= +file_open_keys=8205 +file_open_selection_and_close_everything_keys= +file_explore_path_keys= +file_open_new_keys= +file_open_path_keys=8461 +file_open_with_keys= +file_open_with_default_verb_keys= +file_play_keys= +file_preview_keys= +file_print_keys= +file_print_to_keys= +file_properties_keys=8717 +file_read_extended_information_keys=8517 +file_rename_keys=8305 +file_run_as_keys= +file_exit_keys=337 +file_custom_verb_1_keys= +file_custom_verb_2_keys= +file_custom_verb_3_keys= +file_custom_verb_4_keys= +file_custom_verb_5_keys= +file_custom_verb_6_keys= +file_custom_verb_7_keys= +file_custom_verb_8_keys= +file_custom_verb_9_keys= +file_custom_verb_10_keys= +file_custom_verb_11_keys= +file_custom_verb_12_keys= +edit_cut_keys=8536 +edit_copy_keys=8515,8493 +edit_paste_keys=8534,9261 +edit_select_all_keys=8513 +edit_invert_selection_keys= +view_filters_keys= +view_status_bar_keys= +view_window_size_small_keys=561 +view_window_size_medium_keys=562 +view_window_size_large_keys=563 +view_window_size_auto_fit_keys=564 +view_zoom_zoom_in_keys=443,363 +view_zoom_zoom_out_keys=445,365 +view_zoom_reset_keys=304,352 +view_go_to_back_keys=549,166 +view_go_to_forward_keys=551,167 +view_go_to_home_keys=548 +view_sort_by_name_keys=305 +view_sort_by_path_keys=306 +view_sort_by_size_keys=307 +view_sort_by_extension_keys=308 +view_sort_by_type_keys=309 +view_sort_by_date_modified_keys=310 +view_sort_by_date_created_keys=311 +view_sort_by_attributes_keys=312 +view_sort_by_file_list_filename_keys= +view_sort_by_run_count_keys= +view_sort_by_date_run_keys= +view_sort_by_date_recently_changed_keys=313 +view_sort_by_date_accessed_keys= +view_sort_by_ascending_keys= +view_sort_by_descending_keys= +view_refresh_keys=116 +view_fullscreen_keys=122 +view_toggle_ltrrtl_keys= +view_on_top_never_keys= +view_on_top_always_keys=340 +view_on_top_while_searching_keys= +search_match_case_keys=329 +search_match_whole_word_keys=322 +search_match_path_keys=341 +search_match_diacritics_keys=333 +search_enable_regex_keys=338 +search_add_to_filters_keys= +search_organize_filters_keys=1350 +bookmarks_add_to_bookmarks_keys=324 +bookmarks_organize_bookmarks_keys=1346 +tools_options_keys=336 +tools_console_keys=448 +tools_file_list_editor_keys= +tools_connect_to_etp_server_keys= +tools_disconnect_from_etp_server_keys= +help_everything_help_keys=112 +help_search_syntax_keys= +help_regex_syntax_keys= +help_command_line_options_keys= +help_everything_website_keys= +help_check_for_updates_keys= +help_about_everything_keys=368 +search_edit_focus_search_edit_keys=326,114 +search_edit_delete_previous_word_keys=4360 +search_edit_auto_complete_search_keys=4384 +search_edit_show_search_history_keys= +search_edit_show_all_search_history_keys=4646,4648 +result_list_item_up_keys=8230,4134 +result_list_item_down_keys=8232,4136 +result_list_page_up_keys=8225,4129 +result_list_page_down_keys=8226,4130 +result_list_start_of_list_keys=8228 +result_list_end_of_list_keys=8227 +result_list_item_up_extend_keys=9254,5158 +result_list_item_down_extend_keys=9256,5160 +result_list_page_up_extend_keys=9249,5153 +result_list_page_down_extend_keys=9250,5154 +result_list_start_of_list_extend_keys=9252 +result_list_end_of_list_extend_keys=9251 +result_list_focus_up_keys=8486,4390 +result_list_focus_down_keys=8488,4392 +result_list_focus_page_up_keys=8481,4385 +result_list_focus_page_down_keys=8482,4386 +result_list_focus_start_of_list_keys=8484 +result_list_focus_end_of_list_keys=8483 +result_list_focus_up_extend_keys=9510,5414 +result_list_focus_down_extend_keys=9512,5416 +result_list_focus_page_up_extend_keys=9505,5409 +result_list_focus_page_down_extend_keys=9506,5410 +result_list_focus_start_of_list_extend_keys=9508 +result_list_focus_end_of_list_extend_keys=9507 +result_list_focus_result_list_keys= +result_list_toggle_path_column_keys=1330 +result_list_toggle_size_column_keys=1331 +result_list_toggle_extension_column_keys=1332 +result_list_toggle_type_column_keys=1333 +result_list_toggle_date_modified_column_keys=1334 +result_list_toggle_date_created_column_keys=1335 +result_list_toggle_attributes_column_keys=1336 +result_list_toggle_file_list_filename_column_keys= +result_list_toggle_run_count_column_keys= +result_list_toggle_date_recently_changed_column_keys=1337 +result_list_toggle_date_accessed_column_keys= +result_list_toggle_date_run_column_keys= +result_list_size_all_columns_to_fit_keys=8555 +result_list_size_result_list_to_fit_keys= +result_list_context_menu_keys=9337 +result_list_scroll_left_keys=8229 +result_list_scroll_right_keys=8231 +result_list_scroll_page_left_keys=8485 +result_list_scroll_page_right_keys=8487 +result_list_select_focus_keys=8224 +result_list_toggle_focus_selection_keys=8480 +result_list_copy_selection_to_clipboard_as_csv_keys= +result_list_font= +result_list_font_size= +search_edit_font= +search_edit_font_size= +status_bar_font= +status_bar_font_size= +header_font= +header_font_size= +normal_background_color= +normal_foreground_color= +normal_bold= +highlighted_background_color= +highlighted_foreground_color= +highlighted_bold= +selected_background_color= +selected_foreground_color= +selected_bold= +highlighted_selected_background_color= +highlighted_selected_foreground_color= +highlighted_selected_bold= +selected_inactive_background_color= +selected_inactive_foreground_color= +selected_inactive_bold= +highlighted_selected_inactive_background_color= +highlighted_selected_inactive_foreground_color= +highlighted_selected_inactive_bold= +drop_target_background_color= +drop_target_foreground_color= +drop_target_bold= +highlighted_drop_target_background_color= +highlighted_drop_target_foreground_color= +highlighted_drop_target_bold= +current_sort_background_color= +current_sort_foreground_color= +current_sort_bold= +highlighted_current_sort_background_color= +highlighted_current_sort_foreground_color= +highlighted_current_sort_bold= +mouseover_background_color= +mouseover_foreground_color= +mouseover_bold= +mouseover_highlighted_background_color= +mouseover_highlighted_foreground_color= +mouseover_highlighted_bold= +current_sort_mouseover_background_color= +current_sort_mouseover_foreground_color= +current_sort_mouseover_bold= +mouseover_current_sort_highlighted_background_color= +mouseover_current_sort_highlighted_foreground_color= +mouseover_current_sort_highlighted_bold= +alternate_row_background_color= +alternate_row_foreground_color= +alternate_row_bold= +alternate_row_highlighted_background_color= +alternate_row_highlighted_foreground_color= +alternate_row_highlighted_bold= +current_sort_alternate_row_background_color= +current_sort_alternate_row_foreground_color= +current_sort_alternate_row_bold= +current_sort_alternate_row_highlighted_background_color= +current_sort_alternate_row_highlighted_foreground_color= +current_sort_alternate_row_highlighted_bold= diff --git a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj index 0c677c0d2..96380b9b2 100644 --- a/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj +++ b/Plugins/Wox.Plugin.Everything/Wox.Plugin.Everything.csproj @@ -44,6 +44,7 @@ + diff --git a/Plugins/Wox.Plugin.Everything/plugin.json b/Plugins/Wox.Plugin.Everything/plugin.json index 0f7418f95..8eb78934e 100644 --- a/Plugins/Wox.Plugin.Everything/plugin.json +++ b/Plugins/Wox.Plugin.Everything/plugin.json @@ -1,6 +1,6 @@ { "ID":"D2D2C23B084D411DB66FE0C79D6C2A6E", - "ActionKeyword":"f", + "ActionKeyword":"*", "Name":"Everything", "Description":"Search Everything", "Author":"qianlifeng,orzfly", diff --git a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs index d09501370..fe0a2a8f4 100644 --- a/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs +++ b/Plugins/Wox.Plugin.PluginIndicator/PluginIndicator.cs @@ -67,7 +67,7 @@ namespace Wox.Plugin.PluginIndicator public string GetTranslatedPluginDescription() { - return context.API.GetTranslation("wox_plugin_luginindicator_plugin_description"); + return context.API.GetTranslation("wox_plugin_pluginindicator_plugin_description"); } } } diff --git a/Wox.CrashReporter/Properties/AssemblyInfo.cs b/Wox.CrashReporter/Properties/AssemblyInfo.cs index 688a8e327..13ef80c58 100644 --- a/Wox.CrashReporter/Properties/AssemblyInfo.cs +++ b/Wox.CrashReporter/Properties/AssemblyInfo.cs @@ -1,36 +1,19 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("Wox.CrashReporter")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Wox.CrashReporter")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("0ea3743c-2c0d-4b13-b9ce-e5e1f85aea23")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Wox.CrashReporter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Wox.CrashReporter")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("0ea3743c-2c0d-4b13-b9ce-e5e1f85aea23")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Wox.CrashReporter/ReportWindow.xaml b/Wox.CrashReporter/ReportWindow.xaml index abd22798e..c9f7a92ff 100644 --- a/Wox.CrashReporter/ReportWindow.xaml +++ b/Wox.CrashReporter/ReportWindow.xaml @@ -35,7 +35,7 @@ - + diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index 05612cd9c..c5a7d1a57 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -12,6 +12,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Exceptionless; using Wox.Core; using Wox.Core.Exception; using Wox.Core.i18n; @@ -49,19 +50,18 @@ namespace Wox.CrashReporter string sendingMsg = InternationalizationManager.Instance.GetTranslation("reportWindow_sending"); tbSendReport.Content = sendingMsg; btnSend.IsEnabled = false; - ThreadPool.QueueUserWorkItem(o => SendReport()); + SendReport(); } private void SendReport() { - Hide(); - string error = string.Format("{{\"data\":{0}}}", ExceptionFormatter.FormatExcpetion(exception)); - string response = HttpRequest.Post(APIServer.ErrorReportURL, error, HttpProxy.Instance); - if (response.ToLower() != "ok") - { - Log.Warn("sending crash report failed: " + response); - } - Dispatcher.Invoke(new Action(Close)); + string reproduceSteps = + new TextRange(tbReproduceSteps.Document.ContentStart, tbReproduceSteps.Document.ContentEnd).Text; + exception.ToExceptionless() + .SetUserDescription(reproduceSteps) + .Submit(); + ExceptionlessClient.Current.ProcessQueue(); + Close(); } private void btnCancel_Click(object sender, RoutedEventArgs e) diff --git a/Wox.CrashReporter/Wox.CrashReporter.csproj b/Wox.CrashReporter/Wox.CrashReporter.csproj index 565c82d81..822e39768 100644 --- a/Wox.CrashReporter/Wox.CrashReporter.csproj +++ b/Wox.CrashReporter/Wox.CrashReporter.csproj @@ -1,109 +1,118 @@ - - - - - Debug - AnyCPU - {2FEB2298-7653-4009-B1EA-FFFB1A768BCC} - Library - Properties - Wox.CrashReporter - Wox.CrashReporter - v3.5 - 512 - ..\ - true - - - - true - full - false - ..\Output\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - ..\Output\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - - - - - - ReportWindow.xaml - - - - - Designer - MSBuild:Compile - - - - - {B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} - Wox.Core - - - {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} - Wox.Infrastructure - - - {8451ECDD-2EA4-4966-BB0A-7BBC40138E80} - Wox.Plugin - - - - - PreserveNewest - - - PreserveNewest - - - - - PreserveNewest - - - - - PreserveNewest - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - + + + + + Debug + AnyCPU + {2FEB2298-7653-4009-B1EA-FFFB1A768BCC} + Library + Properties + Wox.CrashReporter + Wox.CrashReporter + v3.5 + 512 + ..\ + true + + + + true + full + false + ..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + ..\Output\Release\ + TRACE + prompt + 4 + false + + + + ..\packages\Exceptionless.1.5.2121\lib\net35\Exceptionless.dll + + + ..\packages\Exceptionless.1.5.2121\lib\net35\Exceptionless.Models.dll + + + + + + + + + + + + + + + + + ReportWindow.xaml + + + + + Designer + MSBuild:Compile + + + + + {B749F0DB-8E75-47DB-9E5E-265D16D0C0D2} + Wox.Core + + + {4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} + Wox.Infrastructure + + + {8451ECDD-2EA4-4966-BB0A-7BBC40138E80} + Wox.Plugin + + + + + PreserveNewest + + + PreserveNewest + + + + + PreserveNewest + + + + + PreserveNewest + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/Wox.CrashReporter/packages.config b/Wox.CrashReporter/packages.config new file mode 100644 index 000000000..aaa9e6ed9 --- /dev/null +++ b/Wox.CrashReporter/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Wox.Infrastructure/Properties/AssemblyInfo.cs b/Wox.Infrastructure/Properties/AssemblyInfo.cs index b40c42166..092a40914 100644 --- a/Wox.Infrastructure/Properties/AssemblyInfo.cs +++ b/Wox.Infrastructure/Properties/AssemblyInfo.cs @@ -2,9 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 + [assembly: AssemblyTitle("Wox.Infrastructure")] [assembly: AssemblyDescription("https://github.com/qianlifeng/Wox")] [assembly: AssemblyConfiguration("")] @@ -13,24 +11,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("The MIT License (MIT)")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID [assembly: Guid("aee57a31-29e5-4f03-a41f-7917910fe90f")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Wox/App.config b/Wox/App.config index af328919a..ab8b3cde5 100644 --- a/Wox/App.config +++ b/Wox/App.config @@ -1,12 +1,16 @@ + +
+ - + - - + + - + + \ No newline at end of file diff --git a/Wox/Helper/ErrorReporting.cs b/Wox/Helper/ErrorReporting.cs index cff796318..d1de5c982 100644 --- a/Wox/Helper/ErrorReporting.cs +++ b/Wox/Helper/ErrorReporting.cs @@ -13,7 +13,6 @@ namespace Wox.Helper { public static void Report(Exception e) { - if (Debugger.IsAttached) return; Log.Error(ExceptionFormatter.FormatExcpetion(e)); new CrashReporter.CrashReporter(e).Show(); } diff --git a/Wox/Properties/AssemblyInfo.cs b/Wox/Properties/AssemblyInfo.cs index 525979aae..cfddac76a 100644 --- a/Wox/Properties/AssemblyInfo.cs +++ b/Wox/Properties/AssemblyInfo.cs @@ -19,4 +19,5 @@ using System.Windows; ResourceDictionaryLocation.SourceAssembly )] [assembly: AssemblyVersion("1.1.0")] -[assembly: AssemblyFileVersion("1.1.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.1.0")] +[assembly: Exceptionless.Configuration.Exceptionless("13462a93b5e843c7bae7da13a86bc00b", EnableLogging = true, LogPath = "E:\\exceptionless.log")] \ No newline at end of file diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 4badbf06b..2122a7bb6 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -62,6 +62,14 @@ + + False + ..\packages\Exceptionless.1.5.2121\lib\net35\Exceptionless.dll + + + False + ..\packages\Exceptionless.1.5.2121\lib\net35\Exceptionless.Models.dll + False ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll diff --git a/Wox/packages.config b/Wox/packages.config index 9f1a6d32b..054bbd20c 100644 --- a/Wox/packages.config +++ b/Wox/packages.config @@ -1,5 +1,6 @@  + From 268df237399c910984a177d41f1478d96ac6fa85 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 8 Feb 2015 17:09:14 +0800 Subject: [PATCH 19/26] Add uninstalleverything command as everything serivce will prevent move/remove wox folder. --- Plugins/Wox.Plugin.Everything/Main.cs | 44 +++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/Plugins/Wox.Plugin.Everything/Main.cs b/Plugins/Wox.Plugin.Everything/Main.cs index 58a41644f..4318485e6 100644 --- a/Plugins/Wox.Plugin.Everything/Main.cs +++ b/Plugins/Wox.Plugin.Everything/Main.cs @@ -30,6 +30,21 @@ namespace Wox.Plugin.Everything ContextMenuStorage.Instance.Save(); } + if (keyword == "uninstalleverything") + { + Result r = new Result(); + r.Title = "Uninstall Everything"; + r.SubTitle = "You need to uninstall everything service if you can not move/delete wox folder"; + r.IcoPath = "Images\\find.png"; + r.Action = (c) => + { + UnInstallEverything(); + return true; + }; + r.Score = 2000; + results.Add(r); + } + try { var searchList = api.Search(keyword, maxCount: ContextMenuStorage.Instance.MaxSearchCount).ToList(); @@ -142,7 +157,7 @@ namespace Wox.Plugin.Everything private void StartEverything() { - if (!CheckEverythingSericeRunning()) + if (!CheckEverythingServiceRunning()) { if (InstallAndRunEverythingService()) { @@ -174,6 +189,31 @@ namespace Wox.Plugin.Everything } } + private bool UnInstallEverything() + { + try + { + Process p = new Process(); + p.StartInfo.Verb = "runas"; + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + p.StartInfo.FileName = GetEverythingPath(); + p.StartInfo.UseShellExecute = true; + p.StartInfo.Arguments = "-uninstall-service"; + p.Start(); + + Process[] proc = Process.GetProcessesByName("Everything"); + foreach (Process process in proc) + { + process.Kill(); + } + return true; + } + catch (Exception e) + { + return false; + } + } + private void StartEverythingClient() { try @@ -191,7 +231,7 @@ namespace Wox.Plugin.Everything } } - private bool CheckEverythingSericeRunning() + private bool CheckEverythingServiceRunning() { try { From 8d3364474945d0d3bf9f9167bca3a1f9ac1db31c Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Sun, 8 Feb 2015 21:25:59 +0800 Subject: [PATCH 20/26] Add a new theme --- Wox/Themes/Gray.xaml | 47 ++++++++++++++++++++++++++++++++++++++++++++ Wox/Wox.csproj | 5 +++++ 2 files changed, 52 insertions(+) create mode 100644 Wox/Themes/Gray.xaml diff --git a/Wox/Themes/Gray.xaml b/Wox/Themes/Gray.xaml new file mode 100644 index 000000000..0593357f7 --- /dev/null +++ b/Wox/Themes/Gray.xaml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + #00AAF6 + + + + diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 2122a7bb6..90937cd00 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -254,6 +254,11 @@ Designer PreserveNewest + + MSBuild:Compile + Designer + PreserveNewest + Designer MSBuild:Compile From b8f829dbc32a48d5ee8aa807e35bda75b190baaa Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 9 Feb 2015 00:13:08 +0800 Subject: [PATCH 21/26] Add item number [WIP] --- Wox/Images/menu.png | Bin 346 -> 0 bytes Wox/ResultPanel.xaml | 5 ++-- Wox/ResultPanel.xaml.cs | 55 +++++++++++++++++++++++++++++++++++----- Wox/Themes/Base.xaml | 12 ++++++--- Wox/Themes/Gray.xaml | 3 +++ Wox/Wox.csproj | 3 --- 6 files changed, 62 insertions(+), 16 deletions(-) delete mode 100644 Wox/Images/menu.png diff --git a/Wox/Images/menu.png b/Wox/Images/menu.png deleted file mode 100644 index d7395f4d9fbc9552f63ae80b8e9dc81a69b108d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 346 zcmV-g0j2(lP)_i805%p8yo?|oB#pKyMEoD$5(D2??fPI~X5lx?yjd1S(T#}CbWF9F zrs)#L@$(2B1i^#P^GxfyQkG@3EQ@l00V~FFWGGzMm5(|CE6TE@JkKSJ&ghER^KHdH z^`0ZDsycBbkmq^Y9)Oh|K=43U(gVw~499V3pF~xhb84FA&4*!N*fR`6>ib?fzReZ$`bwr$gHrm76XpfpVxZ`)RS;QKyxU8fviz>2!A1sqM1MEeS0 snQ5B$?S$7O9&AlsO!xo)*GGT>03%omcdi7(3jhEB07*qoM6N<$f@>X-X#fBK diff --git a/Wox/ResultPanel.xaml b/Wox/ResultPanel.xaml index a3ada3cd3..f22120520 100644 --- a/Wox/ResultPanel.xaml +++ b/Wox/ResultPanel.xaml @@ -24,7 +24,7 @@ - + @@ -36,13 +36,12 @@ - + - diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index 341c08e12..c52367f69 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -130,21 +130,58 @@ namespace Wox public List GetVisibleResults() { - var theStackPanel = GetInnerStackPanel(lbResults); List visibleElements = new List(); - - for (int i = 0; i < theStackPanel.Children.Count; i++) + VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); + for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) { - - if (i >= theStackPanel.VerticalOffset && i <= theStackPanel.VerticalOffset + theStackPanel.ViewportHeight) + ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; + if (item != null) { - FrameworkElement element = theStackPanel.Children[i] as FrameworkElement; - visibleElements.Add(element.DataContext as Result); + visibleElements.Add(item.DataContext as Result); } } return visibleElements; } + private void UpdateItemNumber() + { + VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); + int index = 0; + for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) + { + index++; + ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; + if (item != null) + { + ContentPresenter myContentPresenter = FindVisualChild(item); + if (myContentPresenter != null) + { + DataTemplate dataTemplate = myContentPresenter.ContentTemplate; + TextBlock tbItemNumber = (TextBlock)dataTemplate.FindName("tbItemNumber", myContentPresenter); + tbItemNumber.Text = index.ToString(); + } + } + } + } + + + private childItem FindVisualChild(DependencyObject obj) where childItem : DependencyObject + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) + { + DependencyObject child = VisualTreeHelper.GetChild(obj, i); + if (child != null && child is childItem) + return (childItem)child; + else + { + childItem childOfChild = FindVisualChild(child); + if (childOfChild != null) + return childOfChild; + } + } + return null; + } + private VirtualizingStackPanel GetInnerStackPanel(FrameworkElement element) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) @@ -189,6 +226,10 @@ namespace Wox if (e.AddedItems.Count > 0 && e.AddedItems[0] != null) { lbResults.ScrollIntoView(e.AddedItems[0]); + Dispatcher.DelayInvoke("UpdateItemNumber", o => + { + UpdateItemNumber(); + }, TimeSpan.FromMilliseconds(3)); } } diff --git a/Wox/Themes/Base.xaml b/Wox/Themes/Base.xaml index afaf5bb9a..39866e052 100644 --- a/Wox/Themes/Base.xaml +++ b/Wox/Themes/Base.xaml @@ -38,6 +38,12 @@ + + diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 90937cd00..0a3a843e2 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -334,9 +334,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From a942882c7374f5e38abb390872336c1804c737ed Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 9 Feb 2015 19:16:13 +0800 Subject: [PATCH 22/26] Add QueryHistory to Wox (Ctrl+Up and Ctrl+Down) --- .../Wox.Plugin.QueryHistory/QueryHistory.cs | 2 - Wox.CrashReporter/ReportWindow.xaml.cs | 19 ++- Wox.Plugin/IPublicAPI.cs | 12 +- Wox.sln | 7 - Wox/App.config | 4 - Wox/Images/history.png | Bin 0 -> 4219 bytes Wox/MainWindow.xaml.cs | 115 ++++++++++------ Wox/Properties/AssemblyInfo.cs | 2 +- Wox/ResultPanel.xaml | 2 +- Wox/ResultPanel.xaml.cs | 35 +++-- Wox/Storage/QueryHistoryStorage.cs | 126 ++++++++++++++++++ Wox/Wox.csproj | 2 + 12 files changed, 232 insertions(+), 94 deletions(-) create mode 100644 Wox/Images/history.png create mode 100644 Wox/Storage/QueryHistoryStorage.cs diff --git a/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs b/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs index 7f74a9e0b..838e08bfe 100644 --- a/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs +++ b/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs @@ -34,8 +34,6 @@ namespace Wox.Plugin.QueryHistory public void Init(PluginInitContext context) { this.context = context; - context.API.AfterWoxQueryEvent += API_AfterWoxQueryEvent; - context.API.BeforeWoxQueryEvent += API_BeforeWoxQueryEvent; } void API_BeforeWoxQueryEvent(WoxQueryEventArgs e) diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index c5a7d1a57..67c8b1d1a 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -55,13 +55,18 @@ namespace Wox.CrashReporter private void SendReport() { - string reproduceSteps = - new TextRange(tbReproduceSteps.Document.ContentStart, tbReproduceSteps.Document.ContentEnd).Text; - exception.ToExceptionless() - .SetUserDescription(reproduceSteps) - .Submit(); - ExceptionlessClient.Current.ProcessQueue(); - Close(); + ThreadPool.QueueUserWorkItem(o => + { + string reproduceSteps = new TextRange(tbReproduceSteps.Document.ContentStart, tbReproduceSteps.Document.ContentEnd).Text; + exception.ToExceptionless() + .SetUserDescription(reproduceSteps) + .Submit(); + ExceptionlessClient.Current.ProcessQueue(); + Dispatcher.Invoke(new Action(() => + { + Close(); + })); + }); } private void btnCancel_Click(object sender, RoutedEventArgs e) diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index 3b2691177..7928440ad 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -46,7 +46,7 @@ namespace Wox.Plugin /// Just change the query text, this won't raise search ///
/// - void ChangeQueryText(string query); + void ChangeQueryText(string query, bool selectAll = false); /// /// Close Wox @@ -122,16 +122,6 @@ namespace Wox.Plugin /// event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; - /// - /// Fired after wox execute a query - /// - event AfterWoxQueryEventHandler AfterWoxQueryEvent; - - /// - /// Fired before wox start to execute a query - /// - event AfterWoxQueryEventHandler BeforeWoxQueryEvent; - /// /// Fired after drop to result item of current plugin /// diff --git a/Wox.sln b/Wox.sln index 1759a11e0..07ab868b2 100644 --- a/Wox.sln +++ b/Wox.sln @@ -39,8 +39,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Color", "Plugins EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.CrashReporter", "Wox.CrashReporter\Wox.CrashReporter.csproj", "{2FEB2298-7653-4009-B1EA-FFFB1A768BCC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.QueryHistory", "Plugins\Wox.Plugin.QueryHistory\Wox.Plugin.QueryHistory.csproj", "{B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UpdateFeedGenerator", "Wox.UpdateFeedGenerator\Wox.UpdateFeedGenerator.csproj", "{D120E62B-EC59-4FB4-8129-EFDD4C446A5F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Everything", "Plugins\Wox.Plugin.Everything\Wox.Plugin.Everything.csproj", "{230AE83F-E92E-4E69-8355-426B305DA9C0}" @@ -119,10 +117,6 @@ Global {2FEB2298-7653-4009-B1EA-FFFB1A768BCC}.Debug|Any CPU.Build.0 = Debug|Any CPU {2FEB2298-7653-4009-B1EA-FFFB1A768BCC}.Release|Any CPU.ActiveCfg = Release|Any CPU {2FEB2298-7653-4009-B1EA-FFFB1A768BCC}.Release|Any CPU.Build.0 = Release|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Release|Any CPU.Build.0 = Release|Any CPU {D120E62B-EC59-4FB4-8129-EFDD4C446A5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D120E62B-EC59-4FB4-8129-EFDD4C446A5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D120E62B-EC59-4FB4-8129-EFDD4C446A5F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -147,7 +141,6 @@ Global {0B9DE348-9361-4940-ADB6-F5953BFFCCEC} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {A3DCCBCA-ACC1-421D-B16E-210896234C26} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {F35190AA-4758-4D9E-A193-E3BDF6AD3567} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {230AE83F-E92E-4E69-8355-426B305DA9C0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} EndGlobalSection EndGlobal diff --git a/Wox/App.config b/Wox/App.config index ab8b3cde5..55ab1e0d9 100644 --- a/Wox/App.config +++ b/Wox/App.config @@ -1,8 +1,5 @@ - -
- @@ -12,5 +9,4 @@ - \ No newline at end of file diff --git a/Wox/Images/history.png b/Wox/Images/history.png new file mode 100644 index 0000000000000000000000000000000000000000..6bb070398fdac483d4a9a5d6ce14440334efd927 GIT binary patch literal 4219 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 { ignoreTextChange = true; tbQuery.Text = query; tbQuery.CaretIndex = tbQuery.Text.Length; + if (selectAll) + { + tbQuery.SelectAll(); + } })); } @@ -144,8 +148,6 @@ namespace Wox public event WoxKeyDownEventHandler BackKeyDownEvent; public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; - public event AfterWoxQueryEventHandler AfterWoxQueryEvent; - public event AfterWoxQueryEventHandler BeforeWoxQueryEvent; public event ResultItemDropEventHandler ResultItemDropEvent; public void PushResults(Query query, PluginMetadata plugin, List results) @@ -433,7 +435,6 @@ namespace Wox queryHasReturn = false; Query query = new Query(lastQuery); query.IsIntantQuery = searchDelay == 0; - FireBeforeWoxQueryEvent(query); Query(query); Dispatcher.DelayInvoke("ShowProgressbar", originQuery => { @@ -442,10 +443,15 @@ namespace Wox StartProgress(); } }, TimeSpan.FromMilliseconds(150), tbQuery.Text); - FireAfterWoxQueryEvent(query); + //reset query history index after user start new query + ResetQueryHistoryIndex(); }, TimeSpan.FromMilliseconds(searchDelay)); } + private void ResetQueryHistoryIndex() + { + QueryHistoryStorage.Instance.Reset(); + } private int GetSearchDelay(string query) { if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantQuery(query)) @@ -458,38 +464,6 @@ namespace Wox return 200; } - private void FireAfterWoxQueryEvent(Query q) - { - if (AfterWoxQueryEvent != null) - { - //We shouldn't let those events slow down real query - //so I put it in the new thread - ThreadPool.QueueUserWorkItem(o => - { - AfterWoxQueryEvent(new WoxQueryEventArgs() - { - Query = q - }); - }); - } - } - - private void FireBeforeWoxQueryEvent(Query q) - { - if (BeforeWoxQueryEvent != null) - { - //We shouldn't let those events slow down real query - //so I put it in the new thread - ThreadPool.QueueUserWorkItem(o => - { - BeforeWoxQueryEvent(new WoxQueryEventArgs() - { - Query = q - }); - }); - } - } - private void Query(Query q) { PluginManager.Query(q); @@ -544,6 +518,7 @@ namespace Wox Activate(); Focus(); tbQuery.Focus(); + ResetQueryHistoryIndex(); if (selectAll) tbQuery.SelectAll(); } @@ -616,12 +591,26 @@ namespace Wox break; case Key.Down: - SelectNextItem(); + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + DisplayNextQuery(); + } + else + { + SelectNextItem(); + } e.Handled = true; break; case Key.Up: - SelectPrevItem(); + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + DisplayPrevQuery(); + } + else + { + SelectPrevItem(); + } e.Handled = true; break; @@ -703,6 +692,40 @@ namespace Wox } } + private void DisplayPrevQuery() + { + var prev = QueryHistoryStorage.Instance.Previous(); + DisplayQueryHistory(prev); + } + + private void DisplayNextQuery() + { + var nextQuery = QueryHistoryStorage.Instance.Next(); + DisplayQueryHistory(nextQuery); + } + + private void DisplayQueryHistory(HistoryItem history) + { + if (history != null) + { + ChangeQueryText(history.Query, true); + pnlResult.Dirty = true; + UpdateResultViewInternal(new List() + { + new Result(){ + Title = "Execute " + history.Query+ " query", + SubTitle = "Last Execute Time: " + history.ExecutedDateTime, + IcoPath = "Images\\history.png", + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ =>{ + ChangeQuery(history.Query,true); + return false; + } + } + }); + } + } + private void SelectItem(int index) { int zeroBasedIndex = index - 1; @@ -775,6 +798,7 @@ namespace Wox HideWox(); } UserSelectedRecordStorage.Instance.Add(result); + QueryHistoryStorage.Instance.Add(tbQuery.Text); } } } @@ -792,13 +816,18 @@ namespace Wox o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; }); List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); - Dispatcher.Invoke(new Action(() => - { - pnlResult.AddResults(l); - })); + UpdateResultViewInternal(l); } } + private void UpdateResultViewInternal(List list) + { + Dispatcher.Invoke(new Action(() => + { + pnlResult.AddResults(list); + })); + } + private Result GetTopMostContextMenu(Result result) { if (TopMostRecordStorage.Instance.IsTopMost(result)) diff --git a/Wox/Properties/AssemblyInfo.cs b/Wox/Properties/AssemblyInfo.cs index cfddac76a..b4d5aea91 100644 --- a/Wox/Properties/AssemblyInfo.cs +++ b/Wox/Properties/AssemblyInfo.cs @@ -20,4 +20,4 @@ using System.Windows; )] [assembly: AssemblyVersion("1.1.0")] [assembly: AssemblyFileVersion("1.1.0")] -[assembly: Exceptionless.Configuration.Exceptionless("13462a93b5e843c7bae7da13a86bc00b", EnableLogging = true, LogPath = "E:\\exceptionless.log")] \ No newline at end of file +[assembly: Exceptionless.Configuration.Exceptionless("e0b256fbe9384498ba89aae2a6b7f8ab")] \ No newline at end of file diff --git a/Wox/ResultPanel.xaml b/Wox/ResultPanel.xaml index f22120520..26b18f4f1 100644 --- a/Wox/ResultPanel.xaml +++ b/Wox/ResultPanel.xaml @@ -24,7 +24,7 @@ - + diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index c52367f69..21251bb01 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -145,26 +145,25 @@ namespace Wox private void UpdateItemNumber() { - VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); - int index = 0; - for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) - { - index++; - ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; - if (item != null) - { - ContentPresenter myContentPresenter = FindVisualChild(item); - if (myContentPresenter != null) - { - DataTemplate dataTemplate = myContentPresenter.ContentTemplate; - TextBlock tbItemNumber = (TextBlock)dataTemplate.FindName("tbItemNumber", myContentPresenter); - tbItemNumber.Text = index.ToString(); - } - } - } + //VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); + //int index = 0; + //for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) + //{ + // index++; + // ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; + // if (item != null) + // { + // ContentPresenter myContentPresenter = FindVisualChild(item); + // if (myContentPresenter != null) + // { + // DataTemplate dataTemplate = myContentPresenter.ContentTemplate; + // TextBlock tbItemNumber = (TextBlock)dataTemplate.FindName("tbItemNumber", myContentPresenter); + // tbItemNumber.Text = index.ToString(); + // } + // } + //} } - private childItem FindVisualChild(DependencyObject obj) where childItem : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) diff --git a/Wox/Storage/QueryHistoryStorage.cs b/Wox/Storage/QueryHistoryStorage.cs new file mode 100644 index 000000000..d39ebaad1 --- /dev/null +++ b/Wox/Storage/QueryHistoryStorage.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Newtonsoft.Json; +using Wox.Infrastructure.Storage; + +namespace Wox.Storage +{ + public class QueryHistoryStorage : JsonStrorage + { + [JsonProperty] + private List History = new List(); + + private int MaxHistory = 300; + private int cursor = 0; + + protected override string ConfigFolder + { + get { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Config"); } + } + + protected override string ConfigName + { + get { return "QueryHistory"; } + } + + public HistoryItem Previous() + { + if (History.Count == 0 || cursor == 0) return null; + return History[--cursor]; + } + + public HistoryItem Next() + { + if (History.Count == 0 || cursor >= History.Count - 1) return null; + return History[++cursor]; + } + + public void Reset() + { + cursor = History.Count; + } + + public void Add(string query) + { + if (string.IsNullOrEmpty(query)) return; + if (History.Count > MaxHistory) + { + History.RemoveAt(0); + } + + if (History.Count > 0 && History.Last().Query == query) + { + History.Last().ExecutedDateTime = DateTime.Now; + } + else + { + History.Add(new HistoryItem() + { + Query = query, + ExecutedDateTime = DateTime.Now + }); + } + + if (History.Count % 5 == 0) + { + Save(); + } + + Reset(); + } + + public List GetHistory() + { + return History.OrderByDescending(o => o.ExecutedDateTime).ToList(); + } + } + + public class HistoryItem + { + public string Query { get; set; } + public DateTime ExecutedDateTime { get; set; } + + public string GetTimeAgo() + { + return DateTimeAgo(ExecutedDateTime); + } + + private string DateTimeAgo(DateTime dt) + { + TimeSpan span = DateTime.Now - dt; + if (span.Days > 365) + { + int years = (span.Days / 365); + if (span.Days % 365 != 0) + years += 1; + return String.Format("about {0} {1} ago", + years, years == 1 ? "year" : "years"); + } + if (span.Days > 30) + { + int months = (span.Days / 30); + if (span.Days % 31 != 0) + months += 1; + return String.Format("about {0} {1} ago", + months, months == 1 ? "month" : "months"); + } + if (span.Days > 0) + return String.Format("about {0} {1} ago", + span.Days, span.Days == 1 ? "day" : "days"); + if (span.Hours > 0) + return String.Format("about {0} {1} ago", + span.Hours, span.Hours == 1 ? "hour" : "hours"); + if (span.Minutes > 0) + return String.Format("about {0} {1} ago", + span.Minutes, span.Minutes == 1 ? "minute" : "minutes"); + if (span.Seconds > 5) + return String.Format("about {0} seconds ago", span.Seconds); + if (span.Seconds <= 5) + return "just now"; + return string.Empty; + } + } +} diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 0a3a843e2..5795de7ba 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -123,6 +123,7 @@ + @@ -194,6 +195,7 @@ PreserveNewest + Designer MSBuild:Compile From 3652394dabb23c9f880b4609a51fd5cacf4f8cb3 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 9 Feb 2015 21:34:29 +0800 Subject: [PATCH 23/26] Update version --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 429a0011e..90e4a3550 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 1.1.1.{build} +version: 1.2.0.{build} configuration: Release From eafce4442c36c54c0345336063efb83e50a47d9c Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 9 Feb 2015 21:59:23 +0800 Subject: [PATCH 24/26] Change project generate sequence --- Wox.sln | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Wox.sln b/Wox.sln index 07ab868b2..4fa783561 100644 --- a/Wox.sln +++ b/Wox.sln @@ -10,6 +10,22 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox", "Wox\Wox.csproj", "{DB90F671-D861-46BB-93A3-F1304F5BA1C5}" + ProjectSection(ProjectDependencies) = postProject + {D120E62B-EC59-4FB4-8129-EFDD4C446A5F} = {D120E62B-EC59-4FB4-8129-EFDD4C446A5F} + {230AE83F-E92E-4E69-8355-426B305DA9C0} = {230AE83F-E92E-4E69-8355-426B305DA9C0} + {1EE20B48-82FB-48A2-8086-675D6DDAB4F0} = {1EE20B48-82FB-48A2-8086-675D6DDAB4F0} + {0B9DE348-9361-4940-ADB6-F5953BFFCCEC} = {0B9DE348-9361-4940-ADB6-F5953BFFCCEC} + {FDB3555B-58EF-4AE6-B5F1-904719637AB4} = {FDB3555B-58EF-4AE6-B5F1-904719637AB4} + {FF742965-9A80-41A5-B042-D6C7D3A21708} = {FF742965-9A80-41A5-B042-D6C7D3A21708} + {59BD9891-3837-438A-958D-ADC7F91F6F7E} = {59BD9891-3837-438A-958D-ADC7F91F6F7E} + {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} + {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {787B8AA6-CA93-4C84-96FE-DF31110AD1C4} + {F35190AA-4758-4D9E-A193-E3BDF6AD3567} = {F35190AA-4758-4D9E-A193-E3BDF6AD3567} + {FDED22C8-B637-42E8-824A-63B5B6E05A3A} = {FDED22C8-B637-42E8-824A-63B5B6E05A3A} + {A3DCCBCA-ACC1-421D-B16E-210896234C26} = {A3DCCBCA-ACC1-421D-B16E-210896234C26} + {049490F0-ECD2-4148-9B39-2135EC346EBE} = {049490F0-ECD2-4148-9B39-2135EC346EBE} + {403B57F2-1856-4FC7-8A24-36AB346B763E} = {403B57F2-1856-4FC7-8A24-36AB346B763E} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Infrastructure", "Wox.Infrastructure\Wox.Infrastructure.csproj", "{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3}" EndProject From e767cee4c0dc02b7a4add19357278a0d09e7b1f1 Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 9 Feb 2015 22:14:38 +0800 Subject: [PATCH 25/26] Update query history language --- Wox/Languages/en.xaml | 4 +++- Wox/Languages/zh-cn.xaml | 3 ++- Wox/Languages/zh-tw.xaml | 4 +++- Wox/MainWindow.xaml.cs | 6 ++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Wox/Languages/en.xaml b/Wox/Languages/en.xaml index 1fdea4f03..aaa5953d3 100644 --- a/Wox/Languages/en.xaml +++ b/Wox/Languages/en.xaml @@ -7,8 +7,10 @@ Invalid wox plugin file format Set as topmost in this query Cancel topmost in this query - + Execute query:{0} + Last execute time:{0} + Wox Settings General diff --git a/Wox/Languages/zh-cn.xaml b/Wox/Languages/zh-cn.xaml index 977c44799..7b2d632de 100644 --- a/Wox/Languages/zh-cn.xaml +++ b/Wox/Languages/zh-cn.xaml @@ -7,7 +7,8 @@ 不是合法的Wox插件格式 在当前查询中置顶 取消置顶 - + 执行查询:{0} + 上次执行时间:{0} Wox设置 diff --git a/Wox/Languages/zh-tw.xaml b/Wox/Languages/zh-tw.xaml index 79cc35b51..1e3d40e82 100644 --- a/Wox/Languages/zh-tw.xaml +++ b/Wox/Languages/zh-tw.xaml @@ -7,7 +7,9 @@ 不是合法的Wox插件格式 在當前查詢中置頂 取消置頂 - + 執行查詢:{0} + 上次執行時間:{0} + Wox設置 通用 diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index e04fd218c..dafc53f4a 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -710,11 +710,13 @@ namespace Wox { ChangeQueryText(history.Query, true); pnlResult.Dirty = true; + var executeQueryHistoryTitle = GetTranslation("executeQuery"); + var lastExecuteTime = GetTranslation("lastExecuteTime"); UpdateResultViewInternal(new List() { new Result(){ - Title = "Execute " + history.Query+ " query", - SubTitle = "Last Execute Time: " + history.ExecutedDateTime, + Title = string.Format(executeQueryHistoryTitle,history.Query), + SubTitle = string.Format(lastExecuteTime,history.ExecutedDateTime), IcoPath = "Images\\history.png", PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Action = _ =>{ From 815d911143f0eb88fb6d62d0d1aee12f72265b2f Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Tue, 10 Feb 2015 23:48:09 +0800 Subject: [PATCH 26/26] Add log for storage crashing --- Wox.Core/UserSettings/UserSettingStorage.cs | 9 +-------- Wox.CrashReporter/ReportWindow.xaml.cs | 1 + Wox.Infrastructure/Storage/BinaryStorage.cs | 3 ++- Wox/Wox.csproj | 1 + 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Wox.Core/UserSettings/UserSettingStorage.cs b/Wox.Core/UserSettings/UserSettingStorage.cs index 436cfaf70..ff2cc107a 100644 --- a/Wox.Core/UserSettings/UserSettingStorage.cs +++ b/Wox.Core/UserSettings/UserSettingStorage.cs @@ -130,14 +130,7 @@ namespace Wox.Core.UserSettings OpacityMode = OpacityMode.Normal; LeaveCmdOpen = false; HideWhenDeactive = false; - CustomPluginHotkeys = new List() - { - new CustomPluginHotkey() - { - ActionKeyword = "history ", - Hotkey = "Alt + H" - } - }; + CustomPluginHotkeys = new List(); return this; } diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index 67c8b1d1a..ff948f795 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -55,6 +55,7 @@ namespace Wox.CrashReporter private void SendReport() { + Hide(); ThreadPool.QueueUserWorkItem(o => { string reproduceSteps = new TextRange(tbReproduceSteps.Document.ContentStart, tbReproduceSteps.Document.ContentEnd).Text; diff --git a/Wox.Infrastructure/Storage/BinaryStorage.cs b/Wox.Infrastructure/Storage/BinaryStorage.cs index 7651ca770..9ad13bfaf 100644 --- a/Wox.Infrastructure/Storage/BinaryStorage.cs +++ b/Wox.Infrastructure/Storage/BinaryStorage.cs @@ -56,8 +56,9 @@ namespace Wox.Infrastructure.Storage } } } - catch (Exception) + catch (Exception e) { + Log.Error(e); serializedObject = LoadDefault(); #if (DEBUG) { diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 5795de7ba..8ea87a58e 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -122,6 +122,7 @@ +