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 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;
78  m_footprintAttr->SetEditor( new GRID_CELL_FOOTPRINT_ID_EDITOR( aDialog ) );
79 
80  m_urlAttr = new wxGridCellAttr;
81  m_urlAttr->SetEditor( new GRID_CELL_URL_EDITOR( aDialog ) );
82 
83  m_boolAttr = new wxGridCellAttr;
84  m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
85  m_boolAttr->SetEditor( new wxGridCellBoolEditor() );
86  m_boolAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
87 
88  wxArrayString vAlignNames;
89  vAlignNames.Add( _( "Top" ) );
90  vAlignNames.Add( _( "Center" ) );
91  vAlignNames.Add( _( "Bottom" ) );
92  m_vAlignAttr = new wxGridCellAttr;
93  m_vAlignAttr->SetEditor( new wxGridCellChoiceEditor( vAlignNames ) );
94  m_vAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
95 
96  wxArrayString hAlignNames;
97  hAlignNames.Add( _( "Left" ) );
98  hAlignNames.Add(_( "Center" ) );
99  hAlignNames.Add(_( "Right" ) );
100  m_hAlignAttr = new wxGridCellAttr;
101  m_hAlignAttr->SetEditor( new wxGridCellChoiceEditor( hAlignNames ) );
102  m_hAlignAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
103 
104  wxArrayString orientationNames;
105  orientationNames.Add( _( "Horizontal" ) );
106  orientationNames.Add(_( "Vertical" ) );
107  m_orientationAttr = new wxGridCellAttr;
108  m_orientationAttr->SetEditor( new wxGridCellChoiceEditor( orientationNames ) );
109  m_orientationAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_BOTTOM );
110 }
111 
112 
113 template <class T>
115 {
116  m_readOnlyAttr->DecRef();
117  m_fieldNameAttr->DecRef();
118  m_boolAttr->DecRef();
119  m_referenceAttr->DecRef();
120  m_valueAttr->DecRef();
121  m_footprintAttr->DecRef();
122  m_urlAttr->DecRef();
123  m_vAlignAttr->DecRef();
124  m_hAlignAttr->DecRef();
125  m_orientationAttr->DecRef();
126 }
127 
128 
129 template <class T>
131 {
132  switch( aCol )
133  {
134  case FDC_NAME: return _( "Name" );
135  case FDC_VALUE: return _( "Value" );
136  case FDC_SHOWN: return _( "Show" );
137  case FDC_H_ALIGN: return _( "H Align" );
138  case FDC_V_ALIGN: return _( "V Align" );
139  case FDC_ITALIC: return _( "Italic" );
140  case FDC_BOLD: return _( "Bold" );
141  case FDC_TEXT_SIZE: return _( "Text Size" );
142  case FDC_ORIENTATION: return _( "Orientation" );
143  case FDC_POSX: return _( "X Position" );
144  case FDC_POSY: return _( "Y Position" );
145  default: wxFAIL; return wxEmptyString;
146  }
147 }
148 
149 
150 template <class T>
151 bool FIELDS_GRID_TABLE<T>::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
152 {
153  switch( aCol )
154  {
155  case FDC_NAME:
156  case FDC_VALUE:
157  case FDC_H_ALIGN:
158  case FDC_V_ALIGN:
159  case FDC_TEXT_SIZE:
160  case FDC_ORIENTATION:
161  case FDC_POSX:
162  case FDC_POSY:
163  return aTypeName == wxGRID_VALUE_STRING;
164 
165  case FDC_SHOWN:
166  case FDC_ITALIC:
167  case FDC_BOLD:
168  return aTypeName == wxGRID_VALUE_BOOL;
169 
170  default:
171  wxFAIL;
172  return false;
173  }
174 }
175 
176 
177 template <class T>
178 bool FIELDS_GRID_TABLE<T>::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
179 {
180  return CanGetValueAs( aRow, aCol, aTypeName );
181 }
182 
183 
184 template <class T>
185 wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
186 {
187  switch( aCol )
188  {
189  case FDC_NAME:
190  if( aRow < MANDATORY_FIELDS )
191  {
192  m_readOnlyAttr->IncRef();
193  return m_readOnlyAttr;
194  }
195  else
196  {
197  m_fieldNameAttr->IncRef();
198  return m_fieldNameAttr;
199  }
200 
201  case FDC_VALUE:
202  if( aRow == REFERENCE )
203  {
204  m_referenceAttr->IncRef();
205  return m_referenceAttr;
206  }
207  else if( aRow == VALUE )
208  {
209  // For power symbols, the value is not editable, because value and pin name must
210  // be the same and can be edited only in library editor.
211  if( m_part && m_part->IsPower() && ! m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
212  {
213  m_readOnlyAttr->IncRef();
214  return m_readOnlyAttr;
215  }
216  else
217  {
218  m_valueAttr->IncRef();
219  return m_valueAttr;
220  }
221  }
222  else if( aRow == FOOTPRINT )
223  {
224  m_footprintAttr->IncRef();
225  return m_footprintAttr;
226  }
227  else if( aRow == DATASHEET )
228  {
229  m_urlAttr->IncRef();
230  return m_urlAttr;
231  }
232  else
233  {
234  wxString fieldname = GetValue( aRow, FDC_NAME );
235  const TEMPLATE_FIELDNAME* templateFn = m_frame->GetTemplateFieldName( fieldname );
236 
237  if( templateFn && templateFn->m_URL )
238  {
239  m_urlAttr->IncRef();
240  return m_urlAttr;
241  }
242  }
243  return nullptr;
244 
245  case FDC_TEXT_SIZE:
246  case FDC_POSX:
247  case FDC_POSY:
248  return nullptr;
249 
250  case FDC_H_ALIGN:
251  m_hAlignAttr->IncRef();
252  return m_hAlignAttr;
253 
254  case FDC_V_ALIGN:
255  m_vAlignAttr->IncRef();
256  return m_vAlignAttr;
257 
258  case FDC_ORIENTATION:
259  m_orientationAttr->IncRef();
260  return m_orientationAttr;
261 
262  case FDC_SHOWN:
263  case FDC_ITALIC:
264  case FDC_BOLD:
265  m_boolAttr->IncRef();
266  return m_boolAttr;
267 
268  default:
269  wxFAIL;
270  return nullptr;
271  }
272 }
273 
274 
275 template <class T>
276 wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
277 {
278  wxCHECK( aRow < GetNumberRows(), wxEmptyString );
279  const T& field = this->at( (size_t) aRow );
280 
281  switch( aCol )
282  {
283  case FDC_NAME:
284  // Use default field name for mandatory fields, because they are transalted
285  // according to the current locale
286  if( aRow < MANDATORY_FIELDS )
288  else
289  return field.GetName( false );
290 
291  case FDC_VALUE:
292  return field.GetText();
293 
294  case FDC_SHOWN:
295  return StringFromBool( field.IsVisible() );
296 
297  case FDC_H_ALIGN:
298  switch ( field.GetHorizJustify() )
299  {
301  return _( "Left" );
303  return _( "Center" );
305  return _( "Right" );
306  }
307 
308  break;
309 
310  case FDC_V_ALIGN:
311  switch ( field.GetVertJustify() )
312  {
314  return _( "Top" );
316  return _( "Center" );
318  return _( "Bottom" );
319  }
320 
321  break;
322 
323  case FDC_ITALIC:
324  return StringFromBool( field.IsItalic() );
325 
326  case FDC_BOLD:
327  return StringFromBool( field.IsBold() );
328 
329  case FDC_TEXT_SIZE:
330  return StringFromValue( m_userUnits, field.GetTextSize().GetHeight(), true, true );
331 
332  case FDC_ORIENTATION:
333  switch ( (int) field.GetTextAngle() )
334  {
335  case TEXT_ANGLE_HORIZ:
336  return _( "Horizontal" );
337  case TEXT_ANGLE_VERT:
338  return _( "Vertical" );
339  }
340 
341  break;
342 
343  case FDC_POSX:
344  return StringFromValue( m_userUnits, field.GetTextPos().x, true );
345 
346  case FDC_POSY:
347  return StringFromValue( m_userUnits, field.GetTextPos().y, true );
348 
349  default:
350  // we can't assert here because wxWidgets sometimes calls this without checking
351  // the column type when trying to see if there's an overflow
352  break;
353  }
354 
355  return wxT( "bad wxWidgets!" );
356 }
357 
358 
359 template <class T>
360 bool FIELDS_GRID_TABLE<T>::GetValueAsBool( int aRow, int aCol )
361 {
362  wxCHECK( aRow < GetNumberRows(), false );
363  const T& field = this->at( (size_t) aRow );
364 
365  switch( aCol )
366  {
367  case FDC_SHOWN: return field.IsVisible();
368  case FDC_ITALIC: return field.IsItalic();
369  case FDC_BOLD: return field.IsBold();
370  default:
371  wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
372  return false;
373  }
374 }
375 
376 
377 template <class T>
378 void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue )
379 {
380  wxCHECK( aRow < GetNumberRows(), /*void*/ );
381  T& field = this->at( (size_t) aRow );
382  wxPoint pos;
383 
384  switch( aCol )
385  {
386  case FDC_NAME:
387  field.SetName( aValue );
388  break;
389 
390  case FDC_VALUE:
391  field.SetText( aValue );
392  break;
393 
394  case FDC_SHOWN:
395  field.SetVisible( BoolFromString( aValue ) );
396  break;
397 
398  case FDC_H_ALIGN:
399  if( aValue == _( "Left" ) )
400  field.SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
401  else if( aValue == _( "Center" ) )
402  field.SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
403  else if( aValue == _( "Right" ) )
404  field.SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
405  else
406  wxFAIL_MSG( wxT( "unknown horizontal alignment: " ) + aValue );
407  break;
408 
409  case FDC_V_ALIGN:
410  if( aValue == _( "Top" ) )
411  field.SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
412  else if( aValue == _( "Center" ) )
413  field.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
414  else if( aValue == _( "Bottom" ) )
415  field.SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
416  else
417  wxFAIL_MSG( wxT( "unknown vertical alignment: " ) + aValue);
418  break;
419 
420  case FDC_ITALIC:
421  field.SetItalic( BoolFromString( aValue ) );
422  break;
423 
424  case FDC_BOLD:
425  field.SetBold( BoolFromString( aValue ) );
426  break;
427 
428  case FDC_TEXT_SIZE:
429  field.SetTextSize( wxSize( ValueFromString( m_userUnits, aValue ),
430  ValueFromString( m_userUnits, aValue ) ) );
431  break;
432 
433  case FDC_ORIENTATION:
434  if( aValue == _( "Horizontal" ) )
435  field.SetTextAngle( TEXT_ANGLE_HORIZ );
436  else if( aValue == _( "Vertical" ) )
437  field.SetTextAngle( TEXT_ANGLE_VERT );
438  else
439  wxFAIL_MSG( wxT( "unknown orientation: " ) + aValue );
440  break;
441 
442  case FDC_POSX:
443  case FDC_POSY:
444  pos = field.GetTextPos();
445  if( aCol == FDC_POSX )
446  pos.x = ValueFromString( m_userUnits, aValue );
447  else
448  pos.y = ValueFromString( m_userUnits, aValue );
449  field.SetTextPos( pos );
450  break;
451 
452  default:
453  wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
454  break;
455  }
456 
457  GetView()->Refresh();
458 }
459 
460 
461 template <class T>
462 void FIELDS_GRID_TABLE<T>::SetValueAsBool( int aRow, int aCol, bool aValue )
463 {
464  wxCHECK( aRow < GetNumberRows(), /*void*/ );
465  T& field = this->at( (size_t) aRow );
466 
467  switch( aCol )
468  {
469  case FDC_SHOWN:
470  field.SetVisible( aValue );
471  break;
472  case FDC_ITALIC:
473  field.SetItalic( aValue );
474  break;
475  case FDC_BOLD:
476  field.SetBold( aValue );
477  break;
478  default:
479  wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
480  break;
481  }
482 }
483 
484 
485 // Explicit Instantiations
486 
487 template class FIELDS_GRID_TABLE<SCH_FIELD>;
488 template class FIELDS_GRID_TABLE<LIB_FIELD>;
489 
490 
491 
493 {
494  if( m_grid->GetGridCursorRow() == FOOTPRINT && m_grid->GetGridCursorCol() == FDC_VALUE )
495  {
496  menu.Append( MYID_SELECT_FOOTPRINT, _( "Select Footprint..." ), _( "Browse for footprint" ) );
497  menu.AppendSeparator();
498  }
499  else if( m_grid->GetGridCursorRow() == DATASHEET && m_grid->GetGridCursorCol() == FDC_VALUE )
500  {
501  menu.Append( MYID_SHOW_DATASHEET, _( "Show Datasheet" ), _( "Show datasheet in browser" ) );
502  menu.AppendSeparator();
503  }
504 
506 }
507 
508 
509 void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
510 {
511  if( event.GetId() == MYID_SELECT_FOOTPRINT )
512  {
513  // pick a footprint using the footprint picker.
514  wxString fpid = m_grid->GetCellValue( FOOTPRINT, FDC_VALUE );
516 
517  if( frame->ShowModal( &fpid, m_dlg ) )
518  m_grid->SetCellValue( FOOTPRINT, FDC_VALUE, fpid );
519 
520  frame->Destroy();
521  }
522  else if (event.GetId() == MYID_SHOW_DATASHEET )
523  {
524  wxString datasheet_uri = m_grid->GetCellValue( DATASHEET, FDC_VALUE );
525  GetAssociatedDocument( m_dlg, datasheet_uri );
526  }
527  else
528  {
530  }
531 }
532 
533 template <class T>
535 {
536  if( aValue )
537  return wxT( "1" );
538  else
539  return wxT( "0" );
540 }
541 
542 template <class T>
544 {
545  if( aValue == wxT( "1" ) )
546  {
547  return true;
548  }
549  else if( aValue == wxT( "0" ) )
550  {
551  return false;
552  }
553  else
554  {
555  wxFAIL_MSG( wxString::Format( wxT( "string \"%s\" can't be converted to boolean correctly, it will have been perceived as FALSE" ), aValue ) );
556  return false;
557  }
558 }
#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:120
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
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".
Class GRID_CELL_TEXT_EDITOR.
Definition: validators.h:42
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:300
SCH_FIELD_VALIDATOR m_referenceValidator
Defintions 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.
#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:44
wxGridCellAttr * m_fieldNameAttr
wxGridCellAttr * m_urlAttr
virtual void doPopupSelection(wxCommandEvent &event)
SCH_FIELD_VALIDATOR m_valueValidator
bool GetValueAsBool(int aRow, int aCol) override
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
Definition for part library class.
Definition of the SCH_FIELD class for Eeschema.
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)