Fix wxTextValidator introducing a wxTextValidatorStyle enums since it does not support multiple combined styles; fix wxTextValidator::Validate when wxFILTER_EXCLUDE_LIST is used; fixes #1211

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57940 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-01-09 12:43:20 +00:00
parent 79bd5e982b
commit 40ae960071
5 changed files with 192 additions and 142 deletions

View File

@@ -49,7 +49,10 @@ public:
#if wxUSE_VALIDATORS
void SetTextValidator( const wxTextValidator& validator );
void SetTextValidator( long style = wxFILTER_NONE );
#if WXWIN_COMPATIBILITY_2_8
wxDEPRECATED( void SetTextValidator( long style ) );
#endif
void SetTextValidator( wxTextValidatorStyle style = wxFILTER_NONE );
wxTextValidator* GetTextValidator() { return (wxTextValidator*)m_textctrl->GetValidator(); }
#endif
// wxUSE_VALIDATORS

View File

@@ -20,22 +20,26 @@ class WXDLLIMPEXP_FWD_CORE wxTextEntry;
#include "wx/validate.h"
#define wxFILTER_NONE 0x0000
#define wxFILTER_ASCII 0x0001
#define wxFILTER_ALPHA 0x0002
#define wxFILTER_ALPHANUMERIC 0x0004
#define wxFILTER_NUMERIC 0x0008
#define wxFILTER_INCLUDE_LIST 0x0010
#define wxFILTER_EXCLUDE_LIST 0x0020
#define wxFILTER_INCLUDE_CHAR_LIST 0x0040
#define wxFILTER_EXCLUDE_CHAR_LIST 0x0080
enum wxTextValidatorStyle
{
wxFILTER_NONE,
wxFILTER_ASCII,
wxFILTER_ALPHA,
wxFILTER_ALPHANUMERIC,
wxFILTER_NUMERIC,
wxFILTER_INCLUDE_LIST,
wxFILTER_EXCLUDE_LIST,
wxFILTER_INCLUDE_CHAR_LIST,
wxFILTER_EXCLUDE_CHAR_LIST
};
class WXDLLIMPEXP_CORE wxTextValidator: public wxValidator
{
DECLARE_DYNAMIC_CLASS(wxTextValidator)
public:
wxTextValidator(long style = wxFILTER_NONE, wxString *val = 0);
wxTextValidator(wxTextValidatorStyle style = wxFILTER_NONE, wxString *val = NULL);
#if WXWIN_COMPATIBILITY_2_8
wxDEPRECATED_CONSTRUCTOR( wxTextValidator(long style, wxString *val) );
#endif
wxTextValidator(const wxTextValidator& val);
virtual ~wxTextValidator(){}
@@ -58,8 +62,11 @@ public:
virtual bool TransferFromWindow();
// ACCESSORS
inline long GetStyle() const { return m_validatorStyle; }
inline void SetStyle(long style) { m_validatorStyle = style; }
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
wxTextEntry *GetTextEntry();
@@ -75,15 +82,15 @@ public:
// Filter keystrokes
void OnChar(wxKeyEvent& event);
DECLARE_EVENT_TABLE()
protected:
long m_validatorStyle;
wxString * m_stringValue;
wxArrayString m_includes;
wxArrayString m_excludes;
wxTextValidatorStyle m_validatorStyle;
wxString * m_stringValue;
wxArrayString m_includes;
wxArrayString m_excludes;
private:
DECLARE_DYNAMIC_CLASS(wxTextValidator)
DECLARE_EVENT_TABLE()
// Cannot use
// DECLARE_NO_COPY_CLASS(wxTextValidator)
// because copy constructor is explicitly declared above;

View File

@@ -6,6 +6,46 @@
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
/**
Styles used by wxTextValidator.
*/
enum wxTextValidatorStyle
{
/// No filtering takes place.
wxFILTER_NONE,
/// Non-ASCII characters are filtered out.
wxFILTER_ASCII,
/// Non-alpha characters are filtered out.
wxFILTER_ALPHA,
/// Non-alphanumeric characters are filtered out.
wxFILTER_ALPHANUMERIC,
/// Non-numeric characters are filtered out.
wxFILTER_NUMERIC,
/// Use an include list. The validator checks if the user input is on
/// 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::SetIncludes().
wxFILTER_INCLUDE_CHAR_LIST,
/// Use an include list. The validator checks if each input character is
/// in the list (one character per list element), complaining if it is.
/// See wxTextValidator::SetExcludes().
wxFILTER_EXCLUDE_CHAR_LIST
};
/**
@class wxTextValidator
@@ -14,33 +54,6 @@
For more information, please see @ref overview_validator.
@beginStyleTable
@style{wxFILTER_NONE}
No filtering takes place.
@style{wxFILTER_ASCII}
Non-ASCII characters are filtered out.
@style{wxFILTER_ALPHA}
Non-alpha characters are filtered out.
@style{wxFILTER_ALPHANUMERIC}
Non-alphanumeric characters are filtered out.
@style{wxFILTER_NUMERIC}
Non-numeric characters are filtered out.
@style{wxFILTER_INCLUDE_LIST}
Use an include list. The validator checks if the user input is on
the list, complaining if not. See SetIncludes().
@style{wxFILTER_EXCLUDE_LIST}
Use an exclude list. The validator checks if the user input is on
the list, complaining if it is. See SetExcludes().
@style{wxFILTER_INCLUDE_CHAR_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 SetIncludes().
@style{wxFILTER_EXCLUDE_CHAR_LIST}
Use an include list. The validator checks if each input character is
in the list (one character per list element), complaining if it is.
See SetExcludes().
@endStyleTable
@library{wxcore}
@category{validator}
@@ -53,18 +66,19 @@ public:
Default constructor.
*/
wxTextValidator(const wxTextValidator& validator);
/**
Constructor taking a style and optional pointer to a wxString variable.
@param style
A bitlist of flags documented in the class description.
One of the ::wxTextValidatorStyle styles.
@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(long style = wxFILTER_NONE, wxString* valPtr = NULL);
wxTextValidator(wxTextValidatorStyle style = wxFILTER_NONE, wxString* valPtr = NULL);
/**
Clones the text validator using the copy constructor.
@@ -105,7 +119,7 @@ public:
/**
Sets the validator style.
*/
void SetStyle(long style);
void SetStyle(wxTextValidatorStyle style);
/**
Transfers the value in the text control to the string.

View File

@@ -33,15 +33,71 @@
#include <string.h>
#include <stdlib.h>
IMPLEMENT_DYNAMIC_CLASS(wxTextValidator, wxValidator)
// ----------------------------------------------------------------------------
// global helpers
// ----------------------------------------------------------------------------
static bool wxIsAlpha(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
if (!wxIsalpha(val[i]))
return false;
}
return true;
}
static bool wxIsAlphaNumeric(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
if (!wxIsalnum(val[i]))
return false;
}
return true;
}
static bool wxIsNumeric(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
// Allow for "," (French) as well as "." -- in future we should
// use wxSystemSettings or other to do better localisation
if ((!wxIsdigit(val[i])) && (val[i] != wxT('.')) && (val[i] != wxT(',')) && (val[i] != wxT('e')) &&
(val[i] != wxT('E')) && (val[i] != wxT('+')) && (val[i] != wxT('-')))
return false;
}
return true;
}
// ----------------------------------------------------------------------------
// wxTextValidator
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxTextValidator, wxValidator)
BEGIN_EVENT_TABLE(wxTextValidator, wxValidator)
EVT_CHAR(wxTextValidator::OnChar)
END_EVENT_TABLE()
static bool wxIsNumeric(const wxString& val);
#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;
@@ -95,28 +151,6 @@ wxTextEntry *wxTextValidator::GetTextEntry()
return NULL;
}
static bool wxIsAlpha(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
if (!wxIsalpha(val[i]))
return false;
}
return true;
}
static bool wxIsAlphaNumeric(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
if (!wxIsalnum(val[i]))
return false;
}
return true;
}
// Called when the value in the window must be validated.
// This function can pop up an error message.
bool wxTextValidator::Validate(wxWindow *parent)
@@ -131,63 +165,57 @@ bool wxTextValidator::Validate(wxWindow *parent)
wxString val(text->GetValue());
bool ok = true;
// NB: this format string should contian exactly one '%s'
// NB: this format string should always contain exactly one '%s'
wxString errormsg;
bool includes = (m_validatorStyle & wxFILTER_INCLUDE_LIST) != 0;
if ( includes || (m_validatorStyle & wxFILTER_EXCLUDE_LIST) )
switch (m_validatorStyle)
{
// if includes, it's only ok to have the members of the list,
// otherwise it's only ok to have non-members
ok = includes == (m_includes.Index(val) != wxNOT_FOUND);
if ( !ok )
{
case wxFILTER_INCLUDE_LIST:
if ( m_includes.Index(val) == wxNOT_FOUND )
errormsg = _("'%s' is invalid");
}
}
else if ( (m_validatorStyle & wxFILTER_ASCII) && !val.IsAscii() )
{
ok = false;
break;
errormsg = _("'%s' should only contain ASCII characters.");
}
else if ( (m_validatorStyle & wxFILTER_ALPHA) && !wxIsAlpha(val) )
{
ok = false;
case wxFILTER_EXCLUDE_LIST:
if ( m_excludes.Index(val) != wxNOT_FOUND )
errormsg = _("'%s' is invalid");
break;
errormsg = _("'%s' should only contain alphabetic characters.");
}
else if ( (m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsAlphaNumeric(val))
{
ok = false;
case wxFILTER_ASCII:
if ( !val.IsAscii() )
errormsg = _("'%s' should only contain ASCII characters.");
break;
errormsg = _("'%s' should only contain alphabetic or numeric characters.");
}
else if ( (m_validatorStyle & wxFILTER_NUMERIC) && !wxIsNumeric(val))
{
ok = false;
case wxFILTER_ALPHA:
if ( !wxIsAlpha(val) )
errormsg = _("'%s' should only contain alphabetic characters.");
break;
errormsg = _("'%s' should be numeric.");
}
else if ( (m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(val))
{
//it's only ok to have the members of the list
errormsg = _("'%s' is invalid");
ok = false;
}
else if ( (m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(val))
{
// it's only ok to have non-members of the list
errormsg = _("'%s' is invalid");
ok = false;
case wxFILTER_ALPHANUMERIC:
if ( !wxIsAlphaNumeric(val) )
errormsg = _("'%s' should only contain alphabetic or numeric characters.");
break;
case wxFILTER_NUMERIC:
if ( !wxIsNumeric(val) )
errormsg = _("'%s' should be numeric.");
break;
case wxFILTER_INCLUDE_CHAR_LIST:
if ( !IsInCharIncludes(val) )
errormsg = _("'%s' is invalid");
break;
case wxFILTER_EXCLUDE_CHAR_LIST:
if ( !IsNotInCharExcludes(val) )
errormsg = _("'%s' is invalid");
break;
default:
wxFAIL_MSG("invalid text validator style");
}
if ( !ok )
if ( !errormsg.empty() )
{
wxASSERT_MSG( !errormsg.empty(), _T("you forgot to set errormsg") );
m_validatorWindow->SetFocus();
wxString buf;
@@ -195,9 +223,11 @@ bool wxTextValidator::Validate(wxWindow *parent)
wxMessageBox(buf, _("Validation conflict"),
wxOK | wxICON_EXCLAMATION, parent);
return false;
}
return ok;
return true;
}
// Called to transfer data to the window
@@ -267,13 +297,14 @@ void wxTextValidator::OnChar(wxKeyEvent& event)
if (
!(keyCode < WXK_SPACE || keyCode == WXK_DELETE || keyCode > WXK_START) &&
(
((m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(wxString((wxChar) keyCode, 1))) ||
((m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(wxString((wxChar) keyCode, 1))) ||
((m_validatorStyle & wxFILTER_ASCII) && !isascii(keyCode)) ||
((m_validatorStyle & wxFILTER_ALPHA) && !wxIsalpha(keyCode)) ||
((m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsalnum(keyCode)) ||
((m_validatorStyle & wxFILTER_NUMERIC) && !wxIsdigit(keyCode)
&& keyCode != wxT('.') && keyCode != wxT(',') && keyCode != wxT('-') && keyCode != wxT('+') && keyCode != wxT('e') && keyCode != wxT('E'))
((m_validatorStyle == wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(wxString((wxChar) keyCode, 1))) ||
((m_validatorStyle == wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(wxString((wxChar) keyCode, 1))) ||
((m_validatorStyle == wxFILTER_ASCII) && !isascii(keyCode)) ||
((m_validatorStyle == wxFILTER_ALPHA) && !wxIsalpha(keyCode)) ||
((m_validatorStyle == wxFILTER_ALPHANUMERIC) && !wxIsalnum(keyCode)) ||
((m_validatorStyle == wxFILTER_NUMERIC) && !wxIsdigit(keyCode)
&& keyCode != wxT('.') && keyCode != wxT(',') && keyCode != wxT('-') && keyCode != wxT('+')
&& keyCode != wxT('e') && keyCode != wxT('E'))
)
)
{
@@ -288,19 +319,6 @@ void wxTextValidator::OnChar(wxKeyEvent& event)
event.Skip();
}
static bool wxIsNumeric(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
// Allow for "," (French) as well as "." -- in future we should
// use wxSystemSettings or other to do better localisation
if ((!wxIsdigit(val[i])) && (val[i] != wxT('.')) && (val[i] != wxT(',')) && (val[i] != wxT('e')) && (val[i] != wxT('E')) && (val[i] != wxT('+')) && (val[i] != wxT('-')))
return false;
}
return true;
}
#endif
// wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)

View File

@@ -151,7 +151,15 @@ void wxTextEntryDialog::SetValue(const wxString& val)
}
#if wxUSE_VALIDATORS
#if WXWIN_COMPATIBILITY_2_8
void wxTextEntryDialog::SetTextValidator( long style )
{
SetTextValidator((wxTextValidatorStyle)style);
}
#endif
void wxTextEntryDialog::SetTextValidator( wxTextValidatorStyle style )
{
wxTextValidator validator( style, &m_value );
m_textctrl->SetValidator( validator );