Add clipboard plugin.

This commit is contained in:
qianlifeng
2014-02-28 23:21:01 +08:00
parent 7d1ee33e1f
commit 7f769e00b9
31 changed files with 455 additions and 65 deletions

View File

@@ -125,6 +125,7 @@ namespace Wox.Plugin.Doc
//frm.ShowDoc(url); //frm.ShowDoc(url);
string browser = GetDefaultBrowserPath(); string browser = GetDefaultBrowserPath();
Process.Start(browser, String.Format("\"file:///{0}\"", url)); Process.Start(browser, String.Format("\"file:///{0}\"", url));
return true;
} }
}); });
} }

View File

@@ -0,0 +1,234 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace Wox.Plugin.Clipboard
{
public static class ClipboardMonitor
{
public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data);
public static event OnClipboardChangeEventHandler OnClipboardChange;
public static void Start()
{
ClipboardWatcher.Start();
ClipboardWatcher.OnClipboardChange += (ClipboardFormat format, object data) =>
{
if (OnClipboardChange != null)
OnClipboardChange(format, data);
};
}
public static void Stop()
{
OnClipboardChange = null;
ClipboardWatcher.Stop();
}
class ClipboardWatcher : Form
{
// static instance of this form
private static ClipboardWatcher mInstance;
// needed to dispose this form
static IntPtr nextClipboardViewer;
public delegate void OnClipboardChangeEventHandler(ClipboardFormat format, object data);
public static event OnClipboardChangeEventHandler OnClipboardChange;
// start listening
public static void Start()
{
// we can only have one instance if this class
if (mInstance != null)
return;
Thread t = new Thread(new ParameterizedThreadStart(x =>
{
Application.Run(new ClipboardWatcher());
}));
t.SetApartmentState(ApartmentState.STA); // give the [STAThread] attribute
t.Start();
}
// stop listening (dispose form)
public static void Stop()
{
mInstance.Invoke(new MethodInvoker(() =>
{
ChangeClipboardChain(mInstance.Handle, nextClipboardViewer);
}));
mInstance.Invoke(new MethodInvoker(mInstance.Close));
mInstance.Dispose();
mInstance = null;
}
// on load: (hide this window)
protected override void SetVisibleCore(bool value)
{
CreateHandle();
mInstance = this;
nextClipboardViewer = SetClipboardViewer(mInstance.Handle);
base.SetVisibleCore(false);
}
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
// defined in winuser.h
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x030D;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
ClipChanged();
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
case WM_CHANGECBCHAIN:
if (m.WParam == nextClipboardViewer)
nextClipboardViewer = m.LParam;
else
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
default:
base.WndProc(ref m);
break;
}
}
static readonly string[] formats = Enum.GetNames(typeof(ClipboardFormat));
private void ClipChanged()
{
IDataObject iData = System.Windows.Forms.Clipboard.GetDataObject();
ClipboardFormat? format = null;
foreach (var f in formats)
{
if (iData.GetDataPresent(f))
{
format = (ClipboardFormat)Enum.Parse(typeof(ClipboardFormat), f);
break;
}
}
object data = iData.GetData(format.ToString());
if (data == null || format == null)
return;
if (OnClipboardChange != null)
OnClipboardChange((ClipboardFormat)format, data);
}
}
}
public enum ClipboardFormat : byte
{
/// <summary>Specifies the standard ANSI text format. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Text,
/// <summary>Specifies the standard Windows Unicode text format. This static field
/// is read-only.</summary>
/// <filterpriority>1</filterpriority>
UnicodeText,
/// <summary>Specifies the Windows device-independent bitmap (DIB) format. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Dib,
/// <summary>Specifies a Windows bitmap format. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Bitmap,
/// <summary>Specifies the Windows enhanced metafile format. This static field is
/// read-only.</summary>
/// <filterpriority>1</filterpriority>
EnhancedMetafile,
/// <summary>Specifies the Windows metafile format, which Windows Forms does not
/// directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
MetafilePict,
/// <summary>Specifies the Windows symbolic link format, which Windows Forms does
/// not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
SymbolicLink,
/// <summary>Specifies the Windows Data Interchange Format (DIF), which Windows Forms
/// does not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Dif,
/// <summary>Specifies the Tagged Image File Format (TIFF), which Windows Forms does
/// not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Tiff,
/// <summary>Specifies the standard Windows original equipment manufacturer (OEM)
/// text format. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
OemText,
/// <summary>Specifies the Windows palette format. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Palette,
/// <summary>Specifies the Windows pen data format, which consists of pen strokes
/// for handwriting software, Windows Forms does not use this format. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
PenData,
/// <summary>Specifies the Resource Interchange File Format (RIFF) audio format,
/// which Windows Forms does not directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Riff,
/// <summary>Specifies the wave audio format, which Windows Forms does not directly
/// use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
WaveAudio,
/// <summary>Specifies the Windows file drop format, which Windows Forms does not
/// directly use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
FileDrop,
/// <summary>Specifies the Windows culture format, which Windows Forms does not directly
/// use. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Locale,
/// <summary>Specifies text consisting of HTML data. This static field is read-only.
/// </summary>
/// <filterpriority>1</filterpriority>
Html,
/// <summary>Specifies text consisting of Rich Text Format (RTF) data. This static
/// field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Rtf,
/// <summary>Specifies a comma-separated value (CSV) format, which is a common interchange
/// format used by spreadsheets. This format is not used directly by Windows Forms.
/// This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
CommaSeparatedValue,
/// <summary>Specifies the Windows Forms string class format, which Windows Forms
/// uses to store string objects. This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
StringFormat,
/// <summary>Specifies a format that encapsulates any type of Windows Forms object.
/// This static field is read-only.</summary>
/// <filterpriority>1</filterpriority>
Serializable,
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

View File

@@ -1,21 +1,85 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Runtime.InteropServices;
using System.Windows.Forms;
using WindowsInput;
using WindowsInput.Native;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Wox.Plugin.DotnetPluginTest namespace Wox.Plugin.Clipboard
{ {
public class Main : IPlugin public class Main : IPlugin
{ {
private const int MaxDataCount = 100;
private readonly KeyboardSimulator keyboardSimulator = new KeyboardSimulator(new InputSimulator());
private PluginInitContext context;
List<string> dataList = new List<string>();
public List<Result> Query(Query query) public List<Result> Query(Query query)
{ {
return new List<Result>(); var results = new List<Result>();
List<string> displayData = new List<string>();
if (query.ActionParameters.Count == 0)
{
displayData = dataList;
}
else
{
displayData = dataList.Where(i => i.ToLower().Contains(query.GetAllRemainingParameter().ToLower()))
.ToList();
}
results.AddRange(displayData.Select(o => new Result
{
Title = o,
IcoPath = "Images\\clipboard.png",
Action = c =>
{
if (c.SpecialKeyState.CtrlPressed)
{
context.ShowCurrentResultItemTooltip(o);
return false;
}
else
{
System.Windows.Forms.Clipboard.SetText(o);
context.HideApp();
keyboardSimulator.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_V);
return true;
}
}
}).Reverse());
return results;
} }
public void Init(PluginInitContext context) public void Init(PluginInitContext context)
{ {
var s = JsonSerializer.Create(); this.context = context;
ClipboardMonitor.OnClipboardChange += ClipboardMonitor_OnClipboardChange;
ClipboardMonitor.Start();
}
void ClipboardMonitor_OnClipboardChange(ClipboardFormat format, object data)
{
if (format == ClipboardFormat.Html ||
format == ClipboardFormat.SymbolicLink ||
format == ClipboardFormat.Text ||
format == ClipboardFormat.UnicodeText)
{
if (data != null && !string.IsNullOrEmpty(data.ToString()))
{
if (dataList.Contains(data.ToString()))
{
dataList.Remove(data.ToString());
}
dataList.Add(data.ToString());
if (dataList.Count > MaxDataCount)
{
dataList.Remove(dataList.First());
}
}
}
} }
} }
} }

View File

@@ -7,8 +7,8 @@
<ProjectGuid>{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}</ProjectGuid> <ProjectGuid>{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.DotnetPluginTest</RootNamespace> <RootNamespace>Wox.Plugin.Clipboard</RootNamespace>
<AssemblyName>Wox.Plugin.DotnetPluginTest</AssemblyName> <AssemblyName>Wox.Plugin.Clipboard</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
@@ -38,12 +38,17 @@
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="WindowsInput">
<HintPath>..\..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ClipboardMonitor.cs" />
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
@@ -59,9 +64,13 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Images\clipboard.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\</PostBuildEvent> <PostBuildEvent>xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\
xcopy /Y /E $(ProjectDir)Images $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\Images\</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

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

View File

@@ -1,8 +1,8 @@
[plugin] [plugin]
ActionKeyword = ts ActionKeyword = cb
Name = dotnet test Name = clipboard monitor
Author = qianlifeng Author = qianlifeng
Version = 0.1 Version = 0.1
Language = csharp Language = csharp
Description = test Description = clipboard monitor
ExecuteFile = Wox.Plugin.DotnetPluginTest.dll ExecuteFile = Wox.Plugin.Clipboard.dll

View File

@@ -36,6 +36,7 @@ namespace Wox.Plugin.Everything
{ {
context.ShowMsg("Could not start " + r.Title, ex.Message, null); context.ShowMsg("Could not start " + r.Title, ex.Message, null);
} }
return true;
}; };
results.Add(r); results.Add(r);
} }

View File

@@ -81,6 +81,7 @@ namespace Wox.Plugin.Fanyi
Clipboard.SetText(dst); Clipboard.SetText(dst);
context.ShowMsg("translation has been copyed to your clipboard.", "", context.ShowMsg("translation has been copyed to your clipboard.", "",
AssemblyDirectory + "\\Images\\translate.png"); AssemblyDirectory + "\\Images\\translate.png");
return true;
} }
}); });
} }

View File

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

View File

@@ -43,6 +43,7 @@ namespace Wox.Plugin.System
{ {
MessageBox.Show("open url failed:" + c.Url); MessageBox.Show("open url failed:" + c.Url);
} }
return true;
} }
}).ToList(); }).ToList();
} }

View File

@@ -30,6 +30,7 @@ namespace Wox.Plugin.System
{ {
ExecuteCmd(m.Key); ExecuteCmd(m.Key);
AddCmdHistory(m.Key); AddCmdHistory(m.Key);
return true;
} }
}).Take(5); }).Take(5);
@@ -49,6 +50,7 @@ namespace Wox.Plugin.System
{ {
ExecuteCmd(cmd); ExecuteCmd(cmd);
AddCmdHistory(cmd); AddCmdHistory(cmd);
return true;
} }
}; };
results.Add(result); results.Add(result);
@@ -64,6 +66,7 @@ namespace Wox.Plugin.System
{ {
ExecuteCmd(m.Key); ExecuteCmd(m.Key);
AddCmdHistory(m.Key); AddCmdHistory(m.Key);
return true;
} }
}).Take(4); }).Take(4);

View File

@@ -26,6 +26,7 @@ namespace Wox.Plugin.System
Action = (c) => Action = (c) =>
{ {
Process.Start(query.RawQuery); Process.Start(query.RawQuery);
return true;
} }
}; };
results.Add(result); results.Add(result);

View File

@@ -68,6 +68,7 @@ namespace Wox.Plugin.System
throw e; throw e;
} }
} }
return true;
} }
}).ToList(); }).ToList();
} }

View File

@@ -18,7 +18,11 @@ namespace Wox.Plugin.System
Title = "Wox Setting Dialog", Title = "Wox Setting Dialog",
Score = 100, Score = 100,
IcoPath = "Images/app.png", IcoPath = "Images/app.png",
Action = (contenxt) => context.OpenSettingDialog() Action = (contenxt) =>
{
context.OpenSettingDialog();
return true;
}
}); });
} }

View File

@@ -47,7 +47,11 @@ namespace Wox.Plugin.System
SubTitle = "Shutdown Computer", SubTitle = "Shutdown Computer",
Score = 100, Score = 100,
IcoPath = "Images\\exit.png", IcoPath = "Images\\exit.png",
Action = (c) => Process.Start("shutdown","/s /t 0") Action = (c) =>
{
Process.Start("shutdown", "/s /t 0");
return true;
}
}); });
availableResults.Add(new Result availableResults.Add(new Result
{ {
@@ -63,7 +67,11 @@ namespace Wox.Plugin.System
SubTitle = "Lock this computer", SubTitle = "Lock this computer",
Score = 20, Score = 20,
IcoPath = "Images\\lock.png", IcoPath = "Images\\lock.png",
Action = (c) => LockWorkStation() Action = (c) =>
{
LockWorkStation();
return true;
}
}); });
availableResults.Add(new Result availableResults.Add(new Result
{ {
@@ -71,7 +79,11 @@ namespace Wox.Plugin.System
SubTitle = "Close this app", SubTitle = "Close this app",
Score = 110, Score = 110,
IcoPath = "Images\\app.png", IcoPath = "Images\\app.png",
Action = (c) => context.CloseApp() Action = (c) =>
{
context.CloseApp();
return true;
}
}); });
} }
} }

View File

@@ -27,8 +27,11 @@ namespace Wox.Plugin.System
SubTitle = string.Format("Activate {0} plugin", metadata.Name), SubTitle = string.Format("Activate {0} plugin", metadata.Name),
Score = 50, Score = 50,
IcoPath = "Images/work.png", IcoPath = "Images/work.png",
Action = (c) => changeQuery(metadataCopy.ActionKeyword + " "), Action = (c) =>
DontHideWoxAfterSelect = true {
changeQuery(metadataCopy.ActionKeyword + " ");
return false;
},
}; };
results.Add(result); results.Add(result);
} }
@@ -40,8 +43,11 @@ namespace Wox.Plugin.System
SubTitle = string.Format("Activate {0} web search", n.ActionWord), SubTitle = string.Format("Activate {0} web search", n.ActionWord),
Score = 50, Score = 50,
IcoPath = "Images/work.png", IcoPath = "Images/work.png",
Action = (c) => changeQuery(n.ActionWord + " "), Action = (c) =>
DontHideWoxAfterSelect = true {
changeQuery(n.ActionWord + " ");
return false;
}
})); }));
return results; return results;

View File

@@ -26,7 +26,11 @@ namespace Wox.Plugin.System
{ {
Title = string.Format("Search {0} for \"{1}\"", webSearch.Title, keyword), Title = string.Format("Search {0} for \"{1}\"", webSearch.Title, keyword),
IcoPath = webSearch.IconPath, IcoPath = webSearch.IconPath,
Action = (c) => Process.Start(webSearch.Url.Replace("{q}", keyword)) Action = (c) =>
{
Process.Start(webSearch.Url.Replace("{q}", keyword));
return true;
}
}); });
} }

View File

@@ -16,5 +16,7 @@ namespace Wox.Plugin
public Action ShowApp { get; set; } public Action ShowApp { get; set; }
public Action<string,string,string> ShowMsg { get; set; } public Action<string,string,string> ShowMsg { get; set; }
public Action OpenSettingDialog { get; set; } public Action OpenSettingDialog { get; set; }
public Action<string> ShowCurrentResultItemTooltip { get; set; }
} }
} }

View File

@@ -20,6 +20,7 @@ namespace Wox.Plugin
if (string.IsNullOrEmpty(RawQuery)) return; if (string.IsNullOrEmpty(RawQuery)) return;
string[] strings = RawQuery.Split(' '); string[] strings = RawQuery.Split(' ');
//todo:not exactly correct. query that didn't containing a space should be a valid query
if (strings.Length == 1) return; //we consider a valid query must contain a space if (strings.Length == 1) return; //we consider a valid query must contain a space
ActionName = strings[0]; ActionName = strings[0];
@@ -31,5 +32,16 @@ namespace Wox.Plugin
} }
} }
} }
public string GetAllRemainingParameter()
{
string[] strings = RawQuery.Split(' ');
if (strings.Length > 1)
{
return RawQuery.Substring(RawQuery.IndexOf(' ') + 1);
}
return string.Empty;
}
} }
} }

View File

@@ -9,10 +9,12 @@ namespace Wox.Plugin
public string Title { get; set; } public string Title { get; set; }
public string SubTitle { get; set; } public string SubTitle { get; set; }
public string IcoPath { get; set; } public string IcoPath { get; set; }
public Action<ActionContext> Action { get; set; }
public int Score { get; set; }
public bool DontHideWoxAfterSelect { get; set; } /// <summary>
/// return true to hide wox after select result
/// </summary>
public Func<ActionContext,bool> Action { get; set; }
public int Score { get; set; }
/// <summary> /// <summary>
/// Auto add scores for MRU items /// Auto add scores for MRU items

View File

@@ -13,7 +13,6 @@ namespace Wox.Test
public void QueryActionTest() public void QueryActionTest()
{ {
Query q = new Query("this"); Query q = new Query("this");
Assert.AreEqual(q.ActionName,"this");
q = new Query("ev file.txt"); q = new Query("ev file.txt");
Assert.AreEqual(q.ActionName,"ev"); Assert.AreEqual(q.ActionName,"ev");
@@ -24,6 +23,9 @@ namespace Wox.Test
Assert.AreEqual(q.ActionName,"ev"); Assert.AreEqual(q.ActionName,"ev");
Assert.AreEqual(q.ActionParameters.Count,2); Assert.AreEqual(q.ActionParameters.Count,2);
Assert.AreEqual(q.ActionParameters[1],"file2.txt"); Assert.AreEqual(q.ActionParameters[1],"file2.txt");
q = new Query("ev file.txt file2.tx st");
Assert.AreEqual(q.GetAllRemainingParameter(), "file.txt file2.tx st");
} }
} }
} }

View File

@@ -25,7 +25,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Everything", "Pl
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC.csproj", "{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC.csproj", "{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.DotnetPluginTest", "Plugins\Wox.Plugin.DotnetPluginTest\Wox.Plugin.DotnetPluginTest.csproj", "{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Clipboard", "Plugins\Wox.Plugin.DotnetPluginTest\Wox.Plugin.Clipboard.csproj", "{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -56,8 +56,8 @@ namespace Wox
CommonStorage.Instance.UserSetting.CustomPluginHotkeys.Add(pluginHotkey); CommonStorage.Instance.UserSetting.CustomPluginHotkeys.Add(pluginHotkey);
settingWidow.MainWindow.SetHotkey(ctlHotkey.CurrentHotkey.ToString(), delegate settingWidow.MainWindow.SetHotkey(ctlHotkey.CurrentHotkey.ToString(), delegate
{ {
settingWidow.MainWindow.ShowApp();
settingWidow.MainWindow.ChangeQuery(pluginHotkey.ActionKeyword); settingWidow.MainWindow.ChangeQuery(pluginHotkey.ActionKeyword);
settingWidow.MainWindow.ShowApp();
}); });
MessageBox.Show("Add hotkey successfully!"); MessageBox.Show("Add hotkey successfully!");
} }

View File

@@ -42,7 +42,10 @@ namespace Wox
return GetIcon(resolvedPath); return GetIcon(resolvedPath);
} }
if(!string.IsNullOrEmpty(path)) return new BitmapImage(new Uri(resolvedPath)); if (!string.IsNullOrEmpty(resolvedPath) && File.Exists(resolvedPath))
{
return new BitmapImage(new Uri(resolvedPath));
}
return null; return null;
} }

View File

@@ -18,7 +18,7 @@
<RowDefinition></RowDefinition> <RowDefinition></RowDefinition>
<RowDefinition></RowDefinition> <RowDefinition></RowDefinition>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBox AllowDrop="True" Style="{DynamicResource QueryBoxStyle}" Grid.Row="0" x:Name="tbQuery" PreviewKeyDown="TbQuery_OnPreviewKeyDown" TextChanged="TextBoxBase_OnTextChanged" /> <TextBox 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> <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"/> <wox:ResultPanel x:Name="resultCtrl" Grid.Row="2"/>
</Grid> </Grid>

View File

@@ -23,7 +23,7 @@ using ContextMenu = System.Windows.Forms.ContextMenu;
using KeyEventArgs = System.Windows.Input.KeyEventArgs; using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MenuItem = System.Windows.Forms.MenuItem; using MenuItem = System.Windows.Forms.MenuItem;
using MessageBox = System.Windows.MessageBox; using MessageBox = System.Windows.MessageBox;
using Timer = System.Timers.Timer; using ToolTip = System.Windows.Controls.ToolTip;
namespace Wox namespace Wox
{ {
@@ -38,11 +38,13 @@ namespace Wox
private bool WinRStroked; private bool WinRStroked;
private NotifyIcon notifyIcon; private NotifyIcon notifyIcon;
private bool queryHasReturn; private bool queryHasReturn;
private ToolTip toolTip = new ToolTip();
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
progressBar.ToolTip = toolTip;
InitialTray(); InitialTray();
ThreadPool.SetMaxThreads(30, 10); ThreadPool.SetMaxThreads(30, 10);
@@ -87,7 +89,7 @@ namespace Wox
SetHotkey(hotkey.Hotkey, delegate SetHotkey(hotkey.Hotkey, delegate
{ {
ShowApp(); ShowApp();
ChangeQuery(hotkey1.ActionKeyword); ChangeQuery(hotkey1.ActionKeyword, true);
}); });
} }
} }
@@ -105,27 +107,6 @@ namespace Wox
e.Handled = true; e.Handled = true;
} }
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.
var t = new 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() private void InitProgressbarAnimation()
{ {
var da = new DoubleAnimation(progressBar.X2, Width + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); var da = new DoubleAnimation(progressBar.X2, Width + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600)));
@@ -153,6 +134,7 @@ namespace Wox
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{ {
toolTip.IsOpen = false;
resultCtrl.Dirty = true; resultCtrl.Dirty = true;
Dispatcher.DelayInvoke("UpdateSearch", Dispatcher.DelayInvoke("UpdateSearch",
o => o =>
@@ -289,11 +271,13 @@ namespace Wox
case Key.Down: case Key.Down:
resultCtrl.SelectNext(); resultCtrl.SelectNext();
toolTip.IsOpen = false;
e.Handled = true; e.Handled = true;
break; break;
case Key.Up: case Key.Up:
resultCtrl.SelectPrev(); resultCtrl.SelectPrev();
toolTip.IsOpen = false;
e.Handled = true; e.Handled = true;
break; break;
@@ -309,16 +293,16 @@ namespace Wox
Result result = resultCtrl.AcceptSelect(); Result result = resultCtrl.AcceptSelect();
if (result != null) if (result != null)
{ {
if (!result.DontHideWoxAfterSelect)
{
HideWox();
}
if (result.Action != null) if (result.Action != null)
{ {
result.Action(new ActionContext() bool hideWindow = result.Action(new ActionContext()
{ {
SpecialKeyState = new GloablHotkey().CheckModifiers() SpecialKeyState = new GloablHotkey().CheckModifiers()
}); });
if (hideWindow)
{
HideWox();
}
CommonStorage.Instance.UserSelectedRecords.Add(result); CommonStorage.Instance.UserSelectedRecords.Add(result);
} }
} }
@@ -342,7 +326,7 @@ namespace Wox
} }
Dispatcher.DelayInvoke("ShowResult", k => resultCtrl.Dispatcher.Invoke(new Action(() => Dispatcher.DelayInvoke("ShowResult", k => resultCtrl.Dispatcher.Invoke(new Action(() =>
{ {
List<Result> l =waitShowResultList.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList(); List<Result> l = waitShowResultList.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == tbQuery.Text).ToList();
waitShowResultList.Clear(); waitShowResultList.Clear();
resultCtrl.AddResults(l); resultCtrl.AddResults(l);
})), TimeSpan.FromMilliseconds(50)); })), TimeSpan.FromMilliseconds(50));
@@ -362,10 +346,14 @@ namespace Wox
#region Public API #region Public API
public void ChangeQuery(string query) public void ChangeQuery(string query, bool requery = false)
{ {
tbQuery.Text = query; tbQuery.Text = query;
tbQuery.CaretIndex = tbQuery.Text.Length; tbQuery.CaretIndex = tbQuery.Text.Length;
if (requery)
{
TextBoxBase_OnTextChanged(null, null);
}
} }
public void CloseApp() public void CloseApp()
@@ -396,6 +384,14 @@ namespace Wox
new SettingWidow(this).Show(); new SettingWidow(this).Show();
} }
public void ShowCurrentResultItemTooltip(string text)
{
toolTip.Content = text;
toolTip.IsOpen = true;
}
#endregion #endregion
} }
} }

View File

@@ -35,7 +35,8 @@ namespace Wox.PluginLoader
HideApp = App.Window.HideApp, HideApp = App.Window.HideApp,
ShowApp = () => App.Window.ShowApp(), ShowApp = () => App.Window.ShowApp(),
ShowMsg = (title, subTitle, iconPath) => App.Window.ShowMsg(title, subTitle, iconPath), ShowMsg = (title, subTitle, iconPath) => App.Window.ShowMsg(title, subTitle, iconPath),
OpenSettingDialog = () => App.Window.OpenSettingDialog() OpenSettingDialog = () => App.Window.OpenSettingDialog(),
ShowCurrentResultItemTooltip = (msg) => App.Window.ShowCurrentResultItemTooltip(msg)
})); }));
} }
} }

View File

@@ -36,7 +36,11 @@ namespace Wox.PluginLoader
PythonResult ps = pythonResult; PythonResult ps = pythonResult;
if (!string.IsNullOrEmpty(ps.ActionName)) if (!string.IsNullOrEmpty(ps.ActionName))
{ {
ps.Action = (context) => InvokeFunc(ps.ActionName, GetPythonActionContext(context), new PyString(ps.ActionPara)); ps.Action = (context) =>
{
InvokeFunc(ps.ActionName, GetPythonActionContext(context), new PyString(ps.ActionPara));
return true;
};
} }
r.Add(ps); r.Add(ps);
} }

View File

@@ -40,7 +40,7 @@
<RowDefinition></RowDefinition> <RowDefinition></RowDefinition>
<RowDefinition Height="Auto" x:Name="SubTitleRowDefinition"></RowDefinition> <RowDefinition Height="Auto" x:Name="SubTitleRowDefinition"></RowDefinition>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Style="{DynamicResource ItemTitleStyle}" VerticalAlignment="Center" x:Name="tbTitle" Text="{Binding Title}"></TextBlock> <TextBlock Style="{DynamicResource ItemTitleStyle}" ToolTip="{Binding Title}" x:Name="tbTitle" Text="{Binding Title}"></TextBlock>
<TextBlock Style="{DynamicResource ItemSubTitleStyle}" Visibility="{Binding SubTitle, Converter={wox:StringNullOrEmptyToVisibilityConverter}}" Grid.Row="1" x:Name="tbSubTitle" Text="{Binding SubTitle}"></TextBlock> <TextBlock Style="{DynamicResource ItemSubTitleStyle}" Visibility="{Binding SubTitle, Converter={wox:StringNullOrEmptyToVisibilityConverter}}" Grid.Row="1" x:Name="tbSubTitle" Text="{Binding SubTitle}"></TextBlock>
</Grid> </Grid>
</Grid> </Grid>

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media;
using Wox.Helper; using Wox.Helper;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Plugin; using Wox.Plugin;
@@ -58,6 +59,29 @@ namespace Wox
return location; return location;
} }
private FrameworkElement FindByName(string name, FrameworkElement root)
{
Stack<FrameworkElement> tree = new Stack<FrameworkElement>();
tree.Push(root);
while (tree.Count > 0)
{
FrameworkElement current = tree.Pop();
if (current.Name == name)
return current;
int count = VisualTreeHelper.GetChildrenCount(current);
for (int i = 0; i < count; ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(current, i);
if (child is FrameworkElement)
tree.Push((FrameworkElement)child);
}
}
return null;
}
public void SelectNext() public void SelectNext()
{ {
int index = lbResults.SelectedIndex; int index = lbResults.SelectedIndex;