wxTextValidator improvements
Improve char inclusion/exclusion support; update the sample to show more features of this class and add a unit test for it. Closes https://github.com/wxWidgets/wxWidgets/pull/1093
This commit is contained in:
committed by
Vadim Zeitlin
parent
697125dc03
commit
36f6f8ad49
@@ -104,6 +104,10 @@ Changes in behaviour which may result in build errors
|
|||||||
e.g. if the error is due to spelling an option name wrongly, fixing or
|
e.g. if the error is due to spelling an option name wrongly, fixing or
|
||||||
removing its name.
|
removing its name.
|
||||||
|
|
||||||
|
- wxTextValidator::Get{In,Ex}cludes() now return a const reference to
|
||||||
|
wxArrayString. Please update your code to use the appropriate setter
|
||||||
|
Set[Char]{In,Ex}cludes(), instead of mutating the internal data directly.
|
||||||
|
|
||||||
|
|
||||||
3.1.3: (released 2019-??-??)
|
3.1.3: (released 2019-??-??)
|
||||||
----------------------------
|
----------------------------
|
||||||
|
@@ -31,9 +31,20 @@ enum wxTextValidatorStyle
|
|||||||
wxFILTER_INCLUDE_LIST = 0x40,
|
wxFILTER_INCLUDE_LIST = 0x40,
|
||||||
wxFILTER_INCLUDE_CHAR_LIST = 0x80,
|
wxFILTER_INCLUDE_CHAR_LIST = 0x80,
|
||||||
wxFILTER_EXCLUDE_LIST = 0x100,
|
wxFILTER_EXCLUDE_LIST = 0x100,
|
||||||
wxFILTER_EXCLUDE_CHAR_LIST = 0x200
|
wxFILTER_EXCLUDE_CHAR_LIST = 0x200,
|
||||||
|
wxFILTER_XDIGITS = 0x400,
|
||||||
|
wxFILTER_SPACE = 0x800,
|
||||||
|
|
||||||
|
// filter char class (for internal use only)
|
||||||
|
wxFILTER_CC = wxFILTER_SPACE|wxFILTER_ASCII|wxFILTER_NUMERIC|
|
||||||
|
wxFILTER_ALPHANUMERIC|wxFILTER_ALPHA|
|
||||||
|
wxFILTER_DIGITS|wxFILTER_XDIGITS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTextValidator
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxTextValidator: public wxValidator
|
class WXDLLIMPEXP_CORE wxTextValidator: public wxValidator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -68,31 +79,78 @@ public:
|
|||||||
|
|
||||||
wxTextEntry *GetTextEntry();
|
wxTextEntry *GetTextEntry();
|
||||||
|
|
||||||
|
// strings & chars inclusions:
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
void SetCharIncludes(const wxString& chars);
|
void SetCharIncludes(const wxString& chars);
|
||||||
void SetIncludes(const wxArrayString& includes) { m_includes = includes; }
|
void AddCharIncludes(const wxString& chars);
|
||||||
inline wxArrayString& GetIncludes() { return m_includes; }
|
|
||||||
|
void SetIncludes(const wxArrayString& includes);
|
||||||
|
void AddInclude(const wxString& include);
|
||||||
|
|
||||||
|
const wxArrayString& GetIncludes() const { return m_includes; }
|
||||||
|
wxString GetCharIncludes() const { return m_charIncludes; }
|
||||||
|
|
||||||
|
// strings & chars exclusions:
|
||||||
|
// ---------------------------
|
||||||
|
|
||||||
void SetCharExcludes(const wxString& chars);
|
void SetCharExcludes(const wxString& chars);
|
||||||
void SetExcludes(const wxArrayString& excludes) { m_excludes = excludes; }
|
void AddCharExcludes(const wxString& chars);
|
||||||
inline wxArrayString& GetExcludes() { return m_excludes; }
|
|
||||||
|
void SetExcludes(const wxArrayString& excludes);
|
||||||
|
void AddExclude(const wxString& exclude);
|
||||||
|
|
||||||
|
const wxArrayString& GetExcludes() const { return m_excludes; }
|
||||||
|
wxString GetCharExcludes() const { return m_charExcludes; }
|
||||||
|
|
||||||
bool HasFlag(wxTextValidatorStyle style) const
|
bool HasFlag(wxTextValidatorStyle style) const
|
||||||
{ return (m_validatorStyle & style) != 0; }
|
{ return (m_validatorStyle & style) != 0; }
|
||||||
|
|
||||||
|
// implementation only
|
||||||
|
// --------------------
|
||||||
|
|
||||||
|
// returns the error message if the contents of 'str' are invalid
|
||||||
|
virtual wxString IsValid(const wxString& str) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// returns true if all characters of the given string are present in m_includes
|
bool IsCharIncluded(const wxUniChar& c) const
|
||||||
|
{
|
||||||
|
return m_charIncludes.find(c) != wxString::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCharExcluded(const wxUniChar& c) const
|
||||||
|
{
|
||||||
|
return m_charExcludes.find(c) != wxString::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsIncluded(const wxString& str) const
|
||||||
|
{
|
||||||
|
if ( HasFlag(wxFILTER_INCLUDE_LIST) )
|
||||||
|
return m_includes.Index(str) != wxNOT_FOUND;
|
||||||
|
|
||||||
|
// m_includes should be ignored (i.e. return true)
|
||||||
|
// if the style is not set.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsExcluded(const wxString& str) const
|
||||||
|
{
|
||||||
|
return m_excludes.Index(str) != wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns false if the character is invalid
|
||||||
|
bool IsValidChar(const wxUniChar& c) const;
|
||||||
|
|
||||||
|
// These two functions (undocumented now) are kept for compatibility reasons.
|
||||||
bool ContainsOnlyIncludedCharacters(const wxString& val) const;
|
bool ContainsOnlyIncludedCharacters(const wxString& val) const;
|
||||||
|
|
||||||
// returns true if at least one character of the given string is present in m_excludes
|
|
||||||
bool ContainsExcludedCharacters(const wxString& val) const;
|
bool ContainsExcludedCharacters(const wxString& val) const;
|
||||||
|
|
||||||
// returns the error message if the contents of 'val' are invalid
|
|
||||||
virtual wxString IsValid(const wxString& val) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
long m_validatorStyle;
|
long m_validatorStyle;
|
||||||
wxString* m_stringValue;
|
wxString* m_stringValue;
|
||||||
|
wxString m_charIncludes;
|
||||||
|
wxString m_charExcludes;
|
||||||
wxArrayString m_includes;
|
wxArrayString m_includes;
|
||||||
wxArrayString m_excludes;
|
wxArrayString m_excludes;
|
||||||
|
|
||||||
|
@@ -9,8 +9,11 @@
|
|||||||
/**
|
/**
|
||||||
Styles used by wxTextValidator.
|
Styles used by wxTextValidator.
|
||||||
|
|
||||||
Note that when you specify more styles in wxTextValidator the validation checks
|
Notice that wxFILTER_EXCLUDE[_CHAR]_LIST pair can be used to document the
|
||||||
are performed in the order in which the styles of this enumeration are defined.
|
purpose of the validator only and are not enforced in the implementation of
|
||||||
|
the wxTextValidator. Therefore, calling the corresponding member functions:
|
||||||
|
wxTextValidator::{SetExcludes,SetCharExcludes}(), is enough to create the
|
||||||
|
desired validator.
|
||||||
*/
|
*/
|
||||||
enum wxTextValidatorStyle
|
enum wxTextValidatorStyle
|
||||||
{
|
{
|
||||||
@@ -33,9 +36,11 @@ enum wxTextValidatorStyle
|
|||||||
/// Non-alphanumeric characters are filtered out.
|
/// Non-alphanumeric characters are filtered out.
|
||||||
/// Uses the wxWidgets wrapper for the standard CRT function @c isalnum
|
/// Uses the wxWidgets wrapper for the standard CRT function @c isalnum
|
||||||
/// (which is locale-dependent) on all characters of the string.
|
/// (which is locale-dependent) on all characters of the string.
|
||||||
|
/// Equivalent to wxFILTER_ALPHA combined with wxFILTER_DIGITS or
|
||||||
|
/// wxFILTER_XDIGITS, or with both of them.
|
||||||
wxFILTER_ALPHANUMERIC,
|
wxFILTER_ALPHANUMERIC,
|
||||||
|
|
||||||
/// Non-numeric characters are filtered out.
|
/// Non-digit characters are filtered out.
|
||||||
/// Uses the wxWidgets wrapper for the standard CRT function @c isdigit
|
/// Uses the wxWidgets wrapper for the standard CRT function @c isdigit
|
||||||
/// (which is locale-dependent) on all characters of the string.
|
/// (which is locale-dependent) on all characters of the string.
|
||||||
wxFILTER_DIGITS,
|
wxFILTER_DIGITS,
|
||||||
@@ -50,19 +55,36 @@ enum wxTextValidatorStyle
|
|||||||
/// the list, complaining if not. See wxTextValidator::SetIncludes().
|
/// the list, complaining if not. See wxTextValidator::SetIncludes().
|
||||||
wxFILTER_INCLUDE_LIST,
|
wxFILTER_INCLUDE_LIST,
|
||||||
|
|
||||||
/// Use an include list. The validator checks if each input character is
|
/// Use an include char list.
|
||||||
/// in the list (one character per list element), complaining if not.
|
/// Characters in the include char list will be allowed to be in the
|
||||||
/// See wxTextValidator::SetCharIncludes().
|
/// user input. See wxTextValidator::SetCharIncludes().
|
||||||
|
/// If this style is set with one or more of the following styles:
|
||||||
|
/// wxFILTER_ASCII, wxFILTER_ALPHA, wxFILTER_ALPHANUMERIC, wxFILTER_DIGITS,
|
||||||
|
/// wxFILTER_XDIGITS, wxFILTER_NUMERIC it just extends the character class
|
||||||
|
/// denoted by the aforementioned styles with those specified in the include
|
||||||
|
/// char list. If set alone, then the charactes allowed to be in the user input
|
||||||
|
/// are restricted to those, and only those, present in the include char list.
|
||||||
wxFILTER_INCLUDE_CHAR_LIST,
|
wxFILTER_INCLUDE_CHAR_LIST,
|
||||||
|
|
||||||
/// Use an exclude list. The validator checks if the user input is on
|
/// Use an exclude list. The validator checks if the user input is on
|
||||||
/// the list, complaining if it is. See wxTextValidator::SetExcludes().
|
/// the list, complaining if it is. See wxTextValidator::SetExcludes().
|
||||||
wxFILTER_EXCLUDE_LIST,
|
wxFILTER_EXCLUDE_LIST,
|
||||||
|
|
||||||
/// Use an exclude list. The validator checks if each input character is
|
/// Use an exclude char list.
|
||||||
/// in the list (one character per list element), complaining if it is.
|
/// Characters in the exclude char list won't be allowed to be in the
|
||||||
/// See wxTextValidator::SetCharExcludes().
|
/// user input. See wxTextValidator::SetCharExcludes().
|
||||||
wxFILTER_EXCLUDE_CHAR_LIST
|
wxFILTER_EXCLUDE_CHAR_LIST,
|
||||||
|
|
||||||
|
/// Non-hexadecimal characters are filtered out.
|
||||||
|
/// Uses the wxWidgets wrapper for the standard CRT function @c isxdigit
|
||||||
|
/// (which is locale-dependent) on all characters of the string.
|
||||||
|
wxFILTER_XDIGITS,
|
||||||
|
|
||||||
|
/// A convenience flag for use with the other flags.
|
||||||
|
/// The space character is more often used with alphanumeric characters
|
||||||
|
/// which makes setting a flag more easier than calling SetCharIncludes(" ")
|
||||||
|
/// for that matter.
|
||||||
|
wxFILTER_SPACE
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +105,7 @@ class wxTextValidator : public wxValidator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Default constructor.
|
Copy constructor.
|
||||||
*/
|
*/
|
||||||
wxTextValidator(const wxTextValidator& validator);
|
wxTextValidator(const wxTextValidator& validator);
|
||||||
|
|
||||||
@@ -106,14 +128,28 @@ public:
|
|||||||
virtual wxObject* Clone() const;
|
virtual wxObject* Clone() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a reference to the exclude list (the list of invalid values).
|
Returns a copy of the exclude char list (the list of invalid characters).
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
*/
|
*/
|
||||||
wxArrayString& GetExcludes();
|
wxString GetCharExcludes() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns a reference to the include list (the list of valid values).
|
Returns a copy of the include char list (the list of additional valid characters).
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
*/
|
*/
|
||||||
wxArrayString& GetIncludes();
|
wxString GetCharIncludes() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a const reference to the exclude list (the list of invalid values).
|
||||||
|
*/
|
||||||
|
const wxArrayString& GetExcludes() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a const reference to the include list (the list of valid values).
|
||||||
|
*/
|
||||||
|
const wxArrayString& GetIncludes() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the validator style.
|
Returns the validator style.
|
||||||
@@ -135,41 +171,81 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the exclude list (invalid values for the user input).
|
Sets the exclude list (invalid values for the user input).
|
||||||
|
|
||||||
|
@note Beware that exclusion takes priority over inclusion.
|
||||||
*/
|
*/
|
||||||
void SetExcludes(const wxArrayString& stringList);
|
void SetExcludes(const wxArrayString& stringList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Breaks the given @a chars strings in single characters and sets the
|
Sets the exclude char list (invalid characters for the user input).
|
||||||
internal wxArrayString used to store the "excluded" characters
|
|
||||||
(see SetExcludes()).
|
|
||||||
|
|
||||||
This function is mostly useful when @c wxFILTER_EXCLUDE_CHAR_LIST was used.
|
@note Beware that exclusion takes priority over inclusion.
|
||||||
|
@note This function may cancel the effect of @c wxFILTER_SPACE if the passed
|
||||||
|
in string @a chars contains the @b space character.
|
||||||
*/
|
*/
|
||||||
void SetCharExcludes(const wxString& chars);
|
void SetCharExcludes(const wxString& chars);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the include list (valid values for the user input).
|
Sets the include list (valid values for the user input).
|
||||||
|
|
||||||
|
@see IsIncluded()
|
||||||
*/
|
*/
|
||||||
void SetIncludes(const wxArrayString& stringList);
|
void SetIncludes(const wxArrayString& stringList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Breaks the given @a chars strings in single characters and sets the
|
Sets the include char list (additional valid values for the user input).
|
||||||
internal wxArrayString used to store the "included" characters
|
|
||||||
(see SetIncludes()).
|
|
||||||
|
|
||||||
This function is mostly useful when @c wxFILTER_INCLUDE_CHAR_LIST was used.
|
@note Any explicitly excluded characters will still be excluded even if
|
||||||
|
they're part of @a chars.
|
||||||
*/
|
*/
|
||||||
void SetCharIncludes(const wxString& chars);
|
void SetCharIncludes(const wxString& chars);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds @a exclude to the list of excluded values.
|
||||||
|
|
||||||
|
@note Beware that exclusion takes priority over inclusion.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
void AddExclude(const wxString& exclude);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds @a include to the list of included values.
|
||||||
|
|
||||||
|
@note Any explicitly excluded characters will still be excluded.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
void AddInclude(const wxString& include);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds @a chars to the list of excluded characters.
|
||||||
|
|
||||||
|
@note Beware that exclusion takes priority over inclusion.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
void AddCharExcludes(const wxString& chars);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds @a chars to the list of included characters.
|
||||||
|
|
||||||
|
@note Any explicitly excluded characters will still be excluded even if
|
||||||
|
they're part of @a chars.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
void AddCharIncludes(const wxString& chars);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the validator style which must be a combination of one or more
|
Sets the validator style which must be a combination of one or more
|
||||||
of the ::wxTextValidatorStyle values.
|
of the ::wxTextValidatorStyle values.
|
||||||
|
|
||||||
Note that not all possible combinations make sense!
|
Note that not all possible combinations make sense! Also, some
|
||||||
Also note that the order in which the checks are performed is important,
|
combinations have shorter and more idiomatic alternative, e.g.
|
||||||
in case you specify more than a single style.
|
@c wxFILTER_ALPHANUMERIC can be used instead of
|
||||||
wxTextValidator will perform the checks in the same definition order
|
@c wxFILTER_ALPHA|wxFILTER_DIGITS.
|
||||||
used in the ::wxTextValidatorStyle enumeration.
|
|
||||||
*/
|
*/
|
||||||
void SetStyle(long style);
|
void SetStyle(long style);
|
||||||
|
|
||||||
@@ -189,24 +265,52 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool Validate(wxWindow* parent);
|
virtual bool Validate(wxWindow* parent);
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns @true if all the characters of the given @a val string
|
|
||||||
are present in the include list (set by SetIncludes() or SetCharIncludes()).
|
|
||||||
*/
|
|
||||||
bool ContainsOnlyIncludedCharacters(const wxString& val) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns true if at least one character of the given @a val string
|
|
||||||
is present in the exclude list (set by SetExcludes() or SetCharExcludes()).
|
|
||||||
*/
|
|
||||||
bool ContainsExcludedCharacters(const wxString& val) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the error message if the contents of @a val are invalid
|
Returns the error message if the contents of @a val are invalid
|
||||||
or the empty string if @a val is valid.
|
or the empty string if @a val is valid.
|
||||||
*/
|
*/
|
||||||
virtual wxString IsValid(const wxString& val) const;
|
virtual wxString IsValid(const wxString& val) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if the char @a c is allowed to be in the user input string.
|
||||||
|
Additional characters, set by SetCharIncludes() or AddCharIncludes() are
|
||||||
|
also considered.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
bool IsCharIncluded(const wxUniChar& c) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if the char @a c is not allowed to be in the user input string.
|
||||||
|
(characters set by SetCharExcludes() or AddCharExcludes()).
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
bool IsCharExcluded(const wxUniChar& c) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if the string @a str is one of the includes strings set by
|
||||||
|
SetIncludes() or AddInclude().
|
||||||
|
|
||||||
|
Notice that unless wxFILTER_INCLUDE_LIST is specified (in which case the
|
||||||
|
validator will complain if the user input is not on the list), the list
|
||||||
|
will be ignored and won't participate in the validation process.
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
bool IsIncluded(const wxString& str) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if the string @a str is one of the excludes strings set by
|
||||||
|
SetExcludes() or AddExclude().
|
||||||
|
|
||||||
|
@since 3.1.3
|
||||||
|
*/
|
||||||
|
bool IsExcluded(const wxString& str) const;
|
||||||
|
|
||||||
|
/// Returns false if the character @a c is invalid.
|
||||||
|
bool IsValidChar(const wxUniChar& c) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -650,16 +650,12 @@ wxValidator* wxArrayDoubleProperty::DoGetValidator() const
|
|||||||
#if wxUSE_VALIDATORS
|
#if wxUSE_VALIDATORS
|
||||||
WX_PG_DOGETVALIDATOR_ENTRY()
|
WX_PG_DOGETVALIDATOR_ENTRY()
|
||||||
|
|
||||||
wxTextValidator* validator = new wxTextValidator(wxFILTER_INCLUDE_CHAR_LIST);
|
wxTextValidator* validator =
|
||||||
|
new wxNumericPropertyValidator(wxNumericPropertyValidator::Float);
|
||||||
|
|
||||||
// Accept characters for numeric elements
|
|
||||||
wxNumericPropertyValidator numValidator(wxNumericPropertyValidator::Float);
|
|
||||||
wxArrayString incChars(numValidator.GetIncludes());
|
|
||||||
// Accept also a delimiter and space character
|
// Accept also a delimiter and space character
|
||||||
incChars.Add(m_delimiter);
|
validator->AddCharIncludes(m_delimiter);
|
||||||
incChars.Add(" ");
|
validator->AddCharIncludes(" ");
|
||||||
|
|
||||||
validator->SetIncludes(incChars);
|
|
||||||
|
|
||||||
WX_PG_DOGETVALIDATOR_EXIT(validator)
|
WX_PG_DOGETVALIDATOR_EXIT(validator)
|
||||||
#else
|
#else
|
||||||
|
@@ -40,8 +40,6 @@
|
|||||||
// Global data
|
// Global data
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
MyData g_data;
|
|
||||||
|
|
||||||
wxString g_listbox_choices[] =
|
wxString g_listbox_choices[] =
|
||||||
{"one", "two", "three"};
|
{"one", "two", "three"};
|
||||||
|
|
||||||
@@ -51,6 +49,8 @@ wxString g_combobox_choices[] =
|
|||||||
wxString g_radiobox_choices[] =
|
wxString g_radiobox_choices[] =
|
||||||
{"green", "yellow", "red"};
|
{"green", "yellow", "red"};
|
||||||
|
|
||||||
|
MyData g_data;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// MyData
|
// MyData
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -63,6 +63,7 @@ MyData::MyData()
|
|||||||
m_string = "Spaces are invalid here";
|
m_string = "Spaces are invalid here";
|
||||||
m_string2 = "Valid text";
|
m_string2 = "Valid text";
|
||||||
m_listbox_choices.Add(0);
|
m_listbox_choices.Add(0);
|
||||||
|
m_combobox_choice = g_combobox_choices[0];
|
||||||
m_intValue = 0;
|
m_intValue = 0;
|
||||||
m_smallIntValue = 3;
|
m_smallIntValue = 3;
|
||||||
m_doubleValue = 12354.31;
|
m_doubleValue = 12354.31;
|
||||||
@@ -247,28 +248,19 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
|
|||||||
|
|
||||||
wxFlexGridSizer *flexgridsizer = new wxFlexGridSizer(3, 2, 5, 5);
|
wxFlexGridSizer *flexgridsizer = new wxFlexGridSizer(3, 2, 5, 5);
|
||||||
|
|
||||||
// Create and add controls to sizers. Note that a member variable
|
// Create and add controls to sizers.
|
||||||
// of g_data is bound to each control upon construction. There is
|
|
||||||
// currently no easy way to substitute a different validator or a
|
|
||||||
// different transfer variable after a control has been constructed.
|
|
||||||
|
|
||||||
// Pointers to some of these controls are saved in member variables
|
// Pointers to some of these controls are saved in member variables
|
||||||
// so that we can use them elsewhere, like this one.
|
// so that we can use them elsewhere, like this one.
|
||||||
m_text = new wxTextCtrl(this, VALIDATE_TEXT, wxEmptyString,
|
m_text = new wxTextCtrl(this, VALIDATE_TEXT);
|
||||||
wxDefaultPosition, wxDefaultSize, 0,
|
m_text->SetToolTip("wxTextValidator not set");
|
||||||
wxTextValidator(wxFILTER_ALPHA, &g_data.m_string));
|
m_text->SetHint("Enter some text here, please...");
|
||||||
m_text->SetToolTip("uses wxTextValidator with wxFILTER_ALPHA");
|
|
||||||
flexgridsizer->Add(m_text, 1, wxGROW);
|
flexgridsizer->Add(m_text, 1, wxGROW);
|
||||||
|
|
||||||
|
// Make it possible to change the wxTextValidator for m_text at runtime.
|
||||||
// Now set a wxTextValidator with an explicit list of characters NOT allowed:
|
wxButton* const button =
|
||||||
wxTextValidator textVal(wxFILTER_EMPTY|wxFILTER_EXCLUDE_CHAR_LIST, &g_data.m_string2);
|
new wxButton(this, wxID_ANY, "Set new wxTextValidator...");
|
||||||
textVal.SetCharExcludes("bcwyz");
|
button->Bind(wxEVT_BUTTON, &MyDialog::OnChangeValidator, this);
|
||||||
wxTextCtrl* txt2 =
|
flexgridsizer->Add(button, wxSizerFlags().Center());
|
||||||
new wxTextCtrl(this, VALIDATE_TEXT2, wxEmptyString,
|
|
||||||
wxDefaultPosition, wxDefaultSize, 0, textVal);
|
|
||||||
txt2->SetToolTip("uses wxTextValidator with wxFILTER_EMPTY|wxFILTER_EXCLUDE_CHAR_LIST to exclude 'bcwyz'");
|
|
||||||
flexgridsizer->Add(txt2, 1, wxGROW);
|
|
||||||
|
|
||||||
flexgridsizer->Add(new wxListBox((wxWindow*)this, VALIDATE_LIST,
|
flexgridsizer->Add(new wxListBox((wxWindow*)this, VALIDATE_LIST,
|
||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
@@ -391,17 +383,298 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
|
|||||||
|
|
||||||
// make the dialog a bit bigger than its minimal size:
|
// make the dialog a bit bigger than its minimal size:
|
||||||
SetSize(GetBestSize()*1.5);
|
SetSize(GetBestSize()*1.5);
|
||||||
}
|
|
||||||
|
|
||||||
bool MyDialog::TransferDataToWindow()
|
// Now sets the focus to m_text
|
||||||
{
|
|
||||||
bool r = wxDialog::TransferDataToWindow();
|
|
||||||
|
|
||||||
// These function calls have to be made here, after the
|
|
||||||
// dialog has been created.
|
|
||||||
m_text->SetFocus();
|
m_text->SetFocus();
|
||||||
m_combobox->SetSelection(0);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyDialog::OnChangeValidator(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
TextValidatorDialog dialog(this, m_text);
|
||||||
|
|
||||||
|
if ( dialog.ShowModal() == wxID_OK )
|
||||||
|
{
|
||||||
|
dialog.ApplyValidator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// TextValidatorDialog
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TextValidatorDialog::TextValidatorDialog(wxWindow *parent, wxTextCtrl* txtCtrl)
|
||||||
|
: wxDialog(parent, wxID_ANY, "wxTextValidator Dialog"),
|
||||||
|
m_txtCtrl(txtCtrl),
|
||||||
|
m_noValidation(true),
|
||||||
|
m_validatorStyle(wxFILTER_NONE)
|
||||||
|
{
|
||||||
|
if ( m_txtCtrl )
|
||||||
|
{
|
||||||
|
wxTextValidator* txtValidator =
|
||||||
|
wxDynamicCast(m_txtCtrl->GetValidator(), wxTextValidator);
|
||||||
|
|
||||||
|
if ( txtValidator )
|
||||||
|
{
|
||||||
|
m_validatorStyle = txtValidator->GetStyle();
|
||||||
|
|
||||||
|
if ( m_validatorStyle != wxFILTER_NONE )
|
||||||
|
m_noValidation = false;
|
||||||
|
|
||||||
|
m_charIncludes = txtValidator->GetCharIncludes();
|
||||||
|
m_charExcludes = txtValidator->GetCharExcludes();
|
||||||
|
m_includes = txtValidator->GetIncludes();
|
||||||
|
m_excludes = txtValidator->GetExcludes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFlexGridSizer *fgSizer = new wxFlexGridSizer(2, FromDIP(wxSize(5, 5)));
|
||||||
|
const wxSizerFlags center = wxSizerFlags().CenterVertical();
|
||||||
|
|
||||||
|
const StyleValidator styleVal(&m_validatorStyle);
|
||||||
|
|
||||||
|
wxCheckBox* filterNone = new wxCheckBox(this, Id_None, "wxFILTER_NONE");
|
||||||
|
filterNone->SetValue(m_noValidation);
|
||||||
|
fgSizer->Add(filterNone);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "No filtering takes place."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Empty, "wxFILTER_EMPTY"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Empty strings are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Ascii, "wxFILTER_ASCII"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Non-ASCII characters are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Alpha, "wxFILTER_ALPHA"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Non-alpha characters are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Alphanumeric, "wxFILTER_ALPHANUMERIC"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Non-alphanumeric characters are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Digits, "wxFILTER_DIGITS"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Non-digit characters are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Numeric, "wxFILTER_NUMERIC"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Non-numeric characters are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_IncludeList, "wxFILTER_INCLUDE_LIST"), center)
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxTextCtrl(this, Id_IncludeListTxt), wxSizerFlags().Expand())
|
||||||
|
->GetWindow()->Bind(wxEVT_KILL_FOCUS, &TextValidatorDialog::OnKillFocus, this);
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_IncludeCharList, "wxFILTER_INCLUDE_CHAR_LIST"), center)
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxTextCtrl(this, Id_IncludeCharListTxt, wxString(), wxDefaultPosition,
|
||||||
|
wxDefaultSize, 0, wxGenericValidator(&m_charIncludes)),
|
||||||
|
wxSizerFlags().Expand())
|
||||||
|
->GetWindow()->Bind(wxEVT_KILL_FOCUS, &TextValidatorDialog::OnKillFocus, this);
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_ExcludeList, "wxFILTER_EXCLUDE_LIST"), center)
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxTextCtrl(this, Id_ExcludeListTxt), wxSizerFlags().Expand())
|
||||||
|
->GetWindow()->Bind(wxEVT_KILL_FOCUS, &TextValidatorDialog::OnKillFocus, this);
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_ExcludeCharList, "wxFILTER_EXCLUDE_CHAR_LIST"), center)
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxTextCtrl(this, Id_ExcludeCharListTxt, wxString(), wxDefaultPosition,
|
||||||
|
wxDefaultSize, 0, wxGenericValidator(&m_charExcludes)),
|
||||||
|
wxSizerFlags().Expand())
|
||||||
|
->GetWindow()->Bind(wxEVT_KILL_FOCUS, &TextValidatorDialog::OnKillFocus, this);
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Xdigits, "wxFILTER_XDIGITS"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Non-xdigit characters are filtered out."));
|
||||||
|
|
||||||
|
fgSizer->Add(new wxCheckBox(this, Id_Space, "wxFILTER_SPACE"))
|
||||||
|
->GetWindow()->SetValidator(styleVal);
|
||||||
|
fgSizer->Add(new wxStaticText(this, wxID_ANY, "Allow spaces."));
|
||||||
|
|
||||||
|
// Set the main sizer.
|
||||||
|
wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
mainsizer->Add(fgSizer, wxSizerFlags(1).Border(wxALL, 10).Expand());
|
||||||
|
|
||||||
|
mainsizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
|
||||||
|
wxSizerFlags().Expand().DoubleBorder());
|
||||||
|
|
||||||
|
SetSizer(mainsizer);
|
||||||
|
mainsizer->SetSizeHints(this);
|
||||||
|
|
||||||
|
// Bind event handlers.
|
||||||
|
Bind(wxEVT_CHECKBOX, &TextValidatorDialog::OnChecked, this);
|
||||||
|
Bind(wxEVT_UPDATE_UI, &TextValidatorDialog::OnUpdateUI,
|
||||||
|
this, Id_Ascii, Id_ExcludeCharListTxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextValidatorDialog::OnUpdateUI(wxUpdateUIEvent& event)
|
||||||
|
{
|
||||||
|
event.Enable(!m_noValidation);
|
||||||
|
|
||||||
|
if ( m_noValidation )
|
||||||
|
event.Check(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextValidatorDialog::OnChecked(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
if ( event.GetId() == Id_None )
|
||||||
|
{
|
||||||
|
m_noValidation = event.IsChecked();
|
||||||
|
|
||||||
|
if ( m_noValidation )
|
||||||
|
{
|
||||||
|
long style = wxFILTER_NONE;
|
||||||
|
|
||||||
|
// we should keep this flag on if it has been set.
|
||||||
|
if ( HasFlag(wxFILTER_EMPTY) )
|
||||||
|
style = wxFILTER_EMPTY;
|
||||||
|
|
||||||
|
m_validatorStyle = style;
|
||||||
|
|
||||||
|
m_charIncludes.clear();
|
||||||
|
m_charExcludes.clear();
|
||||||
|
m_includes.clear();
|
||||||
|
m_excludes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextValidatorDialog::OnKillFocus(wxFocusEvent &event)
|
||||||
|
{
|
||||||
|
wxTextCtrl* txtCtrl = wxDynamicCast(event.GetEventObject(), wxTextCtrl);
|
||||||
|
|
||||||
|
if ( txtCtrl && txtCtrl->IsModified() )
|
||||||
|
{
|
||||||
|
const int id = event.GetId();
|
||||||
|
|
||||||
|
if ( id == Id_IncludeCharListTxt )
|
||||||
|
{
|
||||||
|
m_charIncludes = txtCtrl->GetValue();
|
||||||
|
}
|
||||||
|
else if ( id == Id_ExcludeCharListTxt )
|
||||||
|
{
|
||||||
|
m_charExcludes = txtCtrl->GetValue();
|
||||||
|
}
|
||||||
|
else if ( id == Id_IncludeListTxt )
|
||||||
|
{
|
||||||
|
m_includes = wxSplit(txtCtrl->GetValue(), ' ');
|
||||||
|
}
|
||||||
|
else if ( id == Id_ExcludeListTxt )
|
||||||
|
{
|
||||||
|
m_excludes = wxSplit(txtCtrl->GetValue(), ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextValidatorDialog::ApplyValidator()
|
||||||
|
{
|
||||||
|
if ( !m_txtCtrl )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString tooltip = "uses wxTextValidator with ";
|
||||||
|
|
||||||
|
if ( m_noValidation )
|
||||||
|
{
|
||||||
|
tooltip += "wxFILTER_NONE|";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( HasFlag(wxFILTER_ASCII) )
|
||||||
|
tooltip += "wxFILTER_ASCII|";
|
||||||
|
if ( HasFlag(wxFILTER_ALPHA) )
|
||||||
|
tooltip += "wxFILTER_ALPHA|";
|
||||||
|
if ( HasFlag(wxFILTER_ALPHANUMERIC) )
|
||||||
|
tooltip += "wxFILTER_ALPHANUMERIC|";
|
||||||
|
if ( HasFlag(wxFILTER_DIGITS) )
|
||||||
|
tooltip += "wxFILTER_DIGITS|";
|
||||||
|
if ( HasFlag(wxFILTER_NUMERIC) )
|
||||||
|
tooltip += "wxFILTER_NUMERIC|";
|
||||||
|
if ( HasFlag(wxFILTER_XDIGITS) )
|
||||||
|
tooltip += "wxFILTER_XDIGITS|";
|
||||||
|
if ( HasFlag(wxFILTER_SPACE) )
|
||||||
|
tooltip += "wxFILTER_SPACE|";
|
||||||
|
if ( HasFlag(wxFILTER_INCLUDE_LIST) )
|
||||||
|
tooltip += "wxFILTER_INCLUDE_LIST|";
|
||||||
|
if ( HasFlag(wxFILTER_INCLUDE_CHAR_LIST) )
|
||||||
|
tooltip += "wxFILTER_INCLUDE_CHAR_LIST|";
|
||||||
|
if ( HasFlag(wxFILTER_EXCLUDE_LIST) )
|
||||||
|
tooltip += "wxFILTER_EXCLUDE_LIST|";
|
||||||
|
if ( HasFlag(wxFILTER_EXCLUDE_CHAR_LIST) )
|
||||||
|
tooltip += "wxFILTER_EXCLUDE_CHAR_LIST|";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( HasFlag(wxFILTER_EMPTY) )
|
||||||
|
{
|
||||||
|
tooltip += "wxFILTER_EMPTY|";
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip.RemoveLast(); // remove the trailing '|' char.
|
||||||
|
|
||||||
|
if ( !m_charIncludes.empty() )
|
||||||
|
{
|
||||||
|
tooltip += "\nAllowed chars: ";
|
||||||
|
tooltip += m_charIncludes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !m_charExcludes.empty() )
|
||||||
|
{
|
||||||
|
tooltip += "\nDisallowed chars: ";
|
||||||
|
tooltip += m_charExcludes;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_txtCtrl->SetToolTip(tooltip);
|
||||||
|
|
||||||
|
// Prepare and set the wxTextValidator
|
||||||
|
wxTextValidator txtVal(m_validatorStyle, &g_data.m_string);
|
||||||
|
txtVal.SetCharIncludes(m_charIncludes);
|
||||||
|
txtVal.SetCharExcludes(m_charExcludes);
|
||||||
|
txtVal.SetIncludes(m_includes);
|
||||||
|
txtVal.SetExcludes(m_excludes);
|
||||||
|
|
||||||
|
m_txtCtrl->SetValidator(txtVal);
|
||||||
|
m_txtCtrl->SetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextValidatorDialog::StyleValidator::TransferToWindow()
|
||||||
|
{
|
||||||
|
wxASSERT( wxDynamicCast(m_validatorWindow, wxCheckBox) );
|
||||||
|
|
||||||
|
if ( m_style )
|
||||||
|
{
|
||||||
|
wxCheckBox* cb = (wxCheckBox*)GetWindow();
|
||||||
|
if ( !cb )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const long style = 1 << (cb->GetId()-wxID_HIGHEST-1);
|
||||||
|
|
||||||
|
cb->SetValue((*m_style & style) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextValidatorDialog::StyleValidator::TransferFromWindow()
|
||||||
|
{
|
||||||
|
wxASSERT( wxDynamicCast(m_validatorWindow, wxCheckBox) );
|
||||||
|
|
||||||
|
if ( m_style )
|
||||||
|
{
|
||||||
|
wxCheckBox* cb = (wxCheckBox*)GetWindow();
|
||||||
|
if ( !cb )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const long style = 1 << (cb->GetId()-wxID_HIGHEST-1);
|
||||||
|
|
||||||
|
if ( cb->IsChecked() )
|
||||||
|
*m_style |= style;
|
||||||
|
else
|
||||||
|
*m_style &= ~style;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@@ -48,7 +48,8 @@ public:
|
|||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
const long style = wxDEFAULT_DIALOG_STYLE);
|
const long style = wxDEFAULT_DIALOG_STYLE);
|
||||||
|
|
||||||
bool TransferDataToWindow() wxOVERRIDE;
|
void OnChangeValidator(wxCommandEvent& event);
|
||||||
|
|
||||||
wxTextCtrl *m_text;
|
wxTextCtrl *m_text;
|
||||||
wxComboBox *m_combobox;
|
wxComboBox *m_combobox;
|
||||||
|
|
||||||
@@ -56,6 +57,81 @@ public:
|
|||||||
wxTextCtrl *m_numericTextDouble;
|
wxTextCtrl *m_numericTextDouble;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// TextValidatorDialog
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
class TextValidatorDialog : public wxDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextValidatorDialog(wxWindow *parent, wxTextCtrl* txtCtrl);
|
||||||
|
|
||||||
|
void OnUpdateUI(wxUpdateUIEvent& event);
|
||||||
|
void OnChecked(wxCommandEvent& event);
|
||||||
|
void OnKillFocus( wxFocusEvent &event );
|
||||||
|
|
||||||
|
void ApplyValidator();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Special validator for our checkboxes
|
||||||
|
class StyleValidator : public wxValidator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StyleValidator(long* style) { m_style = style; }
|
||||||
|
|
||||||
|
virtual bool Validate(wxWindow *WXUNUSED(parent)) wxOVERRIDE { return true; }
|
||||||
|
virtual wxObject* Clone() const wxOVERRIDE { return new StyleValidator(*this); }
|
||||||
|
|
||||||
|
// Called to transfer data to the window
|
||||||
|
virtual bool TransferToWindow() wxOVERRIDE;
|
||||||
|
|
||||||
|
// Called to transfer data from the window
|
||||||
|
virtual bool TransferFromWindow() wxOVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
long* m_style;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool HasFlag(wxTextValidatorStyle style) const
|
||||||
|
{
|
||||||
|
return (m_validatorStyle & style) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// CheckBoxes Ids (should be in sync with wxTextValidatorStyle)
|
||||||
|
Id_None = wxID_HIGHEST,
|
||||||
|
Id_Empty,
|
||||||
|
Id_Ascii,
|
||||||
|
Id_Alpha,
|
||||||
|
Id_Alphanumeric,
|
||||||
|
Id_Digits,
|
||||||
|
Id_Numeric,
|
||||||
|
Id_IncludeList,
|
||||||
|
Id_IncludeCharList,
|
||||||
|
Id_ExcludeList,
|
||||||
|
Id_ExcludeCharList,
|
||||||
|
Id_Xdigits,
|
||||||
|
Id_Space,
|
||||||
|
|
||||||
|
// TextCtrls Ids
|
||||||
|
Id_IncludeListTxt,
|
||||||
|
Id_IncludeCharListTxt,
|
||||||
|
Id_ExcludeListTxt,
|
||||||
|
Id_ExcludeCharListTxt,
|
||||||
|
};
|
||||||
|
|
||||||
|
wxTextCtrl* const m_txtCtrl;
|
||||||
|
|
||||||
|
bool m_noValidation;
|
||||||
|
long m_validatorStyle;
|
||||||
|
|
||||||
|
wxString m_charIncludes;
|
||||||
|
wxString m_charExcludes;
|
||||||
|
wxArrayString m_includes;
|
||||||
|
wxArrayString m_excludes;
|
||||||
|
};
|
||||||
|
|
||||||
class MyData
|
class MyData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "wx/textctrl.h"
|
#include "wx/textctrl.h"
|
||||||
#include "wx/combobox.h"
|
#include "wx/combobox.h"
|
||||||
|
#include "wx/log.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/msgdlg.h"
|
#include "wx/msgdlg.h"
|
||||||
#include "wx/intl.h"
|
#include "wx/intl.h"
|
||||||
@@ -76,25 +77,6 @@ wxTextValidator::wxTextValidator(const wxTextValidator& val)
|
|||||||
void wxTextValidator::SetStyle(long style)
|
void wxTextValidator::SetStyle(long style)
|
||||||
{
|
{
|
||||||
m_validatorStyle = style;
|
m_validatorStyle = style;
|
||||||
|
|
||||||
#if wxDEBUG_LEVEL
|
|
||||||
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 // wxDEBUG_LEVEL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTextValidator::Copy(const wxTextValidator& val)
|
bool wxTextValidator::Copy(const wxTextValidator& val)
|
||||||
@@ -104,6 +86,8 @@ bool wxTextValidator::Copy(const wxTextValidator& val)
|
|||||||
m_validatorStyle = val.m_validatorStyle;
|
m_validatorStyle = val.m_validatorStyle;
|
||||||
m_stringValue = val.m_stringValue;
|
m_stringValue = val.m_stringValue;
|
||||||
|
|
||||||
|
m_charIncludes = val.m_charIncludes;
|
||||||
|
m_charExcludes = val.m_charExcludes;
|
||||||
m_includes = val.m_includes;
|
m_includes = val.m_includes;
|
||||||
m_excludes = val.m_excludes;
|
m_excludes = val.m_excludes;
|
||||||
|
|
||||||
@@ -153,25 +137,7 @@ bool wxTextValidator::Validate(wxWindow *parent)
|
|||||||
if ( !text )
|
if ( !text )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wxString val(text->GetValue());
|
const wxString& errormsg = IsValid(text->GetValue());
|
||||||
|
|
||||||
wxString errormsg;
|
|
||||||
|
|
||||||
// We can only do some kinds of validation once the input is complete, so
|
|
||||||
// check for them here:
|
|
||||||
if ( HasFlag(wxFILTER_EMPTY) && val.empty() )
|
|
||||||
errormsg = _("Required information entry is empty.");
|
|
||||||
else if ( HasFlag(wxFILTER_INCLUDE_LIST) && m_includes.Index(val) == wxNOT_FOUND )
|
|
||||||
errormsg = wxString::Format(_("'%s' is not one of the valid strings"), val);
|
|
||||||
else if ( HasFlag(wxFILTER_EXCLUDE_LIST) && m_excludes.Index(val) != wxNOT_FOUND )
|
|
||||||
errormsg = wxString::Format(_("'%s' is one of the invalid strings"), val);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !errormsg.empty() )
|
if ( !errormsg.empty() )
|
||||||
{
|
{
|
||||||
@@ -215,89 +181,98 @@ bool wxTextValidator::TransferFromWindow()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRIX mipsPro refuses to compile wxStringCheck<func>() if func is inline so
|
wxString wxTextValidator::IsValid(const wxString& str) const
|
||||||
// let's work around this by using this non-template function instead of
|
|
||||||
// wxStringCheck(). And while this might be fractionally less efficient because
|
|
||||||
// the function call won't be inlined like this, we don't care enough about
|
|
||||||
// this to add extra #ifs for non-IRIX case.
|
|
||||||
namespace
|
|
||||||
{
|
{
|
||||||
|
if ( HasFlag(wxFILTER_EMPTY) && str.empty() )
|
||||||
|
return _("Required information entry is empty.");
|
||||||
|
else if ( IsExcluded(str) )
|
||||||
|
return wxString::Format(_("'%s' is one of the invalid strings"), str);
|
||||||
|
else if ( !IsIncluded(str) )
|
||||||
|
return wxString::Format(_("'%s' is not one of the valid strings"), str);
|
||||||
|
|
||||||
bool CheckString(bool (*func)(const wxUniChar&), const wxString& str)
|
// check the whole string for invalid chars.
|
||||||
|
for ( wxString::const_iterator i = str.begin(), end = str.end();
|
||||||
|
i != end; ++i )
|
||||||
{
|
{
|
||||||
for ( wxString::const_iterator i = str.begin(); i != str.end(); ++i )
|
if ( !IsValidChar(*i) )
|
||||||
{
|
{
|
||||||
if ( !func(*i) )
|
return wxString::Format(
|
||||||
return false;
|
_("'%s' contains invalid character(s)"), str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return wxString();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
wxString wxTextValidator::IsValid(const wxString& val) const
|
|
||||||
{
|
|
||||||
// wxFILTER_EMPTY is checked for in wxTextValidator::Validate
|
|
||||||
|
|
||||||
if ( HasFlag(wxFILTER_ASCII) && !val.IsAscii() )
|
|
||||||
return _("'%s' should only contain ASCII characters.");
|
|
||||||
if ( HasFlag(wxFILTER_ALPHA) && !CheckString(wxIsalpha, val) )
|
|
||||||
return _("'%s' should only contain alphabetic characters.");
|
|
||||||
if ( HasFlag(wxFILTER_ALPHANUMERIC) && !CheckString(wxIsalnum, val) )
|
|
||||||
return _("'%s' should only contain alphabetic or numeric characters.");
|
|
||||||
if ( HasFlag(wxFILTER_DIGITS) && !CheckString(wxIsdigit, val) )
|
|
||||||
return _("'%s' should only contain digits.");
|
|
||||||
if ( HasFlag(wxFILTER_NUMERIC) && !wxIsNumeric(val) )
|
|
||||||
return _("'%s' should be numeric.");
|
|
||||||
if ( HasFlag(wxFILTER_INCLUDE_CHAR_LIST) && !ContainsOnlyIncludedCharacters(val) )
|
|
||||||
return _("'%s' doesn't consist only of valid characters");
|
|
||||||
if ( HasFlag(wxFILTER_EXCLUDE_CHAR_LIST) && ContainsExcludedCharacters(val) )
|
|
||||||
return _("'%s' contains illegal characters");
|
|
||||||
|
|
||||||
return wxEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxTextValidator::ContainsOnlyIncludedCharacters(const wxString& val) const
|
|
||||||
{
|
|
||||||
for ( wxString::const_iterator i = val.begin(); i != val.end(); ++i )
|
|
||||||
if (m_includes.Index((wxString) *i) == wxNOT_FOUND)
|
|
||||||
// one character of 'val' is NOT present in m_includes...
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// all characters of 'val' are present in m_includes
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxTextValidator::ContainsExcludedCharacters(const wxString& val) const
|
|
||||||
{
|
|
||||||
for ( wxString::const_iterator i = val.begin(); i != val.end(); ++i )
|
|
||||||
if (m_excludes.Index((wxString) *i) != wxNOT_FOUND)
|
|
||||||
// one character of 'val' is present in m_excludes...
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// all characters of 'val' are NOT present in m_excludes
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxTextValidator::SetCharIncludes(const wxString& chars)
|
void wxTextValidator::SetCharIncludes(const wxString& chars)
|
||||||
{
|
{
|
||||||
wxArrayString arr;
|
m_charIncludes.clear();
|
||||||
|
|
||||||
for ( wxString::const_iterator i = chars.begin(); i != chars.end(); ++i )
|
AddCharIncludes(chars);
|
||||||
arr.Add(*i);
|
}
|
||||||
|
|
||||||
SetIncludes(arr);
|
void wxTextValidator::AddCharIncludes(const wxString& chars)
|
||||||
|
{
|
||||||
|
m_charIncludes += chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextValidator::SetCharExcludes(const wxString& chars)
|
void wxTextValidator::SetCharExcludes(const wxString& chars)
|
||||||
{
|
{
|
||||||
wxArrayString arr;
|
m_charExcludes.clear();
|
||||||
|
|
||||||
for ( wxString::const_iterator i = chars.begin(); i != chars.end(); ++i )
|
AddCharExcludes(chars);
|
||||||
arr.Add(*i);
|
}
|
||||||
|
|
||||||
SetExcludes(arr);
|
void wxTextValidator::AddCharExcludes(const wxString& chars)
|
||||||
|
{
|
||||||
|
m_charExcludes += chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextValidator::SetIncludes(const wxArrayString& includes)
|
||||||
|
{
|
||||||
|
// preserve compatibily with versions prior 3.1.3 which used m_includes
|
||||||
|
// to store the list of char includes.
|
||||||
|
if ( HasFlag(wxFILTER_INCLUDE_CHAR_LIST) )
|
||||||
|
{
|
||||||
|
for ( wxArrayString::const_iterator i = includes.begin(),
|
||||||
|
end = includes.end(); i != end; ++i )
|
||||||
|
{
|
||||||
|
AddCharIncludes(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_includes = includes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextValidator::AddInclude(const wxString& include)
|
||||||
|
{
|
||||||
|
m_includes.push_back(include);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextValidator::SetExcludes(const wxArrayString& excludes)
|
||||||
|
{
|
||||||
|
// preserve compatibily with versions prior 3.1.3 which used m_excludes
|
||||||
|
// to store the list of char excludes.
|
||||||
|
if ( HasFlag(wxFILTER_EXCLUDE_CHAR_LIST) )
|
||||||
|
{
|
||||||
|
for ( wxArrayString::const_iterator i = excludes.begin(),
|
||||||
|
end = excludes.end(); i != end; ++i )
|
||||||
|
{
|
||||||
|
AddCharExcludes(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_excludes = excludes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextValidator::AddExclude(const wxString& exclude)
|
||||||
|
{
|
||||||
|
m_excludes.push_back(exclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextValidator::OnChar(wxKeyEvent& event)
|
void wxTextValidator::OnChar(wxKeyEvent& event)
|
||||||
@@ -321,8 +296,8 @@ void wxTextValidator::OnChar(wxKeyEvent& event)
|
|||||||
if (keyCode < WXK_SPACE || keyCode == WXK_DELETE)
|
if (keyCode < WXK_SPACE || keyCode == WXK_DELETE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxString str((wxUniChar)keyCode, 1);
|
// Filter out invalid characters
|
||||||
if (IsValid(str).empty())
|
if ( IsValidChar(static_cast<wxUniChar>(keyCode)) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( !wxValidator::IsSilent() )
|
if ( !wxValidator::IsSilent() )
|
||||||
@@ -332,6 +307,71 @@ void wxTextValidator::OnChar(wxKeyEvent& event)
|
|||||||
event.Skip(false);
|
event.Skip(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxTextValidator::IsValidChar(const wxUniChar& c) const
|
||||||
|
{
|
||||||
|
if ( !m_validatorStyle ) // no filtering if HasFlag(wxFILTER_NONE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( IsCharExcluded(c) ) // disallow any char in the m_charExcludes.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( IsCharIncluded(c) ) // allow any char in the m_charIncludes.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( !HasFlag(wxFILTER_CC) )
|
||||||
|
{
|
||||||
|
// Validity is entirely determined by the exclude/include char lists
|
||||||
|
// and this character is in neither, so consider that it is valid if
|
||||||
|
// and only if we accept anything.
|
||||||
|
return !HasFlag(wxFILTER_INCLUDE_CHAR_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( HasFlag(wxFILTER_SPACE) && wxIsspace(c) )
|
||||||
|
return true;
|
||||||
|
if ( HasFlag(wxFILTER_ASCII) && c.IsAscii() )
|
||||||
|
return true;
|
||||||
|
if ( HasFlag(wxFILTER_NUMERIC) && wxIsNumeric(c) )
|
||||||
|
return true;
|
||||||
|
if ( HasFlag(wxFILTER_ALPHANUMERIC) && wxIsalnum(c) )
|
||||||
|
return true;
|
||||||
|
if ( HasFlag(wxFILTER_ALPHA) && wxIsalpha(c) )
|
||||||
|
return true;
|
||||||
|
if ( HasFlag(wxFILTER_DIGITS) && wxIsdigit(c) )
|
||||||
|
return true;
|
||||||
|
if ( HasFlag(wxFILTER_XDIGITS) && wxIsxdigit(c) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If we are here, this means that the char c does not belong to any of the
|
||||||
|
// character classes checked above (e.g. emoji chars) so just return false.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// kept for compatibility reasons.
|
||||||
|
bool wxTextValidator::ContainsOnlyIncludedCharacters(const wxString& str) const
|
||||||
|
{
|
||||||
|
for ( wxString::const_iterator i = str.begin(), end = str.end();
|
||||||
|
i != end; ++i )
|
||||||
|
{
|
||||||
|
if ( !IsCharIncluded(*i) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// kept for compatibility reasons.
|
||||||
|
bool wxTextValidator::ContainsExcludedCharacters(const wxString& str) const
|
||||||
|
{
|
||||||
|
for ( wxString::const_iterator i = str.begin(), end = str.end();
|
||||||
|
i != end; ++i )
|
||||||
|
{
|
||||||
|
if ( IsCharExcluded(*i) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)
|
// wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)
|
||||||
|
@@ -262,9 +262,7 @@ private:
|
|||||||
|
|
||||||
if ( m_combo )
|
if ( m_combo )
|
||||||
{
|
{
|
||||||
wxArrayString allowedChars;
|
wxString allowedChars = wxS("0123456789");
|
||||||
for ( wxChar c = wxT('0'); c <= wxT('9'); c++ )
|
|
||||||
allowedChars.Add(wxString(c, 1));
|
|
||||||
|
|
||||||
const wxChar *p2 = m_format.c_str();
|
const wxChar *p2 = m_format.c_str();
|
||||||
while ( *p2 )
|
while ( *p2 )
|
||||||
@@ -272,12 +270,12 @@ private:
|
|||||||
if ( *p2 == '%')
|
if ( *p2 == '%')
|
||||||
p2 += 2;
|
p2 += 2;
|
||||||
else
|
else
|
||||||
allowedChars.Add(wxString(*p2++, 1));
|
allowedChars << (*p2++); // append char
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_VALIDATORS
|
#if wxUSE_VALIDATORS
|
||||||
wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST);
|
wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST);
|
||||||
tv.SetIncludes(allowedChars);
|
tv.SetCharIncludes(allowedChars);
|
||||||
m_combo->SetValidator(tv);
|
m_combo->SetValidator(tv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -160,47 +160,41 @@ wxNumericPropertyValidator::
|
|||||||
wxNumericPropertyValidator( NumericType numericType, int base )
|
wxNumericPropertyValidator( NumericType numericType, int base )
|
||||||
: wxTextValidator(wxFILTER_INCLUDE_CHAR_LIST)
|
: wxTextValidator(wxFILTER_INCLUDE_CHAR_LIST)
|
||||||
{
|
{
|
||||||
wxArrayString arr;
|
long style = GetStyle();
|
||||||
arr.Add(wxS("0"));
|
|
||||||
arr.Add(wxS("1"));
|
|
||||||
arr.Add(wxS("2"));
|
|
||||||
arr.Add(wxS("3"));
|
|
||||||
arr.Add(wxS("4"));
|
|
||||||
arr.Add(wxS("5"));
|
|
||||||
arr.Add(wxS("6"));
|
|
||||||
arr.Add(wxS("7"));
|
|
||||||
|
|
||||||
if ( base >= 10 )
|
// always allow plus and minus signs
|
||||||
|
wxString allowedChars("+-");
|
||||||
|
|
||||||
|
switch ( base )
|
||||||
{
|
{
|
||||||
arr.Add(wxS("8"));
|
case 2:
|
||||||
arr.Add(wxS("9"));
|
allowedChars += wxS("01");
|
||||||
if ( base >= 16 )
|
break;
|
||||||
{
|
case 8:
|
||||||
arr.Add(wxS("a")); arr.Add(wxS("A"));
|
allowedChars += wxS("01234567");
|
||||||
arr.Add(wxS("b")); arr.Add(wxS("B"));
|
break;
|
||||||
arr.Add(wxS("c")); arr.Add(wxS("C"));
|
case 10:
|
||||||
arr.Add(wxS("d")); arr.Add(wxS("D"));
|
style |= wxFILTER_DIGITS;
|
||||||
arr.Add(wxS("e")); arr.Add(wxS("E"));
|
break;
|
||||||
arr.Add(wxS("f")); arr.Add(wxS("F"));
|
case 16:
|
||||||
}
|
style |= wxFILTER_XDIGITS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxLogWarning( _("Unknown base %d. Base 10 will be used."), base );
|
||||||
|
style |= wxFILTER_DIGITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( numericType == Signed )
|
if ( numericType == Float )
|
||||||
{
|
{
|
||||||
arr.Add(wxS("+"));
|
allowedChars += wxS("eE");
|
||||||
arr.Add(wxS("-"));
|
|
||||||
}
|
|
||||||
else if ( numericType == Float )
|
|
||||||
{
|
|
||||||
arr.Add(wxS("+"));
|
|
||||||
arr.Add(wxS("-"));
|
|
||||||
arr.Add(wxS("e")); arr.Add(wxS("E"));
|
|
||||||
|
|
||||||
// Use locale-specific decimal point
|
// Use locale-specific decimal point
|
||||||
arr.Add(wxString::Format(wxS("%g"), 1.1)[1]);
|
allowedChars += wxString::Format(wxS("%g"), 1.1)[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
SetIncludes(arr);
|
SetStyle(style);
|
||||||
|
SetCharIncludes(allowedChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxNumericPropertyValidator::Validate(wxWindow* parent)
|
bool wxNumericPropertyValidator::Validate(wxWindow* parent)
|
||||||
@@ -2021,15 +2015,7 @@ wxValidator* wxFileProperty::GetClassValidator()
|
|||||||
static wxString v;
|
static wxString v;
|
||||||
wxTextValidator* validator = new wxTextValidator(wxFILTER_EXCLUDE_CHAR_LIST,&v);
|
wxTextValidator* validator = new wxTextValidator(wxFILTER_EXCLUDE_CHAR_LIST,&v);
|
||||||
|
|
||||||
wxArrayString exChars;
|
validator->SetCharExcludes(wxString("?*|<>\""));
|
||||||
exChars.Add(wxS("?"));
|
|
||||||
exChars.Add(wxS("*"));
|
|
||||||
exChars.Add(wxS("|"));
|
|
||||||
exChars.Add(wxS("<"));
|
|
||||||
exChars.Add(wxS(">"));
|
|
||||||
exChars.Add(wxS("\""));
|
|
||||||
|
|
||||||
validator->SetExcludes(exChars);
|
|
||||||
|
|
||||||
WX_PG_DOGETVALIDATOR_EXIT(validator)
|
WX_PG_DOGETVALIDATOR_EXIT(validator)
|
||||||
#else
|
#else
|
||||||
|
@@ -260,6 +260,7 @@ TEST_GUI_OBJECTS = \
|
|||||||
test_gui_wrapsizer.o \
|
test_gui_wrapsizer.o \
|
||||||
test_gui_toplevel.o \
|
test_gui_toplevel.o \
|
||||||
test_gui_valnum.o \
|
test_gui_valnum.o \
|
||||||
|
test_gui_valtext.o \
|
||||||
test_gui_clientsize.o \
|
test_gui_clientsize.o \
|
||||||
test_gui_setsize.o \
|
test_gui_setsize.o \
|
||||||
test_gui_xrctest.o
|
test_gui_xrctest.o
|
||||||
@@ -1052,6 +1053,9 @@ test_gui_toplevel.o: $(srcdir)/toplevel/toplevel.cpp $(TEST_GUI_ODEP)
|
|||||||
test_gui_valnum.o: $(srcdir)/validators/valnum.cpp $(TEST_GUI_ODEP)
|
test_gui_valnum.o: $(srcdir)/validators/valnum.cpp $(TEST_GUI_ODEP)
|
||||||
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/validators/valnum.cpp
|
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/validators/valnum.cpp
|
||||||
|
|
||||||
|
test_gui_valtext.o: $(srcdir)/validators/valtext.cpp $(TEST_GUI_ODEP)
|
||||||
|
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/validators/valtext.cpp
|
||||||
|
|
||||||
test_gui_clientsize.o: $(srcdir)/window/clientsize.cpp $(TEST_GUI_ODEP)
|
test_gui_clientsize.o: $(srcdir)/window/clientsize.cpp $(TEST_GUI_ODEP)
|
||||||
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/window/clientsize.cpp
|
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/window/clientsize.cpp
|
||||||
|
|
||||||
|
@@ -247,6 +247,7 @@ TEST_GUI_OBJECTS = \
|
|||||||
$(OBJS)\test_gui_wrapsizer.obj \
|
$(OBJS)\test_gui_wrapsizer.obj \
|
||||||
$(OBJS)\test_gui_toplevel.obj \
|
$(OBJS)\test_gui_toplevel.obj \
|
||||||
$(OBJS)\test_gui_valnum.obj \
|
$(OBJS)\test_gui_valnum.obj \
|
||||||
|
$(OBJS)\test_gui_valtext.obj \
|
||||||
$(OBJS)\test_gui_clientsize.obj \
|
$(OBJS)\test_gui_clientsize.obj \
|
||||||
$(OBJS)\test_gui_setsize.obj \
|
$(OBJS)\test_gui_setsize.obj \
|
||||||
$(OBJS)\test_gui_xrctest.obj
|
$(OBJS)\test_gui_xrctest.obj
|
||||||
@@ -1107,6 +1108,9 @@ $(OBJS)\test_gui_toplevel.obj: .\toplevel\toplevel.cpp
|
|||||||
$(OBJS)\test_gui_valnum.obj: .\validators\valnum.cpp
|
$(OBJS)\test_gui_valnum.obj: .\validators\valnum.cpp
|
||||||
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\validators\valnum.cpp
|
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\validators\valnum.cpp
|
||||||
|
|
||||||
|
$(OBJS)\test_gui_valtext.obj: .\validators\valtext.cpp
|
||||||
|
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\validators\valtext.cpp
|
||||||
|
|
||||||
$(OBJS)\test_gui_clientsize.obj: .\window\clientsize.cpp
|
$(OBJS)\test_gui_clientsize.obj: .\window\clientsize.cpp
|
||||||
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\window\clientsize.cpp
|
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\window\clientsize.cpp
|
||||||
|
|
||||||
|
@@ -242,6 +242,7 @@ TEST_GUI_OBJECTS = \
|
|||||||
$(OBJS)\test_gui_wrapsizer.o \
|
$(OBJS)\test_gui_wrapsizer.o \
|
||||||
$(OBJS)\test_gui_toplevel.o \
|
$(OBJS)\test_gui_toplevel.o \
|
||||||
$(OBJS)\test_gui_valnum.o \
|
$(OBJS)\test_gui_valnum.o \
|
||||||
|
$(OBJS)\test_gui_valtext.o \
|
||||||
$(OBJS)\test_gui_clientsize.o \
|
$(OBJS)\test_gui_clientsize.o \
|
||||||
$(OBJS)\test_gui_setsize.o \
|
$(OBJS)\test_gui_setsize.o \
|
||||||
$(OBJS)\test_gui_xrctest.o
|
$(OBJS)\test_gui_xrctest.o
|
||||||
@@ -1084,6 +1085,9 @@ $(OBJS)\test_gui_toplevel.o: ./toplevel/toplevel.cpp
|
|||||||
$(OBJS)\test_gui_valnum.o: ./validators/valnum.cpp
|
$(OBJS)\test_gui_valnum.o: ./validators/valnum.cpp
|
||||||
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
|
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
|
||||||
|
|
||||||
|
$(OBJS)\test_gui_valtext.o: ./validators/valtext.cpp
|
||||||
|
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
|
||||||
|
|
||||||
$(OBJS)\test_gui_clientsize.o: ./window/clientsize.cpp
|
$(OBJS)\test_gui_clientsize.o: ./window/clientsize.cpp
|
||||||
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
|
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
|
||||||
|
|
||||||
|
@@ -253,6 +253,7 @@ TEST_GUI_OBJECTS = \
|
|||||||
$(OBJS)\test_gui_wrapsizer.obj \
|
$(OBJS)\test_gui_wrapsizer.obj \
|
||||||
$(OBJS)\test_gui_toplevel.obj \
|
$(OBJS)\test_gui_toplevel.obj \
|
||||||
$(OBJS)\test_gui_valnum.obj \
|
$(OBJS)\test_gui_valnum.obj \
|
||||||
|
$(OBJS)\test_gui_valtext.obj \
|
||||||
$(OBJS)\test_gui_clientsize.obj \
|
$(OBJS)\test_gui_clientsize.obj \
|
||||||
$(OBJS)\test_gui_setsize.obj \
|
$(OBJS)\test_gui_setsize.obj \
|
||||||
$(OBJS)\test_gui_xrctest.obj
|
$(OBJS)\test_gui_xrctest.obj
|
||||||
@@ -1298,6 +1299,9 @@ $(OBJS)\test_gui_toplevel.obj: .\toplevel\toplevel.cpp
|
|||||||
$(OBJS)\test_gui_valnum.obj: .\validators\valnum.cpp
|
$(OBJS)\test_gui_valnum.obj: .\validators\valnum.cpp
|
||||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\validators\valnum.cpp
|
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\validators\valnum.cpp
|
||||||
|
|
||||||
|
$(OBJS)\test_gui_valtext.obj: .\validators\valtext.cpp
|
||||||
|
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\validators\valtext.cpp
|
||||||
|
|
||||||
$(OBJS)\test_gui_clientsize.obj: .\window\clientsize.cpp
|
$(OBJS)\test_gui_clientsize.obj: .\window\clientsize.cpp
|
||||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\window\clientsize.cpp
|
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\window\clientsize.cpp
|
||||||
|
|
||||||
|
@@ -272,6 +272,7 @@
|
|||||||
sizers/wrapsizer.cpp
|
sizers/wrapsizer.cpp
|
||||||
toplevel/toplevel.cpp
|
toplevel/toplevel.cpp
|
||||||
validators/valnum.cpp
|
validators/valnum.cpp
|
||||||
|
validators/valtext.cpp
|
||||||
window/clientsize.cpp
|
window/clientsize.cpp
|
||||||
window/setsize.cpp
|
window/setsize.cpp
|
||||||
xml/xrctest.cpp
|
xml/xrctest.cpp
|
||||||
|
@@ -595,6 +595,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\validators\valnum.cpp">
|
RelativePath=".\validators\valnum.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\validators\valtext.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\controls\virtlistctrltest.cpp">
|
RelativePath=".\controls\virtlistctrltest.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
@@ -1262,6 +1262,10 @@
|
|||||||
RelativePath=".\validators\valnum.cpp"
|
RelativePath=".\validators\valnum.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\validators\valtext.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\controls\virtlistctrltest.cpp"
|
RelativePath=".\controls\virtlistctrltest.cpp"
|
||||||
>
|
>
|
||||||
|
@@ -1234,6 +1234,10 @@
|
|||||||
RelativePath=".\validators\valnum.cpp"
|
RelativePath=".\validators\valnum.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\validators\valtext.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\controls\virtlistctrltest.cpp"
|
RelativePath=".\controls\virtlistctrltest.cpp"
|
||||||
>
|
>
|
||||||
|
190
tests/validators/valtext.cpp
Normal file
190
tests/validators/valtext.cpp
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: tests/validators/valtext.cpp
|
||||||
|
// Purpose: wxTextValidator unit test
|
||||||
|
// Author: Ali Kettab
|
||||||
|
// Created: 2019-01-01
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "testprec.h"
|
||||||
|
|
||||||
|
#if wxUSE_VALIDATORS && wxUSE_UIACTIONSIMULATOR
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/textctrl.h"
|
||||||
|
#include "wx/valtext.h"
|
||||||
|
#endif // WX_PRECOMP
|
||||||
|
|
||||||
|
#include "wx/uiaction.h"
|
||||||
|
|
||||||
|
class TextValidatorTestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextValidatorTestCase()
|
||||||
|
: m_text(new wxTextCtrl(wxTheApp->GetTopWindow(), wxID_ANY))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~TextValidatorTestCase()
|
||||||
|
{
|
||||||
|
delete m_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxTextCtrl* const m_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEXT_VALIDATOR_TEST_CASE(name, tags) \
|
||||||
|
TEST_CASE_METHOD(TextValidatorTestCase, name, tags)
|
||||||
|
|
||||||
|
TEXT_VALIDATOR_TEST_CASE("wxTextValidator::IsValid", "[wxTextValidator][filters]")
|
||||||
|
{
|
||||||
|
wxString value = "";
|
||||||
|
wxTextValidator val(wxFILTER_NONE, &value);
|
||||||
|
|
||||||
|
SECTION("wxFILTER_NONE - no filtering should take place")
|
||||||
|
{
|
||||||
|
CHECK( val.IsValid("wx-90.?! @_~E+{").empty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_EMPTY - empty strings are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_EMPTY);
|
||||||
|
|
||||||
|
CHECK( !val.IsValid("").empty() );
|
||||||
|
CHECK( val.IsValid(" ").empty() ); // space is valid
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_ASCII - non-ASCII characters are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_ASCII);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wx-90.?! @_~E+{").empty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_ALPHA - non-alpha characters are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_ALPHA);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wx").empty() );
|
||||||
|
CHECK( !val.IsValid("wx_").empty() ); // _ is not alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_ALPHANUMERIC - non-alphanumeric characters are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_ALPHANUMERIC);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wx01").empty() );
|
||||||
|
CHECK( !val.IsValid("wx 01").empty() ); // 'space' is not alphanumeric
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_DIGITS - non-digit characters are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_DIGITS);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("97").empty() );
|
||||||
|
CHECK( !val.IsValid("9.7").empty() ); // . is not digit
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_XDIGITS - non-xdigit characters are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_XDIGITS);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("90AEF").empty() );
|
||||||
|
CHECK( !val.IsValid("90GEF").empty() ); // G is not xdigit
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_NUMERIC - non-numeric characters are filtered out")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_NUMERIC);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("+90.e-2").empty() );
|
||||||
|
CHECK( !val.IsValid("-8.5#0").empty() ); // # is not numeric
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_INCLUDE_LIST - use include list")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_INCLUDE_LIST);
|
||||||
|
|
||||||
|
wxArrayString includes;
|
||||||
|
includes.push_back("wxMSW");
|
||||||
|
includes.push_back("wxGTK");
|
||||||
|
includes.push_back("wxOSX");
|
||||||
|
val.SetIncludes(includes);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wxGTK").empty() );
|
||||||
|
CHECK( !val.IsValid("wxQT").empty() ); // wxQT is not included
|
||||||
|
|
||||||
|
SECTION("wxFILTER_EXCLUDE_LIST - use exclude with include list")
|
||||||
|
{
|
||||||
|
wxArrayString excludes;
|
||||||
|
excludes.push_back("wxGTK");
|
||||||
|
excludes.push_back("wxGTK1");
|
||||||
|
val.SetExcludes(excludes);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wxOSX").empty() );
|
||||||
|
CHECK( !val.IsValid("wxGTK").empty() ); // wxGTK now excluded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_EXCLUDE_LIST - use exclude list")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_EXCLUDE_LIST);
|
||||||
|
|
||||||
|
wxArrayString excludes;
|
||||||
|
excludes.push_back("wxMSW");
|
||||||
|
excludes.push_back("wxGTK");
|
||||||
|
excludes.push_back("wxOSX");
|
||||||
|
val.SetExcludes(excludes);
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wxQT & wxUNIV").empty() );
|
||||||
|
CHECK( !val.IsValid("wxMSW").empty() ); // wxMSW is excluded
|
||||||
|
|
||||||
|
SECTION("wxFILTER_INCLUDE_LIST - use include with exclude list")
|
||||||
|
{
|
||||||
|
wxArrayString includes;
|
||||||
|
includes.push_back("wxGTK");
|
||||||
|
val.SetIncludes(includes); // exclusion takes priority over inclusion.
|
||||||
|
|
||||||
|
CHECK( val.IsValid("wxUNIV").empty() );
|
||||||
|
CHECK( !val.IsValid("wxMSW").empty() ); // wxMSW still excluded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_INCLUDE_CHAR_LIST - use include char list")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_INCLUDE_CHAR_LIST);
|
||||||
|
val.SetCharIncludes("tuvwxyz.012+-");
|
||||||
|
|
||||||
|
CHECK( val.IsValid("0.2t+z-1").empty() );
|
||||||
|
CHECK( !val.IsValid("x*y").empty() ); // * is not included
|
||||||
|
|
||||||
|
val.AddCharIncludes("*");
|
||||||
|
|
||||||
|
CHECK( val.IsValid("x*y").empty() ); // * now included
|
||||||
|
CHECK( !val.IsValid("x%y").empty() ); // % is not included
|
||||||
|
|
||||||
|
val.AddCharExcludes("*"); // exclusion takes priority over inclusion.
|
||||||
|
|
||||||
|
CHECK( !val.IsValid("x*y").empty() ); // * now excluded
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("wxFILTER_EXCLUDE_CHAR_LIST - use exclude char list")
|
||||||
|
{
|
||||||
|
val.SetStyle(wxFILTER_EXCLUDE_CHAR_LIST);
|
||||||
|
val.SetCharExcludes("tuvwxyz.012+-");
|
||||||
|
|
||||||
|
CHECK( val.IsValid("A*B=?").empty() );
|
||||||
|
CHECK( !val.IsValid("0.6/t").empty() ); // t is excluded
|
||||||
|
|
||||||
|
val.AddCharIncludes("t"); // exclusion takes priority over inclusion.
|
||||||
|
|
||||||
|
CHECK( !val.IsValid("0.6/t").empty() ); // t still excluded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_VALIDATORS && wxUSE_UIACTIONSIMULATOR
|
Reference in New Issue
Block a user