using System; using System.Collections.Generic; using System.Globalization; namespace JD.UserControls.QuickOpenDialogs { /// /// Allows to search using default search patterns (contains words in order, ...). /// public class TextQuery { private readonly string m_text; private readonly string[] m_words; public TextQuery(string text) { m_text = text ?? string.Empty; m_words = m_text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } /// /// Returns the length of the original search /// public int TextLength { get { return m_text.Length; } } /// /// Returns the number of word in the query /// public IReadOnlyList Words { get { return m_words; } } /// /// The original unformatted text of the query. /// public string OriginalText { get { return m_text; } } /// /// Checks the text for a match. /// public MatchResult Matches(string text) { if (string.IsNullOrEmpty(text)) { return MatchResult.Invalid; } int index = 0; int score = -1; for (int i = 0; i < m_words.Length; ++i) { if (index >= text.Length) { return MatchResult.Invalid; } index = CultureInfo.InvariantCulture.CompareInfo.IndexOf(text, m_words[i], CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase); if (index == -1) { return MatchResult.Invalid; } CheckPreviousSeparator(text, index, ref score); index += m_words[i].Length; CheckNextSeparator(text, index, ref score); } return new MatchResult(score); } private static void CheckPreviousSeparator(string text, int index, ref int score) { if (index == 0) { score -= 4; } else if (IsSeparator(text[index - 1])) { score -= 2; } } private static void CheckNextSeparator(string text, int index, ref int score) { if (index >= text.Length || IsSeparator(text[index])) { score -= 1; } } private static bool IsSeparator(char c) { return char.IsWhiteSpace(c) || c == '.' || c == '\\'; } public struct MatchResult : IComparable { public static readonly MatchResult Invalid = new MatchResult(); private readonly int m_score; public MatchResult(int score) { m_score = score; } public bool IsMatch { get { return m_score != 0; } } public int CompareTo(MatchResult other) { return m_score.CompareTo(other.m_score); } } } }