]> git.saurik.com Git - wxWidgets.git/blob - src/common/valtext.cpp
s/wxWindows/wxWidgets; update wx-dev mail address
[wxWidgets.git] / src / common / valtext.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/valtext.cpp
3 // Purpose: wxTextValidator
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)
20
21 #include "wx/valtext.h"
22
23 #ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/textctrl.h"
26 #include "wx/combobox.h"
27 #include "wx/utils.h"
28 #include "wx/msgdlg.h"
29 #include "wx/intl.h"
30 #endif
31
32 #include <ctype.h>
33 #include <string.h>
34 #include <stdlib.h>
35
36 // ----------------------------------------------------------------------------
37 // global helpers
38 // ----------------------------------------------------------------------------
39
40 static bool wxIsAlpha(const wxString& val)
41 {
42 int i;
43 for ( i = 0; i < (int)val.length(); i++)
44 {
45 if (!wxIsalpha(val[i]))
46 return false;
47 }
48 return true;
49 }
50
51 static bool wxIsAlphaNumeric(const wxString& val)
52 {
53 int i;
54 for ( i = 0; i < (int)val.length(); i++)
55 {
56 if (!wxIsalnum(val[i]))
57 return false;
58 }
59 return true;
60 }
61
62 static bool wxIsNumeric(const wxString& val)
63 {
64 int i;
65 for ( i = 0; i < (int)val.length(); i++)
66 {
67 // Allow for "," (French) as well as "." -- in future we should
68 // use wxSystemSettings or other to do better localisation
69 if ((!wxIsdigit(val[i])) && (val[i] != wxT('.')) && (val[i] != wxT(',')) && (val[i] != wxT('e')) &&
70 (val[i] != wxT('E')) && (val[i] != wxT('+')) && (val[i] != wxT('-')))
71 return false;
72 }
73 return true;
74 }
75
76
77 // ----------------------------------------------------------------------------
78 // wxTextValidator
79 // ----------------------------------------------------------------------------
80
81 IMPLEMENT_DYNAMIC_CLASS(wxTextValidator, wxValidator)
82 BEGIN_EVENT_TABLE(wxTextValidator, wxValidator)
83 EVT_CHAR(wxTextValidator::OnChar)
84 END_EVENT_TABLE()
85
86
87 #if WXWIN_COMPATIBILITY_2_8
88 wxTextValidator::wxTextValidator(long style, wxString *val)
89 {
90 m_validatorStyle = (wxTextValidatorStyle)style;
91 m_stringValue = val;
92 }
93
94 void wxTextValidator::SetStyle(long style)
95 {
96 SetStyle((wxTextValidatorStyle)style);
97 }
98 #endif
99
100 wxTextValidator::wxTextValidator(wxTextValidatorStyle style, wxString *val)
101 {
102 m_validatorStyle = style;
103 m_stringValue = val;
104 /*
105 m_refData = new wxVTextRefData;
106
107 M_VTEXTDATA->m_validatorStyle = style;
108 M_VTEXTDATA->m_stringValue = val;
109 */
110 }
111
112 wxTextValidator::wxTextValidator(const wxTextValidator& val)
113 : wxValidator()
114 {
115 Copy(val);
116 }
117
118 bool wxTextValidator::Copy(const wxTextValidator& val)
119 {
120 wxValidator::Copy(val);
121
122 m_validatorStyle = val.m_validatorStyle;
123 m_stringValue = val.m_stringValue;
124
125 m_includes = val.m_includes;
126 m_excludes = val.m_excludes;
127
128 return true;
129 }
130
131 wxTextEntry *wxTextValidator::GetTextEntry()
132 {
133 #if wxUSE_TEXTCTRL
134 if (m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl)))
135 {
136 return (wxTextCtrl*)m_validatorWindow;
137 }
138 #endif
139
140 #if wxUSE_COMBOBOX
141 if (m_validatorWindow->IsKindOf(CLASSINFO(wxComboBox)))
142 {
143 return (wxComboBox*)m_validatorWindow;
144 }
145 #endif
146
147 wxFAIL_MSG(
148 _T("wxTextValidator can only be used with wxTextCtrl or wxComboBox")
149 );
150
151 return NULL;
152 }
153
154 // Called when the value in the window must be validated.
155 // This function can pop up an error message.
156 bool wxTextValidator::Validate(wxWindow *parent)
157 {
158 // If window is disabled, simply return
159 if ( !m_validatorWindow->IsEnabled() )
160 return true;
161
162 wxTextEntry * const text = GetTextEntry();
163 if ( !text )
164 return false;
165
166 wxString val(text->GetValue());
167
168 // NB: this format string should always contain exactly one '%s'
169 wxString errormsg;
170
171 switch (m_validatorStyle)
172 {
173 case wxFILTER_INCLUDE_LIST:
174 if ( m_includes.Index(val) == wxNOT_FOUND )
175 errormsg = _("'%s' is invalid");
176 break;
177
178 case wxFILTER_EXCLUDE_LIST:
179 if ( m_excludes.Index(val) != wxNOT_FOUND )
180 errormsg = _("'%s' is invalid");
181 break;
182
183 case wxFILTER_ASCII:
184 if ( !val.IsAscii() )
185 errormsg = _("'%s' should only contain ASCII characters.");
186 break;
187
188 case wxFILTER_ALPHA:
189 if ( !wxIsAlpha(val) )
190 errormsg = _("'%s' should only contain alphabetic characters.");
191 break;
192
193 case wxFILTER_ALPHANUMERIC:
194 if ( !wxIsAlphaNumeric(val) )
195 errormsg = _("'%s' should only contain alphabetic or numeric characters.");
196 break;
197
198 case wxFILTER_NUMERIC:
199 if ( !wxIsNumeric(val) )
200 errormsg = _("'%s' should be numeric.");
201 break;
202
203 case wxFILTER_INCLUDE_CHAR_LIST:
204 if ( !IsInCharIncludes(val) )
205 errormsg = _("'%s' is invalid");
206 break;
207
208 case wxFILTER_EXCLUDE_CHAR_LIST:
209 if ( !IsNotInCharExcludes(val) )
210 errormsg = _("'%s' is invalid");
211 break;
212
213 default:
214 wxFAIL_MSG("invalid text validator style");
215 }
216
217 if ( !errormsg.empty() )
218 {
219 m_validatorWindow->SetFocus();
220
221 wxString buf;
222 buf.Printf(errormsg, val.c_str());
223
224 wxMessageBox(buf, _("Validation conflict"),
225 wxOK | wxICON_EXCLAMATION, parent);
226
227 return false;
228 }
229
230 return true;
231 }
232
233 // Called to transfer data to the window
234 bool wxTextValidator::TransferToWindow(void)
235 {
236 if ( m_stringValue )
237 {
238 wxTextEntry * const text = GetTextEntry();
239 if ( !text )
240 return false;
241
242 text->SetValue(*m_stringValue);
243 }
244
245 return true;
246 }
247
248 // Called to transfer data to the window
249 bool wxTextValidator::TransferFromWindow(void)
250 {
251 if ( m_stringValue )
252 {
253 wxTextEntry * const text = GetTextEntry();
254 if ( !text )
255 return false;
256
257 *m_stringValue = text->GetValue();
258 }
259
260 return true;
261 }
262
263 bool wxTextValidator::IsInCharIncludes(const wxString& val)
264 {
265 size_t i;
266 for ( i = 0; i < val.length(); i++)
267 {
268 if (m_includes.Index((wxString) val[i]) == wxNOT_FOUND)
269 return false;
270 }
271 return true;
272 }
273
274 bool wxTextValidator::IsNotInCharExcludes(const wxString& val)
275 {
276 size_t i;
277 for ( i = 0; i < val.length(); i++)
278 {
279 if (m_excludes.Index((wxString) val[i]) != wxNOT_FOUND)
280 return false;
281 }
282 return true;
283 }
284
285 void wxTextValidator::OnChar(wxKeyEvent& event)
286 {
287 /*
288 if ( !M_VTEXTDATA )
289 return;
290 */
291
292 if ( m_validatorWindow )
293 {
294 int keyCode = event.GetKeyCode();
295
296 // we don't filter special keys and Delete
297 if (
298 !(keyCode < WXK_SPACE || keyCode == WXK_DELETE || keyCode > WXK_START) &&
299 (
300 ((m_validatorStyle == wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(wxString((wxChar) keyCode, 1))) ||
301 ((m_validatorStyle == wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(wxString((wxChar) keyCode, 1))) ||
302 ((m_validatorStyle == wxFILTER_ASCII) && !isascii(keyCode)) ||
303 ((m_validatorStyle == wxFILTER_ALPHA) && !wxIsalpha(keyCode)) ||
304 ((m_validatorStyle == wxFILTER_ALPHANUMERIC) && !wxIsalnum(keyCode)) ||
305 ((m_validatorStyle == wxFILTER_NUMERIC) && !wxIsdigit(keyCode)
306 && keyCode != wxT('.') && keyCode != wxT(',') && keyCode != wxT('-') && keyCode != wxT('+')
307 && keyCode != wxT('e') && keyCode != wxT('E'))
308 )
309 )
310 {
311 if ( !wxValidator::IsSilent() )
312 wxBell();
313
314 // eat message
315 return;
316 }
317 }
318
319 event.Skip();
320 }
321
322
323 #endif
324 // wxUSE_VALIDATORS && (wxUSE_TEXTCTRL || wxUSE_COMBOBOX)