1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/valtext.cpp
3 // Purpose: wxTextValidator
4 // Author: Julian Smart
5 // Modified by: Francesco Montorsi
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
19 #if wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)
21 #include "wx/valtext.h"
25 #include "wx/textctrl.h"
26 #include "wx/combobox.h"
28 #include "wx/msgdlg.h"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 static bool wxIsNumeric(const wxString
& val
)
42 for ( wxString::const_iterator i
= val
.begin(); i
!= val
.end(); ++i
)
44 // Allow for "," (French) as well as "." -- in future we should
45 // use wxSystemSettings or other to do better localisation
46 if ((!wxIsdigit(*i
)) && (*i
!= wxT('.')) && (*i
!= wxT(',')) && (*i
!= wxT('e')) &&
47 (*i
!= wxT('E')) && (*i
!= wxT('+')) && (*i
!= wxT('-')))
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 IMPLEMENT_DYNAMIC_CLASS(wxTextValidator
, wxValidator
)
58 BEGIN_EVENT_TABLE(wxTextValidator
, wxValidator
)
59 EVT_CHAR(wxTextValidator::OnChar
)
63 #if WXWIN_COMPATIBILITY_2_8
64 wxTextValidator::wxTextValidator(long style
, wxString
*val
)
66 m_validatorStyle
= (wxTextValidatorStyle
)style
;
70 void wxTextValidator::SetStyle(long style
)
72 SetStyle((wxTextValidatorStyle
)style
);
76 wxTextValidator::wxTextValidator(wxTextValidatorStyle style
, wxString
*val
)
78 m_validatorStyle
= style
;
82 wxTextValidator::wxTextValidator(const wxTextValidator
& val
)
88 bool wxTextValidator::Copy(const wxTextValidator
& val
)
90 wxValidator::Copy(val
);
92 m_validatorStyle
= val
.m_validatorStyle
;
93 m_stringValue
= val
.m_stringValue
;
95 m_includes
= val
.m_includes
;
96 m_excludes
= val
.m_excludes
;
101 wxTextEntry
*wxTextValidator::GetTextEntry()
104 if (m_validatorWindow
->IsKindOf(CLASSINFO(wxTextCtrl
)))
106 return (wxTextCtrl
*)m_validatorWindow
;
111 if (m_validatorWindow
->IsKindOf(CLASSINFO(wxComboBox
)))
113 return (wxComboBox
*)m_validatorWindow
;
118 _T("wxTextValidator can only be used with wxTextCtrl or wxComboBox")
124 // Called when the value in the window must be validated.
125 // This function can pop up an error message.
126 bool wxTextValidator::Validate(wxWindow
*parent
)
128 // If window is disabled, simply return
129 if ( !m_validatorWindow
->IsEnabled() )
132 wxTextEntry
* const text
= GetTextEntry();
136 wxString
val(text
->GetValue());
138 // NB: this format string should always contain exactly one '%s'
140 if (!IsValid(val
, &errormsg
))
142 wxASSERT(!errormsg
.empty());
144 m_validatorWindow
->SetFocus();
147 buf
.Printf(errormsg
, val
.c_str());
149 wxMessageBox(buf
, _("Validation conflict"),
150 wxOK
| wxICON_EXCLAMATION
, parent
);
158 // Called to transfer data to the window
159 bool wxTextValidator::TransferToWindow()
163 wxTextEntry
* const text
= GetTextEntry();
167 text
->SetValue(*m_stringValue
);
173 // Called to transfer data to the window
174 bool wxTextValidator::TransferFromWindow()
178 wxTextEntry
* const text
= GetTextEntry();
182 *m_stringValue
= text
->GetValue();
188 bool wxTextValidator::IsValid(const wxString
& val
, wxString
* pErr
) const
191 switch (m_validatorStyle
)
197 case wxFILTER_INCLUDE_LIST
:
198 if ( m_includes
.Index(val
) == wxNOT_FOUND
)
199 errormsg
= _("'%s' is invalid");
202 case wxFILTER_EXCLUDE_LIST
:
203 if ( m_excludes
.Index(val
) != wxNOT_FOUND
)
204 errormsg
= _("'%s' is invalid");
208 if ( !val
.IsAscii() )
209 errormsg
= _("'%s' should only contain ASCII characters.");
213 if ( !wxStringCheck
<wxIsalpha
>(val
) )
214 errormsg
= _("'%s' should only contain alphabetic characters.");
217 case wxFILTER_ALPHANUMERIC
:
218 if ( !wxStringCheck
<wxIsalnum
>(val
) )
219 errormsg
= _("'%s' should only contain alphabetic or numeric characters.");
222 case wxFILTER_SIMPLE_NUMBER
:
223 if ( !wxStringCheck
<wxIsdigit
>(val
) )
224 errormsg
= _("'%s' should be numeric.");
227 case wxFILTER_NUMERIC
:
228 if ( !wxIsNumeric(val
) )
229 errormsg
= _("'%s' should be numeric.");
232 case wxFILTER_INCLUDE_CHAR_LIST
:
233 if ( !ContainsOnlyIncludedCharacters(val
) )
234 errormsg
= _("'%s' is invalid");
237 case wxFILTER_EXCLUDE_CHAR_LIST
:
238 if ( ContainsExcludedCharacters(val
) )
239 errormsg
= _("'%s' is invalid");
243 wxFAIL_MSG("invalid text validator style");
249 return errormsg
.empty();
252 bool wxTextValidator::ContainsOnlyIncludedCharacters(const wxString
& val
) const
254 for ( wxString::const_iterator i
= val
.begin(); i
!= val
.end(); ++i
)
255 if (m_includes
.Index((wxString
) *i
) == wxNOT_FOUND
)
256 // one character of 'val' is NOT present in m_includes...
259 // all characters of 'val' are present in m_includes
263 bool wxTextValidator::ContainsExcludedCharacters(const wxString
& val
) const
265 for ( wxString::const_iterator i
= val
.begin(); i
!= val
.end(); ++i
)
266 if (m_excludes
.Index((wxString
) *i
) != wxNOT_FOUND
)
267 // one character of 'val' is present in m_excludes...
270 // all characters of 'val' are NOT present in m_excludes
274 void wxTextValidator::SetCharIncludes(const wxString
& chars
)
278 for ( wxString::const_iterator i
= chars
.begin(); i
!= chars
.end(); ++i
)
284 void wxTextValidator::SetCharExcludes(const wxString
& chars
)
288 for ( wxString::const_iterator i
= chars
.begin(); i
!= chars
.end(); ++i
)
294 void wxTextValidator::OnChar(wxKeyEvent
& event
)
296 if (!m_validatorWindow
)
302 int keyCode
= event
.GetKeyCode();
304 // we don't filter special keys and delete
305 if (keyCode
< WXK_SPACE
|| keyCode
== WXK_DELETE
|| keyCode
>= WXK_START
)
311 wxString
str((wxUniChar
)keyCode
, 1);
312 if (!IsValid(str
, NULL
))
314 if ( !wxValidator::IsSilent() )
326 // wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)