This commit is contained in:
qianlifeng
2014-02-24 09:28:55 +08:00
42 changed files with 1238 additions and 687 deletions

View File

@@ -23,53 +23,36 @@ namespace Wox.Plugin.Doc
List<Result> results = new List<Result>(); List<Result> results = new List<Result>();
if (query.ActionParameters.Count == 0) if (query.ActionParameters.Count == 0)
{ {
results.Add(new Result()
{
Title = "Current supported docs:"
});
results.AddRange(docs.Select(o => new Result() results.AddRange(docs.Select(o => new Result()
{ {
Title = o.Name.Replace(".docset", ""), Title = o.Name.Replace(".docset", "").Replace(" ",""),
IcoPath = o.IconPath IcoPath = o.IconPath
}).ToList()); }).ToList());
return results; return results;
} }
foreach (Doc doc in docs) if (query.ActionParameters.Count >= 2)
{ {
results.AddRange(QuerySqllite(doc, query.ActionParameters[0])); 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; return results;
} }
public void Init(PluginInitContext context) 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"; docsetBasePath = context.PluginMetadata.PluginDirecotry + @"Docset";
if (!Directory.Exists(docsetBasePath)) if (!Directory.Exists(docsetBasePath))
Directory.CreateDirectory(docsetBasePath); Directory.CreateDirectory(docsetBasePath);
@@ -110,7 +93,6 @@ namespace Wox.Plugin.Doc
} }
} }
} }
} }
return imagePath; return imagePath;
} }

View 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

View File

@@ -83,6 +83,7 @@
<None Include="plugin.ini"> <None Include="plugin.ini">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="README.md" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj"> <ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
@@ -101,7 +102,7 @@
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <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> </PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <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. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View 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();
}
}
}

View File

@@ -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")]

View File

@@ -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>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net35" />
</packages>

View 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

View File

@@ -16,7 +16,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\..\Wox\bin\Debug\Plugins\Everything\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -81,10 +81,9 @@
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>xcopy /Y $(TargetDir)$(TargetFileName) $(SolutionDir)Wox\bin\Debug\Plugins\Everything\ <PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\
xcopy /Y $(TargetDir)plugin.ini $(SolutionDir)Wox\bin\Debug\Plugins\Everything\ xcopy /Y $(ProjectDir)x86\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\x86\
xcopy /Y $(ProjectDir)x86\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\Everything\x86\ xcopy /Y $(ProjectDir)x64\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\x64\</PostBuildEvent>
xcopy /Y $(ProjectDir)x64\Everything.dll $(SolutionDir)Wox\bin\Debug\Plugins\Everything\x64\</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- 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. Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -69,9 +69,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>xcopy /Y $(TargetDir)$(TargetFileName) $(SolutionDir)Wox\bin\Debug\Plugins\Fanyi\ <PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent>
xcopy /Y $(TargetDir)plugin.ini $(SolutionDir)Wox\bin\Debug\Plugins\Fanyi\
xcopy /Y $(ProjectDir)Images\*.* $(SolutionDir)Wox\bin\Debug\Plugins\Fanyi\Images\</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- 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. Other similar extension points exist, see Microsoft.Common.targets.

View File

@@ -27,7 +27,7 @@ def query(key):
pass pass
return json.dumps(results) return json.dumps(results)
def killProcess(pid): def killProcess(context,pid):
p = psutil.Process(int(pid)) p = psutil.Process(int(pid))
if p: if p:
p.kill() p.kill()

View File

@@ -27,7 +27,7 @@ def query(key):
results.append(res) results.append(res)
return json.dumps(results) return json.dumps(results)
def openUrl(url): def openUrl(context,url):
webbrowser.open(url) webbrowser.open(url)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -22,4 +22,4 @@ Currently, Wox support using C# and Python to write your plugins. Please refer t
Share plugin 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).

View File

@@ -62,6 +62,7 @@ namespace Wox.Infrastructure
Instance.UserSetting.Theme = "Default"; Instance.UserSetting.Theme = "Default";
Instance.UserSetting.ReplaceWinR = true; Instance.UserSetting.ReplaceWinR = true;
Instance.UserSetting.WebSearches = Instance.UserSetting.LoadDefaultWebSearches(); Instance.UserSetting.WebSearches = Instance.UserSetting.LoadDefaultWebSearches();
Instance.UserSetting.Hotkey = "Alt + Space";
} }
public static CommonStorage Instance public static CommonStorage Instance

View File

@@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Wox.Plugin; using Wox.Plugin;
namespace Wox.Helper namespace Wox.Infrastructure
{ {
public enum KeyEvent : int public enum KeyEvent : int
{ {
@@ -29,13 +29,11 @@ namespace Wox.Helper
WM_SYSKEYDOWN = 260 WM_SYSKEYDOWN = 260
} }
/// <summary> /// <summary>
/// Listens keyboard globally. /// Listens keyboard globally.
/// <remarks>Uses WH_KEYBOARD_LL.</remarks> /// <remarks>Uses WH_KEYBOARD_LL.</remarks>
/// </summary> /// </summary>
public class KeyboardListener : IDisposable public class GloablHotkey : IDisposable
{ {
private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc; private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc;
private IntPtr hookId = IntPtr.Zero; private IntPtr hookId = IntPtr.Zero;
@@ -48,7 +46,7 @@ namespace Wox.Helper
private const int VK_ALT = 0x12; private const int VK_ALT = 0x12;
private const int VK_WIN = 91; private const int VK_WIN = 91;
public KeyboardListener() public GloablHotkey()
{ {
// We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime // We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime
hookedLowLevelKeyboardProc = LowLevelKeyboardProc; hookedLowLevelKeyboardProc = LowLevelKeyboardProc;
@@ -107,7 +105,7 @@ namespace Wox.Helper
return (IntPtr)1; return (IntPtr)1;
} }
~KeyboardListener() ~GloablHotkey()
{ {
Dispose(); Dispose();
} }
@@ -153,37 +151,6 @@ namespace Wox.Helper
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize); 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)] [StructLayout(LayoutKind.Explicit)]
public struct INPUT public struct INPUT
{ {

View 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;
}
}
}

View 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; }
}
}

View File

@@ -5,10 +5,11 @@ namespace Wox.Infrastructure.UserSettings
{ {
public class UserSetting public class UserSetting
{ {
public string Hotkey { get; set; }
public string Theme { get; set; } public string Theme { get; set; }
public bool ReplaceWinR { get; set; } public bool ReplaceWinR { get; set; }
public List<WebSearch> WebSearches { get; set; } public List<WebSearch> WebSearches { get; set; }
public List<CustomPluginHotkey> CustomPluginHotkeys { get; set; }
public bool StartWoxOnSystemStartup { get; set; } public bool StartWoxOnSystemStartup { get; set; }
public List<WebSearch> LoadDefaultWebSearches() public List<WebSearch> LoadDefaultWebSearches()

View File

@@ -50,9 +50,12 @@
<Compile Include="ChineseToPinYin.cs" /> <Compile Include="ChineseToPinYin.cs" />
<Compile Include="CommonStorage.cs" /> <Compile Include="CommonStorage.cs" />
<Compile Include="FuzzyMatcher.cs" /> <Compile Include="FuzzyMatcher.cs" />
<Compile Include="GloablHotkey.cs" />
<Compile Include="HotkeyModel.cs" />
<Compile Include="IniParser.cs" /> <Compile Include="IniParser.cs" />
<Compile Include="UAC.cs" /> <Compile Include="UAC.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UserSettings\PluginHotkey.cs" />
<Compile Include="UserSettings\UserSelectedRecords.cs" /> <Compile Include="UserSettings\UserSelectedRecords.cs" />
<Compile Include="UserSettings\UserSetting.cs" /> <Compile Include="UserSettings\UserSetting.cs" />
<Compile Include="UserSettings\WebSearch.cs" /> <Compile Include="UserSettings\WebSearch.cs" />

33
Wox.sln
View File

@@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.21005.1 VisualStudioVersion = 12.0.30110.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Test", "Wox.Test\Wox.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Test", "Wox.Test\Wox.Test.csproj", "{FF742965-9A80-41A5-B042-D6C7D3A21708}"
EndProject EndProject
@@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Everything", "Pl
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC.csproj", "{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC.csproj", "{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}"
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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|Win32.ActiveCfg = Release|Any CPU
{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}.UnitTests|x64.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 {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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -354,5 +384,6 @@ Global
{353769D3-D11C-4D86-BD06-AC8C1D68642B} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {353769D3-D11C-4D86-BD06-AC8C1D68642B} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{6B6696B1-A547-4FD4-85EF-E1FD0F54AD2C} = {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} {230AE83F-E92E-4E69-8355-426B305DA9C0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View 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>

View 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);
}
}
}

View File

@@ -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("Couldnt register the hot key.");
MessageBox.Show("Couldnt register the hot key.");
#if (DEBUG)
{
throw new InvalidOperationException("Couldnt 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
}
}

View 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
View 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
View 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
View 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;
}
}
}

View File

@@ -3,47 +3,48 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Threading; using WindowsInput;
using WindowsInput.Native;
using NHotkey;
using NHotkey.Wpf;
using Wox.Commands; using Wox.Commands;
using Wox.Helper;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Infrastructure.UserSettings;
using Wox.Plugin; using Wox.Plugin;
using Wox.PluginLoader; using Wox.PluginLoader;
using Application = System.Windows.Application; using Application = System.Windows.Application;
using ContextMenu = System.Windows.Forms.ContextMenu;
using KeyEventArgs = System.Windows.Input.KeyEventArgs; using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MenuItem = System.Windows.Forms.MenuItem;
using MessageBox = System.Windows.MessageBox; using MessageBox = System.Windows.MessageBox;
using UserControl = System.Windows.Controls.UserControl; using Timer = System.Timers.Timer;
namespace Wox namespace Wox
{ {
public partial class MainWindow 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; private NotifyIcon notifyIcon;
Storyboard progressBarStoryboard = new Storyboard(); private bool queryHasReturn;
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());
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
InitialTray(); InitialTray();
hook.KeyPressed += OnHotKey;
hook.RegisterHotKey(XModifierKeys.Alt, Keys.Space);
resultCtrl.resultItemChangedEvent += resultCtrl_resultItemChangedEvent;
ThreadPool.SetMaxThreads(30, 10); ThreadPool.SetMaxThreads(30, 10);
InitProgressbarAnimation(); InitProgressbarAnimation();
try try
@@ -54,13 +55,54 @@ namespace Wox
{ {
SetTheme(CommonStorage.Instance.UserSetting.Theme = "Default"); 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() private void WakeupApp()
@@ -69,25 +111,25 @@ namespace Wox
//This is caused by the Virtual Mermory Page Mechanisam. So, our solution is execute some codes in every min //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. //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(() => t.Elapsed += (o, e) => Dispatcher.Invoke(new Action(() =>
{
if (Visibility != Visibility.Visible)
{ {
if (Visibility != Visibility.Visible) double oldLeft = Left;
{ Left = 20000;
double oldLeft = Left; ShowWox();
Left = 20000; CommandFactory.DispatchCommand(new Query("qq"), false);
ShowWox(); HideWox();
CommandFactory.DispatchCommand(new Query("qq"), false); Left = oldLeft;
HideWox(); }
Left = oldLeft; }));
}
}));
} }
private void InitProgressbarAnimation() private void InitProgressbarAnimation()
{ {
DoubleAnimation da = new DoubleAnimation(progressBar.X2, Width + 100, 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)));
DoubleAnimation da1 = new DoubleAnimation(progressBar.X1, Width, 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(da, new PropertyPath("(Line.X2)"));
Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)"));
progressBarStoryboard.Children.Add(da); progressBarStoryboard.Children.Add(da);
@@ -101,60 +143,42 @@ namespace Wox
{ {
notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true };
notifyIcon.Click += (o, e) => ShowWox(); 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(); 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(); exit.Click += (o, e) => CloseApp();
System.Windows.Forms.MenuItem[] childen = { open, exit }; MenuItem[] childen = { open, exit };
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen); notifyIcon.ContextMenu = new 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();
}
} }
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{ {
resultCtrl.Dirty = true; resultCtrl.Dirty = true;
Dispatcher.DelayInvoke("UpdateSearch", Dispatcher.DelayInvoke("UpdateSearch",
o => o =>
{ {
Dispatcher.DelayInvoke("ClearResults", i => Dispatcher.DelayInvoke("ClearResults", i =>
{ {
// first try to use clear method inside resultCtrl, which is more closer to the add new results // first try to use clear method inside resultCtrl, which is more closer to the add new results
// and this will not bring splash issues.After waiting 30ms, if there still no results added, we // and this will not bring splash issues.After waiting 30ms, if there still no results added, we
// must clear the result. otherwise, it will be confused why the query changed, but the results // must clear the result. otherwise, it will be confused why the query changed, but the results
// didn't. // didn't.
if (resultCtrl.Dirty) resultCtrl.Clear(); if (resultCtrl.Dirty) resultCtrl.Clear();
}, TimeSpan.FromMilliseconds(30), null); }, TimeSpan.FromMilliseconds(30), null);
var q = new Query(tbQuery.Text); var q = new Query(tbQuery.Text);
CommandFactory.DispatchCommand(q); CommandFactory.DispatchCommand(q);
queryHasReturn = false; queryHasReturn = false;
if (Plugins.HitThirdpartyKeyword(q)) if (Plugins.HitThirdpartyKeyword(q))
{ {
Dispatcher.DelayInvoke("ShowProgressbar", originQuery => Dispatcher.DelayInvoke("ShowProgressbar", originQuery =>
{ {
if (!queryHasReturn && originQuery == tbQuery.Text) if (!queryHasReturn && originQuery == tbQuery.Text)
{ {
StartProgress(); StartProgress();
} }
}, TimeSpan.FromSeconds(1), tbQuery.Text); }, TimeSpan.FromSeconds(1), tbQuery.Text);
} }
}, TimeSpan.FromMilliseconds(150));
}, TimeSpan.FromMilliseconds(150));
} }
private void StartProgress() private void StartProgress()
@@ -212,10 +236,12 @@ namespace Wox
Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2;
Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3; Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3;
WakeupApp(); SetHotkey(CommonStorage.Instance.UserSetting.Hotkey, OnHotkey);
SetCustomPluginHotkey();
//WakeupApp();
Plugins.Init(); Plugins.Init();
keyboardListener.hookedKeyboardCallback += KListener_hookedKeyboardCallback; globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
} }
private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) 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) if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int)Keys.LWin)
{ {
WinRStroked = false; WinRStroked = false;
keyboardSimulator.ModifiedKeyStroke(WindowsInput.Native.VirtualKeyCode.LWIN, WindowsInput.Native.VirtualKeyCode.CONTROL); keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.CONTROL);
return false; return false;
} }
} }
@@ -283,11 +309,18 @@ namespace Wox
Result result = resultCtrl.AcceptSelect(); Result result = resultCtrl.AcceptSelect();
if (result != null) if (result != null)
{ {
CommonStorage.Instance.UserSelectedRecords.Add(result);
if (!result.DontHideWoxAfterSelect) if (!result.DontHideWoxAfterSelect)
{ {
HideWox(); 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) if (list.Count > 0)
{ {
//todo:this should be opened to users, it's their choise to use it or not in thier workflows //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); {
}); if (o.AutoAjustScore) o.Score += CommonStorage.Instance.UserSelectedRecords.GetSelectedCount(o);
});
lock (locker) lock (locker)
{ {
resultCtrl.Dispatcher.Invoke(new Action(() => waitShowResultList.AddRange(list);
{
List<Result> l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
resultCtrl.AddResults(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) public void SetTheme(string themeName)
{ {
ResourceDictionary dict = new ResourceDictionary var dict = new ResourceDictionary
{ {
Source = new Uri("pack://application:,,,/Themes/" + themeName + ".xaml") Source = new Uri("pack://application:,,,/Themes/" + themeName + ".xaml")
}; };
@@ -326,8 +362,6 @@ namespace Wox
#region Public API #region Public API
//Those method can be invoked by plugins
public void ChangeQuery(string query) public void ChangeQuery(string query)
{ {
tbQuery.Text = query; tbQuery.Text = query;
@@ -337,6 +371,7 @@ namespace Wox
public void CloseApp() public void CloseApp()
{ {
notifyIcon.Visible = false; notifyIcon.Visible = false;
Close();
Environment.Exit(0); Environment.Exit(0);
} }
@@ -352,14 +387,13 @@ namespace Wox
public void ShowMsg(string title, string subTitle, string iconPath) 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); m.Show(title, subTitle, iconPath);
} }
public void OpenSettingDialog() public void OpenSettingDialog()
{ {
SettingWidow s = new SettingWidow(this); new SettingWidow(this).Show();
s.Show();
} }
#endregion #endregion

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
@@ -20,7 +21,7 @@ namespace Wox.PluginLoader
{ {
try 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(); 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) if (types.Count == 0)
{ {

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using Python.Runtime; using Python.Runtime;
using Wox.Plugin; using Wox.Plugin;
using Wox.Helper;
namespace Wox.PluginLoader namespace Wox.PluginLoader
{ {
@@ -11,6 +12,8 @@ namespace Wox.PluginLoader
{ {
public override List<PluginPair> LoadPlugin() public override List<PluginPair> LoadPlugin()
{ {
if (!CheckPythonEnvironmentInstalled()) return new List<PluginPair>();
List<PluginPair> plugins = new List<PluginPair>(); List<PluginPair> plugins = new List<PluginPair>();
List<PluginMetadata> metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.Python.ToUpper()).ToList(); List<PluginMetadata> metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.Python.ToUpper()).ToList();
foreach (PluginMetadata metadata in metadatas) foreach (PluginMetadata metadata in metadatas)
@@ -26,5 +29,18 @@ namespace Wox.PluginLoader
return plugins; 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;
}
} }
} }

View File

@@ -1,9 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Documents;
using Newtonsoft.Json; using Newtonsoft.Json;
using Python.Runtime; using Python.Runtime;
using Wox.Helper; using Wox.Helper;
@@ -13,7 +10,6 @@ namespace Wox.PluginLoader
{ {
public class PythonPluginWrapper : IPlugin public class PythonPluginWrapper : IPlugin
{ {
private PluginMetadata metadata; private PluginMetadata metadata;
private string moduleName; private string moduleName;
@@ -40,19 +36,20 @@ namespace Wox.PluginLoader
PythonResult ps = pythonResult; PythonResult ps = pythonResult;
if (!string.IsNullOrEmpty(ps.ActionName)) 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); r.Add(ps);
} }
return r; return r;
} }
catch (Exception) catch (Exception e)
{ {
#if (DEBUG) #if (DEBUG)
{ {
throw; throw new WoxPythonException(e.Message);
} }
#endif #endif
Log.Error(string.Format("Python Plugin {0} query failed: {1}", metadata.Name, e.Message));
} }
return new List<Result>(); return new List<Result>();
@@ -73,15 +70,37 @@ namespace Wox.PluginLoader
private string InvokeFunc(string func, params PyObject[] paras) private string InvokeFunc(string func, params PyObject[] paras)
{ {
string json; string json = null;
IntPtr gs = PythonEngine.AcquireLock(); IntPtr gs = PythonEngine.AcquireLock();
PyObject module = PythonEngine.ImportModule(moduleName); 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)) if (module.HasAttr(func))
{ {
PyObject res = paras.Length > 0 ? module.InvokeMethod(func, paras) : module.InvokeMethod(func); try
json = Runtime.GetManagedString(res.Handle); {
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 else
{ {
@@ -90,7 +109,7 @@ namespace Wox.PluginLoader
Log.Error(error); Log.Error(error);
#if (DEBUG) #if (DEBUG)
{ {
throw new ArgumentException(error); throw new WoxPythonException(error);
} }
#endif #endif
} }

View File

@@ -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>

View File

@@ -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));
}
}
}

View File

@@ -3,9 +3,55 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:wox="clr-namespace:Wox"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"> d:DesignHeight="300" d:DesignWidth="300">
<ScrollViewer x:Name="sv" Template="{DynamicResource ScrollViewerControlTemplate}" MaxHeight="300" VerticalScrollBarVisibility="Auto"> <UserControl.Resources>
<StackPanel x:Name="pnlContainer"/> <wox:ImagePathConverter x:Key="ImagePathConverter"/>
</ScrollViewer> </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> </UserControl>

View File

@@ -1,8 +1,10 @@
using System.Collections.Generic; using System;
using System.Linq; using System.Collections.Generic;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using Wox.Helper; using Wox.Helper;
using Wox.Infrastructure;
using Wox.Plugin; using Wox.Plugin;
namespace Wox namespace Wox
@@ -11,70 +13,37 @@ namespace Wox
{ {
public bool Dirty { get; set; } 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) public void AddResults(List<Result> results)
{ {
if (results.Count == 0) return;
if (Dirty) if (Dirty)
{ {
Dirty = false; Dirty = false;
pnlContainer.Children.Clear(); lbResults.Items.Clear();
} }
foreach (var result in results)
for (int i = 0; i < results.Count; i++)
{ {
Result result = results[i]; int position = GetInsertLocation(result.Score);
if (!CheckExisted(result)) lbResults.Items.Insert(position, result);
{
ResultItem control = new ResultItem(result);
pnlContainer.Children.Insert(GetInsertLocation(result.Score), control);
}
} }
gridContainer.Margin = lbResults.Items.Count > 0 ? new Thickness { Top = 8 } : new Thickness { Top = 0 };
SelectFirst(); 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) private int GetInsertLocation(int currentScore)
{ {
int location = pnlContainer.Children.Count; int location = lbResults.Items.Count;
if (pnlContainer.Children.Count == 0) return 0; if (lbResults.Items.Count == 0) return 0;
if (currentScore > ((ResultItem)pnlContainer.Children[0]).Result.Score) 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; Result next = lbResults.Items[index] as Result;
ResultItem prev = pnlContainer.Children[index - 1] as ResultItem; Result prev = lbResults.Items[index - 1] as Result;
if (next != null && prev != null) 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; location = index + 1;
} }
@@ -89,40 +58,10 @@ namespace Wox
return location; 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() public void SelectNext()
{ {
int index = GetCurrentSelectedResultIndex(); int index = lbResults.SelectedIndex;
if (index == pnlContainer.Children.Count - 1) if (index == lbResults.Items.Count - 1)
{ {
index = -1; index = -1;
} }
@@ -131,98 +70,33 @@ namespace Wox
public void SelectPrev() public void SelectPrev()
{ {
int index = GetCurrentSelectedResultIndex(); int index = lbResults.SelectedIndex;
if (index == 0) if (index == 0)
{ {
index = pnlContainer.Children.Count; index = lbResults.Items.Count;
} }
Select(index - 1); Select(index - 1);
} }
private void Select(int index) private void SelectFirst()
{
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()
{ {
Select(0); Select(0);
} }
private void Select(int index)
{
if (index >= 0 && index < lbResults.Items.Count)
{
lbResults.SelectedItem = lbResults.Items.GetItemAt(index);
}
}
public Result AcceptSelect() public Result AcceptSelect()
{ {
int index = GetCurrentSelectedResultIndex(); int index = lbResults.SelectedIndex;
if (index < 0) return null; if (index < 0) return null;
var resultItemControl = pnlContainer.Children[index] as ResultItem; return lbResults.Items[index] as Result;
if (resultItemControl != null)
{
if (resultItemControl.Result.Action != null)
{
resultItemControl.Result.Action(new ActionContext()
{
SpecialKeyState = new KeyboardListener().CheckModifiers()
});
}
return resultItemControl.Result;
}
return null;
} }
public ResultPanel() public ResultPanel()
@@ -232,9 +106,16 @@ namespace Wox
public void Clear() public void Clear()
{ {
pnlContainer.Children.Clear(); lbResults.Items.Clear();
pnlContainer.Height = 0; gridContainer.Margin = new Thickness { Top = 0 };
OnResultItemChangedEvent(); }
private void lbResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
lbResults.ScrollIntoView(e.AddedItems[0]);
}
} }
} }
} }

View File

@@ -1,6 +1,7 @@
<Window x:Class="Wox.SettingWidow" <Window x:Class="Wox.SettingWidow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wox="clr-namespace:Wox"
Icon="Images\app.png" Icon="Images\app.png"
Title="Wox Setting" Title="Wox Setting"
ResizeMode="NoResize" ResizeMode="NoResize"
@@ -22,10 +23,55 @@
<TextBlock Text="Theme:" /> <TextBlock Text="Theme:" />
<ComboBox x:Name="themeComboBox" SelectionChanged="ThemeComboBox_OnSelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/> <ComboBox x:Name="themeComboBox" SelectionChanged="ThemeComboBox_OnSelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</TabItem> </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"> <TabItem Header="Web Search">
<Grid> <Grid Margin="10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="50"></RowDefinition> <RowDefinition Height="50"></RowDefinition>

View File

@@ -19,7 +19,7 @@ namespace Wox
{ {
public partial class SettingWidow : Window public partial class SettingWidow : Window
{ {
private MainWindow mainWindow; public MainWindow MainWindow;
public SettingWidow() public SettingWidow()
{ {
@@ -28,9 +28,17 @@ namespace Wox
public SettingWidow(MainWindow mainWindow) public SettingWidow(MainWindow mainWindow)
{ {
this.mainWindow = mainWindow; this.MainWindow = mainWindow;
InitializeComponent(); InitializeComponent();
Loaded += Setting_Loaded; 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) => cbReplaceWinR.Checked += (o, e) =>
{ {
CommonStorage.Instance.UserSetting.ReplaceWinR = true; CommonStorage.Instance.UserSetting.ReplaceWinR = true;
@@ -41,10 +49,7 @@ namespace Wox
CommonStorage.Instance.UserSetting.ReplaceWinR = false; CommonStorage.Instance.UserSetting.ReplaceWinR = false;
CommonStorage.Instance.Save(); CommonStorage.Instance.Save();
}; };
}
private void Setting_Loaded(object sender, RoutedEventArgs e)
{
foreach (string theme in LoadAvailableThemes()) foreach (string theme in LoadAvailableThemes())
{ {
string themeName = theme.Substring(theme.LastIndexOf('\\') + 1).Replace(".xaml", ""); string themeName = theme.Substring(theme.LastIndexOf('\\') + 1).Replace(".xaml", "");
@@ -54,6 +59,7 @@ namespace Wox
themeComboBox.SelectedItem = CommonStorage.Instance.UserSetting.Theme; themeComboBox.SelectedItem = CommonStorage.Instance.UserSetting.Theme;
cbReplaceWinR.IsChecked = CommonStorage.Instance.UserSetting.ReplaceWinR; cbReplaceWinR.IsChecked = CommonStorage.Instance.UserSetting.ReplaceWinR;
webSearchView.ItemsSource = CommonStorage.Instance.UserSetting.WebSearches; webSearchView.ItemsSource = CommonStorage.Instance.UserSetting.WebSearches;
lvCustomHotkey.ItemsSource = CommonStorage.Instance.UserSetting.CustomPluginHotkeys;
cbStartWithWindows.IsChecked = CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup; cbStartWithWindows.IsChecked = CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup;
} }
@@ -71,7 +77,7 @@ namespace Wox
private void ThemeComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) private void ThemeComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
string themeName = themeComboBox.SelectedItem.ToString(); string themeName = themeComboBox.SelectedItem.ToString();
mainWindow.SetTheme(themeName); MainWindow.SetTheme(themeName);
CommonStorage.Instance.UserSetting.Theme = themeName; CommonStorage.Instance.UserSetting.Theme = themeName;
CommonStorage.Instance.Save(); CommonStorage.Instance.Save();
} }
@@ -79,7 +85,7 @@ namespace Wox
private void btnAddWebSearch_OnClick(object sender, RoutedEventArgs e) private void btnAddWebSearch_OnClick(object sender, RoutedEventArgs e)
{ {
WebSearchSetting webSearch = new WebSearchSetting(this); WebSearchSetting webSearch = new WebSearchSetting(this);
webSearch.Show(); webSearch.ShowDialog();
} }
private void btnDeleteWebSearch_OnClick(object sender, RoutedEventArgs e) private void btnDeleteWebSearch_OnClick(object sender, RoutedEventArgs e)
@@ -104,8 +110,8 @@ namespace Wox
if (seletedWebSearch != null) if (seletedWebSearch != null)
{ {
WebSearchSetting webSearch = new WebSearchSetting(this); WebSearchSetting webSearch = new WebSearchSetting(this);
webSearch.Show();
webSearch.UpdateItem(seletedWebSearch); webSearch.UpdateItem(seletedWebSearch);
webSearch.ShowDialog();
} }
else 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
} }
} }

View 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;
}
}
}

View File

@@ -30,16 +30,35 @@
<Setter Property="FontSize" Value="16" /> <Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Medium" /> <Setter Property="FontWeight" Value="Medium" />
</Style> </Style>
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}"> <Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}" >
<Setter Property="Foreground" Value="#D9D9D4" /> <Setter Property="Foreground" Value="#D9D9D4" />
</Style> </Style>
<Style x:Key="ItemStyle" TargetType="{x:Type UserControl}"> <Style x:Key="ItemTitleSelectedStyle" TargetType="{x:Type TextBlock}" >
<Setter Property="Background" Value="Transparent" /> <Setter Property="Foreground" Value="#FFFFF8" />
<Style.Triggers> <Setter Property="FontSize" Value="16" />
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Selected}" Value="true"> <Setter Property="FontWeight" Value="Medium" />
<Setter Property="Background" Value="#4F6180" /> </Style>
</DataTrigger> <Style x:Key="ItemSubTitleSelectedStyle" TargetType="{x:Type TextBlock}" >
</Style.Triggers> <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> </Style>
<!-- ScrollViewer Style --> <!-- ScrollViewer Style -->

View File

@@ -23,32 +23,42 @@
<Setter Property="Stroke" Value="Blue"></Setter> <Setter Property="Stroke" Value="Blue"></Setter>
</Style> </Style>
<!-- Item Style --> <!-- Item Style -->
<Style x:Key="ItemTitleStyle" TargetType="{x:Type TextBlock}" > <Style x:Key="ItemTitleStyle" TargetType="{x:Type TextBlock}" >
<Setter Property="Foreground" Value="#141411"></Setter> <Setter Property="Foreground" Value="#141411"></Setter>
<Setter Property="FontSize" Value="16"></Setter> <Setter Property="FontSize" Value="16"></Setter>
<Setter Property="FontWeight" Value="Medium"></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>
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}" > <Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}" >
<Setter Property="Foreground" Value="#B3B2B0"></Setter> <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>
<Style x:Key="ItemStyle" TargetType="{x:Type UserControl}" > <Style x:Key="ItemTitleSelectedStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="Transparent"></Setter> <Setter Property="Foreground" Value="#F6F6FF" />
<Style.Triggers> <Setter Property="FontSize" Value="16"></Setter>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Selected}" Value="true"> <Setter Property="FontWeight" Value="Medium"></Setter>
<Setter Property="Background" Value="#543BFD"></Setter> </Style>
</DataTrigger> <Style x:Key="ItemSubTitleSelectedStyle" TargetType="{x:Type TextBlock}">
</Style.Triggers> <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> </Style>
<!-- ScrollViewer Style --> <!-- ScrollViewer Style -->
@@ -123,4 +133,4 @@
</Setter> </Setter>
</Style> </Style>
</ResourceDictionary> </ResourceDictionary>

View File

@@ -89,6 +89,12 @@
<Reference Include="Newtonsoft.Json"> <Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference> </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="PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="ReachFramework" /> <Reference Include="ReachFramework" />
<Reference Include="System" /> <Reference Include="System" />
@@ -119,12 +125,18 @@
<Compile Include="Commands\CommandFactory.cs" /> <Compile Include="Commands\CommandFactory.cs" />
<Compile Include="Commands\PluginCommand.cs" /> <Compile Include="Commands\PluginCommand.cs" />
<Compile Include="Commands\SystemCommand.cs" /> <Compile Include="Commands\SystemCommand.cs" />
<Compile Include="CustomPluginHotkeySetting.xaml.cs">
<DependentUpon>CustomPluginHotkeySetting.xaml</DependentUpon>
</Compile>
<Compile Include="DispatcherExtensions.cs" /> <Compile Include="DispatcherExtensions.cs" />
<Compile Include="Helper\KeyboardHook.cs" />
<Compile Include="Helper\Log.cs" /> <Compile Include="Helper\Log.cs" />
<Compile Include="Helper\PluginInstaller.cs" /> <Compile Include="Helper\PluginInstaller.cs" />
<Compile Include="Helper\WoxException.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"> <Compile Include="Msg.xaml.cs">
<DependentUpon>Msg.xaml</DependentUpon> <DependentUpon>Msg.xaml</DependentUpon>
</Compile> </Compile>
@@ -137,15 +149,21 @@
<Compile Include="ResultPanel.xaml.cs"> <Compile Include="ResultPanel.xaml.cs">
<DependentUpon>ResultPanel.xaml</DependentUpon> <DependentUpon>ResultPanel.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="ResultItem.xaml.cs">
<DependentUpon>ResultItem.xaml</DependentUpon>
</Compile>
<Compile Include="SettingWindow.xaml.cs"> <Compile Include="SettingWindow.xaml.cs">
<DependentUpon>SettingWindow.xaml</DependentUpon> <DependentUpon>SettingWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="StringNullOrEmptyToVisibilityConverter.cs" />
<Compile Include="WebSearchSetting.xaml.cs"> <Compile Include="WebSearchSetting.xaml.cs">
<DependentUpon>WebSearchSetting.xaml</DependentUpon> <DependentUpon>WebSearchSetting.xaml</DependentUpon>
</Compile> </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"> <Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -166,10 +184,6 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="ResultItem.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SettingWindow.xaml"> <Page Include="SettingWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -3,5 +3,7 @@
<package id="InputSimulator" version="1.0.4.0" targetFramework="net35" /> <package id="InputSimulator" version="1.0.4.0" targetFramework="net35" />
<package id="log4net" version="2.0.3" targetFramework="net35" /> <package id="log4net" version="2.0.3" targetFramework="net35" />
<package id="Newtonsoft.Json" version="5.0.8" 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" /> <package id="SharpZipLib" version="0.86.0" targetFramework="net35" />
</packages> </packages>