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);
string browser = GetDefaultBrowserPath();
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.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using WindowsInput;
using WindowsInput.Native;
using Newtonsoft.Json;
namespace Wox.Plugin.DotnetPluginTest
namespace Wox.Plugin.Clipboard
{
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)
{
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)
{
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>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Wox.Plugin.DotnetPluginTest</RootNamespace>
<AssemblyName>Wox.Plugin.DotnetPluginTest</AssemblyName>
<RootNamespace>Wox.Plugin.Clipboard</RootNamespace>
<AssemblyName>Wox.Plugin.Clipboard</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
@@ -38,12 +38,17 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsInput">
<HintPath>..\..\packages\InputSimulator.1.0.4.0\lib\net20\WindowsInput.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ClipboardMonitor.cs" />
<Compile Include="Main.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@@ -59,9 +64,13 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="Images\clipboard.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<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>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

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

View File

@@ -1,8 +1,8 @@
[plugin]
ActionKeyword = ts
Name = dotnet test
ActionKeyword = cb
Name = clipboard monitor
Author = qianlifeng
Version = 0.1
Language = csharp
Description = test
ExecuteFile = Wox.Plugin.DotnetPluginTest.dll
Description = clipboard monitor
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);
}
return true;
};
results.Add(r);
}

View File

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

View File

@@ -69,7 +69,8 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<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>
<!-- 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.

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,7 +18,11 @@ namespace Wox.Plugin.System
Title = "Wox Setting Dialog",
Score = 100,
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",
Score = 100,
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
{
@@ -63,7 +67,11 @@ namespace Wox.Plugin.System
SubTitle = "Lock this computer",
Score = 20,
IcoPath = "Images\\lock.png",
Action = (c) => LockWorkStation()
Action = (c) =>
{
LockWorkStation();
return true;
}
});
availableResults.Add(new Result
{
@@ -71,7 +79,11 @@ namespace Wox.Plugin.System
SubTitle = "Close this app",
Score = 110,
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),
Score = 50,
IcoPath = "Images/work.png",
Action = (c) => changeQuery(metadataCopy.ActionKeyword + " "),
DontHideWoxAfterSelect = true
Action = (c) =>
{
changeQuery(metadataCopy.ActionKeyword + " ");
return false;
},
};
results.Add(result);
}
@@ -40,8 +43,11 @@ namespace Wox.Plugin.System
SubTitle = string.Format("Activate {0} web search", n.ActionWord),
Score = 50,
IcoPath = "Images/work.png",
Action = (c) => changeQuery(n.ActionWord + " "),
DontHideWoxAfterSelect = true
Action = (c) =>
{
changeQuery(n.ActionWord + " ");
return false;
}
}));
return results;

View File

@@ -26,7 +26,11 @@ namespace Wox.Plugin.System
{
Title = string.Format("Search {0} for \"{1}\"", webSearch.Title, keyword),
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<string,string,string> ShowMsg { 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;
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
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 SubTitle { 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>
/// Auto add scores for MRU items

View File

@@ -13,7 +13,6 @@ namespace Wox.Test
public void QueryActionTest()
{
Query q = new Query("this");
Assert.AreEqual(q.ActionName,"this");
q = new Query("ev file.txt");
Assert.AreEqual(q.ActionName,"ev");
@@ -24,6 +23,9 @@ namespace Wox.Test
Assert.AreEqual(q.ActionName,"ev");
Assert.AreEqual(q.ActionParameters.Count,2);
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
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC.csproj", "{C9BC17A0-C2BC-4185-AC1F-32E3352C1233}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.DotnetPluginTest", "Plugins\Wox.Plugin.DotnetPluginTest\Wox.Plugin.DotnetPluginTest.csproj", "{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Clipboard", "Plugins\Wox.Plugin.DotnetPluginTest\Wox.Plugin.Clipboard.csproj", "{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

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

View File

@@ -42,7 +42,10 @@ namespace Wox
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;
}

View File

@@ -18,7 +18,7 @@
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</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>
<wox:ResultPanel x:Name="resultCtrl" Grid.Row="2"/>
</Grid>

View File

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

View File

@@ -35,7 +35,8 @@ namespace Wox.PluginLoader
HideApp = App.Window.HideApp,
ShowApp = () => App.Window.ShowApp(),
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;
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);
}

View File

@@ -40,7 +40,7 @@
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto" x:Name="SubTitleRowDefinition"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Style="{DynamicResource ItemTitleStyle}" VerticalAlignment="Center" x:Name="tbTitle" Text="{Binding Title}"></TextBlock>
<TextBlock Style="{DynamicResource 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>
</Grid>
</Grid>

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Wox.Helper;
using Wox.Infrastructure;
using Wox.Plugin;
@@ -58,6 +59,29 @@ namespace Wox
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()
{
int index = lbResults.SelectedIndex;