diff --git a/Plugins/Wox.Plugin.CMD/CMD.cs b/Plugins/Wox.Plugin.CMD/CMD.cs index f2ed269ee7..b1e003d354 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 8e36ec9257..17a6b84a15 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 0f7418f956..8eb78934eb 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 8ec7599416..fad46efa3f 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 f9c428178b..ac972ff556 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 ff473061c8..75cd0203a0 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 0000000000..0fa42076b9 --- /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 5248cbb57c..8e55230367 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 80f2a52a48..25c14f4bd9 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 d55e678a3f..7cea6f4a7d 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)