mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Merge branch 'master' of https://github.com/qianlifeng/Wox.git
This commit is contained in:
@@ -23,53 +23,36 @@ namespace Wox.Plugin.Doc
|
||||
List<Result> results = new List<Result>();
|
||||
if (query.ActionParameters.Count == 0)
|
||||
{
|
||||
results.Add(new Result()
|
||||
{
|
||||
Title = "Current supported docs:"
|
||||
});
|
||||
results.AddRange(docs.Select(o => new Result()
|
||||
{
|
||||
Title = o.Name.Replace(".docset", ""),
|
||||
Title = o.Name.Replace(".docset", "").Replace(" ",""),
|
||||
IcoPath = o.IconPath
|
||||
}).ToList());
|
||||
return results;
|
||||
}
|
||||
|
||||
if (query.ActionParameters.Count >= 2)
|
||||
{
|
||||
Doc firstOrDefault = docs.FirstOrDefault(o => o.Name.Replace(".docset", "").Replace(" ","").ToLower() == query.ActionParameters[0]);
|
||||
if (firstOrDefault != null)
|
||||
{
|
||||
results.AddRange(QuerySqllite(firstOrDefault, query.ActionParameters[1]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Doc doc in docs)
|
||||
{
|
||||
results.AddRange(QuerySqllite(doc, query.ActionParameters[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
|
||||
//todo:move to common place
|
||||
var otherCompanyDlls = new DirectoryInfo(context.PluginMetadata.PluginDirecotry).GetFiles("*.dll");
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
||||
{
|
||||
var dll = otherCompanyDlls.FirstOrDefault(fi =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly assembly = Assembly.LoadFile(fi.FullName);
|
||||
return assembly.FullName == args.Name;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (dll == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Assembly.LoadFile(dll.FullName);
|
||||
};
|
||||
|
||||
docsetBasePath = context.PluginMetadata.PluginDirecotry + @"Docset";
|
||||
if (!Directory.Exists(docsetBasePath))
|
||||
Directory.CreateDirectory(docsetBasePath);
|
||||
@@ -110,7 +93,6 @@ namespace Wox.Plugin.Doc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
5
Plugins/Wox.Plugin.Doc/README.md
Normal file
5
Plugins/Wox.Plugin.Doc/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
How to use?
|
||||
|
||||
1. Docset download link:[http://kapeli.com/docset_links](http://kapeli.com/docset_links)
|
||||
2. Unzip doc zip into "Plugins\Doc\Docset\{docname}"
|
||||
3. Restart Wox
|
||||
@@ -83,6 +83,7 @@
|
||||
<None Include="plugin.ini">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="README.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
|
||||
@@ -101,7 +102,7 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\Doc\</PostBuildEvent>
|
||||
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
21
Plugins/Wox.Plugin.DotnetPluginTest/Main.cs
Normal file
21
Plugins/Wox.Plugin.DotnetPluginTest/Main.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Wox.Plugin.DotnetPluginTest
|
||||
{
|
||||
public class Main : IPlugin
|
||||
{
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
return new List<Result>();
|
||||
}
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
var s = JsonSerializer.Create();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的常规信息通过以下
|
||||
// 特性集控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Wox.Plugin.DotnetPluginTest")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Wox.Plugin.DotnetPluginTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 使此程序集中的类型
|
||||
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
|
||||
// 则将该类型上的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("62685493-1710-4c1d-a179-cf466a44f45e")]
|
||||
|
||||
// 程序集的版本信息由下面四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
|
||||
// 方法是按如下所示使用“*”:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Wox.Plugin.DotnetPluginTest</RootNamespace>
|
||||
<AssemblyName>Wox.Plugin.DotnetPluginTest</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.6.0.1\lib\net35\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
|
||||
<Project>{8451ecdd-2ea4-4966-bb0a-7bbc40138e80}</Project>
|
||||
<Name>Wox.Plugin</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="plugin.ini">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
4
Plugins/Wox.Plugin.DotnetPluginTest/packages.config
Normal file
4
Plugins/Wox.Plugin.DotnetPluginTest/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net35" />
|
||||
</packages>
|
||||
8
Plugins/Wox.Plugin.DotnetPluginTest/plugin.ini
Normal file
8
Plugins/Wox.Plugin.DotnetPluginTest/plugin.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[plugin]
|
||||
ActionKeyword = ts
|
||||
Name = dotnet test
|
||||
Author = qianlifeng
|
||||
Version = 0.1
|
||||
Language = csharp
|
||||
Description = test
|
||||
ExecuteFile = Wox.Plugin.DotnetPluginTest.dll
|
||||
@@ -16,7 +16,7 @@
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Wox\bin\Debug\Plugins\Everything\</OutputPath>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
@@ -81,10 +81,9 @@
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /Y $(TargetDir)$(TargetFileName) $(SolutionDir)Wox\bin\Debug\Plugins\Everything\
|
||||
xcopy /Y $(TargetDir)plugin.ini $(SolutionDir)Wox\bin\Debug\Plugins\Everything\
|
||||
xcopy /Y $(ProjectDir)x86\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\Everything\x86\
|
||||
xcopy /Y $(ProjectDir)x64\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\Everything\x64\</PostBuildEvent>
|
||||
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\
|
||||
xcopy /Y $(ProjectDir)x86\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\x86\
|
||||
xcopy /Y $(ProjectDir)x64\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\x64\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -69,9 +69,7 @@
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /Y $(TargetDir)$(TargetFileName) $(SolutionDir)Wox\bin\Debug\Plugins\Fanyi\
|
||||
xcopy /Y $(TargetDir)plugin.ini $(SolutionDir)Wox\bin\Debug\Plugins\Fanyi\
|
||||
xcopy /Y $(ProjectDir)Images\*.* $(SolutionDir)Wox\bin\Debug\Plugins\Fanyi\Images\</PostBuildEvent>
|
||||
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -27,7 +27,7 @@ def query(key):
|
||||
pass
|
||||
return json.dumps(results)
|
||||
|
||||
def killProcess(pid):
|
||||
def killProcess(context,pid):
|
||||
p = psutil.Process(int(pid))
|
||||
if p:
|
||||
p.kill()
|
||||
|
||||
@@ -27,7 +27,7 @@ def query(key):
|
||||
results.append(res)
|
||||
return json.dumps(results)
|
||||
|
||||
def openUrl(url):
|
||||
def openUrl(context,url):
|
||||
webbrowser.open(url)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -22,4 +22,4 @@ Currently, Wox support using C# and Python to write your plugins. Please refer t
|
||||
Share plugin
|
||||
=========
|
||||
|
||||
Share your plugin through <a href="http://plugin.getwox.com/">WoxPlugins</a>. After you upload your plugin, other uses can download or search your plugin through `plugin` command (this is a plugin for plugin management, which is one of the default plugins inside Wox).
|
||||
Share your plugin through <a href="http://www.getwox.com/plugin">WoxPlugins</a>. After you upload your plugin, other uses can download or search your plugin through `plugin` command (this is a plugin for plugin management, which is one of the default plugins inside Wox).
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace Wox.Infrastructure
|
||||
Instance.UserSetting.Theme = "Default";
|
||||
Instance.UserSetting.ReplaceWinR = true;
|
||||
Instance.UserSetting.WebSearches = Instance.UserSetting.LoadDefaultWebSearches();
|
||||
Instance.UserSetting.Hotkey = "Alt + Space";
|
||||
}
|
||||
|
||||
public static CommonStorage Instance
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Helper
|
||||
namespace Wox.Infrastructure
|
||||
{
|
||||
public enum KeyEvent : int
|
||||
{
|
||||
@@ -29,13 +29,11 @@ namespace Wox.Helper
|
||||
WM_SYSKEYDOWN = 260
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Listens keyboard globally.
|
||||
/// <remarks>Uses WH_KEYBOARD_LL.</remarks>
|
||||
/// </summary>
|
||||
public class KeyboardListener : IDisposable
|
||||
public class GloablHotkey : IDisposable
|
||||
{
|
||||
private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc;
|
||||
private IntPtr hookId = IntPtr.Zero;
|
||||
@@ -48,7 +46,7 @@ namespace Wox.Helper
|
||||
private const int VK_ALT = 0x12;
|
||||
private const int VK_WIN = 91;
|
||||
|
||||
public KeyboardListener()
|
||||
public GloablHotkey()
|
||||
{
|
||||
// We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime
|
||||
hookedLowLevelKeyboardProc = LowLevelKeyboardProc;
|
||||
@@ -107,7 +105,7 @@ namespace Wox.Helper
|
||||
return (IntPtr)1;
|
||||
}
|
||||
|
||||
~KeyboardListener()
|
||||
~GloablHotkey()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
@@ -153,37 +151,6 @@ namespace Wox.Helper
|
||||
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
|
||||
}
|
||||
|
||||
public enum InputType
|
||||
{
|
||||
INPUT_MOUSE = 0,
|
||||
INPUT_KEYBOARD = 1,
|
||||
INPUT_HARDWARE = 2,
|
||||
}
|
||||
[Flags()]
|
||||
public enum MOUSEEVENTF
|
||||
{
|
||||
MOVE = 0x0001, //mouse move
|
||||
LEFTDOWN = 0x0002, //left button down
|
||||
LEFTUP = 0x0004, //left button up
|
||||
RIGHTDOWN = 0x0008, //right button down
|
||||
RIGHTUP = 0x0010, //right button up
|
||||
MIDDLEDOWN = 0x0020, //middle button down
|
||||
MIDDLEUP = 0x0040, //middle button up
|
||||
XDOWN = 0x0080, //x button down
|
||||
XUP = 0x0100, //x button down
|
||||
WHEEL = 0x0800, //wheel button rolled
|
||||
VIRTUALDESK = 0x4000, //map to entire virtual desktop
|
||||
ABSOLUTE = 0x8000, //absolute move
|
||||
}
|
||||
|
||||
[Flags()]
|
||||
public enum KEYEVENTF
|
||||
{
|
||||
EXTENDEDKEY = 0x0001,
|
||||
KEYUP = 0x0002,
|
||||
UNICODE = 0x0004,
|
||||
SCANCODE = 0x0008,
|
||||
}
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct INPUT
|
||||
{
|
||||
126
Wox.Infrastructure/HotkeyModel.cs
Normal file
126
Wox.Infrastructure/HotkeyModel.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
namespace Wox.Infrastructure
|
||||
{
|
||||
public class HotkeyModel
|
||||
{
|
||||
public bool Alt { get; set; }
|
||||
public bool Shift { get; set; }
|
||||
public bool Win { get; set; }
|
||||
public bool Ctrl { get; set; }
|
||||
public Key CharKey { get; set; }
|
||||
|
||||
public ModifierKeys ModifierKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
ModifierKeys modifierKeys = ModifierKeys.None;
|
||||
if (Alt)
|
||||
{
|
||||
modifierKeys = ModifierKeys.Alt;
|
||||
}
|
||||
if (Shift)
|
||||
{
|
||||
modifierKeys = modifierKeys | ModifierKeys.Shift;
|
||||
}
|
||||
if (Win)
|
||||
{
|
||||
modifierKeys = modifierKeys | ModifierKeys.Windows;
|
||||
}
|
||||
if (Ctrl)
|
||||
{
|
||||
modifierKeys = modifierKeys | ModifierKeys.Control;
|
||||
}
|
||||
return modifierKeys;
|
||||
}
|
||||
}
|
||||
|
||||
public HotkeyModel() { }
|
||||
|
||||
public HotkeyModel(string hotkeyString)
|
||||
{
|
||||
ParseHotkey(hotkeyString);
|
||||
}
|
||||
|
||||
public HotkeyModel(bool alt, bool shift, bool win, bool ctrl, Key key)
|
||||
{
|
||||
Alt = alt;
|
||||
Shift = shift;
|
||||
Win = win;
|
||||
Ctrl = ctrl;
|
||||
CharKey = key;
|
||||
}
|
||||
|
||||
private void ParseHotkey(string hotkeyString)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hotkeyString))
|
||||
{
|
||||
List<string> keys = hotkeyString.Replace(" ", "").Split('+').ToList();
|
||||
if (keys.Contains("Alt"))
|
||||
{
|
||||
Alt = true;
|
||||
keys.Remove("Alt");
|
||||
}
|
||||
if (keys.Contains("Shift"))
|
||||
{
|
||||
Shift = true;
|
||||
keys.Remove("Shift");
|
||||
}
|
||||
if (keys.Contains("Win"))
|
||||
{
|
||||
Win = true;
|
||||
keys.Remove("Win");
|
||||
}
|
||||
if (keys.Contains("Ctrl"))
|
||||
{
|
||||
Ctrl = true;
|
||||
keys.Remove("Ctrl");
|
||||
}
|
||||
if (keys.Count > 0)
|
||||
{
|
||||
string charKey = keys[0];
|
||||
try
|
||||
{
|
||||
CharKey = (Key)Enum.Parse(typeof(Key), charKey);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string text = string.Empty;
|
||||
if (Ctrl)
|
||||
{
|
||||
text += "Ctrl";
|
||||
}
|
||||
if (Alt)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Alt" : " + Alt";
|
||||
}
|
||||
if (Shift)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Shift" : " + Shift";
|
||||
}
|
||||
if (Win)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Win" : " + Win";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(CharKey.ToString()))
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? CharKey.ToString() : " + " + CharKey;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Wox.Infrastructure/UserSettings/PluginHotkey.cs
Normal file
13
Wox.Infrastructure/UserSettings/PluginHotkey.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Wox.Infrastructure.UserSettings
|
||||
{
|
||||
public class CustomPluginHotkey
|
||||
{
|
||||
public string Hotkey { get; set; }
|
||||
public string ActionKeyword { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,11 @@ namespace Wox.Infrastructure.UserSettings
|
||||
{
|
||||
public class UserSetting
|
||||
{
|
||||
public string Hotkey { get; set; }
|
||||
public string Theme { get; set; }
|
||||
public bool ReplaceWinR { get; set; }
|
||||
public List<WebSearch> WebSearches { get; set; }
|
||||
|
||||
public List<CustomPluginHotkey> CustomPluginHotkeys { get; set; }
|
||||
public bool StartWoxOnSystemStartup { get; set; }
|
||||
|
||||
public List<WebSearch> LoadDefaultWebSearches()
|
||||
|
||||
@@ -50,9 +50,12 @@
|
||||
<Compile Include="ChineseToPinYin.cs" />
|
||||
<Compile Include="CommonStorage.cs" />
|
||||
<Compile Include="FuzzyMatcher.cs" />
|
||||
<Compile Include="GloablHotkey.cs" />
|
||||
<Compile Include="HotkeyModel.cs" />
|
||||
<Compile Include="IniParser.cs" />
|
||||
<Compile Include="UAC.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UserSettings\PluginHotkey.cs" />
|
||||
<Compile Include="UserSettings\UserSelectedRecords.cs" />
|
||||
<Compile Include="UserSettings\UserSetting.cs" />
|
||||
<Compile Include="UserSettings\WebSearch.cs" />
|
||||
|
||||
33
Wox.sln
33
Wox.sln
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
VisualStudioVersion = 12.0.30110.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Test", "Wox.Test\Wox.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}"
|
||||
EndProject
|
||||
@@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Everything", "Pl
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC.csproj", "{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.DotnetPluginTest", "Plugins\Wox.Plugin.DotnetPluginTest\Wox.Plugin.DotnetPluginTest.csproj", "{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -346,6 +348,34 @@ Global
|
||||
{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}.UnitTests|Win32.ActiveCfg = Release|Any CPU
|
||||
{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}.UnitTests|x64.ActiveCfg = Release|Any CPU
|
||||
{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}.UnitTests|x86.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|Any CPU.Build.0 = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|Win32.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|x64.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.EmbeddingTest|x86.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|Any CPU.Build.0 = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|Win32.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|x64.ActiveCfg = Release|Any CPU
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}.UnitTests|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -354,5 +384,6 @@ Global
|
||||
{353769D3-D11C-4D86-BD06-AC8C1D68642B} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
|
||||
{6B6696B1-A547-4FD4-85EF-E1FD0F54AD2C} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
|
||||
{230AE83F-E92E-4E69-8355-426B305DA9C0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
|
||||
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
35
Wox/CustomPluginHotkeySetting.xaml
Normal file
35
Wox/CustomPluginHotkeySetting.xaml
Normal file
@@ -0,0 +1,35 @@
|
||||
<Window x:Class="Wox.CustomPluginHotkeySetting"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:wox="clr-namespace:Wox"
|
||||
Icon="Images\app.png"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="Custom Plugin Hotkey" Height="200" Width="674.766">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150"></ColumnDefinition>
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Hotkey:</TextBlock>
|
||||
<wox:HotkeyControl x:Name="ctlHotkey" Margin="10" Grid.Column="1" />
|
||||
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Action Keyword:</TextBlock>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Grid.Column="1" >
|
||||
<TextBox x:Name="tbAction" Margin="10" Width="400" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
|
||||
<Button x:Name="btnTestActionKeyword" Padding="10 5 10 5" Height="30" Click="BtnTestActionKeyword_OnClick">Test</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1">
|
||||
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="25">Cancel</Button>
|
||||
<Button x:Name="btnAdd" Margin="10 0 10 0" Width="80" Height="25" Click="btnAdd_OnClick">
|
||||
<TextBlock x:Name="lblAdd">Add</TextBlock>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
111
Wox/CustomPluginHotkeySetting.xaml.cs
Normal file
111
Wox/CustomPluginHotkeySetting.xaml.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.UserSettings;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class CustomPluginHotkeySetting : Window
|
||||
{
|
||||
private SettingWidow settingWidow;
|
||||
private bool update;
|
||||
private CustomPluginHotkey updateCustomHotkey;
|
||||
|
||||
|
||||
public CustomPluginHotkeySetting(SettingWidow settingWidow)
|
||||
{
|
||||
this.settingWidow = settingWidow;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnAdd_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!update)
|
||||
{
|
||||
if (!ctlHotkey.CurrentHotkeyAvailable)
|
||||
{
|
||||
MessageBox.Show("Hotkey is unavailable, please select a new hotkey");
|
||||
return;
|
||||
}
|
||||
|
||||
if (CommonStorage.Instance.UserSetting.CustomPluginHotkeys == null)
|
||||
{
|
||||
CommonStorage.Instance.UserSetting.CustomPluginHotkeys = new List<CustomPluginHotkey>();
|
||||
}
|
||||
|
||||
var pluginHotkey = new CustomPluginHotkey()
|
||||
{
|
||||
Hotkey = ctlHotkey.CurrentHotkey.ToString(),
|
||||
ActionKeyword = tbAction.Text
|
||||
};
|
||||
CommonStorage.Instance.UserSetting.CustomPluginHotkeys.Add(pluginHotkey);
|
||||
settingWidow.MainWindow.SetHotkey(ctlHotkey.CurrentHotkey.ToString(), delegate
|
||||
{
|
||||
settingWidow.MainWindow.ShowApp();
|
||||
settingWidow.MainWindow.ChangeQuery(pluginHotkey.ActionKeyword);
|
||||
});
|
||||
MessageBox.Show("Add hotkey successfully!");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (updateCustomHotkey.Hotkey != ctlHotkey.CurrentHotkey.ToString() && !ctlHotkey.CurrentHotkeyAvailable)
|
||||
{
|
||||
MessageBox.Show("Hotkey is unavailable, please select a new hotkey");
|
||||
return;
|
||||
}
|
||||
var oldHotkey = updateCustomHotkey.Hotkey;
|
||||
updateCustomHotkey.ActionKeyword = tbAction.Text;
|
||||
updateCustomHotkey.Hotkey = ctlHotkey.CurrentHotkey.ToString();
|
||||
//remove origin hotkey
|
||||
settingWidow.MainWindow.RemoveHotkey(oldHotkey);
|
||||
settingWidow.MainWindow.SetHotkey(updateCustomHotkey.Hotkey, delegate
|
||||
{
|
||||
settingWidow.MainWindow.ShowApp();
|
||||
settingWidow.MainWindow.ChangeQuery(updateCustomHotkey.ActionKeyword);
|
||||
});
|
||||
MessageBox.Show("Update successfully!");
|
||||
}
|
||||
|
||||
CommonStorage.Instance.Save();
|
||||
settingWidow.ReloadCustomPluginHotkeyView();
|
||||
Close();
|
||||
}
|
||||
|
||||
public void UpdateItem(CustomPluginHotkey item)
|
||||
{
|
||||
updateCustomHotkey = CommonStorage.Instance.UserSetting.CustomPluginHotkeys.FirstOrDefault(o => o.ActionKeyword == item.ActionKeyword && o.Hotkey == item.Hotkey);
|
||||
if (updateCustomHotkey == null)
|
||||
{
|
||||
MessageBox.Show("Invalid plugin hotkey");
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
tbAction.Text = updateCustomHotkey.ActionKeyword;
|
||||
ctlHotkey.SetHotkey(updateCustomHotkey.Hotkey, false);
|
||||
update = true;
|
||||
lblAdd.Text = "Update";
|
||||
}
|
||||
|
||||
private void BtnTestActionKeyword_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
settingWidow.MainWindow.ShowApp();
|
||||
settingWidow.MainWindow.ChangeQuery(tbAction.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public sealed class KeyboardHook : IDisposable
|
||||
{
|
||||
// Registers a hot key with Windows.
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
|
||||
// Unregisters the hot key with Windows.
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
/// <summary>
|
||||
/// Represents the window that is used internally to get the messages.
|
||||
/// </summary>
|
||||
private class Window : NativeWindow, IDisposable
|
||||
{
|
||||
private static int wmHotkey = 0x0312;
|
||||
|
||||
public Window()
|
||||
{
|
||||
// create the handle for the window.
|
||||
CreateHandle(new CreateParams());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to get the notifications.
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
base.WndProc(ref m);
|
||||
|
||||
// check if we got a hot key pressed.
|
||||
if (m.Msg == wmHotkey)
|
||||
{
|
||||
// get the keys.
|
||||
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
|
||||
XModifierKeys xModifier = (XModifierKeys)((int)m.LParam & 0xFFFF);
|
||||
|
||||
// invoke the event to notify the parent.
|
||||
if (KeyPressed != null)
|
||||
KeyPressed(this, new KeyPressedEventArgs(xModifier, key));
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<KeyPressedEventArgs> KeyPressed;
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DestroyHandle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
private Window window = new Window();
|
||||
private int currentId;
|
||||
|
||||
public KeyboardHook()
|
||||
{
|
||||
// register the event of the inner native window.
|
||||
window.KeyPressed += delegate(object sender, KeyPressedEventArgs args)
|
||||
{
|
||||
if (KeyPressed != null)
|
||||
KeyPressed(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a hot key in the system.
|
||||
/// </summary>
|
||||
/// <param name="xModifier">The modifiers that are associated with the hot key.</param>
|
||||
/// <param name="key">The key itself that is associated with the hot key.</param>
|
||||
public void RegisterHotKey(XModifierKeys xModifier, Keys key)
|
||||
{
|
||||
// increment the counter.
|
||||
currentId = currentId + 1;
|
||||
|
||||
// register the hot key.
|
||||
if (!RegisterHotKey(window.Handle, currentId, (uint)xModifier, (uint)key))
|
||||
{
|
||||
Log.Error("Couldn’t register the hot key.");
|
||||
MessageBox.Show("Couldn’t register the hot key.");
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new InvalidOperationException("Couldn’t register the hot key.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A hot key has been pressed.
|
||||
/// </summary>
|
||||
public event EventHandler<KeyPressedEventArgs> KeyPressed;
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// unregister all the registered hot keys.
|
||||
for (int i = currentId; i > 0; i--)
|
||||
{
|
||||
UnregisterHotKey(window.Handle, i);
|
||||
}
|
||||
|
||||
// dispose the inner native window.
|
||||
window.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event Args for the event that is fired after the hot key has been pressed.
|
||||
/// </summary>
|
||||
public class KeyPressedEventArgs : EventArgs
|
||||
{
|
||||
private XModifierKeys xModifier;
|
||||
private Keys key;
|
||||
|
||||
internal KeyPressedEventArgs(XModifierKeys xModifier, Keys key)
|
||||
{
|
||||
this.xModifier = xModifier;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public XModifierKeys XModifier
|
||||
{
|
||||
get { return xModifier; }
|
||||
}
|
||||
|
||||
public Keys Key
|
||||
{
|
||||
get { return key; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The enumeration of possible modifiers.
|
||||
/// </summary>
|
||||
public enum XModifierKeys : uint
|
||||
{
|
||||
Alt = 1,
|
||||
Control = 2,
|
||||
Shift = 4,
|
||||
Win = 8
|
||||
}
|
||||
}
|
||||
14
Wox/Helper/WoxPythonException.cs
Normal file
14
Wox/Helper/WoxPythonException.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public class WoxPythonException : WoxException
|
||||
{
|
||||
public WoxPythonException(string msg) : base(msg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Wox/HotkeyControl.xaml
Normal file
17
Wox/HotkeyControl.xaml
Normal file
@@ -0,0 +1,17 @@
|
||||
<UserControl x:Class="Wox.HotkeyControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
Height="24"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150"></ColumnDefinition>
|
||||
<ColumnDefinition Width="120"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="tbHotkey" TabIndex="100" VerticalContentAlignment="Center" Grid.Column="0" PreviewKeyDown="TbHotkey_OnPreviewKeyDown"></TextBox>
|
||||
<TextBlock x:Name="tbMsg" Visibility="Hidden" Margin="5 0 0 0" VerticalAlignment="Center" Grid.Column="1" ></TextBlock>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
140
Wox/HotkeyControl.xaml.cs
Normal file
140
Wox/HotkeyControl.xaml.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using NHotkey;
|
||||
using NHotkey.Wpf;
|
||||
using Wox.Helper;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Plugin;
|
||||
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class HotkeyControl : UserControl
|
||||
{
|
||||
public HotkeyModel CurrentHotkey { get; private set; }
|
||||
public bool CurrentHotkeyAvailable { get; private set; }
|
||||
|
||||
public event EventHandler OnHotkeyChanged;
|
||||
|
||||
protected virtual void OnOnHotkeyChanged()
|
||||
{
|
||||
EventHandler handler = OnHotkeyChanged;
|
||||
if (handler != null) handler(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public HotkeyControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void TbHotkey_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
tbMsg.Visibility = Visibility.Hidden;
|
||||
|
||||
//when alt is pressed, the real key should be e.SystemKey
|
||||
Key key = (e.Key == Key.System ? e.SystemKey : e.Key);
|
||||
|
||||
string text = string.Empty;
|
||||
SpecialKeyState specialKeyState = new GloablHotkey().CheckModifiers();
|
||||
if (specialKeyState.AltPressed)
|
||||
{
|
||||
text += "Alt";
|
||||
}
|
||||
if (specialKeyState.CtrlPressed)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Ctrl" : " + Ctrl";
|
||||
}
|
||||
if (specialKeyState.ShiftPressed)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Shift" : " + Shift";
|
||||
}
|
||||
if (specialKeyState.WinPressed)
|
||||
{
|
||||
text += string.IsNullOrEmpty(text) ? "Win" : " + Win";
|
||||
}
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
text += "Ctrl + Alt";
|
||||
}
|
||||
|
||||
if (IsKeyACharOrNumber(key))
|
||||
{
|
||||
text += " + " + key;
|
||||
}
|
||||
else if (key == Key.Space)
|
||||
{
|
||||
text += " + Space";
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (text == tbHotkey.Text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher.DelayInvoke("HotkeyAvailableTest", o => SetHotkey(text), TimeSpan.FromMilliseconds(300));
|
||||
}
|
||||
|
||||
public void SetHotkey(string keyStr, bool triggerValidate = true)
|
||||
{
|
||||
tbMsg.Visibility = Visibility.Visible;
|
||||
tbHotkey.Text = keyStr;
|
||||
tbHotkey.Select(tbHotkey.Text.Length, 0);
|
||||
CurrentHotkey = new HotkeyModel(keyStr);
|
||||
|
||||
if (triggerValidate)
|
||||
{
|
||||
CurrentHotkeyAvailable = CheckHotAvailabel(CurrentHotkey);
|
||||
if (!CurrentHotkeyAvailable)
|
||||
{
|
||||
tbMsg.Foreground = new SolidColorBrush(Colors.Red);
|
||||
tbMsg.Text = "hotkey unavailable";
|
||||
}
|
||||
else
|
||||
{
|
||||
tbMsg.Foreground = new SolidColorBrush(Colors.Green);
|
||||
tbMsg.Text = "succeed";
|
||||
}
|
||||
OnOnHotkeyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckHotAvailabel(HotkeyModel hotkey)
|
||||
{
|
||||
try
|
||||
{
|
||||
HotkeyManager.Current.AddOrReplace("HotkeyAvailableTest", hotkey.CharKey, hotkey.ModifierKeys, OnHotkey);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
HotkeyManager.Current.Remove("HotkeyAvailableTest");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnHotkey(object sender, HotkeyEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static bool IsKeyACharOrNumber(Key key)
|
||||
{
|
||||
return (key >= Key.A && key <= Key.Z) || (key >= Key.D0 && key <= Key.D9);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Wox/ImagePathConverter.cs
Normal file
55
Wox/ImagePathConverter.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public class ImagePathConverter : IMultiValueConverter
|
||||
{
|
||||
private static ImageSource GetIcon(string fileName)
|
||||
{
|
||||
Icon icon = Icon.ExtractAssociatedIcon(fileName);
|
||||
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon.Handle,
|
||||
new Int32Rect(0, 0, icon.Width, icon.Height),
|
||||
BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values[0] == null) return null;
|
||||
|
||||
string path = values[0].ToString();
|
||||
string pluginDirectory = values[1].ToString();
|
||||
|
||||
string resolvedPath = string.Empty;
|
||||
if (!string.IsNullOrEmpty(path) && path.Contains(":\\") && File.Exists(path))
|
||||
{
|
||||
resolvedPath = path;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(path) && File.Exists(pluginDirectory + path))
|
||||
{
|
||||
resolvedPath = pluginDirectory + path;
|
||||
}
|
||||
|
||||
if (resolvedPath.ToLower().EndsWith(".exe") || resolvedPath.ToLower().EndsWith(".lnk"))
|
||||
{
|
||||
return GetIcon(resolvedPath);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(path)) return new BitmapImage(new Uri(resolvedPath));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,47 +3,48 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Threading;
|
||||
using WindowsInput;
|
||||
using WindowsInput.Native;
|
||||
using NHotkey;
|
||||
using NHotkey.Wpf;
|
||||
using Wox.Commands;
|
||||
using Wox.Helper;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Infrastructure.UserSettings;
|
||||
using Wox.Plugin;
|
||||
using Wox.PluginLoader;
|
||||
using Application = System.Windows.Application;
|
||||
using ContextMenu = System.Windows.Forms.ContextMenu;
|
||||
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
||||
using MenuItem = System.Windows.Forms.MenuItem;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class MainWindow
|
||||
{
|
||||
private KeyboardHook hook = new KeyboardHook();
|
||||
private static readonly object locker = new object();
|
||||
|
||||
private static readonly List<Result> waitShowResultList = new List<Result>();
|
||||
private readonly GloablHotkey globalHotkey = new GloablHotkey();
|
||||
private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator());
|
||||
private readonly Storyboard progressBarStoryboard = new Storyboard();
|
||||
private bool WinRStroked;
|
||||
private NotifyIcon notifyIcon;
|
||||
Storyboard progressBarStoryboard = new Storyboard();
|
||||
private bool queryHasReturn = false;
|
||||
|
||||
private KeyboardListener keyboardListener = new KeyboardListener();
|
||||
private bool WinRStroked = false;
|
||||
private static object locker = new object();
|
||||
|
||||
private WindowsInput.KeyboardSimulator keyboardSimulator = new WindowsInput.KeyboardSimulator(new WindowsInput.InputSimulator());
|
||||
private bool queryHasReturn;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
InitialTray();
|
||||
hook.KeyPressed += OnHotKey;
|
||||
hook.RegisterHotKey(XModifierKeys.Alt, Keys.Space);
|
||||
resultCtrl.resultItemChangedEvent += resultCtrl_resultItemChangedEvent;
|
||||
|
||||
ThreadPool.SetMaxThreads(30, 10);
|
||||
InitProgressbarAnimation();
|
||||
try
|
||||
@@ -54,13 +55,54 @@ namespace Wox
|
||||
{
|
||||
SetTheme(CommonStorage.Instance.UserSetting.Theme = "Default");
|
||||
}
|
||||
|
||||
this.Closing += MainWindow_Closing;
|
||||
}
|
||||
|
||||
void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
public void SetHotkey(string hotkeyStr, EventHandler<HotkeyEventArgs> action)
|
||||
{
|
||||
e.Cancel = true;
|
||||
var hotkey = new HotkeyModel(hotkeyStr);
|
||||
try
|
||||
{
|
||||
HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
MessageBox.Show("Registe hotkey: " + CommonStorage.Instance.UserSetting.Hotkey + " failed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveHotkey(string hotkeyStr)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hotkeyStr))
|
||||
{
|
||||
HotkeyManager.Current.Remove(hotkeyStr);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCustomPluginHotkey()
|
||||
{
|
||||
if (CommonStorage.Instance.UserSetting.CustomPluginHotkeys == null) return;
|
||||
foreach (CustomPluginHotkey hotkey in CommonStorage.Instance.UserSetting.CustomPluginHotkeys)
|
||||
{
|
||||
CustomPluginHotkey hotkey1 = hotkey;
|
||||
SetHotkey(hotkey.Hotkey, delegate
|
||||
{
|
||||
ShowApp();
|
||||
ChangeQuery(hotkey1.ActionKeyword);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHotkey(object sender, HotkeyEventArgs e)
|
||||
{
|
||||
if (!IsVisible)
|
||||
{
|
||||
ShowWox();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideWox();
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void WakeupApp()
|
||||
@@ -69,7 +111,7 @@ namespace Wox
|
||||
//This is caused by the Virtual Mermory Page Mechanisam. So, our solution is execute some codes in every min
|
||||
//which may prevent sysetem uninstall memory from RAM to disk.
|
||||
|
||||
System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 5) { AutoReset = true, Enabled = true };
|
||||
var t = new Timer(1000 * 60 * 5) { AutoReset = true, Enabled = true };
|
||||
t.Elapsed += (o, e) => Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
if (Visibility != Visibility.Visible)
|
||||
@@ -86,8 +128,8 @@ namespace Wox
|
||||
|
||||
private void InitProgressbarAnimation()
|
||||
{
|
||||
DoubleAnimation da = new DoubleAnimation(progressBar.X2, Width + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
|
||||
DoubleAnimation da1 = new DoubleAnimation(progressBar.X1, Width, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
|
||||
var da = new DoubleAnimation(progressBar.X2, Width + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
|
||||
var da1 = new DoubleAnimation(progressBar.X1, Width, 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);
|
||||
@@ -101,29 +143,12 @@ namespace Wox
|
||||
{
|
||||
notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true };
|
||||
notifyIcon.Click += (o, e) => ShowWox();
|
||||
System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Open");
|
||||
var open = new MenuItem("Open");
|
||||
open.Click += (o, e) => ShowWox();
|
||||
System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
|
||||
var exit = new MenuItem("Exit");
|
||||
exit.Click += (o, e) => CloseApp();
|
||||
System.Windows.Forms.MenuItem[] childen = { open, exit };
|
||||
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
|
||||
}
|
||||
|
||||
private void resultCtrl_resultItemChangedEvent()
|
||||
{
|
||||
resultCtrl.Margin = resultCtrl.GetCurrentResultCount() > 0 ? new Thickness { Top = grid.Margin.Top } : new Thickness { Top = 0 };
|
||||
}
|
||||
|
||||
private void OnHotKey(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
if (!IsVisible)
|
||||
{
|
||||
ShowWox();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideWox();
|
||||
}
|
||||
MenuItem[] childen = { open, exit };
|
||||
notifyIcon.ContextMenu = new ContextMenu(childen);
|
||||
}
|
||||
|
||||
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
@@ -153,7 +178,6 @@ namespace Wox
|
||||
}
|
||||
}, TimeSpan.FromSeconds(1), tbQuery.Text);
|
||||
}
|
||||
|
||||
}, TimeSpan.FromMilliseconds(150));
|
||||
}
|
||||
|
||||
@@ -212,10 +236,12 @@ namespace Wox
|
||||
Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2;
|
||||
Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3;
|
||||
|
||||
WakeupApp();
|
||||
SetHotkey(CommonStorage.Instance.UserSetting.Hotkey, OnHotkey);
|
||||
SetCustomPluginHotkey();
|
||||
//WakeupApp();
|
||||
Plugins.Init();
|
||||
|
||||
keyboardListener.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
|
||||
globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
|
||||
}
|
||||
|
||||
private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state)
|
||||
@@ -232,7 +258,7 @@ namespace Wox
|
||||
if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int)Keys.LWin)
|
||||
{
|
||||
WinRStroked = false;
|
||||
keyboardSimulator.ModifiedKeyStroke(WindowsInput.Native.VirtualKeyCode.LWIN, WindowsInput.Native.VirtualKeyCode.CONTROL);
|
||||
keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.CONTROL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -283,11 +309,18 @@ namespace Wox
|
||||
Result result = resultCtrl.AcceptSelect();
|
||||
if (result != null)
|
||||
{
|
||||
CommonStorage.Instance.UserSelectedRecords.Add(result);
|
||||
if (!result.DontHideWoxAfterSelect)
|
||||
{
|
||||
HideWox();
|
||||
}
|
||||
if (result.Action != null)
|
||||
{
|
||||
result.Action(new ActionContext()
|
||||
{
|
||||
SpecialKeyState = new GloablHotkey().CheckModifiers()
|
||||
});
|
||||
CommonStorage.Instance.UserSelectedRecords.Add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,24 +331,27 @@ namespace Wox
|
||||
if (list.Count > 0)
|
||||
{
|
||||
//todo:this should be opened to users, it's their choise to use it or not in thier workflows
|
||||
list.ForEach(o =>
|
||||
list.ForEach(
|
||||
o =>
|
||||
{
|
||||
if (o.AutoAjustScore) o.Score += CommonStorage.Instance.UserSelectedRecords.GetSelectedCount(o);
|
||||
});
|
||||
lock (locker)
|
||||
{
|
||||
resultCtrl.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
List<Result> l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
|
||||
resultCtrl.AddResults(list);
|
||||
}));
|
||||
waitShowResultList.AddRange(list);
|
||||
}
|
||||
Dispatcher.DelayInvoke("ShowResult", k => resultCtrl.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
List<Result> l =waitShowResultList.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
|
||||
waitShowResultList.Clear();
|
||||
resultCtrl.AddResults(l);
|
||||
})), TimeSpan.FromMilliseconds(50));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTheme(string themeName)
|
||||
{
|
||||
ResourceDictionary dict = new ResourceDictionary
|
||||
var dict = new ResourceDictionary
|
||||
{
|
||||
Source = new Uri("pack://application:,,,/Themes/" + themeName + ".xaml")
|
||||
};
|
||||
@@ -326,8 +362,6 @@ namespace Wox
|
||||
|
||||
#region Public API
|
||||
|
||||
//Those method can be invoked by plugins
|
||||
|
||||
public void ChangeQuery(string query)
|
||||
{
|
||||
tbQuery.Text = query;
|
||||
@@ -337,6 +371,7 @@ namespace Wox
|
||||
public void CloseApp()
|
||||
{
|
||||
notifyIcon.Visible = false;
|
||||
Close();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
@@ -352,14 +387,13 @@ namespace Wox
|
||||
|
||||
public void ShowMsg(string title, string subTitle, string iconPath)
|
||||
{
|
||||
Msg m = new Msg { Owner = GetWindow(this) };
|
||||
var m = new Msg { Owner = GetWindow(this) };
|
||||
m.Show(title, subTitle, iconPath);
|
||||
}
|
||||
|
||||
public void OpenSettingDialog()
|
||||
{
|
||||
SettingWidow s = new SettingWidow(this);
|
||||
s.Show();
|
||||
new SettingWidow(this).Show();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
@@ -20,7 +21,7 @@ namespace Wox.PluginLoader
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly asm = Assembly.LoadFile(metadata.ExecuteFilePath);
|
||||
Assembly asm = Assembly.Load(AssemblyName.GetAssemblyName(metadata.ExecuteFilePath));
|
||||
List<Type> types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && (o.BaseType == typeof(BaseSystemPlugin) || o.GetInterfaces().Contains(typeof(IPlugin)))).ToList();
|
||||
if (types.Count == 0)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using Python.Runtime;
|
||||
using Wox.Plugin;
|
||||
using Wox.Helper;
|
||||
|
||||
namespace Wox.PluginLoader
|
||||
{
|
||||
@@ -11,6 +12,8 @@ namespace Wox.PluginLoader
|
||||
{
|
||||
public override List<PluginPair> LoadPlugin()
|
||||
{
|
||||
if (!CheckPythonEnvironmentInstalled()) return new List<PluginPair>();
|
||||
|
||||
List<PluginPair> plugins = new List<PluginPair>();
|
||||
List<PluginMetadata> metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.Python.ToUpper()).ToList();
|
||||
foreach (PluginMetadata metadata in metadatas)
|
||||
@@ -26,5 +29,18 @@ namespace Wox.PluginLoader
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
private bool CheckPythonEnvironmentInstalled() {
|
||||
try
|
||||
{
|
||||
PythonEngine.Initialize();
|
||||
PythonEngine.Shutdown();
|
||||
}
|
||||
catch {
|
||||
Log.Error("Could't find python environment, all python plugins disabled.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Documents;
|
||||
using Newtonsoft.Json;
|
||||
using Python.Runtime;
|
||||
using Wox.Helper;
|
||||
@@ -13,7 +10,6 @@ namespace Wox.PluginLoader
|
||||
{
|
||||
public class PythonPluginWrapper : IPlugin
|
||||
{
|
||||
|
||||
private PluginMetadata metadata;
|
||||
private string moduleName;
|
||||
|
||||
@@ -40,19 +36,20 @@ namespace Wox.PluginLoader
|
||||
PythonResult ps = pythonResult;
|
||||
if (!string.IsNullOrEmpty(ps.ActionName))
|
||||
{
|
||||
ps.Action = (context) => InvokeFunc(ps.ActionName, GetPythonActionContext(context),new PyString(ps.ActionPara));
|
||||
ps.Action = (context) => InvokeFunc(ps.ActionName, GetPythonActionContext(context), new PyString(ps.ActionPara));
|
||||
}
|
||||
r.Add(ps);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw;
|
||||
throw new WoxPythonException(e.Message);
|
||||
}
|
||||
#endif
|
||||
Log.Error(string.Format("Python Plugin {0} query failed: {1}", metadata.Name, e.Message));
|
||||
}
|
||||
|
||||
return new List<Result>();
|
||||
@@ -73,16 +70,38 @@ namespace Wox.PluginLoader
|
||||
|
||||
private string InvokeFunc(string func, params PyObject[] paras)
|
||||
{
|
||||
string json;
|
||||
string json = null;
|
||||
|
||||
IntPtr gs = PythonEngine.AcquireLock();
|
||||
|
||||
PyObject module = PythonEngine.ImportModule(moduleName);
|
||||
if (module == null)
|
||||
{
|
||||
string error = string.Format("Python Invoke failed: {0} doesn't has module {1}",
|
||||
metadata.ExecuteFilePath, moduleName);
|
||||
Log.Error(error);
|
||||
return json;
|
||||
}
|
||||
|
||||
if (module.HasAttr(func))
|
||||
{
|
||||
try
|
||||
{
|
||||
PyObject res = paras.Length > 0 ? module.InvokeMethod(func, paras) : module.InvokeMethod(func);
|
||||
json = Runtime.GetManagedString(res.Handle);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
string error = string.Format("Python Invoke failed: {0}", e.Message);
|
||||
Log.Error(error);
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new WoxPythonException(error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
string error = string.Format("Python Invoke failed: {0} doesn't has function {1}",
|
||||
@@ -90,7 +109,7 @@ namespace Wox.PluginLoader
|
||||
Log.Error(error);
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new ArgumentException(error);
|
||||
throw new WoxPythonException(error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<UserControl x:Class="Wox.ResultItem"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="400"
|
||||
x:Name="resultItemControl"
|
||||
Style="{DynamicResource ItemStyle}"
|
||||
Height="50">
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5" Cursor="Hand">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="32"></ColumnDefinition>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left" ></Image>
|
||||
<Grid Margin="5 0 5 0" Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition x:Name="SubTitleRowDefinition"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Style="{DynamicResource ItemTitleStyle}" VerticalAlignment="Center" x:Name="tbTitle">Title</TextBlock>
|
||||
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" Grid.Row="1" x:Name="tbSubTitle">sub title</TextBlock>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,105 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Wox.Annotations;
|
||||
using Wox.Helper;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Plugin;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class ResultItem : UserControl, INotifyPropertyChanged
|
||||
{
|
||||
private bool selected;
|
||||
|
||||
public Result Result { get; private set; }
|
||||
|
||||
public bool Selected
|
||||
{
|
||||
get
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
set
|
||||
{
|
||||
selected = value;
|
||||
OnPropertyChanged("Selected");
|
||||
}
|
||||
}
|
||||
|
||||
public ResultItem(Result result)
|
||||
{
|
||||
InitializeComponent();
|
||||
Result = result;
|
||||
|
||||
tbTitle.Text = result.Title;
|
||||
tbSubTitle.Text = result.SubTitle;
|
||||
if (string.IsNullOrEmpty(result.SubTitle))
|
||||
{
|
||||
SubTitleRowDefinition.Height = new GridLength(0);
|
||||
}
|
||||
string path = string.Empty;
|
||||
if (!string.IsNullOrEmpty(result.IcoPath) && result.IcoPath.Contains(":\\") && File.Exists(result.IcoPath))
|
||||
{
|
||||
path = result.IcoPath;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(result.IcoPath) && File.Exists(result.PluginDirectory + result.IcoPath))
|
||||
{
|
||||
path = result.PluginDirectory + result.IcoPath;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
if (path.ToLower().EndsWith(".exe") || path.ToLower().EndsWith(".lnk"))
|
||||
{
|
||||
imgIco.Source = GetIcon(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
imgIco.Source = new BitmapImage(new Uri(path));
|
||||
}
|
||||
}
|
||||
|
||||
AddHandler(MouseLeftButtonUpEvent, new RoutedEventHandler((o, e) =>
|
||||
{
|
||||
if (Result.Action != null)
|
||||
Result.Action(new ActionContext()
|
||||
{
|
||||
SpecialKeyState = new KeyboardListener().CheckModifiers()
|
||||
});
|
||||
|
||||
CommonStorage.Instance.UserSelectedRecords.Add(result);
|
||||
if (!result.DontHideWoxAfterSelect)
|
||||
{
|
||||
App.Window.HideApp();
|
||||
}
|
||||
e.Handled = true;
|
||||
}));
|
||||
}
|
||||
|
||||
private static ImageSource GetIcon(string fileName)
|
||||
{
|
||||
Icon icon = Icon.ExtractAssociatedIcon(fileName);
|
||||
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
|
||||
icon.Handle,
|
||||
new Int32Rect(0, 0, icon.Width, icon.Height),
|
||||
BitmapSizeOptions.FromEmptyOptions());
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChangedEventHandler handler = PropertyChanged;
|
||||
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,55 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:wox="clr-namespace:Wox"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<ScrollViewer x:Name="sv" Template="{DynamicResource ScrollViewerControlTemplate}" MaxHeight="300" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel x:Name="pnlContainer"/>
|
||||
</ScrollViewer>
|
||||
<UserControl.Resources>
|
||||
<wox:ImagePathConverter x:Key="ImagePathConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid x:Name="gridContainer">
|
||||
<ListBox x:Name="lbResults" Style="{DynamicResource listboxStyle}" SelectionChanged ="lbResults_SelectionChanged" Focusable="False" KeyboardNavigation.DirectionalNavigation="Cycle" SelectionMode="Single" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
|
||||
<ListBox.Resources>
|
||||
<!--SelectedItem with focus-->
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{DynamicResource ResultItemHighlightBackgroundColor}"/>
|
||||
<!--SelectedItem without focus-->
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{DynamicResource ResultItemHighlightBackgroundColor}"/>
|
||||
</ListBox.Resources>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid HorizontalAlignment="Stretch" Height="40" VerticalAlignment="Stretch" Margin="5" Cursor="Hand">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="32"></ColumnDefinition>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left" >
|
||||
<Image.Source>
|
||||
<MultiBinding Converter="{StaticResource ImagePathConverter}">
|
||||
<MultiBinding.Bindings>
|
||||
<Binding Path="IcoPath" />
|
||||
<Binding Path="PluginDirectory" />
|
||||
</MultiBinding.Bindings>
|
||||
</MultiBinding>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Grid Margin="5 0 5 0" Grid.Column="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition Height="Auto" x:Name="SubTitleRowDefinition"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Style="{DynamicResource ItemTitleStyle}" VerticalAlignment="Center" x:Name="tbTitle" Text="{Binding Title}"></TextBlock>
|
||||
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" Visibility="{Binding SubTitle, Converter={wox:StringNullOrEmptyToVisibilityConverter}}" Grid.Row="1" x:Name="tbSubTitle" Text="{Binding SubTitle}"></TextBlock>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
|
||||
<Setter TargetName="tbTitle" Property="Style" Value="{DynamicResource ItemTitleSelectedStyle}"/>
|
||||
<Setter TargetName="tbSubTitle" Property="Style" Value="{DynamicResource ItemSubTitleSelectedStyle}"/>
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Helper;
|
||||
using Wox.Infrastructure;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox
|
||||
@@ -11,70 +13,37 @@ namespace Wox
|
||||
{
|
||||
public bool Dirty { get; set; }
|
||||
|
||||
public delegate void ResultItemsChanged();
|
||||
|
||||
public event ResultItemsChanged resultItemChangedEvent;
|
||||
|
||||
protected virtual void OnResultItemChangedEvent()
|
||||
{
|
||||
ResultItemsChanged handler = resultItemChangedEvent;
|
||||
if (handler != null) handler();
|
||||
}
|
||||
|
||||
public void AddResults(List<Result> results)
|
||||
{
|
||||
if (results.Count == 0) return;
|
||||
|
||||
if (Dirty)
|
||||
{
|
||||
Dirty = false;
|
||||
pnlContainer.Children.Clear();
|
||||
lbResults.Items.Clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
foreach (var result in results)
|
||||
{
|
||||
Result result = results[i];
|
||||
if (!CheckExisted(result))
|
||||
{
|
||||
ResultItem control = new ResultItem(result);
|
||||
pnlContainer.Children.Insert(GetInsertLocation(result.Score), control);
|
||||
int position = GetInsertLocation(result.Score);
|
||||
lbResults.Items.Insert(position, result);
|
||||
}
|
||||
}
|
||||
|
||||
gridContainer.Margin = lbResults.Items.Count > 0 ? new Thickness { Top = 8 } : new Thickness { Top = 0 };
|
||||
SelectFirst();
|
||||
pnlContainer.UpdateLayout();
|
||||
|
||||
double resultItemHeight = 0;
|
||||
if (pnlContainer.Children.Count > 0)
|
||||
{
|
||||
var resultItem = pnlContainer.Children[0] as ResultItem;
|
||||
if (resultItem != null)
|
||||
resultItemHeight = resultItem.ActualHeight;
|
||||
}
|
||||
pnlContainer.Height = pnlContainer.Children.Count * resultItemHeight;
|
||||
OnResultItemChangedEvent();
|
||||
}
|
||||
|
||||
private bool CheckExisted(Result result)
|
||||
{
|
||||
return pnlContainer.Children.Cast<ResultItem>().Any(child => child.Result.Equals(result));
|
||||
}
|
||||
|
||||
private int GetInsertLocation(int currentScore)
|
||||
{
|
||||
int location = pnlContainer.Children.Count;
|
||||
if (pnlContainer.Children.Count == 0) return 0;
|
||||
if (currentScore > ((ResultItem)pnlContainer.Children[0]).Result.Score) return 0;
|
||||
int location = lbResults.Items.Count;
|
||||
if (lbResults.Items.Count == 0) return 0;
|
||||
if (currentScore > ((Result)lbResults.Items[0]).Score) return 0;
|
||||
|
||||
for (int index = 1; index < pnlContainer.Children.Count; index++)
|
||||
for (int index = 1; index < lbResults.Items.Count; index++)
|
||||
{
|
||||
ResultItem next = pnlContainer.Children[index] as ResultItem;
|
||||
ResultItem prev = pnlContainer.Children[index - 1] as ResultItem;
|
||||
Result next = lbResults.Items[index] as Result;
|
||||
Result prev = lbResults.Items[index - 1] as Result;
|
||||
if (next != null && prev != null)
|
||||
{
|
||||
if ((currentScore >= next.Result.Score && currentScore <= prev.Result.Score))
|
||||
if ((currentScore >= next.Score && currentScore <= prev.Score))
|
||||
{
|
||||
if (currentScore == next.Result.Score)
|
||||
if (currentScore == next.Score)
|
||||
{
|
||||
location = index + 1;
|
||||
}
|
||||
@@ -89,40 +58,10 @@ namespace Wox
|
||||
return location;
|
||||
}
|
||||
|
||||
public int GetCurrentResultCount()
|
||||
{
|
||||
return pnlContainer.Children.Count;
|
||||
}
|
||||
|
||||
public int GetCurrentSelectedResultIndex()
|
||||
{
|
||||
for (int i = 0; i < pnlContainer.Children.Count; i++)
|
||||
{
|
||||
var resultItemControl = pnlContainer.Children[i] as ResultItem;
|
||||
if (resultItemControl != null && resultItemControl.Selected)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void UnSelectAll()
|
||||
{
|
||||
for (int i = 0; i < pnlContainer.Children.Count; i++)
|
||||
{
|
||||
var resultItemControl = pnlContainer.Children[i] as ResultItem;
|
||||
if (resultItemControl != null && resultItemControl.Selected)
|
||||
{
|
||||
resultItemControl.Selected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectNext()
|
||||
{
|
||||
int index = GetCurrentSelectedResultIndex();
|
||||
if (index == pnlContainer.Children.Count - 1)
|
||||
int index = lbResults.SelectedIndex;
|
||||
if (index == lbResults.Items.Count - 1)
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
@@ -131,98 +70,33 @@ namespace Wox
|
||||
|
||||
public void SelectPrev()
|
||||
{
|
||||
int index = GetCurrentSelectedResultIndex();
|
||||
int index = lbResults.SelectedIndex;
|
||||
if (index == 0)
|
||||
{
|
||||
index = pnlContainer.Children.Count;
|
||||
index = lbResults.Items.Count;
|
||||
}
|
||||
Select(index - 1);
|
||||
}
|
||||
|
||||
private void Select(int index)
|
||||
{
|
||||
if (pnlContainer.Children.Count > 0)
|
||||
{
|
||||
int oldIndex = GetCurrentSelectedResultIndex();
|
||||
|
||||
UnSelectAll();
|
||||
var resultItemControl = pnlContainer.Children[index] as ResultItem;
|
||||
if (resultItemControl != null)
|
||||
{
|
||||
resultItemControl.Selected = true;
|
||||
|
||||
double scrollPosition = 0;
|
||||
Point newItemBottomPoint = resultItemControl.TranslatePoint(new Point(0, resultItemControl.ActualHeight), pnlContainer);
|
||||
scrollPosition = newItemBottomPoint.Y;
|
||||
if (index == 0)
|
||||
{
|
||||
sv.ScrollToTop();
|
||||
return;
|
||||
}
|
||||
if (index == pnlContainer.Children.Count - 1)
|
||||
{
|
||||
sv.ScrollToBottom();
|
||||
return;
|
||||
}
|
||||
|
||||
if (index < oldIndex)
|
||||
{
|
||||
//move up and old item is at the top of the scroll view
|
||||
var scrollPostionY = sv.VerticalOffset - sv.VerticalOffset%resultItemControl.ActualHeight +
|
||||
resultItemControl.ActualHeight;
|
||||
if (newItemBottomPoint.Y - scrollPostionY == 0)
|
||||
{
|
||||
scrollPosition = sv.VerticalOffset - resultItemControl.ActualHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//move down and old item is at the bottom of scroll view
|
||||
double scrollPostionY = (sv.ActualHeight + sv.VerticalOffset) - (sv.ActualHeight + sv.VerticalOffset)%resultItemControl.ActualHeight;
|
||||
if (scrollPostionY == newItemBottomPoint.Y - resultItemControl.ActualHeight)
|
||||
{
|
||||
scrollPosition = newItemBottomPoint.Y - sv.ActualHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sv.ScrollToVerticalOffset(scrollPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectFirst()
|
||||
private void SelectFirst()
|
||||
{
|
||||
Select(0);
|
||||
}
|
||||
|
||||
private void Select(int index)
|
||||
{
|
||||
if (index >= 0 && index < lbResults.Items.Count)
|
||||
{
|
||||
lbResults.SelectedItem = lbResults.Items.GetItemAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public Result AcceptSelect()
|
||||
{
|
||||
int index = GetCurrentSelectedResultIndex();
|
||||
int index = lbResults.SelectedIndex;
|
||||
if (index < 0) return null;
|
||||
|
||||
var resultItemControl = pnlContainer.Children[index] as ResultItem;
|
||||
if (resultItemControl != null)
|
||||
{
|
||||
if (resultItemControl.Result.Action != null)
|
||||
{
|
||||
resultItemControl.Result.Action(new ActionContext()
|
||||
{
|
||||
SpecialKeyState = new KeyboardListener().CheckModifiers()
|
||||
});
|
||||
}
|
||||
|
||||
return resultItemControl.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
return lbResults.Items[index] as Result;
|
||||
}
|
||||
|
||||
public ResultPanel()
|
||||
@@ -232,9 +106,16 @@ namespace Wox
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
pnlContainer.Children.Clear();
|
||||
pnlContainer.Height = 0;
|
||||
OnResultItemChangedEvent();
|
||||
lbResults.Items.Clear();
|
||||
gridContainer.Margin = new Thickness { Top = 0 };
|
||||
}
|
||||
|
||||
private void lbResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0)
|
||||
{
|
||||
lbResults.ScrollIntoView(e.AddedItems[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<Window x:Class="Wox.SettingWidow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:wox="clr-namespace:Wox"
|
||||
Icon="Images\app.png"
|
||||
Title="Wox Setting"
|
||||
ResizeMode="NoResize"
|
||||
@@ -22,10 +23,55 @@
|
||||
<TextBlock Text="Theme:" />
|
||||
<ComboBox x:Name="themeComboBox" SelectionChanged="ThemeComboBox_OnSelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="Hotkey">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition Height="50"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock VerticalAlignment="Center" Margin="0 0 10 0">Wox Hotkey:</TextBlock>
|
||||
<wox:HotkeyControl x:Name="ctlHotkey"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Vertical" VerticalAlignment="Top">
|
||||
<TextBlock VerticalAlignment="Center" Margin="0 0 10 0">Custom Plugin Hotkey:</TextBlock>
|
||||
<ListView x:Name="lvCustomHotkey" Margin="0 5 0 0">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridView.Columns>
|
||||
<GridViewColumn Header="Hotkey" Width="180">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path= Hotkey}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Action Keyword" Width="500">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path= ActionKeyword}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView.Columns>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button x:Name="btnDeleteCustomHotkey" Click="BtnDeleteCustomHotkey_OnClick" Width="100" Margin="10">Delete</Button>
|
||||
<Button x:Name="btnEditCustomHotkey" Click="BtnEditCustomHotkey_OnClick" Width="100" Margin="10">Edit</Button>
|
||||
<Button x:Name="btnAddCustomeHotkey" Click="BtnAddCustomeHotkey_OnClick" Width="100" Margin="10">Add</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Web Search">
|
||||
<Grid>
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="50"></RowDefinition>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Wox
|
||||
{
|
||||
public partial class SettingWidow : Window
|
||||
{
|
||||
private MainWindow mainWindow;
|
||||
public MainWindow MainWindow;
|
||||
|
||||
public SettingWidow()
|
||||
{
|
||||
@@ -28,9 +28,17 @@ namespace Wox
|
||||
|
||||
public SettingWidow(MainWindow mainWindow)
|
||||
{
|
||||
this.mainWindow = mainWindow;
|
||||
this.MainWindow = mainWindow;
|
||||
InitializeComponent();
|
||||
Loaded += Setting_Loaded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void Setting_Loaded(object sender, RoutedEventArgs ev)
|
||||
{
|
||||
ctlHotkey.OnHotkeyChanged += ctlHotkey_OnHotkeyChanged;
|
||||
ctlHotkey.SetHotkey(CommonStorage.Instance.UserSetting.Hotkey, false);
|
||||
cbReplaceWinR.Checked += (o, e) =>
|
||||
{
|
||||
CommonStorage.Instance.UserSetting.ReplaceWinR = true;
|
||||
@@ -41,10 +49,7 @@ namespace Wox
|
||||
CommonStorage.Instance.UserSetting.ReplaceWinR = false;
|
||||
CommonStorage.Instance.Save();
|
||||
};
|
||||
}
|
||||
|
||||
private void Setting_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
foreach (string theme in LoadAvailableThemes())
|
||||
{
|
||||
string themeName = theme.Substring(theme.LastIndexOf('\\') + 1).Replace(".xaml", "");
|
||||
@@ -54,6 +59,7 @@ namespace Wox
|
||||
themeComboBox.SelectedItem = CommonStorage.Instance.UserSetting.Theme;
|
||||
cbReplaceWinR.IsChecked = CommonStorage.Instance.UserSetting.ReplaceWinR;
|
||||
webSearchView.ItemsSource = CommonStorage.Instance.UserSetting.WebSearches;
|
||||
lvCustomHotkey.ItemsSource = CommonStorage.Instance.UserSetting.CustomPluginHotkeys;
|
||||
cbStartWithWindows.IsChecked = CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup;
|
||||
}
|
||||
|
||||
@@ -71,7 +77,7 @@ namespace Wox
|
||||
private void ThemeComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
string themeName = themeComboBox.SelectedItem.ToString();
|
||||
mainWindow.SetTheme(themeName);
|
||||
MainWindow.SetTheme(themeName);
|
||||
CommonStorage.Instance.UserSetting.Theme = themeName;
|
||||
CommonStorage.Instance.Save();
|
||||
}
|
||||
@@ -79,7 +85,7 @@ namespace Wox
|
||||
private void btnAddWebSearch_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WebSearchSetting webSearch = new WebSearchSetting(this);
|
||||
webSearch.Show();
|
||||
webSearch.ShowDialog();
|
||||
}
|
||||
|
||||
private void btnDeleteWebSearch_OnClick(object sender, RoutedEventArgs e)
|
||||
@@ -104,8 +110,8 @@ namespace Wox
|
||||
if (seletedWebSearch != null)
|
||||
{
|
||||
WebSearchSetting webSearch = new WebSearchSetting(this);
|
||||
webSearch.Show();
|
||||
webSearch.UpdateItem(seletedWebSearch);
|
||||
webSearch.ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -159,6 +165,74 @@ namespace Wox
|
||||
}
|
||||
}
|
||||
|
||||
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(CommonStorage.Instance.UserSetting.Hotkey);
|
||||
CommonStorage.Instance.UserSetting.Hotkey = ctlHotkey.CurrentHotkey.ToString();
|
||||
CommonStorage.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("Are your sure to delete " + item.Hotkey + " plugin hotkey?","Delete Custom Plugin Hotkey",
|
||||
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
CommonStorage.Instance.UserSetting.CustomPluginHotkeys.Remove(item);
|
||||
lvCustomHotkey.Items.Refresh();
|
||||
CommonStorage.Instance.Save();
|
||||
MainWindow.RemoveHotkey(item.Hotkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please select an item");
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnEditCustomHotkey_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
CustomPluginHotkey item = lvCustomHotkey.SelectedItem as CustomPluginHotkey;
|
||||
if (item != null)
|
||||
{
|
||||
CustomPluginHotkeySetting window = new CustomPluginHotkeySetting(this);
|
||||
window.UpdateItem(item);
|
||||
window.ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please select an item");
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnAddCustomeHotkey_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
new CustomPluginHotkeySetting(this).ShowDialog();
|
||||
}
|
||||
|
||||
public void ReloadCustomPluginHotkeyView()
|
||||
{
|
||||
lvCustomHotkey.Items.Refresh();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
26
Wox/StringNullOrEmptyToVisibilityConverter.cs
Normal file
26
Wox/StringNullOrEmptyToVisibilityConverter.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public class StringNullOrEmptyToVisibilityConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return string.IsNullOrEmpty(value as string) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,16 +30,35 @@
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
<Setter Property="FontWeight" Value="Medium" />
|
||||
</Style>
|
||||
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}">
|
||||
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#D9D9D4" />
|
||||
</Style>
|
||||
<Style x:Key="ItemStyle" TargetType="{x:Type UserControl}">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Selected}" Value="true">
|
||||
<Setter Property="Background" Value="#4F6180" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
<Style x:Key="ItemTitleSelectedStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#FFFFF8" />
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
<Setter Property="FontWeight" Value="Medium" />
|
||||
</Style>
|
||||
<Style x:Key="ItemSubTitleSelectedStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#D9D9D4" />
|
||||
</Style>
|
||||
<Color x:Key="ResultItemHighlightBackgroundColor">#4F6180</Color>
|
||||
|
||||
<Style x:Key="listboxStyle" TargetType="{x:Type ListBox}">
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBox">
|
||||
<ScrollViewer Focusable="false" Template="{DynamicResource ScrollViewerControlTemplate}">
|
||||
<StackPanel IsItemsHost="True" />
|
||||
</ScrollViewer>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- ScrollViewer Style -->
|
||||
|
||||
@@ -23,32 +23,42 @@
|
||||
<Setter Property="Stroke" Value="Blue"></Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
<!-- Item Style -->
|
||||
<Style x:Key="ItemTitleStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#141411"></Setter>
|
||||
<Setter Property="FontSize" Value="16"></Setter>
|
||||
<Setter Property="FontWeight" Value="Medium"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=resultItemControl, Path=Selected}" Value="true">
|
||||
<Setter Property="Foreground" Value="#F6F6FF"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#B3B2B0"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=resultItemControl, Path=Selected}" Value="true">
|
||||
<Setter Property="Foreground" Value="#F6F6FF"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="ItemStyle" TargetType="{x:Type UserControl}" >
|
||||
<Setter Property="Background" Value="Transparent"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Selected}" Value="true">
|
||||
<Setter Property="Background" Value="#543BFD"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
<Style x:Key="ItemTitleSelectedStyle" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#F6F6FF" />
|
||||
<Setter Property="FontSize" Value="16"></Setter>
|
||||
<Setter Property="FontWeight" Value="Medium"></Setter>
|
||||
</Style>
|
||||
<Style x:Key="ItemSubTitleSelectedStyle" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#F6F6FF" />
|
||||
</Style>
|
||||
<Color x:Key="ResultItemHighlightBackgroundColor">#543BFD</Color>
|
||||
|
||||
<Style x:Key="listboxStyle" TargetType="{x:Type ListBox}">
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBox">
|
||||
<ScrollViewer Focusable="false" Template="{DynamicResource ScrollViewerControlTemplate}">
|
||||
<StackPanel IsItemsHost="True" />
|
||||
</ScrollViewer>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- ScrollViewer Style -->
|
||||
|
||||
@@ -89,6 +89,12 @@
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NHotkey">
|
||||
<HintPath>..\packages\NHotkey.1.1.0.0\lib\NHotkey.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NHotkey.Wpf">
|
||||
<HintPath>..\packages\NHotkey.Wpf.1.1.0.0\lib\NHotkey.Wpf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||
<Reference Include="ReachFramework" />
|
||||
<Reference Include="System" />
|
||||
@@ -119,12 +125,18 @@
|
||||
<Compile Include="Commands\CommandFactory.cs" />
|
||||
<Compile Include="Commands\PluginCommand.cs" />
|
||||
<Compile Include="Commands\SystemCommand.cs" />
|
||||
<Compile Include="CustomPluginHotkeySetting.xaml.cs">
|
||||
<DependentUpon>CustomPluginHotkeySetting.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="DispatcherExtensions.cs" />
|
||||
<Compile Include="Helper\KeyboardHook.cs" />
|
||||
<Compile Include="Helper\Log.cs" />
|
||||
<Compile Include="Helper\PluginInstaller.cs" />
|
||||
<Compile Include="Helper\WoxException.cs" />
|
||||
<Compile Include="Helper\KeyboardListener.cs" />
|
||||
<Compile Include="Helper\WoxPythonException.cs" />
|
||||
<Compile Include="HotkeyControl.xaml.cs">
|
||||
<DependentUpon>HotkeyControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ImagePathConverter.cs" />
|
||||
<Compile Include="Msg.xaml.cs">
|
||||
<DependentUpon>Msg.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -137,15 +149,21 @@
|
||||
<Compile Include="ResultPanel.xaml.cs">
|
||||
<DependentUpon>ResultPanel.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ResultItem.xaml.cs">
|
||||
<DependentUpon>ResultItem.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SettingWindow.xaml.cs">
|
||||
<DependentUpon>SettingWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="StringNullOrEmptyToVisibilityConverter.cs" />
|
||||
<Compile Include="WebSearchSetting.xaml.cs">
|
||||
<DependentUpon>WebSearchSetting.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="CustomPluginHotkeySetting.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="HotkeyControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
@@ -166,10 +184,6 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="ResultItem.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="SettingWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
<package id="InputSimulator" version="1.0.4.0" targetFramework="net35" />
|
||||
<package id="log4net" version="2.0.3" targetFramework="net35" />
|
||||
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net35" />
|
||||
<package id="NHotkey" version="1.1.0.0" targetFramework="net35" />
|
||||
<package id="NHotkey.Wpf" version="1.1.0.0" targetFramework="net35" />
|
||||
<package id="SharpZipLib" version="0.86.0" targetFramework="net35" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user