From 8621fe2e3cd58bee75b31d040023210c2dada734 Mon Sep 17 00:00:00 2001 From: Colin Liu Date: Thu, 18 Feb 2016 19:30:36 +0800 Subject: [PATCH] Refactor MainWindow with MVVM - Add MVVM structure(BaseViewModel) - Create ViewModel for MainWindow - Refactor MainWindow.xaml to support MVVM - Move PublicAPI implementation from MainViewModel to PublicAPIInstance --- Wox/Converters/VisibilityConverter.cs | 30 + Wox/MainWindow.xaml | 29 +- Wox/MainWindow.xaml.cs | 1010 +++++++------------------ Wox/PublicAPIInstance.cs | 309 ++++++++ Wox/ViewModel/BaseViewModel.cs | 50 ++ Wox/ViewModel/MainViewModel.cs | 449 +++++++++++ less.exe.stackdump | 15 + 7 files changed, 1153 insertions(+), 739 deletions(-) create mode 100644 Wox/Converters/VisibilityConverter.cs create mode 100644 Wox/PublicAPIInstance.cs create mode 100644 Wox/ViewModel/BaseViewModel.cs create mode 100644 Wox/ViewModel/MainViewModel.cs create mode 100644 less.exe.stackdump diff --git a/Wox/Converters/VisibilityConverter.cs b/Wox/Converters/VisibilityConverter.cs new file mode 100644 index 0000000000..46488bde37 --- /dev/null +++ b/Wox/Converters/VisibilityConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace Wox.Converters +{ + class VisibilityConverter : ConvertorBase + { + public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null || value == DependencyProperty.UnsetValue) + { + return null; + } + + return bool.Parse(value.ToString()) ? Visibility.Visible : Visibility.Collapsed; + } + + public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + } + +} diff --git a/Wox/MainWindow.xaml b/Wox/MainWindow.xaml index e4873a677a..2ba87ff018 100644 --- a/Wox/MainWindow.xaml +++ b/Wox/MainWindow.xaml @@ -1,6 +1,7 @@  + + + + + + + + + - - - - + + + + + + + + + + \ No newline at end of file diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index aa802a3ad6..4d5ea4744b 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -34,219 +34,54 @@ using MenuItem = System.Windows.Forms.MenuItem; using MessageBox = System.Windows.MessageBox; using Stopwatch = Wox.Infrastructure.Stopwatch; using ToolTip = System.Windows.Controls.ToolTip; +using Wox.ViewModel; namespace Wox { - public partial class MainWindow : IPublicAPI + public partial class MainWindow { #region Properties private readonly Storyboard progressBarStoryboard = new Storyboard(); private NotifyIcon notifyIcon; - private bool _queryHasReturn; - private Query _lastQuery = new Query(); - private ToolTip toolTip = new ToolTip(); - - private bool _ignoreTextChange; - private List CurrentContextMenus = new List(); - private string textBeforeEnterContextMenuMode; - - #endregion - - #region Public API - - public void ChangeQuery(string query, bool requery = false) - { - Dispatcher.Invoke(() => - { - tbQuery.Text = query; - tbQuery.CaretIndex = tbQuery.Text.Length; - if (requery) - { - TbQuery_OnTextChanged(null, null); - } - }); - } - - public void ChangeQueryText(string query, bool selectAll = false) - { - Dispatcher.Invoke(() => - { - _ignoreTextChange = true; - tbQuery.Text = query; - tbQuery.CaretIndex = tbQuery.Text.Length; - if (selectAll) - { - tbQuery.SelectAll(); - } - }); - } - - public void CloseApp() - { - notifyIcon.Visible = false; - Application.Current.Shutdown(); - } - - public void RestarApp() - { - ProcessStartInfo info = new ProcessStartInfo - { - FileName = Application.ResourceAssembly.Location, - Arguments = SingleInstance.Restart - }; - Process.Start(info); - } - - public void HideApp() - { - Dispatcher.Invoke(HideWox); - } - - public void ShowApp() - { - Dispatcher.Invoke(() => ShowWox()); - } - - public void ShowMsg(string title, string subTitle, string iconPath) - { - Dispatcher.Invoke(() => - { - var m = new Msg { Owner = GetWindow(this) }; - m.Show(title, subTitle, iconPath); - }); - } - - public void OpenSettingDialog(string tabName = "general") - { - Dispatcher.Invoke(() => - { - SettingWindow sw = SingletonWindowOpener.Open(this); - sw.SwitchTo(tabName); - }); - } - - public void StartLoadingBar() - { - Dispatcher.Invoke(StartProgress); - } - - public void StopLoadingBar() - { - Dispatcher.Invoke(StopProgress); - } - - public void InstallPlugin(string path) - { - Dispatcher.Invoke(() => PluginManager.InstallPlugin(path)); - } - - public void ReloadPlugins() - { - Dispatcher.Invoke(() => PluginManager.Init(this)); - } - - public string GetTranslation(string key) - { - return InternationalizationManager.Instance.GetTranslation(key); - } - - public List GetAllPlugins() - { - return PluginManager.AllPlugins.ToList(); - } - - public event WoxKeyDownEventHandler BackKeyDownEvent; - public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; - public event ResultItemDropEventHandler ResultItemDropEvent; - - public void PushResults(Query query, PluginMetadata plugin, List results) - { - results.ForEach(o => - { - o.PluginDirectory = plugin.PluginDirectory; - o.PluginID = plugin.ID; - o.OriginQuery = query; - }); - UpdateResultView(results, plugin, query); - } - - public void ShowContextMenu(PluginMetadata plugin, List results) - { - if (results != null && results.Count > 0) - { - results.ForEach(o => - { - o.PluginDirectory = plugin.PluginDirectory; - o.PluginID = plugin.ID; - o.ContextMenu = null; - }); - pnlContextMenu.Clear(); - pnlContextMenu.AddResults(results, plugin.ID); - pnlContextMenu.Visibility = Visibility.Visible; - pnlResult.Visibility = Visibility.Collapsed; - } - } + + #endregion + public MainWindow() { InitializeComponent(); - ThreadPool.SetMaxThreads(30, 10); - ThreadPool.SetMinThreads(10, 5); - - WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); - GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback; - progressBar.ToolTip = toolTip; - pnlResult.LeftMouseClickEvent += SelectResult; - pnlResult.ItemDropEvent += pnlResult_ItemDropEvent; - pnlContextMenu.LeftMouseClickEvent += SelectResult; - pnlResult.RightMouseClickEvent += pnlResult_RightMouseClickEvent; - Closing += MainWindow_Closing; - - - SetHotkey(UserSettingStorage.Instance.Hotkey, OnHotkey); - SetCustomPluginHotkey(); + InitialTray(); + + //pnlResult.ItemDropEvent += pnlResult_ItemDropEvent; + Closing += MainWindow_Closing; + } - void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject, DragEventArgs args) - { - PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); - if (ResultItemDropEvent != null && pluginPair != null) - { - foreach (var delegateHandler in ResultItemDropEvent.GetInvocationList()) - { - if (delegateHandler.Target == pluginPair.Plugin) - { - delegateHandler.DynamicInvoke(result, dropDataObject, args); - } - } - } - } - - private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) - { - if (GlobalKeyboardEvent != null) - { - return GlobalKeyboardEvent((int)keyevent, vkcode, state); - } - return true; - } - - void pnlResult_RightMouseClickEvent(Result result) - { - ShowContextMenu(result); - } + //void pnlResult_ItemDropEvent(Result result, IDataObject dropDataObject, DragEventArgs args) + //{ + // PluginPair pluginPair = PluginManager.AllPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); + // if (ResultItemDropEvent != null && pluginPair != null) + // { + // foreach (var delegateHandler in ResultItemDropEvent.GetInvocationList()) + // { + // if (delegateHandler.Target == pluginPair.Plugin) + // { + // delegateHandler.DynamicInvoke(result, dropDataObject, args); + // } + // } + // } + //} void MainWindow_Closing(object sender, CancelEventArgs e) { UserSettingStorage.Instance.WindowLeft = Left; UserSettingStorage.Instance.WindowTop = Top; UserSettingStorage.Instance.Save(); - HideWox(); e.Cancel = true; } @@ -304,82 +139,6 @@ namespace Wox }); } - public void SetHotkey(string hotkeyStr, EventHandler action) - { - var hotkey = new HotkeyModel(hotkeyStr); - SetHotkey(hotkey, action); - } - - public void SetHotkey(HotkeyModel hotkey, EventHandler action) - { - string hotkeyStr = hotkey.ToString(); - try - { - HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action); - } - catch (Exception) - { - string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr); - MessageBox.Show(errorMsg); - } - } - - public void RemoveHotkey(string hotkeyStr) - { - if (!string.IsNullOrEmpty(hotkeyStr)) - { - HotkeyManager.Current.Remove(hotkeyStr); - } - } - - /// - /// Checks if Wox should ignore any hotkeys - /// - /// - private bool ShouldIgnoreHotkeys() - { - //double if to omit calling win32 function - if (UserSettingStorage.Instance.IgnoreHotkeysOnFullscreen) - if (WindowIntelopHelper.IsWindowFullscreen()) - return true; - - return false; - } - - private void SetCustomPluginHotkey() - { - if (UserSettingStorage.Instance.CustomPluginHotkeys == null) return; - foreach (CustomPluginHotkey hotkey in UserSettingStorage.Instance.CustomPluginHotkeys) - { - CustomPluginHotkey hotkey1 = hotkey; - SetHotkey(hotkey.Hotkey, delegate - { - if (ShouldIgnoreHotkeys()) return; - ShowApp(); - ChangeQuery(hotkey1.ActionKeyword, true); - }); - } - } - - private void OnHotkey(object sender, HotkeyEventArgs e) - { - if (ShouldIgnoreHotkeys()) return; - ToggleWox(); - e.Handled = true; - } - - public void ToggleWox() - { - if (!IsVisible) - { - ShowWox(); - } - else - { - HideWox(); - } - } - private void InitProgressbarAnimation() { var da = new DoubleAnimation(progressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); @@ -395,119 +154,18 @@ namespace Wox private void InitialTray() { - notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; - notifyIcon.Click += (o, e) => ShowWox(); - var open = new MenuItem(GetTranslation("iconTrayOpen")); - open.Click += (o, e) => ShowWox(); - var setting = new MenuItem(GetTranslation("iconTraySettings")); - setting.Click += (o, e) => OpenSettingDialog(); - var about = new MenuItem(GetTranslation("iconTrayAbout")); - about.Click += (o, e) => OpenSettingDialog("about"); - var exit = new MenuItem(GetTranslation("iconTrayExit")); - exit.Click += (o, e) => CloseApp(); - MenuItem[] childen = { open, setting, about, exit }; - notifyIcon.ContextMenu = new ContextMenu(childen); - } - - private void QueryContextMenu() - { - var contextMenuId = "Context Menu Id"; - pnlContextMenu.Clear(); - var query = tbQuery.Text.ToLower(); - if (string.IsNullOrEmpty(query)) - { - pnlContextMenu.AddResults(CurrentContextMenus, contextMenuId); - } - else - { - List filterResults = new List(); - foreach (Result contextMenu in CurrentContextMenus) - { - if (StringMatcher.IsMatch(contextMenu.Title, query) - || StringMatcher.IsMatch(contextMenu.SubTitle, query)) - { - filterResults.Add(contextMenu); - } - } - pnlContextMenu.AddResults(filterResults, contextMenuId); - } - } - - private void TbQuery_OnTextChanged(object sender, TextChangedEventArgs e) - { - if (_ignoreTextChange) { _ignoreTextChange = false; return; } - - toolTip.IsOpen = false; - if (IsInContextMenuMode) - { - QueryContextMenu(); - return; - } - - string query = tbQuery.Text.Trim(); - if (!string.IsNullOrEmpty(query)) - { - Query(query); - //reset query history index after user start new query - ResetQueryHistoryIndex(); - } - else - { - pnlResult.Clear(); - } - } - - private void ResetQueryHistoryIndex() - { - pnlResult.RemoveResultsFor(QueryHistoryStorage.MetaData); - QueryHistoryStorage.Instance.Reset(); - } - 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)) - { - pnlResult.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata); - } - } - else - { - if (string.IsNullOrEmpty(keyword)) - { - pnlResult.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata); - } - else if (lastKeyword != keyword) - { - pnlResult.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata); - } - } - _lastQuery = query; - Dispatcher.InvokeAsync(async () => - { - await Task.Delay(150); - if (!string.IsNullOrEmpty(query.RawQuery) && query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn) - { - StartProgress(); - } - }); - PluginManager.QueryForAllPlugins(query); - } - StopProgress(); - } - - private void BackToResultMode() - { - ChangeQueryText(textBeforeEnterContextMenuMode); - pnlResult.Visibility = Visibility.Visible; - pnlContextMenu.Visibility = Visibility.Collapsed; + //notifyIcon = new NotifyIcon { Text = "Wox", Icon = Properties.Resources.app, Visible = true }; + //notifyIcon.Click += (o, e) => ShowWox(); + //var open = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTrayOpen")); + //open.Click += (o, e) => ShowWox(); + //var setting = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTraySettings")); + //setting.Click += (o, e) => OpenSettingDialog(); + //var about = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTrayAbout")); + //about.Click += (o, e) => OpenSettingDialog("about"); + //var exit = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTrayExit")); + //exit.Click += (o, e) => CloseApp(); + //MenuItem[] childen = { open, setting, about, exit }; + //notifyIcon.ContextMenu = new ContextMenu(childen); } private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) @@ -515,401 +173,285 @@ namespace Wox if (e.ChangedButton == MouseButton.Left) DragMove(); } - private void StartProgress() - { - progressBar.Visibility = Visibility.Visible; - } - - private void StopProgress() - { - progressBar.Visibility = Visibility.Hidden; - } - - private void HideWox() - { - UserSettingStorage.Instance.WindowLeft = Left; - UserSettingStorage.Instance.WindowTop = Top; - if (IsInContextMenuMode) - { - BackToResultMode(); - } - Hide(); - } - private void ShowWox(bool selectAll = true) { - UserSettingStorage.Instance.IncreaseActivateTimes(); - Left = GetWindowsLeft(); - Top = GetWindowsTop(); + //UserSettingStorage.Instance.IncreaseActivateTimes(); + //Left = GetWindowsLeft(); + //Top = GetWindowsTop(); - Show(); - Activate(); - Focus(); - tbQuery.Focus(); - ResetQueryHistoryIndex(); - if (selectAll) tbQuery.SelectAll(); + //Show(); + //Activate(); + //Focus(); + //tbQuery.Focus(); + //ResetQueryHistoryIndex(); + //if (selectAll) tbQuery.SelectAll(); } private void MainWindow_OnDeactivated(object sender, EventArgs e) { if (UserSettingStorage.Instance.HideWhenDeactive) { - HideWox(); + //TODO:Hide the window when deactivated + //HideWox(); } } - private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) - { - //when alt is pressed, the real key should be e.SystemKey - Key key = (e.Key == Key.System ? e.SystemKey : e.Key); - switch (key) - { - case Key.Escape: - if (IsInContextMenuMode) - { - BackToResultMode(); - } - else - { - HideWox(); - } - e.Handled = true; - break; + //private void TbQuery_OnPreviewKeyDown(object sender, KeyEventArgs e) + //{ + // //when alt is pressed, the real key should be e.SystemKey + // Key key = (e.Key == Key.System ? e.SystemKey : e.Key); + // switch (key) + // { + // case Key.Escape: + // if (IsInContextMenuMode) + // { + // BackToResultMode(); + // } + // else + // { + // HideWox(); + // } + // e.Handled = true; + // break; - case Key.Tab: - if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) - { - SelectPrevItem(); - } - else - { - SelectNextItem(); - } - e.Handled = true; - break; + // case Key.Tab: + // if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) + // { + // SelectPrevItem(); + // } + // else + // { + // SelectNextItem(); + // } + // e.Handled = true; + // break; - case Key.N: - case Key.J: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - SelectNextItem(); - } - break; + // case Key.N: + // case Key.J: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // SelectNextItem(); + // } + // break; - case Key.P: - case Key.K: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - SelectPrevItem(); - } - break; + // case Key.P: + // case Key.K: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // SelectPrevItem(); + // } + // break; - case Key.O: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - if (IsInContextMenuMode) - { - BackToResultMode(); - } - else - { - ShowContextMenu(GetActiveResult()); - } - } - break; + // case Key.O: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // if (IsInContextMenuMode) + // { + // BackToResultMode(); + // } + // else + // { + // ShowContextMenu(GetActiveResult()); + // } + // } + // break; - case Key.Down: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - DisplayNextQuery(); - } - else - { - SelectNextItem(); - } - e.Handled = true; - break; + // case Key.Down: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // DisplayNextQuery(); + // } + // else + // { + // SelectNextItem(); + // } + // e.Handled = true; + // break; - case Key.Up: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - DisplayPrevQuery(); - } - else - { - SelectPrevItem(); - } - e.Handled = true; - break; + // case Key.Up: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // DisplayPrevQuery(); + // } + // else + // { + // SelectPrevItem(); + // } + // e.Handled = true; + // break; - case Key.D: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - pnlResult.SelectNextPage(); - } - break; + // case Key.D: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // pnlResult.SelectNextPage(); + // } + // break; - case Key.PageDown: - pnlResult.SelectNextPage(); - e.Handled = true; - break; + // case Key.PageDown: + // pnlResult.SelectNextPage(); + // e.Handled = true; + // break; - case Key.U: - if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) - { - pnlResult.SelectPrevPage(); - } - break; + // case Key.U: + // if (GlobalHotkey.Instance.CheckModifiers().CtrlPressed) + // { + // pnlResult.SelectPrevPage(); + // } + // break; - case Key.PageUp: - pnlResult.SelectPrevPage(); - e.Handled = true; - break; + // case Key.PageUp: + // pnlResult.SelectPrevPage(); + // e.Handled = true; + // break; - case Key.Back: - if (BackKeyDownEvent != null) - { - BackKeyDownEvent(new WoxKeyDownEventArgs - { - Query = tbQuery.Text, - keyEventArgs = e - }); - } - break; + // case Key.Back: + // if (BackKeyDownEvent != null) + // { + // BackKeyDownEvent(new WoxKeyDownEventArgs + // { + // Query = tbQuery.Text, + // keyEventArgs = e + // }); + // } + // break; - case Key.F1: - Process.Start("http://doc.getwox.com"); - break; + // case Key.F1: + // Process.Start("http://doc.getwox.com"); + // break; - case Key.Enter: - Result activeResult = GetActiveResult(); - if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) - { - ShowContextMenu(activeResult); - } - else - { - SelectResult(activeResult); - } - e.Handled = true; - break; + // case Key.Enter: + // Result activeResult = GetActiveResult(); + // if (GlobalHotkey.Instance.CheckModifiers().ShiftPressed) + // { + // ShowContextMenu(activeResult); + // } + // else + // { + // SelectResult(activeResult); + // } + // e.Handled = true; + // break; - case Key.D1: - SelectItem(1); - break; + // case Key.D1: + // SelectItem(1); + // break; - case Key.D2: - SelectItem(2); - break; + // case Key.D2: + // SelectItem(2); + // break; - case Key.D3: - SelectItem(3); - break; + // case Key.D3: + // SelectItem(3); + // break; - case Key.D4: - SelectItem(4); - break; + // case Key.D4: + // SelectItem(4); + // break; - case Key.D5: - SelectItem(5); - break; - case Key.D6: - SelectItem(6); - break; + // case Key.D5: + // SelectItem(5); + // break; + // case Key.D6: + // SelectItem(6); + // break; - } - } + // } + //} - private void DisplayPrevQuery() - { - var prev = QueryHistoryStorage.Instance.Previous(); - DisplayQueryHistory(prev); - } + //private void DisplayPrevQuery() + //{ + // var prev = QueryHistoryStorage.Instance.Previous(); + // DisplayQueryHistory(prev); + //} - private void DisplayNextQuery() - { - var nextQuery = QueryHistoryStorage.Instance.Next(); - DisplayQueryHistory(nextQuery); - } + //private void DisplayNextQuery() + //{ + // var nextQuery = QueryHistoryStorage.Instance.Next(); + // DisplayQueryHistory(nextQuery); + //} - private void DisplayQueryHistory(HistoryItem history) - { - if (history != null) - { - var historyMetadata = QueryHistoryStorage.MetaData; - ChangeQueryText(history.Query, true); - var executeQueryHistoryTitle = GetTranslation("executeQuery"); - var lastExecuteTime = GetTranslation("lastExecuteTime"); - pnlResult.RemoveResultsExcept(historyMetadata); - UpdateResultViewInternal(new List - { - new Result - { - Title = string.Format(executeQueryHistoryTitle,history.Query), - SubTitle = string.Format(lastExecuteTime,history.ExecutedDateTime), - IcoPath = "Images\\history.png", - PluginDirectory = WoxDirectroy.Executable, - Action = _ =>{ - ChangeQuery(history.Query,true); - return false; - } - } - }, historyMetadata); - } - } + //private void DisplayQueryHistory(HistoryItem history) + //{ + // if (history != null) + // { + // var historyMetadata = QueryHistoryStorage.MetaData; + // ChangeQueryText(history.Query, true); + // var executeQueryHistoryTitle = GetTranslation("executeQuery"); + // var lastExecuteTime = GetTranslation("lastExecuteTime"); + // pnlResult.RemoveResultsExcept(historyMetadata); + // UpdateResultViewInternal(new List + // { + // new Result + // { + // Title = string.Format(executeQueryHistoryTitle,history.Query), + // SubTitle = string.Format(lastExecuteTime,history.ExecutedDateTime), + // IcoPath = "Images\\history.png", + // PluginDirectory = WoxDirectroy.Executable, + // Action = _ =>{ + // ChangeQuery(history.Query,true); + // return false; + // } + // } + // }, historyMetadata); + // } + //} - private void SelectItem(int index) - { - int zeroBasedIndex = index - 1; - SpecialKeyState keyState = GlobalHotkey.Instance.CheckModifiers(); - if (keyState.AltPressed || keyState.CtrlPressed) - { - List visibleResults = pnlResult.GetVisibleResults(); - if (zeroBasedIndex < visibleResults.Count) - { - SelectResult(visibleResults[zeroBasedIndex]); - } - } - } + //private void SelectItem(int index) + //{ + // int zeroBasedIndex = index - 1; + // SpecialKeyState keyState = GlobalHotkey.Instance.CheckModifiers(); + // if (keyState.AltPressed || keyState.CtrlPressed) + // { + // List visibleResults = pnlResult.GetVisibleResults(); + // if (zeroBasedIndex < visibleResults.Count) + // { + // SelectResult(visibleResults[zeroBasedIndex]); + // } + // } + //} - private bool IsInContextMenuMode - { - get { return pnlContextMenu.Visibility == Visibility.Visible; } - } + //private bool IsInContextMenuMode + //{ + // get { return pnlContextMenu.Visibility == Visibility.Visible; } + //} - private Result GetActiveResult() - { - if (IsInContextMenuMode) - { - return pnlContextMenu.GetActiveResult(); - } - else - { - return pnlResult.GetActiveResult(); - } - } + //private Result GetActiveResult() + //{ + // if (IsInContextMenuMode) + // { + // return pnlContextMenu.GetActiveResult(); + // } + // else + // { + // return pnlResult.GetActiveResult(); + // } + //} - private void SelectPrevItem() - { - if (IsInContextMenuMode) - { - pnlContextMenu.SelectPrev(); - } - else - { - pnlResult.SelectPrev(); - } - toolTip.IsOpen = false; - } + //private void SelectPrevItem() + //{ + // if (IsInContextMenuMode) + // { + // pnlContextMenu.SelectPrev(); + // } + // else + // { + // pnlResult.SelectPrev(); + // } + // toolTip.IsOpen = false; + //} - private void SelectNextItem() - { - if (IsInContextMenuMode) - { - pnlContextMenu.SelectNext(); - } - else - { - pnlResult.SelectNext(); - } - toolTip.IsOpen = false; - } - - private void SelectResult(Result result) - { - if (result != null) - { - if (result.Action != null) - { - bool hideWindow = result.Action(new ActionContext - { - SpecialKeyState = GlobalHotkey.Instance.CheckModifiers() - }); - if (hideWindow) - { - HideWox(); - } - UserSelectedRecordStorage.Instance.Add(result); - QueryHistoryStorage.Instance.Add(tbQuery.Text); - } - } - } - - private void UpdateResultView(List list, PluginMetadata metadata, Query originQuery) - { - _queryHasReturn = true; - progressBar.Dispatcher.Invoke(StopProgress); - - list.ForEach(o => - { - o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; - }); - if (originQuery.RawQuery == _lastQuery.RawQuery) - { - UpdateResultViewInternal(list, metadata); - } - } - - private void UpdateResultViewInternal(List list, PluginMetadata metadata) - { - Dispatcher.Invoke(() => - { - Stopwatch.Normal($"UI update cost for {metadata.Name}", - () => { pnlResult.AddResults(list, metadata.ID); }); - }); - } - - private Result GetTopMostContextMenu(Result result) - { - if (TopMostRecordStorage.Instance.IsTopMost(result)) - { - return new Result(GetTranslation("cancelTopMostInThisQuery"), "Images\\down.png") - { - PluginDirectory = WoxDirectroy.Executable, - Action = _ => - { - TopMostRecordStorage.Instance.Remove(result); - ShowMsg("Succeed", "", ""); - return false; - } - }; - } - else - { - return new Result(GetTranslation("setAsTopMostInThisQuery"), "Images\\up.png") - { - PluginDirectory = WoxDirectroy.Executable, - Action = _ => - { - TopMostRecordStorage.Instance.AddOrUpdate(result); - ShowMsg("Succeed", "", ""); - return false; - } - }; - } - } - - private void ShowContextMenu(Result result) - { - if (result == null) return; - List results = PluginManager.GetContextMenusForPlugin(result); - results.ForEach(o => - { - o.PluginDirectory = PluginManager.GetPluginForId(result.PluginID).Metadata.PluginDirectory; - o.PluginID = result.PluginID; - o.OriginQuery = result.OriginQuery; - }); - - results.Add(GetTopMostContextMenu(result)); - - textBeforeEnterContextMenuMode = tbQuery.Text; - ChangeQueryText(""); - pnlContextMenu.Clear(); - pnlContextMenu.AddResults(results, result.PluginID); - CurrentContextMenus = results; - pnlContextMenu.Visibility = Visibility.Visible; - pnlResult.Visibility = Visibility.Collapsed; - } + //private void SelectNextItem() + //{ + // if (IsInContextMenuMode) + // { + // pnlContextMenu.SelectNext(); + // } + // else + // { + // pnlResult.SelectNext(); + // } + // toolTip.IsOpen = false; + //} private void MainWindow_OnDrop(object sender, DragEventArgs e) { diff --git a/Wox/PublicAPIInstance.cs b/Wox/PublicAPIInstance.cs new file mode 100644 index 0000000000..da5d23ee7f --- /dev/null +++ b/Wox/PublicAPIInstance.cs @@ -0,0 +1,309 @@ +using NHotkey; +using NHotkey.Wpf; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Threading; +using Wox.Core.Plugin; +using Wox.Core.Resource; +using Wox.Core.UserSettings; +using Wox.Helper; +using Wox.Infrastructure.Hotkey; +using Wox.Plugin; +using Wox.ViewModel; + +namespace Wox +{ + public class PublicAPIInstance : IPublicAPI + { + + #region Constructor + + public PublicAPIInstance(MainViewModel mainVM) + { + this.MainVM = mainVM; + + ThreadPool.SetMaxThreads(30, 10); + ThreadPool.SetMinThreads(10, 5); + GlobalHotkey.Instance.hookedKeyboardCallback += KListener_hookedKeyboardCallback; + WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); + + SetHotkey(UserSettingStorage.Instance.Hotkey, OnHotkey); + SetCustomPluginHotkey(); + } + + #endregion + + #region Properties + + private MainViewModel MainVM + { + get; + set; + } + + #endregion + + #region Public API + + public void ChangeQuery(string query, bool requery = false) + { + this.MainVM.QueryText = query; + + //Application.Current.Dispatcher.Invoke(() => + //{ + + // tbQuery.CaretIndex = this.MainVM.QueryText.Length; + // if (requery) + // { + // TbQuery_OnTextChanged(null, null); + // } + //}); + } + + public void ChangeQueryText(string query, bool selectAll = false) + { + this.MainVM.QueryText = query; + + //Application.Current.Dispatcher.Invoke(() => + //{ + + // tbQuery.CaretIndex = tbQuery.Text.Length; + // if (selectAll) + // { + // tbQuery.SelectAll(); + // } + //}); + } + + public void CloseApp() + { + //notifyIcon.Visible = false; + Application.Current.Shutdown(); + } + + public void RestarApp() + { + ProcessStartInfo info = new ProcessStartInfo + { + FileName = Application.ResourceAssembly.Location, + Arguments = SingleInstance.Restart + }; + Process.Start(info); + } + + public void HideApp() + { + HideWox(); + } + + public void ShowApp() + { + ShowWox(); + } + + public void ShowMsg(string title, string subTitle, string iconPath) + { + Application.Current.Dispatcher.Invoke(() => + { + var m = new Msg { Owner = Application.Current.MainWindow }; + m.Show(title, subTitle, iconPath); + }); + } + + public void OpenSettingDialog(string tabName = "general") + { + Application.Current.Dispatcher.Invoke(() => + { + SettingWindow sw = SingletonWindowOpener.Open(this); + sw.SwitchTo(tabName); + }); + } + + public void StartLoadingBar() + { + this.MainVM.IsProgressBarVisible = true; + } + + public void StopLoadingBar() + { + this.MainVM.IsProgressBarVisible = false; + } + + public void InstallPlugin(string path) + { + Application.Current.Dispatcher.Invoke(() => PluginManager.InstallPlugin(path)); + } + + public void ReloadPlugins() + { + Application.Current.Dispatcher.Invoke(() => PluginManager.Init(this)); + } + + public string GetTranslation(string key) + { + return InternationalizationManager.Instance.GetTranslation(key); + } + + public List GetAllPlugins() + { + return PluginManager.AllPlugins.ToList(); + } + + public event WoxKeyDownEventHandler BackKeyDownEvent; + public event WoxGlobalKeyboardEventHandler GlobalKeyboardEvent; + public event ResultItemDropEventHandler ResultItemDropEvent; + + public void PushResults(Query query, PluginMetadata plugin, List results) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + o.OriginQuery = query; + }); + this.MainVM.UpdateResultView(results, plugin, query); + } + + public void ShowContextMenu(PluginMetadata plugin, List results) + { + if (results != null && results.Count > 0) + { + results.ForEach(o => + { + o.PluginDirectory = plugin.PluginDirectory; + o.PluginID = plugin.ID; + }); + + this.MainVM.ActionPanel.Clear(); + + //TODO:Show Action Panel accordingly + //pnlContextMenu.Clear(); + //pnlContextMenu.AddResults(results, plugin.ID); + //pnlContextMenu.Visibility = Visibility.Visible; + //pnlResult.Visibility = Visibility.Collapsed; + } + } + + #endregion + + #region Private Methods + + private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) + { + if (GlobalKeyboardEvent != null) + { + return GlobalKeyboardEvent((int)keyevent, vkcode, state); + } + return true; + } + + private void HideWox() + { + UserSettingStorage.Instance.WindowLeft = this.MainVM.Left; + UserSettingStorage.Instance.WindowTop = this.MainVM.Top; + this.MainVM.IsVisible = false; + } + + private void ShowWox(bool selectAll = true) + { + UserSettingStorage.Instance.IncreaseActivateTimes(); + this.MainVM.IsVisible = true; + + //TODO:Adjust window properties + //Left = GetWindowsLeft(); + //Top = GetWindowsTop(); + + //Show(); + //Activate(); + //Focus(); + //tbQuery.Focus(); + //ResetQueryHistoryIndex(); + //if (selectAll) tbQuery.SelectAll(); + } + + public void SetHotkey(string hotkeyStr, EventHandler action) + { + var hotkey = new HotkeyModel(hotkeyStr); + SetHotkey(hotkey, action); + } + + public void SetHotkey(HotkeyModel hotkey, EventHandler action) + { + string hotkeyStr = hotkey.ToString(); + try + { + HotkeyManager.Current.AddOrReplace(hotkeyStr, hotkey.CharKey, hotkey.ModifierKeys, action); + } + catch (Exception) + { + string errorMsg = string.Format(InternationalizationManager.Instance.GetTranslation("registerHotkeyFailed"), hotkeyStr); + MessageBox.Show(errorMsg); + } + } + + public void RemoveHotkey(string hotkeyStr) + { + if (!string.IsNullOrEmpty(hotkeyStr)) + { + HotkeyManager.Current.Remove(hotkeyStr); + } + } + + /// + /// Checks if Wox should ignore any hotkeys + /// + /// + private bool ShouldIgnoreHotkeys() + { + //double if to omit calling win32 function + if (UserSettingStorage.Instance.IgnoreHotkeysOnFullscreen) + if (WindowIntelopHelper.IsWindowFullscreen()) + return true; + + return false; + } + + private void SetCustomPluginHotkey() + { + if (UserSettingStorage.Instance.CustomPluginHotkeys == null) return; + foreach (CustomPluginHotkey hotkey in UserSettingStorage.Instance.CustomPluginHotkeys) + { + CustomPluginHotkey hotkey1 = hotkey; + SetHotkey(hotkey.Hotkey, delegate + { + if (ShouldIgnoreHotkeys()) return; + ShowApp(); + ChangeQuery(hotkey1.ActionKeyword, true); + }); + } + } + + private void OnHotkey(object sender, HotkeyEventArgs e) + { + if (ShouldIgnoreHotkeys()) return; + ToggleWox(); + e.Handled = true; + } + + private void ToggleWox() + { + if (!MainVM.IsVisible) + { + ShowWox(); + } + else + { + HideWox(); + } + } + + #endregion + } +} diff --git a/Wox/ViewModel/BaseViewModel.cs b/Wox/ViewModel/BaseViewModel.cs new file mode 100644 index 0000000000..c720dfcdf0 --- /dev/null +++ b/Wox/ViewModel/BaseViewModel.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace Wox.ViewModel +{ + public class BaseViewModel : INotifyPropertyChanged + { + + protected virtual void OnPropertyChanged(string propertyName) + { + if (null != this.PropertyChanged) + { + this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } + + public class RelayCommand : ICommand + { + + private Action _action; + + public RelayCommand(Action action) + { + this._action = action; + } + + public virtual bool CanExecute(object parameter) + { + return true; + } + + public event EventHandler CanExecuteChanged; + + public virtual void Execute(object parameter) + { + if (null != this._action) + { + this._action(); + } + } + } +} diff --git a/Wox/ViewModel/MainViewModel.cs b/Wox/ViewModel/MainViewModel.cs new file mode 100644 index 0000000000..b79ca98dc9 --- /dev/null +++ b/Wox/ViewModel/MainViewModel.cs @@ -0,0 +1,449 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using Wox.Core.Plugin; +using Wox.Core.Resource; +using Wox.Infrastructure; +using Wox.Infrastructure.Hotkey; +using Wox.Plugin; +using Wox.Storage; + +namespace Wox.ViewModel +{ + public class MainViewModel : BaseViewModel + { + #region Private Fields + + private ResultPanelViewModel _searchResultPanel; + private ResultPanelViewModel _actionPanel; + private string _queryText; + private bool _isVisible; + private bool _isSearchResultPanelVisible; + private bool _isActionPanelVisible; + private bool _isProgressBarVisible; + private bool _isProgressBarTooltipVisible; + private double _left; + private double _top; + + private bool _queryHasReturn; + private Query _lastQuery = new Query(); + private bool _ignoreTextChange; + private List CurrentContextMenus = new List(); + private string _textBeforeEnterContextMenuMode; + + #endregion + + #region Constructor + + public MainViewModel() + { + this.InitializeResultPanel(); + this.InitializeActionPanel(); + this.InitializeKeyCommands(); + + this._queryHasReturn = false; + } + + #endregion + + #region ViewModel Properties + + public ResultPanelViewModel SearchResultPanel + { + get + { + return this._searchResultPanel; + } + } + + public ResultPanelViewModel ActionPanel + { + get + { + return this._actionPanel; + } + } + + public string QueryText + { + get + { + return this._queryText; + } + set + { + this._queryText = value; + OnPropertyChanged("QueryText"); + + this.HandleQueryTextUpdated(); + } + } + + public bool IsVisible + { + get + { + return this._isVisible; + } + set + { + this._isVisible = value; + OnPropertyChanged("IsVisible"); + + if (!value && this.IsActionPanelVisible) + { + this.BackToSearchMode(); + } + } + } + + public bool IsSearchResultPanelVisible + { + get + { + return this._isSearchResultPanelVisible; + } + set + { + this._isSearchResultPanelVisible = value; + OnPropertyChanged("IsSearchResultPanelVisible"); + } + } + + public bool IsActionPanelVisible + { + get + { + return this._isActionPanelVisible; + } + set + { + this._isActionPanelVisible = value; + OnPropertyChanged("IsActionPanelVisible"); + } + } + + public bool IsProgressBarVisible + { + get + { + return this._isProgressBarVisible; + } + set + { + this._isProgressBarVisible = value; + OnPropertyChanged("IsProgressBarVisible"); + } + } + + public bool IsProgressBarTooltipVisible + { + get + { + return this._isProgressBarTooltipVisible; + } + set + { + this._isProgressBarTooltipVisible = value; + OnPropertyChanged("IsProgressBarTooltipVisible"); + } + } + + public double Left + { + get + { + return this._left; + } + set + { + this._left = value; + OnPropertyChanged("Left"); + } + } + + public double Top + { + get + { + return this._top; + } + set + { + this._top = value; + OnPropertyChanged("Top"); + } + } + + public ICommand EscCommand + { + get; + set; + } + + #endregion + + #region Private Methods + + private void InitializeKeyCommands() + { + this.EscCommand = new RelayCommand(() => { + + if (this.IsActionPanelVisible) + { + this.BackToSearchMode(); + } + else + { + this.IsVisible = false; + } + + }); + } + + private void InitializeResultPanel() + { + this._searchResultPanel = new ResultPanelViewModel(); + this.IsSearchResultPanelVisible = false; + this._searchResultPanel.ResultOpenedInPanel += (o, e) => + { + if (e.HideWindow) + { + this.IsVisible = false; + } + UserSelectedRecordStorage.Instance.Add(e.Result.RawResult); + QueryHistoryStorage.Instance.Add(this.QueryText); + }; + + this._searchResultPanel.ResultActionPanelOpenedInPanel += (o, e) => + { + this.ShowActionPanel(e.Result.RawResult); + }; + } + + private void ShowActionPanel(Result result) + { + if (result == null) return; + List results = PluginManager.GetContextMenusForPlugin(result); + results.ForEach(o => + { + o.PluginDirectory = PluginManager.GetPluginForId(result.PluginID).Metadata.PluginDirectory; + o.PluginID = result.PluginID; + o.OriginQuery = result.OriginQuery; + }); + + results.Add(GetTopMostContextMenu(result)); + + _textBeforeEnterContextMenuMode = this.QueryText; + + this._actionPanel.Clear(); + this._actionPanel.AddResults(results, result.PluginID); + CurrentContextMenus = results; + + this.IsActionPanelVisible = true; + this.IsSearchResultPanelVisible = false; + + this.QueryText = ""; + + } + + private Result GetTopMostContextMenu(Result result) + { + if (TopMostRecordStorage.Instance.IsTopMost(result)) + { + return new Result(InternationalizationManager.Instance.GetTranslation("cancelTopMostInThisQuery"), "Images\\down.png") + { + PluginDirectory = WoxDirectroy.Executable, + Action = _ => + { + TopMostRecordStorage.Instance.Remove(result); + //TODO:Modify the way showing this message + //ShowMsg("Succeed", "", ""); + return false; + } + }; + } + else + { + return new Result(InternationalizationManager.Instance.GetTranslation("setAsTopMostInThisQuery"), "Images\\up.png") + { + PluginDirectory = WoxDirectroy.Executable, + Action = _ => + { + TopMostRecordStorage.Instance.AddOrUpdate(result); + //TODO:Modify the way showing this message + //ShowMsg("Succeed", "", ""); + return false; + } + }; + } + } + + private void InitializeActionPanel() + { + this._actionPanel = new ResultPanelViewModel(); + this.IsActionPanelVisible = false; + this._actionPanel.ResultOpenedInPanel += (o, e) => + { + if (e.HideWindow) + { + this.IsVisible = false; + } + }; + } + + private void HandleQueryTextUpdated() + { + if (_ignoreTextChange) { _ignoreTextChange = false; return; } + + this.IsProgressBarTooltipVisible = false; + if (this.IsActionPanelVisible) + { + QueryActionPanel(); + } + else + { + string query = this.QueryText.Trim(); + if (!string.IsNullOrEmpty(query)) + { + Query(query); + //reset query history index after user start new query + ResetQueryHistoryIndex(); + } + else + { + this._searchResultPanel.Clear(); + } + } + } + + private void QueryActionPanel() + { + var contextMenuId = "Context Menu Id"; + this._actionPanel.Clear(); + var query = this.QueryText.ToLower(); + if (string.IsNullOrEmpty(query)) + { + this._actionPanel.AddResults(CurrentContextMenus, contextMenuId); + } + else + { + List filterResults = new List(); + foreach (Result contextMenu in CurrentContextMenus) + { + if (StringMatcher.IsMatch(contextMenu.Title, query) + || StringMatcher.IsMatch(contextMenu.SubTitle, query)) + { + filterResults.Add(contextMenu); + } + } + this._actionPanel.AddResults(filterResults, contextMenuId); + } + } + + 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)) + { + this._searchResultPanel.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata); + } + } + else + { + if (string.IsNullOrEmpty(keyword)) + { + this._searchResultPanel.RemoveResultsFor(PluginManager.NonGlobalPlugins[lastKeyword].Metadata); + } + else if (lastKeyword != keyword) + { + this._searchResultPanel.RemoveResultsExcept(PluginManager.NonGlobalPlugins[keyword].Metadata); + } + } + _lastQuery = query; + + Action action = new Action(async () => + { + await Task.Delay(150); + if (!string.IsNullOrEmpty(query.RawQuery) && query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn) + { + this.IsProgressBarTooltipVisible = true; + } + }); + action.Invoke(); + + //Application.Current.Dispatcher.InvokeAsync(async () => + //{ + // await Task.Delay(150); + // if (!string.IsNullOrEmpty(query.RawQuery) && query.RawQuery == _lastQuery.RawQuery && !_queryHasReturn) + // { + // StartProgress(); + // } + //}); + PluginManager.QueryForAllPlugins(query); + } + + this.IsProgressBarTooltipVisible = false; + } + + private void ResetQueryHistoryIndex() + { + this._searchResultPanel.RemoveResultsFor(QueryHistoryStorage.MetaData); + QueryHistoryStorage.Instance.Reset(); + } + + private void UpdateResultViewInternal(List list, PluginMetadata metadata) + { + Stopwatch.Normal($"UI update cost for {metadata.Name}", + () => { this._searchResultPanel.AddResults(list, metadata.ID); }); + } + + private void BackToSearchMode() + { + this.QueryText = _textBeforeEnterContextMenuMode; + this.IsActionPanelVisible = false; + this.IsSearchResultPanelVisible = true; + } + + #endregion + + #region Public Methods + + public void UpdateResultView(List list, PluginMetadata metadata, Query originQuery) + { + _queryHasReturn = true; + this.IsProgressBarTooltipVisible = false; + + list.ForEach(o => + { + o.Score += UserSelectedRecordStorage.Instance.GetSelectedCount(o) * 5; + }); + if (originQuery.RawQuery == _lastQuery.RawQuery) + { + Application.Current.Dispatcher.Invoke(() => { + UpdateResultViewInternal(list, metadata); + }); + } + + if(list.Count > 0) + { + this.IsSearchResultPanelVisible = true; + } + } + + #endregion + + } +} diff --git a/less.exe.stackdump b/less.exe.stackdump new file mode 100644 index 0000000000..ec6e43c4a0 --- /dev/null +++ b/less.exe.stackdump @@ -0,0 +1,15 @@ +Stack trace: +Frame Function Args +00000010000 0018007208E (0018024F7D0, 00180215E59, 00000010000, 0000022B940) +00000010000 00180046DF2 (0000022C9A8, 001803253F8, 00000000001, 001803253F8) +00000010000 00180046E32 (00000000001, 00180325608, 00000010000, 00000000002) +00000010000 0018006C65D (001800CDED2, 00000000000, 00000000000, 00000000000) +0000022CBC0 0018006C6EE (00000000020, 00000000023, 00180047805, 00000000000) +0000022CBC0 001800475B7 (000002B6150, 00002080014, 0000022CDB0, 00000000000) +00000000000 0018004602C (00000000000, 00000000000, 00000000000, 00000000000) +00000000000 001800460C4 (00000000000, 00000000000, 00000000000, 00000000000) +00000000000 00100414FC1 (00000000000, 00000000000, 00000000000, 00000000000) +00000000000 00100401010 (00000000000, 00000000000, 00000000000, 00000000000) +00000000000 000779A59CD (00000000000, 00000000000, 00000000000, 00000000000) +00000000000 00077ADB981 (00000000000, 00000000000, 00000000000, 00000000000) +End of stack trace