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