KiCad PCB EDA Suite
sch_symbol.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <sch_edit_frame.h>
26 #include <widgets/msgpanel.h>
27 #include <bitmaps.h>
28 #include <core/mirror.h>
29 #include <lib_rectangle.h>
30 #include <lib_pin.h>
31 #include <lib_text.h>
32 #include <sch_symbol.h>
33 #include <sch_sheet_path.h>
34 #include <schematic.h>
35 #include <trace_helpers.h>
36 #include <trigo.h>
37 #include <refdes_utils.h>
38 #include <wx/log.h>
39 #include <string_utils.h>
40 
41 
46 std::string toUTFTildaText( const wxString& txt )
47 {
48  std::string ret = TO_UTF8( txt );
49 
50  for( std::string::iterator it = ret.begin(); it!=ret.end(); ++it )
51  {
52  if( (unsigned char) *it <= ' ' )
53  *it = '~';
54  }
55  return ret;
56 }
57 
58 
72 static LIB_SYMBOL* dummy()
73 {
74  static LIB_SYMBOL* symbol;
75 
76  if( !symbol )
77  {
78  symbol = new LIB_SYMBOL( wxEmptyString );
79 
80  LIB_RECTANGLE* square = new LIB_RECTANGLE( symbol );
81 
82  square->MoveTo( wxPoint( Mils2iu( -200 ), Mils2iu( 200 ) ) );
83  square->SetEndPosition( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) );
84 
85  LIB_TEXT* text = new LIB_TEXT( symbol );
86 
87  text->SetTextSize( wxSize( Mils2iu( 150 ), Mils2iu( 150 ) ) );
88  text->SetText( wxString( wxT( "??" ) ) );
89 
90  symbol->AddDrawItem( square );
91  symbol->AddDrawItem( text );
92  }
93 
94  return symbol;
95 }
96 
97 
98 SCH_SYMBOL::SCH_SYMBOL( const wxPoint& aPos, SCH_ITEM* aParent ) :
99  SCH_ITEM( aParent, SCH_SYMBOL_T )
100 {
101  Init( aPos );
102 }
103 
104 
105 SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
106  const SCH_SHEET_PATH* aSheet, int unit, int convert, const wxPoint& pos ) :
107  SCH_ITEM( nullptr, SCH_SYMBOL_T )
108 {
109  Init( pos );
110 
111  m_unit = unit;
112  m_convert = convert;
113  m_lib_id = aLibId;
114 
115  std::unique_ptr< LIB_SYMBOL > part;
116 
117  part = aSymbol.Flatten();
118  part->SetParent();
119  SetLibSymbol( part.release() );
120 
121  // Copy fields from the library symbol
122  UpdateFields( aSheet,
123  true, /* update style */
124  false, /* update ref */
125  false, /* update other fields */
126  true, /* reset ref */
127  true /* reset other fields */ );
128 
129  m_prefix = UTIL::GetRefDesPrefix( m_part->GetReferenceField().GetText() );
130 
131  if( aSheet )
132  {
134 
135  // Value and footprint name are stored in the SCH_SHEET_PATH path manager,
136  // if aSheet != nullptr, not in the symbol itself.
137  // Copy them to the currently displayed field texts
138  SetValue( GetValue( aSheet, false ) );
139  SetFootprint( GetFootprint( aSheet, false ) );
140  }
141 
142  // Inherit the include in bill of materials and board netlist settings from library symbol.
143  m_inBom = aSymbol.GetIncludeInBom();
144  m_onBoard = aSymbol.GetIncludeOnBoard();
145 }
146 
147 
148 SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const SCH_SHEET_PATH* aSheet,
149  const PICKED_SYMBOL& aSel, const wxPoint& pos ) :
150  SCH_SYMBOL( aSymbol, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos )
151 {
152  // Set any fields that were modified as part of the symbol selection
153  for( const std::pair<int, wxString>& i : aSel.Fields )
154  {
155  SCH_FIELD* field = GetFieldById( i.first );
156 
157  if( field )
158  field->SetText( i.second );
159  }
160 }
161 
162 
164  SCH_ITEM( aSymbol )
165 {
166  m_parent = aSymbol.m_parent;
167  m_pos = aSymbol.m_pos;
168  m_unit = aSymbol.m_unit;
169  m_convert = aSymbol.m_convert;
170  m_lib_id = aSymbol.m_lib_id;
171  m_isInNetlist = aSymbol.m_isInNetlist;
172  m_inBom = aSymbol.m_inBom;
173  m_onBoard = aSymbol.m_onBoard;
174 
175  if( aSymbol.m_part )
176  SetLibSymbol( new LIB_SYMBOL( *aSymbol.m_part.get() ) );
177 
178  const_cast<KIID&>( m_Uuid ) = aSymbol.m_Uuid;
179 
180  m_transform = aSymbol.m_transform;
181  m_prefix = aSymbol.m_prefix;
183  m_fields = aSymbol.m_fields;
184 
185  // Re-parent the fields, which before this had aSymbol as parent
186  for( SCH_FIELD& field : m_fields )
187  field.SetParent( this );
188 
191 }
192 
193 
194 void SCH_SYMBOL::Init( const wxPoint& pos )
195 {
196  m_pos = pos;
197  m_unit = 1; // In multi unit chip - which unit to draw.
198  m_convert = LIB_ITEM::LIB_CONVERT::BASE; // De Morgan Handling
199 
200  // The rotation/mirror transformation matrix. pos normal
202 
203  // construct only the mandatory fields, which are the first 4 only.
204  for( int i = 0; i < MANDATORY_FIELDS; ++i )
205  {
206  m_fields.emplace_back( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
207 
208  if( i == REFERENCE_FIELD )
209  m_fields.back().SetLayer( LAYER_REFERENCEPART );
210  else if( i == VALUE_FIELD )
211  m_fields.back().SetLayer( LAYER_VALUEPART );
212  else
213  m_fields.back().SetLayer( LAYER_FIELDS );
214  }
215 
216  m_prefix = wxString( wxT( "U" ) );
217  m_isInNetlist = true;
218  m_inBom = true;
219  m_onBoard = true;
220 }
221 
222 
224 {
225  return new SCH_SYMBOL( *this );
226 }
227 
228 
229 void SCH_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
230 {
231  aCount = 3;
232  aLayers[0] = LAYER_DEVICE;
233  aLayers[1] = LAYER_DEVICE_BACKGROUND;
234  aLayers[2] = LAYER_SELECTION_SHADOWS;
235 }
236 
237 
238 void SCH_SYMBOL::SetLibId( const LIB_ID& aLibId )
239 {
240  if( m_lib_id != aLibId )
241  {
242  m_lib_id = aLibId;
243  SetModified();
244  }
245 }
246 
247 
249 {
250  if( !m_schLibSymbolName.IsEmpty() )
251  return m_schLibSymbolName;
252  else
253  return m_lib_id.Format();
254 }
255 
256 
258 {
259  wxCHECK2( ( aLibSymbol == nullptr ) || ( aLibSymbol->IsRoot() ), aLibSymbol = nullptr );
260 
261  m_part.reset( aLibSymbol );
262  UpdatePins();
263 }
264 
265 
267 {
268  if( m_part )
269  return m_part->GetDescription();
270 
271  return wxEmptyString;
272 }
273 
274 
275 wxString SCH_SYMBOL::GetDatasheet() const
276 {
277  if( m_part )
278  return m_part->GetDatasheetField().GetText();
279 
280  return wxEmptyString;
281 }
282 
283 
285 {
286  std::map<wxString, wxString> altPinMap;
287  std::map<wxString, KIID> pinUuidMap;
288 
289  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
290  {
291  pinUuidMap[ pin->GetNumber() ] = pin->m_Uuid;
292 
293  if( !pin->GetAlt().IsEmpty() )
294  altPinMap[ pin->GetNumber() ] = pin->GetAlt();
295  }
296 
297  m_pins.clear();
298  m_pinMap.clear();
299 
300  if( !m_part )
301  return;
302 
303  unsigned i = 0;
304 
305  for( LIB_PIN* libPin = m_part->GetNextPin(); libPin; libPin = m_part->GetNextPin( libPin ) )
306  {
307  wxASSERT( libPin->Type() == LIB_PIN_T );
308 
309  if( libPin->GetConvert() && m_convert && ( m_convert != libPin->GetConvert() ) )
310  continue;
311 
312  m_pins.push_back( std::make_unique<SCH_PIN>( libPin, this ) );
313 
314  auto ii = pinUuidMap.find( libPin->GetNumber() );
315 
316  if( ii != pinUuidMap.end() )
317  const_cast<KIID&>( m_pins.back()->m_Uuid ) = ii->second;
318 
319  auto iii = altPinMap.find( libPin->GetNumber() );
320 
321  if( iii != altPinMap.end() )
322  m_pins.back()->SetAlt( iii->second );
323 
324  m_pinMap[ libPin ] = i;
325 
326  ++i;
327  }
328 }
329 
330 
331 void SCH_SYMBOL::SetUnit( int aUnit )
332 {
333  if( m_unit != aUnit )
334  {
335  m_unit = aUnit;
336  SetModified();
337  }
338 }
339 
340 
341 void SCH_SYMBOL::UpdateUnit( int aUnit )
342 {
343  m_unit = aUnit;
344 }
345 
346 
347 void SCH_SYMBOL::SetConvert( int aConvert )
348 {
349  if( m_convert != aConvert )
350  {
351  m_convert = aConvert;
352 
353  // The convert may have a different pin layout so the update the pin map.
354  UpdatePins();
355  SetModified();
356  }
357 }
358 
359 
360 void SCH_SYMBOL::SetTransform( const TRANSFORM& aTransform )
361 {
362  if( m_transform != aTransform )
363  {
364  m_transform = aTransform;
365  SetModified();
366  }
367 }
368 
369 
371 {
372  if( m_part )
373  return m_part->GetUnitCount();
374 
375  return 0;
376 }
377 
378 
379 void SCH_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
380 {
381  LIB_SYMBOL_OPTIONS opts;
382  opts.transform = m_transform;
383  opts.draw_visible_fields = false;
384  opts.draw_hidden_fields = false;
385 
386  if( m_part )
387  {
388  m_part->Print( aSettings, m_pos + aOffset, m_unit, m_convert, opts );
389  }
390  else // Use dummy() part if the actual cannot be found.
391  {
392  dummy()->Print( aSettings, m_pos + aOffset, 0, 0, opts );
393  }
394 
395  for( SCH_FIELD& field : m_fields )
396  field.Print( aSettings, aOffset );
397 }
398 
399 
400 void SCH_SYMBOL::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef,
401  int aUnit, const wxString& aValue,
402  const wxString& aFootprint )
403 {
404  // Search for an existing path and remove it if found (should not occur)
405  for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
406  {
407  if( m_instanceReferences[ii].m_Path == aPath )
408  {
409  wxLogTrace( traceSchSheetPaths, "Removing symbol instance:\n"
410  " sheet path %s\n"
411  " reference %s, unit %d from symbol %s.",
412  aPath.AsString(),
413  m_instanceReferences[ii].m_Reference,
414  m_instanceReferences[ii].m_Unit,
415  m_Uuid.AsString() );
416 
417  m_instanceReferences.erase( m_instanceReferences.begin() + ii );
418  ii--;
419  }
420  }
421 
422  SYMBOL_INSTANCE_REFERENCE instance;
423  instance.m_Path = aPath;
424  instance.m_Reference = aRef;
425  instance.m_Unit = aUnit;
426  instance.m_Value = aValue;
427  instance.m_Footprint = aFootprint;
428 
429  wxLogTrace( traceSchSheetPaths, "Adding symbol instance:\n"
430  " sheet path %s\n"
431  " reference %s, unit %d to symbol %s.",
432  aPath.AsString(),
433  aRef,
434  aUnit,
435  m_Uuid.AsString() );
436 
437  m_instanceReferences.push_back( instance );
438 }
439 
440 
441 const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit ) const
442 {
443  KIID_PATH path = sheet->Path();
444  wxString ref;
445 
446  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
447  {
448  if( instance.m_Path == path )
449  {
450  ref = instance.m_Reference;
451  break;
452  }
453  }
454 
455  // If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
456  // use this as a default for this path. This will happen if we load a version 1 schematic
457  // file. It will also mean that multiple instances of the same sheet by default all have
458  // the same symbol references, but perhaps this is best.
459  if( ref.IsEmpty() && !GetField( REFERENCE_FIELD )->GetText().IsEmpty() )
460  {
461  const_cast<SCH_SYMBOL*>( this )->SetRef( sheet, GetField( REFERENCE_FIELD )->GetText() );
462  ref = GetField( REFERENCE_FIELD )->GetText();
463  }
464 
465  if( ref.IsEmpty() )
467 
468  if( aIncludeUnit && GetUnitCount() > 1 )
469  ref += LIB_SYMBOL::SubReference( GetUnit() );
470 
471  return ref;
472 }
473 
474 
475 bool SCH_SYMBOL::IsReferenceStringValid( const wxString& aReferenceString )
476 {
477  return !UTIL::GetRefDesPrefix( aReferenceString ).IsEmpty();
478 }
479 
480 
481 void SCH_SYMBOL::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
482 {
483  KIID_PATH path = sheet->Path();
484  bool notInArray = true;
485 
486  // check to see if it is already there before inserting it
488  {
489  if( instance.m_Path == path )
490  {
491  instance.m_Reference = ref;
492  notInArray = false;
493  }
494  }
495 
496  if( notInArray )
498 
499  for( std::unique_ptr<SCH_PIN>& pin : m_pins )
500  pin->ClearDefaultNetName( sheet );
501 
503 
504  rf->SetText( ref ); // for drawing.
505 
506  // Reinit the m_prefix member if needed
508 
509  if( m_prefix.IsEmpty() )
510  m_prefix = wxT( "U" );
511 
512  // Power symbols have references starting with # and are not included in netlists
513  m_isInNetlist = ! ref.StartsWith( wxT( "#" ) );
514 }
515 
516 
518 {
519  KIID_PATH path = aSheet->Path();
520 
521  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
522  {
523  if( instance.m_Path == path )
524  return instance.m_Reference.Last() != '?';
525  }
526 
527  return false;
528 }
529 
530 
532 {
533  KIID_PATH path = aSheet->Path();
534 
535  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
536  {
537  if( instance.m_Path == path )
538  return instance.m_Unit;
539  }
540 
541  // If it was not found in m_Paths array, then use m_unit. This will happen if we load a
542  // version 1 schematic file.
543  return m_unit;
544 }
545 
546 
547 void SCH_SYMBOL::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
548 {
549  KIID_PATH path = aSheet->Path();
550 
551  // check to see if it is already there before inserting it
553  {
554  if( instance.m_Path == path )
555  {
556  instance.m_Unit = aUnitSelection;
557  return;
558  }
559  }
560 
561  // didn't find it; better add it
563 }
564 
565 
566 void SCH_SYMBOL::SetUnitSelection( int aUnitSelection )
567 {
569  instance.m_Unit = aUnitSelection;
570 }
571 
572 
573 const wxString SCH_SYMBOL::GetValue( const SCH_SHEET_PATH* sheet, bool aResolve ) const
574 {
575  KIID_PATH path = sheet->Path();
576 
577  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
578  {
579  if( instance.m_Path == path && !instance.m_Value.IsEmpty() )
580  {
581  // This can only be an override from an Update Schematic from PCB, and therefore
582  // will always be fully resolved.
583  return instance.m_Value;
584  }
585  }
586 
587  if( !aResolve )
588  return GetField( VALUE_FIELD )->GetText();
589 
590  return GetField( VALUE_FIELD )->GetShownText();
591 }
592 
593 
594 void SCH_SYMBOL::SetValue( const SCH_SHEET_PATH* sheet, const wxString& aValue )
595 {
596  if( sheet == nullptr )
597  {
598  // Clear instance overrides and set primary field value
600  instance.m_Value = wxEmptyString;
601 
602  m_fields[ VALUE_FIELD ].SetText( aValue );
603  return;
604  }
605 
606  KIID_PATH path = sheet->Path();
607 
608  // check to see if it is already there before inserting it
610  {
611  if( instance.m_Path == path )
612  {
613  instance.m_Value = aValue;
614  return;
615  }
616  }
617 
618  // didn't find it; better add it
620  aValue, wxEmptyString );
621 }
622 
623 
624 const wxString SCH_SYMBOL::GetFootprint( const SCH_SHEET_PATH* sheet, bool aResolve ) const
625 {
626  KIID_PATH path = sheet->Path();
627 
628  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
629  {
630  if( instance.m_Path == path && !instance.m_Footprint.IsEmpty() )
631  {
632  // This can only be an override from an Update Schematic from PCB, and therefore
633  // will always be fully resolved.
634  return instance.m_Footprint;
635  }
636  }
637 
638  if( !aResolve )
639  return GetField( FOOTPRINT_FIELD )->GetText();
640 
642 }
643 
644 
645 void SCH_SYMBOL::SetFootprint( const SCH_SHEET_PATH* sheet, const wxString& aFootprint )
646 {
647  if( sheet == nullptr )
648  {
649  // Clear instance overrides and set primary field value
651  instance.m_Footprint = wxEmptyString;
652 
653  m_fields[ FOOTPRINT_FIELD ].SetText( aFootprint );
654  return;
655  }
656 
657  KIID_PATH path = sheet->Path();
658 
659  // check to see if it is already there before inserting it
661  {
662  if( instance.m_Path == path )
663  {
664  instance.m_Footprint = aFootprint;
665  return;
666  }
667  }
668 
669  // didn't find it; better add it
671  wxEmptyString, aFootprint );
672 }
673 
674 
676 {
677  return &m_fields[aFieldType];
678 }
679 
680 
682 {
683  return &m_fields[aFieldType];
684 }
685 
686 
688 {
689  for( size_t ii = 0; ii < m_fields.size(); ++ii )
690  {
691  if( m_fields[ii].GetId() == aFieldId )
692  return &m_fields[ii];
693  }
694 
695  return nullptr;
696 }
697 
698 
699 wxString SCH_SYMBOL::GetFieldText( const wxString& aFieldName, SCH_EDIT_FRAME* aFrame ) const
700 {
701  for( const SCH_FIELD& field : m_fields )
702  {
703  if( aFieldName == field.GetName() || aFieldName == field.GetCanonicalName() )
704  return field.GetText();
705  }
706 
707  return wxEmptyString;
708 }
709 
710 
711 void SCH_SYMBOL::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
712 {
713  for( SCH_FIELD& field : m_fields )
714  {
715  if( !aVisibleOnly || ( field.IsVisible() && !field.IsVoid() ) )
716  aVector.push_back( &field );
717  }
718 }
719 
720 
722 {
723  int newNdx = m_fields.size();
724 
725  m_fields.push_back( aField );
726  return &m_fields[newNdx];
727 }
728 
729 
730 void SCH_SYMBOL::RemoveField( const wxString& aFieldName )
731 {
732  for( unsigned i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
733  {
734  if( aFieldName == m_fields[i].GetName( false ) )
735  {
736  m_fields.erase( m_fields.begin() + i );
737  return;
738  }
739  }
740 }
741 
742 
743 SCH_FIELD* SCH_SYMBOL::FindField( const wxString& aFieldName, bool aIncludeDefaultFields )
744 {
745  unsigned start = aIncludeDefaultFields ? 0 : MANDATORY_FIELDS;
746 
747  for( unsigned i = start; i < m_fields.size(); ++i )
748  {
749  if( aFieldName == m_fields[i].GetName( false ) )
750  return &m_fields[i];
751  }
752 
753  return nullptr;
754 }
755 
756 
757 void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef,
758  bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields )
759 {
760  if( m_part )
761  {
762  wxString symbolName;
763  std::vector<LIB_FIELD*> fields;
764 
765  m_part->GetFields( fields );
766 
767  for( const LIB_FIELD* libField : fields )
768  {
769  int id = libField->GetId();
770  SCH_FIELD* schField;
771 
772  if( id >= 0 && id < MANDATORY_FIELDS )
773  {
774  schField = GetFieldById( id );
775  }
776  else
777  {
778  schField = FindField( libField->GetCanonicalName() );
779 
780  if( !schField )
781  {
782  wxString fieldName = libField->GetCanonicalName();
783  SCH_FIELD newField( wxPoint( 0, 0), GetFieldCount(), this, fieldName );
784  schField = AddField( newField );
785  }
786  }
787 
788  if( aUpdateStyle )
789  {
790  schField->ImportValues( *libField );
791  schField->SetTextPos( m_pos + libField->GetTextPos() );
792  }
793 
794  if( id == REFERENCE_FIELD && aPath )
795  {
796  if( aResetRef )
797  SetRef( aPath, m_part->GetReferenceField().GetText() );
798  else if( aUpdateRef )
799  SetRef( aPath, libField->GetText() );
800  }
801  else if( id == VALUE_FIELD )
802  {
803  if( aResetOtherFields )
804  SetValue( aPath, UnescapeString( m_lib_id.GetLibItemName() ) ); // alias-specific value
805  else
806  SetValue( aPath, UnescapeString( libField->GetText() ) );
807  }
808  else if( id == FOOTPRINT_FIELD )
809  {
810  if( aResetOtherFields || aUpdateOtherFields )
811  SetFootprint( aPath, libField->GetText() );
812  }
813  else if( id == DATASHEET_FIELD )
814  {
815  if( aResetOtherFields )
816  schField->SetText( GetDatasheet() ); // alias-specific value
817  else if( aUpdateOtherFields )
818  schField->SetText( libField->GetText() );
819  }
820  else
821  {
822  if( aResetOtherFields || aUpdateOtherFields )
823  schField->SetText( libField->GetText() );
824  }
825  }
826  }
827 }
828 
829 
830 void SCH_SYMBOL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
831 {
832  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
833  aFunction( pin.get() );
834 
835  for( SCH_FIELD& field : m_fields )
836  aFunction( &field );
837 }
838 
839 
840 SCH_PIN* SCH_SYMBOL::GetPin( const wxString& aNumber ) const
841 {
842  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
843  {
844  if( pin->GetNumber() == aNumber )
845  return pin.get();
846  }
847 
848  return nullptr;
849 }
850 
851 
852 void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
853 {
854  if( m_part )
855  m_part->GetPins( aPinsList, m_unit, m_convert );
856 }
857 
858 
860 {
861  wxASSERT( m_pinMap.count( aLibPin ) );
862  return m_pins[ m_pinMap.at( aLibPin ) ].get();
863 }
864 
865 
866 std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
867 {
868  std::vector<SCH_PIN*> pins;
869 
870  if( aSheet == nullptr )
871  {
872  wxCHECK_MSG( Schematic(), pins, "Can't call GetPins on a symbol with no schematic" );
873 
874  aSheet = &Schematic()->CurrentSheet();
875  }
876 
877  int unit = GetUnitSelection( aSheet );
878 
879  for( const auto& p : m_pins )
880  {
881  if( unit && p->GetLibPin()->GetUnit() && ( p->GetLibPin()->GetUnit() != unit ) )
882  continue;
883 
884  pins.push_back( p.get() );
885  }
886 
887  return pins;
888 }
889 
890 
892 {
893  wxCHECK_RET( (aItem != nullptr) && (aItem->Type() == SCH_SYMBOL_T),
894  wxT( "Cannot swap data with invalid symbol." ) );
895 
896  SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
897 
898  std::swap( m_lib_id, symbol->m_lib_id );
899 
900  LIB_SYMBOL* libSymbol = symbol->m_part.release();
901  symbol->m_part.reset( m_part.release() );
902  symbol->UpdatePins();
903  m_part.reset( libSymbol );
904  UpdatePins();
905 
906  std::swap( m_pos, symbol->m_pos );
907  std::swap( m_unit, symbol->m_unit );
908  std::swap( m_convert, symbol->m_convert );
909 
910  m_fields.swap( symbol->m_fields ); // std::vector's swap()
911 
912  for( SCH_FIELD& field : symbol->m_fields )
913  field.SetParent( symbol );
914 
915  for( SCH_FIELD& field : m_fields )
916  field.SetParent( this );
917 
918  TRANSFORM tmp = m_transform;
919 
920  m_transform = symbol->m_transform;
921  symbol->m_transform = tmp;
922 
923  std::swap( m_instanceReferences, symbol->m_instanceReferences );
924  std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName );
925 }
926 
927 
928 void SCH_SYMBOL::GetContextualTextVars( wxArrayString* aVars ) const
929 {
930  for( int i = 0; i < MANDATORY_FIELDS; ++i )
931  aVars->push_back( m_fields[i].GetCanonicalName().Upper() );
932 
933  for( size_t i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
934  aVars->push_back( m_fields[i].GetName() );
935 
936  aVars->push_back( wxT( "FOOTPRINT_LIBRARY" ) );
937  aVars->push_back( wxT( "FOOTPRINT_NAME" ) );
938  aVars->push_back( wxT( "UNIT" ) );
939 }
940 
941 
942 bool SCH_SYMBOL::ResolveTextVar( wxString* token, int aDepth ) const
943 {
944  SCHEMATIC* schematic = Schematic();
945 
946  // SCH_SYMOL object has no context outside a schematic.
947  wxCHECK( schematic, false );
948 
949  for( int i = 0; i < MANDATORY_FIELDS; ++i )
950  {
951  if( token->IsSameAs( m_fields[ i ].GetCanonicalName().Upper() ) )
952  {
953  if( i == REFERENCE_FIELD )
954  *token = GetRef( &schematic->CurrentSheet(), true );
955  else if( i == VALUE_FIELD )
956  *token = GetValue( &schematic->CurrentSheet(), true );
957  else if( i == FOOTPRINT_FIELD )
958  *token = GetFootprint( &schematic->CurrentSheet(), true );
959  else
960  *token = m_fields[ i ].GetShownText( aDepth + 1 );
961 
962  return true;
963  }
964  }
965 
966  for( size_t i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
967  {
968  if( token->IsSameAs( m_fields[ i ].GetName() )
969  || token->IsSameAs( m_fields[ i ].GetName().Upper() ) )
970  {
971  *token = m_fields[ i ].GetShownText( aDepth + 1 );
972  return true;
973  }
974  }
975 
976  for( const TEMPLATE_FIELDNAME& templateFieldname :
978  {
979  if( token->IsSameAs( templateFieldname.m_Name )
980  || token->IsSameAs( templateFieldname.m_Name.Upper() ) )
981  {
982  // If we didn't find it in the fields list then it isn't set on this symbol.
983  // Just return an empty string.
984  *token = wxEmptyString;
985  return true;
986  }
987  }
988 
989  if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
990  {
991  wxString footprint;
992 
993  footprint = GetFootprint( &schematic->CurrentSheet(), true );
994 
995  wxArrayString parts = wxSplit( footprint, ':' );
996 
997  *token = parts[ 0 ];
998  return true;
999  }
1000  else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
1001  {
1002  wxString footprint;
1003 
1004  footprint = GetFootprint( &schematic->CurrentSheet(), true );
1005 
1006  wxArrayString parts = wxSplit( footprint, ':' );
1007 
1008  *token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
1009  return true;
1010  }
1011  else if( token->IsSameAs( wxT( "UNIT" ) ) )
1012  {
1013  int unit;
1014 
1015  unit = GetUnitSelection( &schematic->CurrentSheet() );
1016 
1017  *token = LIB_SYMBOL::SubReference( unit );
1018  return true;
1019  }
1020 
1021  return false;
1022 }
1023 
1024 
1026 {
1027  // Build a reference with no annotation, i.e. a reference ending with a single '?'
1028  wxString defRef = UTIL::GetRefDesUnannotated( m_prefix );
1029 
1030  if( aSheetPath )
1031  {
1032  KIID_PATH path = aSheetPath->Path();
1033 
1035  {
1036  if( instance.m_Path == path )
1037  instance.m_Reference = defRef;
1038  }
1039  }
1040  else
1041  {
1043  instance.m_Reference = defRef;
1044  }
1045 
1046  for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1047  pin->ClearDefaultNetName( aSheetPath );
1048 
1049  // These 2 changes do not work in complex hierarchy.
1050  // When a clear annotation is made, the calling function must call a
1051  // UpdateAllScreenReferences for the active sheet.
1052  // But this call cannot made here.
1053  m_fields[REFERENCE_FIELD].SetText( defRef ); //for drawing.
1054 }
1055 
1056 
1058 {
1059  // a empty sheet path is illegal:
1060  wxCHECK( aSheetPath.size() > 0, false );
1061 
1062  wxString reference_path;
1063 
1064  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
1065  {
1066  // if aSheetPath is found, nothing to do:
1067  if( instance.m_Path == aSheetPath )
1068  return false;
1069  }
1070 
1071  // This entry does not exist: add it, with its last-used reference
1072  AddHierarchicalReference( aSheetPath, m_fields[REFERENCE_FIELD].GetText(), m_unit );
1073  return true;
1074 }
1075 
1076 
1078  const KIID_PATH& aNewSheetPath )
1079 {
1080  auto it = std::find_if( m_instanceReferences.begin(), m_instanceReferences.end(),
1081  [ aOldSheetPath ]( SYMBOL_INSTANCE_REFERENCE& r )->bool
1082  {
1083  return aOldSheetPath == r.m_Path;
1084  }
1085  );
1086 
1087  if( it != m_instanceReferences.end() )
1088  {
1089  wxLogTrace( traceSchSheetPaths,
1090  "Replacing sheet path %s\n with sheet path %s\n for symbol %s.",
1091  aOldSheetPath.AsString(), aNewSheetPath.AsString(), m_Uuid.AsString() );
1092 
1093  it->m_Path = aNewSheetPath;
1094  return true;
1095  }
1096 
1097  wxLogTrace( traceSchSheetPaths,
1098  "Could not find sheet path %s\n to replace with sheet path %s\n for symbol %s.",
1099  aOldSheetPath.AsString(), aNewSheetPath.AsString(), m_Uuid.AsString() );
1100 
1101  return false;
1102 }
1103 
1104 
1105 void SCH_SYMBOL::SetOrientation( int aOrientation )
1106 {
1107  TRANSFORM temp = TRANSFORM();
1108  bool transform = false;
1109 
1110  switch( aOrientation )
1111  {
1112  case SYM_ORIENT_0:
1113  case SYM_NORMAL: // default transform matrix
1114  m_transform.x1 = 1;
1115  m_transform.y2 = -1;
1116  m_transform.x2 = m_transform.y1 = 0;
1117  break;
1118 
1119  case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1120  temp.x1 = temp.y2 = 0;
1121  temp.y1 = 1;
1122  temp.x2 = -1;
1123  transform = true;
1124  break;
1125 
1126  case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1127  temp.x1 = temp.y2 = 0;
1128  temp.y1 = -1;
1129  temp.x2 = 1;
1130  transform = true;
1131  break;
1132 
1133  case SYM_MIRROR_Y: // Mirror Y (incremental rotation)
1134  temp.x1 = -1;
1135  temp.y2 = 1;
1136  temp.y1 = temp.x2 = 0;
1137  transform = true;
1138  break;
1139 
1140  case SYM_MIRROR_X: // Mirror X (incremental rotation)
1141  temp.x1 = 1;
1142  temp.y2 = -1;
1143  temp.y1 = temp.x2 = 0;
1144  transform = true;
1145  break;
1146 
1147  case SYM_ORIENT_90:
1150  break;
1151 
1152  case SYM_ORIENT_180:
1156  break;
1157 
1158  case SYM_ORIENT_270:
1161  break;
1162 
1163  case ( SYM_ORIENT_0 + SYM_MIRROR_X ):
1166  break;
1167 
1168  case ( SYM_ORIENT_0 + SYM_MIRROR_Y ):
1171  break;
1172 
1173  case ( SYM_ORIENT_90 + SYM_MIRROR_X ):
1176  break;
1177 
1178  case ( SYM_ORIENT_90 + SYM_MIRROR_Y ):
1181  break;
1182 
1183  case ( SYM_ORIENT_180 + SYM_MIRROR_X ):
1186  break;
1187 
1188  case ( SYM_ORIENT_180 + SYM_MIRROR_Y ):
1191  break;
1192 
1193  case ( SYM_ORIENT_270 + SYM_MIRROR_X ):
1196  break;
1197 
1198  case ( SYM_ORIENT_270 + SYM_MIRROR_Y ):
1201  break;
1202 
1203  default:
1204  transform = false;
1205  wxFAIL_MSG( "Invalid schematic symbol orientation type." );
1206  break;
1207  }
1208 
1209  if( transform )
1210  {
1211  /* The new matrix transform is the old matrix transform modified by the
1212  * requested transformation, which is the temp transform (rot,
1213  * mirror ..) in order to have (in term of matrix transform):
1214  * transform coord = new_m_transform * coord
1215  * where transform coord is the coord modified by new_m_transform from
1216  * the initial value coord.
1217  * new_m_transform is computed (from old_m_transform and temp) to
1218  * have:
1219  * transform coord = old_m_transform * temp
1220  */
1221  TRANSFORM newTransform;
1222 
1223  newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1224  newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1225  newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1226  newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1227  m_transform = newTransform;
1228  }
1229 }
1230 
1231 
1233 {
1234  int rotate_values[] =
1235  {
1236  SYM_ORIENT_0,
1237  SYM_ORIENT_90,
1243  SYM_MIRROR_Y,
1248  };
1249 
1250  // Try to find the current transform option:
1251  TRANSFORM transform = m_transform;
1252 
1253  for( int type_rotate : rotate_values )
1254  {
1255  SetOrientation( type_rotate );
1256 
1257  if( transform == m_transform )
1258  return type_rotate;
1259  }
1260 
1261  // Error: orientation not found in list (should not happen)
1262  wxFAIL_MSG( "Schematic symbol orientation matrix internal error." );
1263  m_transform = transform;
1264 
1265  return SYM_NORMAL;
1266 }
1267 
1268 
1269 #if defined(DEBUG)
1270 
1271 void SCH_SYMBOL::Show( int nestLevel, std::ostream& os ) const
1272 {
1273  // for now, make it look like XML:
1274  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1275  << " ref=\"" << TO_UTF8( GetField( REFERENCE_FIELD )->GetName() )
1276  << '"' << " chipName=\""
1277  << GetLibId().Format() << '"' << m_pos
1278  << " layer=\"" << m_layer
1279  << '"' << ">\n";
1280 
1281  // skip the reference, it's been output already.
1282  for( int i = 1; i < GetFieldCount(); ++i )
1283  {
1284  const wxString& value = GetFields()[i].GetText();
1285 
1286  if( !value.IsEmpty() )
1287  {
1288  NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1289  << TO_UTF8( GetFields()[i].GetName() )
1290  << '"' << " value=\""
1291  << TO_UTF8( value ) << "\"/>\n";
1292  }
1293  }
1294 
1295  NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1296 }
1297 
1298 #endif
1299 
1300 
1302 {
1303  EDA_RECT bBox;
1304 
1305  if( m_part )
1306  bBox = m_part->GetBodyBoundingBox( m_unit, m_convert );
1307  else
1308  bBox = dummy()->GetBodyBoundingBox( m_unit, m_convert );
1309 
1310  int x0 = bBox.GetX();
1311  int xm = bBox.GetRight();
1312 
1313  // We must reverse Y values, because matrix orientation
1314  // suppose Y axis normal for the library items coordinates,
1315  // m_transform reverse Y values, but bBox is already reversed!
1316  int y0 = -bBox.GetY();
1317  int ym = -bBox.GetBottom();
1318 
1319  // Compute the real Boundary box (rotated, mirrored ...)
1320  int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
1321  int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
1322  int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
1323  int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
1324 
1325  bBox.SetX( x1 );
1326  bBox.SetY( y1 );
1327  bBox.SetWidth( x2 - x1 );
1328  bBox.SetHeight( y2 - y1 );
1329  bBox.Normalize();
1330 
1331  bBox.Offset( m_pos );
1332  return bBox;
1333 }
1334 
1335 
1337 {
1338  EDA_RECT bbox = GetBodyBoundingBox();
1339 
1340  for( const SCH_FIELD& field : m_fields )
1341  {
1342  if( field.IsVisible() )
1343  bbox.Merge( field.GetBoundingBox() );
1344  }
1345 
1346  return bbox;
1347 }
1348 
1349 
1350 const EDA_RECT SCH_SYMBOL::GetBoundingBox( bool aIncludeInvisibleText ) const
1351 {
1352  EDA_RECT bbox = GetBodyBoundingBox();
1353 
1354  for( const SCH_FIELD& field : m_fields )
1355  {
1356  if( field.IsVisible() || aIncludeInvisibleText )
1357  bbox.Merge( field.GetBoundingBox() );
1358  }
1359 
1360  return bbox;
1361 }
1362 
1363 
1365 {
1366  wxString msg;
1367 
1368  SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1369  SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1370 
1371  // part and alias can differ if alias is not the root
1372  if( m_part )
1373  {
1374  if( m_part.get() != dummy() )
1375  {
1376  aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( currentSheet ) ) );
1377 
1378  msg = m_part->IsPower() ? _( "Power symbol" ) : _( "Value" );
1379 
1380  aList.push_back( MSG_PANEL_ITEM( msg, GetValue( currentSheet, true ) ) );
1381 
1382 #if 0 // Display symbol flags, for debug only
1383  aList.push_back( MSG_PANEL_ITEM( _( "flags" ),
1384  wxString::Format( "%X", GetEditFlags() ) ) );
1385 #endif
1386 
1387  // Display symbol reference in library and library
1388  aList.push_back( MSG_PANEL_ITEM( _( "Name" ),
1389  UnescapeString( GetLibId().GetLibItemName() ) ) );
1390 
1391  if( !m_part->IsRoot() )
1392  {
1393  msg = _( "Missing parent" );
1394 
1395  std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock();
1396 
1397  if( parent )
1398  msg = parent->GetName();
1399 
1400  aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), UnescapeString( msg ) ) );
1401  }
1402  else if( !m_lib_id.GetLibNickname().empty() )
1403  {
1404  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname() ) );
1405  }
1406  else
1407  {
1408  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Undefined!!!" ) ) );
1409  }
1410 
1411  // Display the current associated footprint, if exists.
1412  msg = GetFootprint( currentSheet, true );
1413 
1414  if( msg.IsEmpty() )
1415  msg = _( "<Unknown>" );
1416 
1417  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg ) );
1418 
1419  // Display description of the symbol, and keywords found in lib
1420  aList.push_back( MSG_PANEL_ITEM( _( "Description" ), m_part->GetDescription(),
1421  DARKCYAN ) );
1422  aList.push_back( MSG_PANEL_ITEM( _( "Keywords" ), m_part->GetKeyWords() ) );
1423  }
1424  }
1425  else
1426  {
1427  aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( currentSheet ) ) );
1428 
1429  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetValue( currentSheet, true ) ) );
1430  aList.push_back( MSG_PANEL_ITEM( _( "Name" ), GetLibId().GetLibItemName() ) );
1431 
1432  wxString libNickname = GetLibId().GetLibNickname();
1433 
1434  if( libNickname.empty() )
1435  {
1436  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "No library defined!" ) ) );
1437  }
1438  else
1439  {
1440  msg.Printf( _( "Symbol not found in %s!" ), libNickname );
1441  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), msg ) );
1442  }
1443  }
1444 }
1445 
1446 
1448 {
1449  return BITMAPS::add_component;
1450 }
1451 
1452 
1454 {
1455  int dx = m_pos.x;
1456 
1458  MIRROR( m_pos.x, aCenter );
1459  dx -= m_pos.x; // dx,0 is the move vector for this transform
1460 
1461  for( SCH_FIELD& field : m_fields )
1462  {
1463  // Move the fields to the new position because the symbol itself has moved.
1464  wxPoint pos = field.GetTextPos();
1465  pos.x -= dx;
1466  field.SetTextPos( pos );
1467  }
1468 }
1469 
1470 
1471 void SCH_SYMBOL::MirrorVertically( int aCenter )
1472 {
1473  int dy = m_pos.y;
1474 
1476  MIRROR( m_pos.y, aCenter );
1477  dy -= m_pos.y; // dy,0 is the move vector for this transform
1478 
1479  for( SCH_FIELD& field : m_fields )
1480  {
1481  // Move the fields to the new position because the symbol itself has moved.
1482  wxPoint pos = field.GetTextPos();
1483  pos.y -= dy;
1484  field.SetTextPos( pos );
1485  }
1486 }
1487 
1488 
1489 void SCH_SYMBOL::Rotate( const wxPoint& aCenter )
1490 {
1491  wxPoint prev = m_pos;
1492 
1493  RotatePoint( &m_pos, aCenter, 900 );
1494 
1496 
1497  for( SCH_FIELD& field : m_fields )
1498  {
1499  // Move the fields to the new position because the symbol itself has moved.
1500  wxPoint pos = field.GetTextPos();
1501  pos.x -= prev.x - m_pos.x;
1502  pos.y -= prev.y - m_pos.y;
1503  field.SetTextPos( pos );
1504  }
1505 }
1506 
1507 
1508 bool SCH_SYMBOL::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
1509 {
1510  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
1511 
1512  // Symbols are searchable via the child field and pin item text.
1513  return false;
1514 }
1515 
1516 
1517 void SCH_SYMBOL::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
1518 {
1519  for( auto& pin : m_pins )
1520  {
1521  LIB_PIN* lib_pin = pin->GetLibPin();
1522 
1523  if( lib_pin->GetUnit() && m_unit && ( m_unit != lib_pin->GetUnit() ) )
1524  continue;
1525 
1526  DANGLING_END_ITEM item( PIN_END, lib_pin, GetPinPhysicalPosition( lib_pin ), this );
1527  aItemList.push_back( item );
1528  }
1529 }
1530 
1531 
1532 bool SCH_SYMBOL::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
1533  const SCH_SHEET_PATH* aPath )
1534 {
1535  bool changed = false;
1536 
1537  for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1538  {
1539  bool previousState = pin->IsDangling();
1540  pin->SetIsDangling( true );
1541 
1542  wxPoint pos = m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos;
1543 
1544  for( DANGLING_END_ITEM& each_item : aItemList )
1545  {
1546  // Some people like to stack pins on top of each other in a symbol to indicate
1547  // internal connection. While technically connected, it is not particularly useful
1548  // to display them that way, so skip any pins that are in the same symbol as this
1549  // one.
1550  if( each_item.GetParent() == this )
1551  continue;
1552 
1553  switch( each_item.GetType() )
1554  {
1555  case PIN_END:
1556  case LABEL_END:
1557  case SHEET_LABEL_END:
1558  case WIRE_START_END:
1559  case WIRE_END_END:
1560  case NO_CONNECT_END:
1561  case JUNCTION_END:
1562 
1563  if( pos == each_item.GetPosition() )
1564  pin->SetIsDangling( false );
1565 
1566  break;
1567 
1568  default:
1569  break;
1570  }
1571 
1572  if( !pin->IsDangling() )
1573  break;
1574  }
1575 
1576  changed = ( changed || ( previousState != pin->IsDangling() ) );
1577  }
1578 
1579  return changed;
1580 }
1581 
1582 
1583 wxPoint SCH_SYMBOL::GetPinPhysicalPosition( const LIB_PIN* Pin ) const
1584 {
1585  wxCHECK_MSG( Pin != nullptr && Pin->Type() == LIB_PIN_T, wxPoint( 0, 0 ),
1586  wxT( "Cannot get physical position of pin." ) );
1587 
1588  return m_transform.TransformCoordinate( Pin->GetPosition() ) + m_pos;
1589 }
1590 
1591 
1592 std::vector<wxPoint> SCH_SYMBOL::GetConnectionPoints() const
1593 {
1594  std::vector<wxPoint> retval;
1595 
1596  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1597  {
1598  // Collect only pins attached to the current unit and convert.
1599  // others are not associated to this symbol instance
1600  int pin_unit = pin->GetLibPin()->GetUnit();
1601  int pin_convert = pin->GetLibPin()->GetConvert();
1602 
1603  if( pin_unit > 0 && pin_unit != GetUnit() )
1604  continue;
1605 
1606  if( pin_convert > 0 && pin_convert != GetConvert() )
1607  continue;
1608 
1609  retval.push_back( m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos );
1610  }
1611 
1612  return retval;
1613 }
1614 
1615 
1616 LIB_ITEM* SCH_SYMBOL::GetDrawItem( const wxPoint& aPosition, KICAD_T aType )
1617 {
1618  if( m_part )
1619  {
1620  // Calculate the position relative to the symbol.
1621  wxPoint libPosition = aPosition - m_pos;
1622 
1623  return m_part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
1624  }
1625 
1626  return nullptr;
1627 }
1628 
1629 
1631 {
1632  return wxString::Format( _( "Symbol %s [%s]" ),
1633  GetField( REFERENCE_FIELD )->GetShownText(),
1634  UnescapeString( GetLibId().GetLibItemName() ) );
1635 }
1636 
1637 
1638 SEARCH_RESULT SCH_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
1639  const KICAD_T aFilterTypes[] )
1640 {
1641  KICAD_T stype;
1642 
1643  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
1644  {
1645  if( stype == SCH_LOCATE_ANY_T
1646  || ( stype == SCH_SYMBOL_T )
1647  || ( stype == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
1648  {
1649  if( SEARCH_RESULT::QUIT == aInspector( this, aTestData ) )
1650  return SEARCH_RESULT::QUIT;
1651  }
1652 
1653  if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
1654  {
1655  for( SCH_FIELD& field : m_fields )
1656  {
1657  if( SEARCH_RESULT::QUIT == aInspector( &field, (void*) this ) )
1658  return SEARCH_RESULT::QUIT;
1659  }
1660  }
1661 
1662  if( stype == SCH_FIELD_LOCATE_REFERENCE_T )
1663  {
1664  if( SEARCH_RESULT::QUIT == aInspector( GetField( REFERENCE_FIELD ), (void*) this ) )
1665  return SEARCH_RESULT::QUIT;
1666  }
1667 
1668  if( stype == SCH_FIELD_LOCATE_VALUE_T
1669  || ( stype == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
1670  {
1671  if( SEARCH_RESULT::QUIT == aInspector( GetField( VALUE_FIELD ), (void*) this ) )
1672  return SEARCH_RESULT::QUIT;
1673  }
1674 
1675  if( stype == SCH_FIELD_LOCATE_FOOTPRINT_T )
1676  {
1677  if( SEARCH_RESULT::QUIT == aInspector( GetField( FOOTPRINT_FIELD ), (void*) this ) )
1678  return SEARCH_RESULT::QUIT;
1679  }
1680 
1681  if( stype == SCH_FIELD_LOCATE_DATASHEET_T )
1682  {
1683  if( SEARCH_RESULT::QUIT == aInspector( GetField( DATASHEET_FIELD ), (void*) this ) )
1684  return SEARCH_RESULT::QUIT;
1685  }
1686 
1687  if( stype == SCH_LOCATE_ANY_T || stype == SCH_PIN_T )
1688  {
1689  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1690  {
1691  // Collect only pins attached to the current unit and convert.
1692  // others are not associated to this symbol instance
1693  int pin_unit = pin->GetLibPin()->GetUnit();
1694  int pin_convert = pin->GetLibPin()->GetConvert();
1695 
1696  if( pin_unit > 0 && pin_unit != GetUnit() )
1697  continue;
1698 
1699  if( pin_convert > 0 && pin_convert != GetConvert() )
1700  continue;
1701 
1702  if( SEARCH_RESULT::QUIT == aInspector( pin.get(), (void*) this ) )
1703  return SEARCH_RESULT::QUIT;
1704  }
1705  }
1706  }
1707 
1708  return SEARCH_RESULT::CONTINUE;
1709 }
1710 
1711 
1712 bool SCH_SYMBOL::operator <( const SCH_ITEM& aItem ) const
1713 {
1714  if( Type() != aItem.Type() )
1715  return Type() < aItem.Type();
1716 
1717  auto symbol = static_cast<const SCH_SYMBOL*>( &aItem );
1718 
1719  EDA_RECT rect = GetBodyBoundingBox();
1720 
1721  if( rect.GetArea() != symbol->GetBodyBoundingBox().GetArea() )
1722  return rect.GetArea() < symbol->GetBodyBoundingBox().GetArea();
1723 
1724  if( m_pos.x != symbol->m_pos.x )
1725  return m_pos.x < symbol->m_pos.x;
1726 
1727  if( m_pos.y != symbol->m_pos.y )
1728  return m_pos.y < symbol->m_pos.y;
1729 
1730  return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
1731 }
1732 
1733 
1734 bool SCH_SYMBOL::operator==( const SCH_SYMBOL& aSymbol ) const
1735 {
1736  if( GetFieldCount() != aSymbol.GetFieldCount() )
1737  return false;
1738 
1739  for( int i = VALUE_FIELD; i < GetFieldCount(); i++ )
1740  {
1741  if( GetFields()[i].GetText().Cmp( aSymbol.GetFields()[i].GetText() ) != 0 )
1742  return false;
1743  }
1744 
1745  return true;
1746 }
1747 
1748 
1749 bool SCH_SYMBOL::operator!=( const SCH_SYMBOL& aSymbol ) const
1750 {
1751  return !( *this == aSymbol );
1752 }
1753 
1754 
1756 {
1757  wxCHECK_MSG( Type() == aItem.Type(), *this,
1758  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1759  GetClass() );
1760 
1761  if( &aItem != this )
1762  {
1763  SCH_ITEM::operator=( aItem );
1764 
1765  SCH_SYMBOL* c = (SCH_SYMBOL*) &aItem;
1766 
1767  m_lib_id = c->m_lib_id;
1768 
1769  LIB_SYMBOL* libSymbol = c->m_part ? new LIB_SYMBOL( *c->m_part.get() ) : nullptr;
1770 
1771  m_part.reset( libSymbol );
1772  m_pos = c->m_pos;
1773  m_unit = c->m_unit;
1774  m_convert = c->m_convert;
1775  m_transform = c->m_transform;
1776 
1778 
1779  m_fields = c->m_fields; // std::vector's assignment operator
1780 
1781  // Reparent fields after assignment to new symbol.
1782  for( SCH_FIELD& field : m_fields )
1783  field.SetParent( this );
1784 
1785  UpdatePins();
1786  }
1787 
1788  return *this;
1789 }
1790 
1791 
1792 bool SCH_SYMBOL::HitTest( const wxPoint& aPosition, int aAccuracy ) const
1793 {
1794  EDA_RECT bBox = GetBodyBoundingBox();
1795  bBox.Inflate( aAccuracy );
1796 
1797  if( bBox.Contains( aPosition ) )
1798  return true;
1799 
1800  return false;
1801 }
1802 
1803 
1804 bool SCH_SYMBOL::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
1805 {
1807  return false;
1808 
1809  EDA_RECT rect = aRect;
1810 
1811  rect.Inflate( aAccuracy );
1812 
1813  if( aContained )
1814  return rect.Contains( GetBodyBoundingBox() );
1815 
1816  return rect.Intersects( GetBodyBoundingBox() );
1817 }
1818 
1819 
1820 bool SCH_SYMBOL::doIsConnected( const wxPoint& aPosition ) const
1821 {
1822  wxPoint new_pos = m_transform.InverseTransform().TransformCoordinate( aPosition - m_pos );
1823 
1824  for( const auto& pin : m_pins )
1825  {
1826  if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
1827  continue;
1828 
1829  // Collect only pins attached to the current unit and convert.
1830  // others are not associated to this symbol instance
1831  int pin_unit = pin->GetLibPin()->GetUnit();
1832  int pin_convert = pin->GetLibPin()->GetConvert();
1833 
1834  if( pin_unit > 0 && pin_unit != GetUnit() )
1835  continue;
1836 
1837  if( pin_convert > 0 && pin_convert != GetConvert() )
1838  continue;
1839 
1840  if( pin->GetLocalPosition() == new_pos )
1841  return true;
1842  }
1843 
1844  return false;
1845 }
1846 
1847 
1849 {
1850  return m_isInNetlist;
1851 }
1852 
1853 
1854 void SCH_SYMBOL::Plot( PLOTTER* aPlotter ) const
1855 {
1856  if( m_part )
1857  {
1858  TRANSFORM temp = GetTransform();
1859  aPlotter->StartBlock( nullptr );
1860 
1861  m_part->Plot( aPlotter, GetUnit(), GetConvert(), m_pos, temp );
1862 
1863  for( SCH_FIELD field : m_fields )
1864  field.Plot( aPlotter );
1865 
1866  aPlotter->EndBlock( nullptr );
1867  }
1868 }
1869 
1870 
1872 {
1873  for( const auto& pin : m_pins )
1874  {
1875  if( pin->IsBrightened() )
1876  return true;
1877  }
1878 
1879  return false;
1880 }
1881 
1882 
1884 {
1885  for( auto& pin : m_pins )
1886  pin->ClearBrightened();
1887 }
1888 
1889 
1890 bool SCH_SYMBOL::IsPointClickableAnchor( const wxPoint& aPos ) const
1891 {
1892  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1893  {
1894  int pin_unit = pin->GetLibPin()->GetUnit();
1895  int pin_convert = pin->GetLibPin()->GetConvert();
1896 
1897  if( pin_unit > 0 && pin_unit != GetUnit() )
1898  continue;
1899 
1900  if( pin_convert > 0 && pin_convert != GetConvert() )
1901  continue;
1902 
1903  if( pin->IsPointClickableAnchor( aPos ) )
1904  return true;
1905  }
1906 
1907  return false;
1908 }
bool m_isInNetlist
True if the symbol should appear in the netlist.
Definition: sch_symbol.h:700
Field Reference of part, i.e. "IC21".
void UpdateFields(const SCH_SHEET_PATH *aPath, bool aUpdateStyle, bool aUpdateRef, bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields)
Restore fields to the original library values.
Definition: sch_symbol.cpp:757
MANDATORY_FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
void Print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset) override
Print a symbol.
Definition: sch_symbol.cpp:379
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
void Offset(int dx, int dy)
Definition: eda_rect.h:147
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
void SetModified()
Definition: eda_item.cpp:65
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:479
wxString GetRefDesUnannotated(const wxString &aSource)
Return an unannotated refdes from either a prefix or an existing refdes.
wxString m_prefix
C, R, U, Q etc - the first character(s) which typically indicate what the symbol is.
Definition: sch_symbol.h:678
bool operator!=(const SCH_SYMBOL &aSymbol) const
bool ReplaceInstanceSheetPath(const KIID_PATH &aOldSheetPath, const KIID_PATH &aNewSheetPath)
Replace aOldSheetPath with aNewSheetPath in the instance list.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
void Merge(const EDA_RECT &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: eda_rect.cpp:432
virtual void EndBlock(void *aData)
calling this function allows one to define the end of a group of drawing items for instance in SVG or...
Definition: plotter.h:496
int y2
Definition: transform.h:51
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:675
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:331
Holds all the data relating to one schematic.
Definition: schematic.h:59
Define a symbol library graphical text item.
Definition: lib_text.h:39
int GetX() const
Definition: eda_rect.h:98
int GetUnitCount() const
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:370
std::vector< std::unique_ptr< SCH_PIN > > m_pins
Definition: sch_symbol.h:697
void ImportValues(const LIB_FIELD &aSource)
Copy parameters from a LIB_FIELD source.
Definition: sch_field.cpp:247
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:167
Field object used in symbol libraries.
Definition: lib_field.h:59
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath)
Clear exiting symbol annotation.
bool IsPointClickableAnchor(const wxPoint &aPos) const override
void SetValue(const SCH_SHEET_PATH *sheet, const wxString &aValue)
Definition: sch_symbol.cpp:594
SCH_SYMBOL(const wxPoint &pos=wxPoint(0, 0), SCH_ITEM *aParent=nullptr)
Definition: sch_symbol.cpp:98
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList, const SCH_SHEET_PATH *aPath=nullptr) override
Test if the symbol's dangling state has changed for all pins.
TEMPLATES m_TemplateFieldNames
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
Definition: sch_symbol.cpp:942
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:711
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition: transform.cpp:57
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:246
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:97
Collection of utility functions for component reference designators (refdes)
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
int x2
Definition: transform.h:50
virtual void StartBlock(void *aData)
calling this function allows one to define the beginning of a group of drawing items,...
Definition: plotter.h:487
bool GetIncludeOnBoard() const
Definition: lib_symbol.h:593
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_symbol.cpp:229
wxString AsString() const
Definition: kiid.cpp:218
SCH_FIELDS m_fields
Variable length list of fields.
Definition: sch_symbol.h:693
bool Matches(const wxFindReplaceData &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
int x1
Definition: transform.h:48
Schematic editor (Eeschema) main window.
void SetLibId(const LIB_ID &aName)
Definition: sch_symbol.cpp:238
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:445
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:481
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:441
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
The base class for create windows for drawing purpose.
bool draw_visible_fields
Definition: lib_symbol.h:65
std::string toUTFTildaText(const wxString &txt)
Convert a wxString to UTF8 and replace any control characters with a ~, where a control character is ...
Definition: sch_symbol.cpp:46
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_symbol.cpp:891
Define a library symbol object.
Definition: lib_symbol.h:96
void SetFootprint(const SCH_SHEET_PATH *sheet, const wxString &aFootprint)
Definition: sch_symbol.cpp:645
wxString GetDatasheet() const
Return the documentation text for the given part alias.
Definition: sch_symbol.cpp:275
TRANSFORM & GetTransform()
Definition: sch_symbol.h:231
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:257
std::vector< wxPoint > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:332
void Init(const wxPoint &pos=wxPoint(0, 0))
Definition: sch_symbol.cpp:194
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:494
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:547
bool doIsConnected(const wxPoint &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: sch_field.cpp:105
int m_unit
The unit for multiple part per package symbols.
Definition: sch_symbol.h:674
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:94
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:116
name of datasheet
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:42
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
void UpdateUnit(int aUnit)
Change the unit number to aUnit without setting any internal flags.
Definition: sch_symbol.cpp:341
int GetBottom() const
Definition: eda_rect.h:114
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
TRANSFORM transform
Definition: lib_symbol.h:64
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:72
void Plot(PLOTTER *aPlotter) const override
Plot the schematic item to aPlotter.
void GetLibPins(std::vector< LIB_PIN * > &aPinsList) const
Populate a vector with all the pins from the library object.
Definition: sch_symbol.cpp:852
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
int y1
Definition: transform.h:49
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_symbol.cpp:223
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
Definition: sch_symbol.cpp:928
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: sch_field.cpp:562
int GetUnit() const
Definition: lib_item.h:272
bool IsInNetlist() const
int m_convert
The alternate body style for symbols that have more than one body style defined.
Definition: sch_symbol.h:675
wxString m_schLibSymbolName
The name used to look up a symbol in the symbol library embedded in a schematic.
Definition: sch_symbol.h:690
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
SCH_LAYER_ID m_layer
Definition: sch_item.h:492
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
Definition: sch_symbol.cpp:721
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Field Value of part, i.e. "3.3K".
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:114
void SetHeight(int val)
Definition: eda_rect.h:176
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:248
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:421
int GetRight() const
Definition: eda_rect.h:111
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:531
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
Definition: sch_symbol.cpp:284
EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the fields.
wxPoint m_pos
Definition: sch_symbol.h:672
A simple container for schematic symbol instance information.
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
void SetX(int val)
Definition: eda_rect.h:158
wxLogTrace helper definitions.
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:653
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslate=true)
Return a default symbol field name for field aFieldNdx for all components.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::unique_ptr< LIB_SYMBOL > m_part
Definition: sch_symbol.h:695
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:158
double GetArea() const
Return the area of the rectangle.
Definition: eda_rect.cpp:483
void SetWidth(int val)
Definition: eda_rect.h:170
const wxString GetValue(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific value for the given sheet path.
Definition: sch_symbol.cpp:573
bool m_onBoard
True to include in netlist when updating board.
Definition: sch_symbol.h:702
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:743
wxString GetClass() const override
Return the class name.
Definition: sch_symbol.h:118
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Assign the members of aItem to another object.
Definition: eda_item.cpp:180
UTF8 Format() const
Definition: lib_id.cpp:116
wxString UnescapeString(const wxString &aSource)
wxString GetFieldText(const wxString &aFieldName, SCH_EDIT_FRAME *aFrame) const
Search for a field named aFieldName and returns text associated with this field.
Definition: sch_symbol.cpp:699
void SetY(int val)
Definition: eda_rect.h:164
const EDA_RECT GetBodyBoundingBox(int aUnit, int aConvert) const
Get the symbol bounding box excluding fields.
Definition: lib_symbol.cpp:851
void SetConvert(int aConvert)
Definition: sch_symbol.cpp:347
const KIID m_Uuid
Definition: eda_item.h:475
bool IsAnnotated(const SCH_SHEET_PATH *aSheet)
Check if the symbol has a valid annotation (reference) for the given sheet path.
Definition: sch_symbol.cpp:517
wxPoint GetPosition() const override
Definition: lib_pin.h:210
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.
EDA_UNITS
Definition: eda_units.h:38
bool HasBrightenedPins()
void Normalize()
Ensures that the height ant width are positive.
Definition: eda_rect.cpp:35
void Print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset, int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS &aOpts)
Print symbol.
Definition: lib_symbol.cpp:477
LIB_ID m_lib_id
Name and library the symbol was loaded from, i.e. 74xx:74LS00.
Definition: sch_symbol.h:673
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an item.
void ClearBrightenedPins()
Base plotter engine class.
Definition: plotter.h:121
bool m_inBom
True to include in bill of materials export.
Definition: sch_symbol.h:701
std::unordered_map< LIB_PIN *, unsigned > m_pinMap
Definition: sch_symbol.h:698
Schematic symbol object.
Definition: sch_symbol.h:78
#define SKIP_STRUCT
flag indicating that the structure should be ignored
const wxChar *const traceFindItem
Flag to enable find debug tracing.
SCH_SYMBOL & operator=(const SCH_ITEM &aItem)
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
bool operator<(const SCH_ITEM &aItem) const override
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
Definition: sch_symbol.cpp:840
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:481
wxString AsString() const
Definition: kiid.cpp:277
void Rotate(const wxPoint &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Handle the component boundary box.
Definition: eda_rect.h:42
TRANSFORM m_transform
The rotation/mirror transformation matrix.
Definition: sch_symbol.h:692
int GetY() const
Definition: eda_rect.h:99
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:97
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:202
Hold a name of a symbol's field, field value, and default visibility.
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
Definition: sch_symbol.cpp:830
bool operator==(const SCH_SYMBOL &aSymbol) const
int GetOrientation()
Get the display symbol orientation.
SCH_SHEET_PATH & GetCurrentSheet() const
T Convert(const wxString &aValue)
Convert a wxString to a generic type T.
Definition: eagle_parser.h:173
wxString GetDescription() const
Return information about the aliased parts.
Definition: sch_symbol.cpp:266
const wxString GetFootprint(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific footprint assignment for the given sheet path.
Definition: sch_symbol.cpp:624
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit, const wxString &aValue=wxEmptyString, const wxString &aFootprint=wxEmptyString)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:400
double square(double x)
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:171
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:83
std::vector< SYMBOL_INSTANCE_REFERENCE > m_instanceReferences
Definition: sch_symbol.h:706
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
EDA_MSG_PANEL items for displaying messages.
Definition: msgpanel.h:53
int GetUnit() const
Definition: sch_symbol.h:195
std::vector< SCH_FIELD > & GetFields()
Return a vector of fields from the symbol.
Definition: sch_symbol.h:366
LIB_ITEM * GetDrawItem(const wxPoint &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:121
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
not connected (must be left open)
SEARCH_RESULT
Definition: eda_item.h:41
Message panel definition file.
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:475
SCH_FIELD * GetFieldById(int aFieldId)
Return a field in this symbol.
Definition: sch_symbol.cpp:687
int GetConvert() const
Definition: sch_symbol.h:223
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
Definition: sch_symbol.cpp:730
std::vector< std::pair< int, wxString > > Fields
Definition: sch_screen.h:86
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:193
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
const TEMPLATE_FIELDNAMES & GetTemplateFieldNames()
Return a template field name list for read only access.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
Definition: sch_symbol.cpp:866
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
bool GetIncludeInBom() const
Definition: lib_symbol.h:585
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:147
bool empty() const
Definition: utf8.h:103
void SetTransform(const TRANSFORM &aTransform)
Definition: sch_symbol.cpp:360
Field Name Module PCB, i.e. "16DIP300".