/ src / modules / launcher / Plugins / Microsoft.Plugin.WindowWalker / Components / SearchController.cs
SearchController.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 // Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/ 6 using System; 7 using System.Collections.Generic; 8 using System.Globalization; 9 using System.Linq; 10 11 namespace Microsoft.Plugin.WindowWalker.Components 12 { 13 /// <summary> 14 /// Responsible for searching and finding matches for the strings provided. 15 /// Essentially the UI independent model of the application 16 /// </summary> 17 internal class SearchController 18 { 19 /// <summary> 20 /// the current search text 21 /// </summary> 22 private string searchText; 23 24 /// <summary> 25 /// Open window search results 26 /// </summary> 27 private List<SearchResult> searchMatches; 28 29 /// <summary> 30 /// Singleton pattern 31 /// </summary> 32 private static SearchController instance; 33 34 /// <summary> 35 /// Gets or sets the current search text 36 /// </summary> 37 internal string SearchText 38 { 39 get 40 { 41 return searchText; 42 } 43 44 set 45 { 46 // Using CurrentCulture since this is user facing 47 searchText = value.ToLower(CultureInfo.CurrentCulture).Trim(); 48 } 49 } 50 51 /// <summary> 52 /// Gets the open window search results 53 /// </summary> 54 internal List<SearchResult> SearchMatches 55 { 56 get { return new List<SearchResult>(searchMatches).OrderByDescending(x => x.Score).ToList(); } 57 } 58 59 /// <summary> 60 /// Gets singleton Pattern 61 /// </summary> 62 internal static SearchController Instance 63 { 64 get 65 { 66 if (instance == null) 67 { 68 instance = new SearchController(); 69 } 70 71 return instance; 72 } 73 } 74 75 /// <summary> 76 /// Initializes a new instance of the <see cref="SearchController"/> class. 77 /// Initializes the search controller object 78 /// </summary> 79 private SearchController() 80 { 81 searchText = string.Empty; 82 } 83 84 /// <summary> 85 /// Event handler for when the search text has been updated 86 /// </summary> 87 internal void UpdateSearchText(string searchText) 88 { 89 SearchText = searchText; 90 SyncOpenWindowsWithModel(); 91 } 92 93 /// <summary> 94 /// Syncs the open windows with the OpenWindows Model 95 /// </summary> 96 internal void SyncOpenWindowsWithModel() 97 { 98 System.Diagnostics.Debug.Print("Syncing WindowSearch result with OpenWindows Model"); 99 100 List<Window> snapshotOfOpenWindows = OpenWindows.Instance.Windows; 101 102 if (string.IsNullOrWhiteSpace(SearchText)) 103 { 104 searchMatches = AllOpenWindows(snapshotOfOpenWindows); 105 } 106 else 107 { 108 searchMatches = FuzzySearchOpenWindows(snapshotOfOpenWindows); 109 } 110 } 111 112 /// <summary> 113 /// Search method that matches the title of windows with the user search text 114 /// </summary> 115 /// <param name="openWindows">what windows are open</param> 116 /// <returns>Returns search results</returns> 117 private List<SearchResult> FuzzySearchOpenWindows(List<Window> openWindows) 118 { 119 List<SearchResult> result = new List<SearchResult>(); 120 var searchStrings = new SearchString(searchText, SearchResult.SearchType.Fuzzy); 121 122 foreach (var window in openWindows) 123 { 124 var titleMatch = FuzzyMatching.FindBestFuzzyMatch(window.Title, searchStrings.SearchText); 125 var processMatch = FuzzyMatching.FindBestFuzzyMatch(window.Process.Name, searchStrings.SearchText); 126 127 if ((titleMatch.Count != 0 || processMatch.Count != 0) && window.Title.Length != 0) 128 { 129 result.Add(new SearchResult(window, titleMatch, processMatch, searchStrings.SearchType)); 130 } 131 } 132 133 System.Diagnostics.Debug.Print("Found " + result.Count + " windows that match the search text"); 134 135 return result; 136 } 137 138 /// <summary> 139 /// Search method that matches all the windows with a title 140 /// </summary> 141 /// <param name="openWindows">what windows are open</param> 142 /// <returns>Returns search results</returns> 143 private List<SearchResult> AllOpenWindows(List<Window> openWindows) 144 { 145 List<SearchResult> result = new List<SearchResult>(); 146 147 foreach (var window in openWindows) 148 { 149 if (window.Title.Length != 0) 150 { 151 result.Add(new SearchResult(window)); 152 } 153 } 154 155 return result.OrderBy(w => w.Result.Title).ToList(); 156 } 157 158 /// <summary> 159 /// Event args for a window list update event 160 /// </summary> 161 internal class SearchResultUpdateEventArgs : EventArgs 162 { 163 } 164 } 165 }