Rename the project.
20
Wox/App.config
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
|
||||
</configSections>
|
||||
<log4net>
|
||||
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
|
||||
<file value="log.txt"/>
|
||||
<appendToFile value="true"/>
|
||||
<rollingStyle value="Date"/>
|
||||
<datePattern value="yyyyMMdd-HH:mm:ss"/>
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="Date:%date Level:%-5level Msg:%message%newline"/>
|
||||
</layout>
|
||||
</appender>
|
||||
<root>
|
||||
<appender-ref ref="LogFileAppender"/>
|
||||
</root>
|
||||
</log4net>
|
||||
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
|
||||
12
Wox/App.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<Application x:Class="Wox.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
>
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Themes/Default.xaml"></ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
80
Wox/App.xaml.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using Microsoft.VisualBasic.ApplicationServices;
|
||||
using Wox.Commands;
|
||||
using StartupEventArgs = System.Windows.StartupEventArgs;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public static class EntryPoint
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
SingleInstanceManager manager = new SingleInstanceManager();
|
||||
manager.Run(args);
|
||||
}
|
||||
}
|
||||
|
||||
// Using VB bits to detect single instances and process accordingly:
|
||||
// * OnStartup is fired when the first instance loads
|
||||
// * OnStartupNextInstance is fired when the application is re-run again
|
||||
// NOTE: it is redirected to this instance thanks to IsSingleInstance
|
||||
public class SingleInstanceManager : WindowsFormsApplicationBase
|
||||
{
|
||||
App app;
|
||||
|
||||
public SingleInstanceManager()
|
||||
{
|
||||
this.IsSingleInstance = true;
|
||||
}
|
||||
|
||||
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
|
||||
{
|
||||
// First time app is launched
|
||||
app = new App();
|
||||
app.InitializeComponent();
|
||||
app.Run();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
|
||||
{
|
||||
// Subsequent launches
|
||||
base.OnStartupNextInstance(eventArgs);
|
||||
app.Activate(eventArgs.CommandLine.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
|
||||
private static MainWindow window;
|
||||
|
||||
public static MainWindow Window
|
||||
{
|
||||
get
|
||||
{
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
window = new MainWindow();
|
||||
window.ShowApp();
|
||||
window.ParseArgs(e.Args);
|
||||
}
|
||||
|
||||
public void Activate(string[] args)
|
||||
{
|
||||
window.ShowApp();
|
||||
window.ParseArgs(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Wox/Commands/BaseCommand.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Commands
|
||||
{
|
||||
public abstract class BaseCommand
|
||||
{
|
||||
public abstract void Dispatch(Query query, bool updateView = true);
|
||||
|
||||
protected void UpdateResultView(List<Result> results)
|
||||
{
|
||||
App.Window.OnUpdateResultView(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Wox/Commands/CommandFactory.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Commands
|
||||
{
|
||||
internal static class CommandFactory
|
||||
{
|
||||
private static PluginCommand pluginCmd;
|
||||
private static SystemCommand systemCmd;
|
||||
|
||||
public static void DispatchCommand(Query query, bool updateView = true)
|
||||
{
|
||||
//lazy init command instance.
|
||||
if (pluginCmd == null)
|
||||
{
|
||||
pluginCmd = new PluginCommand();
|
||||
}
|
||||
if (systemCmd == null)
|
||||
{
|
||||
systemCmd = new SystemCommand();
|
||||
}
|
||||
|
||||
systemCmd.Dispatch(query,updateView);
|
||||
pluginCmd.Dispatch(query,updateView);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Wox/Commands/PluginCommand.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Python.Runtime;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
using Wox.PluginLoader;
|
||||
|
||||
namespace Wox.Commands
|
||||
{
|
||||
public class PluginCommand : BaseCommand
|
||||
{
|
||||
private string currentPythonModulePath = string.Empty;
|
||||
private IntPtr GIL;
|
||||
|
||||
public override void Dispatch(Query q,bool updateView = true)
|
||||
{
|
||||
PluginPair thirdPlugin = Plugins.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == q.ActionName);
|
||||
if (thirdPlugin != null && !string.IsNullOrEmpty(thirdPlugin.Metadata.ActionKeyword))
|
||||
{
|
||||
if (thirdPlugin.Metadata.Language == AllowedLanguage.Python)
|
||||
{
|
||||
SwitchPythonEnv(thirdPlugin);
|
||||
}
|
||||
ThreadPool.QueueUserWorkItem(t =>
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Result> r = thirdPlugin.Plugin.Query(q);
|
||||
r.ForEach(o =>
|
||||
{
|
||||
o.PluginDirectory = thirdPlugin.Metadata.PluginDirecotry;
|
||||
o.OriginQuery = q;
|
||||
});
|
||||
if(updateView) UpdateResultView(r);
|
||||
}
|
||||
catch (Exception queryException)
|
||||
{
|
||||
Log.Error(string.Format("Plugin {0} query failed: {1}", thirdPlugin.Metadata.Name,
|
||||
queryException.Message));
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void SwitchPythonEnv(PluginPair thirdPlugin)
|
||||
{
|
||||
if (currentPythonModulePath != thirdPlugin.Metadata.PluginDirecotry)
|
||||
{
|
||||
//this must initial in main thread
|
||||
currentPythonModulePath = thirdPlugin.Metadata.PluginDirecotry;
|
||||
|
||||
if (GIL != IntPtr.Zero)
|
||||
{
|
||||
Runtime.PyEval_RestoreThread(GIL);
|
||||
PythonEngine.Shutdown();
|
||||
}
|
||||
PythonEngine.Initialize();
|
||||
IntPtr pyStrPtr = Runtime.PyString_FromString(thirdPlugin.Metadata.PluginDirecotry);
|
||||
IntPtr SysDotPath = Runtime.PySys_GetObject("path");
|
||||
Runtime.PyList_Append(SysDotPath, pyStrPtr);
|
||||
GIL = PythonEngine.BeginAllowThreads();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Wox/Commands/SystemCommand.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Wox.Plugin;
|
||||
using Wox.PluginLoader;
|
||||
|
||||
namespace Wox.Commands
|
||||
{
|
||||
public class SystemCommand : BaseCommand
|
||||
{
|
||||
private List<PluginPair> systemPlugins;
|
||||
|
||||
public SystemCommand()
|
||||
{
|
||||
systemPlugins = Plugins.AllPlugins.Where(o => o.Metadata.PluginType == PluginType.System).ToList();
|
||||
}
|
||||
|
||||
public override void Dispatch(Query query,bool updateView = true)
|
||||
{
|
||||
foreach (PluginPair pair in systemPlugins)
|
||||
{
|
||||
PluginPair pair1 = pair;
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
List<Result> results = pair1.Plugin.Query(query);
|
||||
foreach (Result result in results)
|
||||
{
|
||||
result.PluginDirectory = pair1.Metadata.PluginDirecotry;
|
||||
result.OriginQuery = query;
|
||||
result.AutoAjustScore = true;
|
||||
}
|
||||
if(results.Count > 0 && updateView) UpdateResultView(results);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Wox/DispatcherExtensions.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public static class DispatcherExtensions
|
||||
{
|
||||
private static Dictionary<string, DispatcherTimer> timers =
|
||||
new Dictionary<string, DispatcherTimer>();
|
||||
private static readonly object syncRoot = new object();
|
||||
|
||||
public static string DelayInvoke(this Dispatcher dispatcher, string namedInvocation,
|
||||
Action<string> 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<string> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
85
Wox/Helper/CommonStorage.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using Wox.Models;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
[Serializable]
|
||||
public class CommonStorage
|
||||
{
|
||||
private static string configPath = Directory.GetCurrentDirectory() + "\\data.json";
|
||||
private static object locker = new object();
|
||||
private static CommonStorage storage;
|
||||
|
||||
public UserSetting UserSetting { get; set; }
|
||||
public UserSelectedRecords UserSelectedRecords { get; set; }
|
||||
|
||||
private CommonStorage()
|
||||
{
|
||||
//default setting
|
||||
UserSetting = new UserSetting
|
||||
{
|
||||
Theme = "Default",
|
||||
ReplaceWinR = true,
|
||||
WebSearches = new List<WebSearch>()
|
||||
};
|
||||
|
||||
UserSelectedRecords = new UserSelectedRecords();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
//json is a good choise, readable and flexiable
|
||||
string json = JsonConvert.SerializeObject(storage, Formatting.Indented);
|
||||
File.WriteAllText(configPath, json);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Load()
|
||||
{
|
||||
if (!File.Exists(configPath))
|
||||
{
|
||||
File.Create(configPath).Close();
|
||||
}
|
||||
string json = File.ReadAllText(configPath);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
try
|
||||
{
|
||||
storage = JsonConvert.DeserializeObject<CommonStorage>(json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//on-op, keep default storage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CommonStorage Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (storage == null)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (storage == null)
|
||||
{
|
||||
storage = new CommonStorage();
|
||||
Load();
|
||||
}
|
||||
}
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Wox/Helper/DwmDropShadow.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Drawing.Printing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public static class DwmDropShadow
|
||||
{
|
||||
|
||||
[DllImport("dwmapi.dll", PreserveSig = true)]
|
||||
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
|
||||
|
||||
/// <summary>
|
||||
/// Drops a standard shadow to a WPF Window, even if the window isborderless. Only works with DWM (Vista and Seven).
|
||||
/// This method is much more efficient than setting AllowsTransparency to true and using the DropShadow effect,
|
||||
/// as AllowsTransparency involves a huge permormance issue (hardware acceleration is turned off for all the window).
|
||||
/// </summary>
|
||||
/// <param name="window">Window to which the shadow will be applied</param>
|
||||
public static void DropShadowToWindow(Window window)
|
||||
{
|
||||
if (!DropShadow(window))
|
||||
{
|
||||
window.SourceInitialized += new EventHandler(window_SourceInitialized);
|
||||
}
|
||||
}
|
||||
|
||||
private static void window_SourceInitialized(object sender, EventArgs e) //fixed typo
|
||||
{
|
||||
Window window = (Window)sender;
|
||||
|
||||
DropShadow(window);
|
||||
|
||||
window.SourceInitialized -= new EventHandler(window_SourceInitialized);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The actual method that makes API calls to drop the shadow to the window
|
||||
/// </summary>
|
||||
/// <param name="window">Window to which the shadow will be applied</param>
|
||||
/// <returns>True if the method succeeded, false if not</returns>
|
||||
private static bool DropShadow(Window window)
|
||||
{
|
||||
try
|
||||
{
|
||||
WindowInteropHelper helper = new WindowInteropHelper(window);
|
||||
int val = 2;
|
||||
int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 2);
|
||||
|
||||
if (ret1 == 0)
|
||||
{
|
||||
Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 };
|
||||
int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m);
|
||||
return ret2 == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Probably dwmapi.dll not found (incompatible OS)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
217
Wox/Helper/IniParser.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public class IniParser
|
||||
{
|
||||
private Hashtable keyPairs = new Hashtable();
|
||||
private String iniFilePath;
|
||||
|
||||
private struct SectionPair
|
||||
{
|
||||
public String Section;
|
||||
public String Key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the INI file at the given path and enumerates the values in the IniParser.
|
||||
/// </summary>
|
||||
/// <param name="iniPath">Full path to INI file.</param>
|
||||
public IniParser(String iniPath)
|
||||
{
|
||||
TextReader iniFile = null;
|
||||
String strLine = null;
|
||||
String currentRoot = null;
|
||||
String[] keyPair = null;
|
||||
|
||||
iniFilePath = iniPath;
|
||||
|
||||
if (File.Exists(iniPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
iniFile = new StreamReader(iniPath);
|
||||
|
||||
strLine = iniFile.ReadLine();
|
||||
|
||||
while (strLine != null)
|
||||
{
|
||||
strLine = strLine.Trim();
|
||||
|
||||
if (strLine != "")
|
||||
{
|
||||
if (strLine.StartsWith("[") && strLine.EndsWith("]"))
|
||||
{
|
||||
currentRoot = strLine.Substring(1, strLine.Length - 2).ToUpper();
|
||||
}
|
||||
else
|
||||
{
|
||||
keyPair = strLine.Split(new char[] { '=' }, 2);
|
||||
|
||||
SectionPair sectionPair;
|
||||
String value = null;
|
||||
|
||||
if (currentRoot == null)
|
||||
currentRoot = "ROOT";
|
||||
|
||||
sectionPair.Section = currentRoot;
|
||||
sectionPair.Key = keyPair[0].ToUpper().Trim();
|
||||
|
||||
if (keyPair.Length > 1)
|
||||
value = keyPair[1];
|
||||
|
||||
keyPairs.Add(sectionPair, value.Trim());
|
||||
}
|
||||
}
|
||||
|
||||
strLine = iniFile.ReadLine();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (iniFile != null)
|
||||
iniFile.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new FileNotFoundException("Unable to locate " + iniPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value for the given section, key pair.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Section name.</param>
|
||||
/// <param name="settingName">Key name.</param>
|
||||
public String GetSetting(String sectionName, String settingName)
|
||||
{
|
||||
SectionPair sectionPair;
|
||||
sectionPair.Section = sectionName.ToUpper().Trim();
|
||||
sectionPair.Key = settingName.ToUpper().Trim();
|
||||
|
||||
return (String)keyPairs[sectionPair];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all lines for given section.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Section to enum.</param>
|
||||
public String[] EnumSection(String sectionName)
|
||||
{
|
||||
ArrayList tmpArray = new ArrayList();
|
||||
|
||||
foreach (SectionPair pair in keyPairs.Keys)
|
||||
{
|
||||
if (pair.Section == sectionName.ToUpper())
|
||||
tmpArray.Add(pair.Key);
|
||||
}
|
||||
|
||||
return (String[])tmpArray.ToArray(typeof(String));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or replaces a setting to the table to be saved.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Section to add under.</param>
|
||||
/// <param name="settingName">Key name to add.</param>
|
||||
/// <param name="settingValue">Value of key.</param>
|
||||
public void AddSetting(String sectionName, String settingName, String settingValue)
|
||||
{
|
||||
SectionPair sectionPair;
|
||||
sectionPair.Section = sectionName.ToUpper();
|
||||
sectionPair.Key = settingName.ToUpper();
|
||||
|
||||
if (keyPairs.ContainsKey(sectionPair))
|
||||
keyPairs.Remove(sectionPair);
|
||||
|
||||
keyPairs.Add(sectionPair, settingValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or replaces a setting to the table to be saved with a null value.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Section to add under.</param>
|
||||
/// <param name="settingName">Key name to add.</param>
|
||||
public void AddSetting(String sectionName, String settingName)
|
||||
{
|
||||
AddSetting(sectionName, settingName, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a setting.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Section to add under.</param>
|
||||
/// <param name="settingName">Key name to add.</param>
|
||||
public void DeleteSetting(String sectionName, String settingName)
|
||||
{
|
||||
SectionPair sectionPair;
|
||||
sectionPair.Section = sectionName.ToUpper();
|
||||
sectionPair.Key = settingName.ToUpper();
|
||||
|
||||
if (keyPairs.ContainsKey(sectionPair))
|
||||
keyPairs.Remove(sectionPair);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save settings to new file.
|
||||
/// </summary>
|
||||
/// <param name="newFilePath">New file path.</param>
|
||||
public void SaveSettings(String newFilePath)
|
||||
{
|
||||
ArrayList sections = new ArrayList();
|
||||
String tmpValue = "";
|
||||
String strToSave = "";
|
||||
|
||||
foreach (SectionPair sectionPair in keyPairs.Keys)
|
||||
{
|
||||
if (!sections.Contains(sectionPair.Section))
|
||||
sections.Add(sectionPair.Section);
|
||||
}
|
||||
|
||||
foreach (String section in sections)
|
||||
{
|
||||
strToSave += ("[" + section + "]\r\n");
|
||||
|
||||
foreach (SectionPair sectionPair in keyPairs.Keys)
|
||||
{
|
||||
if (sectionPair.Section == section)
|
||||
{
|
||||
tmpValue = (String)keyPairs[sectionPair];
|
||||
|
||||
if (tmpValue != null)
|
||||
tmpValue = "=" + tmpValue;
|
||||
|
||||
strToSave += (sectionPair.Key + tmpValue + "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
strToSave += "\r\n";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TextWriter tw = new StreamWriter(newFilePath);
|
||||
tw.Write(strToSave);
|
||||
tw.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save settings back to ini file.
|
||||
/// </summary>
|
||||
public void SaveSettings()
|
||||
{
|
||||
SaveSettings(iniFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
154
Wox/Helper/KeyboardHook.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public sealed class KeyboardHook : IDisposable
|
||||
{
|
||||
// Registers a hot key with Windows.
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
|
||||
// Unregisters the hot key with Windows.
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
/// <summary>
|
||||
/// Represents the window that is used internally to get the messages.
|
||||
/// </summary>
|
||||
private class Window : NativeWindow, IDisposable
|
||||
{
|
||||
private static int wmHotkey = 0x0312;
|
||||
|
||||
public Window()
|
||||
{
|
||||
// create the handle for the window.
|
||||
CreateHandle(new CreateParams());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to get the notifications.
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
base.WndProc(ref m);
|
||||
|
||||
// check if we got a hot key pressed.
|
||||
if (m.Msg == wmHotkey)
|
||||
{
|
||||
// get the keys.
|
||||
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
|
||||
XModifierKeys xModifier = (XModifierKeys)((int)m.LParam & 0xFFFF);
|
||||
|
||||
// invoke the event to notify the parent.
|
||||
if (KeyPressed != null)
|
||||
KeyPressed(this, new KeyPressedEventArgs(xModifier, key));
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<KeyPressedEventArgs> KeyPressed;
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DestroyHandle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
private Window window = new Window();
|
||||
private int currentId;
|
||||
|
||||
public KeyboardHook()
|
||||
{
|
||||
// register the event of the inner native window.
|
||||
window.KeyPressed += delegate(object sender, KeyPressedEventArgs args)
|
||||
{
|
||||
if (KeyPressed != null)
|
||||
KeyPressed(this, args);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a hot key in the system.
|
||||
/// </summary>
|
||||
/// <param name="xModifier">The modifiers that are associated with the hot key.</param>
|
||||
/// <param name="key">The key itself that is associated with the hot key.</param>
|
||||
public void RegisterHotKey(XModifierKeys xModifier, Keys key)
|
||||
{
|
||||
// increment the counter.
|
||||
currentId = currentId + 1;
|
||||
|
||||
// register the hot key.
|
||||
if (!RegisterHotKey(window.Handle, currentId, (uint)xModifier, (uint)key))
|
||||
{
|
||||
Log.Error("Couldn’t register the hot key.");
|
||||
MessageBox.Show("Couldn’t register the hot key.");
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new InvalidOperationException("Couldn’t register the hot key.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A hot key has been pressed.
|
||||
/// </summary>
|
||||
public event EventHandler<KeyPressedEventArgs> KeyPressed;
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// unregister all the registered hot keys.
|
||||
for (int i = currentId; i > 0; i--)
|
||||
{
|
||||
UnregisterHotKey(window.Handle, i);
|
||||
}
|
||||
|
||||
// dispose the inner native window.
|
||||
window.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event Args for the event that is fired after the hot key has been pressed.
|
||||
/// </summary>
|
||||
public class KeyPressedEventArgs : EventArgs
|
||||
{
|
||||
private XModifierKeys xModifier;
|
||||
private Keys key;
|
||||
|
||||
internal KeyPressedEventArgs(XModifierKeys xModifier, Keys key)
|
||||
{
|
||||
this.xModifier = xModifier;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public XModifierKeys XModifier
|
||||
{
|
||||
get { return xModifier; }
|
||||
}
|
||||
|
||||
public Keys Key
|
||||
{
|
||||
get { return key; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The enumeration of possible modifiers.
|
||||
/// </summary>
|
||||
public enum XModifierKeys : uint
|
||||
{
|
||||
Alt = 1,
|
||||
Control = 2,
|
||||
Shift = 4,
|
||||
Win = 8
|
||||
}
|
||||
}
|
||||
244
Wox/Helper/KeyboardListener.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public enum KeyEvent : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Key down
|
||||
/// </summary>
|
||||
WM_KEYDOWN = 256,
|
||||
|
||||
/// <summary>
|
||||
/// Key up
|
||||
/// </summary>
|
||||
WM_KEYUP = 257,
|
||||
|
||||
/// <summary>
|
||||
/// System key up
|
||||
/// </summary>
|
||||
WM_SYSKEYUP = 261,
|
||||
|
||||
/// <summary>
|
||||
/// System key down
|
||||
/// </summary>
|
||||
WM_SYSKEYDOWN = 260
|
||||
}
|
||||
|
||||
public class SpecialKeyState
|
||||
{
|
||||
public bool CtrlPressed { get; set; }
|
||||
public bool ShiftPressed { get; set; }
|
||||
public bool AltPressed { get; set; }
|
||||
public bool WinPressed { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listens keyboard globally.
|
||||
///
|
||||
/// <remarks>Uses WH_KEYBOARD_LL.</remarks>
|
||||
/// </summary>
|
||||
public class KeyboardListener : IDisposable
|
||||
{
|
||||
private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc;
|
||||
private IntPtr hookId = IntPtr.Zero;
|
||||
public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state);
|
||||
public event KeyboardCallback hookedKeyboardCallback;
|
||||
|
||||
//Modifier key constants
|
||||
private const int VK_SHIFT = 0x10;
|
||||
private const int VK_CONTROL = 0x11;
|
||||
private const int VK_ALT = 0x12;
|
||||
private const int VK_WIN = 91;
|
||||
|
||||
public KeyboardListener()
|
||||
{
|
||||
// We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime
|
||||
hookedLowLevelKeyboardProc = LowLevelKeyboardProc;
|
||||
// Set the hook
|
||||
hookId = InterceptKeys.SetHook(hookedLowLevelKeyboardProc);
|
||||
}
|
||||
|
||||
private SpecialKeyState CheckModifiers()
|
||||
{
|
||||
SpecialKeyState state = new SpecialKeyState();
|
||||
if ((InterceptKeys.GetKeyState(VK_SHIFT) & 0x8000) != 0)
|
||||
{
|
||||
//SHIFT is pressed
|
||||
state.ShiftPressed = true;
|
||||
}
|
||||
if ((InterceptKeys.GetKeyState(VK_CONTROL) & 0x8000) != 0)
|
||||
{
|
||||
//CONTROL is pressed
|
||||
state.CtrlPressed = true;
|
||||
}
|
||||
if ((InterceptKeys.GetKeyState(VK_ALT) & 0x8000) != 0)
|
||||
{
|
||||
//ALT is pressed
|
||||
state.AltPressed = true;
|
||||
}
|
||||
if ((InterceptKeys.GetKeyState(VK_WIN) & 0x8000) != 0)
|
||||
{
|
||||
//ALT is pressed
|
||||
state.WinPressed = true;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
bool continues = true;
|
||||
|
||||
if (nCode >= 0)
|
||||
{
|
||||
if (wParam.ToUInt32() == (int)KeyEvent.WM_KEYDOWN ||
|
||||
wParam.ToUInt32() == (int)KeyEvent.WM_KEYUP ||
|
||||
wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYDOWN ||
|
||||
wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYUP)
|
||||
{
|
||||
if (hookedKeyboardCallback != null)
|
||||
continues = hookedKeyboardCallback((KeyEvent)wParam.ToUInt32(), Marshal.ReadInt32(lParam), CheckModifiers());
|
||||
}
|
||||
}
|
||||
|
||||
if (continues)
|
||||
{
|
||||
return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
|
||||
}
|
||||
return (IntPtr)1;
|
||||
}
|
||||
|
||||
~KeyboardListener()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
InterceptKeys.UnhookWindowsHookEx(hookId);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InterceptKeys
|
||||
{
|
||||
public delegate IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);
|
||||
|
||||
private static int WH_KEYBOARD_LL = 13;
|
||||
|
||||
public static IntPtr SetHook(LowLevelKeyboardProc proc)
|
||||
{
|
||||
using (Process curProcess = Process.GetCurrentProcess())
|
||||
using (ProcessModule curModule = curProcess.MainModule)
|
||||
{
|
||||
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, UIntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern short GetKeyState(int keyCode);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize);
|
||||
|
||||
|
||||
public static void SendKeyStroke(int funckey, int key)
|
||||
{
|
||||
INPUT[] input = new INPUT[4];
|
||||
input[0].type = input[1].type = input[2].type = input[3].type = (int)InputType.INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = input[2].ki.wVk = (short) funckey;
|
||||
input[1].ki.wVk = input[3].ki.wVk = (short) key;
|
||||
|
||||
input[2].ki.dwFlags = input[3].ki.dwFlags =(int) KEYEVENTF.KEYUP;
|
||||
|
||||
SendInput((uint)input.Length, input, Marshal.SizeOf(input[0]));
|
||||
}
|
||||
}
|
||||
|
||||
public enum InputType
|
||||
{
|
||||
INPUT_MOUSE = 0,
|
||||
INPUT_KEYBOARD = 1,
|
||||
INPUT_HARDWARE = 2,
|
||||
}
|
||||
[Flags()]
|
||||
public enum MOUSEEVENTF
|
||||
{
|
||||
MOVE = 0x0001, //mouse move
|
||||
LEFTDOWN = 0x0002, //left button down
|
||||
LEFTUP = 0x0004, //left button up
|
||||
RIGHTDOWN = 0x0008, //right button down
|
||||
RIGHTUP = 0x0010, //right button up
|
||||
MIDDLEDOWN = 0x0020, //middle button down
|
||||
MIDDLEUP = 0x0040, //middle button up
|
||||
XDOWN = 0x0080, //x button down
|
||||
XUP = 0x0100, //x button down
|
||||
WHEEL = 0x0800, //wheel button rolled
|
||||
VIRTUALDESK = 0x4000, //map to entire virtual desktop
|
||||
ABSOLUTE = 0x8000, //absolute move
|
||||
}
|
||||
|
||||
[Flags()]
|
||||
public enum KEYEVENTF
|
||||
{
|
||||
EXTENDEDKEY = 0x0001,
|
||||
KEYUP = 0x0002,
|
||||
UNICODE = 0x0004,
|
||||
SCANCODE = 0x0008,
|
||||
}
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct INPUT
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Int32 type;//0-MOUSEINPUT;1-KEYBDINPUT;2-HARDWAREINPUT
|
||||
[FieldOffset(4)]
|
||||
public KEYBDINPUT ki;
|
||||
[FieldOffset(4)]
|
||||
public MOUSEINPUT mi;
|
||||
[FieldOffset(4)]
|
||||
public HARDWAREINPUT hi;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MOUSEINPUT
|
||||
{
|
||||
public Int32 dx;
|
||||
public Int32 dy;
|
||||
public Int32 mouseData;
|
||||
public Int32 dwFlags;
|
||||
public Int32 time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KEYBDINPUT
|
||||
{
|
||||
public Int16 wVk;
|
||||
public Int16 wScan;
|
||||
public Int32 dwFlags;
|
||||
public Int32 time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct HARDWAREINPUT
|
||||
{
|
||||
public Int32 uMsg;
|
||||
public Int16 wParamL;
|
||||
public Int16 wParamH;
|
||||
}
|
||||
}
|
||||
15
Wox/Helper/Log.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public class Log
|
||||
{
|
||||
private static ILog fileLogger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static void Error(string msg)
|
||||
{
|
||||
fileLogger.Error(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Wox/Helper/WoxException.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Wox.Helper
|
||||
{
|
||||
public class WoxException : Exception
|
||||
{
|
||||
public WoxException(string msg)
|
||||
: base(msg)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Wox/Images/app.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
Wox/Images/bookmark.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
Wox/Images/close.png
Normal file
|
After Width: | Height: | Size: 139 B |
BIN
Wox/Images/cmd.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Wox/Images/ctrl.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Wox/Images/enter.png
Normal file
|
After Width: | Height: | Size: 367 B |
BIN
Wox/Images/exit.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Wox/Images/folder.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
Wox/Images/lock.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Wox/Images/logoff.png
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
Wox/Images/work.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
25
Wox/MainWindow.xaml
Normal file
@@ -0,0 +1,25 @@
|
||||
<Window x:Class="Wox.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wox="clr-namespace:Wox"
|
||||
Title="Wox"
|
||||
Topmost="True"
|
||||
Loaded="MainWindow_OnLoaded"
|
||||
SizeToContent="Height"
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="None"
|
||||
WindowStartupLocation="Manual"
|
||||
ShowInTaskbar="False"
|
||||
Style="{DynamicResource WindowStyle}"
|
||||
Icon="Images\app.png"
|
||||
>
|
||||
<Grid Style="{DynamicResource GridStyle}" x:Name="grid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition ></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox AllowDrop="True" Style="{DynamicResource QueryBoxStyle}" Grid.Row="0" x:Name="tbQuery" PreviewKeyDown="TbQuery_OnPreviewKeyDown" TextChanged="TextBoxBase_OnTextChanged" />
|
||||
<Line Style="{DynamicResource PendingLineStyle}" x:Name="progressBar" Y1="0" Y2="0" X2="100" Grid.Row="1" Height="2" StrokeThickness="1"></Line>
|
||||
<wox:ResultPanel x:Name="resultCtrl" Grid.Row="2"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
370
Wox/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,370 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Animation;
|
||||
using Wox.Commands;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
using Wox.PluginLoader;
|
||||
using Application = System.Windows.Application;
|
||||
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class MainWindow
|
||||
{
|
||||
private KeyboardHook hook = new KeyboardHook();
|
||||
private NotifyIcon notifyIcon;
|
||||
Storyboard progressBarStoryboard = new Storyboard();
|
||||
private bool queryHasReturn = false;
|
||||
|
||||
private KeyboardListener keyboardListener = new KeyboardListener();
|
||||
private bool WinRStroked = false;
|
||||
|
||||
private WindowsInput.KeyboardSimulator keyboardSimulator = new WindowsInput.KeyboardSimulator(new WindowsInput.InputSimulator());
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
hook.KeyPressed += OnHotKey;
|
||||
hook.RegisterHotKey(XModifierKeys.Alt, Keys.Space);
|
||||
resultCtrl.resultItemChangedEvent += resultCtrl_resultItemChangedEvent;
|
||||
ThreadPool.SetMaxThreads(30, 10);
|
||||
InitProgressbarAnimation();
|
||||
try
|
||||
{
|
||||
SetTheme(CommonStorage.Instance.UserSetting.Theme);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
SetTheme(CommonStorage.Instance.UserSetting.Theme = "Default");
|
||||
}
|
||||
}
|
||||
|
||||
private void WakeupApp()
|
||||
{
|
||||
//After hide wox in the background for a long time. It will become very slow in the next show.
|
||||
//This is caused by the Virtual Mermory Page Mechanisam. So, our solution is execute some codes in every min
|
||||
//which may prevent sysetem uninstall memory from RAM to disk.
|
||||
|
||||
System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 5) { AutoReset = true, Enabled = true };
|
||||
t.Elapsed += (o, e) => Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
if (Visibility != Visibility.Visible)
|
||||
{
|
||||
double oldLeft = Left;
|
||||
Left = 20000;
|
||||
ShowWox();
|
||||
CommandFactory.DispatchCommand(new Query("qq"), false);
|
||||
HideWox();
|
||||
Left = oldLeft;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true };
|
||||
notifyIcon.Click += (o, e) => ShowWox();
|
||||
System.Windows.Forms.MenuItem open = new System.Windows.Forms.MenuItem("Open");
|
||||
open.Click += (o, e) => ShowWox();
|
||||
System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("Exit");
|
||||
exit.Click += (o, e) => CloseApp();
|
||||
System.Windows.Forms.MenuItem[] childen = { open, exit };
|
||||
notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
|
||||
}
|
||||
|
||||
private void resultCtrl_resultItemChangedEvent()
|
||||
{
|
||||
resultCtrl.Margin = resultCtrl.GetCurrentResultCount() > 0 ? new Thickness { Top = grid.Margin.Top } : new Thickness { Top = 0 };
|
||||
}
|
||||
|
||||
private void OnHotKey(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
if (!IsVisible)
|
||||
{
|
||||
ShowWox();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideWox();
|
||||
}
|
||||
}
|
||||
|
||||
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
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);
|
||||
CommandFactory.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 HideWox()
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void ShowWox(bool selectAll = true)
|
||||
{
|
||||
Show();
|
||||
Activate();
|
||||
Focus();
|
||||
tbQuery.Focus();
|
||||
if (selectAll) tbQuery.SelectAll();
|
||||
}
|
||||
|
||||
public void ParseArgs(string[] args)
|
||||
{
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
switch (args[0])
|
||||
{
|
||||
case "reloadWorkflows":
|
||||
Plugins.Init();
|
||||
break;
|
||||
|
||||
case "query":
|
||||
if (args.Length > 1)
|
||||
{
|
||||
string query = args[1];
|
||||
tbQuery.Text = query;
|
||||
tbQuery.SelectAll();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetAutoStart(bool IsAtuoRun)
|
||||
{
|
||||
//string LnkPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "//Wox.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 = "Wox";
|
||||
// shortcut.Save();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// System.IO.File.Delete(LnkPath);
|
||||
//}
|
||||
}
|
||||
|
||||
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2;
|
||||
Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3;
|
||||
|
||||
Plugins.Init();
|
||||
InitialTray();
|
||||
SetAutoStart(true);
|
||||
WakeupApp();
|
||||
|
||||
//var engine = new Jurassic.ScriptEngine();
|
||||
//MessageBox.Show(engine.Evaluate("5 * 10 + 2").ToString());
|
||||
keyboardListener.hookedKeyboardCallback += KListener_hookedKeyboardCallback;
|
||||
}
|
||||
|
||||
private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state)
|
||||
{
|
||||
if (CommonStorage.Instance.UserSetting.ReplaceWinR)
|
||||
{
|
||||
//todo:need refatoring. move those codes to CMD file or expose events
|
||||
if (keyevent == KeyEvent.WM_KEYDOWN && vkcode == (int)Keys.R && state.WinPressed)
|
||||
{
|
||||
WinRStroked = true;
|
||||
Dispatcher.BeginInvoke(new Action(OnWinRPressed));
|
||||
return false;
|
||||
}
|
||||
if (keyevent == KeyEvent.WM_KEYUP && WinRStroked && vkcode == (int)Keys.LWin)
|
||||
{
|
||||
WinRStroked = false;
|
||||
keyboardSimulator.ModifiedKeyStroke(WindowsInput.Native.VirtualKeyCode.LWIN, WindowsInput.Native.VirtualKeyCode.CONTROL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnWinRPressed()
|
||||
{
|
||||
ShowWox(false);
|
||||
if (tbQuery.Text != ">")
|
||||
{
|
||||
resultCtrl.Clear();
|
||||
ChangeQuery(">");
|
||||
}
|
||||
tbQuery.CaretIndex = tbQuery.Text.Length;
|
||||
}
|
||||
|
||||
private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Escape:
|
||||
HideWox();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.Down:
|
||||
resultCtrl.SelectNext();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.Up:
|
||||
resultCtrl.SelectPrev();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.Enter:
|
||||
AcceptSelect();
|
||||
e.Handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void AcceptSelect()
|
||||
{
|
||||
Result result = resultCtrl.AcceptSelect();
|
||||
if (result != null)
|
||||
{
|
||||
CommonStorage.Instance.UserSelectedRecords.Add(result);
|
||||
if (!result.DontHideWoxAfterSelect)
|
||||
{
|
||||
HideWox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnUpdateResultView(List<Result> list)
|
||||
{
|
||||
queryHasReturn = true;
|
||||
progressBar.Dispatcher.Invoke(new Action(StopProgress));
|
||||
if (list.Count > 0)
|
||||
{
|
||||
//todo:this should be opened to users, it's their choise to use it or not in thier workflows
|
||||
list.ForEach(o =>
|
||||
{
|
||||
if (o.AutoAjustScore) o.Score += CommonStorage.Instance.UserSelectedRecords.GetSelectedCount(o);
|
||||
});
|
||||
resultCtrl.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
List<Result> l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
|
||||
resultCtrl.AddResults(l);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTheme(string themeName)
|
||||
{
|
||||
ResourceDictionary dict = new ResourceDictionary
|
||||
{
|
||||
Source = new Uri("pack://application:,,,/Themes/" + themeName + ".xaml")
|
||||
};
|
||||
|
||||
Application.Current.Resources.MergedDictionaries.Clear();
|
||||
Application.Current.Resources.MergedDictionaries.Add(dict);
|
||||
}
|
||||
|
||||
#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;
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
public void HideApp()
|
||||
{
|
||||
HideWox();
|
||||
}
|
||||
|
||||
public void ShowApp()
|
||||
{
|
||||
ShowWox();
|
||||
}
|
||||
|
||||
public void ShowMsg(string title, string subTitle, string iconPath)
|
||||
{
|
||||
Msg m = new Msg { Owner = GetWindow(this) };
|
||||
m.Show(title, subTitle, iconPath);
|
||||
}
|
||||
|
||||
public void OpenSettingDialog()
|
||||
{
|
||||
SettingWidow s = new SettingWidow(this);
|
||||
s.Show();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
47
Wox/Models/UserSelectedRecords.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class UserSelectedRecords
|
||||
{
|
||||
private static int hasAddedCount = 0;
|
||||
|
||||
public Dictionary<string,int> Records = new Dictionary<string, int>();
|
||||
|
||||
public void Add(Result result)
|
||||
{
|
||||
if (Records.ContainsKey(result.ToString()))
|
||||
{
|
||||
Records[result.ToString()] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Records.Add(result.ToString(), 1);
|
||||
}
|
||||
|
||||
//hasAddedCount++;
|
||||
//if (hasAddedCount == 10)
|
||||
//{
|
||||
// hasAddedCount = 0;
|
||||
//}
|
||||
CommonStorage.Instance.Save();
|
||||
|
||||
}
|
||||
|
||||
public int GetSelectedCount(Result result)
|
||||
{
|
||||
if (Records.ContainsKey(result.ToString()))
|
||||
{
|
||||
return Records[result.ToString()];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Wox/Models/UserSetting.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Wox.Models
|
||||
{
|
||||
public class UserSetting
|
||||
{
|
||||
public string Theme { get; set; }
|
||||
public bool ReplaceWinR { get; set; }
|
||||
public List<WebSearch> WebSearches { get; set; }
|
||||
}
|
||||
}
|
||||
10
Wox/Models/WebSearch.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Wox.Models
|
||||
{
|
||||
public class WebSearch
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
public string IconPath { get; set; }
|
||||
public string Website { get; set; }
|
||||
public string Enabled { get; set; }
|
||||
}
|
||||
}
|
||||
38
Wox/Msg.xaml
Normal file
@@ -0,0 +1,38 @@
|
||||
<Window x:Class="Wox.Msg"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="#ebebeb"
|
||||
Topmost="True"
|
||||
SizeToContent="Height"
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="None"
|
||||
ShowInTaskbar="False"
|
||||
Title="Msg" Height="60" Width="420">
|
||||
<Window.Triggers>
|
||||
<EventTrigger RoutedEvent="Window.Loaded">
|
||||
<BeginStoryboard>
|
||||
<Storyboard >
|
||||
<DoubleAnimation x:Name="showAnimation" Duration="0:0:0.3" Storyboard.TargetProperty="Top" AccelerationRatio="0.2"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
|
||||
</Window.Triggers>
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="32"></ColumnDefinition>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="16"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left" ></Image>
|
||||
<Grid HorizontalAlignment="Stretch" Margin="5 0 0 0" Grid.Column="1" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="29"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Name="tbTitle" FontSize="16" Foreground="#37392c" FontWeight="Medium">Title</TextBlock>
|
||||
<TextBlock Grid.Row="1" Foreground="#8e94a4" x:Name="tbSubTitle">sdfdsf</TextBlock>
|
||||
</Grid>
|
||||
<Image x:Name="imgClose" Grid.Column="2" Cursor="Hand" Width="16" VerticalAlignment="Top" HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
</Window>
|
||||
84
Wox/Msg.xaml.cs
Normal file
@@ -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 Wox
|
||||
{
|
||||
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\\app.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Wox/PluginLoader/BasePluginLoader.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.System;
|
||||
|
||||
namespace Wox.PluginLoader
|
||||
{
|
||||
public abstract class BasePluginLoader
|
||||
{
|
||||
private static string PluginPath = AppDomain.CurrentDomain.BaseDirectory + "Plugins";
|
||||
private static string PluginConfigName = "plugin.ini";
|
||||
protected static List<PluginMetadata> pluginMetadatas = new List<PluginMetadata>();
|
||||
public abstract List<PluginPair> LoadPlugin();
|
||||
|
||||
public static void ParsePluginsConfig()
|
||||
{
|
||||
pluginMetadatas.Clear();
|
||||
ParseSystemPlugins();
|
||||
ParseThirdPartyPlugins();
|
||||
}
|
||||
|
||||
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 = "Wox.Plugin.System.dll";
|
||||
metadata.ExecuteFilePath = AppDomain.CurrentDomain.BaseDirectory + metadata.ExecuteFileName;
|
||||
metadata.PluginDirecotry = AppDomain.CurrentDomain.BaseDirectory;
|
||||
pluginMetadatas.Add(metadata);
|
||||
}
|
||||
|
||||
private static void ParseThirdPartyPlugins()
|
||||
{
|
||||
if (!Directory.Exists(PluginPath))
|
||||
Directory.CreateDirectory(PluginPath);
|
||||
|
||||
string[] directories = Directory.GetDirectories(PluginPath);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
PluginMetadata metadata = GetMetadataFromIni(directory);
|
||||
if (metadata != null) pluginMetadatas.Add(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
private static PluginMetadata GetMetadataFromIni(string directory)
|
||||
{
|
||||
string iniPath = directory + "\\" + PluginConfigName;
|
||||
|
||||
if (!File.Exists(iniPath))
|
||||
{
|
||||
Log.Error(string.Format("parse plugin {0} failed: didn't find config file.", iniPath));
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PluginMetadata metadata = new PluginMetadata();
|
||||
IniParser ini = new IniParser(iniPath);
|
||||
metadata.Name = ini.GetSetting("plugin", "Name");
|
||||
metadata.Author = ini.GetSetting("plugin", "Author");
|
||||
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 = directory + "\\" + ini.GetSetting("plugin", "ExecuteFile");
|
||||
metadata.PluginDirecotry = directory + "\\";
|
||||
metadata.ExecuteFileName = ini.GetSetting("plugin", "ExecuteFile");
|
||||
|
||||
if (!AllowedLanguage.IsAllowed(metadata.Language))
|
||||
{
|
||||
string error = string.Format("Parse ini {0} failed: invalid language {1}", iniPath,
|
||||
metadata.Language);
|
||||
Log.Error(error);
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new WoxException(error);
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
if (!File.Exists(metadata.ExecuteFilePath))
|
||||
{
|
||||
string error = string.Format("Parse ini {0} failed: ExecuteFilePath didn't exist {1}", iniPath,
|
||||
metadata.ExecuteFilePath);
|
||||
Log.Error(error);
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new WoxException(error);
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(string.Format("Parse ini {0} failed: {1}", iniPath, e.Message));
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Change python execute file name to unique file name using GUID
|
||||
///// this is because if two pythong plugin use the same
|
||||
///// </summary>
|
||||
///// <param name="metadata"></param>
|
||||
///// <returns></returns>
|
||||
//private static PluginMetadata filterPythonMetadata(PluginMetadata metadata)
|
||||
//{
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
57
Wox/PluginLoader/CSharpPluginLoader.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.System;
|
||||
|
||||
namespace Wox.PluginLoader
|
||||
{
|
||||
public class CSharpPluginLoader : BasePluginLoader
|
||||
{
|
||||
public override List<PluginPair> LoadPlugin()
|
||||
{
|
||||
List<PluginPair> plugins = new List<PluginPair>();
|
||||
|
||||
List<PluginMetadata> metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp.ToUpper()).ToList();
|
||||
foreach (PluginMetadata metadata in metadatas)
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly asm = Assembly.LoadFile(metadata.ExecuteFilePath);
|
||||
List<Type> types = asm.GetTypes().Where(o => o.IsClass && !o.IsAbstract && (o.BaseType == typeof(BaseSystemPlugin) || o.GetInterfaces().Contains(typeof(IPlugin)))).ToList();
|
||||
if (types.Count == 0)
|
||||
{
|
||||
Log.Error(string.Format("Cound't load plugin {0}: didn't find the class who implement IPlugin",
|
||||
metadata.Name));
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Type type in types)
|
||||
{
|
||||
PluginPair pair = new PluginPair()
|
||||
{
|
||||
Plugin = Activator.CreateInstance(type) as IPlugin,
|
||||
Metadata = metadata
|
||||
};
|
||||
plugins.Add(pair);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(string.Format("Cound't load plugin {0}: {1}", metadata.Name, e.Message));
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Wox/PluginLoader/Plugins.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.CSharp;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.PluginLoader
|
||||
{
|
||||
public static class Plugins
|
||||
{
|
||||
private static List<PluginPair> plugins = new List<PluginPair>();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
plugins.Clear();
|
||||
BasePluginLoader.ParsePluginsConfig();
|
||||
|
||||
plugins.AddRange(new PythonPluginLoader().LoadPlugin());
|
||||
plugins.AddRange(new CSharpPluginLoader().LoadPlugin());
|
||||
foreach (IPlugin plugin in plugins.Select(pluginPair => pluginPair.Plugin))
|
||||
{
|
||||
IPlugin plugin1 = plugin;
|
||||
PluginPair pluginPair = plugins.FirstOrDefault(o => o.Plugin == plugin1);
|
||||
if (pluginPair != null)
|
||||
{
|
||||
PluginMetadata metadata = pluginPair.Metadata;
|
||||
ThreadPool.QueueUserWorkItem(o => plugin1.Init(new PluginInitContext()
|
||||
{
|
||||
Plugins = plugins,
|
||||
PluginMetadata = metadata,
|
||||
ChangeQuery = s => App.Window.ChangeQuery(s),
|
||||
CloseApp = App.Window.CloseApp,
|
||||
HideApp = App.Window.HideApp,
|
||||
ShowApp = () => App.Window.ShowApp(),
|
||||
ShowMsg = (title, subTitle, iconPath) => App.Window.ShowMsg(title, subTitle, iconPath),
|
||||
OpenSettingDialog = () => App.Window.OpenSettingDialog()
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PluginPair> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Wox/PluginLoader/PythonPluginLoader.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Python.Runtime;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.PluginLoader
|
||||
{
|
||||
public class PythonPluginLoader : BasePluginLoader
|
||||
{
|
||||
public override List<PluginPair> LoadPlugin()
|
||||
{
|
||||
List<PluginPair> plugins = new List<PluginPair>();
|
||||
List<PluginMetadata> metadatas = pluginMetadatas.Where(o => o.Language.ToUpper() == AllowedLanguage.Python.ToUpper()).ToList();
|
||||
foreach (PluginMetadata metadata in metadatas)
|
||||
{
|
||||
PythonPluginWrapper python = new PythonPluginWrapper(metadata);
|
||||
PluginPair pair = new PluginPair()
|
||||
{
|
||||
Plugin = python,
|
||||
Metadata = metadata
|
||||
};
|
||||
plugins.Add(pair);
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
}
|
||||
}
|
||||
99
Wox/PluginLoader/PythonPluginWrapper.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Documents;
|
||||
using Newtonsoft.Json;
|
||||
using Python.Runtime;
|
||||
using Wox.Helper;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox.PluginLoader
|
||||
{
|
||||
public class PythonPluginWrapper : IPlugin
|
||||
{
|
||||
|
||||
private PluginMetadata metadata;
|
||||
private string moduleName;
|
||||
|
||||
public PythonPluginWrapper(PluginMetadata metadata)
|
||||
{
|
||||
this.metadata = metadata;
|
||||
moduleName = metadata.ExecuteFileName.Replace(".py", "");
|
||||
}
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
{
|
||||
try
|
||||
{
|
||||
string jsonResult = InvokeFunc("query", query.RawQuery);
|
||||
if (string.IsNullOrEmpty(jsonResult))
|
||||
{
|
||||
return new List<Result>();
|
||||
}
|
||||
|
||||
List<PythonResult> o = JsonConvert.DeserializeObject<List<PythonResult>>(jsonResult);
|
||||
List<Result> r = new List<Result>();
|
||||
foreach (PythonResult pythonResult in o)
|
||||
{
|
||||
PythonResult ps = pythonResult;
|
||||
if (!string.IsNullOrEmpty(ps.ActionName))
|
||||
{
|
||||
ps.Action = () => InvokeFunc(ps.ActionName, ps.ActionPara);
|
||||
}
|
||||
r.Add(ps);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private string InvokeFunc(string func, params string[] para)
|
||||
{
|
||||
string json;
|
||||
|
||||
PyObject[] paras = { };
|
||||
if (para != null && para.Length > 0)
|
||||
{
|
||||
paras = para.Select(o => new PyString(o)).ToArray();
|
||||
}
|
||||
|
||||
IntPtr gs = PythonEngine.AcquireLock();
|
||||
|
||||
PyObject module = PythonEngine.ImportModule(moduleName);
|
||||
if (module.HasAttr(func))
|
||||
{
|
||||
PyObject res = paras.Length > 0 ? module.InvokeMethod(func, paras) : module.InvokeMethod(func);
|
||||
json = Runtime.GetManagedString(res.Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
string error = string.Format("Python Invoke failed: {0} doesn't has function {1}",
|
||||
metadata.ExecuteFilePath, func);
|
||||
Log.Error(error);
|
||||
#if (DEBUG)
|
||||
{
|
||||
throw new ArgumentException(error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PythonEngine.ReleaseLock(gs);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
577
Wox/Properties/Annotations.cs
Normal file
@@ -0,0 +1,577 @@
|
||||
using System;
|
||||
|
||||
#pragma warning disable 1591
|
||||
// ReSharper disable UnusedMember.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
// ReSharper disable IntroduceOptionalParameters.Global
|
||||
// ReSharper disable MemberCanBeProtected.Global
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace Wox.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the value of the marked element could be <c>null</c> sometimes,
|
||||
/// so the check for <c>null</c> is necessary before its usage
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [CanBeNull] public object Test() { return null; }
|
||||
/// public void UseTest() {
|
||||
/// var p = Test();
|
||||
/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.Delegate |
|
||||
AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class CanBeNullAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the value of the marked element could never be <c>null</c>
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [NotNull] public object Foo() {
|
||||
/// return null; // Warning: Possible 'null' assignment
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.Delegate |
|
||||
AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class NotNullAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the marked method builds string by format pattern and (optional) arguments.
|
||||
/// Parameter, which contains format string, should be given in constructor. The format string
|
||||
/// should be in <see cref="string.Format(IFormatProvider,string,object[])"/>-like form
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [StringFormatMethod("message")]
|
||||
/// public void ShowError(string message, params object[] args) { /* do something */ }
|
||||
/// public void Foo() {
|
||||
/// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Constructor | AttributeTargets.Method,
|
||||
AllowMultiple = false, Inherited = true)]
|
||||
public sealed class StringFormatMethodAttribute : Attribute
|
||||
{
|
||||
/// <param name="formatParameterName">
|
||||
/// Specifies which parameter of an annotated method should be treated as format-string
|
||||
/// </param>
|
||||
public StringFormatMethodAttribute(string formatParameterName)
|
||||
{
|
||||
FormatParameterName = formatParameterName;
|
||||
}
|
||||
|
||||
public string FormatParameterName { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the function argument should be string literal and match one
|
||||
/// of the parameters of the caller function. For example, ReSharper annotates
|
||||
/// the parameter of <see cref="System.ArgumentNullException"/>
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// public void Foo(string param) {
|
||||
/// if (param == null)
|
||||
/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class InvokerParameterNameAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the method is contained in a type that implements
|
||||
/// <see cref="System.ComponentModel.INotifyPropertyChanged"/> interface
|
||||
/// and this method is used to notify that some property value changed
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The method should be non-static and conform to one of the supported signatures:
|
||||
/// <list>
|
||||
/// <item><c>NotifyChanged(string)</c></item>
|
||||
/// <item><c>NotifyChanged(params string[])</c></item>
|
||||
/// <item><c>NotifyChanged{T}(Expression{Func{T}})</c></item>
|
||||
/// <item><c>NotifyChanged{T,U}(Expression{Func{T,U}})</c></item>
|
||||
/// <item><c>SetProperty{T}(ref T, T, string)</c></item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <example><code>
|
||||
/// public class Foo : INotifyPropertyChanged {
|
||||
/// public event PropertyChangedEventHandler PropertyChanged;
|
||||
/// [NotifyPropertyChangedInvocator]
|
||||
/// protected virtual void NotifyChanged(string propertyName) { ... }
|
||||
///
|
||||
/// private string _name;
|
||||
/// public string Name {
|
||||
/// get { return _name; }
|
||||
/// set { _name = value; NotifyChanged("LastName"); /* Warning */ }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// Examples of generated notifications:
|
||||
/// <list>
|
||||
/// <item><c>NotifyChanged("Property")</c></item>
|
||||
/// <item><c>NotifyChanged(() => Property)</c></item>
|
||||
/// <item><c>NotifyChanged((VM x) => x.Property)</c></item>
|
||||
/// <item><c>SetProperty(ref myField, value, "Property")</c></item>
|
||||
/// </list>
|
||||
/// </example>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute
|
||||
{
|
||||
public NotifyPropertyChangedInvocatorAttribute() { }
|
||||
public NotifyPropertyChangedInvocatorAttribute(string parameterName)
|
||||
{
|
||||
ParameterName = parameterName;
|
||||
}
|
||||
|
||||
public string ParameterName { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes dependency between method input and output
|
||||
/// </summary>
|
||||
/// <syntax>
|
||||
/// <p>Function Definition Table syntax:</p>
|
||||
/// <list>
|
||||
/// <item>FDT ::= FDTRow [;FDTRow]*</item>
|
||||
/// <item>FDTRow ::= Input => Output | Output <= Input</item>
|
||||
/// <item>Input ::= ParameterName: Value [, Input]*</item>
|
||||
/// <item>Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value}</item>
|
||||
/// <item>Value ::= true | false | null | notnull | canbenull</item>
|
||||
/// </list>
|
||||
/// If method has single input parameter, it's name could be omitted.<br/>
|
||||
/// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same)
|
||||
/// for method output means that the methos doesn't return normally.<br/>
|
||||
/// <c>canbenull</c> annotation is only applicable for output parameters.<br/>
|
||||
/// You can use multiple <c>[ContractAnnotation]</c> for each FDT row,
|
||||
/// or use single attribute with rows separated by semicolon.<br/>
|
||||
/// </syntax>
|
||||
/// <examples><list>
|
||||
/// <item><code>
|
||||
/// [ContractAnnotation("=> halt")]
|
||||
/// public void TerminationMethod()
|
||||
/// </code></item>
|
||||
/// <item><code>
|
||||
/// [ContractAnnotation("halt <= condition: false")]
|
||||
/// public void Assert(bool condition, string text) // regular assertion method
|
||||
/// </code></item>
|
||||
/// <item><code>
|
||||
/// [ContractAnnotation("s:null => true")]
|
||||
/// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
|
||||
/// </code></item>
|
||||
/// <item><code>
|
||||
/// // A method that returns null if the parameter is null, and not null if the parameter is not null
|
||||
/// [ContractAnnotation("null => null; notnull => notnull")]
|
||||
/// public object Transform(object data)
|
||||
/// </code></item>
|
||||
/// <item><code>
|
||||
/// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
|
||||
/// public bool TryParse(string s, out Person result)
|
||||
/// </code></item>
|
||||
/// </list></examples>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||
public sealed class ContractAnnotationAttribute : Attribute
|
||||
{
|
||||
public ContractAnnotationAttribute([NotNull] string contract)
|
||||
: this(contract, false) { }
|
||||
|
||||
public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates)
|
||||
{
|
||||
Contract = contract;
|
||||
ForceFullStates = forceFullStates;
|
||||
}
|
||||
|
||||
public string Contract { get; private set; }
|
||||
public bool ForceFullStates { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that marked element should be localized or not
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [LocalizationRequiredAttribute(true)]
|
||||
/// public class Foo {
|
||||
/// private string str = "my string"; // Warning: Localizable string
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class LocalizationRequiredAttribute : Attribute
|
||||
{
|
||||
public LocalizationRequiredAttribute() : this(true) { }
|
||||
public LocalizationRequiredAttribute(bool required)
|
||||
{
|
||||
Required = required;
|
||||
}
|
||||
|
||||
public bool Required { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the value of the marked type (or its derivatives)
|
||||
/// cannot be compared using '==' or '!=' operators and <c>Equals()</c>
|
||||
/// should be used instead. However, using '==' or '!=' for comparison
|
||||
/// with <c>null</c> is always permitted.
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [CannotApplyEqualityOperator]
|
||||
/// class NoEquality { }
|
||||
/// class UsesNoEquality {
|
||||
/// public void Test() {
|
||||
/// var ca1 = new NoEquality();
|
||||
/// var ca2 = new NoEquality();
|
||||
/// if (ca1 != null) { // OK
|
||||
/// bool condition = ca1 == ca2; // Warning
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Interface | AttributeTargets.Class |
|
||||
AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class CannotApplyEqualityOperatorAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// When applied to a target attribute, specifies a requirement for any type marked
|
||||
/// with the target attribute to implement or inherit specific type or types.
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [BaseTypeRequired(typeof(IComponent)] // Specify requirement
|
||||
/// public class ComponentAttribute : Attribute { }
|
||||
/// [Component] // ComponentAttribute requires implementing IComponent interface
|
||||
/// public class MyComponent : IComponent { }
|
||||
/// </code></example>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
|
||||
[BaseTypeRequired(typeof(Attribute))]
|
||||
public sealed class BaseTypeRequiredAttribute : Attribute
|
||||
{
|
||||
public BaseTypeRequiredAttribute([NotNull] Type baseType)
|
||||
{
|
||||
BaseType = baseType;
|
||||
}
|
||||
|
||||
[NotNull] public Type BaseType { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the marked symbol is used implicitly
|
||||
/// (e.g. via reflection, in external library), so this symbol
|
||||
/// will not be marked as unused (as well as by other usage inspections)
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class UsedImplicitlyAttribute : Attribute
|
||||
{
|
||||
public UsedImplicitlyAttribute()
|
||||
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
|
||||
|
||||
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
|
||||
: this(useKindFlags, ImplicitUseTargetFlags.Default) { }
|
||||
|
||||
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
|
||||
: this(ImplicitUseKindFlags.Default, targetFlags) { }
|
||||
|
||||
public UsedImplicitlyAttribute(
|
||||
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
|
||||
{
|
||||
UseKindFlags = useKindFlags;
|
||||
TargetFlags = targetFlags;
|
||||
}
|
||||
|
||||
public ImplicitUseKindFlags UseKindFlags { get; private set; }
|
||||
public ImplicitUseTargetFlags TargetFlags { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be used on attributes and causes ReSharper
|
||||
/// to not mark symbols marked with such attributes as unused
|
||||
/// (as well as by other usage inspections)
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class MeansImplicitUseAttribute : Attribute
|
||||
{
|
||||
public MeansImplicitUseAttribute()
|
||||
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
|
||||
|
||||
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
|
||||
: this(useKindFlags, ImplicitUseTargetFlags.Default) { }
|
||||
|
||||
public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
|
||||
: this(ImplicitUseKindFlags.Default, targetFlags) { }
|
||||
|
||||
public MeansImplicitUseAttribute(
|
||||
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
|
||||
{
|
||||
UseKindFlags = useKindFlags;
|
||||
TargetFlags = targetFlags;
|
||||
}
|
||||
|
||||
[UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; }
|
||||
[UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ImplicitUseKindFlags
|
||||
{
|
||||
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
|
||||
/// <summary>Only entity marked with attribute considered used</summary>
|
||||
Access = 1,
|
||||
/// <summary>Indicates implicit assignment to a member</summary>
|
||||
Assign = 2,
|
||||
/// <summary>
|
||||
/// Indicates implicit instantiation of a type with fixed constructor signature.
|
||||
/// That means any unused constructor parameters won't be reported as such.
|
||||
/// </summary>
|
||||
InstantiatedWithFixedConstructorSignature = 4,
|
||||
/// <summary>Indicates implicit instantiation of a type</summary>
|
||||
InstantiatedNoFixedConstructorSignature = 8,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify what is considered used implicitly
|
||||
/// when marked with <see cref="MeansImplicitUseAttribute"/>
|
||||
/// or <see cref="UsedImplicitlyAttribute"/>
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ImplicitUseTargetFlags
|
||||
{
|
||||
Default = Itself,
|
||||
Itself = 1,
|
||||
/// <summary>Members of entity marked with attribute are considered used</summary>
|
||||
Members = 2,
|
||||
/// <summary>Entity marked with attribute and all its members considered used</summary>
|
||||
WithMembers = Itself | Members
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This attribute is intended to mark publicly available API
|
||||
/// which should not be removed and so is treated as used
|
||||
/// </summary>
|
||||
[MeansImplicitUse]
|
||||
public sealed class PublicAPIAttribute : Attribute
|
||||
{
|
||||
public PublicAPIAttribute() { }
|
||||
public PublicAPIAttribute([NotNull] string comment)
|
||||
{
|
||||
Comment = comment;
|
||||
}
|
||||
|
||||
[NotNull] public string Comment { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells code analysis engine if the parameter is completely handled
|
||||
/// when the invoked method is on stack. If the parameter is a delegate,
|
||||
/// indicates that delegate is executed while the method is executed.
|
||||
/// If the parameter is an enumerable, indicates that it is enumerated
|
||||
/// while the method is executed
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter, Inherited = true)]
|
||||
public sealed class InstantHandleAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a method does not make any observable state changes.
|
||||
/// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [Pure] private int Multiply(int x, int y) { return x * y; }
|
||||
/// public void Foo() {
|
||||
/// const int a = 2, b = 2;
|
||||
/// Multiply(a, b); // Waring: Return value of pure method is not used
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
|
||||
public sealed class PureAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a parameter is a path to a file or a folder
|
||||
/// within a web project. Path can be relative or absolute,
|
||||
/// starting from web root (~)
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public class PathReferenceAttribute : Attribute
|
||||
{
|
||||
public PathReferenceAttribute() { }
|
||||
public PathReferenceAttribute([PathReference] string basePath)
|
||||
{
|
||||
BasePath = basePath;
|
||||
}
|
||||
|
||||
[NotNull] public string BasePath { get; private set; }
|
||||
}
|
||||
|
||||
// ASP.NET MVC attributes
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter
|
||||
/// is an MVC action. If applied to a method, the MVC action name is calculated
|
||||
/// implicitly from the context. Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
|
||||
public sealed class AspMvcActionAttribute : Attribute
|
||||
{
|
||||
public AspMvcActionAttribute() { }
|
||||
public AspMvcActionAttribute([NotNull] string anonymousProperty)
|
||||
{
|
||||
AnonymousProperty = anonymousProperty;
|
||||
}
|
||||
|
||||
[NotNull] public string AnonymousProperty { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC area.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class AspMvcAreaAttribute : PathReferenceAttribute
|
||||
{
|
||||
public AspMvcAreaAttribute() { }
|
||||
public AspMvcAreaAttribute([NotNull] string anonymousProperty)
|
||||
{
|
||||
AnonymousProperty = anonymousProperty;
|
||||
}
|
||||
|
||||
[NotNull] public string AnonymousProperty { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. If applied to a parameter, indicates that
|
||||
/// the parameter is an MVC controller. If applied to a method,
|
||||
/// the MVC controller name is calculated implicitly from the context.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
|
||||
public sealed class AspMvcControllerAttribute : Attribute
|
||||
{
|
||||
public AspMvcControllerAttribute() { }
|
||||
public AspMvcControllerAttribute([NotNull] string anonymousProperty)
|
||||
{
|
||||
AnonymousProperty = anonymousProperty;
|
||||
}
|
||||
|
||||
[NotNull] public string AnonymousProperty { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC Master.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Controller.View(String, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class AspMvcMasterAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC model type.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Controller.View(String, Object)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class AspMvcModelTypeAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. If applied to a parameter, indicates that
|
||||
/// the parameter is an MVC partial view. If applied to a method,
|
||||
/// the MVC partial view name is calculated implicitly from the context.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
|
||||
public sealed class AspMvcPartialViewAttribute : PathReferenceAttribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Allows disabling all inspections
|
||||
/// for MVC views within a class or a method.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public sealed class AspMvcSupressViewErrorAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class AspMvcDisplayTemplateAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC editor template.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class AspMvcEditorTemplateAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC template.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.ComponentModel.DataAnnotations.UIHintAttribute(System.String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class AspMvcTemplateAttribute : Attribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter
|
||||
/// is an MVC view. If applied to a method, the MVC view name is calculated implicitly
|
||||
/// from the context. Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.Mvc.Controller.View(Object)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
|
||||
public sealed class AspMvcViewAttribute : PathReferenceAttribute { }
|
||||
|
||||
/// <summary>
|
||||
/// ASP.NET MVC attribute. When applied to a parameter of an attribute,
|
||||
/// indicates that this parameter is an MVC action name
|
||||
/// </summary>
|
||||
/// <example><code>
|
||||
/// [ActionName("Foo")]
|
||||
/// public ActionResult Login(string returnUrl) {
|
||||
/// ViewBag.ReturnUrl = Url.Action("Foo"); // OK
|
||||
/// return RedirectToAction("Bar"); // Error: Cannot resolve action
|
||||
/// }
|
||||
/// </code></example>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
|
||||
public sealed class AspMvcActionSelectorAttribute : Attribute { }
|
||||
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Parameter | AttributeTargets.Property |
|
||||
AttributeTargets.Field, Inherited = true)]
|
||||
public sealed class HtmlElementAttributesAttribute : Attribute
|
||||
{
|
||||
public HtmlElementAttributesAttribute() { }
|
||||
public HtmlElementAttributesAttribute([NotNull] string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
[NotNull] public string Name { get; private set; }
|
||||
}
|
||||
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Parameter | AttributeTargets.Field |
|
||||
AttributeTargets.Property, Inherited = true)]
|
||||
public sealed class HtmlAttributeValueAttribute : Attribute
|
||||
{
|
||||
public HtmlAttributeValueAttribute([NotNull] string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
[NotNull] public string Name { get; private set; }
|
||||
}
|
||||
|
||||
// Razor attributes
|
||||
|
||||
/// <summary>
|
||||
/// Razor attribute. Indicates that a parameter or a method is a Razor section.
|
||||
/// Use this attribute for custom wrappers similar to
|
||||
/// <c>System.Web.WebPages.WebPageBase.RenderSection(String)</c>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, Inherited = true)]
|
||||
public sealed class RazorSectionAttribute : Attribute { }
|
||||
}
|
||||
56
Wox/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// 有关程序集的常规信息通过以下
|
||||
// 特性集控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Wox")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Wox")]
|
||||
[assembly: AssemblyCopyright("Copyright © qianlifeng 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 使此程序集中的类型
|
||||
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
|
||||
// 则将该类型上的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//若要开始生成可本地化的应用程序,请在
|
||||
//<PropertyGroup> 中的 .csproj 文件中
|
||||
//设置 <UICulture>CultureYouAreCodingWith</UICulture>。例如,如果您在源文件中
|
||||
//使用的是美国英语,请将 <UICulture> 设置为 en-US。然后取消
|
||||
//对以下 NeutralResourceLanguage 特性的注释。更新
|
||||
//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //主题特定资源词典所处位置
|
||||
//(在页面或应用程序资源词典中
|
||||
// 未找到某个资源的情况下使用)
|
||||
ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
|
||||
//(在页面、应用程序或任何主题特定资源词典中
|
||||
// 未找到某个资源的情况下使用)
|
||||
)]
|
||||
|
||||
|
||||
// 程序集的版本信息由下面四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
|
||||
// 方法是按如下所示使用“*”:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
|
||||
73
Wox/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,73 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.18052
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Wox.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 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() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[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("Wox.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用此强类型资源类,为所有资源查找
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon app {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("app", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
124
Wox/Properties/Resources.resx
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="app" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\app.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
26
Wox/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.18052
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Wox.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Wox/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
BIN
Wox/Resources/app.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
Wox/Resources/ctrl.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
31
Wox/ResultItem.xaml
Normal file
@@ -0,0 +1,31 @@
|
||||
<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/>
|
||||
<ColumnDefinition Width="73.064"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="imgIco" Width="32" Height="32" HorizontalAlignment="Left" ></Image>
|
||||
<Grid HorizontalAlignment="Stretch" Margin="5 0 0 0" Grid.Column="1" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="23"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Style="{DynamicResource ItemTitleStyle}" x:Name="tbTitle">Title</TextBlock>
|
||||
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" Grid.Row="1" x:Name="tbSubTitle">sub title</TextBlock>
|
||||
</Grid>
|
||||
<DockPanel Grid.Column="2" Visibility="Hidden">
|
||||
<Image x:Name="img" Source="Images\ctrl.png" VerticalAlignment="Center"/>
|
||||
<TextBlock x:Name="tbIndex" Visibility="Hidden" FontSize="16" Foreground="#5c1f87" Margin="0 5 0 0" Text="1" VerticalAlignment="Center" HorizontalAlignment="Left" />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
110
Wox/ResultItem.xaml.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
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.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;
|
||||
if (selected)
|
||||
{
|
||||
img.Visibility = Visibility.Visible;
|
||||
img.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\Images\\enter.png"));
|
||||
}
|
||||
else
|
||||
{
|
||||
img.Visibility = Visibility.Hidden;
|
||||
}
|
||||
OnPropertyChanged("Selected");
|
||||
}
|
||||
}
|
||||
|
||||
public void SetIndex(int index)
|
||||
{
|
||||
tbIndex.Text = index.ToString();
|
||||
}
|
||||
|
||||
public ResultItem(Result result)
|
||||
{
|
||||
InitializeComponent();
|
||||
Result = result;
|
||||
|
||||
tbTitle.Text = result.Title;
|
||||
tbSubTitle.Text = result.SubTitle;
|
||||
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) =>
|
||||
{
|
||||
Result.Action();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Wox/ResultPanel.xaml
Normal file
@@ -0,0 +1,11 @@
|
||||
<UserControl x:Class="Wox.ResultPanel"
|
||||
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:DesignHeight="300" d:DesignWidth="300">
|
||||
<ScrollViewer x:Name="sv" Template="{DynamicResource ScrollViewerControlTemplate}" MaxHeight="300" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel x:Name="pnlContainer"/>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
237
Wox/ResultPanel.xaml.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Plugin;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class ResultPanel : UserControl
|
||||
{
|
||||
public bool Dirty { get; set; }
|
||||
|
||||
public delegate void ResultItemsChanged();
|
||||
|
||||
public event ResultItemsChanged resultItemChangedEvent;
|
||||
|
||||
protected virtual void OnResultItemChangedEvent()
|
||||
{
|
||||
ResultItemsChanged handler = resultItemChangedEvent;
|
||||
if (handler != null) handler();
|
||||
}
|
||||
|
||||
public void AddResults(List<Result> results)
|
||||
{
|
||||
if (results.Count == 0) return;
|
||||
|
||||
if (Dirty)
|
||||
{
|
||||
Dirty = false;
|
||||
pnlContainer.Children.Clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
{
|
||||
Result result = results[i];
|
||||
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;
|
||||
if (pnlContainer.Children.Count > 0)
|
||||
{
|
||||
var resultItem = pnlContainer.Children[0] as ResultItem;
|
||||
if (resultItem != null)
|
||||
resultItemHeight = resultItem.ActualHeight;
|
||||
}
|
||||
pnlContainer.Height = pnlContainer.Children.Count * resultItemHeight;
|
||||
OnResultItemChangedEvent();
|
||||
}
|
||||
|
||||
private bool CheckExisted(Result result)
|
||||
{
|
||||
return pnlContainer.Children.Cast<ResultItem>().Any(child => child.Result.Equals(result));
|
||||
}
|
||||
|
||||
private int GetInsertLocation(int currentScore)
|
||||
{
|
||||
int location = pnlContainer.Children.Count;
|
||||
if (pnlContainer.Children.Count == 0) return 0;
|
||||
if (currentScore > ((ResultItem)pnlContainer.Children[0]).Result.Score) return 0;
|
||||
|
||||
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))
|
||||
{
|
||||
if (currentScore == next.Result.Score)
|
||||
{
|
||||
location = index + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
location = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
public int GetCurrentResultCount()
|
||||
{
|
||||
return pnlContainer.Children.Count;
|
||||
}
|
||||
|
||||
public int GetCurrentSelectedResultIndex()
|
||||
{
|
||||
for (int i = 0; i < pnlContainer.Children.Count; i++)
|
||||
{
|
||||
var resultItemControl = pnlContainer.Children[i] as ResultItem;
|
||||
if (resultItemControl != null && resultItemControl.Selected)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void UnSelectAll()
|
||||
{
|
||||
for (int i = 0; i < pnlContainer.Children.Count; i++)
|
||||
{
|
||||
var resultItemControl = pnlContainer.Children[i] as ResultItem;
|
||||
if (resultItemControl != null && resultItemControl.Selected)
|
||||
{
|
||||
resultItemControl.Selected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectNext()
|
||||
{
|
||||
int index = GetCurrentSelectedResultIndex();
|
||||
if (index == pnlContainer.Children.Count - 1)
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
Select(index + 1);
|
||||
}
|
||||
|
||||
public void SelectPrev()
|
||||
{
|
||||
int index = GetCurrentSelectedResultIndex();
|
||||
if (index == 0)
|
||||
{
|
||||
index = pnlContainer.Children.Count;
|
||||
}
|
||||
Select(index - 1);
|
||||
}
|
||||
|
||||
private void Select(int index)
|
||||
{
|
||||
if (pnlContainer.Children.Count > 0)
|
||||
{
|
||||
int oldIndex = GetCurrentSelectedResultIndex();
|
||||
|
||||
UnSelectAll();
|
||||
var resultItemControl = pnlContainer.Children[index] as ResultItem;
|
||||
if (resultItemControl != null)
|
||||
{
|
||||
resultItemControl.Selected = true;
|
||||
|
||||
double scrollPosition = 0;
|
||||
Point newItemBottomPoint = resultItemControl.TranslatePoint(new Point(0, resultItemControl.ActualHeight), pnlContainer);
|
||||
scrollPosition = newItemBottomPoint.Y;
|
||||
if (index == 0)
|
||||
{
|
||||
sv.ScrollToTop();
|
||||
return;
|
||||
}
|
||||
if (index == pnlContainer.Children.Count - 1)
|
||||
{
|
||||
sv.ScrollToBottom();
|
||||
return;
|
||||
}
|
||||
|
||||
if (index < oldIndex)
|
||||
{
|
||||
//move up and old item is at the top of the scroll view
|
||||
var scrollPostionY = sv.VerticalOffset - sv.VerticalOffset%resultItemControl.ActualHeight +
|
||||
resultItemControl.ActualHeight;
|
||||
if (newItemBottomPoint.Y - scrollPostionY == 0)
|
||||
{
|
||||
scrollPosition = sv.VerticalOffset - resultItemControl.ActualHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//move down and old item is at the bottom of scroll view
|
||||
double scrollPostionY = (sv.ActualHeight + sv.VerticalOffset) - (sv.ActualHeight + sv.VerticalOffset)%resultItemControl.ActualHeight;
|
||||
if (scrollPostionY == newItemBottomPoint.Y - resultItemControl.ActualHeight)
|
||||
{
|
||||
scrollPosition = newItemBottomPoint.Y - sv.ActualHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sv.ScrollToVerticalOffset(scrollPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectFirst()
|
||||
{
|
||||
Select(0);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
return resultItemControl.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResultPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
pnlContainer.Children.Clear();
|
||||
pnlContainer.Height = 0;
|
||||
OnResultItemChangedEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Wox/SettingWindow.xaml
Normal file
@@ -0,0 +1,62 @@
|
||||
<Window x:Class="Wox.SettingWidow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Icon="Images\app.png"
|
||||
Title="Wox Setting"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Height="407.447" Width="843.989">
|
||||
|
||||
<TabControl Height="auto" >
|
||||
<TabItem Header="Basic">
|
||||
<StackPanel Orientation="Vertical" Margin="10">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Theme:" />
|
||||
<ComboBox x:Name="themeComboBox" SelectionChanged="ThemeComboBox_OnSelectionChanged" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<CheckBox x:Name="cbReplaceWinR" />
|
||||
<TextBlock Text="Replace Win+R:" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="Web Search">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="50"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<ListView Grid.Row="0">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridView.Columns>
|
||||
<GridViewColumn Header="Keyword" Width="180">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=OPERATOR}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Website" Width="500">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=DDATE}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Enable" Width="50" >
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Path=CONTENT}"></TextBlock>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView.Columns>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
<Button Grid.Row="1" HorizontalAlignment="Right" Click="ButtonBase_OnClick" Width="100" Margin="10">Add</Button>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Window>
|
||||
63
Wox/SettingWindow.xaml.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Wox.Helper;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class SettingWidow : Window
|
||||
{
|
||||
private MainWindow mainWindow;
|
||||
|
||||
public SettingWidow(MainWindow mainWindow)
|
||||
{
|
||||
this.mainWindow = mainWindow;
|
||||
InitializeComponent();
|
||||
Loaded += Setting_Loaded;
|
||||
cbReplaceWinR.Checked += (o, e) =>
|
||||
{
|
||||
CommonStorage.Instance.UserSetting.ReplaceWinR = true;
|
||||
CommonStorage.Instance.Save();
|
||||
};
|
||||
cbReplaceWinR.Unchecked += (o, e) =>
|
||||
{
|
||||
CommonStorage.Instance.UserSetting.ReplaceWinR = false;
|
||||
CommonStorage.Instance.Save();
|
||||
};
|
||||
}
|
||||
|
||||
private void Setting_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
foreach (string theme in LoadAvailableThemes())
|
||||
{
|
||||
string themeName = theme.Substring(theme.LastIndexOf('\\') + 1).Replace(".xaml", "");
|
||||
themeComboBox.Items.Add(themeName);
|
||||
}
|
||||
|
||||
themeComboBox.SelectedItem = CommonStorage.Instance.UserSetting.Theme;
|
||||
cbReplaceWinR.IsChecked = CommonStorage.Instance.UserSetting.ReplaceWinR;
|
||||
}
|
||||
|
||||
private List<string> LoadAvailableThemes()
|
||||
{
|
||||
string themePath = Directory.GetCurrentDirectory() + "\\Themes\\";
|
||||
return Directory.GetFiles(themePath).Where(filePath => filePath.EndsWith(".xaml")).ToList();
|
||||
}
|
||||
|
||||
private void ThemeComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
string themeName = themeComboBox.SelectedItem.ToString();
|
||||
mainWindow.SetTheme(themeName);
|
||||
CommonStorage.Instance.UserSetting.Theme = themeName;
|
||||
CommonStorage.Instance.Save();
|
||||
}
|
||||
|
||||
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WebSearchSetting webSearch = new WebSearchSetting();
|
||||
webSearch.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Wox/Themes/Default.xaml
Normal file
@@ -0,0 +1,117 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
<Style x:Key="QueryBoxStyle" TargetType="{x:Type TextBox}">
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="FontSize" Value="25" />
|
||||
<Setter Property="FontWeight" Value="Medium" />
|
||||
<Setter Property="AllowDrop" Value="true" />
|
||||
<Setter Property="Height" Value="46" />
|
||||
<Setter Property="Background" Value="#616161" />
|
||||
<Setter Property="Foreground" Value="#E3E0E3" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
|
||||
</Style>
|
||||
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
|
||||
<Setter Property="Height" Value="80" />
|
||||
<Setter Property="Width" Value="500" />
|
||||
<Setter Property="Background" Value="#424242" />
|
||||
</Style>
|
||||
<Style x:Key="GridStyle" TargetType="{x:Type Grid}">
|
||||
<Setter Property="Margin" Value="8 10 8 8" />
|
||||
</Style>
|
||||
<Style x:Key="PendingLineStyle" TargetType="{x:Type Line}">
|
||||
<Setter Property="Stroke" Value="Blue" />
|
||||
</Style>
|
||||
|
||||
<!-- Item Style -->
|
||||
<Style x:Key="ItemTitleStyle" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#FFFFF8" />
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
<Setter Property="FontWeight" Value="Medium" />
|
||||
</Style>
|
||||
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="Foreground" Value="#D9D9D4" />
|
||||
</Style>
|
||||
<Style x:Key="ItemStyle" TargetType="{x:Type UserControl}">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Selected}" Value="true">
|
||||
<Setter Property="Background" Value="#4F6180" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- ScrollViewer Style -->
|
||||
<ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}">
|
||||
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!--content in the left of ScrollViewer, just default-->
|
||||
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
|
||||
CanContentScroll="{TemplateBinding CanContentScroll}"
|
||||
CanHorizontallyScroll="False"
|
||||
CanVerticallyScroll="False"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
Content="{TemplateBinding Content}"
|
||||
Grid.Column="0"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
Grid.Row="0" />
|
||||
|
||||
<!--Scrollbar in thr rigth of ScrollViewer-->
|
||||
<ScrollBar x:Name="PART_VerticalScrollBar"
|
||||
AutomationProperties.AutomationId="VerticalScrollBar"
|
||||
Cursor="Arrow"
|
||||
Grid.Column="1"
|
||||
Margin="3 0 0 0"
|
||||
Maximum="{TemplateBinding ScrollableHeight}"
|
||||
Minimum="0"
|
||||
Grid.Row="0"
|
||||
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
|
||||
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ViewportSize="{TemplateBinding ViewportHeight}"
|
||||
Style="{DynamicResource ScrollBarStyle}" />
|
||||
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
<!-- button style in the middle of the scrollbar -->
|
||||
<Style x:Key="ThumbStyle" TargetType="{x:Type Thumb}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Border CornerRadius="2" DockPanel.Dock="Right" Background="#616161" BorderBrush="Transparent" BorderThickness="0" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ScrollBarStyle" TargetType="{x:Type ScrollBar}">
|
||||
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false" />
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
|
||||
<!-- must set min width -->
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="Width" Value="5"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ScrollBar}">
|
||||
<DockPanel>
|
||||
<Track x:Name="PART_Track" IsDirectionReversed="true" DockPanel.Dock="Right">
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{DynamicResource ThumbStyle}"/>
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</DockPanel>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
126
Wox/Themes/Light.xaml
Normal file
@@ -0,0 +1,126 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Style x:Key="QueryBoxStyle" TargetType="{x:Type TextBox}">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="FontSize" Value="25"/>
|
||||
<Setter Property="FontWeight" Value="Medium"/>
|
||||
<Setter Property="AllowDrop" Value="true"/>
|
||||
<Setter Property="Height" Value="46"/>
|
||||
<Setter Property="Background" Value="#DEDEDE"/>
|
||||
<Setter Property="Foreground" Value="#2E2F30" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
|
||||
</Style>
|
||||
<Style x:Key="WindowStyle" TargetType="{x:Type Window}" >
|
||||
<Setter Property="Background" Value="#EDEDED"></Setter>
|
||||
<Setter Property="Width" Value="520"></Setter>
|
||||
<Setter Property="Height" Value="80"></Setter>
|
||||
</Style>
|
||||
<Style x:Key="GridStyle" TargetType="{x:Type Grid}" >
|
||||
<Setter Property="Margin" Value="8 10 8 8"></Setter>
|
||||
</Style>
|
||||
<Style x:Key="PendingLineStyle" TargetType="{x:Type Line}" >
|
||||
<Setter Property="Stroke" Value="Blue"></Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Item Style -->
|
||||
<Style x:Key="ItemTitleStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#141411"></Setter>
|
||||
<Setter Property="FontSize" Value="16"></Setter>
|
||||
<Setter Property="FontWeight" Value="Medium"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=resultItemControl, Path=Selected}" Value="true">
|
||||
<Setter Property="Foreground" Value="#F6F6FF"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="ItemSubTitleStyle" TargetType="{x:Type TextBlock}" >
|
||||
<Setter Property="Foreground" Value="#B3B2B0"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ElementName=resultItemControl, Path=Selected}" Value="true">
|
||||
<Setter Property="Foreground" Value="#F6F6FF"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="ItemStyle" TargetType="{x:Type UserControl}" >
|
||||
<Setter Property="Background" Value="Transparent"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Selected}" Value="true">
|
||||
<Setter Property="Background" Value="#543BFD"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- ScrollViewer Style -->
|
||||
<ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}">
|
||||
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!--content in the left of ScrollViewer, just default-->
|
||||
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
|
||||
CanContentScroll="{TemplateBinding CanContentScroll}"
|
||||
CanHorizontallyScroll="False"
|
||||
CanVerticallyScroll="False"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
Content="{TemplateBinding Content}"
|
||||
Grid.Column="0"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
Grid.Row="0" />
|
||||
|
||||
<!--Scrollbar in thr rigth of ScrollViewer-->
|
||||
<ScrollBar x:Name="PART_VerticalScrollBar"
|
||||
AutomationProperties.AutomationId="VerticalScrollBar"
|
||||
Cursor="Arrow"
|
||||
Grid.Column="1"
|
||||
Margin="2 0 0 0"
|
||||
Maximum="{TemplateBinding ScrollableHeight}"
|
||||
Minimum="0"
|
||||
Grid.Row="0"
|
||||
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
|
||||
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ViewportSize="{TemplateBinding ViewportHeight}"
|
||||
Style="{DynamicResource ScrollBarStyle}" />
|
||||
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
<!-- button style in the middle of the scrollbar -->
|
||||
<Style x:Key="ThumbStyle" TargetType="{x:Type Thumb}">
|
||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||
<Setter Property="OverridesDefaultStyle" Value="true"/>
|
||||
<Setter Property="IsTabStop" Value="false"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Border CornerRadius="2" DockPanel.Dock="Right" Background="#DEDEDE" BorderBrush="Transparent" BorderThickness="0" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ScrollBarStyle" TargetType="{x:Type ScrollBar}">
|
||||
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false" />
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
|
||||
<!-- must set min width -->
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="Width" Value="3.5"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ScrollBar}">
|
||||
<DockPanel>
|
||||
<Track x:Name="PART_Track" IsDirectionReversed="true" DockPanel.Dock="Right">
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{DynamicResource ThumbStyle}"/>
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</DockPanel>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
48
Wox/WebSearchSetting.xaml
Normal file
@@ -0,0 +1,48 @@
|
||||
<Window x:Class="Wox.WebSearchSetting"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Icon="Images\app.png"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="WebSearchSetting" Height="400" Width="674.766">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition Height="40"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition Height="24"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition Height="24"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition Height="24"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="120"></ColumnDefinition>
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Search URL:</TextBlock>
|
||||
<TextBox Margin="10" Grid.Row="0" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
|
||||
<TextBlock Margin="10 0 10 0" Foreground="Gray" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" HorizontalAlignment="Left">Perform a search on a website and copy the result URL. Replace your search term with {query} in curly brackets</TextBlock>
|
||||
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Title:</TextBlock>
|
||||
<TextBox Margin="10" Grid.Row="2" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
|
||||
<TextBlock Margin="10 0 10 0" Foreground="Gray" VerticalAlignment="Top" Grid.Row="3" Grid.Column="1" TextWrapping="Wrap" HorizontalAlignment="Left">What to show in the Wox. The search query is automatically appended for clarity.</TextBlock>
|
||||
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Keyword:</TextBlock>
|
||||
<TextBox Margin="10" Grid.Row="4" Width="400" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
|
||||
<TextBlock Margin="10 0 10 0" Foreground="Gray" VerticalAlignment="Top" Grid.Row="5" Grid.Column="1" TextWrapping="Wrap" HorizontalAlignment="Left">What you type to use this shortcut.</TextBlock>
|
||||
|
||||
<TextBlock Margin="10" FontSize="14" Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right">Validation:</TextBlock>
|
||||
<StackPanel Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<TextBox Margin="10" Width="400" HorizontalAlignment="Left"></TextBox>
|
||||
<Button x:Name="btnValidation" Width="60" Height="24">Test</Button>
|
||||
</StackPanel>
|
||||
<TextBlock Margin="10 0 10 0" Foreground="Gray" VerticalAlignment="Top" Grid.Row="7" Grid.Column="1" TextWrapping="Wrap" HorizontalAlignment="Left">Type some text and click test to check it works.</TextBlock>
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="8" Grid.Column="1">
|
||||
<Button x:Name="btnCancel" Click="BtnCancel_OnClick" Margin="10 0 10 0" Width="80" Height="25">Cancel</Button>
|
||||
<Button Margin="10 0 10 0" Width="80" Height="25">Add</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
28
Wox/WebSearchSetting.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
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;
|
||||
|
||||
namespace Wox
|
||||
{
|
||||
public partial class WebSearchSetting : Window
|
||||
{
|
||||
public WebSearchSetting()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
291
Wox/Wox.csproj
Normal file
@@ -0,0 +1,291 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.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>{DB90F671-D861-46BB-93A3-F1304F5BA1C5}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Wox</RootNamespace>
|
||||
<AssemblyName>Wox</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
<TargetFrameworkProfile />
|
||||
<PublishUrl>发布\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>app.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>Wox.EntryPoint</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Accessibility" />
|
||||
<Reference Include="log4net">
|
||||
<HintPath>..\packages\log4net.2.0.3\lib\net35-full\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||
<Reference Include="ReachFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Printing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="UIAutomationProvider" />
|
||||
<Reference Include="UIAutomationTypes" />
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="WindowsInput">
|
||||
<HintPath>..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Commands\BaseCommand.cs" />
|
||||
<Compile Include="Commands\CommandFactory.cs" />
|
||||
<Compile Include="Commands\PluginCommand.cs" />
|
||||
<Compile Include="Commands\SystemCommand.cs" />
|
||||
<Compile Include="DispatcherExtensions.cs" />
|
||||
<Compile Include="Helper\DwmDropShadow.cs" />
|
||||
<Compile Include="Helper\KeyboardHook.cs" />
|
||||
<Compile Include="Helper\Log.cs" />
|
||||
<Compile Include="Helper\CommonStorage.cs" />
|
||||
<Compile Include="Models\UserSetting.cs" />
|
||||
<Compile Include="Models\WebSearch.cs" />
|
||||
<Compile Include="Helper\WoxException.cs" />
|
||||
<Compile Include="Helper\KeyboardListener.cs" />
|
||||
<Compile Include="Msg.xaml.cs">
|
||||
<DependentUpon>Msg.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="PluginLoader\BasePluginLoader.cs" />
|
||||
<Compile Include="PluginLoader\CSharpPluginLoader.cs" />
|
||||
<Compile Include="Helper\IniParser.cs" />
|
||||
<Compile Include="PluginLoader\Plugins.cs" />
|
||||
<Compile Include="PluginLoader\PythonPluginLoader.cs" />
|
||||
<Compile Include="PluginLoader\PythonPluginWrapper.cs" />
|
||||
<Compile Include="Properties\Annotations.cs" />
|
||||
<Compile Include="ResultPanel.xaml.cs">
|
||||
<DependentUpon>ResultPanel.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ResultItem.xaml.cs">
|
||||
<DependentUpon>ResultItem.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\UserSelectedRecords.cs" />
|
||||
<Compile Include="SettingWindow.xaml.cs">
|
||||
<DependentUpon>SettingWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WebSearchSetting.xaml.cs">
|
||||
<DependentUpon>WebSearchSetting.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="Msg.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="ResultPanel.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="ResultItem.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="SettingWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Themes\Light.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Themes\Default.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="WebSearchSetting.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Pythonnet.Runtime\Python.Runtime.csproj">
|
||||
<Project>{097b4ac0-74e9-4c58-bcf8-c69746ec8271}</Project>
|
||||
<Name>Python.Runtime</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Wox.Plugin.System\Wox.Plugin.System.csproj">
|
||||
<Project>{69ce0206-cb41-453d-88af-df86092ef9b8}</Project>
|
||||
<Name>Wox.Plugin.System</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Wox.Plugin\Wox.Plugin.csproj">
|
||||
<Project>{8451ECDD-2EA4-4966-BB0A-7BBC40138E80}</Project>
|
||||
<Name>Wox.Plugin</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\app.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\ctrl.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\ctrl.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="app.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Service References\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\app.png" />
|
||||
<Resource Include="Images\bookmark.png" />
|
||||
<Resource Include="Images\close.png" />
|
||||
<Resource Include="Images\cmd.png" />
|
||||
<Resource Include="Images\enter.png" />
|
||||
<Resource Include="Images\exit.png" />
|
||||
<Resource Include="Images\folder.png" />
|
||||
<Resource Include="Images\lock.png" />
|
||||
<Resource Include="Images\logoff.png" />
|
||||
<Resource Include="Images\work.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /Y $(ProjectDir)Images\*.* $(TargetDir)Images\
|
||||
xcopy /Y $(ProjectDir)app.ico $(TargetDir)
|
||||
xcopy /Y $(ProjectDir)Themes\*.* $(TargetDir)Themes\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
BIN
Wox/app.ico
Normal file
|
After Width: | Height: | Size: 361 KiB |
BIN
Wox/app.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
6
Wox/packages.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="InputSimulator" version="1.0.4.0" targetFramework="net35" />
|
||||
<package id="log4net" version="2.0.3" targetFramework="net35" />
|
||||
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net35" />
|
||||
</packages>
|
||||