diff --git a/Wox/MainWindow.xaml b/Wox/MainWindow.xaml
index 575eb9616b..3412cd0ac3 100644
--- a/Wox/MainWindow.xaml
+++ b/Wox/MainWindow.xaml
@@ -36,6 +36,7 @@
+
@@ -77,6 +78,9 @@
+
+
+
\ No newline at end of file
diff --git a/Wox/Storage/HistoryItem.cs b/Wox/Storage/HistoryItem.cs
new file mode 100644
index 0000000000..084fa2882e
--- /dev/null
+++ b/Wox/Storage/HistoryItem.cs
@@ -0,0 +1,45 @@
+using System;
+
+namespace Wox.Storage
+{
+ public class HistoryItem
+ {
+ public string Query { get; set; }
+ public DateTime ExecutedDateTime { get; set; }
+
+ public string GetTimeAgo()
+ {
+ return DateTimeAgo(ExecutedDateTime);
+ }
+
+ private string DateTimeAgo(DateTime dt)
+ {
+ var span = DateTime.Now - dt;
+ if (span.Days > 365)
+ {
+ int years = (span.Days / 365);
+ if (span.Days % 365 != 0)
+ years += 1;
+ return $"about {years} {(years == 1 ? "year" : "years")} ago";
+ }
+ if (span.Days > 30)
+ {
+ int months = (span.Days / 30);
+ if (span.Days % 31 != 0)
+ months += 1;
+ return $"about {months} {(months == 1 ? "month" : "months")} ago";
+ }
+ if (span.Days > 0)
+ return $"about {span.Days} {(span.Days == 1 ? "day" : "days")} ago";
+ if (span.Hours > 0)
+ return $"about {span.Hours} {(span.Hours == 1 ? "hour" : "hours")} ago";
+ if (span.Minutes > 0)
+ return $"about {span.Minutes} {(span.Minutes == 1 ? "minute" : "minutes")} ago";
+ if (span.Seconds > 5)
+ return $"about {span.Seconds} seconds ago";
+ if (span.Seconds <= 5)
+ return "just now";
+ return string.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Wox/Storage/QueryHistory.cs b/Wox/Storage/QueryHistory.cs
index d66113fe7f..fc3f5250b6 100644
--- a/Wox/Storage/QueryHistory.cs
+++ b/Wox/Storage/QueryHistory.cs
@@ -2,111 +2,36 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
-using Wox.Infrastructure.Storage;
using Wox.Plugin;
namespace Wox.Storage
{
- public class QueryHistory
+ public class History
{
- public List History = new List();
+ public List Items { get; set; } = new List();
- private int MaxHistory = 300;
- private int cursor;
-
- public static PluginMetadata MetaData { get; } = new PluginMetadata
- { ID = "Query history", Name = "Query history" };
-
- 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;
- }
+ private int _maxHistory = 300;
public void Add(string query)
{
if (string.IsNullOrEmpty(query)) return;
- if (History.Count > MaxHistory)
+ if (Items.Count > _maxHistory)
{
- History.RemoveAt(0);
+ Items.RemoveAt(0);
}
- if (History.Count > 0 && History.Last().Query == query)
+ if (Items.Count > 0 && Items.Last().Query == query)
{
- History.Last().ExecutedDateTime = DateTime.Now;
+ Items.Last().ExecutedDateTime = DateTime.Now;
}
else
{
- History.Add(new HistoryItem
+ Items.Add(new HistoryItem
{
Query = query,
ExecutedDateTime = DateTime.Now
});
}
-
- 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/ViewModel/MainViewModel.cs b/Wox/ViewModel/MainViewModel.cs
index 530e66972e..d5fa307f69 100644
--- a/Wox/ViewModel/MainViewModel.cs
+++ b/Wox/ViewModel/MainViewModel.cs
@@ -27,14 +27,13 @@ namespace Wox.ViewModel
private bool _queryHasReturn;
private Query _lastQuery;
- private string _queryTextBeforeLoadContextMenu;
- private string _queryText;
+ private string _queryTextBeforeLeaveResults;
- private readonly JsonStrorage _queryHistoryStorage;
+ private readonly JsonStrorage _historyItemsStorage;
private readonly JsonStrorage _userSelectedRecordStorage;
private readonly JsonStrorage _topMostRecordStorage;
private readonly Settings _settings;
- private readonly QueryHistory _queryHistory;
+ private readonly History _history;
private readonly UserSelectedRecord _userSelectedRecord;
private readonly TopMostRecord _topMostRecord;
@@ -42,6 +41,8 @@ namespace Wox.ViewModel
private CancellationToken _updateToken;
private bool _saved;
+ private Internationalization _translator = InternationalizationManager.Instance;
+
#endregion
#region Constructor
@@ -49,21 +50,22 @@ namespace Wox.ViewModel
public MainViewModel(Settings settings)
{
_saved = false;
- _queryTextBeforeLoadContextMenu = "";
+ _queryTextBeforeLeaveResults = "";
_queryText = "";
_lastQuery = new Query();
_settings = settings;
- _queryHistoryStorage = new JsonStrorage();
+ _historyItemsStorage = new JsonStrorage();
_userSelectedRecordStorage = new JsonStrorage();
_topMostRecordStorage = new JsonStrorage();
- _queryHistory = _queryHistoryStorage.Load();
+ _history = _historyItemsStorage.Load();
_userSelectedRecord = _userSelectedRecordStorage.Load();
_topMostRecord = _topMostRecordStorage.Load();
ContextMenu = new ResultsViewModel(_settings);
Results = new ResultsViewModel(_settings);
+ History = new ResultsViewModel(_settings);
_selectedResults = Results;
InitializeKeyCommands();
@@ -82,7 +84,6 @@ namespace Wox.ViewModel
{
Task.Run(() =>
{
-
PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query);
UpdateResultView(e.Results, pair.Metadata, e.Query);
}, _updateToken);
@@ -115,21 +116,6 @@ namespace Wox.ViewModel
SelectedResults.SelectPrevResult();
});
-
- /**
- DisplayNextQueryCommand = new RelayCommand(_ =>
- {
- var nextQuery = _queryHistory.Next();
- DisplayQueryHistory(nextQuery);
- });
-
- DisplayPrevQueryCommand = new RelayCommand(_ =>
- {
- var prev = _queryHistory.Previous();
- DisplayQueryHistory(prev);
- });
- **/
-
SelectNextPageCommand = new RelayCommand(_ =>
{
SelectedResults.SelectNextPage();
@@ -170,7 +156,7 @@ namespace Wox.ViewModel
if (ResultsSelected())
{
_userSelectedRecord.Add(result);
- _queryHistory.Add(result.OriginQuery.RawQuery);
+ _history.Add(result.OriginQuery.RawQuery);
}
}
});
@@ -187,6 +173,18 @@ namespace Wox.ViewModel
}
});
+ LoadHistoryCommand = new RelayCommand(_ =>
+ {
+ if (ResultsSelected())
+ {
+ SelectedResults = History;
+ History.SelectedIndex = _history.Items.Count - 1;
+ }
+ else
+ {
+ SelectedResults = Results;
+ }
+ });
}
#endregion
@@ -194,38 +192,22 @@ namespace Wox.ViewModel
#region ViewModel Properties
public ResultsViewModel Results { get; private set; }
-
public ResultsViewModel ContextMenu { get; private set; }
+ public ResultsViewModel History { get; private set; }
+ private string _queryText;
public string QueryText
{
get { return _queryText; }
set
{
_queryText = value;
- ProgressBarVisibility = Visibility.Hidden;
-
- _updateSource?.Cancel();
- _updateSource = new CancellationTokenSource();
- _updateToken = _updateSource.Token;
-
- if (ResultsSelected())
- {
- QueryResults();
- }
- else
- {
- QueryContextMenu();
- }
+ Query();
}
}
-
-
-
public bool QueryTextSelected { get; set; }
private ResultsViewModel _selectedResults;
-
private ResultsViewModel SelectedResults
{
get { return _selectedResults; }
@@ -234,14 +216,28 @@ namespace Wox.ViewModel
_selectedResults = value;
if (ResultsSelected())
{
- QueryText = _queryTextBeforeLoadContextMenu;
ContextMenu.Visbility = Visibility.Collapsed;
+ History.Visbility = Visibility.Collapsed;
+ QueryText = _queryTextBeforeLeaveResults;
}
else
{
- _queryTextBeforeLoadContextMenu = QueryText;
- QueryText = "";
Results.Visbility = Visibility.Collapsed;
+ _queryTextBeforeLeaveResults = QueryText;
+
+
+ // Because of Fody's optimization
+ // setter won't be called when property value is not changed.
+ // so we need manually call Query()
+ // http://stackoverflow.com/posts/25895769/revisions
+ if (string.IsNullOrEmpty(QueryText))
+ {
+ Query();
+ }
+ else
+ {
+ QueryText = string.Empty;
+ }
}
_selectedResults.Visbility = Visibility.Visible;
}
@@ -254,22 +250,34 @@ namespace Wox.ViewModel
public ICommand EscCommand { get; set; }
public ICommand SelectNextItemCommand { get; set; }
public ICommand SelectPrevItemCommand { get; set; }
- //todo happlebao restore history command
- public ICommand DisplayNextQueryCommand { get; set; }
- public ICommand DisplayPrevQueryCommand { get; set; }
public ICommand SelectNextPageCommand { get; set; }
public ICommand SelectPrevPageCommand { get; set; }
public ICommand StartHelpCommand { get; set; }
public ICommand LoadContextMenuCommand { get; set; }
+ public ICommand LoadHistoryCommand { get; set; }
public ICommand OpenResultCommand { get; set; }
#endregion
- #region Private Methods
+ public void Query()
+ {
+ if (ResultsSelected())
+ {
+ QueryResults();
+ }
+ else if (ContextMenuSelected())
+ {
+ QueryContextMenu();
+ }
+ else if (HistorySelected())
+ {
+ QueryHistory();
+ }
+ }
private void QueryContextMenu()
{
- const string contextMenuId = "Context Menu Id";
+ const string id = "Context Menu ID";
var query = QueryText.ToLower().Trim();
ContextMenu.Clear();
@@ -277,11 +285,9 @@ namespace Wox.ViewModel
if (selected != null) // SelectedItem returns null if selection is empty.
{
- var id = selected.PluginID;
-
var results = PluginManager.GetContextMenusForPlugin(selected);
results.Add(ContextMenuTopMost(selected));
- results.Add(ContextMenuPluginInfo(id));
+ results.Add(ContextMenuPluginInfo(selected.PluginID));
if (!string.IsNullOrEmpty(query))
{
@@ -290,22 +296,116 @@ namespace Wox.ViewModel
r => StringMatcher.IsMatch(r.Title, query) ||
StringMatcher.IsMatch(r.SubTitle, query)
).ToList();
- ContextMenu.AddResults(filtered, contextMenuId);
+ ContextMenu.AddResults(filtered, id);
}
else
{
- ContextMenu.AddResults(results, contextMenuId);
+ ContextMenu.AddResults(results, id);
}
}
}
+ private void QueryHistory()
+ {
+ const string id = "Query History ID";
+ var query = QueryText.ToLower().Trim();
+ History.Clear();
+
+ var results = new List();
+ foreach (var h in _history.Items)
+ {
+ var title = _translator.GetTranslation("executeQuery");
+ var time = _translator.GetTranslation("lastExecuteTime");
+ var result = new Result
+ {
+ Title = string.Format(title, h.Query),
+ SubTitle = string.Format(time, h.ExecutedDateTime),
+ IcoPath = "Images\\history.png",
+ OriginQuery = new Query { RawQuery = h.Query },
+ Action = _ =>
+ {
+ SelectedResults = Results;
+ QueryText = h.Query;
+ return false;
+ }
+ };
+ results.Add(result);
+ }
+
+ if (!string.IsNullOrEmpty(query))
+ {
+ var filtered = results.Where
+ (
+ r => StringMatcher.IsMatch(r.Title, query) ||
+ StringMatcher.IsMatch(r.SubTitle, query)
+ ).ToList();
+ History.AddResults(filtered, id);
+ }
+ else
+ {
+ History.AddResults(results, id);
+ }
+ }
+
private void QueryResults()
{
if (!string.IsNullOrEmpty(QueryText))
{
- Query(QueryText.Trim());
- //reset query history index after user start new query
- ResetQueryHistoryIndex();
+ _updateSource?.Cancel();
+ _updateSource = new CancellationTokenSource();
+ _updateToken = _updateSource.Token;
+
+ ProgressBarVisibility = Visibility.Hidden;
+ _queryHasReturn = false;
+ var query = PluginManager.QueryInit(QueryText.Trim());
+ if (query != null)
+ {
+ // handle the exclusiveness of plugin using action keyword
+ string lastKeyword = _lastQuery.ActionKeyword;
+ string keyword = query.ActionKeyword;
+ if (string.IsNullOrEmpty(lastKeyword))
+ {
+ if (!string.IsNullOrEmpty(keyword))
+ {
+ Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
+ }
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(keyword))
+ {
+ Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata);
+ }
+ else if (lastKeyword != keyword)
+ {
+ Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
+ }
+ }
+
+ _lastQuery = query;
+ Task.Delay(200, _updateToken).ContinueWith(_ =>
+ {
+ if (query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn)
+ {
+ ProgressBarVisibility = Visibility.Visible;
+ }
+ }, _updateToken);
+
+ var plugins = PluginManager.ValidPluginsForQuery(query);
+ Task.Run(() =>
+ {
+ Parallel.ForEach(plugins, plugin =>
+ {
+ var config = _settings.PluginSettings.Plugins[plugin.Metadata.ID];
+ if (!config.Disabled)
+ {
+
+ var results = PluginManager.QueryForPlugin(plugin, query);
+ UpdateResultView(results, plugin.Metadata, query);
+ }
+ });
+ }, _updateToken);
+ }
}
else
{
@@ -314,98 +414,6 @@ namespace Wox.ViewModel
}
}
- private void Query(string text)
- {
- _queryHasReturn = false;
- var query = PluginManager.QueryInit(text);
- if (query != null)
- {
- // handle the exclusiveness of plugin using action keyword
- string lastKeyword = _lastQuery.ActionKeyword;
- string keyword = query.ActionKeyword;
- if (string.IsNullOrEmpty(lastKeyword))
- {
- if (!string.IsNullOrEmpty(keyword))
- {
- Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
- }
- }
- else
- {
- if (string.IsNullOrEmpty(keyword))
- {
- Results.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata);
- }
- else if (lastKeyword != keyword)
- {
- Results.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata);
- }
- }
-
- _lastQuery = query;
- Task.Delay(200, _updateToken).ContinueWith(_ =>
- {
- if (query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn)
- {
- ProgressBarVisibility = Visibility.Visible;
- }
- }, _updateToken);
-
- var plugins = PluginManager.ValidPluginsForQuery(query);
- Task.Run(() =>
- {
- Parallel.ForEach(plugins, plugin =>
- {
- var config = _settings.PluginSettings.Plugins[plugin.Metadata.ID];
- if (!config.Disabled)
- {
-
- var results = PluginManager.QueryForPlugin(plugin, query);
- UpdateResultView(results, plugin.Metadata, query);
- }
- });
- }, _updateToken);
- }
- }
-
- private void ResetQueryHistoryIndex()
- {
- Results.RemoveResultsFor(QueryHistory.MetaData);
- _queryHistory.Reset();
- }
- /**
- private void DisplayQueryHistory(HistoryItem history)
- {
- if (history != null)
- {
- var historyMetadata = QueryHistory.MetaData;
-
- QueryText = history.Query;
- OnTextBoxSelected();
-
- var executeQueryHistoryTitle = InternationalizationManager.Instance.GetTranslation("executeQuery");
- var lastExecuteTime = InternationalizationManager.Instance.GetTranslation("lastExecuteTime");
- Results.RemoveResultsExcept(historyMetadata);
- var result = new Result
- {
- Title = string.Format(executeQueryHistoryTitle, history.Query),
- SubTitle = string.Format(lastExecuteTime, history.ExecutedDateTime),
- IcoPath = "Images\\history.png",
- PluginDirectory = Infrastructure.Constant.ProgramDirectory,
- Action = _ =>
- {
- QueryText = history.Query;
- OnTextBoxSelected();
- return false;
- }
- };
- Task.Run(() =>
- {
- Results.AddResults(new List {result}, historyMetadata.ID);
- }, _updateToken);
- }
- }
- **/
private Result ContextMenuTopMost(Result result)
{
@@ -473,7 +481,18 @@ namespace Wox.ViewModel
return selected;
}
- #endregion
+ private bool ContextMenuSelected()
+ {
+ var selected = SelectedResults == ContextMenu;
+ return selected;
+ }
+
+
+ private bool HistorySelected()
+ {
+ var selected = SelectedResults == History;
+ return selected;
+ }
#region Hotkey
private void SetHotkey(string hotkeyStr, EventHandler action)
@@ -527,8 +546,8 @@ namespace Wox.ViewModel
SetHotkey(hotkey.Hotkey, (s, e) =>
{
if (ShouldIgnoreHotkeys()) return;
- QueryText = hotkey.ActionKeyword;
MainWindowVisibility = Visibility.Visible;
+ QueryText = hotkey.ActionKeyword;
});
}
}
@@ -561,7 +580,7 @@ namespace Wox.ViewModel
{
if (!_saved)
{
- _queryHistoryStorage.Save();
+ _historyItemsStorage.Save();
_userSelectedRecordStorage.Save();
_topMostRecordStorage.Save();
diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj
index fc4207128c..306fa0ec3c 100644
--- a/Wox/Wox.csproj
+++ b/Wox/Wox.csproj
@@ -165,6 +165,7 @@
ResultListBox.xaml
+