KiCad PCB EDA Suite
fields_grid_table.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) 2018-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <kiway.h>
25 #include <kiway_player.h>
26 #include <dialog_shim.h>
27 #include <fields_grid_table.h>
28 #include <sch_base_frame.h>
29 #include <sch_field.h>
30 #include <sch_validators.h>
31 #include <validators.h>
32 #include <class_library.h>
33 #include <template_fieldnames.h>
36 
37 #include "eda_doc.h"
38 
39 
40 enum
41 {
42  MYID_SELECT_FOOTPRINT = 991, // must be within GRID_TRICKS' enum range
44 };
45 
46 
47 template <class T>
49  LIB_PART* aPart ) :
50  m_frame( aFrame ),
51  m_userUnits( aDialog->GetUserUnits() ),
52  m_part( aPart ),
53  m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ),
54  m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ),
55  m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE )
56 {
57  // Build the various grid cell attributes.
58 
59  m_readOnlyAttr = new wxGridCellAttr;
60  m_readOnlyAttr->SetReadOnly( true );
61 
62  m_fieldNameAttr = new wxGridCellAttr;
63  GRID_CELL_TEXT_EDITOR* nameEditor = new GRID_CELL_TEXT_EDITOR();
64  nameEditor->SetValidator( m_fieldNameValidator );
65  m_fieldNameAttr->SetEditor( nameEditor );
66 
67  m_referenceAttr = new wxGridCellAttr;
68  GRID_CELL_TEXT_EDITOR* referenceEditor = new GRID_CELL_TEXT_EDITOR();
69  referenceEditor->SetValidator( m_referenceValidator );
70  m_referenceAttr->SetEditor( referenceEditor );
71 
72  m_valueAttr = new wxGridCellAttr;
73  GRID_CELL_TEXT_EDITOR* valueEditor = new GRID_CELL_TEXT_EDITOR();
74  valueEditor->SetValidator( m_valueValidator );
75  m_valueAttr->SetEditor( valueEditor );
76 
77  m_footprintAttr = new wxGridCellAttr;
79  fpIdEditor->SetValidator( LIB_ID_VALIDATOR( LIB_ID::ID_PCB ) );
80  m_footprintAttr->SetEditor( fpIdEditor );
81 
82  m_urlAttr = new wxGridCellAttr;
83  GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( aDialog );
84  urlEditor->SetValidator( SCH_FIELD_VALIDATOR( aFrame->IsType( FRAME_SCH_LIB_EDITOR ),
85  DATASHEET ) );
86  m_urlAttr->SetEditor( urlEditor );
87 
88  m_nonUrlAttr = new wxGridCellAttr;
89  wxGridCellTextEditor* nonUrlEditor = new wxGridCellTextEditor();
90  nonUrlEditor->SetValidator( SCH_FIELD_VALIDATOR( aFrame->IsType( FRAME_SCH_LIB_EDITOR ),
91  DATASHEET ) );
92  m_nonUrlAttr->SetEditor( nonUrlEditor );
93 
94  m_boolAttr = new wxGridCellAttr;
95  m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
96  m_boolAttr->SetEditor( new wxGridCellBoolEditor() );
97  m_boolAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
98 
99  wxArrayString vAlignNames;
100  vAlignNames.Add( _( "Top" ) );
101  vAlignNames.Add( _( "Center" ) );
102  vAlignNames.Add( _( "Bottom" ) );
103  m_vAlignAttr = new wxGridCellAttr;
104  m_vAlignAttr->SetEditor( new wxGridCellChoiceEditor( vAlignNames ) );
105  m_vAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
106 
107  wxArrayString hAlignNames;
108  hAlignNames.Add( _( "Left" ) );
109  hAlignNames.Add(_( "Center" ) );
110  hAlignNames.Add(_( "Right" ) );
111  m_hAlignAttr = new wxGridCellAttr;
112  m_hAlignAttr->SetEditor( new wxGridCellChoiceEditor( hAlignNames ) );
113  m_hAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
114 
115  wxArrayString orientationNames;
116  orientationNames.Add( _( "Horizontal" ) );
117  orientationNames.Add(_( "Vertical" ) );
118  m_orientationAttr = new wxGridCellAttr;
119  m_orientationAttr->SetEditor( new wxGridCellChoiceEditor( orientationNames ) );
120  m_orientationAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
121 }
122 
123 
124 template <class T>
126 {
127  m_readOnlyAttr->DecRef();
128  m_fieldNameAttr->DecRef();
129  m_boolAttr->DecRef();
130  m_referenceAttr->DecRef();
131  m_valueAttr->DecRef();
132  m_footprintAttr->DecRef();
133  m_urlAttr->DecRef();
134  m_vAlignAttr->DecRef();
135  m_hAlignAttr->DecRef();
136  m_orientationAttr->DecRef();
137 }
138 
139 
140 template <class T>
142 {
143  switch( aCol )
144  {
145  case FDC_NAME: return _( "Name" );
146  case FDC_VALUE: return _( "Value" );
147  case FDC_SHOWN: return _( "Show" );
148  case FDC_H_ALIGN: return _( "H Align" );
149  case FDC_V_ALIGN: return _( "V Align" );
150  case FDC_ITALIC: return _( "Italic" );
151  case FDC_BOLD: return _( "Bold" );
152  case FDC_TEXT_SIZE: return _( "Text Size" );
153  case FDC_ORIENTATION: return _( "Orientation" );
154  case FDC_POSX: return _( "X Position" );
155  case FDC_POSY: return _( "Y Position" );
156  default: wxFAIL; return wxEmptyString;
157  }
158 }
159 
160 
161 template <class T>
162 bool FIELDS_GRID_TABLE<T>::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
163 {
164  switch( aCol )
165  {
166  case FDC_NAME:
167  case FDC_VALUE:
168  case FDC_H_ALIGN:
169  case FDC_V_ALIGN:
170  case FDC_TEXT_SIZE:
171  case FDC_ORIENTATION:
172  case FDC_POSX:
173  case FDC_POSY:
174  return aTypeName == wxGRID_VALUE_STRING;
175 
176  case FDC_SHOWN:
177  case FDC_ITALIC:
178  case FDC_BOLD:
179  return aTypeName == wxGRID_VALUE_BOOL;
180 
181  default:
182  wxFAIL;
183  return false;
184  }
185 }
186 
187 
188 template <class T>
189 bool FIELDS_GRID_TABLE<T>::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
190 {
191  return CanGetValueAs( aRow, aCol, aTypeName );
192 }
193 
194 
195 template <class T>
196 wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
197 {
198  switch( aCol )
199  {
200  case FDC_NAME:
201  if( aRow < MANDATORY_FIELDS )
202  {
203  m_readOnlyAttr->IncRef();
204  return m_readOnlyAttr;
205  }
206  else
207  {
208  m_fieldNameAttr->IncRef();
209  return m_fieldNameAttr;
210  }
211 
212  case FDC_VALUE:
213  if( aRow == REFERENCE )
214  {
215  m_referenceAttr->IncRef();
216  return m_referenceAttr;
217  }
218  else if( aRow == VALUE )
219  {
220  // For power symbols, the value is not editable, because value and pin name must
221  // be the same and can be edited only in library editor.
222  if( m_part && m_part->IsPower() && ! m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
223  {
224  m_readOnlyAttr->IncRef();
225  return m_readOnlyAttr;
226  }
227  else
228  {
229  m_valueAttr->IncRef();
230  return m_valueAttr;
231  }
232  }
233  else if( aRow == FOOTPRINT )
234  {
235  m_footprintAttr->IncRef();
236  return m_footprintAttr;
237  }
238  else if( aRow == DATASHEET )
239  {
240  m_urlAttr->IncRef();
241  return m_urlAttr;
242  }
243  else
244  {
245  wxString fieldname = GetValue( aRow, FDC_NAME );
246  const TEMPLATE_FIELDNAME* templateFn = m_frame->GetTemplateFieldName( fieldname );
247 
248  if( templateFn && templateFn->m_URL )
249  {
250  m_urlAttr->IncRef();
251  return m_urlAttr;
252  }
253  else
254  {
255  m_nonUrlAttr->IncRef();
256  return m_nonUrlAttr;
257  }
258  }
259  return nullptr;
260 
261  case FDC_TEXT_SIZE:
262  case FDC_POSX:
263  case FDC_POSY:
264  return nullptr;
265 
266  case FDC_H_ALIGN:
267  m_hAlignAttr->IncRef();
268  return m_hAlignAttr;
269 
270  case FDC_V_ALIGN:
271  m_vAlignAttr->IncRef();
272  return m_vAlignAttr;
273 
274  case FDC_ORIENTATION:
275  m_orientationAttr->IncRef();
276  return m_orientationAttr;
277 
278  case FDC_SHOWN:
279  case FDC_ITALIC:
280  case FDC_BOLD:
281  m_boolAttr->IncRef();
282  return m_boolAttr;
283 
284  default:
285  wxFAIL;
286  return nullptr;
287  }
288 }
289 
290 
291 template <class T>
292 wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
293 {
294  wxCHECK( aRow < GetNumberRows(), wxEmptyString );
295  const T& field = this->at( (size_t) aRow );
296 
297  switch( aCol )
298  {
299  case FDC_NAME:
300  // Use default field name for mandatory fields, because they are translated
301  // according to the current locale
302  if( aRow < MANDATORY_FIELDS )
304  else
305  return field.GetName( false );
306 
307  case FDC_VALUE:
308  return field.GetText();
309 
310  case FDC_SHOWN:
311  return StringFromBool( field.IsVisible() );
312 
313  case FDC_H_ALIGN:
314  switch ( field.GetHorizJustify() )
315  {
317  return _( "Left" );
319  return _( "Center" );
321  return _( "Right" );
322  }
323 
324  break;
325 
326  case FDC_V_ALIGN:
327  switch ( field.GetVertJustify() )
328  {
330  return _( "Top" );
332  return _( "Center" );
334  return _( "Bottom" );
335  }
336 
337  break;
338 
339  case FDC_ITALIC:
340  return StringFromBool( field.IsItalic() );
341 
342  case FDC_BOLD:
343  return StringFromBool( field.IsBold() );
344 
345  case FDC_TEXT_SIZE:
346  return StringFromValue( m_userUnits, field.GetTextSize().GetHeight(), true, true );
347 
348  case FDC_ORIENTATION:
349  switch ( (int) field.GetTextAngle() )
350  {
351  case TEXT_ANGLE_HORIZ:
352  return _( "Horizontal" );
353  case TEXT_ANGLE_VERT:
354  return _( "Vertical" );
355  }
356 
357  break;
358 
359  case FDC_POSX:
360  return StringFromValue( m_userUnits, field.GetTextPos().x, true );
361 
362  case FDC_POSY:
363  return StringFromValue( m_userUnits, field.GetTextPos().y, true );
364 
365  default:
366  // we can't assert here because wxWidgets sometimes calls this without checking
367  // the column type when trying to see if there's an overflow
368  break;
369  }
370 
371  return wxT( "bad wxWidgets!" );
372 }
373 
374 
375 template <class T>
376 bool FIELDS_GRID_TABLE<T>::GetValueAsBool( int aRow, int aCol )
377 {
378  wxCHECK( aRow < GetNumberRows(), false );
379  const T& field = this->at( (size_t) aRow );
380 
381  switch( aCol )
382  {
383  case FDC_SHOWN: return field.IsVisible();
384  case FDC_ITALIC: return field.IsItalic();
385  case FDC_BOLD: return field.IsBold();
386  default:
387  wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
388  return false;
389  }
390 }
391 
392 
393 template <class T>
394 void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue )
395 {
396  wxCHECK( aRow < GetNumberRows(), /*void*/ );
397  T& field = this->at( (size_t) aRow );
398  wxPoint pos;
399 
400  switch( aCol )
401  {
402  case FDC_NAME:
403  field.SetName( aValue );
404  break;
405 
406  case FDC_VALUE:
407  field.SetText( aValue );
408  break;
409 
410  case FDC_SHOWN:
411  field.SetVisible( BoolFromString( aValue ) );
412  break;
413 
414  case FDC_H_ALIGN:
415  if( aValue == _( "Left" ) )
416  field.SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
417  else if( aValue == _( "Center" ) )
418  field.SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
419  else if( aValue == _( "Right" ) )
420  field.SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
421  else
422  wxFAIL_MSG( wxT( "unknown horizontal alignment: " ) + aValue );
423  break;
424 
425  case FDC_V_ALIGN:
426  if( aValue == _( "Top" ) )
427  field.SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
428  else if( aValue == _( "Center" ) )
429  field.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
430  else if( aValue == _( "Bottom" ) )
431  field.SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
432  else
433  wxFAIL_MSG( wxT( "unknown vertical alignment: " ) + aValue);
434  break;
435 
436  case FDC_ITALIC:
437  field.SetItalic( BoolFromString( aValue ) );
438  break;
439 
440  case FDC_BOLD:
441  field.SetBold( BoolFromString( aValue ) );
442  break;
443 
444  case FDC_TEXT_SIZE:
445  field.SetTextSize( wxSize( ValueFromString( m_userUnits, aValue ),
446  ValueFromString( m_userUnits, aValue ) ) );
447  break;
448 
449  case FDC_ORIENTATION:
450  if( aValue == _( "Horizontal" ) )
451  field.SetTextAngle( TEXT_ANGLE_HORIZ );
452  else if( aValue == _( "Vertical" ) )
453  field.SetTextAngle( TEXT_ANGLE_VERT );
454  else
455  wxFAIL_MSG( wxT( "unknown orientation: " ) + aValue );
456  break;
457 
458  case FDC_POSX:
459  case FDC_POSY:
460  pos = field.GetTextPos();
461  if( aCol == FDC_POSX )
462  pos.x = ValueFromString( m_userUnits, aValue );
463  else
464  pos.y = ValueFromString( m_userUnits, aValue );
465  field.SetTextPos( pos );
466  break;
467 
468  default:
469  wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
470  break;
471  }
472 
473  GetView()->Refresh();
474 }
475 
476 
477 template <class T>
478 void FIELDS_GRID_TABLE<T>::SetValueAsBool( int aRow, int aCol, bool aValue )
479 {
480  wxCHECK( aRow < GetNumberRows(), /*void*/ );
481  T& field = this->at( (size_t) aRow );
482 
483  switch( aCol )
484  {
485  case FDC_SHOWN:
486  field.SetVisible( aValue );
487  break;
488  case FDC_ITALIC:
489  field.SetItalic( aValue );
490  break;
491  case FDC_BOLD:
492  field.SetBold( aValue );
493  break;
494  default:
495  wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
496  break;
497  }
498 }
499 
500 
501 // Explicit Instantiations
502 
503 template class FIELDS_GRID_TABLE<SCH_FIELD>;
504 template class FIELDS_GRID_TABLE<LIB_FIELD>;
505 
506 
508 {
509  if( m_grid->GetGridCursorRow() == FOOTPRINT && m_grid->GetGridCursorCol() == FDC_VALUE )
510  {
511  menu.Append( MYID_SELECT_FOOTPRINT, _( "Select Footprint..." ),
512  _( "Browse for footprint" ) );
513  menu.AppendSeparator();
514  }
515  else if( m_grid->GetGridCursorRow() == DATASHEET && m_grid->GetGridCursorCol() == FDC_VALUE )
516  {
517  menu.Append( MYID_SHOW_DATASHEET, _( "Show Datasheet" ),
518  _( "Show datasheet in browser" ) );
519  menu.AppendSeparator();
520  }
521 
523 }
524 
525 
526 void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
527 {
528  if( event.GetId() == MYID_SELECT_FOOTPRINT )
529  {
530  // pick a footprint using the footprint picker.
531  wxString fpid = m_grid->GetCellValue( FOOTPRINT, FDC_VALUE );
533 
534  if( frame->ShowModal( &fpid, m_dlg ) )
535  m_grid->SetCellValue( FOOTPRINT, FDC_VALUE, fpid );
536 
537  frame->Destroy();
538  }
539  else if (event.GetId() == MYID_SHOW_DATASHEET )
540  {
541  wxString datasheet_uri = m_grid->GetCellValue( DATASHEET, FDC_VALUE );
542  GetAssociatedDocument( m_dlg, datasheet_uri );
543  }
544  else
545  {
547  }
548 }
549 
550 
551 template <class T>
553 {
554  if( aValue )
555  return wxT( "1" );
556  else
557  return wxT( "0" );
558 }
559 
560 
561 template <class T>
563 {
564  if( aValue == "1" )
565  {
566  return true;
567  }
568  else if( aValue == "0" )
569  {
570  return false;
571  }
572  else
573  {
574  wxFAIL_MSG( wxString::Format( "string \"%s\" can't be converted to boolean "
575  "correctly, it will have been perceived as FALSE", aValue ) );
576  return false;
577  }
578 }
#define TEXT_ANGLE_HORIZ
virtual void showPopupMenu(wxMenu &menu) override
Class KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a porti...
Definition: kiway_player.h:127
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:61
name of datasheet
#define TEXT_ANGLE_VERT
int GetUserUnits()
Returns the currently selected user unit value for the interface.
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
This file is part of the common library.
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
wxGridCellAttr * m_referenceAttr
bool m_URL
If field should have a browse button.
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, const wxPathList *aPaths)
Function GetAssociatedDocument open a document (file) with the suitable browser.
Definition: eda_doc.cpp:87
static const wxString GetDefaultFieldName(int aFieldNdx)
Function GetDefaultFieldName returns a default symbol field name for field aFieldNdx for all componen...
Class DIALOG_SHIM may sit in the inheritance tree between wxDialog and any class written by wxFormBui...
Definition: dialog_shim.h:83
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue, bool aUseMils)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application.
Definition: base_units.cpp:409
wxString GetColLabelValue(int aCol) override
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
This class works around a bug in wxGrid where the first keystroke doesn't get sent through the valida...
Definition: validators.h:44
wxGridCellAttr * m_readOnlyAttr
WX_GRID * m_grid
I don't own the grid, but he owns me.
Definition: grid_tricks.h:58
#define VALUE
wxGridCellAttr * m_hAlignAttr
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:321
SCH_FIELD_VALIDATOR m_referenceValidator
Definitions of control validators for schematic dialogs.
wxString GetValue(int aRow, int aCol) override
SCH_FIELD_VALIDATOR m_fieldNameValidator
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
wxGridCellAttr * m_boolAttr
Define a library symbol object.
Custom validator that verifies that a string defines a valid LIB_ID.
Definition: validators.h:170
#define FIELD_NAME
bool BoolFromString(wxString aValue)
wxGridCellAttr * GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) override
virtual void SetValidator(const wxValidator &validator) override
Definition: validators.cpp:46
wxGridCellAttr * m_fieldNameAttr
wxGridCellAttr * m_urlAttr
virtual void doPopupSelection(wxCommandEvent &event)
SCH_FIELD_VALIDATOR m_valueValidator
bool GetValueAsBool(int aRow, int aCol) override
bool IsType(FRAME_T aType) const
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
wxGridCellAttr * m_vAlignAttr
virtual void showPopupMenu(wxMenu &menu)
void SetValue(int aRow, int aCol, const wxString &aValue) override
wxGridCellAttr * m_orientationAttr
wxGridCellAttr * m_valueAttr
Struct TEMPLATE_FIELDNAME holds a name of a component's field, field value, and default visibility.
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
wxString StringFromValue(EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ....
Definition: base_units.cpp:210
wxGridCellAttr * m_nonUrlAttr
A text control validator used for validating the text allowed in library and schematic component fiel...
Definition for part library class.
FIELDS_GRID_TABLE(DIALOG_SHIM *aDialog, SCH_BASE_FRAME *aFrame, LIB_PART *aPart)
void SetValueAsBool(int aRow, int aCol, bool aValue) override
A shim class between EDA_DRAW_FRAME and several derived classes: LIB_EDIT_FRAME, LIB_VIEW_FRAME,...
wxGridCellAttr * m_footprintAttr
virtual void doPopupSelection(wxCommandEvent &event) override
VTBL_ENTRY bool ShowModal(wxString *aResult=NULL, wxWindow *aResultantFocusWindow=NULL)
Function ShowModal puts up this wxFrame as if it were a modal dialog, with all other instantiated wxF...
Custom text control validator definitions.
wxString StringFromBool(bool aValue)