diff --git a/Plugins/WinAlfred.Plugin.Fanyi/HttpRequest.cs b/Plugins/WinAlfred.Plugin.Fanyi/HttpRequest.cs
new file mode 100644
index 000000000..385ccec7a
--- /dev/null
+++ b/Plugins/WinAlfred.Plugin.Fanyi/HttpRequest.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+
+//From:http://blog.csdn.net/zhoufoxcn/article/details/6404236
+namespace WinAlfred.Plugin.Fanyi
+{
+ ///
+ /// 有关HTTP请求的辅助类
+ ///
+ public class HttpRequest
+ {
+ private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
+ ///
+ /// 创建GET方式的HTTP请求
+ ///
+ /// 请求的URL
+ /// 请求的超时时间
+ /// 请求的客户端浏览器信息,可以为空
+ /// 随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空
+ ///
+ public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieCollection cookies)
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ArgumentNullException("url");
+ }
+ HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
+ request.Method = "GET";
+ request.UserAgent = DefaultUserAgent;
+ if (!string.IsNullOrEmpty(userAgent))
+ {
+ request.UserAgent = userAgent;
+ }
+ if (timeout.HasValue)
+ {
+ request.Timeout = timeout.Value;
+ }
+ if (cookies != null)
+ {
+ request.CookieContainer = new CookieContainer();
+ request.CookieContainer.Add(cookies);
+ }
+ return request.GetResponse() as HttpWebResponse;
+ }
+ ///
+ /// 创建POST方式的HTTP请求
+ ///
+ /// 请求的URL
+ /// 随同请求POST的参数名称及参数值字典
+ /// 请求的超时时间
+ /// 请求的客户端浏览器信息,可以为空
+ /// 发送HTTP请求时所用的编码
+ /// 随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空
+ ///
+ public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies)
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ArgumentNullException("url");
+ }
+ if (requestEncoding == null)
+ {
+ throw new ArgumentNullException("requestEncoding");
+ }
+ HttpWebRequest request = null;
+ //如果是发送HTTPS请求
+ if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
+ {
+ ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
+ request = WebRequest.Create(url) as HttpWebRequest;
+ request.ProtocolVersion = HttpVersion.Version10;
+ }
+ else
+ {
+ request = WebRequest.Create(url) as HttpWebRequest;
+ }
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+
+ if (!string.IsNullOrEmpty(userAgent))
+ {
+ request.UserAgent = userAgent;
+ }
+ else
+ {
+ request.UserAgent = DefaultUserAgent;
+ }
+
+ if (timeout.HasValue)
+ {
+ request.Timeout = timeout.Value;
+ }
+ if (cookies != null)
+ {
+ request.CookieContainer = new CookieContainer();
+ request.CookieContainer.Add(cookies);
+ }
+ //如果需要POST数据
+ if (!(parameters == null || parameters.Count == 0))
+ {
+ StringBuilder buffer = new StringBuilder();
+ int i = 0;
+ foreach (string key in parameters.Keys)
+ {
+ if (i > 0)
+ {
+ buffer.AppendFormat("&{0}={1}", key, parameters[key]);
+ }
+ else
+ {
+ buffer.AppendFormat("{0}={1}", key, parameters[key]);
+ }
+ i++;
+ }
+ byte[] data = requestEncoding.GetBytes(buffer.ToString());
+ using (Stream stream = request.GetRequestStream())
+ {
+ stream.Write(data, 0, data.Length);
+ }
+ }
+ return request.GetResponse() as HttpWebResponse;
+ }
+
+ private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
+ {
+ return true; //总是接受
+ }
+ }
+}
diff --git a/Plugins/WinAlfred.Plugin.Fanyi/Images/translate.png b/Plugins/WinAlfred.Plugin.Fanyi/Images/translate.png
new file mode 100644
index 000000000..11be5bc95
Binary files /dev/null and b/Plugins/WinAlfred.Plugin.Fanyi/Images/translate.png differ
diff --git a/Plugins/WinAlfred.Plugin.Fanyi/Main.cs b/Plugins/WinAlfred.Plugin.Fanyi/Main.cs
new file mode 100644
index 000000000..cdbbc4167
--- /dev/null
+++ b/Plugins/WinAlfred.Plugin.Fanyi/Main.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+using Newtonsoft.Json;
+
+namespace WinAlfred.Plugin.Fanyi
+{
+ public class TranslateResult
+ {
+ public string from { get; set; }
+ public string to { get; set; }
+ public List trans_result { get; set; }
+
+ }
+
+ public class SrcDst
+ {
+ public string src { get; set; }
+ public string dst { get; set; }
+ }
+
+ public class Main : IPlugin
+ {
+ private string translateURL = "http://openapi.baidu.com/public/2.0/bmt/translate";
+ private string baiduKey = "SnPcDY3iH5jDbklRewkG2D2v";
+
+ static public string AssemblyDirectory
+ {
+ get
+ {
+ string codeBase = Assembly.GetExecutingAssembly().CodeBase;
+ UriBuilder uri = new UriBuilder(codeBase);
+ string path = Uri.UnescapeDataString(uri.Path);
+ return Path.GetDirectoryName(path);
+ }
+ }
+
+ public List Query(Query query)
+ {
+ List results = new List();
+ if (query.ActionParameters.Count == 0)
+ {
+ results.Add(new Result()
+ {
+ Title = "Start to translate between Chinese and English",
+ SubTitle = "Powered by baidu api",
+ IcoPath = "Images\\translate.png"
+ });
+ return results;
+ }
+
+ Dictionary data = new Dictionary();
+ data.Add("from", "auto");
+ data.Add("to", "auto");
+ data.Add("q", query.RawQuery.Substring(3));
+ data.Add("client_id", baiduKey);
+ HttpWebResponse response = HttpRequest.CreatePostHttpResponse(translateURL, data, null, null, Encoding.UTF8, null);
+ Stream s = response.GetResponseStream();
+ if (s != null)
+ {
+ StreamReader reader = new StreamReader(s, Encoding.UTF8);
+ string json = reader.ReadToEnd();
+ TranslateResult o = JsonConvert.DeserializeObject(json);
+ foreach (SrcDst srcDst in o.trans_result)
+ {
+ string dst = srcDst.dst;
+ results.Add(new Result()
+ {
+ Title = dst,
+ SubTitle = "Copy to clipboard",
+ IcoPath = "Images\\translate.png",
+ Action = () =>
+ {
+ Clipboard.SetText(dst);
+ context.ShowMsg("translation has been copyed to your clipboard.", "",
+ AssemblyDirectory + "\\Images\\translate.png");
+ }
+ });
+ }
+ }
+
+ return results;
+ }
+
+ public static string GetHtmlStr(string url)
+ {
+ try
+ {
+ WebRequest rGet = WebRequest.Create(url);
+ WebResponse rSet = rGet.GetResponse();
+ Stream s = rSet.GetResponseStream();
+ StreamReader reader = new StreamReader(s, Encoding.UTF8);
+ return reader.ReadToEnd();
+ }
+ catch (WebException)
+ {
+ //连接失败
+ return null;
+ }
+ }
+
+ public void Init(PluginInitContext context)
+ {
+ this.context = context;
+ }
+
+ private PluginInitContext context { get; set; }
+ }
+}
diff --git a/Plugins/WinAlfred.Plugin.System/Properties/AssemblyInfo.cs b/Plugins/WinAlfred.Plugin.Fanyi/Properties/AssemblyInfo.cs
similarity index 81%
rename from Plugins/WinAlfred.Plugin.System/Properties/AssemblyInfo.cs
rename to Plugins/WinAlfred.Plugin.Fanyi/Properties/AssemblyInfo.cs
index 9f1336c2f..7e841771e 100644
--- a/Plugins/WinAlfred.Plugin.System/Properties/AssemblyInfo.cs
+++ b/Plugins/WinAlfred.Plugin.Fanyi/Properties/AssemblyInfo.cs
@@ -1,36 +1,36 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 有关程序集的常规信息通过以下
-// 特性集控制。更改这些特性值可修改
-// 与程序集关联的信息。
-[assembly: AssemblyTitle("WinAlfred.Plugin.System")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("WinAlfred.Plugin.System")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// 将 ComVisible 设置为 false 使此程序集中的类型
-// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
-// 则将该类型上的 ComVisible 特性设置为 true。
-[assembly: ComVisible(false)]
-
-// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("5cdfe514-80c9-4d82-94e7-c6f79a26ccda")]
-
-// 程序集的版本信息由下面四个值组成:
-//
-// 主版本
-// 次版本
-// 生成号
-// 修订号
-//
-// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
-// 方法是按如下所示使用“*”:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的常规信息通过以下
+// 特性集控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("WinAlfred.Plugin.Fanyi")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("WinAlfred.Plugin.Fanyi")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 使此程序集中的类型
+// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
+// 则将该类型上的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("5b55da55-94f5-4248-af75-5eb40409a8ca")]
+
+// 程序集的版本信息由下面四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
+// 方法是按如下所示使用“*”:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Plugins/WinAlfred.Plugin.System/WinAlfred.Plugin.System.csproj b/Plugins/WinAlfred.Plugin.Fanyi/WinAlfred.Plugin.Fanyi.csproj
similarity index 74%
rename from Plugins/WinAlfred.Plugin.System/WinAlfred.Plugin.System.csproj
rename to Plugins/WinAlfred.Plugin.Fanyi/WinAlfred.Plugin.Fanyi.csproj
index a8dacb8d1..30bee4c18 100644
--- a/Plugins/WinAlfred.Plugin.System/WinAlfred.Plugin.System.csproj
+++ b/Plugins/WinAlfred.Plugin.Fanyi/WinAlfred.Plugin.Fanyi.csproj
@@ -4,13 +4,15 @@
Debug
AnyCPU
- {E515011D-A769-418B-8761-ABE6F29827A0}
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}
Library
Properties
- WinAlfred.Plugin.System
- WinAlfred.Plugin.System
+ WinAlfred.Plugin.Fanyi
+ WinAlfred.Plugin.Fanyi
v3.5
512
+ ..\..\
+ true
true
@@ -30,6 +32,12 @@
4
+
+ ..\..\packages\HtmlAgilityPack.1.4.6\lib\Net20\HtmlAgilityPack.dll
+
+
+ ..\..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll
+
@@ -39,6 +47,7 @@
+
@@ -49,18 +58,20 @@
+
Always
-
+
+
- xcopy /Y $(TargetDir)$(TargetFileName) $(SolutionDir)WinAlfred\bin\Debug\Plugins\System\
-xcopy /Y $(TargetDir)plugin.ini $(SolutionDir)WinAlfred\bin\Debug\Plugins\System\
-xcopy /Y $(ProjectDir)Images\*.* $(SolutionDir)WinAlfred\bin\Debug\Plugins\System\Images\
+ xcopy /Y $(TargetDir)$(TargetFileName) $(SolutionDir)WinAlfred\bin\Debug\Plugins\Fanyi\
+xcopy /Y $(TargetDir)plugin.ini $(SolutionDir)WinAlfred\bin\Debug\Plugins\Fanyi\
+xcopy /Y $(ProjectDir)Images\*.* $(SolutionDir)WinAlfred\bin\Debug\Plugins\Fanyi\Images\
+
\ No newline at end of file
diff --git a/WinAlfred.Plugin.System/packages.config b/WinAlfred.Plugin.System/packages.config
new file mode 100644
index 000000000..9520f36d8
--- /dev/null
+++ b/WinAlfred.Plugin.System/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/WinAlfred.Plugin/IPlugin.cs b/WinAlfred.Plugin/IPlugin.cs
index 87a68f68e..e159235e7 100644
--- a/WinAlfred.Plugin/IPlugin.cs
+++ b/WinAlfred.Plugin/IPlugin.cs
@@ -5,6 +5,6 @@ namespace WinAlfred.Plugin
public interface IPlugin
{
List Query(Query query);
- void Init();
+ void Init(PluginInitContext context);
}
}
\ No newline at end of file
diff --git a/WinAlfred.Plugin/PluginInitContext.cs b/WinAlfred.Plugin/PluginInitContext.cs
new file mode 100644
index 000000000..70025c258
--- /dev/null
+++ b/WinAlfred.Plugin/PluginInitContext.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WinAlfred.Plugin
+{
+ public class PluginInitContext
+ {
+ public List Plugins { get; set; }
+
+ public Action ChangeQuery { get; set; }
+ public Action CloseApp { get; set; }
+ public Action HideApp { get; set; }
+ public Action ShowApp { get; set; }
+ public Action ShowMsg { get; set; }
+ }
+}
diff --git a/WinAlfred.Plugin/PluginMetadata.cs b/WinAlfred.Plugin/PluginMetadata.cs
index 23d54b8c2..167e299e5 100644
--- a/WinAlfred.Plugin/PluginMetadata.cs
+++ b/WinAlfred.Plugin/PluginMetadata.cs
@@ -16,5 +16,6 @@ namespace WinAlfred.Plugin
public string ExecuteFileName { get; set; }
public string PluginDirecotry { get; set; }
public string ActionKeyword { get; set; }
+ public PluginType PluginType { get; set; }
}
}
diff --git a/WinAlfred.Plugin/PluginType.cs b/WinAlfred.Plugin/PluginType.cs
new file mode 100644
index 000000000..1db293c16
--- /dev/null
+++ b/WinAlfred.Plugin/PluginType.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WinAlfred.Plugin
+{
+ public enum PluginType
+ {
+ System,
+ ThirdParty
+ }
+}
diff --git a/WinAlfred.Plugin/Result.cs b/WinAlfred.Plugin/Result.cs
index a66b8851d..784670c7c 100644
--- a/WinAlfred.Plugin/Result.cs
+++ b/WinAlfred.Plugin/Result.cs
@@ -11,11 +11,35 @@ namespace WinAlfred.Plugin
public string IcoPath { get; set; }
public Action Action { get; set; }
public int Score { get; set; }
+
+ public bool DontHideWinAlfredAfterAction { get; set; }
+
+ //todo: this should be controlled by system, not visible to users
+ ///
+ /// Only resulsts that originQuery match with curren query will be displayed in the panel
+ ///
+ public Query OriginQuery { get; set; }
+ ///
+ /// context results connected with current reuslt, usually, it can use <- or -> navigate context results
+ ///
public List ContextResults { get; set; }
///
/// you don't need to set this property if you are developing a plugin
///
public string PluginDirectory { get; set; }
+
+ public new bool Equals(object obj)
+ {
+ if (obj == null || !(obj is Result)) return false;
+
+ Result r = (Result)obj;
+ return r.Title == Title && r.SubTitle == SubTitle;
+ }
+
+ public override string ToString()
+ {
+ return Title + SubTitle;
+ }
}
}
\ No newline at end of file
diff --git a/WinAlfred.Plugin/WinAlfred.Plugin.csproj b/WinAlfred.Plugin/WinAlfred.Plugin.csproj
index e0b1b3869..efcee86f4 100644
--- a/WinAlfred.Plugin/WinAlfred.Plugin.csproj
+++ b/WinAlfred.Plugin/WinAlfred.Plugin.csproj
@@ -60,7 +60,9 @@
+
+
diff --git a/WinAlfred.sln b/WinAlfred.sln
index 6c6a89568..eca79e1fa 100644
--- a/WinAlfred.sln
+++ b/WinAlfred.sln
@@ -7,13 +7,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinAlfred.Plugin", "WinAlfr
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugin", "Plugin", "{3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinAlfred.Plugin.System", "Plugins\WinAlfred.Plugin.System\WinAlfred.Plugin.System.csproj", "{E515011D-A769-418B-8761-ABE6F29827A0}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinAlfred", "WinAlfred\WinAlfred.csproj", "{DB90F671-D861-46BB-93A3-F1304F5BA1C5}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PyWinAlfred", "PyWinAlfred\PyWinAlfred.vcxproj", "{D03FD663-38A8-4C1A-8431-EB44F93E7EBA}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinAlfred.Plugin.System", "WinAlfred.Plugin.System\WinAlfred.Plugin.System.csproj", "{69CE0206-CB41-453D-88AF-DF86092EF9B8}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PyWinAlfred.Test", "PyWinAlfred.Test\PyWinAlfred.Test.vcxproj", "{05D72D92-4010-4F92-A147-906930241573}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinAlfred.Plugin.Fanyi", "Plugins\WinAlfred.Plugin.Fanyi\WinAlfred.Plugin.Fanyi.csproj", "{353769D3-D11C-4D86-BD06-AC8C1D68642B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -54,26 +52,12 @@ Global
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Debug|x86.Build.0 = Debug|Any CPU
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Any CPU.Build.0 = Release|Any CPU
- {8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Mixed Platforms.Build.0 = Release|x86
+ {8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Win32.ActiveCfg = Release|x86
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|Win32.Build.0 = Release|x86
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x64.ActiveCfg = Release|Any CPU
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}.Release|x86.ActiveCfg = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|Win32.ActiveCfg = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|x64.ActiveCfg = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Debug|x86.ActiveCfg = Debug|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|Any CPU.Build.0 = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|Win32.ActiveCfg = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|x64.ActiveCfg = Release|Any CPU
- {E515011D-A769-418B-8761-ABE6F29827A0}.Release|x86.ActiveCfg = Release|Any CPU
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -88,45 +72,39 @@ Global
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|Win32.ActiveCfg = Release|Any CPU
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|x64.ActiveCfg = Release|Any CPU
{DB90F671-D861-46BB-93A3-F1304F5BA1C5}.Release|x86.ActiveCfg = Release|Any CPU
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|Any CPU.ActiveCfg = Debug|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|Mixed Platforms.Build.0 = Debug|x64
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|Win32.ActiveCfg = Debug|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|Win32.Build.0 = Debug|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|x64.ActiveCfg = Debug|x64
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|x64.Build.0 = Debug|x64
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|x86.ActiveCfg = Debug|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Debug|x86.Build.0 = Debug|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|Any CPU.ActiveCfg = Release|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|Mixed Platforms.ActiveCfg = Release|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|Mixed Platforms.Build.0 = Release|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|Win32.ActiveCfg = Release|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|Win32.Build.0 = Release|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|x64.ActiveCfg = Release|x64
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|x64.Build.0 = Release|x64
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|x86.ActiveCfg = Release|Win32
- {D03FD663-38A8-4C1A-8431-EB44F93E7EBA}.Release|x86.Build.0 = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Debug|Any CPU.ActiveCfg = Debug|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
- {05D72D92-4010-4F92-A147-906930241573}.Debug|Mixed Platforms.Build.0 = Debug|x64
- {05D72D92-4010-4F92-A147-906930241573}.Debug|Win32.ActiveCfg = Debug|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Debug|Win32.Build.0 = Debug|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Debug|x64.ActiveCfg = Debug|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Debug|x86.ActiveCfg = Debug|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Debug|x86.Build.0 = Debug|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|Any CPU.ActiveCfg = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|Mixed Platforms.ActiveCfg = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|Mixed Platforms.Build.0 = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|Win32.ActiveCfg = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|Win32.Build.0 = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|x64.ActiveCfg = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|x86.ActiveCfg = Release|Win32
- {05D72D92-4010-4F92-A147-906930241573}.Release|x86.Build.0 = Release|Win32
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|Win32.ActiveCfg = Release|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|x64.ActiveCfg = Release|Any CPU
+ {69CE0206-CB41-453D-88AF-DF86092EF9B8}.Release|x86.ActiveCfg = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|Win32.ActiveCfg = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|x64.ActiveCfg = Release|Any CPU
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {E515011D-A769-418B-8761-ABE6F29827A0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
+ {353769D3-D11C-4D86-BD06-AC8C1D68642B} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87}
EndGlobalSection
EndGlobal
diff --git a/WinAlfred/App.config b/WinAlfred/App.config
index 01c0f5391..e1eb5518f 100644
--- a/WinAlfred/App.config
+++ b/WinAlfred/App.config
@@ -17,4 +17,4 @@
-
+
diff --git a/WinAlfred/App.xaml b/WinAlfred/App.xaml
index ba0967d5d..43657b441 100644
--- a/WinAlfred/App.xaml
+++ b/WinAlfred/App.xaml
@@ -1,7 +1,7 @@
+ >
+
diff --git a/WinAlfred/App.xaml.cs b/WinAlfred/App.xaml.cs
index cc2295037..dfb3747a1 100644
--- a/WinAlfred/App.xaml.cs
+++ b/WinAlfred/App.xaml.cs
@@ -1,11 +1,28 @@
-using System.Windows;
-
-namespace WinAlfred
-{
- ///
- /// App.xaml 的交互逻辑
- ///
- public partial class App : Application
- {
- }
-}
+using System;
+using System.Threading;
+using System.Windows;
+
+namespace WinAlfred
+{
+ ///
+ /// App.xaml 的交互逻辑
+ ///
+ public partial class App : Application
+ {
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+ bool startupFlag;
+ Mutex mutex = new Mutex(true, "WinAlfred", out startupFlag);
+ if (!startupFlag)
+ {
+ Environment.Exit(0);
+ }
+ else
+ {
+ MainWindow mainWindow = new MainWindow();
+ mainWindow.Show();
+ }
+ }
+ }
+}
diff --git a/WinAlfred/Commands/BaseCommand.cs b/WinAlfred/Commands/BaseCommand.cs
new file mode 100644
index 000000000..fd16c8ab5
--- /dev/null
+++ b/WinAlfred/Commands/BaseCommand.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using WinAlfred.Plugin;
+
+namespace WinAlfred.Commands
+{
+ public abstract class BaseCommand
+ {
+ private MainWindow window;
+
+ public abstract void Dispatch(Query query);
+
+ //TODO:Ugly, we should subscribe events here, instead of just use usercontrol as the parameter
+ protected BaseCommand(MainWindow window)
+ {
+ this.window = window;
+ }
+
+ protected void UpdateResultView(List results)
+ {
+ window.OnUpdateResultView(results);
+ }
+ }
+}
diff --git a/WinAlfred/Commands/Command.cs b/WinAlfred/Commands/Command.cs
new file mode 100644
index 000000000..7e9af536e
--- /dev/null
+++ b/WinAlfred/Commands/Command.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using WinAlfred.Helper;
+using WinAlfred.Plugin;
+
+namespace WinAlfred.Commands
+{
+ public class Command
+ {
+ private PluginCommand pluginCmd;
+ private SystemCommand systemCmd;
+
+ public Command(MainWindow window)
+ {
+ pluginCmd = new PluginCommand(window);
+ systemCmd = new SystemCommand(window);
+ }
+
+ public void DispatchCommand(Query query)
+ {
+ systemCmd.Dispatch(query);
+ pluginCmd.Dispatch(query);
+ }
+ }
+}
diff --git a/WinAlfred/Commands/PluginCommand.cs b/WinAlfred/Commands/PluginCommand.cs
new file mode 100644
index 000000000..f30b667ac
--- /dev/null
+++ b/WinAlfred/Commands/PluginCommand.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using WinAlfred.Helper;
+using WinAlfred.Plugin;
+using WinAlfred.PluginLoader;
+
+namespace WinAlfred.Commands
+{
+ public class PluginCommand : BaseCommand
+ {
+ public PluginCommand(MainWindow mainWindow)
+ : base(mainWindow)
+ {
+
+ }
+
+ public override void Dispatch(Query q)
+ {
+
+ foreach (PluginPair pair in Plugins.AllPlugins)
+ {
+ if (pair.Metadata.ActionKeyword == q.ActionName)
+ {
+ PluginPair pair1 = pair;
+ ThreadPool.QueueUserWorkItem(state =>
+ {
+ try
+ {
+ List r = pair1.Plugin.Query(q);
+ r.ForEach(o =>
+ {
+ o.PluginDirectory = pair1.Metadata.PluginDirecotry;
+ o.OriginQuery = q;
+ });
+ UpdateResultView(r);
+ }
+ catch (Exception queryException)
+ {
+ Log.Error(string.Format("Plugin {0} query failed: {1}", pair1.Metadata.Name,
+ queryException.Message));
+#if (DEBUG)
+ {
+ throw;
+ }
+#endif
+ }
+ });
+ }
+ }
+ }
+ }
+}
diff --git a/WinAlfred/Commands/SystemCommand.cs b/WinAlfred/Commands/SystemCommand.cs
new file mode 100644
index 000000000..7ecad9820
--- /dev/null
+++ b/WinAlfred/Commands/SystemCommand.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using WinAlfred.Plugin;
+using WinAlfred.PluginLoader;
+
+namespace WinAlfred.Commands
+{
+ public class SystemCommand : BaseCommand
+ {
+ private List systemPlugins;
+
+ public SystemCommand(MainWindow window)
+ : base(window)
+ {
+ systemPlugins = Plugins.AllPlugins.Where(o => o.Metadata.PluginType == PluginType.System).ToList();
+ }
+
+ public override void Dispatch(Query query)
+ {
+ foreach (PluginPair pair in systemPlugins)
+ {
+ PluginPair pair1 = pair;
+ ThreadPool.QueueUserWorkItem(state =>
+ {
+ List results = pair1.Plugin.Query(query);
+ foreach (Result result in results)
+ {
+ result.PluginDirectory = pair1.Metadata.PluginDirecotry;
+ result.OriginQuery = query;
+ }
+ if(results.Count > 0) UpdateResultView(results);
+ });
+ }
+ }
+ }
+}
diff --git a/WinAlfred/DispatcherExtensions.cs b/WinAlfred/DispatcherExtensions.cs
new file mode 100644
index 000000000..15a56bfa7
--- /dev/null
+++ b/WinAlfred/DispatcherExtensions.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Threading;
+
+namespace WinAlfred
+{
+ public static class DispatcherExtensions
+ {
+ private static Dictionary timers =
+ new Dictionary();
+ private static readonly object syncRoot = new object();
+
+ public static string DelayInvoke(this Dispatcher dispatcher, string namedInvocation,
+ Action action, TimeSpan delay,
+ DispatcherPriority priority = DispatcherPriority.Normal)
+ {
+ return DelayInvoke(dispatcher, namedInvocation, action, delay, string.Empty, priority);
+ }
+
+ public static string DelayInvoke(this Dispatcher dispatcher, string namedInvocation,
+ Action action, TimeSpan delay, string arg,
+ DispatcherPriority priority = DispatcherPriority.Normal)
+ {
+ lock (syncRoot)
+ {
+ if (String.IsNullOrEmpty(namedInvocation))
+ {
+ namedInvocation = Guid.NewGuid().ToString();
+ }
+ else
+ {
+ RemoveTimer(namedInvocation);
+ }
+ var timer = new DispatcherTimer(delay, priority, (s, e) =>
+ {
+ RemoveTimer(namedInvocation);
+ action(arg);
+ }, dispatcher);
+ timer.Start();
+ timers.Add(namedInvocation, timer);
+ return namedInvocation;
+ }
+ }
+
+
+ public static void CancelNamedInvocation(this Dispatcher dispatcher, string namedInvocation)
+ {
+ lock (syncRoot)
+ {
+ RemoveTimer(namedInvocation);
+ }
+ }
+
+ private static void RemoveTimer(string namedInvocation)
+ {
+ if (!timers.ContainsKey(namedInvocation)) return;
+ timers[namedInvocation].Stop();
+ timers.Remove(namedInvocation);
+ }
+
+ }
+}
diff --git a/WinAlfred/Helper/KeyboardHook.cs b/WinAlfred/Helper/KeyboardHook.cs
index 97a775534..be717a541 100644
--- a/WinAlfred/Helper/KeyboardHook.cs
+++ b/WinAlfred/Helper/KeyboardHook.cs
@@ -85,6 +85,7 @@ namespace WinAlfred.Helper
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.");
diff --git a/WinAlfred/Helper/SelectedRecords.cs b/WinAlfred/Helper/SelectedRecords.cs
new file mode 100644
index 000000000..21b49bd26
--- /dev/null
+++ b/WinAlfred/Helper/SelectedRecords.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Windows.Documents;
+using WinAlfred.Plugin;
+
+namespace WinAlfred.Helper
+{
+ public class SelectedRecords
+ {
+ private int hasAddedCount = 0;
+ private Dictionary dict = new Dictionary();
+ private string filePath = Directory.GetCurrentDirectory() + "\\selectedRecords.dat";
+
+ public void LoadSelectedRecords()
+ {
+ if (File.Exists(filePath))
+ {
+ FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
+ BinaryFormatter b = new BinaryFormatter();
+ dict = (Dictionary)b.Deserialize(fileStream);
+ fileStream.Close();
+ }
+
+ if (dict.Count > 1000)
+ {
+ List onlyOnceKeys = (from c in dict where c.Value == 1 select c.Key).ToList();
+ foreach (string onlyOnceKey in onlyOnceKeys)
+ {
+ dict.Remove(onlyOnceKey);
+ }
+ }
+ }
+
+ public void AddSelect(Result result)
+ {
+ hasAddedCount++;
+ if (hasAddedCount == 10)
+ {
+ SaveSelectedRecords();
+ hasAddedCount = 0;
+ }
+
+ if (dict.ContainsKey(result.ToString()))
+ {
+ dict[result.ToString()] += 1;
+ }
+ else
+ {
+ dict.Add(result.ToString(), 1);
+ }
+ }
+
+ public int GetSelectedCount(Result result)
+ {
+ if (dict.ContainsKey(result.ToString()))
+ {
+ return dict[result.ToString()];
+ }
+ return 0;
+ }
+
+ private void SaveSelectedRecords()
+ {
+ FileStream fileStream = new FileStream("selectedRecords.dat", FileMode.Create);
+ BinaryFormatter b = new BinaryFormatter();
+ b.Serialize(fileStream, dict);
+ fileStream.Close();
+ }
+ }
+}
diff --git a/WinAlfred/Images/bookmark.png b/WinAlfred/Images/bookmark.png
new file mode 100644
index 000000000..b8aee3564
Binary files /dev/null and b/WinAlfred/Images/bookmark.png differ
diff --git a/WinAlfred/Images/close.png b/WinAlfred/Images/close.png
new file mode 100644
index 000000000..5ddfe20b8
Binary files /dev/null and b/WinAlfred/Images/close.png differ
diff --git a/WinAlfred/Images/cmd.png b/WinAlfred/Images/cmd.png
new file mode 100644
index 000000000..4e4ca0944
Binary files /dev/null and b/WinAlfred/Images/cmd.png differ
diff --git a/WinAlfred/Images/enter.png b/WinAlfred/Images/enter.png
new file mode 100644
index 000000000..0999b37cd
Binary files /dev/null and b/WinAlfred/Images/enter.png differ
diff --git a/WinAlfred/Images/exit.png b/WinAlfred/Images/exit.png
new file mode 100644
index 000000000..af7c73824
Binary files /dev/null and b/WinAlfred/Images/exit.png differ
diff --git a/Plugins/WinAlfred.Plugin.System/Images/lock.png b/WinAlfred/Images/folder.png
similarity index 59%
rename from Plugins/WinAlfred.Plugin.System/Images/lock.png
rename to WinAlfred/Images/folder.png
index 5a1593aaf..330cb2e4b 100644
Binary files a/Plugins/WinAlfred.Plugin.System/Images/lock.png and b/WinAlfred/Images/folder.png differ
diff --git a/WinAlfred/Images/lock.png b/WinAlfred/Images/lock.png
new file mode 100644
index 000000000..3eaa9abaa
Binary files /dev/null and b/WinAlfred/Images/lock.png differ
diff --git a/WinAlfred/Images/logoff.png b/WinAlfred/Images/logoff.png
new file mode 100644
index 000000000..73c1379b2
Binary files /dev/null and b/WinAlfred/Images/logoff.png differ
diff --git a/WinAlfred/Images/work.png b/WinAlfred/Images/work.png
new file mode 100644
index 000000000..aa447afd8
Binary files /dev/null and b/WinAlfred/Images/work.png differ
diff --git a/WinAlfred/MainWindow.xaml b/WinAlfred/MainWindow.xaml
index 0d1d3d8bb..02da826d8 100644
--- a/WinAlfred/MainWindow.xaml
+++ b/WinAlfred/MainWindow.xaml
@@ -12,9 +12,15 @@
ShowInTaskbar="False"
Icon="Images\ico.png"
>
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/WinAlfred/MainWindow.xaml.cs b/WinAlfred/MainWindow.xaml.cs
index 7eea9d383..35fd1f299 100644
--- a/WinAlfred/MainWindow.xaml.cs
+++ b/WinAlfred/MainWindow.xaml.cs
@@ -1,34 +1,56 @@
using System;
using System.Collections.Generic;
-using System.IO.Ports;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
-using System.Windows.Threading;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using IWshRuntimeLibrary;
+using Microsoft.Win32;
+using WinAlfred.Commands;
using WinAlfred.Helper;
using WinAlfred.Plugin;
using WinAlfred.PluginLoader;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
+using MessageBox = System.Windows.MessageBox;
+using Timer = System.Threading.Timer;
namespace WinAlfred
{
- public partial class MainWindow : Window
+ public partial class MainWindow
{
private KeyboardHook hook = new KeyboardHook();
- public List plugins = new List();
- private List results = new List();
- private NotifyIcon notifyIcon = null;
+ private NotifyIcon notifyIcon;
+ private Command cmdDispatcher;
+ Storyboard progressBarStoryboard = new Storyboard();
+ private bool queryHasReturn = false;
+ SelectedRecords selectedRecords = new SelectedRecords();
public MainWindow()
{
InitializeComponent();
+
hook.KeyPressed += OnHotKey;
hook.RegisterHotKey(XModifierKeys.Alt, Keys.Space);
resultCtrl.resultItemChangedEvent += resultCtrl_resultItemChangedEvent;
- ThreadPool.SetMaxThreads(10, 5);
+ ThreadPool.SetMaxThreads(30, 10);
+ InitProgressbarAnimation();
+ }
+
+ 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)));
+ Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)"));
+ Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)"));
+ progressBarStoryboard.Children.Add(da);
+ progressBarStoryboard.Children.Add(da1);
+ progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever;
+ progressBar.Visibility = Visibility.Hidden;
+ progressBar.BeginStoryboard(progressBarStoryboard);
}
private void InitialTray()
@@ -38,11 +60,7 @@ namespace WinAlfred
System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Open");
open.Click += (o, e) => ShowWinAlfred();
System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
- exit.Click += (o, e) =>
- {
- notifyIcon.Visible = false;
- Close();
- };
+ exit.Click += (o, e) => CloseApp();
System.Windows.Forms.MenuItem[] childen = { open, exit };
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
}
@@ -50,7 +68,7 @@ namespace WinAlfred
private void resultCtrl_resultItemChangedEvent()
{
Height = resultCtrl.pnlContainer.ActualHeight + tbQuery.Height + tbQuery.Margin.Top + tbQuery.Margin.Bottom;
- resultCtrl.Margin = results.Count > 0 ? new Thickness { Bottom = 10, Left = 10, Right = 10 } : new Thickness { Bottom = 0, Left = 10, Right = 10 };
+ resultCtrl.Margin = resultCtrl.GetCurrentResultCount() > 0 ? new Thickness { Bottom = 10, Left = 10, Right = 10 } : new Thickness { Bottom = 0, Left = 10, Right = 10 };
}
private void OnHotKey(object sender, KeyPressedEventArgs e)
@@ -65,40 +83,53 @@ namespace WinAlfred
}
}
+ protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
+ {
+ base.OnMouseLeftButtonDown(e);
+
+ // Begin dragging the window
+ this.DragMove();
+ }
+
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{
- string query = tbQuery.Text;
- ThreadPool.QueueUserWorkItem(state =>
- {
- results.Clear();
- foreach (PluginPair pair in plugins)
- {
- var q = new Query(query);
- if (pair.Metadata.ActionKeyword == q.ActionName)
- {
- try
- {
- results.AddRange(pair.Plugin.Query(q));
- results.ForEach(o => o.PluginDirectory = pair.Metadata.PluginDirecotry);
- }
- catch (Exception queryException)
- {
- Log.Error(string.Format("Plugin {0} query failed: {1}", pair.Metadata.Name,
- queryException.Message));
-#if (DEBUG)
- {
- throw;
- }
-#endif
- }
- }
- }
- resultCtrl.Dispatcher.Invoke(new Action(() =>
- {
- resultCtrl.AddResults(results.OrderByDescending(o => o.Score).ToList());
- resultCtrl.SelectFirst();
- }));
- });
+ resultCtrl.Dirty = true;
+ Dispatcher.DelayInvoke("UpdateSearch",
+ o =>
+ {
+ Dispatcher.DelayInvoke("ClearResults", i =>
+ {
+ // 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
+ // must clear the result. otherwise, it will be confused why the query changed, but the results
+ // didn't.
+ if (resultCtrl.Dirty) resultCtrl.Clear();
+ }, TimeSpan.FromMilliseconds(30), null);
+ var q = new Query(tbQuery.Text);
+ cmdDispatcher.DispatchCommand(q);
+ queryHasReturn = false;
+ if (Plugins.HitThirdpartyKeyword(q))
+ {
+ Dispatcher.DelayInvoke("ShowProgressbar", originQuery =>
+ {
+ if (!queryHasReturn && originQuery == tbQuery.Text)
+ {
+ StartProgress();
+ }
+ }, TimeSpan.FromSeconds(1), tbQuery.Text);
+ }
+
+ }, TimeSpan.FromMilliseconds(300));
+ }
+
+ private void StartProgress()
+ {
+ progressBar.Visibility = Visibility.Visible;
+ }
+
+ private void StopProgress()
+ {
+ progressBar.Visibility = Visibility.Hidden;
}
private void HideWinAlfred()
@@ -108,19 +139,46 @@ namespace WinAlfred
private void ShowWinAlfred()
{
- tbQuery.SelectAll();
Show();
- Focus();
- FocusManager.SetFocusedElement(this, tbQuery);
+ //FocusManager.SetFocusedElement(this, tbQuery);
+ tbQuery.Focusable = true;
+ Keyboard.Focus(tbQuery);
+ tbQuery.SelectAll();
+
+ if (!tbQuery.IsKeyboardFocused)
+ {
+ MessageBox.Show("didnt focus");
+ }
+ }
+
+ private void SetAutoStart(bool IsAtuoRun)
+ {
+ string LnkPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "//WinAlfred.lnk";
+ if (IsAtuoRun)
+ {
+ WshShell shell = new WshShell();
+ IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(LnkPath);
+ shortcut.TargetPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
+ shortcut.WorkingDirectory = Environment.CurrentDirectory;
+ shortcut.WindowStyle = 1; //normal window
+ shortcut.Description = "WinAlfred";
+ shortcut.Save();
+ }
+ else
+ {
+ System.IO.File.Delete(LnkPath);
+ }
}
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
- plugins.AddRange(new PythonPluginLoader().LoadPlugin());
- plugins.AddRange(new CSharpPluginLoader().LoadPlugin());
-
- ShowWinAlfred();
+ Plugins.Init(this);
+ cmdDispatcher = new Command(this);
InitialTray();
+ selectedRecords.LoadSelectedRecords();
+ SetAutoStart(true);
+ //var engine = new Jurassic.ScriptEngine();
+ //MessageBox.Show(engine.Evaluate("5 * 10 + 2").ToString());
}
private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e)
@@ -143,11 +201,70 @@ namespace WinAlfred
break;
case Key.Enter:
- resultCtrl.AcceptSelect();
- HideWinAlfred();
+ Result result = resultCtrl.AcceptSelect();
+ if (result != null)
+ {
+ selectedRecords.AddSelect(result);
+ if (!result.DontHideWinAlfredAfterAction)
+ {
+ HideWinAlfred();
+ }
+ }
e.Handled = true;
break;
}
}
+
+ public void OnUpdateResultView(List list)
+ {
+ queryHasReturn = true;
+ progressBar.Dispatcher.Invoke(new Action(StopProgress));
+ if (list.Count > 0)
+ {
+ list.ForEach(o =>
+ {
+ o.Score += selectedRecords.GetSelectedCount(o);
+ });
+ resultCtrl.Dispatcher.Invoke(new Action(() =>
+ {
+ List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).OrderByDescending(o => o.Score).ToList();
+ resultCtrl.AddResults(l);
+ }));
+ }
+ }
+
+ #region Public API
+
+ //Those method can be invoked by plugins
+
+ public void ChangeQuery(string query)
+ {
+ tbQuery.Text = query;
+ tbQuery.CaretIndex = tbQuery.Text.Length;
+ }
+
+ public void CloseApp()
+ {
+ notifyIcon.Visible = false;
+ Close();
+ }
+
+ public void HideApp()
+ {
+ HideWinAlfred();
+ }
+
+ public void ShowApp()
+ {
+ ShowWinAlfred();
+ }
+
+ public void ShowMsg(string title, string subTitle, string iconPath)
+ {
+ Msg m = new Msg { Owner = GetWindow(this) };
+ m.Show(title, subTitle, iconPath);
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/WinAlfred/Msg.xaml b/WinAlfred/Msg.xaml
new file mode 100644
index 000000000..06d7a65d6
--- /dev/null
+++ b/WinAlfred/Msg.xaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Title
+ sdfdsf
+
+
+
+
diff --git a/WinAlfred/Msg.xaml.cs b/WinAlfred/Msg.xaml.cs
new file mode 100644
index 000000000..5959f7286
--- /dev/null
+++ b/WinAlfred/Msg.xaml.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Forms;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+using Timer = System.Threading.Timer;
+
+namespace WinAlfred
+{
+ public partial class Msg : Window
+ {
+ Storyboard fadeOutStoryboard = new Storyboard();
+ private bool closing = false;
+
+ public Msg()
+ {
+ InitializeComponent();
+
+ Left = Screen.PrimaryScreen.WorkingArea.Right - this.Width;
+ Top = Screen.PrimaryScreen.Bounds.Bottom;
+ showAnimation.From = Screen.PrimaryScreen.Bounds.Bottom;
+ showAnimation.To = Screen.PrimaryScreen.WorkingArea.Bottom - Height;
+
+ // Create the fade out storyboard
+ fadeOutStoryboard.Completed += new EventHandler(fadeOutStoryboard_Completed);
+ DoubleAnimation fadeOutAnimation = new DoubleAnimation(Screen.PrimaryScreen.WorkingArea.Bottom - Height, Screen.PrimaryScreen.Bounds.Bottom, new Duration(TimeSpan.FromSeconds(0.3)))
+ {
+ AccelerationRatio = 0.2
+ };
+ Storyboard.SetTarget(fadeOutAnimation, this);
+ Storyboard.SetTargetProperty(fadeOutAnimation, new PropertyPath(TopProperty));
+ fadeOutStoryboard.Children.Add(fadeOutAnimation);
+
+ imgClose.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + "\\Images\\close.png"));
+ imgClose.MouseUp += imgClose_MouseUp;
+ }
+
+ void imgClose_MouseUp(object sender, MouseButtonEventArgs e)
+ {
+ if (!closing)
+ {
+ closing = true;
+ fadeOutStoryboard.Begin();
+ }
+ }
+
+ private void fadeOutStoryboard_Completed(object sender, EventArgs e)
+ {
+ Close();
+ }
+
+ public void Show(string title, string subTitle, string icopath)
+ {
+ tbTitle.Text = title;
+ tbSubTitle.Text = subTitle;
+ if (!File.Exists(icopath))
+ {
+ icopath = AppDomain.CurrentDomain.BaseDirectory + "Images\\ico.png";
+ }
+ imgIco.Source = new BitmapImage(new Uri(icopath));
+ Show();
+
+ Dispatcher.DelayInvoke("ShowMsg",
+ o =>
+ {
+ if (!closing)
+ {
+ closing = true;
+ Dispatcher.Invoke(new Action(fadeOutStoryboard.Begin));
+ }
+ }, TimeSpan.FromSeconds(3));
+ }
+ }
+}
diff --git a/WinAlfred/PluginLoader/BasePluginLoader.cs b/WinAlfred/PluginLoader/BasePluginLoader.cs
index d16042b49..6a48e7aa0 100644
--- a/WinAlfred/PluginLoader/BasePluginLoader.cs
+++ b/WinAlfred/PluginLoader/BasePluginLoader.cs
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
+using System.Reflection;
using WinAlfred.Helper;
using WinAlfred.Plugin;
+using WinAlfred.Plugin.System;
namespace WinAlfred.PluginLoader
{
@@ -21,11 +24,27 @@ namespace WinAlfred.PluginLoader
private static void ParsePlugins()
{
- ParseDirectories();
- ParsePackagedPlugin();
+ ParseSystemPlugins();
+ ParseThirdPartyPlugins();
}
- private static void ParseDirectories()
+ private static void ParseSystemPlugins()
+ {
+ PluginMetadata metadata = new PluginMetadata();
+ metadata.Name = "System Plugins";
+ metadata.Author = "System";
+ metadata.Description = "system plugins collection";
+ metadata.Language = AllowedLanguage.CSharp;
+ metadata.Version = "1.0";
+ metadata.PluginType = PluginType.System;
+ metadata.ActionKeyword = "*";
+ metadata.ExecuteFileName = "WinAlfred.Plugin.System.dll";
+ metadata.ExecuteFilePath = AppDomain.CurrentDomain.BaseDirectory + metadata.ExecuteFileName;
+ metadata.PluginDirecotry = AppDomain.CurrentDomain.BaseDirectory;
+ pluginMetadatas.Add(metadata);
+ }
+
+ private static void ParseThirdPartyPlugins()
{
string[] directories = Directory.GetDirectories(PluginPath);
foreach (string directory in directories)
@@ -35,11 +54,6 @@ namespace WinAlfred.PluginLoader
}
}
- private static void ParsePackagedPlugin()
- {
-
- }
-
private static PluginMetadata GetMetadataFromIni(string directory)
{
string iniPath = directory + "\\" + PluginConfigName;
@@ -50,7 +64,6 @@ namespace WinAlfred.PluginLoader
return null;
}
-
try
{
PluginMetadata metadata = new PluginMetadata();
@@ -60,6 +73,7 @@ namespace WinAlfred.PluginLoader
metadata.Description = ini.GetSetting("plugin", "Description");
metadata.Language = ini.GetSetting("plugin", "Language");
metadata.Version = ini.GetSetting("plugin", "Version");
+ metadata.PluginType = PluginType.ThirdParty;
metadata.ActionKeyword = ini.GetSetting("plugin", "ActionKeyword");
metadata.ExecuteFilePath = AppDomain.CurrentDomain.BaseDirectory + directory + "\\" + ini.GetSetting("plugin", "ExecuteFile");
metadata.PluginDirecotry = AppDomain.CurrentDomain.BaseDirectory + directory + "\\";
diff --git a/WinAlfred/PluginLoader/CSharpPluginLoader.cs b/WinAlfred/PluginLoader/CSharpPluginLoader.cs
index db857a830..25346eb3f 100644
--- a/WinAlfred/PluginLoader/CSharpPluginLoader.cs
+++ b/WinAlfred/PluginLoader/CSharpPluginLoader.cs
@@ -5,6 +5,7 @@ using System.Reflection;
using System.Threading;
using WinAlfred.Helper;
using WinAlfred.Plugin;
+using WinAlfred.Plugin.System;
namespace WinAlfred.PluginLoader
{
@@ -20,28 +21,23 @@ namespace WinAlfred.PluginLoader
try
{
Assembly asm = Assembly.LoadFile(metadata.ExecuteFilePath);
- List types = asm.GetTypes().Where(o => o.GetInterfaces().Contains(typeof (IPlugin))).ToList();
+ List types = asm.GetTypes().Where(o => o.IsClass && o.GetInterfaces().Contains(typeof(IPlugin)) || o.GetInterfaces().Contains(typeof(ISystemPlugin))).ToList();
if (types.Count == 0)
{
Log.Error(string.Format("Cound't load plugin {0}: didn't find the class who implement IPlugin",
metadata.Name));
continue;
}
- if (types.Count > 1)
- {
- Log.Error(
- string.Format(
- "Cound't load plugin {0}: find more than one class who implement IPlugin, there should only one class implement IPlugin",
- metadata.Name));
- continue;
- }
- PluginPair pair = new PluginPair()
+ foreach (Type type in types)
{
- Plugin = Activator.CreateInstance(types[0]) as IPlugin,
- Metadata = metadata
- };
- plugins.Add(pair);
+ PluginPair pair = new PluginPair()
+ {
+ Plugin = Activator.CreateInstance(type) as IPlugin,
+ Metadata = metadata
+ };
+ plugins.Add(pair);
+ }
}
catch (Exception e)
{
@@ -61,10 +57,7 @@ namespace WinAlfred.PluginLoader
private void InitPlugin(List plugins)
{
- foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin))
- {
- new Thread(plugin.Init).Start();
- }
+
}
}
}
diff --git a/WinAlfred/PluginLoader/Plugins.cs b/WinAlfred/PluginLoader/Plugins.cs
new file mode 100644
index 000000000..06bbceb65
--- /dev/null
+++ b/WinAlfred/PluginLoader/Plugins.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using WinAlfred.Plugin;
+
+namespace WinAlfred.PluginLoader
+{
+ public static class Plugins
+ {
+ private static List plugins = new List();
+
+ public static void Init(MainWindow window)
+ {
+ plugins.Clear();
+ plugins.AddRange(new PythonPluginLoader().LoadPlugin());
+ plugins.AddRange(new CSharpPluginLoader().LoadPlugin());
+ foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin))
+ {
+ IPlugin plugin1 = plugin;
+ ThreadPool.QueueUserWorkItem(o => plugin1.Init(new PluginInitContext()
+ {
+ Plugins = plugins,
+ ChangeQuery = s => window.ChangeQuery(s),
+ CloseApp = window.CloseApp,
+ HideApp = window.HideApp,
+ ShowApp = window.ShowApp,
+ ShowMsg = (title, subTitle, iconPath) => window.ShowMsg(title, subTitle, iconPath)
+ }));
+ }
+ }
+
+ public static List AllPlugins
+ {
+ get { return plugins; }
+ }
+
+ public static bool HitThirdpartyKeyword(Query query)
+ {
+ if (string.IsNullOrEmpty(query.ActionName)) return false;
+
+ return plugins.Any(o => o.Metadata.PluginType == PluginType.ThirdParty && o.Metadata.ActionKeyword == query.ActionName);
+ }
+ }
+}
diff --git a/WinAlfred/PluginLoader/PythonPluginLoader.cs b/WinAlfred/PluginLoader/PythonPluginLoader.cs
index baa5052c4..955ec55ef 100644
--- a/WinAlfred/PluginLoader/PythonPluginLoader.cs
+++ b/WinAlfred/PluginLoader/PythonPluginLoader.cs
@@ -22,10 +22,6 @@ namespace WinAlfred.PluginLoader
plugins.Add(pair);
}
- foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin))
- {
- new Thread(plugin.Init).Start();
- }
return plugins;
}
}
diff --git a/WinAlfred/PluginLoader/PythonPluginWrapper.cs b/WinAlfred/PluginLoader/PythonPluginWrapper.cs
index c9647a573..2dad73816 100644
--- a/WinAlfred/PluginLoader/PythonPluginWrapper.cs
+++ b/WinAlfred/PluginLoader/PythonPluginWrapper.cs
@@ -55,7 +55,7 @@ namespace WinAlfred.PluginLoader
}
- public void Init()
+ public void Init(PluginInitContext context)
{
InitPythonEnv();
}
diff --git a/WinAlfred/Properties/Resources.Designer.cs b/WinAlfred/Properties/Resources.Designer.cs
index 5b4270b0d..c04e7374e 100644
--- a/WinAlfred/Properties/Resources.Designer.cs
+++ b/WinAlfred/Properties/Resources.Designer.cs
@@ -1,73 +1,73 @@
-//------------------------------------------------------------------------------
-//
-// 此代码由工具生成。
-// 运行时版本:4.0.30319.18052
-//
-// 对此文件的更改可能会导致不正确的行为,并且如果
-// 重新生成代码,这些更改将会丢失。
-//
-//------------------------------------------------------------------------------
-
-namespace WinAlfred.Properties {
- using System;
-
-
- ///
- /// 一个强类型的资源类,用于查找本地化的字符串等。
- ///
- // 此类是由 StronglyTypedResourceBuilder
- // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
- // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
- // (以 /str 作为命令选项),或重新生成 VS 项目。
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// 返回此类使用的缓存的 ResourceManager 实例。
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WinAlfred.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// 使用此强类型资源类,为所有资源查找
- /// 重写当前线程的 CurrentUICulture 属性。
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
- ///
- internal static System.Drawing.Icon app {
- get {
- object obj = ResourceManager.GetObject("app", resourceCulture);
- return ((System.Drawing.Icon)(obj));
- }
- }
- }
-}
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.18052
+//
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace WinAlfred.Properties {
+ using System;
+
+
+ ///
+ /// 一个强类型的资源类,用于查找本地化的字符串等。
+ ///
+ // 此类是由 StronglyTypedResourceBuilder
+ // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+ // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+ // (以 /str 作为命令选项),或重新生成 VS 项目。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// 返回此类使用的缓存的 ResourceManager 实例。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WinAlfred.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 使用此强类型资源类,为所有资源查找
+ /// 重写当前线程的 CurrentUICulture 属性。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
+ ///
+ internal static System.Drawing.Icon app {
+ get {
+ object obj = ResourceManager.GetObject("app", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+ }
+}
diff --git a/WinAlfred/Properties/Settings.Designer.cs b/WinAlfred/Properties/Settings.Designer.cs
index d6abbf65e..caf9c18c1 100644
--- a/WinAlfred/Properties/Settings.Designer.cs
+++ b/WinAlfred/Properties/Settings.Designer.cs
@@ -1,26 +1,26 @@
-//------------------------------------------------------------------------------
-//
-// 此代码由工具生成。
-// 运行时版本:4.0.30319.18052
-//
-// 对此文件的更改可能会导致不正确的行为,并且如果
-// 重新生成代码,这些更改将会丢失。
-//
-//------------------------------------------------------------------------------
-
-namespace WinAlfred.Properties {
-
-
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
- private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default {
- get {
- return defaultInstance;
- }
- }
- }
-}
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.18052
+//
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace WinAlfred.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/WinAlfred/ResultItem.xaml b/WinAlfred/ResultItem.xaml
index c20bdecc6..34d3ef4d2 100644
--- a/WinAlfred/ResultItem.xaml
+++ b/WinAlfred/ResultItem.xaml
@@ -21,9 +21,9 @@
Title
sdfdsf
-
-
-
+
+
+
diff --git a/WinAlfred/ResultItem.xaml.cs b/WinAlfred/ResultItem.xaml.cs
index ec251335d..389ee3af3 100644
--- a/WinAlfred/ResultItem.xaml.cs
+++ b/WinAlfred/ResultItem.xaml.cs
@@ -1,8 +1,12 @@
using System;
+using System.Drawing;
+using System.IO;
+using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using WinAlfred.Plugin;
+using Brush = System.Windows.Media.Brush;
namespace WinAlfred
{
@@ -23,6 +27,15 @@ namespace WinAlfred
selected = value;
BrushConverter bc = new BrushConverter();
Background = selected ? (Brush)(bc.ConvertFrom("#d1d1d1")) : (Brush)(bc.ConvertFrom("#ebebeb"));
+ if (selected)
+ {
+ img.Visibility = Visibility.Visible;
+ img.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory()+"\\Images\\enter.png"));
+ }
+ else
+ {
+ img.Visibility = Visibility.Hidden;
+ }
}
}
@@ -39,10 +52,36 @@ namespace WinAlfred
tbTitle.Text = result.Title;
tbSubTitle.Text = result.SubTitle;
- if (!string.IsNullOrEmpty(result.IcoPath))
+ string path = string.Empty;
+ if (!string.IsNullOrEmpty(result.IcoPath) && result.IcoPath.Contains(":\\") && File.Exists(result.IcoPath))
{
- imgIco.Source = new BitmapImage(new Uri(result.PluginDirectory + 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));
+ }
+ }
+ }
+
+ public 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());
}
}
}
diff --git a/WinAlfred/ResultPanel.xaml.cs b/WinAlfred/ResultPanel.xaml.cs
index 40314fcad..26aa8f959 100644
--- a/WinAlfred/ResultPanel.xaml.cs
+++ b/WinAlfred/ResultPanel.xaml.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using WinAlfred.Plugin;
@@ -7,6 +8,8 @@ namespace WinAlfred
{
public partial class ResultPanel : UserControl
{
+ public bool Dirty { get; set; }
+
public delegate void ResultItemsChanged();
public event ResultItemsChanged resultItemChangedEvent;
@@ -19,15 +22,26 @@ namespace WinAlfred
public void AddResults(List results)
{
- pnlContainer.Children.Clear();
+ if (results.Count == 0) return;
+
+ if (Dirty)
+ {
+ Dirty = false;
+ pnlContainer.Children.Clear();
+ }
+
for (int i = 0; i < results.Count; i++)
{
Result result = results[i];
- ResultItem control = new ResultItem(result);
- control.SetIndex(i + 1);
- pnlContainer.Children.Add(control);
+ if (!CheckExisted(result))
+ {
+ ResultItem control = new ResultItem(result);
+ control.SetIndex(i + 1);
+ pnlContainer.Children.Insert(GetInsertLocation(result.Score), control);
+ }
}
+ SelectFirst();
pnlContainer.UpdateLayout();
double resultItemHeight = 0;
@@ -37,11 +51,43 @@ namespace WinAlfred
if (resultItem != null)
resultItemHeight = resultItem.ActualHeight;
}
- pnlContainer.Height = results.Count * resultItemHeight;
+ pnlContainer.Height = pnlContainer.Children.Count * resultItemHeight;
OnResultItemChangedEvent();
}
- private int GetCurrentSelectedResultIndex()
+ private bool CheckExisted(Result result)
+ {
+ return pnlContainer.Children.Cast().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;
+
+ for (int index = 1; index < pnlContainer.Children.Count; index++)
+ {
+ ResultItem next = pnlContainer.Children[index] as ResultItem;
+ ResultItem prev = pnlContainer.Children[index - 1] as ResultItem;
+ if (next != null && prev != null)
+ {
+ if ((currentScore >= next.Result.Score && currentScore <= prev.Result.Score))
+ {
+ location = index;
+ }
+ }
+ }
+
+ return location;
+ }
+
+ public int GetCurrentResultCount()
+ {
+ return pnlContainer.Children.Count;
+ }
+
+ public int GetCurrentSelectedResultIndex()
{
for (int i = 0; i < pnlContainer.Children.Count; i++)
{
@@ -114,7 +160,7 @@ namespace WinAlfred
if (index < oldIndex)
{
//move up and old item is at the top of the scroll view
- if ( newItemBottomPoint.Y - sv.VerticalOffset == 0)
+ if (newItemBottomPoint.Y - sv.VerticalOffset == 0)
{
scrollPosition = sv.VerticalOffset - resultItemControl.ActualHeight;
}
@@ -146,19 +192,35 @@ namespace WinAlfred
Select(0);
}
- public void AcceptSelect()
+ public Result AcceptSelect()
{
int index = GetCurrentSelectedResultIndex();
+ if (index < 0) return null;
+
var resultItemControl = pnlContainer.Children[index] as ResultItem;
if (resultItemControl != null)
{
- if (resultItemControl.Result.Action != null) resultItemControl.Result.Action();
+ if (resultItemControl.Result.Action != null)
+ {
+ resultItemControl.Result.Action();
+ }
+
+ return resultItemControl.Result;
}
+
+ return null;
}
public ResultPanel()
{
InitializeComponent();
}
+
+ public void Clear()
+ {
+ pnlContainer.Children.Clear();
+ pnlContainer.Height = 0;
+ OnResultItemChangedEvent();
+ }
}
}
\ No newline at end of file
diff --git a/WinAlfred/WinAlfred.csproj b/WinAlfred/WinAlfred.csproj
index 02dcadb30..66418b728 100644
--- a/WinAlfred/WinAlfred.csproj
+++ b/WinAlfred/WinAlfred.csproj
@@ -9,7 +9,7 @@
Properties
WinAlfred
WinAlfred
- v4.0
+ v3.5
512
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
4
@@ -39,22 +39,47 @@
app.ico
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
..\packages\log4net.2.0.3\lib\net35-full\log4net.dll
..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll
+
+
+
+
+
+
@@ -64,12 +89,21 @@
MSBuild:Compile
Designer
-
+
+
+
+
+
+
+ Msg.xaml
+
+
+
@@ -78,6 +112,7 @@
ResultItem.xaml
+
MSBuild:Compile
Designer
@@ -90,6 +125,10 @@
MainWindow.xaml
Code
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -128,6 +167,10 @@
+
+ {69ce0206-cb41-453d-88af-df86092ef9b8}
+ WinAlfred.Plugin.System
+
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}
WinAlfred.Plugin
@@ -148,8 +191,22 @@
+
+
+ {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}
+ 1
+ 0
+ 0
+ tlbimp
+ False
+ True
+
+
+
+ xcopy /Y $(ProjectDir)Images\*.* $(SolutionDir)WinAlfred\bin\Debug\Images\
+