X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/10b0f4894bcfc158dc406700365887da74ddbf15..74a8f67d96591cec101def2a7d47c64072aff7fd:/src/common/valtext.cpp diff --git a/src/common/valtext.cpp b/src/common/valtext.cpp index d150671737..43c87eb446 100644 --- a/src/common/valtext.cpp +++ b/src/common/valtext.cpp @@ -33,47 +33,26 @@ #include #include +#include "wx/combo.h" + // ---------------------------------------------------------------------------- // 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++) + for ( wxString::const_iterator i = val.begin(); i != val.end(); ++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('-'))) + if ((!wxIsdigit(*i)) && + (*i != wxS('.')) && (*i != wxS(',')) && (*i != wxS('e')) && + (*i != wxS('E')) && (*i != wxS('+')) && (*i != wxS('-'))) return false; } return true; } - // ---------------------------------------------------------------------------- // wxTextValidator // ---------------------------------------------------------------------------- @@ -83,30 +62,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); +#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) @@ -138,8 +127,16 @@ wxTextEntry *wxTextValidator::GetTextEntry() } #endif +#if wxUSE_COMBOCTRL + if (m_validatorWindow->IsKindOf(CLASSINFO(wxComboCtrl))) + { + return (wxComboCtrl*)m_validatorWindow; + } +#endif + wxFAIL_MSG( - _T("wxTextValidator can only be used with wxTextCtrl or wxComboBox") + "wxTextValidator can only be used with wxTextCtrl, wxComboBox, " + "or wxComboCtrl" ); return NULL; @@ -159,18 +156,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 = _("Required information entry is empty."); + } + 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; @@ -209,69 +211,57 @@ bool wxTextValidator::TransferFromWindow() return true; } -bool wxTextValidator::IsValid(const wxString& val, wxString* pErr) const +// IRIX mipsPro refuses to compile wxStringCheck() if func is inline so +// 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 { - wxString errormsg; - switch (m_validatorStyle) + +bool CheckString(bool (*func)(const wxUniChar&), const wxString& str) +{ + for ( wxString::const_iterator i = str.begin(); i != str.end(); ++i ) { - 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 ( !wxIsAlpha(val) ) - errormsg = _("'%s' should only contain alphabetic characters."); - break; - - 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 ( !func(*i) ) + return false; } - if (pErr) - *pErr = errormsg; + return true; +} + +} // anonymous namespace - return errormsg.empty(); +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_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::IsInCharIncludes(const wxString& val) const +bool wxTextValidator::ContainsOnlyIncludedCharacters(const wxString& val) const { - for (size_t i = 0; i < val.length(); i++) - if (m_includes.Index((wxString) val[i]) == wxNOT_FOUND) + 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; @@ -279,15 +269,35 @@ bool wxTextValidator::IsInCharIncludes(const wxString& val) const return true; } -bool wxTextValidator::IsNotInCharExcludes(const wxString& val) const +bool wxTextValidator::ContainsExcludedCharacters(const wxString& val) const { - for (size_t i = 0; i < val.length(); i++) - if (m_excludes.Index((wxString) val[i]) != wxNOT_FOUND) + 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 false; + return true; // all characters of 'val' are NOT present in m_excludes - return true; + return false; +} + +void wxTextValidator::SetCharIncludes(const wxString& chars) +{ + wxArrayString arr; + + for ( wxString::const_iterator i = chars.begin(); i != chars.end(); ++i ) + arr.Add(*i); + + SetIncludes(arr); +} + +void wxTextValidator::SetCharExcludes(const wxString& chars) +{ + wxArrayString arr; + + for ( wxString::const_iterator i = chars.begin(); i != chars.end(); ++i ) + arr.Add(*i); + + SetExcludes(arr); } void wxTextValidator::OnChar(wxKeyEvent& event) @@ -308,7 +318,7 @@ void wxTextValidator::OnChar(wxKeyEvent& event) } wxString str((wxUniChar)keyCode, 1); - if (!IsValid(str, NULL)) + if (!IsValid(str).empty()) { if ( !wxValidator::IsSilent() ) wxBell();