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_pin.h>
30 #include <lib_text.h>
31 #include <lib_shape.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_SHAPE* square = new LIB_SHAPE( symbol, SHAPE_T::RECT );
81 
82  square->MoveTo( wxPoint( Mils2iu( -200 ), Mils2iu( 200 ) ) );
83  square->SetEnd( 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 = 4;
232  aLayers[0] = LAYER_DANGLING; // Pins are drawn by their parent symbol, so the parent
233  // symbol needs to draw to LAYER_DANGLING
234  aLayers[1] = LAYER_DEVICE;
235  aLayers[2] = LAYER_DEVICE_BACKGROUND;
236  aLayers[3] = LAYER_SELECTION_SHADOWS;
237 }
238 
239 
240 void SCH_SYMBOL::SetLibId( const LIB_ID& aLibId )
241 {
242  if( m_lib_id != aLibId )
243  {
244  m_lib_id = aLibId;
245  SetModified();
246  }
247 }
248 
249 
251 {
252  if( !m_schLibSymbolName.IsEmpty() )
253  return m_schLibSymbolName;
254  else
255  return m_lib_id.Format();
256 }
257 
258 
260 {
261  wxCHECK2( ( aLibSymbol == nullptr ) || ( aLibSymbol->IsRoot() ), aLibSymbol = nullptr );
262 
263  m_part.reset( aLibSymbol );
264  UpdatePins();
265 }
266 
267 
269 {
270  if( m_part )
271  return m_part->GetDescription();
272 
273  return wxEmptyString;
274 }
275 
276 
277 wxString SCH_SYMBOL::GetDatasheet() const
278 {
279  if( m_part )
280  return m_part->GetDatasheetField().GetText();
281 
282  return wxEmptyString;
283 }
284 
285 
287 {
288  std::map<wxString, wxString> altPinMap;
289  std::map<wxString, KIID> pinUuidMap;
290 
291  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
292  {
293  pinUuidMap[ pin->GetNumber() ] = pin->m_Uuid;
294 
295  if( !pin->GetAlt().IsEmpty() )
296  altPinMap[ pin->GetNumber() ] = pin->GetAlt();
297  }
298 
299  m_pins.clear();
300  m_pinMap.clear();
301 
302  if( !m_part )
303  return;
304 
305  unsigned i = 0;
306 
307  for( LIB_PIN* libPin = m_part->GetNextPin(); libPin; libPin = m_part->GetNextPin( libPin ) )
308  {
309  wxASSERT( libPin->Type() == LIB_PIN_T );
310 
311  if( libPin->GetConvert() && m_convert && ( m_convert != libPin->GetConvert() ) )
312  continue;
313 
314  m_pins.push_back( std::make_unique<SCH_PIN>( libPin, this ) );
315 
316  auto ii = pinUuidMap.find( libPin->GetNumber() );
317 
318  if( ii != pinUuidMap.end() )
319  const_cast<KIID&>( m_pins.back()->m_Uuid ) = ii->second;
320 
321  auto iii = altPinMap.find( libPin->GetNumber() );
322 
323  if( iii != altPinMap.end() )
324  m_pins.back()->SetAlt( iii->second );
325 
326  m_pinMap[ libPin ] = i;
327 
328  ++i;
329  }
330 }
331 
332 
333 void SCH_SYMBOL::SetUnit( int aUnit )
334 {
335  if( m_unit != aUnit )
336  {
337  m_unit = aUnit;
338  SetModified();
339  }
340 }
341 
342 
343 void SCH_SYMBOL::UpdateUnit( int aUnit )
344 {
345  m_unit = aUnit;
346 }
347 
348 
349 void SCH_SYMBOL::SetConvert( int aConvert )
350 {
351  if( m_convert != aConvert )
352  {
353  m_convert = aConvert;
354 
355  // The convert may have a different pin layout so the update the pin map.
356  UpdatePins();
357  SetModified();
358  }
359 }
360 
361 
362 void SCH_SYMBOL::SetTransform( const TRANSFORM& aTransform )
363 {
364  if( m_transform != aTransform )
365  {
366  m_transform = aTransform;
367  SetModified();
368  }
369 }
370 
371 
373 {
374  if( m_part )
375  return m_part->GetUnitCount();
376 
377  return 0;
378 }
379 
380 
381 void SCH_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
382 {
383  LIB_SYMBOL_OPTIONS opts;
384  opts.transform = m_transform;
385  opts.draw_visible_fields = false;
386  opts.draw_hidden_fields = false;
387 
388  if( m_part )
389  {
390  m_part->Print( aSettings, m_pos + aOffset, m_unit, m_convert, opts );
391  }
392  else // Use dummy() part if the actual cannot be found.
393  {
394  dummy()->Print( aSettings, m_pos + aOffset, 0, 0, opts );
395  }
396 
397  for( SCH_FIELD& field : m_fields )
398  field.Print( aSettings, aOffset );
399 }
400 
401 
402 void SCH_SYMBOL::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef,
403  int aUnit, const wxString& aValue,
404  const wxString& aFootprint )
405 {
406  // Search for an existing path and remove it if found (should not occur)
407  for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
408  {
409  if( m_instanceReferences[ii].m_Path == aPath )
410  {
411  wxLogTrace( traceSchSheetPaths, "Removing symbol instance:\n"
412  " sheet path %s\n"
413  " reference %s, unit %d from symbol %s.",
414  aPath.AsString(),
415  m_instanceReferences[ii].m_Reference,
416  m_instanceReferences[ii].m_Unit,
417  m_Uuid.AsString() );
418 
419  m_instanceReferences.erase( m_instanceReferences.begin() + ii );
420  ii--;
421  }
422  }
423 
424  SYMBOL_INSTANCE_REFERENCE instance;
425  instance.m_Path = aPath;
426  instance.m_Reference = aRef;
427  instance.m_Unit = aUnit;
428  instance.m_Value = aValue;
429  instance.m_Footprint = aFootprint;
430 
431  wxLogTrace( traceSchSheetPaths, "Adding symbol instance:\n"
432  " sheet path %s\n"
433  " reference %s, unit %d to symbol %s.",
434  aPath.AsString(),
435  aRef,
436  aUnit,
437  m_Uuid.AsString() );
438 
439  m_instanceReferences.push_back( instance );
440 }
441 
442 
443 const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit ) const
444 {
445  KIID_PATH path = sheet->Path();
446  wxString ref;
447 
448  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
449  {
450  if( instance.m_Path == path )
451  {
452  ref = instance.m_Reference;
453  break;
454  }
455  }
456 
457  // If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
458  // use this as a default for this path. This will happen if we load a version 1 schematic
459  // file. It will also mean that multiple instances of the same sheet by default all have
460  // the same symbol references, but perhaps this is best.
461  if( ref.IsEmpty() && !GetField( REFERENCE_FIELD )->GetText().IsEmpty() )
462  {
463  const_cast<SCH_SYMBOL*>( this )->SetRef( sheet, GetField( REFERENCE_FIELD )->GetText() );
464  ref = GetField( REFERENCE_FIELD )->GetText();
465  }
466 
467  if( ref.IsEmpty() )
469 
470  if( aIncludeUnit && GetUnitCount() > 1 )
471  ref += LIB_SYMBOL::SubReference( GetUnit() );
472 
473  return ref;
474 }
475 
476 
477 bool SCH_SYMBOL::IsReferenceStringValid( const wxString& aReferenceString )
478 {
479  return !UTIL::GetRefDesPrefix( aReferenceString ).IsEmpty();
480 }
481 
482 
483 void SCH_SYMBOL::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
484 {
485  KIID_PATH path = sheet->Path();
486  bool notInArray = true;
487 
488  // check to see if it is already there before inserting it
490  {
491  if( instance.m_Path == path )
492  {
493  instance.m_Reference = ref;
494  notInArray = false;
495  }
496  }
497 
498  if( notInArray )
500 
501  for( std::unique_ptr<SCH_PIN>& pin : m_pins )
502  pin->ClearDefaultNetName( sheet );
503 
505 
506  rf->SetText( ref ); // for drawing.
507 
508  // Reinit the m_prefix member if needed
510 
511  if( m_prefix.IsEmpty() )
512  m_prefix = wxT( "U" );
513 
514  // Power symbols have references starting with # and are not included in netlists
515  m_isInNetlist = ! ref.StartsWith( wxT( "#" ) );
516 }
517 
518 
520 {
521  KIID_PATH path = aSheet->Path();
522 
523  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
524  {
525  if( instance.m_Path == path )
526  return instance.m_Reference.Last() != '?';
527  }
528 
529  return false;
530 }
531 
532 
534 {
535  KIID_PATH path = aSheet->Path();
536 
537  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
538  {
539  if( instance.m_Path == path )
540  return instance.m_Unit;
541  }
542 
543  // If it was not found in m_Paths array, then use m_unit. This will happen if we load a
544  // version 1 schematic file.
545  return m_unit;
546 }
547 
548 
549 void SCH_SYMBOL::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
550 {
551  KIID_PATH path = aSheet->Path();
552 
553  // check to see if it is already there before inserting it
555  {
556  if( instance.m_Path == path )
557  {
558  instance.m_Unit = aUnitSelection;
559  return;
560  }
561  }
562 
563  // didn't find it; better add it
565 }
566 
567 
568 void SCH_SYMBOL::SetUnitSelection( int aUnitSelection )
569 {
571  instance.m_Unit = aUnitSelection;
572 }
573 
574 
575 const wxString SCH_SYMBOL::GetValue( const SCH_SHEET_PATH* sheet, bool aResolve ) const
576 {
577  KIID_PATH path = sheet->Path();
578 
579  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
580  {
581  if( instance.m_Path == path && !instance.m_Value.IsEmpty() )
582  {
583  // This can only be an override from an Update Schematic from PCB, and therefore
584  // will always be fully resolved.
585  return instance.m_Value;
586  }
587  }
588 
589  if( !aResolve )
590  return GetField( VALUE_FIELD )->GetText();
591 
592  return GetField( VALUE_FIELD )->GetShownText();
593 }
594 
595 
596 void SCH_SYMBOL::SetValue( const SCH_SHEET_PATH* sheet, const wxString& aValue )
597 {
598  if( sheet == nullptr )
599  {
600  // Clear instance overrides and set primary field value
602  instance.m_Value = wxEmptyString;
603 
604  m_fields[ VALUE_FIELD ].SetText( aValue );
605  return;
606  }
607 
608  KIID_PATH path = sheet->Path();
609 
610  // check to see if it is already there before inserting it
612  {
613  if( instance.m_Path == path )
614  {
615  instance.m_Value = aValue;
616  return;
617  }
618  }
619 
620  // didn't find it; better add it
622  aValue, wxEmptyString );
623 }
624 
625 
626 const wxString SCH_SYMBOL::GetFootprint( const SCH_SHEET_PATH* sheet, bool aResolve ) const
627 {
628  KIID_PATH path = sheet->Path();
629 
630  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
631  {
632  if( instance.m_Path == path && !instance.m_Footprint.IsEmpty() )
633  {
634  // This can only be an override from an Update Schematic from PCB, and therefore
635  // will always be fully resolved.
636  return instance.m_Footprint;
637  }
638  }
639 
640  if( !aResolve )
641  return GetField( FOOTPRINT_FIELD )->GetText();
642 
644 }
645 
646 
647 void SCH_SYMBOL::SetFootprint( const SCH_SHEET_PATH* sheet, const wxString& aFootprint )
648 {
649  if( sheet == nullptr )
650  {
651  // Clear instance overrides and set primary field value
653  instance.m_Footprint = wxEmptyString;
654 
655  m_fields[ FOOTPRINT_FIELD ].SetText( aFootprint );
656  return;
657  }
658 
659  KIID_PATH path = sheet->Path();
660 
661  // check to see if it is already there before inserting it
663  {
664  if( instance.m_Path == path )
665  {
666  instance.m_Footprint = aFootprint;
667  return;
668  }
669  }
670 
671  // didn't find it; better add it
673  wxEmptyString, aFootprint );
674 }
675 
676 
678 {
679  return &m_fields[aFieldType];
680 }
681 
682 
684 {
685  return &m_fields[aFieldType];
686 }
687 
688 
690 {
691  for( size_t ii = 0; ii < m_fields.size(); ++ii )
692  {
693  if( m_fields[ii].GetId() == aFieldId )
694  return &m_fields[ii];
695  }
696 
697  return nullptr;
698 }
699 
700 
701 wxString SCH_SYMBOL::GetFieldText( const wxString& aFieldName, SCH_EDIT_FRAME* aFrame ) const
702 {
703  for( const SCH_FIELD& field : m_fields )
704  {
705  if( aFieldName == field.GetName() || aFieldName == field.GetCanonicalName() )
706  return field.GetText();
707  }
708 
709  return wxEmptyString;
710 }
711 
712 
713 void SCH_SYMBOL::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
714 {
715  for( SCH_FIELD& field : m_fields )
716  {
717  if( !aVisibleOnly || ( field.IsVisible() && !field.IsVoid() ) )
718  aVector.push_back( &field );
719  }
720 }
721 
722 
724 {
725  int newNdx = m_fields.size();
726 
727  m_fields.push_back( aField );
728  return &m_fields[newNdx];
729 }
730 
731 
732 void SCH_SYMBOL::RemoveField( const wxString& aFieldName )
733 {
734  for( unsigned i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
735  {
736  if( aFieldName == m_fields[i].GetName( false ) )
737  {
738  m_fields.erase( m_fields.begin() + i );
739  return;
740  }
741  }
742 }
743 
744 
745 SCH_FIELD* SCH_SYMBOL::FindField( const wxString& aFieldName, bool aIncludeDefaultFields )
746 {
747  unsigned start = aIncludeDefaultFields ? 0 : MANDATORY_FIELDS;
748 
749  for( unsigned i = start; i < m_fields.size(); ++i )
750  {
751  if( aFieldName == m_fields[i].GetName( false ) )
752  return &m_fields[i];
753  }
754 
755  return nullptr;
756 }
757 
758 
759 void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef,
760  bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields )
761 {
762  if( m_part )
763  {
764  wxString symbolName;
765  std::vector<LIB_FIELD*> fields;
766 
767  m_part->GetFields( fields );
768 
769  for( const LIB_FIELD* libField : fields )
770  {
771  int id = libField->GetId();
772  SCH_FIELD* schField;
773 
774  if( id >= 0 && id < MANDATORY_FIELDS )
775  {
776  schField = GetFieldById( id );
777  }
778  else
779  {
780  schField = FindField( libField->GetCanonicalName() );
781 
782  if( !schField )
783  {
784  wxString fieldName = libField->GetCanonicalName();
785  SCH_FIELD newField( wxPoint( 0, 0), GetFieldCount(), this, fieldName );
786  schField = AddField( newField );
787  }
788  }
789 
790  if( aUpdateStyle )
791  {
792  schField->ImportValues( *libField );
793  schField->SetTextPos( m_pos + libField->GetTextPos() );
794  }
795 
796  if( id == REFERENCE_FIELD && aPath )
797  {
798  if( aResetRef )
799  SetRef( aPath, m_part->GetReferenceField().GetText() );
800  else if( aUpdateRef )
801  SetRef( aPath, libField->GetText() );
802  }
803  else if( id == VALUE_FIELD )
804  {
805  if( aResetOtherFields )
806  SetValue( aPath, UnescapeString( m_lib_id.GetLibItemName() ) ); // alias-specific value
807  else
808  SetValue( aPath, UnescapeString( libField->GetText() ) );
809  }
810  else if( id == FOOTPRINT_FIELD )
811  {
812  if( aResetOtherFields || aUpdateOtherFields )
813  SetFootprint( aPath, libField->GetText() );
814  }
815  else if( id == DATASHEET_FIELD )
816  {
817  if( aResetOtherFields )
818  schField->SetText( GetDatasheet() ); // alias-specific value
819  else if( aUpdateOtherFields )
820  schField->SetText( libField->GetText() );
821  }
822  else
823  {
824  if( aResetOtherFields || aUpdateOtherFields )
825  schField->SetText( libField->GetText() );
826  }
827  }
828  }
829 }
830 
831 
832 void SCH_SYMBOL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
833 {
834  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
835  aFunction( pin.get() );
836 
837  for( SCH_FIELD& field : m_fields )
838  aFunction( &field );
839 }
840 
841 
842 SCH_PIN* SCH_SYMBOL::GetPin( const wxString& aNumber ) const
843 {
844  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
845  {
846  if( pin->GetNumber() == aNumber )
847  return pin.get();
848  }
849 
850  return nullptr;
851 }
852 
853 
854 void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
855 {
856  if( m_part )
857  m_part->GetPins( aPinsList, m_unit, m_convert );
858 }
859 
860 
862 {
863  wxASSERT( m_pinMap.count( aLibPin ) );
864  return m_pins[ m_pinMap.at( aLibPin ) ].get();
865 }
866 
867 
868 std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
869 {
870  std::vector<SCH_PIN*> pins;
871 
872  if( aSheet == nullptr )
873  {
874  wxCHECK_MSG( Schematic(), pins, "Can't call GetPins on a symbol with no schematic" );
875 
876  aSheet = &Schematic()->CurrentSheet();
877  }
878 
879  int unit = GetUnitSelection( aSheet );
880 
881  for( const auto& p : m_pins )
882  {
883  if( unit && p->GetLibPin()->GetUnit() && ( p->GetLibPin()->GetUnit() != unit ) )
884  continue;
885 
886  pins.push_back( p.get() );
887  }
888 
889  return pins;
890 }
891 
892 
894 {
895  wxCHECK_RET( (aItem != nullptr) && (aItem->Type() == SCH_SYMBOL_T),
896  wxT( "Cannot swap data with invalid symbol." ) );
897 
898  SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
899 
900  std::swap( m_lib_id, symbol->m_lib_id );
901 
902  LIB_SYMBOL* libSymbol = symbol->m_part.release();
903  symbol->m_part.reset( m_part.release() );
904  symbol->UpdatePins();
905  m_part.reset( libSymbol );
906  UpdatePins();
907 
908  std::swap( m_pos, symbol->m_pos );
909  std::swap( m_unit, symbol->m_unit );
910  std::swap( m_convert, symbol->m_convert );
911 
912  m_fields.swap( symbol->m_fields ); // std::vector's swap()
913 
914  for( SCH_FIELD& field : symbol->m_fields )
915  field.SetParent( symbol );
916 
917  for( SCH_FIELD& field : m_fields )
918  field.SetParent( this );
919 
920  TRANSFORM tmp = m_transform;
921 
922  m_transform = symbol->m_transform;
923  symbol->m_transform = tmp;
924 
925  std::swap( m_instanceReferences, symbol->m_instanceReferences );
926  std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName );
927 }
928 
929 
930 void SCH_SYMBOL::GetContextualTextVars( wxArrayString* aVars ) const
931 {
932  for( int i = 0; i < MANDATORY_FIELDS; ++i )
933  aVars->push_back( m_fields[i].GetCanonicalName().Upper() );
934 
935  for( size_t i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
936  aVars->push_back( m_fields[i].GetName() );
937 
938  aVars->push_back( wxT( "FOOTPRINT_LIBRARY" ) );
939  aVars->push_back( wxT( "FOOTPRINT_NAME" ) );
940  aVars->push_back( wxT( "UNIT" ) );
941 }
942 
943 
944 bool SCH_SYMBOL::ResolveTextVar( wxString* token, int aDepth ) const
945 {
946  SCHEMATIC* schematic = Schematic();
947 
948  // SCH_SYMOL object has no context outside a schematic.
949  wxCHECK( schematic, false );
950 
951  for( int i = 0; i < MANDATORY_FIELDS; ++i )
952  {
953  if( token->IsSameAs( m_fields[ i ].GetCanonicalName().Upper() ) )
954  {
955  if( i == REFERENCE_FIELD )
956  *token = GetRef( &schematic->CurrentSheet(), true );
957  else if( i == VALUE_FIELD )
958  *token = GetValue( &schematic->CurrentSheet(), true );
959  else if( i == FOOTPRINT_FIELD )
960  *token = GetFootprint( &schematic->CurrentSheet(), true );
961  else
962  *token = m_fields[ i ].GetShownText( aDepth + 1 );
963 
964  return true;
965  }
966  }
967 
968  for( size_t i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
969  {
970  if( token->IsSameAs( m_fields[ i ].GetName() )
971  || token->IsSameAs( m_fields[ i ].GetName().Upper() ) )
972  {
973  *token = m_fields[ i ].GetShownText( aDepth + 1 );
974  return true;
975  }
976  }
977 
978  for( const TEMPLATE_FIELDNAME& templateFieldname :
980  {
981  if( token->IsSameAs( templateFieldname.m_Name )
982  || token->IsSameAs( templateFieldname.m_Name.Upper() ) )
983  {
984  // If we didn't find it in the fields list then it isn't set on this symbol.
985  // Just return an empty string.
986  *token = wxEmptyString;
987  return true;
988  }
989  }
990 
991  if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
992  {
993  wxString footprint;
994 
995  footprint = GetFootprint( &schematic->CurrentSheet(), true );
996 
997  wxArrayString parts = wxSplit( footprint, ':' );
998 
999  *token = parts[ 0 ];
1000  return true;
1001  }
1002  else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
1003  {
1004  wxString footprint;
1005 
1006  footprint = GetFootprint( &schematic->CurrentSheet(), true );
1007 
1008  wxArrayString parts = wxSplit( footprint, ':' );
1009 
1010  *token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
1011  return true;
1012  }
1013  else if( token->IsSameAs( wxT( "UNIT" ) ) )
1014  {
1015  int unit;
1016 
1017  unit = GetUnitSelection( &schematic->CurrentSheet() );
1018 
1019  *token = LIB_SYMBOL::SubReference( unit );
1020  return true;
1021  }
1022 
1023  return false;
1024 }
1025 
1026 
1028 {
1029  // Build a reference with no annotation, i.e. a reference ending with a single '?'
1030  wxString defRef = UTIL::GetRefDesUnannotated( m_prefix );
1031 
1032  if( aSheetPath )
1033  {
1034  KIID_PATH path = aSheetPath->Path();
1035 
1037  {
1038  if( instance.m_Path == path )
1039  instance.m_Reference = defRef;
1040  }
1041  }
1042  else
1043  {
1045  instance.m_Reference = defRef;
1046  }
1047 
1048  for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1049  pin->ClearDefaultNetName( aSheetPath );
1050 
1051  // These 2 changes do not work in complex hierarchy.
1052  // When a clear annotation is made, the calling function must call a
1053  // UpdateAllScreenReferences for the active sheet.
1054  // But this call cannot made here.
1055  m_fields[REFERENCE_FIELD].SetText( defRef ); //for drawing.
1056 }
1057 
1058 
1060 {
1061  // a empty sheet path is illegal:
1062  wxCHECK( aSheetPath.size() > 0, false );
1063 
1064  wxString reference_path;
1065 
1066  for( const SYMBOL_INSTANCE_REFERENCE& instance : m_instanceReferences )
1067  {
1068  // if aSheetPath is found, nothing to do:
1069  if( instance.m_Path == aSheetPath )
1070  return false;
1071  }
1072 
1073  // This entry does not exist: add it, with its last-used reference
1074  AddHierarchicalReference( aSheetPath, m_fields[REFERENCE_FIELD].GetText(), m_unit );
1075  return true;
1076 }
1077 
1078 
1080  const KIID_PATH& aNewSheetPath )
1081 {
1082  auto it = std::find_if( m_instanceReferences.begin(), m_instanceReferences.end(),
1083  [ aOldSheetPath ]( SYMBOL_INSTANCE_REFERENCE& r )->bool
1084  {
1085  return aOldSheetPath == r.m_Path;
1086  }
1087  );
1088 
1089  if( it != m_instanceReferences.end() )
1090  {
1091  wxLogTrace( traceSchSheetPaths,
1092  "Replacing sheet path %s\n with sheet path %s\n for symbol %s.",
1093  aOldSheetPath.AsString(), aNewSheetPath.AsString(), m_Uuid.AsString() );
1094 
1095  it->m_Path = aNewSheetPath;
1096  return true;
1097  }
1098 
1099  wxLogTrace( traceSchSheetPaths,
1100  "Could not find sheet path %s\n to replace with sheet path %s\n for symbol %s.",
1101  aOldSheetPath.AsString(), aNewSheetPath.AsString(), m_Uuid.AsString() );
1102 
1103  return false;
1104 }
1105 
1106 
1107 void SCH_SYMBOL::SetOrientation( int aOrientation )
1108 {
1109  TRANSFORM temp = TRANSFORM();
1110  bool transform = false;
1111 
1112  switch( aOrientation )
1113  {
1114  case SYM_ORIENT_0:
1115  case SYM_NORMAL: // default transform matrix
1116  m_transform.x1 = 1;
1117  m_transform.y2 = -1;
1118  m_transform.x2 = m_transform.y1 = 0;
1119  break;
1120 
1121  case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1122  temp.x1 = temp.y2 = 0;
1123  temp.y1 = 1;
1124  temp.x2 = -1;
1125  transform = true;
1126  break;
1127 
1128  case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1129  temp.x1 = temp.y2 = 0;
1130  temp.y1 = -1;
1131  temp.x2 = 1;
1132  transform = true;
1133  break;
1134 
1135  case SYM_MIRROR_Y: // Mirror Y (incremental rotation)
1136  temp.x1 = -1;
1137  temp.y2 = 1;
1138  temp.y1 = temp.x2 = 0;
1139  transform = true;
1140  break;
1141 
1142  case SYM_MIRROR_X: // Mirror X (incremental rotation)
1143  temp.x1 = 1;
1144  temp.y2 = -1;
1145  temp.y1 = temp.x2 = 0;
1146  transform = true;
1147  break;
1148 
1149  case SYM_ORIENT_90:
1152  break;
1153 
1154  case SYM_ORIENT_180:
1158  break;
1159 
1160  case SYM_ORIENT_270:
1163  break;
1164 
1165  case ( SYM_ORIENT_0 + SYM_MIRROR_X ):
1168  break;
1169 
1170  case ( SYM_ORIENT_0 + SYM_MIRROR_Y ):
1173  break;
1174 
1175  case ( SYM_ORIENT_90 + SYM_MIRROR_X ):
1178  break;
1179 
1180  case ( SYM_ORIENT_90 + SYM_MIRROR_Y ):
1183  break;
1184 
1185  case ( SYM_ORIENT_180 + SYM_MIRROR_X ):
1188  break;
1189 
1190  case ( SYM_ORIENT_180 + SYM_MIRROR_Y ):
1193  break;
1194 
1195  case ( SYM_ORIENT_270 + SYM_MIRROR_X ):
1198  break;
1199 
1200  case ( SYM_ORIENT_270 + SYM_MIRROR_Y ):
1203  break;
1204 
1205  default:
1206  transform = false;
1207  wxFAIL_MSG( "Invalid schematic symbol orientation type." );
1208  break;
1209  }
1210 
1211  if( transform )
1212  {
1213  /* The new matrix transform is the old matrix transform modified by the
1214  * requested transformation, which is the temp transform (rot,
1215  * mirror ..) in order to have (in term of matrix transform):
1216  * transform coord = new_m_transform * coord
1217  * where transform coord is the coord modified by new_m_transform from
1218  * the initial value coord.
1219  * new_m_transform is computed (from old_m_transform and temp) to
1220  * have:
1221  * transform coord = old_m_transform * temp
1222  */
1223  TRANSFORM newTransform;
1224 
1225  newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1226  newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1227  newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1228  newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1229  m_transform = newTransform;
1230  }
1231 }
1232 
1233 
1235 {
1236  int rotate_values[] =
1237  {
1238  SYM_ORIENT_0,
1239  SYM_ORIENT_90,
1245  SYM_MIRROR_Y,
1250  };
1251 
1252  // Try to find the current transform option:
1253  TRANSFORM transform = m_transform;
1254 
1255  for( int type_rotate : rotate_values )
1256  {
1257  SetOrientation( type_rotate );
1258 
1259  if( transform == m_transform )
1260  return type_rotate;
1261  }
1262 
1263  // Error: orientation not found in list (should not happen)
1264  wxFAIL_MSG( "Schematic symbol orientation matrix internal error." );
1265  m_transform = transform;
1266 
1267  return SYM_NORMAL;
1268 }
1269 
1270 
1271 #if defined(DEBUG)
1272 
1273 void SCH_SYMBOL::Show( int nestLevel, std::ostream& os ) const
1274 {
1275  // for now, make it look like XML:
1276  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1277  << " ref=\"" << TO_UTF8( GetField( REFERENCE_FIELD )->GetName() )
1278  << '"' << " chipName=\""
1279  << GetLibId().Format() << '"' << m_pos
1280  << " layer=\"" << m_layer
1281  << '"' << ">\n";
1282 
1283  // skip the reference, it's been output already.
1284  for( int i = 1; i < GetFieldCount(); ++i )
1285  {
1286  const wxString& value = GetFields()[i].GetText();
1287 
1288  if( !value.IsEmpty() )
1289  {
1290  NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1291  << TO_UTF8( GetFields()[i].GetName() )
1292  << '"' << " value=\""
1293  << TO_UTF8( value ) << "\"/>\n";
1294  }
1295  }
1296 
1297  NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1298 }
1299 
1300 #endif
1301 
1302 
1303 EDA_RECT SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) const
1304 {
1305  EDA_RECT bBox;
1306 
1307  if( m_part )
1308  bBox = m_part->GetBodyBoundingBox( m_unit, m_convert, aIncludePins );
1309  else
1310  bBox = dummy()->GetBodyBoundingBox( m_unit, m_convert, aIncludePins );
1311 
1312  int x0 = bBox.GetX();
1313  int xm = bBox.GetRight();
1314 
1315  // We must reverse Y values, because matrix orientation
1316  // suppose Y axis normal for the library items coordinates,
1317  // m_transform reverse Y values, but bBox is already reversed!
1318  int y0 = -bBox.GetY();
1319  int ym = -bBox.GetBottom();
1320 
1321  // Compute the real Boundary box (rotated, mirrored ...)
1322  int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
1323  int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
1324  int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
1325  int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
1326 
1327  bBox.SetX( x1 );
1328  bBox.SetY( y1 );
1329  bBox.SetWidth( x2 - x1 );
1330  bBox.SetHeight( y2 - y1 );
1331  bBox.Normalize();
1332 
1333  bBox.Offset( m_pos );
1334 
1335  if( aIncludeFields )
1336  {
1337  for( const SCH_FIELD& field : m_fields )
1338  {
1339  if( field.IsVisible() )
1340  bBox.Merge( field.GetBoundingBox() );
1341  }
1342  }
1343 
1344  return bBox;
1345 }
1346 
1347 
1349 {
1350  return doGetBoundingBox( false, false );
1351 }
1352 
1353 
1355 {
1356  return doGetBoundingBox( true, false );
1357 }
1358 
1359 
1361 {
1362  return doGetBoundingBox( true, true );
1363 }
1364 
1365 
1366 void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1367 {
1368  wxString msg;
1369 
1370  SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1371  SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1372 
1373  // part and alias can differ if alias is not the root
1374  if( m_part )
1375  {
1376  if( m_part.get() != dummy() )
1377  {
1378  aList.emplace_back( _( "Reference" ), GetRef( currentSheet ) );
1379 
1380  msg = m_part->IsPower() ? _( "Power symbol" ) : _( "Value" );
1381  aList.emplace_back( msg, GetValue( currentSheet, true ) );
1382 
1383 #if 0 // Display symbol flags, for debug only
1384  aList.emplace_back( _( "flags" ), wxString::Format( "%X", GetEditFlags() ) );
1385 #endif
1386 
1387  // Display symbol reference in library and library
1388  aList.emplace_back( _( "Name" ), UnescapeString( GetLibId().GetLibItemName() ) );
1389 
1390  if( !m_part->IsRoot() )
1391  {
1392  msg = _( "Missing parent" );
1393 
1394  std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock();
1395 
1396  if( parent )
1397  msg = parent->GetName();
1398 
1399  aList.emplace_back( _( "Alias of" ), UnescapeString( msg ) );
1400  }
1401  else if( !m_lib_id.GetLibNickname().empty() )
1402  {
1403  aList.emplace_back( _( "Library" ), m_lib_id.GetLibNickname() );
1404  }
1405  else
1406  {
1407  aList.emplace_back( _( "Library" ), _( "Undefined!!!" ) );
1408  }
1409 
1410  // Display the current associated footprint, if exists.
1411  msg = GetFootprint( currentSheet, true );
1412 
1413  if( msg.IsEmpty() )
1414  msg = _( "<Unknown>" );
1415 
1416  aList.emplace_back( _( "Footprint" ), msg );
1417 
1418  // Display description of the symbol, and keywords found in lib
1419  aList.emplace_back( _( "Description" ), m_part->GetDescription() );
1420  aList.emplace_back( _( "Keywords" ), m_part->GetKeyWords() );
1421  }
1422  }
1423  else
1424  {
1425  aList.emplace_back( _( "Reference" ), GetRef( currentSheet ) );
1426 
1427  aList.emplace_back( _( "Value" ), GetValue( currentSheet, true ) );
1428  aList.emplace_back( _( "Name" ), GetLibId().GetLibItemName() );
1429 
1430  wxString libNickname = GetLibId().GetLibNickname();
1431 
1432  if( libNickname.empty() )
1433  msg = _( "No library defined!" );
1434  else
1435  msg.Printf( _( "Symbol not found in %s!" ), libNickname );
1436 
1437  aList.emplace_back( _( "Library" ), msg );
1438  }
1439 }
1440 
1441 
1443 {
1444  return BITMAPS::add_component;
1445 }
1446 
1447 
1449 {
1450  int dx = m_pos.x;
1451 
1453  MIRROR( m_pos.x, aCenter );
1454  dx -= m_pos.x; // dx,0 is the move vector for this transform
1455 
1456  for( SCH_FIELD& field : m_fields )
1457  {
1458  // Move the fields to the new position because the symbol itself has moved.
1459  wxPoint pos = field.GetTextPos();
1460  pos.x -= dx;
1461  field.SetTextPos( pos );
1462  }
1463 }
1464 
1465 
1466 void SCH_SYMBOL::MirrorVertically( int aCenter )
1467 {
1468  int dy = m_pos.y;
1469 
1471  MIRROR( m_pos.y, aCenter );
1472  dy -= m_pos.y; // 0,dy is the move vector for this transform
1473 
1474  for( SCH_FIELD& field : m_fields )
1475  {
1476  // Move the fields to the new position because the symbol itself has moved.
1477  wxPoint pos = field.GetTextPos();
1478  pos.y -= dy;
1479  field.SetTextPos( pos );
1480  }
1481 }
1482 
1483 
1484 void SCH_SYMBOL::Rotate( const wxPoint& aCenter )
1485 {
1486  wxPoint prev = m_pos;
1487 
1488  RotatePoint( &m_pos, aCenter, 900 );
1489 
1491 
1492  for( SCH_FIELD& field : m_fields )
1493  {
1494  // Move the fields to the new position because the symbol itself has moved.
1495  wxPoint pos = field.GetTextPos();
1496  pos.x -= prev.x - m_pos.x;
1497  pos.y -= prev.y - m_pos.y;
1498  field.SetTextPos( pos );
1499  }
1500 }
1501 
1502 
1503 bool SCH_SYMBOL::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
1504 {
1505  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
1506 
1507  // Symbols are searchable via the child field and pin item text.
1508  return false;
1509 }
1510 
1511 
1512 void SCH_SYMBOL::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
1513 {
1514  for( auto& pin : m_pins )
1515  {
1516  LIB_PIN* lib_pin = pin->GetLibPin();
1517 
1518  if( lib_pin->GetUnit() && m_unit && ( m_unit != lib_pin->GetUnit() ) )
1519  continue;
1520 
1521  DANGLING_END_ITEM item( PIN_END, lib_pin, GetPinPhysicalPosition( lib_pin ), this );
1522  aItemList.push_back( item );
1523  }
1524 }
1525 
1526 
1527 bool SCH_SYMBOL::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
1528  const SCH_SHEET_PATH* aPath )
1529 {
1530  bool changed = false;
1531 
1532  for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1533  {
1534  bool previousState = pin->IsDangling();
1535  pin->SetIsDangling( true );
1536 
1537  wxPoint pos = m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos;
1538 
1539  for( DANGLING_END_ITEM& each_item : aItemList )
1540  {
1541  // Some people like to stack pins on top of each other in a symbol to indicate
1542  // internal connection. While technically connected, it is not particularly useful
1543  // to display them that way, so skip any pins that are in the same symbol as this
1544  // one.
1545  if( each_item.GetParent() == this )
1546  continue;
1547 
1548  switch( each_item.GetType() )
1549  {
1550  case PIN_END:
1551  case LABEL_END:
1552  case SHEET_LABEL_END:
1553  case WIRE_END:
1554  case NO_CONNECT_END:
1555  case JUNCTION_END:
1556 
1557  if( pos == each_item.GetPosition() )
1558  pin->SetIsDangling( false );
1559 
1560  break;
1561 
1562  default:
1563  break;
1564  }
1565 
1566  if( !pin->IsDangling() )
1567  break;
1568  }
1569 
1570  changed = ( changed || ( previousState != pin->IsDangling() ) );
1571  }
1572 
1573  return changed;
1574 }
1575 
1576 
1577 wxPoint SCH_SYMBOL::GetPinPhysicalPosition( const LIB_PIN* Pin ) const
1578 {
1579  wxCHECK_MSG( Pin != nullptr && Pin->Type() == LIB_PIN_T, wxPoint( 0, 0 ),
1580  wxT( "Cannot get physical position of pin." ) );
1581 
1582  return m_transform.TransformCoordinate( Pin->GetPosition() ) + m_pos;
1583 }
1584 
1585 
1586 std::vector<wxPoint> SCH_SYMBOL::GetConnectionPoints() const
1587 {
1588  std::vector<wxPoint> retval;
1589 
1590  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1591  {
1592  // Collect only pins attached to the current unit and convert.
1593  // others are not associated to this symbol instance
1594  int pin_unit = pin->GetLibPin()->GetUnit();
1595  int pin_convert = pin->GetLibPin()->GetConvert();
1596 
1597  if( pin_unit > 0 && pin_unit != GetUnit() )
1598  continue;
1599 
1600  if( pin_convert > 0 && pin_convert != GetConvert() )
1601  continue;
1602 
1603  retval.push_back( m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos );
1604  }
1605 
1606  return retval;
1607 }
1608 
1609 
1610 LIB_ITEM* SCH_SYMBOL::GetDrawItem( const wxPoint& aPosition, KICAD_T aType )
1611 {
1612  if( m_part )
1613  {
1614  // Calculate the position relative to the symbol.
1615  wxPoint libPosition = aPosition - m_pos;
1616 
1617  return m_part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
1618  }
1619 
1620  return nullptr;
1621 }
1622 
1623 
1625 {
1626  return wxString::Format( _( "Symbol %s [%s]" ),
1627  GetField( REFERENCE_FIELD )->GetShownText(),
1628  UnescapeString( GetLibId().GetLibItemName() ) );
1629 }
1630 
1631 
1632 SEARCH_RESULT SCH_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
1633  const KICAD_T aFilterTypes[] )
1634 {
1635  KICAD_T stype;
1636 
1637  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
1638  {
1639  if( stype == SCH_LOCATE_ANY_T
1640  || ( stype == SCH_SYMBOL_T )
1641  || ( stype == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
1642  {
1643  if( SEARCH_RESULT::QUIT == aInspector( this, aTestData ) )
1644  return SEARCH_RESULT::QUIT;
1645  }
1646 
1647  if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
1648  {
1649  for( SCH_FIELD& field : m_fields )
1650  {
1651  if( SEARCH_RESULT::QUIT == aInspector( &field, (void*) this ) )
1652  return SEARCH_RESULT::QUIT;
1653  }
1654  }
1655 
1656  if( stype == SCH_FIELD_LOCATE_REFERENCE_T )
1657  {
1658  if( SEARCH_RESULT::QUIT == aInspector( GetField( REFERENCE_FIELD ), (void*) this ) )
1659  return SEARCH_RESULT::QUIT;
1660  }
1661 
1662  if( stype == SCH_FIELD_LOCATE_VALUE_T
1663  || ( stype == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
1664  {
1665  if( SEARCH_RESULT::QUIT == aInspector( GetField( VALUE_FIELD ), (void*) this ) )
1666  return SEARCH_RESULT::QUIT;
1667  }
1668 
1669  if( stype == SCH_FIELD_LOCATE_FOOTPRINT_T )
1670  {
1671  if( SEARCH_RESULT::QUIT == aInspector( GetField( FOOTPRINT_FIELD ), (void*) this ) )
1672  return SEARCH_RESULT::QUIT;
1673  }
1674 
1675  if( stype == SCH_FIELD_LOCATE_DATASHEET_T )
1676  {
1677  if( SEARCH_RESULT::QUIT == aInspector( GetField( DATASHEET_FIELD ), (void*) this ) )
1678  return SEARCH_RESULT::QUIT;
1679  }
1680 
1681  if( stype == SCH_LOCATE_ANY_T || stype == SCH_PIN_T )
1682  {
1683  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1684  {
1685  // Collect only pins attached to the current unit and convert.
1686  // others are not associated to this symbol instance
1687  int pin_unit = pin->GetLibPin()->GetUnit();
1688  int pin_convert = pin->GetLibPin()->GetConvert();
1689 
1690  if( pin_unit > 0 && pin_unit != GetUnit() )
1691  continue;
1692 
1693  if( pin_convert > 0 && pin_convert != GetConvert() )
1694  continue;
1695 
1696  if( SEARCH_RESULT::QUIT == aInspector( pin.get(), (void*) this ) )
1697  return SEARCH_RESULT::QUIT;
1698  }
1699  }
1700  }
1701 
1702  return SEARCH_RESULT::CONTINUE;
1703 }
1704 
1705 
1706 bool SCH_SYMBOL::operator <( const SCH_ITEM& aItem ) const
1707 {
1708  if( Type() != aItem.Type() )
1709  return Type() < aItem.Type();
1710 
1711  auto symbol = static_cast<const SCH_SYMBOL*>( &aItem );
1712 
1714 
1715  if( rect.GetArea() != symbol->GetBodyAndPinsBoundingBox().GetArea() )
1716  return rect.GetArea() < symbol->GetBodyAndPinsBoundingBox().GetArea();
1717 
1718  if( m_pos.x != symbol->m_pos.x )
1719  return m_pos.x < symbol->m_pos.x;
1720 
1721  if( m_pos.y != symbol->m_pos.y )
1722  return m_pos.y < symbol->m_pos.y;
1723 
1724  return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
1725 }
1726 
1727 
1728 bool SCH_SYMBOL::operator==( const SCH_SYMBOL& aSymbol ) const
1729 {
1730  if( GetFieldCount() != aSymbol.GetFieldCount() )
1731  return false;
1732 
1733  for( int i = VALUE_FIELD; i < GetFieldCount(); i++ )
1734  {
1735  if( GetFields()[i].GetText().Cmp( aSymbol.GetFields()[i].GetText() ) != 0 )
1736  return false;
1737  }
1738 
1739  return true;
1740 }
1741 
1742 
1743 bool SCH_SYMBOL::operator!=( const SCH_SYMBOL& aSymbol ) const
1744 {
1745  return !( *this == aSymbol );
1746 }
1747 
1748 
1750 {
1751  wxCHECK_MSG( Type() == aItem.Type(), *this,
1752  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1753  GetClass() );
1754 
1755  if( &aItem != this )
1756  {
1757  SCH_ITEM::operator=( aItem );
1758 
1759  SCH_SYMBOL* c = (SCH_SYMBOL*) &aItem;
1760 
1761  m_lib_id = c->m_lib_id;
1762 
1763  LIB_SYMBOL* libSymbol = c->m_part ? new LIB_SYMBOL( *c->m_part.get() ) : nullptr;
1764 
1765  m_part.reset( libSymbol );
1766  m_pos = c->m_pos;
1767  m_unit = c->m_unit;
1768  m_convert = c->m_convert;
1769  m_transform = c->m_transform;
1770 
1772 
1773  m_fields = c->m_fields; // std::vector's assignment operator
1774 
1775  // Reparent fields after assignment to new symbol.
1776  for( SCH_FIELD& field : m_fields )
1777  field.SetParent( this );
1778 
1779  UpdatePins();
1780  }
1781 
1782  return *this;
1783 }
1784 
1785 
1786 bool SCH_SYMBOL::HitTest( const wxPoint& aPosition, int aAccuracy ) const
1787 {
1788  EDA_RECT bBox = GetBodyBoundingBox();
1789  bBox.Inflate( aAccuracy / 2 );
1790 
1791  if( bBox.Contains( aPosition ) )
1792  return true;
1793 
1794  return false;
1795 }
1796 
1797 
1798 bool SCH_SYMBOL::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
1799 {
1801  return false;
1802 
1803  EDA_RECT rect = aRect;
1804 
1805  rect.Inflate( aAccuracy / 2 );
1806 
1807  if( aContained )
1808  return rect.Contains( GetBodyBoundingBox() );
1809 
1810  return rect.Intersects( GetBodyBoundingBox() );
1811 }
1812 
1813 
1814 bool SCH_SYMBOL::doIsConnected( const wxPoint& aPosition ) const
1815 {
1816  wxPoint new_pos = m_transform.InverseTransform().TransformCoordinate( aPosition - m_pos );
1817 
1818  for( const auto& pin : m_pins )
1819  {
1820  if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
1821  continue;
1822 
1823  // Collect only pins attached to the current unit and convert.
1824  // others are not associated to this symbol instance
1825  int pin_unit = pin->GetLibPin()->GetUnit();
1826  int pin_convert = pin->GetLibPin()->GetConvert();
1827 
1828  if( pin_unit > 0 && pin_unit != GetUnit() )
1829  continue;
1830 
1831  if( pin_convert > 0 && pin_convert != GetConvert() )
1832  continue;
1833 
1834  if( pin->GetLocalPosition() == new_pos )
1835  return true;
1836  }
1837 
1838  return false;
1839 }
1840 
1841 
1843 {
1844  return m_isInNetlist;
1845 }
1846 
1847 
1848 void SCH_SYMBOL::Plot( PLOTTER* aPlotter ) const
1849 {
1850  if( m_part )
1851  {
1852  TRANSFORM temp = GetTransform();
1853  aPlotter->StartBlock( nullptr );
1854 
1855  m_part->Plot( aPlotter, GetUnit(), GetConvert(), m_pos, temp );
1856 
1857  for( SCH_FIELD field : m_fields )
1858  field.Plot( aPlotter );
1859 
1860  aPlotter->EndBlock( nullptr );
1861  }
1862 }
1863 
1864 
1866 {
1867  for( const auto& pin : m_pins )
1868  {
1869  if( pin->IsBrightened() )
1870  return true;
1871  }
1872 
1873  return false;
1874 }
1875 
1876 
1878 {
1879  for( auto& pin : m_pins )
1880  pin->ClearBrightened();
1881 }
1882 
1883 
1884 bool SCH_SYMBOL::IsPointClickableAnchor( const wxPoint& aPos ) const
1885 {
1886  for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1887  {
1888  int pin_unit = pin->GetLibPin()->GetUnit();
1889  int pin_convert = pin->GetLibPin()->GetConvert();
1890 
1891  if( pin_unit > 0 && pin_unit != GetUnit() )
1892  continue;
1893 
1894  if( pin_convert > 0 && pin_convert != GetConvert() )
1895  continue;
1896 
1897  if( pin->IsPointClickableAnchor( aPos ) )
1898  return true;
1899  }
1900 
1901  return false;
1902 }
bool m_isInNetlist
True if the symbol should appear in the netlist.
Definition: sch_symbol.h:705
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:759
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:381
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:478
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:683
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
EDA_RECT doGetBoundingBox(bool aIncludePins, bool aIncludeFields) const
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:677
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:333
Holds all the data relating to one schematic.
Definition: schematic.h:59
EDA_RECT GetBodyAndPinsBoundingBox() const
Return a bounding box for the symbol body and pins but not the fields.
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:372
std::vector< std::unique_ptr< SCH_PIN > > m_pins
Definition: sch_symbol.h:702
void ImportValues(const LIB_FIELD &aSource)
Copy parameters from a LIB_FIELD source.
Definition: sch_field.cpp:246
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:596
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:944
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:713
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition: transform.cpp:57
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:267
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:104
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:604
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:230
SCH_FIELDS m_fields
Variable length list of fields.
Definition: sch_symbol.h:698
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:240
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:480
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:480
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:443
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:893
Define a library symbol object.
Definition: lib_symbol.h:96
void SetFootprint(const SCH_SHEET_PATH *sheet, const wxString &aFootprint)
Definition: sch_symbol.cpp:647
wxString GetDatasheet() const
Return the documentation text for the given part alias.
Definition: sch_symbol.cpp:277
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:259
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:365
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:489
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:549
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:679
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:93
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:115
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:343
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
const EDA_RECT GetBodyBoundingBox(int aUnit, int aConvert, bool aIncludePins) const
Get the symbol bounding box excluding fields.
Definition: lib_symbol.cpp:901
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:854
#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:930
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:696
int GetUnit() const
Definition: lib_item.h:258
bool IsInNetlist() const
int m_convert
The alternate body style for symbols that have more than one body style defined.
Definition: sch_symbol.h:680
wxString m_schLibSymbolName
The name used to look up a symbol in the symbol library embedded in a schematic.
Definition: sch_symbol.h:695
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
SCH_LAYER_ID m_layer
Definition: sch_item.h:487
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
Definition: sch_symbol.cpp:723
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:124
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:250
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:424
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:533
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
Definition: sch_symbol.cpp:286
EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the pins or fields.
wxPoint m_pos
Definition: sch_symbol.h:677
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:701
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:700
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:157
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:575
E_SERIE r
Definition: eserie.cpp:41
bool m_onBoard
True to include in netlist when updating board.
Definition: sch_symbol.h:707
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:745
wxString GetClass() const override
Return the class name.
Definition: sch_symbol.h:118
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:701
void SetY(int val)
Definition: eda_rect.h:164
void SetConvert(int aConvert)
Definition: sch_symbol.cpp:349
const KIID m_Uuid
Definition: eda_item.h:474
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:519
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:512
LIB_ID m_lib_id
Name and library the symbol was loaded from, i.e. 74xx:74LS00.
Definition: sch_symbol.h:678
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this 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:706
std::unordered_map< LIB_PIN *, unsigned > m_pinMap
Definition: sch_symbol.h:703
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:842
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:483
wxString AsString() const
Definition: kiid.cpp:310
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:697
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:99
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:193
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:832
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:268
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:626
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:402
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:79
std::vector< SYMBOL_INSTANCE_REFERENCE > m_instanceReferences
Definition: sch_symbol.h:711
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
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:369
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:477
SCH_FIELD * GetFieldById(int aFieldId)
Return a field in this symbol.
Definition: sch_symbol.cpp:689
int GetConvert() const
Definition: sch_symbol.h:223
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
Definition: sch_symbol.cpp:732
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:182
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:154
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:868
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:62
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:112
bool GetIncludeInBom() const
Definition: lib_symbol.h:596
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:362
Field Name Module PCB, i.e. "16DIP300".