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 <[email protected]>
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 <string_utils.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#include <wx/combo.h>
40
42{
43}
44
45
46void 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
55void 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 footprint.cpp which, in turn mimics the
75 // strings from lib_id.cpp
76 // TODO: Unify forbidden character lists
77 wxString illegalChars = wxS( "%$<>\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
130void 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
201void 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
220bool 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
258void 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
271bool LIB_ID_VALIDATOR::Validate( wxWindow *aParent )
272{
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 ) != -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
320 wxTextValidator(),
321 m_allowSpaces( false )
322{
323}
324
325
327 wxTextValidator( aValidator ),
328 m_allowSpaces( aValidator.m_allowSpaces )
329{
330}
331
332
334 wxTextValidator(),
335 m_allowSpaces( aAllowSpaces )
336{
337}
338
339
340bool NETNAME_VALIDATOR::Validate( wxWindow *aParent )
341{
342 // If window is disabled, simply return
343 if ( !m_validatorWindow->IsEnabled() )
344 return true;
345
346 wxTextEntry * const text = GetTextEntry();
347
348 if ( !text )
349 return false;
350
351 const wxString& errormsg = IsValid( text->GetValue() );
352
353 if( !errormsg.empty() )
354 {
355 m_validatorWindow->SetFocus();
356 wxMessageBox( errormsg, _( "Invalid signal name" ), wxOK | wxICON_EXCLAMATION, aParent );
357 return false;
358 }
359
360 return true;
361}
362
363
364wxString NETNAME_VALIDATOR::IsValid( const wxString& str ) const
365{
366 if( str.Contains( '\r' ) || str.Contains( '\n' ) )
367 return _( "Signal names cannot contain CR or LF characters" );
368
369 if( !m_allowSpaces && ( str.Contains( ' ' ) || str.Contains( '\t' ) ) )
370 return _( "Signal names cannot contain spaces" );
371
372 return wxString();
373}
374
375
376void KIUI::ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator )
377{
378 wxWindow* ctrl = aValidator.GetWindow();
379
380 wxCHECK_RET( ctrl != nullptr, wxS( "Transferring validator data without a control" ) );
381
382 wxEventBlocker orient_update_blocker( ctrl, wxEVT_ANY );
383 aValidator.TransferToWindow();
384}
This class provides a custom wxValidator object for limiting the allowable characters when defining a...
Definition: validators.h:92
virtual ~ENV_VAR_NAME_VALIDATOR()
Definition: validators.cpp:124
void OnChar(wxKeyEvent &event)
Definition: validators.cpp:130
ENV_VAR_NAME_VALIDATOR(wxString *aValue=nullptr)
Definition: validators.cpp:108
void OnTextChanged(wxCommandEvent &event)
Definition: validators.cpp:201
FILE_NAME_WITH_PATH_CHAR_VALIDATOR(wxString *aValue=nullptr)
Definition: validators.cpp:82
FOOTPRINT_NAME_VALIDATOR(wxString *aValue=nullptr)
Definition: validators.cpp:71
wxScopedPtr< wxValidator > m_validator
Definition: validators.h:53
virtual void StartingKey(wxKeyEvent &event) override
Definition: validators.cpp:55
virtual void SetValidator(const wxValidator &validator) override
Definition: validators.cpp:46
bool Validate(wxWindow *aParent) override
Definition: validators.cpp:271
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
wxString IsValid(const wxString &aVal) const override
Definition: validators.cpp:364
virtual bool Validate(wxWindow *aParent) override
Definition: validators.cpp:340
NETNAME_VALIDATOR(wxString *aVal=nullptr)
Definition: validators.cpp:319
wxRegEx m_regEx
Definition: validators.h:168
bool Validate(wxWindow *aParent) override
Definition: validators.cpp:220
wxString m_regExString
Original compilation flags (for copy constructor)
Definition: validators.h:162
int m_regExFlags
Compiled regex.
Definition: validators.h:165
void compileRegEx(const wxString &aRegEx, int aFlags)
< Compiles and stores a regular expression
Definition: validators.cpp:258
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
This file is part of the common library.
#define _(s)
void ValidatorTransferToWindowWithoutEvents(wxValidator &aValidator)
Call a text validator's TransferDataToWindow method without firing a text change event.
Definition: validators.cpp:376
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
std::vector< FAB_LAYER_COLOR > dummy
Custom text control validator definitions.