128 lines
No EOL
3.3 KiB
C#
128 lines
No EOL
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
|
|
namespace JD.UserControls.QuickOpenDialogs
|
|
{
|
|
/// <summary>
|
|
/// Allows to search using default search patterns (contains words in order, ...).
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the length of the original search
|
|
/// </summary>
|
|
public int TextLength
|
|
{
|
|
get { return m_text.Length; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the number of word in the query
|
|
/// </summary>
|
|
public IReadOnlyList<string> Words
|
|
{
|
|
get { return m_words; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The original unformatted text of the query.
|
|
/// </summary>
|
|
public string OriginalText
|
|
{
|
|
get { return m_text; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the text for a match.
|
|
/// </summary>
|
|
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<MatchResult>
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
} |