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