Re-add support for multiple text validator styles but
1) catch some invalid configurations in SetStyle() 2) document the order of the checks in wxTextValidator 3) implement wxFILTER_EMPTY 4) rename wxFILTER_SIMPLE_NUMBER => wxFILTER_DIGITS git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58637 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -22,25 +22,23 @@ class WXDLLIMPEXP_FWD_CORE wxTextEntry;
|
||||
|
||||
enum wxTextValidatorStyle
|
||||
{
|
||||
wxFILTER_NONE,
|
||||
wxFILTER_ASCII,
|
||||
wxFILTER_ALPHA,
|
||||
wxFILTER_ALPHANUMERIC,
|
||||
wxFILTER_SIMPLE_NUMBER,
|
||||
wxFILTER_NUMERIC,
|
||||
wxFILTER_INCLUDE_LIST,
|
||||
wxFILTER_EXCLUDE_LIST,
|
||||
wxFILTER_INCLUDE_CHAR_LIST,
|
||||
wxFILTER_EXCLUDE_CHAR_LIST
|
||||
wxFILTER_NONE = 0x0,
|
||||
wxFILTER_EMPTY = 0x1,
|
||||
wxFILTER_ASCII = 0x2,
|
||||
wxFILTER_ALPHA = 0x4,
|
||||
wxFILTER_ALPHANUMERIC = 0x8,
|
||||
wxFILTER_DIGITS = 0x10,
|
||||
wxFILTER_NUMERIC = 0x20,
|
||||
wxFILTER_INCLUDE_LIST = 0x40,
|
||||
wxFILTER_INCLUDE_CHAR_LIST = 0x80,
|
||||
wxFILTER_EXCLUDE_LIST = 0x100,
|
||||
wxFILTER_EXCLUDE_CHAR_LIST = 0x200
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_CORE wxTextValidator: public wxValidator
|
||||
{
|
||||
public:
|
||||
wxTextValidator(wxTextValidatorStyle style = wxFILTER_NONE, wxString *val = NULL);
|
||||
#if WXWIN_COMPATIBILITY_2_8
|
||||
wxDEPRECATED_CONSTRUCTOR( wxTextValidator(long style, wxString *val) );
|
||||
#endif
|
||||
wxTextValidator(long style = wxFILTER_NONE, wxString *val = NULL);
|
||||
wxTextValidator(const wxTextValidator& val);
|
||||
|
||||
virtual ~wxTextValidator(){}
|
||||
@@ -66,11 +64,8 @@ public:
|
||||
void OnChar(wxKeyEvent& event);
|
||||
|
||||
// ACCESSORS
|
||||
inline wxTextValidatorStyle GetStyle() const { return m_validatorStyle; }
|
||||
inline void SetStyle(wxTextValidatorStyle style) { m_validatorStyle = style; }
|
||||
#if WXWIN_COMPATIBILITY_2_8
|
||||
wxDEPRECATED( void SetStyle(long style) );
|
||||
#endif
|
||||
inline long GetStyle() const { return m_validatorStyle; }
|
||||
void SetStyle(long style);
|
||||
|
||||
wxTextEntry *GetTextEntry();
|
||||
|
||||
@@ -82,6 +77,9 @@ public:
|
||||
void SetExcludes(const wxArrayString& excludes) { m_excludes = excludes; }
|
||||
inline wxArrayString& GetExcludes() { return m_excludes; }
|
||||
|
||||
bool HasFlag(wxTextValidatorStyle style) const
|
||||
{ return m_validatorStyle & style; }
|
||||
|
||||
protected:
|
||||
|
||||
// returns true if all characters of the given string are present in m_includes
|
||||
@@ -90,11 +88,11 @@ protected:
|
||||
// returns true if all characters of the given string are NOT present in m_excludes
|
||||
bool ContainsExcludedCharacters(const wxString& val) const;
|
||||
|
||||
// returns true if the contents of 'val' are valid for the current validation style
|
||||
virtual bool IsValid(const wxString& val, wxString* errormsg) const;
|
||||
// returns the error message if the contents of 'val' are invalid
|
||||
virtual wxString IsValid(const wxString& val) const;
|
||||
|
||||
protected:
|
||||
wxTextValidatorStyle m_validatorStyle;
|
||||
long m_validatorStyle;
|
||||
wxString* m_stringValue;
|
||||
wxArrayString m_includes;
|
||||
wxArrayString m_excludes;
|
||||
|
@@ -9,12 +9,20 @@
|
||||
|
||||
/**
|
||||
Styles used by wxTextValidator.
|
||||
|
||||
Note that when you specify more styles in wxTextValidator the validation checks
|
||||
are performed in the order in which the styles of this enumeration are defined.
|
||||
*/
|
||||
enum wxTextValidatorStyle
|
||||
{
|
||||
/// No filtering takes place.
|
||||
wxFILTER_NONE,
|
||||
|
||||
/// Empty strings are filtered out.
|
||||
/// If this style is not specified then empty strings are accepted
|
||||
/// only if they pass the other checks (if you use more than one wxTextValidatorStyle).
|
||||
wxFILTER_EMPTY,
|
||||
|
||||
/// Non-ASCII characters are filtered out. See wxString::IsAscii.
|
||||
wxFILTER_ASCII,
|
||||
|
||||
@@ -31,7 +39,7 @@ enum wxTextValidatorStyle
|
||||
/// Non-numeric characters are filtered out.
|
||||
/// Uses the wxWidgets wrapper for the standard CRT function @c isdigit
|
||||
/// (which is locale-dependent) on all characters of the string.
|
||||
wxFILTER_SIMPLE_NUMBER,
|
||||
wxFILTER_DIGITS,
|
||||
|
||||
/// Non-numeric characters are filtered out.
|
||||
/// Works like @c wxFILTER_SIMPLE_NUMBER but allows also decimal points,
|
||||
@@ -43,15 +51,15 @@ enum wxTextValidatorStyle
|
||||
/// the list, complaining if not. See wxTextValidator::SetIncludes().
|
||||
wxFILTER_INCLUDE_LIST,
|
||||
|
||||
/// Use an exclude list. The validator checks if the user input is on
|
||||
/// the list, complaining if it is. See wxTextValidator::SetExcludes().
|
||||
wxFILTER_EXCLUDE_LIST,
|
||||
|
||||
/// Use an include list. The validator checks if each input character is
|
||||
/// in the list (one character per list element), complaining if not.
|
||||
/// See wxTextValidator::SetCharIncludes().
|
||||
wxFILTER_INCLUDE_CHAR_LIST,
|
||||
|
||||
/// Use an exclude list. The validator checks if the user input is on
|
||||
/// the list, complaining if it is. See wxTextValidator::SetExcludes().
|
||||
wxFILTER_EXCLUDE_LIST,
|
||||
|
||||
/// Use an exclude list. The validator checks if each input character is
|
||||
/// in the list (one character per list element), complaining if it is.
|
||||
/// See wxTextValidator::SetCharExcludes().
|
||||
@@ -83,14 +91,14 @@ public:
|
||||
Constructor taking a style and optional pointer to a wxString variable.
|
||||
|
||||
@param style
|
||||
One of the ::wxTextValidatorStyle styles.
|
||||
One or more of the ::wxTextValidatorStyle styles. See SetStyle().
|
||||
@param valPtr
|
||||
A pointer to a wxString variable that contains the value. This
|
||||
variable should have a lifetime equal to or longer than the
|
||||
validator lifetime (which is usually determined by the lifetime of
|
||||
the window).
|
||||
*/
|
||||
wxTextValidator(wxTextValidatorStyle style = wxFILTER_NONE, wxString* valPtr = NULL);
|
||||
wxTextValidator(long style = wxFILTER_NONE, wxString* valPtr = NULL);
|
||||
|
||||
/**
|
||||
Clones the text validator using the copy constructor.
|
||||
@@ -110,7 +118,7 @@ public:
|
||||
/**
|
||||
Returns the validator style.
|
||||
*/
|
||||
wxTextValidatorStyle GetStyle() const;
|
||||
long GetStyle() const;
|
||||
|
||||
/**
|
||||
Receives character input from the window and filters it according to
|
||||
@@ -147,9 +155,12 @@ public:
|
||||
void SetCharIncludes(const wxString& chars);
|
||||
|
||||
/**
|
||||
Sets the validator style.
|
||||
Sets the validator style which must be a combination of one or more
|
||||
of the ::wxTextValidatorStyle values.
|
||||
|
||||
Note that not all possible combinations make sense!
|
||||
*/
|
||||
void SetStyle(wxTextValidatorStyle style);
|
||||
void SetStyle(long style);
|
||||
|
||||
/**
|
||||
Transfers the value in the text control to the string.
|
||||
|
@@ -248,15 +248,18 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
|
||||
m_text = new wxTextCtrl(this, VALIDATE_TEXT, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, 0,
|
||||
wxTextValidator(wxFILTER_ALPHA, &g_data.m_string));
|
||||
m_text->SetToolTip("uses wxTextValidator with wxFILTER_ALPHA");
|
||||
flexgridsizer->Add(m_text, 1, wxGROW);
|
||||
|
||||
|
||||
// Now set a wxTextValidator with an explicit list of characters NOT allowed:
|
||||
wxTextValidator textVal(wxFILTER_EXCLUDE_CHAR_LIST, &g_data.m_string2);
|
||||
wxTextValidator textVal(wxFILTER_EMPTY|wxFILTER_EXCLUDE_LIST, &g_data.m_string2);
|
||||
textVal.SetCharExcludes("bcwyz");
|
||||
flexgridsizer->Add(new wxTextCtrl(this, VALIDATE_TEXT2, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, 0, textVal),
|
||||
1, wxGROW);
|
||||
wxTextCtrl* txt2 =
|
||||
new wxTextCtrl(this, VALIDATE_TEXT2, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, 0, textVal);
|
||||
txt2->SetToolTip("uses wxTextValidator with wxFILTER_EMPTY|");
|
||||
flexgridsizer->Add(txt2, 1, wxGROW);
|
||||
|
||||
flexgridsizer->Add(new wxListBox((wxWindow*)this, VALIDATE_LIST,
|
||||
wxPoint(10, 30), wxSize(120, wxDefaultCoord),
|
||||
@@ -268,6 +271,7 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
|
||||
wxPoint(130, 30), wxSize(120, wxDefaultCoord),
|
||||
3, g_combobox_choices, 0L,
|
||||
MyComboBoxValidator(&g_data.m_combobox_choice));
|
||||
m_combobox->SetToolTip("uses a custom validator (MyComboBoxValidator)");
|
||||
flexgridsizer->Add(m_combobox, 1, wxALIGN_CENTER);
|
||||
|
||||
// This wxCheckBox* doesn't need to be assigned to any pointer
|
||||
|
@@ -43,8 +43,9 @@ static bool wxIsNumeric(const wxString& val)
|
||||
{
|
||||
// Allow for "," (French) as well as "." -- in future we should
|
||||
// use wxSystemSettings or other to do better localisation
|
||||
if ((!wxIsdigit(*i)) && (*i != wxT('.')) && (*i != wxT(',')) && (*i != wxT('e')) &&
|
||||
(*i != wxT('E')) && (*i != wxT('+')) && (*i != wxT('-')))
|
||||
if ((!wxIsdigit(*i)) &&
|
||||
(*i != wxS('.')) && (*i != wxS(',')) && (*i != wxS('e')) &&
|
||||
(*i != wxS('E')) && (*i != wxS('+')) && (*i != wxS('-')))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -59,24 +60,10 @@ BEGIN_EVENT_TABLE(wxTextValidator, wxValidator)
|
||||
EVT_CHAR(wxTextValidator::OnChar)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
#if WXWIN_COMPATIBILITY_2_8
|
||||
wxTextValidator::wxTextValidator(long style, wxString *val)
|
||||
{
|
||||
m_validatorStyle = (wxTextValidatorStyle)style;
|
||||
m_stringValue = val;
|
||||
}
|
||||
|
||||
void wxTextValidator::SetStyle(long style)
|
||||
{
|
||||
SetStyle((wxTextValidatorStyle)style);
|
||||
}
|
||||
#endif
|
||||
|
||||
wxTextValidator::wxTextValidator(wxTextValidatorStyle style, wxString *val)
|
||||
{
|
||||
m_validatorStyle = style;
|
||||
m_stringValue = val;
|
||||
SetStyle(style);
|
||||
}
|
||||
|
||||
wxTextValidator::wxTextValidator(const wxTextValidator& val)
|
||||
@@ -85,6 +72,30 @@ wxTextValidator::wxTextValidator(const wxTextValidator& val)
|
||||
Copy(val);
|
||||
}
|
||||
|
||||
void wxTextValidator::SetStyle(long style)
|
||||
{
|
||||
m_validatorStyle = style;
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
int check;
|
||||
check = (int)HasFlag(wxFILTER_ALPHA) + (int)HasFlag(wxFILTER_ALPHANUMERIC) +
|
||||
(int)HasFlag(wxFILTER_DIGITS) + (int)HasFlag(wxFILTER_NUMERIC);
|
||||
wxASSERT_MSG(check <= 1,
|
||||
"It makes sense to use only one of the wxFILTER_ALPHA/wxFILTER_ALPHANUMERIC/"
|
||||
"wxFILTER_SIMPLE_NUMBER/wxFILTER_NUMERIC styles");
|
||||
|
||||
wxASSERT_MSG(((int)HasFlag(wxFILTER_INCLUDE_LIST) + (int)HasFlag(wxFILTER_INCLUDE_CHAR_LIST) <= 1) &&
|
||||
((int)HasFlag(wxFILTER_EXCLUDE_LIST) + (int)HasFlag(wxFILTER_EXCLUDE_CHAR_LIST) <= 1),
|
||||
"Using both wxFILTER_[IN|EX]CLUDE_LIST _and_ wxFILTER_[IN|EX]CLUDE_CHAR_LIST "
|
||||
"doesn't work since wxTextValidator internally uses the same array for both");
|
||||
|
||||
check = (int)HasFlag(wxFILTER_INCLUDE_LIST) + (int)HasFlag(wxFILTER_INCLUDE_CHAR_LIST) +
|
||||
(int)HasFlag(wxFILTER_EXCLUDE_LIST) + (int)HasFlag(wxFILTER_EXCLUDE_CHAR_LIST);
|
||||
wxASSERT_MSG(check <= 1,
|
||||
"Using both an include/exclude list may lead to unexpected results");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool wxTextValidator::Copy(const wxTextValidator& val)
|
||||
{
|
||||
wxValidator::Copy(val);
|
||||
@@ -135,18 +146,23 @@ bool wxTextValidator::Validate(wxWindow *parent)
|
||||
|
||||
wxString val(text->GetValue());
|
||||
|
||||
// NB: this format string should always contain exactly one '%s'
|
||||
wxString errormsg;
|
||||
if (!IsValid(val, &errormsg))
|
||||
if ( HasFlag(wxFILTER_EMPTY) && val.empty() )
|
||||
{
|
||||
wxASSERT(!errormsg.empty());
|
||||
|
||||
m_validatorWindow->SetFocus();
|
||||
|
||||
errormsg = _("The empty string is not allowed.");
|
||||
}
|
||||
else if ( !(errormsg = IsValid(val)).empty() )
|
||||
{
|
||||
// NB: this format string should always contain exactly one '%s'
|
||||
wxString buf;
|
||||
buf.Printf(errormsg, val.c_str());
|
||||
errormsg = buf;
|
||||
}
|
||||
|
||||
wxMessageBox(buf, _("Validation conflict"),
|
||||
if ( !errormsg.empty() )
|
||||
{
|
||||
m_validatorWindow->SetFocus();
|
||||
wxMessageBox(errormsg, _("Validation conflict"),
|
||||
wxOK | wxICON_EXCLAMATION, parent);
|
||||
|
||||
return false;
|
||||
@@ -185,68 +201,30 @@ bool wxTextValidator::TransferFromWindow()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxTextValidator::IsValid(const wxString& val, wxString* pErr) const
|
||||
wxString wxTextValidator::IsValid(const wxString& val) const
|
||||
{
|
||||
wxString errormsg;
|
||||
switch (m_validatorStyle)
|
||||
{
|
||||
case wxFILTER_NONE:
|
||||
// nothing to do...
|
||||
break;
|
||||
// wxFILTER_EMPTY is checked for in wxTextValidator::Validate
|
||||
|
||||
case wxFILTER_INCLUDE_LIST:
|
||||
if ( m_includes.Index(val) == wxNOT_FOUND )
|
||||
errormsg = _("'%s' is invalid");
|
||||
break;
|
||||
if ( HasFlag(wxFILTER_ASCII) && !val.IsAscii() )
|
||||
return _("'%s' should only contain ASCII characters.");
|
||||
if ( HasFlag(wxFILTER_ALPHA) && !wxStringCheck<wxIsalpha>(val) )
|
||||
return _("'%s' should only contain alphabetic characters.");
|
||||
if ( HasFlag(wxFILTER_ALPHANUMERIC) && !wxStringCheck<wxIsalnum>(val) )
|
||||
return _("'%s' should only contain alphabetic or numeric characters.");
|
||||
if ( HasFlag(wxFILTER_DIGITS) && !wxStringCheck<wxIsdigit>(val) )
|
||||
return _("'%s' should only contain digits.");
|
||||
if ( HasFlag(wxFILTER_NUMERIC) && !wxIsNumeric(val) )
|
||||
return _("'%s' should be numeric.");
|
||||
if ( HasFlag(wxFILTER_INCLUDE_LIST) && m_includes.Index(val) == wxNOT_FOUND )
|
||||
return _("'%s' is invalid");
|
||||
if ( HasFlag(wxFILTER_INCLUDE_CHAR_LIST) && !ContainsOnlyIncludedCharacters(val) )
|
||||
return _("'%s' is invalid");
|
||||
if ( HasFlag(wxFILTER_EXCLUDE_LIST) && m_excludes.Index(val) != wxNOT_FOUND )
|
||||
return _("'%s' is invalid");
|
||||
if ( HasFlag(wxFILTER_EXCLUDE_CHAR_LIST) && ContainsExcludedCharacters(val) )
|
||||
return _("'%s' is invalid");
|
||||
|
||||
case wxFILTER_EXCLUDE_LIST:
|
||||
if ( m_excludes.Index(val) != wxNOT_FOUND )
|
||||
errormsg = _("'%s' is invalid");
|
||||
break;
|
||||
|
||||
case wxFILTER_ASCII:
|
||||
if ( !val.IsAscii() )
|
||||
errormsg = _("'%s' should only contain ASCII characters.");
|
||||
break;
|
||||
|
||||
case wxFILTER_ALPHA:
|
||||
if ( !wxStringCheck<wxIsalpha>(val) )
|
||||
errormsg = _("'%s' should only contain alphabetic characters.");
|
||||
break;
|
||||
|
||||
case wxFILTER_ALPHANUMERIC:
|
||||
if ( !wxStringCheck<wxIsalnum>(val) )
|
||||
errormsg = _("'%s' should only contain alphabetic or numeric characters.");
|
||||
break;
|
||||
|
||||
case wxFILTER_SIMPLE_NUMBER:
|
||||
if ( !wxStringCheck<wxIsdigit>(val) )
|
||||
errormsg = _("'%s' should be numeric.");
|
||||
break;
|
||||
|
||||
case wxFILTER_NUMERIC:
|
||||
if ( !wxIsNumeric(val) )
|
||||
errormsg = _("'%s' should be numeric.");
|
||||
break;
|
||||
|
||||
case wxFILTER_INCLUDE_CHAR_LIST:
|
||||
if ( !ContainsOnlyIncludedCharacters(val) )
|
||||
errormsg = _("'%s' is invalid");
|
||||
break;
|
||||
|
||||
case wxFILTER_EXCLUDE_CHAR_LIST:
|
||||
if ( ContainsExcludedCharacters(val) )
|
||||
errormsg = _("'%s' is invalid");
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG("invalid text validator style");
|
||||
}
|
||||
|
||||
if (pErr)
|
||||
*pErr = errormsg;
|
||||
|
||||
return errormsg.empty();
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
bool wxTextValidator::ContainsOnlyIncludedCharacters(const wxString& val) const
|
||||
@@ -309,7 +287,7 @@ void wxTextValidator::OnChar(wxKeyEvent& event)
|
||||
}
|
||||
|
||||
wxString str((wxUniChar)keyCode, 1);
|
||||
if (!IsValid(str, NULL))
|
||||
if (!IsValid(str).empty())
|
||||
{
|
||||
if ( !wxValidator::IsSilent() )
|
||||
wxBell();
|
||||
|
Reference in New Issue
Block a user