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