KiCad PCB EDA Suite
validators.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
5  * Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors.
6  * Copyright (C) 2018 CERN
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
31 #include <kicad_string.h>
32 #include <confirm.h>
33 #include <validators.h>
34 
35 #include <wx/grid.h>
36 #include <wx/textctrl.h>
37 #include <wx/textentry.h>
38 #include <wx/log.h>
39 
40 
42 {
43 }
44 
45 
46 void GRID_CELL_TEXT_EDITOR::SetValidator( const wxValidator& validator )
47 {
48  // keep our own copy because wxGridCellTextEditor's is annoyingly private
49  m_validator.reset( static_cast<wxValidator*>( validator.Clone() ) );
50 
51  wxGridCellTextEditor::SetValidator( *m_validator );
52 }
53 
54 
55 void GRID_CELL_TEXT_EDITOR::StartingKey( wxKeyEvent& event )
56 {
57  if( m_validator )
58  {
59  m_validator.get()->SetWindow( Text() );
60  m_validator.get()->ProcessEvent( event );
61  }
62 
63  if( event.GetSkipped() )
64  {
65  wxGridCellTextEditor::StartingKey( event );
66  event.Skip( false );
67  }
68 }
69 
70 
72  wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST, aValue )
73 {
74  // This list of characters follows the string from class_module.cpp
75  // which, in turn mimics the strings from lib_id.cpp
76  // TODO: Unify forbidden character lists
77  wxString illegalChars = "%$<>\t\n\r\"\\/:";
78  SetCharExcludes( illegalChars );
79  }
80 
81 
83  wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST | wxFILTER_EMPTY, aValue )
84 {
85  // The Windows (DOS) file system forbidden characters already include the forbidden
86  // file name characters for both Posix and OSX systems. The characters *?|"<> are
87  // illegal and filtered by the validator, but /\: are valid (\ and : only on Windows.
88  wxString illegalChars = wxFileName::GetForbiddenChars( wxPATH_DOS );
89  wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
90  wxArrayString illegalCharList;
91 
92  for( unsigned i = 0; i < illegalChars.size(); i++ )
93  {
94  if( illegalChars[i] == '/' )
95  continue;
96 
97 #if defined (__WINDOWS__)
98  if( illegalChars[i] == '\\' || illegalChars[i] == ':' )
99  continue;
100 #endif
101  illegalCharList.Add( wxString( illegalChars[i] ) );
102  }
103 
104  SetExcludes( illegalCharList );
105 }
106 
107 
109  wxTextValidator()
110 {
111  Connect( wxEVT_CHAR, wxKeyEventHandler( ENV_VAR_NAME_VALIDATOR::OnChar ) );
112 }
113 
114 
116  : wxTextValidator()
117 {
118  wxValidator::Copy( val );
119 
120  Connect( wxEVT_CHAR, wxKeyEventHandler( ENV_VAR_NAME_VALIDATOR::OnChar ) );
121 }
122 
123 
125 {
126  Disconnect( wxEVT_CHAR, wxKeyEventHandler( ENV_VAR_NAME_VALIDATOR::OnChar ) );
127 }
128 
129 
130 void ENV_VAR_NAME_VALIDATOR::OnChar( wxKeyEvent& aEvent )
131 {
132  if( !m_validatorWindow )
133  {
134  aEvent.Skip();
135  return;
136  }
137 
138  int keyCode = aEvent.GetKeyCode();
139 
140  // we don't filter special keys and delete
141  if( keyCode < WXK_SPACE || keyCode == WXK_DELETE || keyCode >= WXK_START )
142  {
143  aEvent.Skip();
144  return;
145  }
146 
147  wxUniChar c = (wxUChar) keyCode;
148 
149  if( c == wxT( '_' ) )
150  {
151  // OK anywhere
152  aEvent.Skip();
153  }
154  else if( wxIsdigit( c ) )
155  {
156  // not as first character
157  long from, to;
158  GetTextEntry()->GetSelection( &from, &to );
159 
160  if( from < 1 )
161  wxBell();
162  else
163  aEvent.Skip();
164  }
165  else if( wxIsalpha( c ) )
166  {
167  // Capitals only.
168 
169  if( wxIslower( c ) )
170  {
171  // You may wonder why this scope is so twisted, so make yourself comfortable and read:
172  // 1. Changing the keyCode and/or uniChar in the event and passing it on
173  // doesn't work. Some platforms look at the original copy as long as the event
174  // isn't vetoed.
175  // 2. Inserting characters by hand does not move the cursor, meaning either you insert
176  // text backwards (lp:#1798869) or always append, no matter where is the cursor.
177  // wxTextEntry::{Get/Set}InsertionPoint() do not work at all here.
178  // 3. There is wxTextEntry::ForceUpper(), but it is not yet available in common
179  // wxWidgets packages.
180  //
181  // So here we are, with a command event handler that converts
182  // the text to upper case upon every change.
183  wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( GetTextEntry() );
184 
185  if( textCtrl )
186  {
187  textCtrl->Connect( textCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED,
188  wxCommandEventHandler( ENV_VAR_NAME_VALIDATOR::OnTextChanged ) );
189  }
190  }
191 
192  aEvent.Skip();
193  }
194  else
195  {
196  wxBell();
197  }
198 }
199 
200 
201 void ENV_VAR_NAME_VALIDATOR::OnTextChanged( wxCommandEvent& event )
202 {
203  wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
204 
205  if( textCtrl )
206  {
207  if( !textCtrl->IsModified() )
208  return;
209 
210  long insertionPoint = textCtrl->GetInsertionPoint();
211  textCtrl->ChangeValue( textCtrl->GetValue().Upper() );
212  textCtrl->SetInsertionPoint( insertionPoint );
213  textCtrl->Disconnect( textCtrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED );
214  }
215 
216  event.Skip();
217 }
218 
219 
220 bool REGEX_VALIDATOR::Validate( wxWindow* aParent )
221 {
222  // If window is disabled, simply return
223  if( !m_validatorWindow->IsEnabled() )
224  return true;
225 
226  wxTextEntry* const textEntry = GetTextEntry();
227 
228  if( !textEntry )
229  return false;
230 
231  bool valid = true;
232  const wxString& value = textEntry->GetValue();
233 
234  if( m_regEx.Matches( value ) )
235  {
236  size_t start, len;
237  m_regEx.GetMatch( &start, &len );
238 
239  if( start != 0 || len != value.Length() ) // whole string must match
240  valid = false;
241  }
242  else // no match at all
243  {
244  valid = false;
245  }
246 
247  if( !valid )
248  {
249  m_validatorWindow->SetFocus();
250  DisplayError( aParent, wxString::Format( _( "Incorrect value: %s" ), value ) );
251  return false;
252  }
253 
254  return true;
255 }
256 
257 
258 void REGEX_VALIDATOR::compileRegEx( const wxString& aRegEx, int aFlags )
259 {
260  if( !m_regEx.Compile( aRegEx, aFlags ) )
261  {
262  throw std::runtime_error( "REGEX_VALIDATOR: Invalid regular expression: "
263  + aRegEx.ToStdString() );
264  }
265 
266  m_regExString = aRegEx;
267  m_regExFlags = aFlags;
268 }
269 
270 
271 bool LIB_ID_VALIDATOR::Validate( wxWindow *aParent )
272 {
273  LIB_ID dummy;
274 
275  // If window is disabled, simply return
276  if( !m_validatorWindow->IsEnabled() )
277  return true;
278 
279  wxTextEntry* const text = GetTextEntry();
280 
281  if( !text )
282  return false;
283 
284  wxString msg;
285  wxString val( text->GetValue() );
286  wxString tmp = val.Clone(); // For trailing and leading white space tests.
287 
288  // Allow empty string if empty filter not set to allow clearing the LIB_ID.
289  if( !(GetStyle() & wxFILTER_EMPTY) && val.IsEmpty() )
290  return true;
291 
292  if( tmp.Trim() != val ) // Trailing white space.
293  {
294  msg = _( "Entry contains trailing white space." );
295  }
296  else if( tmp.Trim( false ) != val ) // Leading white space.
297  {
298  msg = _( "Entry contains leading white space." );
299  }
300  else if( dummy.Parse( val, m_idType ) != -1 || !dummy.IsValid() ) // Is valid LIB_ID.
301  {
302  msg.Printf( _( "\"%s\" is not a valid library identifier format." ), val );
303  }
304 
305  if( !msg.empty() )
306  {
307  m_validatorWindow->SetFocus();
308 
309  wxMessageBox( msg, _( "Library Identifier Validation Error" ),
310  wxOK | wxICON_EXCLAMATION, aParent );
311 
312  return false;
313  }
314 
315  return true;
316 }
317 
318 
319 void KIUI::ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator )
320 {
321  wxWindow* ctrl = aValidator.GetWindow();
322 
323  wxCHECK_RET( ctrl != nullptr, "Transferring validator data without a control" );
324 
325  wxEventBlocker orient_update_blocker( ctrl, wxEVT_ANY );
326  aValidator.TransferToWindow();
327 }
ENV_VAR_NAME_VALIDATOR(wxString *aValue=NULL)
Definition: validators.cpp:108
wxString m_regExString
Original regular expression (for copy constructor)
Definition: validators.h:157
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:236
wxRegEx m_regEx
Compiled regex
Definition: validators.h:163
This file is part of the common library.
void compileRegEx(const wxString &aRegEx, int aFlags)
Compiles and stores a regular expression
Definition: validators.cpp:258
void ValidatorTransferToWindowWithoutEvents(wxValidator &aValidator)
Call a text validator's TransferDataToWindow method without firing a text change event.
Definition: validators.cpp:319
wxScopedPtr< wxValidator > m_validator
Definition: validators.h:53
bool Validate(wxWindow *aParent) override
Definition: validators.cpp:220
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
virtual void StartingKey(wxKeyEvent &event) override
Definition: validators.cpp:55
LIB_ID::LIB_ID_TYPE m_idType
Definition: validators.h:194
void OnTextChanged(wxCommandEvent &event)
Definition: validators.cpp:201
virtual void SetValidator(const wxValidator &validator) override
Definition: validators.cpp:46
MODULE_NAME_CHAR_VALIDATOR(wxString *aValue=NULL)
Definition: validators.cpp:71
This class provides a custom wxValidator object for limiting the allowable characters when defining a...
Definition: validators.h:91
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
FILE_NAME_WITH_PATH_CHAR_VALIDATOR(wxString *aValue=NULL)
Definition: validators.cpp:82
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
#define _(s)
Definition: 3d_actions.cpp:31
int m_regExFlags
Original compilation flags (for copy constructor)
Definition: validators.h:160
bool Validate(wxWindow *aParent) override
Definition: validators.cpp:271
Custom text control validator definitions.
void OnChar(wxKeyEvent &event)
Definition: validators.cpp:130
virtual ~ENV_VAR_NAME_VALIDATOR()
Definition: validators.cpp:124