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 #if wxUSE_VALIDATORS
void SetTextValidator( const wxTextValidator& validator ); 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(); } wxTextValidator* GetTextValidator() { return (wxTextValidator*)m_textctrl->GetValidator(); }
#endif #endif
// wxUSE_VALIDATORS // wxUSE_VALIDATORS

View File

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

View File

@@ -6,6 +6,46 @@
// Licence: wxWindows license // 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 @class wxTextValidator
@@ -14,33 +54,6 @@
For more information, please see @ref overview_validator. 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} @library{wxcore}
@category{validator} @category{validator}
@@ -53,18 +66,19 @@ public:
Default constructor. Default constructor.
*/ */
wxTextValidator(const wxTextValidator& validator); wxTextValidator(const wxTextValidator& validator);
/** /**
Constructor taking a style and optional pointer to a wxString variable. Constructor taking a style and optional pointer to a wxString variable.
@param style @param style
A bitlist of flags documented in the class description. One of the ::wxTextValidatorStyle styles.
@param valPtr @param valPtr
A pointer to a wxString variable that contains the value. This A pointer to a wxString variable that contains the value. This
variable should have a lifetime equal to or longer than the variable should have a lifetime equal to or longer than the
validator lifetime (which is usually determined by the lifetime of validator lifetime (which is usually determined by the lifetime of
the window). 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. Clones the text validator using the copy constructor.
@@ -105,7 +119,7 @@ public:
/** /**
Sets the validator style. Sets the validator style.
*/ */
void SetStyle(long style); void SetStyle(wxTextValidatorStyle style);
/** /**
Transfers the value in the text control to the string. Transfers the value in the text control to the string.

View File

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

View File

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