KiCad PCB EDA Suite
dialog_symbol_properties.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) 2004-2021 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 
25 
26 #include <bitmaps.h>
27 #include <wx/tooltip.h>
28 #include <grid_tricks.h>
29 #include <confirm.h>
30 #include <kiface_i.h>
31 #include <pin_number.h>
32 #include <kicad_string.h>
33 #include <menus_helpers.h>
35 #include <widgets/grid_combobox.h>
36 #include <widgets/wx_grid.h>
38 #include <ee_collectors.h>
39 #include <class_library.h>
40 #include <fields_grid_table.h>
41 #include <sch_edit_frame.h>
42 #include <sch_reference_list.h>
43 #include <schematic.h>
44 #include <tool/tool_manager.h>
45 #include <tool/actions.h>
46 
47 #ifdef KICAD_SPICE
48 #include <dialog_spice_model.h>
49 #endif /* KICAD_SPICE */
50 
51 
53 {
59 
60  COL_COUNT // keep as last
61 };
62 
63 
64 class SCH_PIN_TABLE_DATA_MODEL : public wxGridTableBase, public std::vector<SCH_PIN>
65 {
66 protected:
67  std::vector<wxGridCellAttr*> m_nameAttrs;
68  wxGridCellAttr* m_readOnlyAttr;
69  wxGridCellAttr* m_typeAttr;
70  wxGridCellAttr* m_shapeAttr;
71 
72 public:
74  m_readOnlyAttr( nullptr ),
75  m_typeAttr( nullptr ),
76  m_shapeAttr( nullptr )
77  {
78  }
79 
81  {
82  for( wxGridCellAttr* attr : m_nameAttrs )
83  attr->DecRef();
84 
85  m_readOnlyAttr->DecRef();
86  m_typeAttr->DecRef();
87  m_shapeAttr->DecRef();
88  }
89 
90  void BuildAttrs()
91  {
92  m_readOnlyAttr = new wxGridCellAttr;
93  m_readOnlyAttr->SetReadOnly( true );
94 
95  for( const SCH_PIN& pin : *this )
96  {
97  LIB_PIN* lib_pin = pin.GetLibPin();
98  wxGridCellAttr* attr = nullptr;
99 
100  if( lib_pin->GetAlternates().empty() )
101  {
102  attr = new wxGridCellAttr;
103  attr->SetReadOnly( true );
104  }
105  else
106  {
107  wxArrayString choices;
108  choices.push_back( lib_pin->GetName() );
109 
110  for( const std::pair<const wxString, LIB_PIN::ALT>& alt : lib_pin->GetAlternates() )
111  choices.push_back( alt.first );
112 
113  attr = new wxGridCellAttr();
114  attr->SetEditor( new GRID_CELL_COMBOBOX( choices ) );
115  }
116 
117  m_nameAttrs.push_back( attr );
118  }
119 
120  m_typeAttr = new wxGridCellAttr;
122  m_typeAttr->SetReadOnly( true );
123 
124  m_shapeAttr = new wxGridCellAttr;
126  m_shapeAttr->SetReadOnly( true );
127  }
128 
129  int GetNumberRows() override { return (int) size(); }
130  int GetNumberCols() override { return COL_COUNT; }
131 
132  wxString GetColLabelValue( int aCol ) override
133  {
134  switch( aCol )
135  {
136  case COL_NUMBER: return _( "Number" );
137  case COL_BASE_NAME: return _( "Base Name" );
138  case COL_ALT_NAME: return _( "Alternate Assignment" );
139  case COL_TYPE: return _( "Electrical Type" );
140  case COL_SHAPE: return _( "Graphic Style" );
141  default: wxFAIL; return wxEmptyString;
142  }
143  }
144 
145  bool IsEmptyCell( int row, int col ) override
146  {
147  return false; // don't allow adjacent cell overflow, even if we are actually empty
148  }
149 
150  wxString GetValue( int aRow, int aCol ) override
151  {
152  return GetValue( at( aRow ), aCol );
153  }
154 
155  static wxString GetValue( const SCH_PIN& aPin, int aCol )
156  {
157  switch( aCol )
158  {
159  case COL_NUMBER: return aPin.GetNumber();
160  case COL_BASE_NAME: return aPin.GetLibPin()->GetName();
161  case COL_ALT_NAME: return aPin.GetAlt();
162  case COL_TYPE: return PinTypeNames()[static_cast<int>( aPin.GetType() )];
163  case COL_SHAPE: return PinShapeNames()[static_cast<int>( aPin.GetShape() )];
164  default: wxFAIL; return wxEmptyString;
165  }
166  }
167 
168  wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind ) override
169  {
170  switch( aCol )
171  {
172  case COL_NUMBER:
173  case COL_BASE_NAME:
174  m_readOnlyAttr->IncRef();
175  return m_readOnlyAttr;
176 
177  case COL_ALT_NAME:
178  m_nameAttrs[ aRow ]->IncRef();
179  return m_nameAttrs[ aRow ];
180 
181  case COL_TYPE:
182  m_typeAttr->IncRef();
183  return m_typeAttr;
184 
185  case COL_SHAPE:
186  m_shapeAttr->IncRef();
187  return m_shapeAttr;
188 
189  default:
190  wxFAIL;
191  return nullptr;
192  }
193  }
194 
195  void SetValue( int aRow, int aCol, const wxString &aValue ) override
196  {
197  switch( aCol )
198  {
199  case COL_ALT_NAME:
200  if( aValue == at( aRow ).GetLibPin()->GetName() )
201  at( aRow ).SetAlt( wxEmptyString );
202  else
203  at( aRow ).SetAlt( aValue );
204  break;
205 
206  case COL_NUMBER:
207  case COL_BASE_NAME:
208  case COL_TYPE:
209  case COL_SHAPE:
210  // Read-only.
211  break;
212 
213  default:
214  wxFAIL;
215  break;
216  }
217  }
218 
219  static bool compare( const SCH_PIN& lhs, const SCH_PIN& rhs, int sortCol, bool ascending )
220  {
221  wxString lhStr = GetValue( lhs, sortCol );
222  wxString rhStr = GetValue( rhs, sortCol );
223 
224  if( lhStr == rhStr )
225  {
226  // Secondary sort key is always COL_NUMBER
227  sortCol = COL_NUMBER;
228  lhStr = GetValue( lhs, sortCol );
229  rhStr = GetValue( rhs, sortCol );
230  }
231 
232  bool res;
233 
234  // N.B. To meet the iterator sort conditions, we cannot simply invert the truth
235  // to get the opposite sort. i.e. ~(a<b) != (a>b)
236  auto cmp = [ ascending ]( const auto a, const auto b )
237  {
238  if( ascending )
239  return a < b;
240  else
241  return b < a;
242  };
243 
244  switch( sortCol )
245  {
246  case COL_NUMBER:
247  case COL_BASE_NAME:
248  case COL_ALT_NAME:
249  res = cmp( PinNumbers::Compare( lhStr, rhStr ), 0 );
250  break;
251  case COL_TYPE:
252  case COL_SHAPE:
253  res = cmp( lhStr.CmpNoCase( rhStr ), 0 );
254  break;
255  default:
256  res = cmp( StrNumCmp( lhStr, rhStr ), 0 );
257  break;
258  }
259 
260  return res;
261  }
262 
263  void SortRows( int aSortCol, bool ascending )
264  {
265  std::sort( begin(), end(),
266  [ aSortCol, ascending ]( const SCH_PIN& lhs, const SCH_PIN& rhs ) -> bool
267  {
268  return compare( lhs, rhs, aSortCol, ascending );
269  } );
270  }
271 };
272 
273 
275  SCH_COMPONENT* aComponent ) :
277  m_comp( nullptr ),
278  m_part( nullptr ),
279  m_fields( nullptr ),
280  m_dataModel( nullptr )
281 {
282  m_comp = aComponent;
283  m_part = m_comp->GetPartRef().get();
284 
285  // GetPartRef() now points to the cached part in the schematic, which should always be
286  // there for usual cases, but can be null when opening old schematics not storing the part
287  // so we need to handle m_part == nullptr
288  wxASSERT( m_part );
289 
290  m_fields = new FIELDS_GRID_TABLE<SCH_FIELD>( this, aParent, m_fieldsGrid, m_part );
291 
292  m_width = 0;
295  m_delayedSelection = true;
296 
297 #ifndef KICAD_SPICE
298  m_spiceFieldsButton->Hide();
299 #endif /* not KICAD_SPICE */
300 
301  // disable some options inside the edit dialog which can cause problems while dragging
302  if( m_comp->IsDragging() )
303  {
304  m_orientationLabel->Disable();
305  m_orientationCtrl->Disable();
306  m_mirrorLabel->Disable();
307  m_mirrorCtrl->Disable();
308  }
309 
310  // Give a bit more room for combobox editors
311  m_fieldsGrid->SetDefaultRowSize( m_fieldsGrid->GetDefaultRowSize() + 4 );
312  m_pinGrid->SetDefaultRowSize( m_pinGrid->GetDefaultRowSize() + 4 );
313 
315  m_fieldsGrid->PushEventHandler( new FIELDS_GRID_TRICKS( m_fieldsGrid, this ) );
316 
317  // Show/hide columns according to user's preference
318  auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
319 
320  if( cfg )
321  {
322  m_shownColumns = cfg->m_Appearance.edit_component_visible_columns;
324  }
325 
326  if( m_part && m_part->HasConversion() )
327  {
328  // DeMorgan conversions are a subclass of alternate pin assignments, so don't allow
329  // free-form alternate assignments as well. (We won't know how to map the alternates
330  // back and forth when the conversion is changed.)
331  m_pinTablePage->Disable();
332  m_pinTablePage->SetToolTip(
333  _( "Alternate pin assignments are not available for DeMorgan components." ) );
334  }
335  else
336  {
338 
339  // Make a copy of the pins for editing
340  for( const std::unique_ptr<SCH_PIN>& pin : m_comp->GetRawPins() )
341  m_dataModel->push_back( *pin );
342 
343  m_dataModel->SortRows( COL_NUMBER, true );
345 
347  }
348 
349  m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) );
350 
351  wxToolTip::Enable( true );
352  m_stdDialogButtonSizerOK->SetDefault();
353 
354  // Configure button logos
355  m_bpAdd->SetBitmap( KiBitmap( small_plus_xpm ) );
356  m_bpDelete->SetBitmap( KiBitmap( small_trash_xpm ) );
357  m_bpMoveUp->SetBitmap( KiBitmap( small_up_xpm ) );
358  m_bpMoveDown->SetBitmap( KiBitmap( small_down_xpm ) );
359 
360  // wxFormBuilder doesn't include this event...
361  m_fieldsGrid->Connect( wxEVT_GRID_CELL_CHANGING,
362  wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging ),
363  nullptr, this );
364 
365  m_pinGrid->Connect( wxEVT_GRID_COL_SORT,
366  wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort ),
367  nullptr, this );
368 
370 }
371 
372 
374 {
375  auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
376 
377  if( cfg )
378  cfg->m_Appearance.edit_component_visible_columns = m_fieldsGrid->GetShownColumns();
379 
380  // Prevents crash bug in wxGrid's d'tor
382 
383  if( m_dataModel )
385 
386  m_fieldsGrid->Disconnect( wxEVT_GRID_CELL_CHANGING,
387  wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging ),
388  nullptr, this );
389 
390  m_pinGrid->Disconnect( wxEVT_GRID_COL_SORT,
391  wxGridEventHandler( DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort ),
392  nullptr, this );
393 
394  // Delete the GRID_TRICKS.
395  m_fieldsGrid->PopEventHandler( true );
396  m_pinGrid->PopEventHandler( true );
397 }
398 
399 
401 {
402  return dynamic_cast<SCH_EDIT_FRAME*>( wxDialog::GetParent() );
403 }
404 
405 
407 {
408  if( !wxDialog::TransferDataToWindow() )
409  return false;
410 
411  std::set<wxString> defined;
412 
413  // Push a copy of each field into m_updateFields
414  for( int i = 0; i < m_comp->GetFieldCount(); ++i )
415  {
416  SCH_FIELD field( m_comp->GetFields()[i] );
417 
418  // change offset to be symbol-relative
419  field.Offset( -m_comp->GetPosition() );
420 
421  defined.insert( field.GetName() );
422  m_fields->push_back( field );
423  }
424 
425  // Add in any template fieldnames not yet defined:
426  for( const TEMPLATE_FIELDNAME& templateFieldname :
427  GetParent()->Schematic().Settings().m_TemplateFieldNames.GetTemplateFieldNames() )
428  {
429  if( defined.count( templateFieldname.m_Name ) <= 0 )
430  {
431  SCH_FIELD field( wxPoint( 0, 0 ), -1, m_comp, templateFieldname.m_Name );
432  field.SetVisible( templateFieldname.m_Visible );
433  m_fields->push_back( field );
434  }
435  }
436 
437  // notify the grid
438  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() );
439  m_fieldsGrid->ProcessTableMessage( msg );
440  AdjustGridColumns( m_fieldsGrid->GetRect().GetWidth() );
441 
442  // If a multi-unit component, set up the unit selector and interchangeable checkbox.
443  if( m_comp->GetUnitCount() > 1 )
444  {
445  for( int ii = 1; ii <= m_comp->GetUnitCount(); ii++ )
446  m_unitChoice->Append( LIB_PART::SubReference( ii, false ) );
447 
448  if( m_comp->GetUnit() <= ( int )m_unitChoice->GetCount() )
449  m_unitChoice->SetSelection( m_comp->GetUnit() - 1 );
450  }
451  else
452  {
453  m_unitLabel->Enable( false );
454  m_unitChoice->Enable( false );
455  }
456 
457  if( m_part && m_part->HasConversion() )
458  {
459  if( m_comp->GetConvert() > LIB_ITEM::LIB_CONVERT::BASE )
460  m_cbAlternateSymbol->SetValue( true );
461  }
462  else
463  {
464  m_cbAlternateSymbol->Enable( false );
465  }
466 
467  // Set the symbol orientation and mirroring.
468  int orientation = m_comp->GetOrientation() & ~( CMP_MIRROR_X | CMP_MIRROR_Y );
469 
470  switch( orientation )
471  {
472  default:
473  case CMP_ORIENT_0: m_orientationCtrl->SetSelection( 0 ); break;
474  case CMP_ORIENT_90: m_orientationCtrl->SetSelection( 1 ); break;
475  case CMP_ORIENT_270: m_orientationCtrl->SetSelection( 2 ); break;
476  case CMP_ORIENT_180: m_orientationCtrl->SetSelection( 3 ); break;
477  }
478 
479  int mirror = m_comp->GetOrientation() & ( CMP_MIRROR_X | CMP_MIRROR_Y );
480 
481  switch( mirror )
482  {
483  default: m_mirrorCtrl->SetSelection( 0 ) ; break;
484  case CMP_MIRROR_X: m_mirrorCtrl->SetSelection( 1 ); break;
485  case CMP_MIRROR_Y: m_mirrorCtrl->SetSelection( 2 ); break;
486  }
487 
488  m_cbExcludeFromBom->SetValue( !m_comp->GetIncludeInBom() );
490 
491  if( m_part )
492  {
493  m_ShowPinNumButt->SetValue( m_part->ShowPinNumbers() );
494  m_ShowPinNameButt->SetValue( m_part->ShowPinNames() );
495  }
496 
497  // Set the component's library name.
498  m_tcLibraryID->SetLabelText( m_comp->GetLibId().Format() );
499 
500  Layout();
501 
502  // Workaround to fix an annoying issue on wxGTK: in some cases selecting a field
503  // to change its value make this value invisible. It happens until the dialog is resized.
504  // So I am guessing there is a problem when initializing sizers settings
505  // Do not create issues on other OS
506  wxSafeYield(); // slice of time to handle events generated when creating the
507  // dialog, especially size events
508  m_fieldsGrid->Layout(); // Force recalculating all sizers in m_fieldsGrid
509 
510  return true;
511 }
512 
513 
514 void DIALOG_SYMBOL_PROPERTIES::OnEditSpiceModel( wxCommandEvent& event )
515 {
516 #ifdef KICAD_SPICE
517  int diff = m_fields->size();
518 
519  DIALOG_SPICE_MODEL dialog( this, *m_comp, m_fields );
520 
521  if( dialog.ShowModal() != wxID_OK )
522  return;
523 
524  diff = (int) m_fields->size() - diff;
525 
526  if( diff > 0 )
527  {
528  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
529  m_fieldsGrid->ProcessTableMessage( msg );
530  }
531  else if( diff < 0 )
532  {
533  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, -diff );
534  m_fieldsGrid->ProcessTableMessage( msg );
535  }
536 
537  m_fieldsGrid->ForceRefresh();
538 #endif /* KICAD_SPICE */
539 }
540 
541 
543 {
544  // Running the Footprint Browser gums up the works and causes the automatic cancel
545  // stuff to no longer work. So we do it here ourselves.
546  EndQuasiModal( wxID_CANCEL );
547 }
548 
549 
551 {
552  wxString msg;
553  LIB_ID id;
554 
555  if( !m_fieldsGrid->CommitPendingChanges() || !m_fieldsGrid->Validate() )
556  return false;
557 
559  {
560  DisplayErrorMessage( this, _( "References must start with a letter." ) );
561 
564  m_delayedSelection = false;
565 
566  return false;
567  }
568 
569  // Check for missing field names.
570  for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
571  {
572  SCH_FIELD& field = m_fields->at( i );
573  wxString fieldName = field.GetName( false );
574 
575  if( fieldName.IsEmpty() )
576  {
577  DisplayErrorMessage( this, _( "Fields must have a name." ) );
578 
580  m_delayedFocusRow = i;
581  m_delayedSelection = false;
582 
583  return false;
584  }
585  }
586 
587  return true;
588 }
589 
590 
592 {
593  if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
594  return false;
595 
597  return false;
598 
600  return false;
601 
602  SCH_SCREEN* currentScreen = GetParent()->GetScreen();
603  SCHEMATIC& schematic = GetParent()->Schematic();
604 
605  wxCHECK( currentScreen, false );
606 
607  // This needs to be done before the LIB_ID is changed to prevent stale library symbols in
608  // the schematic file.
609  currentScreen->Remove( m_comp );
610 
611  wxString msg;
612 
613  // save old cmp in undo list if not already in edit, or moving ...
614  if( m_comp->GetEditFlags() == 0 )
615  GetParent()->SaveCopyInUndoList( currentScreen, m_comp, UNDO_REDO::CHANGED, false );
616 
617  // Save current flags which could be modified by next change settings
618  STATUS_FLAGS flags = m_comp->GetFlags();
619 
620  // For symbols with multiple shapes (De Morgan representation) Set the selected shape:
621  if( m_cbAlternateSymbol->IsEnabled() && m_cbAlternateSymbol->GetValue() )
622  m_comp->SetConvert( LIB_ITEM::LIB_CONVERT::DEMORGAN );
623  else
624  m_comp->SetConvert( LIB_ITEM::LIB_CONVERT::BASE );
625 
626  //Set the part selection in multiple part per package
627  int unit_selection = m_unitChoice->IsEnabled() ? m_unitChoice->GetSelection() + 1 : 1;
628  m_comp->SetUnitSelection( &GetParent()->GetCurrentSheet(), unit_selection );
629  m_comp->SetUnit( unit_selection );
630 
631  switch( m_orientationCtrl->GetSelection() )
632  {
633  case 0: m_comp->SetOrientation( CMP_ORIENT_0 ); break;
634  case 1: m_comp->SetOrientation( CMP_ORIENT_90 ); break;
635  case 2: m_comp->SetOrientation( CMP_ORIENT_270 ); break;
636  case 3: m_comp->SetOrientation( CMP_ORIENT_180 ); break;
637  }
638 
639  switch( m_mirrorCtrl->GetSelection() )
640  {
641  case 0: break;
642  case 1: m_comp->SetOrientation( CMP_MIRROR_X ); break;
643  case 2: m_comp->SetOrientation( CMP_MIRROR_Y ); break;
644  }
645 
646  if( m_part )
647  {
648  m_part->SetShowPinNames( m_ShowPinNameButt->GetValue() );
649  m_part->SetShowPinNumbers( m_ShowPinNumButt->GetValue() );
650  }
651 
652  // Restore m_Flag modified by SetUnit() and other change settings
653  m_comp->ClearFlags();
654  m_comp->SetFlags( flags );
655 
656  // change all field positions from relative to absolute
657  for( unsigned i = 0; i < m_fields->size(); ++i )
658  m_fields->at( i ).Offset( m_comp->GetPosition() );
659 
660  LIB_PART* entry = GetParent()->GetLibPart( m_comp->GetLibId() );
661 
662  if( entry && entry->IsPower() )
663  m_fields->at( VALUE_FIELD ).SetText( m_comp->GetLibId().GetLibItemName() );
664 
665  // Push all fields to the component -except- for those which are TEMPLATE_FIELDNAMES
666  // with empty values.
667  SCH_FIELDS& fields = m_comp->GetFields();
668 
669  fields.clear();
670 
671  for( size_t i = 0; i < m_fields->size(); ++i )
672  {
673  SCH_FIELD& field = m_fields->at( i );
674  bool emptyTemplateField = false;
675 
676  if( i >= MANDATORY_FIELDS )
677  {
678  for( const TEMPLATE_FIELDNAME& fieldname :
680  {
681  if( field.GetName() == fieldname.m_Name && field.GetText().IsEmpty() )
682  {
683  emptyTemplateField = true;
684  break;
685  }
686  }
687  }
688 
689  if( !emptyTemplateField )
690  fields.push_back( field );
691  }
692 
693  // Reference has a specific initialization, depending on the current active sheet
694  // because for a given component, in a complex hierarchy, there are more than one
695  // reference.
696  m_comp->SetRef( &GetParent()->GetCurrentSheet(), m_fields->at( REFERENCE_FIELD ).GetText() );
697 
698  // Similar for Value and Footprint, except that the GUI behaviour is that they are kept
699  // in sync between multiple instances.
700  m_comp->SetValue( m_fields->at( VALUE_FIELD ).GetText() );
701  m_comp->SetFootprint( m_fields->at( FOOTPRINT_FIELD ).GetText() );
702 
703  m_comp->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() );
705 
706  // The value, footprint and datasheet fields and exclude from bill of materials setting
707  // should be kept in sync in multi-unit parts.
708  if( m_comp->GetUnitCount() > 1 && m_comp->IsAnnotated( &GetParent()->GetCurrentSheet() ) )
709  {
710  wxString ref = m_comp->GetRef( &GetParent()->GetCurrentSheet() );
711  int unit = m_comp->GetUnit();
712 
713  for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
714  {
715  SCH_SCREEN* screen = sheet.LastScreen();
716  std::vector<SCH_COMPONENT*> otherUnits;
717  constexpr bool appendUndo = true;
718 
719  CollectOtherUnits( ref, unit, sheet, &otherUnits );
720 
721  for( SCH_COMPONENT* otherUnit : otherUnits )
722  {
723  GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED,
724  appendUndo );
725  otherUnit->SetValue( m_fields->at( VALUE_FIELD ).GetText() );
726  otherUnit->SetFootprint( m_fields->at( FOOTPRINT_FIELD ).GetText() );
727  otherUnit->GetField( DATASHEET_FIELD )->SetText( m_fields->at( DATASHEET_FIELD ).GetText() );
728  otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() );
729  otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() );
730  GetParent()->UpdateItem( otherUnit );
731  }
732  }
733  }
734 
735  // Update any assignments
736  if( m_dataModel )
737  {
738  for( const SCH_PIN& model_pin : *m_dataModel )
739  {
740  // map from the edited copy back to the "real" pin in the component
741  SCH_PIN* src_pin = m_comp->GetPin( model_pin.GetLibPin() );
742  src_pin->SetAlt( model_pin.GetAlt() );
743  }
744  }
745 
746  currentScreen->Append( m_comp );
749  GetParent()->OnModify();
750 
751  // This must go after OnModify() so that the connectivity graph will have been updated.
753 
754  return true;
755 }
756 
757 
759 {
760  wxGridCellEditor* editor = m_fieldsGrid->GetCellEditor( event.GetRow(), event.GetCol() );
761  wxControl* control = editor->GetControl();
762 
763  if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
764  {
765  event.Veto();
766  m_delayedFocusRow = event.GetRow();
767  m_delayedFocusColumn = event.GetCol();
768  m_delayedSelection = false;
769  }
770  else if( event.GetCol() == FDC_NAME )
771  {
772  wxString newName = event.GetString();
773 
774  for( int i = 0; i < m_fieldsGrid->GetNumberRows(); ++i )
775  {
776  if( i == event.GetRow() )
777  continue;
778 
779  if( newName.CmpNoCase( m_fieldsGrid->GetCellValue( i, FDC_NAME ) ) == 0 )
780  {
781  DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
782  newName ) );
783  event.Veto();
784  m_delayedFocusRow = event.GetRow();
785  m_delayedFocusColumn = event.GetCol();
786  m_delayedSelection = false;
787  }
788  }
789  }
790 
791  editor->DecRef();
792 }
793 
794 
796 {
797  if( aEvent.GetRow() == REFERENCE_FIELD && aEvent.GetCol() == FDC_VALUE )
798  m_delayedSelection= true;
799 }
800 
801 
802 void DIALOG_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
803 {
805  return;
806 
807  SCHEMATIC_SETTINGS& settings = m_comp->Schematic()->Settings();
808  int fieldID = m_fields->size();
809  SCH_FIELD newField( wxPoint( 0, 0 ), fieldID, m_comp,
811 
812  newField.SetTextAngle( m_fields->at( REFERENCE_FIELD ).GetTextAngle() );
813  newField.SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
814 
815  m_fields->push_back( newField );
816 
817  // notify the grid
818  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
819  m_fieldsGrid->ProcessTableMessage( msg );
820 
821  m_fieldsGrid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
822  m_fieldsGrid->SetGridCursor( (int) m_fields->size() - 1, 0 );
823 
824  m_fieldsGrid->EnableCellEditControl();
825  m_fieldsGrid->ShowCellEditControl();
826 }
827 
828 
829 void DIALOG_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
830 {
831  int curRow = m_fieldsGrid->GetGridCursorRow();
832 
833  if( curRow < 0 )
834  {
835  return;
836  }
837  else if( curRow < MANDATORY_FIELDS )
838  {
839  DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
840  MANDATORY_FIELDS ) );
841  return;
842  }
843 
844  m_fieldsGrid->CommitPendingChanges( true /* quiet mode */ );
845 
846  m_fields->erase( m_fields->begin() + curRow );
847 
848  // notify the grid
849  wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 );
850  m_fieldsGrid->ProcessTableMessage( msg );
851 
852  if( m_fieldsGrid->GetNumberRows() > 0 )
853  {
854  m_fieldsGrid->MakeCellVisible( std::max( 0, curRow-1 ), m_fieldsGrid->GetGridCursorCol() );
855  m_fieldsGrid->SetGridCursor( std::max( 0, curRow-1 ), m_fieldsGrid->GetGridCursorCol() );
856  }
857 }
858 
859 
860 void DIALOG_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
861 {
863  return;
864 
865  int i = m_fieldsGrid->GetGridCursorRow();
866 
867  if( i > MANDATORY_FIELDS )
868  {
869  SCH_FIELD tmp = m_fields->at( (unsigned) i );
870  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
871  m_fields->insert( m_fields->begin() + i - 1, tmp );
872  m_fieldsGrid->ForceRefresh();
873 
874  m_fieldsGrid->SetGridCursor( i - 1, m_fieldsGrid->GetGridCursorCol() );
875  m_fieldsGrid->MakeCellVisible( m_fieldsGrid->GetGridCursorRow(), m_fieldsGrid->GetGridCursorCol() );
876  }
877  else
878  {
879  wxBell();
880  }
881 }
882 
883 
884 void DIALOG_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
885 {
887  return;
888 
889  int i = m_fieldsGrid->GetGridCursorRow();
890 
891  if( i >= MANDATORY_FIELDS && i < m_fieldsGrid->GetNumberRows() - 1 )
892  {
893  SCH_FIELD tmp = m_fields->at( (unsigned) i );
894  m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
895  m_fields->insert( m_fields->begin() + i + 1, tmp );
896  m_fieldsGrid->ForceRefresh();
897 
898  m_fieldsGrid->SetGridCursor( i + 1, m_fieldsGrid->GetGridCursorCol() );
899  m_fieldsGrid->MakeCellVisible( m_fieldsGrid->GetGridCursorRow(), m_fieldsGrid->GetGridCursorCol() );
900  }
901  else
902  {
903  wxBell();
904  }
905 }
906 
907 
909 {
910  if( TransferDataFromWindow() )
912 }
913 
914 
916 {
917  if( TransferDataFromWindow() )
919 }
920 
921 
923 {
924  if( TransferDataFromWindow() )
926 }
927 
928 
930 {
931  if( TransferDataFromWindow() )
933 }
934 
935 
937 {
938  int row = aEvent.GetRow();
939 
940  if( m_pinGrid->GetCellValue( row, COL_ALT_NAME ) == m_dataModel->GetValue( row, COL_BASE_NAME ) )
941  m_dataModel->SetValue( row, COL_ALT_NAME, wxEmptyString );
942 
943  // These are just to get the cells refreshed
946 
947  m_modified = true;
948 }
949 
950 
952 {
953  int sortCol = aEvent.GetCol();
954  bool ascending;
955 
956  // This is bonkers, but wxWidgets doesn't tell us ascending/descending in the
957  // event, and if we ask it will give us pre-event info.
958  if( m_pinGrid->IsSortingBy( sortCol ) )
959  // same column; invert ascending
960  ascending = !m_pinGrid->IsSortOrderAscending();
961  else
962  // different column; start with ascending
963  ascending = true;
964 
965  m_dataModel->SortRows( sortCol, ascending );
966 }
967 
968 
970 {
971  wxGridUpdateLocker deferRepaintsTillLeavingScope;
972 
973  m_width = aWidth;
974 
975  // Account for scroll bars
976  int fieldsWidth = aWidth - ( m_fieldsGrid->GetSize().x - m_fieldsGrid->GetClientSize().x );
977  int pinTblWidth = aWidth - ( m_pinGrid->GetSize().x - m_pinGrid->GetClientSize().x );
978 
979  m_fieldsGrid->AutoSizeColumn( 0 );
980 
981  int fixedColsWidth = m_fieldsGrid->GetColSize( 0 );
982 
983  for( int i = 2; i < m_fieldsGrid->GetNumberCols(); i++ )
984  fixedColsWidth += m_fieldsGrid->GetColSize( i );
985 
986  m_fieldsGrid->SetColSize( 1, fieldsWidth - fixedColsWidth );
987 
988  // Stretch the Base Name and Alternate Assignment columns to fit.
989  for( int i = 0; i < COL_COUNT; ++i )
990  {
991  if( i != COL_BASE_NAME && i != COL_ALT_NAME )
992  pinTblWidth -= m_pinGrid->GetColSize( i );
993  }
994 
995  // Why? I haven't a clue....
996  pinTblWidth += 22;
997 
998  m_pinGrid->SetColSize( COL_BASE_NAME, pinTblWidth / 2 );
999  m_pinGrid->SetColSize( COL_ALT_NAME, pinTblWidth / 2 );
1000 }
1001 
1002 
1003 void DIALOG_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1004 {
1005  wxString shownColumns = m_fieldsGrid->GetShownColumns();
1006 
1007  if( shownColumns != m_shownColumns )
1008  {
1009  m_shownColumns = shownColumns;
1010 
1011  if( !m_fieldsGrid->IsCellEditControlShown() )
1012  AdjustGridColumns( m_fieldsGrid->GetRect().GetWidth() );
1013  }
1014 
1015  // Handle a delayed focus
1016  if( m_delayedFocusRow >= 0 )
1017  {
1018  m_fieldsGrid->SetFocus();
1021 
1022  m_fieldsGrid->EnableCellEditControl( true );
1023  m_fieldsGrid->ShowCellEditControl();
1024 
1025  m_delayedFocusRow = -1;
1026  m_delayedFocusColumn = -1;
1027  }
1028 
1029  // Handle a delayed selection
1030  if( m_delayedSelection )
1031  {
1032  wxGridCellEditor* cellEditor = m_fieldsGrid->GetCellEditor( REFERENCE_FIELD, FDC_VALUE );
1033 
1034  if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
1036 
1037  cellEditor->DecRef(); // we're done; must release
1038 
1039  m_delayedSelection = false;
1040  }
1041 }
1042 
1043 
1044 void DIALOG_SYMBOL_PROPERTIES::OnSizeGrid( wxSizeEvent& event )
1045 {
1046  auto new_size = event.GetSize().GetX();
1047 
1048  if( m_width != new_size )
1049  {
1050  AdjustGridColumns( new_size );
1051  }
1052 
1053  // Always propagate for a grid repaint (needed if the height changes, as well as width)
1054  event.Skip();
1055 }
1056 
1057 
1058 void DIALOG_SYMBOL_PROPERTIES::OnInitDlg( wxInitDialogEvent& event )
1059 {
1061 
1062  // Now all widgets have the size fixed, call FinishDialogSettings
1064 }
Field Reference of part, i.e. "IC21".
DIALOG_SYMBOL_PROPERTIES(SCH_EDIT_FRAME *aParent, SCH_COMPONENT *aComponent)
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
static int Compare(PinNumber const &lhs, PinNumber const &rhs)
Definition: pin_number.cpp:111
void SortRows(int aSortCol, bool ascending)
wxString GetColLabelValue(int aCol) override
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:51
void SelectReferenceNumber(wxTextEntry *aTextEntry)
Select the number (or "?") in a reference for ease of editing.
Definition: ui_common.cpp:102
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:259
wxString GetValue(int aRow, int aCol) override
LIB_PIN * GetLibPin() const
Definition: sch_pin.h:69
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
Definition: sch_symbol.h:502
const UTF8 & GetLibItemName() const
Definition: lib_id.h:106
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:243
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:420
int GetOrientation()
Get the display symbol orientation.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:265
void SetIncludeInBom(bool aIncludeInBom)
Definition: sch_symbol.h:699
Holds all the data relating to one schematic A schematic may consist of one or more sheets (and one r...
Definition: schematic.h:58
This file is part of the common library.
bool GetIncludeOnBoard() const
Definition: sch_symbol.h:701
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:129
Class DIALOG_SYMBOL_PROPERTIES_BASE.
void CollectOtherUnits(const wxString &aRef, int aUnit, SCH_SHEET_PATH &aSheet, std::vector< SCH_COMPONENT * > *otherUnits)
const std::vector< BITMAP_DEF > & PinTypeIcons()
Definition: pin_type.cpp:191
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:125
TEMPLATES m_TemplateFieldNames
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:97
wxString GetAlt() const
Definition: sch_pin.h:74
int GetUnitCount() const
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:356
void SetVisible(bool aVisible)
Definition: eda_text.h:192
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:52
void OnGridEditorShown(wxGridEvent &event) override
Schematic editor (Eeschema) main window.
wxString GetNumber() const
Definition: sch_pin.h:116
LIB_PART * GetLibPart(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
std::vector< SCH_FIELD > SCH_FIELDS
A container for several SCH_FIELD items.
Definition: sch_symbol.h:63
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:65
void SetIncludeOnBoard(bool aIncludeOnBoard)
Definition: sch_symbol.h:702
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void OnEditSpiceModel(wxCommandEvent &event) override
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:214
bool IsDragging() const
Definition: eda_item.h:170
name of datasheet
void OnAddField(wxCommandEvent &event) override
const std::vector< BITMAP_DEF > & PinShapeIcons()
Definition: pin_type.cpp:209
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populates a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:724
void SetConvert(int aConvert)
Definition: sch_symbol.cpp:333
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
Definition: wx_grid.cpp:97
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
bool ShowPinNames()
Definition: lib_symbol.h:563
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:82
int GetUnit() const
Definition: sch_symbol.h:236
bool ShowPinNumbers()
Definition: lib_symbol.h:571
const wxArrayString & PinShapeNames()
Definition: pin_type.cpp:200
bool IsEmptyCell(int row, int col) override
void SetFlags(STATUS_FLAGS aMask)
Definition: eda_item.h:202
Field Value of part, i.e. "3.3K".
void OnGridCellChanging(wxGridEvent &event)
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void OnMoveUp(wxCommandEvent &event) override
STATUS_FLAGS GetEditFlags() const
Definition: eda_item.h:207
void OnPinTableColSort(wxGridEvent &aEvent)
const wxString & GetName() const
Definition: lib_pin.h:156
void OnSizeGrid(wxSizeEvent &event) override
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
void OnEditSymbol(wxCommandEvent &) override
const BITMAP_OPAQUE small_down_xpm[1]
Definition: small_down.cpp:23
SCHEMATIC & Schematic() const
Define a library symbol object.
Definition: lib_symbol.h:93
unsigned STATUS_FLAGS
Definition: eda_item.h:144
const wxArrayString & PinTypeNames()
Definition: pin_type.cpp:182
static wxString GetValue(const SCH_PIN &aPin, int aCol)
void OnInitDlg(wxInitDialogEvent &event) override
bool IsAnnotated(const SCH_SHEET_PATH *aSheet)
Checks if the component has a valid annotation (reference) for the given sheet path.
Definition: sch_symbol.cpp:532
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:97
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslate=true)
Return a default symbol field name for field aFieldNdx for all components.
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:317
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::unique_ptr< LIB_PART > & GetPartRef()
Definition: sch_symbol.h:205
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:182
bool GetIncludeInBom() const
Definition: sch_symbol.h:698
void OnPinTableCellEdited(wxGridEvent &event) override
const BITMAP_OPAQUE small_up_xpm[1]
Definition: small_up.cpp:23
const BITMAP_OPAQUE small_trash_xpm[1]
Definition: small_trash.cpp:23
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:457
UTF8 Format() const
Definition: lib_id.cpp:233
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
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:110
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Definition: sch_symbol.cpp:477
void EndQuasiModal(int retCode)
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Definition: sch_symbol.cpp:562
std::map< wxString, ALT > & GetAlternates()
Definition: lib_pin.h:180
bool IsPower() const
Definition: lib_symbol.cpp:411
void OnDeleteField(wxCommandEvent &event) override
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:570
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:127
SCH_PIN_TABLE_DATA_MODEL * m_dataModel
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend)
Create a copy of the current schematic item, and put it in the undo list.
#define _(s)
Definition: 3d_actions.cpp:33
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:88
void SetAlt(const wxString &aAlt)
Definition: sch_pin.h:75
wxString GetName(bool aUseDefaultName=true) const
Function GetName returns the field name.
Definition: sch_field.cpp:505
void OnMoveDown(wxCommandEvent &event) override
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:447
std::vector< wxGridCellAttr * > m_nameAttrs
Schematic symbol object.
Definition: sch_symbol.h:78
wxPoint GetPosition() const override
Definition: sch_symbol.h:680
These settings were stored in SCH_BASE_FRAME previously.
Hold a name of a symbol's field, field value, and default visibility.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:203
static bool compare(const SCH_PIN &lhs, const SCH_PIN &rhs, int sortCol, bool ascending)
void OnExchangeSymbol(wxCommandEvent &) override
int GetConvert() const
Definition: sch_symbol.h:264
void OnEditLibrarySymbol(wxCommandEvent &) override
void OnCancelButtonClick(wxCommandEvent &event) override
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
FIELDS_GRID_TABLE< SCH_FIELD > * m_fields
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:174
Definition for part library class.
void SetValue(const SCH_SHEET_PATH *sheet, const wxString &aValue)
Definition: sch_symbol.cpp:609
static bool IsReferenceStringValid(const wxString &aReferenceString)
Tests for an acceptable reference string.
Definition: sch_symbol.cpp:461
void OnUpdateUI(wxUpdateUIEvent &event) override
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:562
STATUS_FLAGS GetFlags() const
Definition: eda_item.h:204
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:188
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind) override
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
Definition: tool_manager.h:267
void OnUpdateSymbol(wxCommandEvent &) override
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
const BITMAP_OPAQUE small_plus_xpm[1]
Definition: small_plus.cpp:18
void SetFootprint(const SCH_SHEET_PATH *sheet, const wxString &aFootprint)
Definition: sch_symbol.cpp:659
const TEMPLATE_FIELDNAMES & GetTemplateFieldNames()
Return a template field name list for read only access.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:427
void SetValue(int aRow, int aCol, const wxString &aValue) override
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
Field Name Module PCB, i.e. "16DIP300".
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
Definition: sch_symbol.cpp:837