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: valtext.cpp 39656 2006-06-09 21:21:53Z ABX $ 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 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 39IMPLEMENT_DYNAMIC_CLASS(wxTextValidator, wxValidator) 40 41BEGIN_EVENT_TABLE(wxTextValidator, wxValidator) 42 EVT_CHAR(wxTextValidator::OnChar) 43END_EVENT_TABLE() 44 45static bool wxIsNumeric(const wxString& val); 46 47wxTextValidator::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 59wxTextValidator::wxTextValidator(const wxTextValidator& val) 60 : wxValidator() 61{ 62 Copy(val); 63} 64 65bool 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 78static bool wxIsAlpha(const wxString& val) 79{ 80 int i; 81 for ( i = 0; i < (int)val.length(); i++) 82 { 83 if (!wxIsalpha(val[i])) 84 return false; 85 } 86 return true; 87} 88 89static bool wxIsAlphaNumeric(const wxString& val) 90{ 91 int i; 92 for ( i = 0; i < (int)val.length(); i++) 93 { 94 if (!wxIsalnum(val[i])) 95 return false; 96 } 97 return true; 98} 99 100// Called when the value in the window must be validated. 101// This function can pop up an error message. 102bool wxTextValidator::Validate(wxWindow *parent) 103{ 104 if( !CheckValidator() ) 105 return false; 106 107 wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow; 108 109 // If window is disabled, simply return 110 if ( !control->IsEnabled() ) 111 return true; 112 113 wxString val(control->GetValue()); 114 115 bool ok = true; 116 117 // NB: this format string should contian exactly one '%s' 118 wxString errormsg; 119 120 bool includes = (m_validatorStyle & wxFILTER_INCLUDE_LIST) != 0; 121 if ( includes || (m_validatorStyle & wxFILTER_EXCLUDE_LIST) ) 122 { 123 // if includes, it's only ok to have the members of the list, 124 // otherwise it's only ok to have non-members 125 ok = includes == (m_includes.Index(val) != wxNOT_FOUND); 126 if ( !ok ) 127 { 128 errormsg = _("'%s' is invalid"); 129 } 130 } 131 else if ( (m_validatorStyle & wxFILTER_ASCII) && !val.IsAscii() ) 132 { 133 ok = false; 134 135 errormsg = _("'%s' should only contain ASCII characters."); 136 } 137 else if ( (m_validatorStyle & wxFILTER_ALPHA) && !wxIsAlpha(val) ) 138 { 139 ok = false; 140 141 errormsg = _("'%s' should only contain alphabetic characters."); 142 } 143 else if ( (m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsAlphaNumeric(val)) 144 { 145 ok = false; 146 147 errormsg = _("'%s' should only contain alphabetic or numeric characters."); 148 } 149 else if ( (m_validatorStyle & wxFILTER_NUMERIC) && !wxIsNumeric(val)) 150 { 151 ok = false; 152 153 errormsg = _("'%s' should be numeric."); 154 } 155 else if ( (m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(val)) 156 { 157 //it's only ok to have the members of the list 158 errormsg = _("'%s' is invalid"); 159 ok = false; 160 } 161 else if ( (m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(val)) 162 { 163 // it's only ok to have non-members of the list 164 errormsg = _("'%s' is invalid"); 165 ok = false; 166 } 167 168 if ( !ok ) 169 { 170 wxASSERT_MSG( !errormsg.empty(), _T("you forgot to set errormsg") ); 171 172 m_validatorWindow->SetFocus(); 173 174 wxString buf; 175 buf.Printf(errormsg, val.c_str()); 176 177 wxMessageBox(buf, _("Validation conflict"), 178 wxOK | wxICON_EXCLAMATION, parent); 179 } 180 181 return ok; 182} 183 184// Called to transfer data to the window 185bool wxTextValidator::TransferToWindow(void) 186{ 187 if( !CheckValidator() ) 188 return false; 189 190 if ( m_stringValue ) 191 { 192 wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow; 193 control->SetValue(* m_stringValue); 194 } 195 196 return true; 197} 198 199// Called to transfer data to the window 200bool wxTextValidator::TransferFromWindow(void) 201{ 202 if( !CheckValidator() ) 203 return false; 204 205 if ( m_stringValue ) 206 { 207 wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow; 208 *m_stringValue = control->GetValue(); 209 } 210 211 return true; 212} 213 214#if WXWIN_COMPATIBILITY_2_4 215 216inline void wxCopyStringListToArrayString(wxArrayString& to, const wxStringList& from) 217{ 218 to.Clear(); 219 220 for ( wxStringList::compatibility_iterator pNode = from.GetFirst(); 221 pNode; 222 pNode = pNode->GetNext() ) 223 { 224 to.Add(pNode->GetData()); 225 } 226} 227 228inline void wxCopyArrayStringToStringList(wxStringList& to, const wxArrayString& from) 229{ 230 to.Clear(); 231 232 for(size_t i = 0; i < from.GetCount(); ++i) 233 to.Add(from[i]); 234} 235 236wxStringList& wxTextValidator::GetIncludeList() 237{ 238 wxCopyArrayStringToStringList(m_includeList, m_includes); 239 return m_includeList; 240} 241 242wxStringList& wxTextValidator::GetExcludeList() 243{ 244 wxCopyArrayStringToStringList(m_excludeList, m_excludes); 245 return m_excludeList; 246} 247 248void wxTextValidator::SetIncludeList(const wxStringList& list) 249{ 250 wxCopyStringListToArrayString(m_includes, list); 251} 252 253void wxTextValidator::SetExcludeList(const wxStringList& list) 254{ 255 wxCopyStringListToArrayString(m_excludes, list); 256} 257 258bool wxTextValidator::IsInCharIncludeList(const wxString& val) 259{ 260 return IsInCharIncludes(val); 261} 262 263bool wxTextValidator::IsNotInCharExcludeList(const wxString& val) 264{ 265 return IsNotInCharExcludes(val); 266} 267 268#endif //compat 2.4 269 270 271bool wxTextValidator::IsInCharIncludes(const wxString& val) 272{ 273 size_t i; 274 for ( i = 0; i < val.length(); i++) 275 { 276 if (m_includes.Index((wxString) val[i]) == wxNOT_FOUND) 277 return false; 278 } 279 return true; 280} 281 282bool wxTextValidator::IsNotInCharExcludes(const wxString& val) 283{ 284 size_t i; 285 for ( i = 0; i < val.length(); i++) 286 { 287 if (m_excludes.Index((wxString) val[i]) != wxNOT_FOUND) 288 return false; 289 } 290 return true; 291} 292 293void wxTextValidator::OnChar(wxKeyEvent& event) 294{ 295/* 296 if ( !M_VTEXTDATA ) 297 return; 298*/ 299 300 if ( m_validatorWindow ) 301 { 302 int keyCode = event.GetKeyCode(); 303 304 // we don't filter special keys and Delete 305 if ( 306 !(keyCode < WXK_SPACE || keyCode == WXK_DELETE || keyCode > WXK_START) && 307 ( 308 ((m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(wxString((wxChar) keyCode, 1))) || 309 ((m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(wxString((wxChar) keyCode, 1))) || 310 ((m_validatorStyle & wxFILTER_ASCII) && !isascii(keyCode)) || 311 ((m_validatorStyle & wxFILTER_ALPHA) && !wxIsalpha(keyCode)) || 312 ((m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsalnum(keyCode)) || 313 ((m_validatorStyle & wxFILTER_NUMERIC) && !wxIsdigit(keyCode) 314 && keyCode != wxT('.') && keyCode != wxT(',') && keyCode != wxT('-') && keyCode != wxT('+') && keyCode != wxT('e') && keyCode != wxT('E')) 315 ) 316 ) 317 { 318 if ( !wxValidator::IsSilent() ) 319 wxBell(); 320 321 // eat message 322 return; 323 } 324 } 325 326 event.Skip(); 327} 328 329static bool wxIsNumeric(const wxString& val) 330{ 331 int i; 332 for ( i = 0; i < (int)val.length(); i++) 333 { 334 // Allow for "," (French) as well as "." -- in future we should 335 // use wxSystemSettings or other to do better localisation 336 if ((!wxIsdigit(val[i])) && (val[i] != wxT('.')) && (val[i] != wxT(',')) && (val[i] != wxT('e')) && (val[i] != wxT('E')) && (val[i] != wxT('+')) && (val[i] != wxT('-'))) 337 return false; 338 } 339 return true; 340} 341 342 343#endif 344 // wxUSE_VALIDATORS && wxUSE_TEXTCTRL 345