// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Microsoft.Plugin.WindowWalker.Components
{
///
/// Responsible for searching and finding matches for the strings provided.
/// Essentially the UI independent model of the application
///
internal class SearchController
{
///
/// the current search text
///
private string searchText;
///
/// Open window search results
///
private List searchMatches;
///
/// Singleton pattern
///
private static SearchController instance;
///
/// Gets or sets the current search text
///
internal string SearchText
{
get
{
return searchText;
}
set
{
// Using CurrentCulture since this is user facing
searchText = value.ToLower(CultureInfo.CurrentCulture).Trim();
}
}
///
/// Gets the open window search results
///
internal List SearchMatches
{
get { return new List(searchMatches).OrderByDescending(x => x.Score).ToList(); }
}
///
/// Gets singleton Pattern
///
internal static SearchController Instance
{
get
{
if (instance == null)
{
instance = new SearchController();
}
return instance;
}
}
///
/// Initializes a new instance of the class.
/// Initializes the search controller object
///
private SearchController()
{
searchText = string.Empty;
}
///
/// Event handler for when the search text has been updated
///
internal void UpdateSearchText(string searchText)
{
SearchText = searchText;
SyncOpenWindowsWithModel();
}
///
/// Syncs the open windows with the OpenWindows Model
///
internal void SyncOpenWindowsWithModel()
{
System.Diagnostics.Debug.Print("Syncing WindowSearch result with OpenWindows Model");
List snapshotOfOpenWindows = OpenWindows.Instance.Windows;
if (string.IsNullOrWhiteSpace(SearchText))
{
searchMatches = AllOpenWindows(snapshotOfOpenWindows);
}
else
{
searchMatches = FuzzySearchOpenWindows(snapshotOfOpenWindows);
}
}
///
/// Search method that matches the title of windows with the user search text
///
/// what windows are open
/// Returns search results
private List FuzzySearchOpenWindows(List openWindows)
{
List result = new List();
var searchStrings = new SearchString(searchText, SearchResult.SearchType.Fuzzy);
foreach (var window in openWindows)
{
var titleMatch = FuzzyMatching.FindBestFuzzyMatch(window.Title, searchStrings.SearchText);
var processMatch = FuzzyMatching.FindBestFuzzyMatch(window.Process.Name, searchStrings.SearchText);
if ((titleMatch.Count != 0 || processMatch.Count != 0) && window.Title.Length != 0)
{
result.Add(new SearchResult(window, titleMatch, processMatch, searchStrings.SearchType));
}
}
System.Diagnostics.Debug.Print("Found " + result.Count + " windows that match the search text");
return result;
}
///
/// Search method that matches all the windows with a title
///
/// what windows are open
/// Returns search results
private List AllOpenWindows(List openWindows)
{
List result = new List();
foreach (var window in openWindows)
{
if (window.Title.Length != 0)
{
result.Add(new SearchResult(window));
}
}
return result.OrderBy(w => w.Result.Title).ToList();
}
///
/// Event args for a window list update event
///
internal class SearchResultUpdateEventArgs : EventArgs
{
}
}
}