From a942882c7374f5e38abb390872336c1804c737ed Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Mon, 9 Feb 2015 19:16:13 +0800 Subject: [PATCH] Add QueryHistory to Wox (Ctrl+Up and Ctrl+Down) --- .../Wox.Plugin.QueryHistory/QueryHistory.cs | 2 - Wox.CrashReporter/ReportWindow.xaml.cs | 19 ++- Wox.Plugin/IPublicAPI.cs | 12 +- Wox.sln | 7 - Wox/App.config | 4 - Wox/Images/history.png | Bin 0 -> 4219 bytes Wox/MainWindow.xaml.cs | 115 ++++++++++------ Wox/Properties/AssemblyInfo.cs | 2 +- Wox/ResultPanel.xaml | 2 +- Wox/ResultPanel.xaml.cs | 35 +++-- Wox/Storage/QueryHistoryStorage.cs | 126 ++++++++++++++++++ Wox/Wox.csproj | 2 + 12 files changed, 232 insertions(+), 94 deletions(-) create mode 100644 Wox/Images/history.png create mode 100644 Wox/Storage/QueryHistoryStorage.cs diff --git a/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs b/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs index 7f74a9e0bd..838e08bfe1 100644 --- a/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs +++ b/Plugins/Wox.Plugin.QueryHistory/QueryHistory.cs @@ -34,8 +34,6 @@ namespace Wox.Plugin.QueryHistory public void Init(PluginInitContext context) { this.context = context; - context.API.AfterWoxQueryEvent += API_AfterWoxQueryEvent; - context.API.BeforeWoxQueryEvent += API_BeforeWoxQueryEvent; } void API_BeforeWoxQueryEvent(WoxQueryEventArgs e) diff --git a/Wox.CrashReporter/ReportWindow.xaml.cs b/Wox.CrashReporter/ReportWindow.xaml.cs index c5a7d1a577..67c8b1d1a0 100644 --- a/Wox.CrashReporter/ReportWindow.xaml.cs +++ b/Wox.CrashReporter/ReportWindow.xaml.cs @@ -55,13 +55,18 @@ namespace Wox.CrashReporter private void SendReport() { - string reproduceSteps = - new TextRange(tbReproduceSteps.Document.ContentStart, tbReproduceSteps.Document.ContentEnd).Text; - exception.ToExceptionless() - .SetUserDescription(reproduceSteps) - .Submit(); - ExceptionlessClient.Current.ProcessQueue(); - Close(); + ThreadPool.QueueUserWorkItem(o => + { + string reproduceSteps = new TextRange(tbReproduceSteps.Document.ContentStart, tbReproduceSteps.Document.ContentEnd).Text; + exception.ToExceptionless() + .SetUserDescription(reproduceSteps) + .Submit(); + ExceptionlessClient.Current.ProcessQueue(); + Dispatcher.Invoke(new Action(() => + { + Close(); + })); + }); } private void btnCancel_Click(object sender, RoutedEventArgs e) diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs index 3b2691177e..7928440adf 100644 --- a/Wox.Plugin/IPublicAPI.cs +++ b/Wox.Plugin/IPublicAPI.cs @@ -46,7 +46,7 @@ namespace Wox.Plugin /// Just change the query text, this won't raise search /// /// - void ChangeQueryText(string query); + void ChangeQueryText(string query, bool selectAll = false); /// /// Close Wox @@ -122,16 +122,6 @@ namespace Wox.Plugin /// event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; - /// - /// Fired after wox execute a query - /// - event AfterWoxQueryEventHandler AfterWoxQueryEvent; - - /// - /// Fired before wox start to execute a query - /// - event AfterWoxQueryEventHandler BeforeWoxQueryEvent; - /// /// Fired after drop to result item of current plugin /// diff --git a/Wox.sln b/Wox.sln index 1759a11e0a..07ab868b2d 100644 --- a/Wox.sln +++ b/Wox.sln @@ -39,8 +39,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Color", "Plugins EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.CrashReporter", "Wox.CrashReporter\Wox.CrashReporter.csproj", "{2FEB2298-7653-4009-B1EA-FFFB1A768BCC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.QueryHistory", "Plugins\Wox.Plugin.QueryHistory\Wox.Plugin.QueryHistory.csproj", "{B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UpdateFeedGenerator", "Wox.UpdateFeedGenerator\Wox.UpdateFeedGenerator.csproj", "{D120E62B-EC59-4FB4-8129-EFDD4C446A5F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Everything", "Plugins\Wox.Plugin.Everything\Wox.Plugin.Everything.csproj", "{230AE83F-E92E-4E69-8355-426B305DA9C0}" @@ -119,10 +117,6 @@ Global {2FEB2298-7653-4009-B1EA-FFFB1A768BCC}.Debug|Any CPU.Build.0 = Debug|Any CPU {2FEB2298-7653-4009-B1EA-FFFB1A768BCC}.Release|Any CPU.ActiveCfg = Release|Any CPU {2FEB2298-7653-4009-B1EA-FFFB1A768BCC}.Release|Any CPU.Build.0 = Release|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0}.Release|Any CPU.Build.0 = Release|Any CPU {D120E62B-EC59-4FB4-8129-EFDD4C446A5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D120E62B-EC59-4FB4-8129-EFDD4C446A5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D120E62B-EC59-4FB4-8129-EFDD4C446A5F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -147,7 +141,6 @@ Global {0B9DE348-9361-4940-ADB6-F5953BFFCCEC} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {A3DCCBCA-ACC1-421D-B16E-210896234C26} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {F35190AA-4758-4D9E-A193-E3BDF6AD3567} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} - {B552DCB6-692E-4B1D-9E0B-9096A2A7E6B0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {230AE83F-E92E-4E69-8355-426B305DA9C0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} EndGlobalSection EndGlobal diff --git a/Wox/App.config b/Wox/App.config index ab8b3cde5f..55ab1e0d9d 100644 --- a/Wox/App.config +++ b/Wox/App.config @@ -1,8 +1,5 @@ - -
- @@ -12,5 +9,4 @@ - \ No newline at end of file diff --git a/Wox/Images/history.png b/Wox/Images/history.png new file mode 100644 index 0000000000000000000000000000000000000000..6bb070398fdac483d4a9a5d6ce14440334efd927 GIT binary patch literal 4219 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 { ignoreTextChange = true; tbQuery.Text = query; tbQuery.CaretIndex = tbQuery.Text.Length; + if (selectAll) + { + tbQuery.SelectAll(); + } })); } @@ -144,8 +148,6 @@ namespace Wox public event WoxKeyDownEventHandler BackKeyDownEvent; public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; - public event AfterWoxQueryEventHandler AfterWoxQueryEvent; - public event AfterWoxQueryEventHandler BeforeWoxQueryEvent; public event ResultItemDropEventHandler ResultItemDropEvent; public void PushResults(Query query, PluginMetadata plugin, List results) @@ -433,7 +435,6 @@ namespace Wox queryHasReturn = false; Query query = new Query(lastQuery); query.IsIntantQuery = searchDelay == 0; - FireBeforeWoxQueryEvent(query); Query(query); Dispatcher.DelayInvoke("ShowProgressbar", originQuery => { @@ -442,10 +443,15 @@ namespace Wox StartProgress(); } }, TimeSpan.FromMilliseconds(150), tbQuery.Text); - FireAfterWoxQueryEvent(query); + //reset query history index after user start new query + ResetQueryHistoryIndex(); }, TimeSpan.FromMilliseconds(searchDelay)); } + private void ResetQueryHistoryIndex() + { + QueryHistoryStorage.Instance.Reset(); + } private int GetSearchDelay(string query) { if (!string.IsNullOrEmpty(query) && PluginManager.IsInstantQuery(query)) @@ -458,38 +464,6 @@ namespace Wox return 200; } - private void FireAfterWoxQueryEvent(Query q) - { - if (AfterWoxQueryEvent != null) - { - //We shouldn't let those events slow down real query - //so I put it in the new thread - ThreadPool.QueueUserWorkItem(o => - { - AfterWoxQueryEvent(new WoxQueryEventArgs() - { - Query = q - }); - }); - } - } - - private void FireBeforeWoxQueryEvent(Query q) - { - if (BeforeWoxQueryEvent != null) - { - //We shouldn't let those events slow down real query - //so I put it in the new thread - ThreadPool.QueueUserWorkItem(o => - { - BeforeWoxQueryEvent(new WoxQueryEventArgs() - { - Query = q - }); - }); - } - } - private void Query(Query q) { PluginManager.Query(q); @@ -544,6 +518,7 @@ namespace Wox Activate(); Focus(); tbQuery.Focus(); + ResetQueryHistoryIndex(); if (selectAll) tbQuery.SelectAll(); } @@ -616,12 +591,26 @@ namespace Wox break; case Key.Down: - SelectNextItem(); + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + DisplayNextQuery(); + } + else + { + SelectNextItem(); + } e.Handled = true; break; case Key.Up: - SelectPrevItem(); + if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + { + DisplayPrevQuery(); + } + else + { + SelectPrevItem(); + } e.Handled = true; break; @@ -703,6 +692,40 @@ namespace Wox } } + private void DisplayPrevQuery() + { + var prev = QueryHistoryStorage.Instance.Previous(); + DisplayQueryHistory(prev); + } + + private void DisplayNextQuery() + { + var nextQuery = QueryHistoryStorage.Instance.Next(); + DisplayQueryHistory(nextQuery); + } + + private void DisplayQueryHistory(HistoryItem history) + { + if (history != null) + { + ChangeQueryText(history.Query, true); + pnlResult.Dirty = true; + UpdateResultViewInternal(new List() + { + new Result(){ + Title = "Execute " + history.Query+ " query", + SubTitle = "Last Execute Time: " + history.ExecutedDateTime, + IcoPath = "Images\\history.png", + PluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Action = _ =>{ + ChangeQuery(history.Query,true); + return false; + } + } + }); + } + } + private void SelectItem(int index) { int zeroBasedIndex = index - 1; @@ -775,6 +798,7 @@ namespace Wox HideWox(); } UserSelectedRecordStorage.Instance.Add(result); + QueryHistoryStorage.Instance.Add(tbQuery.Text); } } } @@ -792,13 +816,18 @@ namespace Wox o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; }); List l = list.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); - Dispatcher.Invoke(new Action(() => - { - pnlResult.AddResults(l); - })); + UpdateResultViewInternal(l); } } + private void UpdateResultViewInternal(List list) + { + Dispatcher.Invoke(new Action(() => + { + pnlResult.AddResults(list); + })); + } + private Result GetTopMostContextMenu(Result result) { if (TopMostRecordStorage.Instance.IsTopMost(result)) diff --git a/Wox/Properties/AssemblyInfo.cs b/Wox/Properties/AssemblyInfo.cs index cfddac76a7..b4d5aea913 100644 --- a/Wox/Properties/AssemblyInfo.cs +++ b/Wox/Properties/AssemblyInfo.cs @@ -20,4 +20,4 @@ using System.Windows; )] [assembly: AssemblyVersion("1.1.0")] [assembly: AssemblyFileVersion("1.1.0")] -[assembly: Exceptionless.Configuration.Exceptionless("13462a93b5e843c7bae7da13a86bc00b", EnableLogging = true, LogPath = "E:\\exceptionless.log")] \ No newline at end of file +[assembly: Exceptionless.Configuration.Exceptionless("e0b256fbe9384498ba89aae2a6b7f8ab")] \ No newline at end of file diff --git a/Wox/ResultPanel.xaml b/Wox/ResultPanel.xaml index f221205206..26b18f4f1a 100644 --- a/Wox/ResultPanel.xaml +++ b/Wox/ResultPanel.xaml @@ -24,7 +24,7 @@ - + diff --git a/Wox/ResultPanel.xaml.cs b/Wox/ResultPanel.xaml.cs index c52367f69c..21251bb010 100644 --- a/Wox/ResultPanel.xaml.cs +++ b/Wox/ResultPanel.xaml.cs @@ -145,26 +145,25 @@ namespace Wox private void UpdateItemNumber() { - VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); - int index = 0; - for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) - { - index++; - ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; - if (item != null) - { - ContentPresenter myContentPresenter = FindVisualChild(item); - if (myContentPresenter != null) - { - DataTemplate dataTemplate = myContentPresenter.ContentTemplate; - TextBlock tbItemNumber = (TextBlock)dataTemplate.FindName("tbItemNumber", myContentPresenter); - tbItemNumber.Text = index.ToString(); - } - } - } + //VirtualizingStackPanel virtualizingStackPanel = GetInnerStackPanel(lbResults); + //int index = 0; + //for (int i = (int)virtualizingStackPanel.VerticalOffset; i <= virtualizingStackPanel.VerticalOffset + virtualizingStackPanel.ViewportHeight; i++) + //{ + // index++; + // ListBoxItem item = lbResults.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; + // if (item != null) + // { + // ContentPresenter myContentPresenter = FindVisualChild(item); + // if (myContentPresenter != null) + // { + // DataTemplate dataTemplate = myContentPresenter.ContentTemplate; + // TextBlock tbItemNumber = (TextBlock)dataTemplate.FindName("tbItemNumber", myContentPresenter); + // tbItemNumber.Text = index.ToString(); + // } + // } + //} } - private childItem FindVisualChild(DependencyObject obj) where childItem : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) diff --git a/Wox/Storage/QueryHistoryStorage.cs b/Wox/Storage/QueryHistoryStorage.cs new file mode 100644 index 0000000000..d39ebaad14 --- /dev/null +++ b/Wox/Storage/QueryHistoryStorage.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Newtonsoft.Json; +using Wox.Infrastructure.Storage; + +namespace Wox.Storage +{ + public class QueryHistoryStorage : JsonStrorage + { + [JsonProperty] + private List History = new List(); + + private int MaxHistory = 300; + private int cursor = 0; + + protected override string ConfigFolder + { + get { return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Config"); } + } + + protected override string ConfigName + { + get { return "QueryHistory"; } + } + + public HistoryItem Previous() + { + if (History.Count == 0 || cursor == 0) return null; + return History[--cursor]; + } + + public HistoryItem Next() + { + if (History.Count == 0 || cursor >= History.Count - 1) return null; + return History[++cursor]; + } + + public void Reset() + { + cursor = History.Count; + } + + public void Add(string query) + { + if (string.IsNullOrEmpty(query)) return; + if (History.Count > MaxHistory) + { + History.RemoveAt(0); + } + + if (History.Count > 0 && History.Last().Query == query) + { + History.Last().ExecutedDateTime = DateTime.Now; + } + else + { + History.Add(new HistoryItem() + { + Query = query, + ExecutedDateTime = DateTime.Now + }); + } + + if (History.Count % 5 == 0) + { + Save(); + } + + Reset(); + } + + public List GetHistory() + { + return History.OrderByDescending(o => o.ExecutedDateTime).ToList(); + } + } + + public class HistoryItem + { + public string Query { get; set; } + public DateTime ExecutedDateTime { get; set; } + + public string GetTimeAgo() + { + return DateTimeAgo(ExecutedDateTime); + } + + private string DateTimeAgo(DateTime dt) + { + TimeSpan span = DateTime.Now - dt; + if (span.Days > 365) + { + int years = (span.Days / 365); + if (span.Days % 365 != 0) + years += 1; + return String.Format("about {0} {1} ago", + years, years == 1 ? "year" : "years"); + } + if (span.Days > 30) + { + int months = (span.Days / 30); + if (span.Days % 31 != 0) + months += 1; + return String.Format("about {0} {1} ago", + months, months == 1 ? "month" : "months"); + } + if (span.Days > 0) + return String.Format("about {0} {1} ago", + span.Days, span.Days == 1 ? "day" : "days"); + if (span.Hours > 0) + return String.Format("about {0} {1} ago", + span.Hours, span.Hours == 1 ? "hour" : "hours"); + if (span.Minutes > 0) + return String.Format("about {0} {1} ago", + span.Minutes, span.Minutes == 1 ? "minute" : "minutes"); + if (span.Seconds > 5) + return String.Format("about {0} seconds ago", span.Seconds); + if (span.Seconds <= 5) + return "just now"; + return string.Empty; + } + } +} diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index 0a3a843e2e..5795de7ba8 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -123,6 +123,7 @@ + @@ -194,6 +195,7 @@ PreserveNewest + Designer MSBuild:Compile