using System.Text.RegularExpressions;
namespace Terminal.Gui.Views;
/// Regex Provider for TextValidateField.
public class TextRegexProvider : ITextValidateProvider
{
private List _pattern = null!;
private Regex _regex = null!;
private List _text = null!;
/// Empty Constructor.
public TextRegexProvider (string pattern) { Pattern = pattern; }
/// Regex pattern property.
public string Pattern
{
get => StringExtensions.ToString (_pattern);
set
{
_pattern = value.ToRuneList ();
CompileMask ();
SetupText ();
}
}
/// When true, validates with the regex pattern on each input, preventing the input if it's not valid.
public bool ValidateOnInput { get; set; } = true;
///
public event EventHandler> TextChanged = null!;
///
public string Text
{
get => StringExtensions.ToString (_text);
set
{
_text = (value != string.Empty ? value.ToRuneList () : null)!;
SetupText ();
}
}
///
public string DisplayText => Text;
///
public bool IsValid => Validate (_text);
///
public bool Fixed => false;
///
public int Cursor (int pos)
{
if (pos < 0)
{
return CursorStart ();
}
if (pos >= _text.Count)
{
return CursorEnd ();
}
return pos;
}
///
public int CursorStart () { return 0; }
///
public int CursorEnd () { return _text.Count; }
///
public int CursorLeft (int pos)
{
if (pos > 0)
{
return pos - 1;
}
return pos;
}
///
public int CursorRight (int pos)
{
if (pos < _text.Count)
{
return pos + 1;
}
return pos;
}
///
public bool Delete (int pos)
{
if (_text.Count > 0 && pos < _text.Count)
{
string oldValue = Text;
_text.RemoveAt (pos);
OnTextChanged (new (in oldValue));
}
return true;
}
///
public bool InsertAt (char ch, int pos)
{
List aux = _text.ToList ();
aux.Insert (pos, (Rune)ch);
if (Validate (aux) || ValidateOnInput == false)
{
string oldValue = Text;
_text.Insert (pos, (Rune)ch);
OnTextChanged (new (in oldValue));
return true;
}
return false;
}
///
public void OnTextChanged (EventArgs args) { TextChanged?.Invoke (this, args); }
/// Compiles the regex pattern for validation./>
private void CompileMask () { _regex = new (StringExtensions.ToString (_pattern), RegexOptions.Compiled); }
private void SetupText ()
{
if (_text is { } && IsValid)
{
return;
}
_text = new ();
}
private bool Validate (List text)
{
Match match = _regex.Match (StringExtensions.ToString (text));
return match.Success;
}
}