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 <fctsys.h>
26 #include <pgm_base.h>
27 #include <sch_draw_panel.h>
28 #include <gr_basic.h>
29 #include <kicad_string.h>
30 #include <richio.h>
31 #include <sch_edit_frame.h>
32 #include <plotter.h>
33 #include <msgpanel.h>
34 #include <bitmaps.h>
35 
36 #include <general.h>
37 #include <class_library.h>
38 #include <lib_rectangle.h>
39 #include <lib_pin.h>
40 #include <lib_text.h>
41 #include <sch_component.h>
42 #include <sch_sheet.h>
43 #include <sch_sheet_path.h>
44 #include <sch_legacy_plugin.h>
45 #include <netlist_object.h>
46 #include <lib_item.h>
47 #include <symbol_lib_table.h>
48 
50 
51 #include <wx/tokenzr.h>
52 #include <iostream>
53 #include <cctype>
54 
55 #include <eeschema_id.h> // for MAX_UNIT_COUNT_PER_PACKAGE definition
56 
57 #include <trace_helpers.h>
58 
59 
64 std::string toUTFTildaText( const wxString& txt )
65 {
66  std::string ret = TO_UTF8( txt );
67 
68  for( std::string::iterator it = ret.begin(); it!=ret.end(); ++it )
69  {
70  if( (unsigned char) *it <= ' ' )
71  *it = '~';
72  }
73  return ret;
74 }
75 
76 
90 static LIB_PART* dummy()
91 {
92  static LIB_PART* part;
93 
94  if( !part )
95  {
96  part = new LIB_PART( wxEmptyString );
97 
98  LIB_RECTANGLE* square = new LIB_RECTANGLE( part );
99 
100  square->MoveTo( wxPoint( Mils2iu( -200 ), Mils2iu( 200 ) ) );
101  square->SetEndPosition( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) );
102 
103  LIB_TEXT* text = new LIB_TEXT( part );
104 
105  text->SetTextSize( wxSize( Mils2iu( 150 ), Mils2iu( 150 ) ) );
106  text->SetText( wxString( wxT( "??" ) ) );
107 
108  part->AddDrawItem( square );
109  part->AddDrawItem( text );
110  }
111 
112  return part;
113 }
114 
115 
117  SCH_ITEM( aParent, SCH_COMPONENT_T )
118 {
119  Init( aPos );
121 }
122 
123 
125  int unit, int convert, const wxPoint& pos ) :
127 {
128  Init( pos );
129 
130  m_unit = unit;
131  m_convert = convert;
132  m_lib_id = aLibId;
133 
134  std::unique_ptr< LIB_PART > part;
135 
136  part = aPart.Flatten();
137  part->SetParent();
138  m_part.reset( part.release() );
140 
141  // Copy fields from the library component
142  UpdateFields( true, true );
143 
144  // Update the pin locations
145  UpdatePins();
146 
147  // Update the reference -- just the prefix for now.
148  if( sheet )
149  SetRef( sheet, aPart.GetReferenceField().GetText() + wxT( "?" ) );
150  else
151  m_prefix = aPart.GetReferenceField().GetText() + wxT( "?" );
152 }
153 
155  LIB_PART& aPart, SCH_SHEET_PATH* aSheet, COMPONENT_SELECTION& aSel, const wxPoint& pos )
156  : SCH_COMPONENT( aPart, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos )
157 {
158  // Set any fields that were modified as part of the component selection
159  for( auto const& i : aSel.Fields )
160  {
161  auto field = this->GetField( i.first );
162 
163  if( field )
164  field->SetText( i.second );
165  }
166 }
167 
168 
170  SCH_ITEM( aComponent )
171 {
172  m_Parent = aComponent.m_Parent;
173  m_Pos = aComponent.m_Pos;
174  m_unit = aComponent.m_unit;
175  m_convert = aComponent.m_convert;
176  m_lib_id = aComponent.m_lib_id;
177  m_isInNetlist = aComponent.m_isInNetlist;
178 
179  if( aComponent.m_part )
180  m_part.reset( new LIB_PART( *aComponent.m_part.get() ) );
181 
182  const_cast<KIID&>( m_Uuid ) = aComponent.m_Uuid;
183 
184  m_transform = aComponent.m_transform;
185  m_prefix = aComponent.m_prefix;
187  m_Fields = aComponent.m_Fields;
188 
189  // Re-parent the fields, which before this had aComponent as parent
190  for( SCH_FIELD& field : m_Fields )
191  field.SetParent( this );
192 
193  UpdatePins();
194 
196 }
197 
198 
199 void SCH_COMPONENT::Init( const wxPoint& pos )
200 {
201  m_Pos = pos;
202  m_unit = 1; // In multi unit chip - which unit to draw.
203  m_convert = LIB_ITEM::LIB_CONVERT::BASE; // De Morgan Handling
204 
205  // The rotation/mirror transformation matrix. pos normal
207 
208  // construct only the mandatory fields, which are the first 4 only.
209  for( int i = 0; i < MANDATORY_FIELDS; ++i )
210  {
211  m_Fields.emplace_back( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
212 
213  if( i == REFERENCE )
214  m_Fields.back().SetLayer( LAYER_REFERENCEPART );
215  else if( i == VALUE )
216  m_Fields.back().SetLayer( LAYER_VALUEPART );
217  else
218  m_Fields.back().SetLayer( LAYER_FIELDS );
219  }
220 
221  m_prefix = wxString( wxT( "U" ) );
222  m_isInNetlist = true;
223 }
224 
225 
227 {
228  return new SCH_COMPONENT( *this );
229 }
230 
231 
232 void SCH_COMPONENT::ViewGetLayers( int aLayers[], int& aCount ) const
233 {
234  aCount = 3;
235  aLayers[0] = LAYER_DEVICE;
236  aLayers[1] = LAYER_DEVICE_BACKGROUND;
237  aLayers[2] = LAYER_SELECTION_SHADOWS;
238 }
239 
240 
241 void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, PART_LIBS* aLibs )
242 {
243  if( m_lib_id != aLibId )
244  {
245  m_lib_id = aLibId;
246  SetModified();
247 
248  if( aLibs )
249  {
250  Resolve( aLibs );
251  }
252  else
253  {
254  m_part.reset();
255  m_pins.clear();
256  m_pinMap.clear();
257  }
258  }
259 }
260 
261 
262 void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable,
263  PART_LIB* aCacheLib )
264 {
265  if( m_lib_id == aLibId )
266  return;
267 
268  m_lib_id = aLibId;
269  SetModified();
270 
271  std::unique_ptr< LIB_PART > symbol;
272 
273  if( aSymLibTable && aSymLibTable->HasLibrary( m_lib_id.GetLibNickname() ) )
274  {
275  LIB_PART* tmp = aSymLibTable->LoadSymbol( m_lib_id );
276 
277  if( tmp )
278  {
279  symbol = tmp->Flatten();
280  symbol->SetParent();
281  }
282  }
283 
284  if( !symbol && aCacheLib )
285  {
286  LIB_PART* tmp = aCacheLib->FindPart( m_lib_id.Format().wx_str() );
287 
288  if( tmp )
289  {
290  symbol = tmp->Flatten();
291  symbol->SetParent();
292  }
293  }
294 
295  m_part.reset( symbol.release() );
296  UpdatePins();
297 }
298 
299 
301 {
302  if( m_part )
303  {
304  return m_part->GetDescription();
305  }
306 
307  return wxEmptyString;
308 }
309 
310 
312 {
313  if( m_part )
314  {
315  return m_part->GetDocFileName();
316  }
317 
318  return wxEmptyString;
319 }
320 
321 
323 {
324  // I've never been happy that the actual individual PART_LIB is left up to
325  // flimsy search path ordering. None-the-less find a part based on that design:
326  if( LIB_PART* part = aLibs->FindLibPart( m_lib_id ) )
327  {
328  std::unique_ptr< LIB_PART > flattenedPart = part->Flatten();
329  flattenedPart->SetParent();
330  m_part.reset( flattenedPart.release() );
331  UpdatePins();
332  return true;
333  }
334 
335  return false;
336 }
337 
338 
339 bool SCH_COMPONENT::Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
340 {
341  std::unique_ptr< LIB_PART > part;
342 
343  try
344  {
345  // We want a full symbol not just the top level child symbol.
346  PROPERTIES props;
347 
348  props[ SCH_LEGACY_PLUGIN::PropNoDocFile ] = "";
349 
350  // LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the the library nickname
351  // is not found in the table so check if the library still exists in the table
352  // before attempting to load the symbol.
353  if( m_lib_id.IsValid() && aLibTable.HasLibrary( m_lib_id.GetLibNickname() ) )
354  {
355  LIB_PART* tmp = aLibTable.LoadSymbol( m_lib_id );
356 
357  if( tmp )
358  {
359  part = tmp->Flatten();
360  part->SetParent();
361  }
362  }
363 
364  // Fall back to cache library. This is temporary until the new schematic file
365  // format is implemented.
366  if( !part && aCacheLib )
367  {
368  wxString libId = m_lib_id.Format().wx_str();
369  libId.Replace( ":", "_" );
370  wxLogTrace( traceSymbolResolver,
371  "Library symbol %s not found falling back to cache library.",
372  m_lib_id.Format().wx_str() );
373  LIB_PART* tmp = aCacheLib->FindPart( libId );
374 
375  if( tmp )
376  {
377  part = tmp->Flatten();
378  part->SetParent();
379  }
380  }
381 
382  if( part )
383  {
384  m_part.reset( part.release() );
385  UpdatePins();
386  return true;
387  }
388  }
389  catch( const IO_ERROR& ioe )
390  {
391  wxLogTrace( traceSymbolResolver, "I/O error %s resolving library symbol %s", ioe.What(),
392  m_lib_id.Format().wx_str() );
393  }
394 
395  wxLogTrace( traceSymbolResolver, "Cannot resolve library symbol %s",
396  m_lib_id.Format().wx_str() );
397 
398  m_part.reset();
399  UpdatePins(); // This will clear the pin map and library symbol pin pointers.
400 
401  return false;
402 }
403 
404 
405 // Helper sort function, used in SCH_COMPONENT::ResolveAll, to sort sch component by lib_id
406 static bool sort_by_libid( const SCH_COMPONENT* ref, SCH_COMPONENT* cmp )
407 {
408  if( ref->GetLibId() == cmp->GetLibId() )
409  {
410  if( ref->GetUnit() == cmp->GetUnit() )
411  return ref->GetConvert() < cmp->GetConvert();
412 
413  return ref->GetUnit() < cmp->GetUnit();
414  }
415 
416  return ref->GetLibId() < cmp->GetLibId();
417 }
418 
419 
421  std::vector<SCH_COMPONENT*>& aComponents, SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
422 {
423  // sort it by lib part. Cmp will be grouped by same lib part.
424  std::sort( aComponents.begin(), aComponents.end(), sort_by_libid );
425 
426  LIB_ID curr_libid;
427 
428  for( unsigned ii = 0; ii < aComponents.size(); ++ii )
429  {
430  SCH_COMPONENT* cmp = aComponents[ii];
431  curr_libid = cmp->m_lib_id;
432  cmp->Resolve( aLibTable, aCacheLib );
433  cmp->UpdatePins();
434 
435  // Propagate the m_part pointer to other members using the same lib_id
436  for( unsigned jj = ii + 1; jj < aComponents.size(); ++jj )
437  {
438  SCH_COMPONENT* next_cmp = aComponents[jj];
439 
440  if( curr_libid != next_cmp->m_lib_id )
441  break;
442 
443  if( cmp->m_part )
444  next_cmp->m_part.reset( new LIB_PART( *cmp->m_part.get() ) );
445 
446  next_cmp->UpdatePins();
447 
448  ii = jj;
449  }
450  }
451 }
452 
453 
455 {
456  m_pins.clear();
457  m_pinMap.clear();
458 
459  if( m_part )
460  {
461  SCH_PIN_MAP map;
462  unsigned i = 0;
463 
464  for( LIB_PIN* libPin = m_part->GetNextPin(); libPin; libPin = m_part->GetNextPin( libPin ) )
465  {
466  wxASSERT( libPin->Type() == LIB_PIN_T );
467 
468  if( libPin->GetConvert() && m_convert && ( m_convert != libPin->GetConvert() ) )
469  continue;
470 
471  m_pins.push_back( std::unique_ptr<SCH_PIN>( new SCH_PIN( libPin, this ) ) );
472  m_pinMap[ libPin ] = i;
473 
474  ++i;
475  }
476  }
477 }
478 
479 
481 {
482  if( m_pinMap.count( aPin ) )
483  return m_pins[ m_pinMap[aPin] ]->Connection( aSheet );
484 
485  return nullptr;
486 }
487 
488 
489 void SCH_COMPONENT::SetUnit( int aUnit )
490 {
491  if( m_unit != aUnit )
492  {
493  m_unit = aUnit;
494  SetModified();
495  }
496 }
497 
498 
499 void SCH_COMPONENT::UpdateUnit( int aUnit )
500 {
501  m_unit = aUnit;
502 }
503 
504 
505 void SCH_COMPONENT::SetConvert( int aConvert )
506 {
507  if( m_convert != aConvert )
508  {
509  m_convert = aConvert;
510  SetModified();
511  }
512 }
513 
514 
515 void SCH_COMPONENT::SetTransform( const TRANSFORM& aTransform )
516 {
517  if( m_transform != aTransform )
518  {
519  m_transform = aTransform;
520  SetModified();
521  }
522 }
523 
524 
526 {
527  if( m_part )
528  return m_part->GetUnitCount();
529 
530  return 0;
531 }
532 
533 
534 void SCH_COMPONENT::Print( wxDC* aDC, const wxPoint& aOffset )
535 {
536  auto opts = PART_DRAW_OPTIONS::Default();
537  opts.transform = m_transform;
538  opts.draw_visible_fields = false;
539  opts.draw_hidden_fields = false;
540 
541  if( m_part )
542  {
543  m_part->Print( aDC, m_Pos + aOffset, m_unit, m_convert, opts );
544  }
545  else // Use dummy() part if the actual cannot be found.
546  {
547  dummy()->Print( aDC, m_Pos + aOffset, 0, 0, opts );
548  }
549 
550  for( SCH_FIELD& field : m_Fields )
551  field.Print( aDC, aOffset );
552 }
553 
554 
555 void SCH_COMPONENT::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef,
556  int aUnit )
557 {
558  // Search for an existing path and remove it if found (should not occur)
559  for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
560  {
561  if( m_instanceReferences[ii].m_Path == aPath )
562  {
563  m_instanceReferences.erase( m_instanceReferences.begin() + ii );
564  ii--;
565  }
566  }
567 
569  instance.m_Path = aPath;
570  instance.m_Reference = aRef;
571  instance.m_Unit = aUnit;
572  m_instanceReferences.push_back( instance );
573 }
574 
575 
576 const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit )
577 {
578  KIID_PATH path = sheet->Path();
579  wxString ref;
580 
581  for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
582  {
583  if( instance.m_Path == path )
584  {
585  ref = instance.m_Reference;
586  break;
587  }
588  }
589 
590  // If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
591  // use this as a default for this path. This will happen if we load a version 1 schematic
592  // file. It will also mean that multiple instances of the same sheet by default all have
593  // the same component references, but perhaps this is best.
594  if( ref.IsEmpty() && !GetField( REFERENCE )->GetText().IsEmpty() )
595  {
596  SetRef( sheet, GetField( REFERENCE )->GetText() );
597  ref = GetField( REFERENCE )->GetText();
598  }
599 
600  if( ref.IsEmpty() )
601  ref = m_prefix;
602 
603  if( aIncludeUnit )
604  ref += LIB_PART::SubReference( GetUnit() );
605 
606  return ref;
607 }
608 
609 
610 bool SCH_COMPONENT::IsReferenceStringValid( const wxString& aReferenceString )
611 {
612  wxString text = aReferenceString;
613  bool ok = true;
614 
615  // Try to unannotate this reference
616  while( !text.IsEmpty() && ( text.Last() == '?' || wxIsdigit( text.Last() ) ) )
617  text.RemoveLast();
618 
619  if( text.IsEmpty() )
620  ok = false;
621 
622  return ok;
623 }
624 
625 
626 void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
627 {
628  KIID_PATH path = sheet->Path();
629  bool notInArray = true;
630 
631  // check to see if it is already there before inserting it
633  {
634  if( instance.m_Path == path )
635  {
636  instance.m_Reference = ref;
637  notInArray = false;
638  }
639  }
640 
641  if( notInArray )
642  AddHierarchicalReference( path, ref, m_unit );
643 
644  SCH_FIELD* rf = GetField( REFERENCE );
645 
646  // @todo Should we really be checking for what is a "reasonable" position?
647  if( rf->GetText().IsEmpty()
648  || ( abs( rf->GetTextPos().x - m_Pos.x ) +
649  abs( rf->GetTextPos().y - m_Pos.y ) > Mils2iu( 10000 ) ) )
650  {
651  // move it to a reasonable position
652  rf->SetTextPos( m_Pos + wxPoint( Mils2iu( 50 ), Mils2iu( 50 ) ) );
653  }
654 
655  rf->SetText( ref ); // for drawing.
656 
657  // Reinit the m_prefix member if needed
658  wxString prefix = ref;
659 
660  if( IsReferenceStringValid( prefix ) )
661  {
662  while( prefix.Last() == '?' || wxIsdigit( prefix.Last() ) )
663  prefix.RemoveLast();
664  }
665  else
666  {
667  prefix = wxT( "U" ); // Set to default ref prefix
668  }
669 
670  if( m_prefix != prefix )
671  m_prefix = prefix;
672 
673  // Power components have references starting with # and are not included in netlists
674  m_isInNetlist = ! ref.StartsWith( wxT( "#" ) );
675 }
676 
677 
679 {
680  KIID_PATH path = aSheet->Path();
681 
682  for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
683  {
684  if( instance.m_Path == path )
685  return instance.m_Reference.Last() != '?';
686  }
687 
688  return false;
689 }
690 
691 
693 {
694  KIID_PATH path = aSheet->Path();
695 
696  for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
697  {
698  if( instance.m_Path == path )
699  return instance.m_Unit;
700  }
701 
702  // If it was not found in m_Paths array, then use m_unit. This will happen if we load a
703  // version 1 schematic file.
704  return m_unit;
705 }
706 
707 
708 void SCH_COMPONENT::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
709 {
710  KIID_PATH path = aSheet->Path();
711  bool notInArray = true;
712 
713  // check to see if it is already there before inserting it
715  {
716  if( instance.m_Path == path )
717  {
718  instance.m_Unit = aUnitSelection;
719  notInArray = false;
720  }
721  }
722 
723  if( notInArray )
724  AddHierarchicalReference( path, m_prefix, aUnitSelection );
725 }
726 
727 
728 SCH_FIELD* SCH_COMPONENT::GetField( int aFieldNdx ) const
729 {
730  const SCH_FIELD* field;
731 
732  if( (unsigned) aFieldNdx < m_Fields.size() )
733  field = &m_Fields[aFieldNdx];
734  else
735  field = NULL;
736 
737  wxASSERT( field );
738 
739  return const_cast<SCH_FIELD*>( field );
740 }
741 
742 
743 wxString SCH_COMPONENT::GetFieldText( const wxString& aFieldName, SCH_EDIT_FRAME* aFrame ) const
744 {
745  for( const SCH_FIELD& field : m_Fields )
746  {
747  if( aFieldName == field.GetName() )
748  return field.GetText();
749  }
750 
751  return wxEmptyString;
752 }
753 
754 
755 void SCH_COMPONENT::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
756 {
757  for( SCH_FIELD& field : m_Fields )
758  {
759  if( !aVisibleOnly || ( field.IsVisible() && !field.IsVoid() ) )
760  aVector.push_back( &field );
761  }
762 }
763 
764 
765 std::vector<SCH_FIELD*> SCH_COMPONENT::GetFields()
766 {
767  std::vector<SCH_FIELD*> retvec;
768  retvec.reserve( m_Fields.size() );
769 
770  for( SCH_FIELD& field : m_Fields )
771  retvec.push_back( &field );
772 
773  return retvec;
774 }
775 
776 
778 {
779  int newNdx = m_Fields.size();
780 
781  m_Fields.push_back( aField );
782  return &m_Fields[newNdx];
783 }
784 
785 
786 void SCH_COMPONENT::RemoveField( const wxString& aFieldName )
787 {
788  for( unsigned i = MANDATORY_FIELDS; i < m_Fields.size(); ++i )
789  {
790  if( aFieldName == m_Fields[i].GetName( false ) )
791  {
792  m_Fields.erase( m_Fields.begin() + i );
793  return;
794  }
795  }
796 }
797 
798 
799 SCH_FIELD* SCH_COMPONENT::FindField( const wxString& aFieldName, bool aIncludeDefaultFields )
800 {
801  unsigned start = aIncludeDefaultFields ? 0 : MANDATORY_FIELDS;
802 
803  for( unsigned i = start; i < m_Fields.size(); ++i )
804  {
805  if( aFieldName == m_Fields[i].GetName( false ) )
806  return &m_Fields[i];
807  }
808 
809  return NULL;
810 }
811 
812 
813 void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
814 {
815  if( m_part )
816  {
817  wxString symbolName;
818  LIB_FIELDS fields;
819  m_part->GetFields( fields );
820 
821  for( const LIB_FIELD& field : fields )
822  {
823  // Can no longer insert an empty name, since names are now keys. The
824  // field index is not used beyond the first MANDATORY_FIELDS
825  if( field.GetName( NATIVE_FIELD_NAME ).IsEmpty() )
826  continue;
827 
828  // See if field already exists (mandatory fields always exist).
829  // for mandatory fields, the name and field id are fixed, so we use the
830  // known and fixed id to get them (more reliable than names, which can be translated)
831  // for other fields (custom fields), locate the field by same name
832  // (field id has no known meaning for custom fields)
833  int idx = field.GetId();
834  SCH_FIELD* schField;
835 
836  if( idx == REFERENCE && !aResetRef )
837  continue;
838 
839  if( (unsigned) idx < MANDATORY_FIELDS )
840  schField = GetField( idx );
841  else
842  schField = FindField( field.GetName( NATIVE_FIELD_NAME ) );
843 
844  if( !schField )
845  {
846  SCH_FIELD newField( wxPoint( 0, 0 ), GetFieldCount(), this,
847  field.GetName( NATIVE_FIELD_NAME ) );
848  schField = AddField( newField );
849  }
850 
851  if( aResetStyle )
852  {
853  schField->ImportValues( field );
854  schField->SetTextPos( m_Pos + field.GetTextPos() );
855  }
856 
857  if( idx == VALUE )
858  {
859  schField->SetText( m_lib_id.GetLibItemName() ); // fetch alias-specific value
860  symbolName = m_lib_id.GetLibItemName();
861  }
862  else if( idx == DATASHEET )
863  {
864  schField->SetText( GetDatasheet() ); // fetch alias-specific value
865 
866  // Some older libraries may be broken and the alias datasheet information
867  // in the document file for the root part may have been dropped. This only
868  // happens for the root part.
869  if( schField->GetText().IsEmpty() && symbolName == m_part->GetName() )
870  schField->SetText( m_part->GetField( DATASHEET )->GetText() );
871  }
872  else
873  {
874  schField->SetText( field.GetText() );
875  }
876  }
877  }
878 }
879 
880 
881 LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number )
882 {
883  if( m_part )
884  {
885  return m_part->GetPin( number, m_unit, m_convert );
886  }
887 
888  return NULL;
889 }
890 
891 
892 void SCH_COMPONENT::GetPins( std::vector<LIB_PIN*>& aPinsList )
893 {
894  if( m_part )
895  m_part->GetPins( aPinsList, m_unit, m_convert );
896 }
897 
898 
900 {
901  if( aSheet == nullptr )
902  aSheet = g_CurrentSheet;
903 
904  // TODO(JE) if this works, consider caching in m_sheet_pins
905  int unit = GetUnitSelection( aSheet );
906  SCH_PIN_PTRS ptrs;
907 
908  for( const auto& p : m_pins )
909  {
910  if( unit && p->GetLibPin()->GetUnit() && ( p->GetLibPin()->GetUnit() != unit ) )
911  continue;
912 
913  ptrs.push_back( p.get() );
914  }
915 
916  return ptrs;
917 }
918 
919 
921 {
922  wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T),
923  wxT( "Cannot swap data with invalid component." ) );
924 
925  SCH_COMPONENT* component = (SCH_COMPONENT*) aItem;
926 
927  std::swap( m_lib_id, component->m_lib_id );
928 
929  LIB_PART* part = component->m_part.release();
930  component->m_part.reset( m_part.release() );
931  component->UpdatePins();
932  m_part.reset( part );
933  UpdatePins();
934 
935  std::swap( m_Pos, component->m_Pos );
936  std::swap( m_unit, component->m_unit );
937  std::swap( m_convert, component->m_convert );
938 
939  m_Fields.swap( component->m_Fields ); // std::vector's swap()
940 
941  for( SCH_FIELD& field : component->m_Fields )
942  field.SetParent( component );
943 
944  for( SCH_FIELD& field : m_Fields )
945  field.SetParent( this );
946 
947  TRANSFORM tmp = m_transform;
948 
949  m_transform = component->m_transform;
950  component->m_transform = tmp;
951 
952  std::swap( m_instanceReferences, component->m_instanceReferences );
953 }
954 
955 
957 {
958  // Build a reference with no annotation,
959  // i.e. a reference ended by only one '?'
960  wxString defRef = m_prefix;
961 
962  if( !IsReferenceStringValid( defRef ) )
963  { // This is a malformed reference: reinit this reference
964  m_prefix = defRef = wxT("U"); // Set to default ref prefix
965  }
966 
967  while( defRef.Last() == '?' )
968  defRef.RemoveLast();
969 
970  defRef.Append( wxT( "?" ) );
971 
972  if( aSheetPath )
973  {
974  KIID_PATH path = aSheetPath->Path();
975 
977  {
978  if( instance.m_Path == path )
979  instance.m_Reference = defRef;
980  }
981  }
982  else
983  {
985  instance.m_Reference = defRef;
986  }
987 
988  // These 2 changes do not work in complex hierarchy.
989  // When a clear annotation is made, the calling function must call a
990  // UpdateAllScreenReferences for the active sheet.
991  // But this call cannot made here.
992  m_Fields[REFERENCE].SetText( defRef ); //for drawing.
993 
994  SetModified();
995 }
996 
997 
999 {
1000  // a empty sheet path is illegal:
1001  wxCHECK( aSheetPath.size() > 0, false );
1002 
1003  wxString reference_path;
1004 
1005  for( const COMPONENT_INSTANCE_REFERENCE& instance : m_instanceReferences )
1006  {
1007  // if aSheetPath is found, nothing to do:
1008  if( instance.m_Path == aSheetPath )
1009  return false;
1010  }
1011 
1012  // This entry does not exist: add it, with its last-used reference
1014  return true;
1015 }
1016 
1017 
1018 void SCH_COMPONENT::SetOrientation( int aOrientation )
1019 {
1020  TRANSFORM temp = TRANSFORM();
1021  bool transform = false;
1022 
1023  switch( aOrientation )
1024  {
1025  case CMP_ORIENT_0:
1026  case CMP_NORMAL: // default transform matrix
1027  m_transform.x1 = 1;
1028  m_transform.y2 = -1;
1029  m_transform.x2 = m_transform.y1 = 0;
1030  break;
1031 
1032  case CMP_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1033  temp.x1 = temp.y2 = 0;
1034  temp.y1 = 1;
1035  temp.x2 = -1;
1036  transform = true;
1037  break;
1038 
1039  case CMP_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1040  temp.x1 = temp.y2 = 0;
1041  temp.y1 = -1;
1042  temp.x2 = 1;
1043  transform = true;
1044  break;
1045 
1046  case CMP_MIRROR_Y: // Mirror Y (incremental rotation)
1047  temp.x1 = -1;
1048  temp.y2 = 1;
1049  temp.y1 = temp.x2 = 0;
1050  transform = true;
1051  break;
1052 
1053  case CMP_MIRROR_X: // Mirror X (incremental rotation)
1054  temp.x1 = 1;
1055  temp.y2 = -1;
1056  temp.y1 = temp.x2 = 0;
1057  transform = true;
1058  break;
1059 
1060  case CMP_ORIENT_90:
1063  break;
1064 
1065  case CMP_ORIENT_180:
1069  break;
1070 
1071  case CMP_ORIENT_270:
1074  break;
1075 
1076  case ( CMP_ORIENT_0 + CMP_MIRROR_X ):
1079  break;
1080 
1081  case ( CMP_ORIENT_0 + CMP_MIRROR_Y ):
1084  break;
1085 
1086  case ( CMP_ORIENT_90 + CMP_MIRROR_X ):
1089  break;
1090 
1091  case ( CMP_ORIENT_90 + CMP_MIRROR_Y ):
1094  break;
1095 
1096  case ( CMP_ORIENT_180 + CMP_MIRROR_X ):
1099  break;
1100 
1101  case ( CMP_ORIENT_180 + CMP_MIRROR_Y ):
1104  break;
1105 
1106  case ( CMP_ORIENT_270 + CMP_MIRROR_X ):
1109  break;
1110 
1111  case ( CMP_ORIENT_270 + CMP_MIRROR_Y ):
1114  break;
1115 
1116  default:
1117  transform = false;
1118  wxMessageBox( wxT( "SetRotateMiroir() error: ill value" ) );
1119  break;
1120  }
1121 
1122  if( transform )
1123  {
1124  /* The new matrix transform is the old matrix transform modified by the
1125  * requested transformation, which is the temp transform (rot,
1126  * mirror ..) in order to have (in term of matrix transform):
1127  * transform coord = new_m_transform * coord
1128  * where transform coord is the coord modified by new_m_transform from
1129  * the initial value coord.
1130  * new_m_transform is computed (from old_m_transform and temp) to
1131  * have:
1132  * transform coord = old_m_transform * temp
1133  */
1134  TRANSFORM newTransform;
1135 
1136  newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1137  newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1138  newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1139  newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1140  m_transform = newTransform;
1141  }
1142 }
1143 
1144 
1146 {
1147  int rotate_values[] =
1148  {
1149  CMP_ORIENT_0,
1150  CMP_ORIENT_90,
1156  CMP_MIRROR_Y,
1161  };
1162 
1163  // Try to find the current transform option:
1164  TRANSFORM transform = m_transform;
1165 
1166  for( int type_rotate : rotate_values )
1167  {
1168  SetOrientation( type_rotate );
1169 
1170  if( transform == m_transform )
1171  return type_rotate;
1172  }
1173 
1174  // Error: orientation not found in list (should not happen)
1175  wxMessageBox( wxT( "Component orientation matrix internal error" ) );
1176  m_transform = transform;
1177 
1178  return CMP_NORMAL;
1179 }
1180 
1181 
1182 #if defined(DEBUG)
1183 
1184 void SCH_COMPONENT::Show( int nestLevel, std::ostream& os ) const
1185 {
1186  // for now, make it look like XML:
1187  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1188  << " ref=\"" << TO_UTF8( GetField( 0 )->GetName() )
1189  << '"' << " chipName=\""
1190  << GetLibId().Format() << '"' << m_Pos
1191  << " layer=\"" << m_Layer
1192  << '"' << ">\n";
1193 
1194  // skip the reference, it's been output already.
1195  for( int i = 1; i < GetFieldCount(); ++i )
1196  {
1197  wxString value = GetField( i )->GetText();
1198 
1199  if( !value.IsEmpty() )
1200  {
1201  NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1202  << TO_UTF8( GetField( i )->GetName() )
1203  << '"' << " value=\""
1204  << TO_UTF8( value ) << "\"/>\n";
1205  }
1206  }
1207 
1208  NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1209 }
1210 
1211 #endif
1212 
1213 
1215 {
1216  EDA_RECT bBox;
1217 
1218  if( m_part )
1219  {
1220  bBox = m_part->GetBodyBoundingBox( m_unit, m_convert );
1221  }
1222  else
1223  {
1224  bBox = dummy()->GetBodyBoundingBox( m_unit, m_convert );
1225  }
1226 
1227  int x0 = bBox.GetX();
1228  int xm = bBox.GetRight();
1229 
1230  // We must reverse Y values, because matrix orientation
1231  // suppose Y axis normal for the library items coordinates,
1232  // m_transform reverse Y values, but bBox is already reversed!
1233  int y0 = -bBox.GetY();
1234  int ym = -bBox.GetBottom();
1235 
1236  // Compute the real Boundary box (rotated, mirrored ...)
1237  int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
1238  int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
1239  int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
1240  int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
1241 
1242  bBox.SetX( x1 );
1243  bBox.SetY( y1 );
1244  bBox.SetWidth( x2 - x1 );
1245  bBox.SetHeight( y2 - y1 );
1246  bBox.Normalize();
1247 
1248  bBox.Offset( m_Pos );
1249  return bBox;
1250 }
1251 
1252 
1254 {
1255  EDA_RECT bbox = GetBodyBoundingBox();
1256 
1257  for( size_t i = 0; i < m_Fields.size(); i++ )
1258  bbox.Merge( m_Fields[i].GetBoundingBox() );
1259 
1260  return bbox;
1261 }
1262 
1263 
1265 {
1266  wxString msg;
1267 
1268  // part and alias can differ if alias is not the root
1269  if( m_part )
1270  {
1271  if( m_part.get() != dummy() )
1272  {
1273  if( g_CurrentSheet )
1274  aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ),
1275  DARKCYAN ) );
1276 
1277  msg = m_part->IsPower() ? _( "Power symbol" ) : _( "Value" );
1278 
1279  aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetShownText(), DARKCYAN ) );
1280 
1281  // Display component reference in library and library
1282  aList.push_back( MSG_PANEL_ITEM( _( "Name" ), GetLibId().GetLibItemName(), BROWN ) );
1283 
1284  if( !m_part->IsRoot() )
1285  {
1286  msg = _( "Missing parent" );
1287 
1288  std::shared_ptr< LIB_PART > parent = m_part->GetParent().lock();
1289 
1290  if( parent )
1291  msg = parent->GetName();
1292 
1293  aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), msg, BROWN ) );
1294  }
1295 
1296  if( m_part->GetLib() && m_part->GetLib()->IsCache() )
1297  aList.push_back( MSG_PANEL_ITEM( _( "Library" ),
1298  m_part->GetLib()->GetLogicalName(), RED ) );
1299  else if( !m_lib_id.GetLibNickname().empty() )
1300  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname(),
1301  BROWN ) );
1302  else
1303  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Undefined!!!" ), RED ) );
1304 
1305  // Display the current associated footprint, if exists.
1306  if( !GetField( FOOTPRINT )->IsVoid() )
1307  msg = GetField( FOOTPRINT )->GetShownText();
1308  else
1309  msg = _( "<Unknown>" );
1310 
1311  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) );
1312 
1313  // Display description of the component, and keywords found in lib
1314  aList.push_back( MSG_PANEL_ITEM( _( "Description" ), m_part->GetDescription(),
1315  DARKCYAN ) );
1316  aList.push_back( MSG_PANEL_ITEM( _( "Key words" ), m_part->GetKeyWords(), DARKCYAN ) );
1317  }
1318  }
1319  else
1320  {
1321  if( g_CurrentSheet )
1322  aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ),
1323  DARKCYAN ) );
1324 
1325  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
1326  DARKCYAN ) );
1327  aList.push_back( MSG_PANEL_ITEM( _( "Name" ), GetLibId().GetLibItemName(), BROWN ) );
1328 
1329  wxString libNickname = GetLibId().GetLibNickname();
1330 
1331  if( libNickname.empty() )
1332  {
1333  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "No library defined!" ), RED ) );
1334  }
1335  else
1336  {
1337  msg.Printf( _( "Symbol not found in %s!" ), libNickname );
1338  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), msg , RED ) );
1339  }
1340  }
1341 }
1342 
1343 
1345 {
1346  return add_component_xpm;
1347 }
1348 
1349 
1350 void SCH_COMPONENT::MirrorY( int aYaxis_position )
1351 {
1352  int dx = m_Pos.x;
1353 
1355  MIRROR( m_Pos.x, aYaxis_position );
1356  dx -= m_Pos.x; // dx,0 is the move vector for this transform
1357 
1358  for( SCH_FIELD& field : m_Fields )
1359  {
1360  // Move the fields to the new position because the component itself has moved.
1361  wxPoint pos = field.GetTextPos();
1362  pos.x -= dx;
1363  field.SetTextPos( pos );
1364  }
1365 }
1366 
1367 
1368 void SCH_COMPONENT::MirrorX( int aXaxis_position )
1369 {
1370  int dy = m_Pos.y;
1371 
1373  MIRROR( m_Pos.y, aXaxis_position );
1374  dy -= m_Pos.y; // dy,0 is the move vector for this transform
1375 
1376  for( SCH_FIELD& field : m_Fields )
1377  {
1378  // Move the fields to the new position because the component itself has moved.
1379  wxPoint pos = field.GetTextPos();
1380  pos.y -= dy;
1381  field.SetTextPos( pos );
1382  }
1383 }
1384 
1385 
1387 {
1388  wxPoint prev = m_Pos;
1389 
1390  RotatePoint( &m_Pos, aPosition, 900 );
1391 
1393 
1394  for( SCH_FIELD& field : m_Fields )
1395  {
1396  // Move the fields to the new position because the component itself has moved.
1397  wxPoint pos = field.GetTextPos();
1398  pos.x -= prev.x - m_Pos.x;
1399  pos.y -= prev.y - m_Pos.y;
1400  field.SetTextPos( pos );
1401  }
1402 }
1403 
1404 
1405 bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData )
1406 {
1407  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
1408 
1409  // Components are searchable via the child field and pin item text.
1410  return false;
1411 }
1412 
1413 
1414 void SCH_COMPONENT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
1415 {
1416  if( m_part )
1417  {
1418  for( LIB_PIN* pin = m_part->GetNextPin(); pin; pin = m_part->GetNextPin( pin ) )
1419  {
1420  wxASSERT( pin->Type() == LIB_PIN_T );
1421 
1422  if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) )
1423  continue;
1424 
1425  if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) )
1426  continue;
1427 
1428  DANGLING_END_ITEM item( PIN_END, pin, GetPinPhysicalPosition( pin ), this );
1429  aItemList.push_back( item );
1430  }
1431  }
1432 }
1433 
1434 
1435 bool SCH_COMPONENT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
1436  const SCH_SHEET_PATH* aPath )
1437 {
1438  bool changed = false;
1439 
1440  for( auto& pin : m_pins )
1441  {
1442  bool previousState = pin->IsDangling();
1443  pin->SetIsDangling( true );
1444 
1445  wxPoint pos = m_transform.TransformCoordinate( pin->GetPosition() ) + m_Pos;
1446 
1447  for( DANGLING_END_ITEM& each_item : aItemList )
1448  {
1449  // Some people like to stack pins on top of each other in a symbol to indicate
1450  // internal connection. While technically connected, it is not particularly useful
1451  // to display them that way, so skip any pins that are in the same symbol as this
1452  // one.
1453  if( each_item.GetParent() == this )
1454  continue;
1455 
1456  switch( each_item.GetType() )
1457  {
1458  case PIN_END:
1459  case LABEL_END:
1460  case SHEET_LABEL_END:
1461  case WIRE_START_END:
1462  case WIRE_END_END:
1463  case NO_CONNECT_END:
1464  case JUNCTION_END:
1465 
1466  if( pos == each_item.GetPosition() )
1467  pin->SetIsDangling( false );
1468 
1469  break;
1470 
1471  default:
1472  break;
1473  }
1474 
1475  if( !pin->IsDangling() )
1476  break;
1477  }
1478 
1479  changed = ( changed || ( previousState != pin->IsDangling() ) );
1480  }
1481 
1482  return changed;
1483 }
1484 
1485 
1487 {
1488  wxCHECK_MSG( Pin != NULL && Pin->Type() == LIB_PIN_T, wxPoint( 0, 0 ),
1489  wxT( "Cannot get physical position of pin." ) );
1490 
1491  return m_transform.TransformCoordinate( Pin->GetPosition() ) + m_Pos;
1492 }
1493 
1494 
1495 void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
1496 {
1497  for( const auto& pin : m_pins )
1498  aPoints.push_back( m_transform.TransformCoordinate( pin->GetPosition() ) + m_Pos );
1499 }
1500 
1501 
1503 {
1504  UpdatePins();
1505 
1506  if( m_part )
1507  {
1508  // Calculate the position relative to the component.
1509  wxPoint libPosition = aPosition - m_Pos;
1510 
1511  return m_part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
1512  }
1513 
1514  return NULL;
1515 }
1516 
1517 
1519 {
1520  return wxString::Format( _( "Symbol %s, %s" ),
1521  GetLibId().GetLibItemName().wx_str(),
1522  GetField( REFERENCE )->GetShownText() );
1523 }
1524 
1525 
1526 SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR aInspector, void* aTestData,
1527  const KICAD_T aFilterTypes[] )
1528 {
1529  KICAD_T stype;
1530 
1531  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
1532  {
1533  // If caller wants to inspect component type or and component children types.
1534  if( stype == SCH_LOCATE_ANY_T || stype == Type() )
1535  {
1536  if( SEARCH_RESULT::QUIT == aInspector( this, aTestData ) )
1537  return SEARCH_RESULT::QUIT;
1538  }
1539 
1540  if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
1541  {
1542  // Test the bounding boxes of fields if they are visible and not empty.
1543  for( SCH_FIELD& field : m_Fields )
1544  {
1545  if( SEARCH_RESULT::QUIT == aInspector( &field, (void*) this ) )
1546  return SEARCH_RESULT::QUIT;
1547  }
1548  }
1549 
1550  if( stype == SCH_FIELD_LOCATE_REFERENCE_T )
1551  {
1552  if( SEARCH_RESULT::QUIT == aInspector( GetField( REFERENCE ), (void*) this ) )
1553  return SEARCH_RESULT::QUIT;
1554  }
1555 
1556  if( stype == SCH_FIELD_LOCATE_VALUE_T )
1557  {
1558  if( SEARCH_RESULT::QUIT == aInspector( GetField( VALUE ), (void*) this ) )
1559  return SEARCH_RESULT::QUIT;
1560  }
1561 
1562  if( stype == SCH_FIELD_LOCATE_FOOTPRINT_T )
1563  {
1564  if( SEARCH_RESULT::QUIT == aInspector( GetField( FOOTPRINT ), (void*) this ) )
1565  return SEARCH_RESULT::QUIT;
1566  }
1567 
1568  if( stype == SCH_FIELD_LOCATE_DATASHEET_T )
1569  {
1570  if( SEARCH_RESULT::QUIT == aInspector( GetField( DATASHEET ), (void*) this ) )
1571  return SEARCH_RESULT::QUIT;
1572  }
1573 
1574  if( stype == SCH_LOCATE_ANY_T || stype == SCH_PIN_T )
1575  {
1576  for( auto& pin : m_pins )
1577  {
1578  if( SEARCH_RESULT::QUIT == aInspector( pin.get(), (void*) this ) )
1579  return SEARCH_RESULT::QUIT;
1580  }
1581  }
1582  }
1583 
1584  return SEARCH_RESULT::CONTINUE;
1585 }
1586 
1587 
1589  SCH_SHEET_PATH* aSheetPath )
1590 {
1591  if( m_part )
1592  {
1593  for( LIB_PIN* pin = m_part->GetNextPin(); pin; pin = m_part->GetNextPin( pin ) )
1594  {
1595  wxASSERT( pin->Type() == LIB_PIN_T );
1596 
1597  if( pin->GetUnit() && ( pin->GetUnit() != GetUnitSelection( aSheetPath ) ) )
1598  continue;
1599 
1600  if( pin->GetConvert() && ( pin->GetConvert() != GetConvert() ) )
1601  continue;
1602 
1603  wxPoint pos = GetTransform().TransformCoordinate( pin->GetPosition() ) + m_Pos;
1604 
1605  NETLIST_OBJECT* item = new NETLIST_OBJECT();
1606  item->m_SheetPathInclude = *aSheetPath;
1607  item->m_Comp = m_pins[ m_pinMap.at( pin ) ].get();
1608  item->m_SheetPath = *aSheetPath;
1609  item->m_Type = NETLIST_ITEM::PIN;
1610  item->m_Link = (SCH_ITEM*) this;
1611  item->m_ElectricalPinType = pin->GetType();
1612  item->m_PinNum = pin->GetNumber();
1613  item->m_Label = pin->GetName();
1614  item->m_Start = item->m_End = pos;
1615 
1616  aNetListItems.push_back( item );
1617 
1618  if( pin->IsPowerConnection() )
1619  {
1620  // There is an associated PIN_LABEL.
1621  item = new NETLIST_OBJECT();
1622  item->m_SheetPathInclude = *aSheetPath;
1623  item->m_Comp = NULL;
1624  item->m_SheetPath = *aSheetPath;
1626  item->m_Label = pin->GetName();
1627  item->m_Start = pos;
1628  item->m_End = item->m_Start;
1629 
1630  aNetListItems.push_back( item );
1631  }
1632  }
1633  }
1634 }
1635 
1636 
1637 bool SCH_COMPONENT::operator <( const SCH_ITEM& aItem ) const
1638 {
1639  if( Type() != aItem.Type() )
1640  return Type() < aItem.Type();
1641 
1642  auto component = static_cast<const SCH_COMPONENT*>( &aItem );
1643 
1644  EDA_RECT rect = GetBodyBoundingBox();
1645 
1646  if( rect.GetArea() != component->GetBodyBoundingBox().GetArea() )
1647  return rect.GetArea() < component->GetBodyBoundingBox().GetArea();
1648 
1649  if( m_Pos.x != component->m_Pos.x )
1650  return m_Pos.x < component->m_Pos.x;
1651 
1652  if( m_Pos.y != component->m_Pos.y )
1653  return m_Pos.y < component->m_Pos.y;
1654 
1655  return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
1656 }
1657 
1658 
1659 bool SCH_COMPONENT::operator==( const SCH_COMPONENT& aComponent ) const
1660 {
1661  if( GetFieldCount() != aComponent.GetFieldCount() )
1662  return false;
1663 
1664  for( int i = VALUE; i < GetFieldCount(); i++ )
1665  {
1666  if( GetField( i )->GetText().Cmp( aComponent.GetField( i )->GetText() ) != 0 )
1667  return false;
1668  }
1669 
1670  return true;
1671 }
1672 
1673 
1674 bool SCH_COMPONENT::operator!=( const SCH_COMPONENT& aComponent ) const
1675 {
1676  return !( *this == aComponent );
1677 }
1678 
1679 
1681 {
1682  wxCHECK_MSG( Type() == aItem.Type(), *this,
1683  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1684  GetClass() );
1685 
1686  if( &aItem != this )
1687  {
1688  SCH_ITEM::operator=( aItem );
1689 
1690  SCH_COMPONENT* c = (SCH_COMPONENT*) &aItem;
1691 
1692  m_lib_id = c->m_lib_id;
1693 
1694  LIB_PART* libSymbol = c->m_part ? new LIB_PART( *c->m_part.get() ) : nullptr;
1695 
1696  m_part.reset( libSymbol );
1697  m_Pos = c->m_Pos;
1698  m_unit = c->m_unit;
1699  m_convert = c->m_convert;
1700  m_transform = c->m_transform;
1701 
1703 
1704  m_Fields = c->m_Fields; // std::vector's assignment operator
1705 
1706  // Reparent fields after assignment to new component.
1707  for( SCH_FIELD& field : m_Fields )
1708  field.SetParent( this );
1709 
1710  UpdatePins();
1711  }
1712 
1713  return *this;
1714 }
1715 
1716 
1717 bool SCH_COMPONENT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
1718 {
1719  EDA_RECT bBox = GetBodyBoundingBox();
1720  bBox.Inflate( aAccuracy );
1721 
1722  if( bBox.Contains( aPosition ) )
1723  return true;
1724 
1725  return false;
1726 }
1727 
1728 
1729 bool SCH_COMPONENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
1730 {
1732  return false;
1733 
1734  EDA_RECT rect = aRect;
1735 
1736  rect.Inflate( aAccuracy );
1737 
1738  if( aContained )
1739  return rect.Contains( GetBodyBoundingBox() );
1740 
1741  return rect.Intersects( GetBodyBoundingBox() );
1742 }
1743 
1744 
1745 bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const
1746 {
1747  wxPoint new_pos = m_transform.InverseTransform().TransformCoordinate( aPosition - m_Pos );
1748 
1749  for( const auto& pin : m_pins )
1750  {
1751  if( pin->GetPosition() == new_pos )
1752  return true;
1753  }
1754 
1755  return false;
1756 }
1757 
1758 
1760 {
1761  return m_isInNetlist;
1762 }
1763 
1764 
1765 void SCH_COMPONENT::Plot( PLOTTER* aPlotter )
1766 {
1767  TRANSFORM temp;
1768 
1769  if( m_part )
1770  {
1771  temp = GetTransform();
1772  aPlotter->StartBlock( nullptr );
1773 
1774  m_part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp );
1775 
1776  for( SCH_FIELD field : m_Fields )
1777  field.Plot( aPlotter );
1778 
1779  aPlotter->EndBlock( nullptr );
1780  }
1781 }
1782 
1783 
1785 {
1786  for( const auto& pin : m_pins )
1787  {
1788  if( pin->IsBrightened() )
1789  return true;
1790  }
1791 
1792  return false;
1793 }
1794 
1795 
1797 {
1798  for( auto& pin : m_pins )
1799  pin->ClearBrightened();
1800 }
1801 
1802 
1804 {
1805  if( m_pinMap.count( aPin ) )
1806  m_pins[ m_pinMap.at( aPin ) ]->SetBrightened();
1807 }
1808 
1809 
1811 {
1812  for( auto& pin : m_pins )
1813  pin->ClearHighlighted();
1814 }
1815 
1816 
1818 {
1819  for( const auto& pin : m_pins )
1820  {
1821  if( pin->IsHighlighted() )
1822  return true;
1823  }
1824 
1825  return false;
1826 }
1827 
1828 
1830 {
1831  if( m_pinMap.count( aPin ) )
1832  m_pins[ m_pinMap.at( aPin ) ]->SetHighlighted();
1833 }
1834 
1835 
1837 {
1838  bool retVal = false;
1839 
1840  if( IsHighlighted() )
1841  {
1843  retVal = true;
1844  }
1845 
1846  // Clear the HIGHLIGHTED flag of pins
1847  if( HasHighlightedPins() )
1848  {
1850  retVal = true;
1851  }
1852 
1853  // Clear the HIGHLIGHTED flag of other items, currently only fields
1854  for( SCH_FIELD& each_field : m_Fields )
1855  {
1856  if( each_field.IsHighlighted() )
1857  {
1858  each_field.ClearFlags( HIGHLIGHTED );
1859  retVal = true;
1860  }
1861  }
1862 
1863  return retVal;
1864 }
bool operator!=(const SCH_COMPONENT &aComponent) const
void UpdateFields(bool aResetStyle, bool aResetRef=false)
Restores fields to the original library values.
EDA_UNITS
Definition: common.h:184
void GetMsgPanelInfo(EDA_UNITS aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
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:52
SCH_LAYER_ID m_Layer
Definition: sch_item.h:152
std::vector< SCH_PIN * > SCH_PIN_PTRS
Definition: sch_component.h:73
void SetModified()
Definition: base_struct.cpp:94
void Rotate(wxPoint aPosition) override
Function Rotate rotates 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
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:183
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
name of datasheet
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
void SetTransform(const TRANSFORM &aTransform)
const wxChar *const traceSymbolResolver
Flag to enable debug output of symbol library resolver results.
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:497
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
void HighlightPin(LIB_PIN *aPin)
bool Matches(wxFindReplaceData &aSearchData, void *aAuxData) override
Function Matches compares the item against the search criteria in aSearchData.
SCH_PINS m_pins
a SCH_PIN for every LIB_PIN (across all units)
SCH_SHEET_PATH m_SheetPathInclude
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
SCH_FIELDS m_Fields
Variable length list of fields.
void ImportValues(const LIB_FIELD &aSource)
Function ImportValues copy parameters from a LIB_FIELD source.
Definition: sch_field.cpp:185
bool Resolve(PART_LIBS *aLibs)
Assigns the current LIB_PART from aLibs which this symbol is based on.
static bool sort_by_libid(const SCH_COMPONENT *ref, SCH_COMPONENT *cmp)
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:131
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
wxPoint m_Pos
Name and library where symbol was loaded from, i.e. "74xx:74LS00".
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
void Print(wxDC *aDC, const wxPoint &aOffset) override
Print a component.
void GetConnectionPoints(std::vector< wxPoint > &aPoints) const override
Function GetConnectionPoints add all the connection points for this item to aPoints.
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Function GetEndPoints adds the schematic item end points to aItemList if the item has end points.
std::unordered_map< LIB_PIN *, unsigned > SCH_PIN_MAP
A map from the library pin pointer to the SCH_PIN's index.
Definition: sch_component.h:76
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition: transform.cpp:59
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:231
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
Function MirrorX mirrors 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:488
void ClearBrightenedPins()
std::vector< COMPONENT_INSTANCE_REFERENCE > m_instanceReferences
LIB_PART * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_PART having aName from the library given by aNickname.
const BITMAP_OPAQUE add_component_xpm[1]
LIB_PIN * GetPin(const wxString &number)
Find a symbol pin by number.
int x1
Definition: transform.h:48
static const wxString GetDefaultFieldName(int aFieldNdx)
Function GetDefaultFieldName returns a default symbol field name for field aFieldNdx for all componen...
wxString GetDescription() const
Return information about the aliased parts.
Schematic editor (Eeschema) main window.
bool HasHighlightedPins()
SCH_SHEET_PATH m_SheetPath
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.
ELECTRICAL_PINTYPE m_ElectricalPinType
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
bool ClearAllHighlightFlags()
Clear the HIGHLIGHTED flag of all items of the component (fields, pins ...)
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
bool IsValid() const
Definition: lib_id.h:171
PROPERTIES is a name/value tuple with unique names and optional values.
Definition: properties.h:34
EDA_ITEM * m_Comp
Field Reference of part, i.e. "IC21".
bool IsHighlighted() const
Definition: base_struct.h:227
bool Contains(const wxPoint &aPoint) const
Function Contains.
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:154
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
Definition: colors.h:54
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:60
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.
NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected items in a...
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
void SetConvert(int aConvert)
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.
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:108
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:48
int y1
Definition: transform.h:49
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:123
#define VALUE
void SetLibId(const LIB_ID &aName, PART_LIBS *aLibs=NULL)
int GetUnit() const
void BrightenPin(LIB_PIN *aPin)
void Print(wxDC *aDc, const wxPoint &aOffset, int aMulti, int aConvert, const PART_DRAW_OPTIONS &aOpts)
Print part.
static void ResolveAll(std::vector< SCH_COMPONENT * > &aComponents, SYMBOL_LIB_TABLE &aLibTable, PART_LIB *aCacheLib=NULL)
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:111
#define NULL
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
bool m_isInNetlist
True if the component should appear in the netlist.
void SetHeight(int val)
Definition: eda_rect.h:186
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:218
TRANSFORM & GetTransform() const
Subclass of DIALOG_SCH_FIND_BASE, which is generated by wxFormBuilder.
EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the fields.
bool operator<(const SCH_ITEM &aItem) const override
wxString GetText(GRAPHIC_PINSHAPE aShape)
Definition: pin_shape.cpp:58
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.
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:129
void GetNetListItem(NETLIST_OBJECT_LIST &aNetListItems, SCH_SHEET_PATH *aSheetPath) override
Function GetNetListItem creates a new NETLIST_OBJECT for the schematic object and adds it to aNetList...
SCH_CONNECTION * GetConnectionForPin(LIB_PIN *aPin, const SCH_SHEET_PATH &aSheet)
Retrieves the connection for a given pin of the component.
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.
LIB_PART * FindLibPart(const LIB_ID &aLibId, const wxString &aLibraryName=wxEmptyString)
Search all libraries in the list for a part.
bool IsAnnotated(const SCH_SHEET_PATH *aSheet)
Checks if the component has a valid annotation (reference) for the given sheet path.
Definition: colors.h:60
static const char * PropNoDocFile
The property used internally by the plugin to disable writing the library documentation (....
void SetUnit(int aUnit)
Change the unit number to aUnit.
SCH_SHEET_PATH.
std::vector< SCH_FIELD * > GetFields()
Returns a vector of fields from the component.
std::unique_ptr< LIB_PART > m_part
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
static PART_DRAW_OPTIONS Default()
double GetArea() const
Function GetArea returns the area of the rectangle.
std::unique_ptr< LIB_PART > Flatten() const
Return a flattened symbol inheritance to the caller.
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear exiting component annotation.
void SetWidth(int val)
Definition: eda_rect.h:180
LIB_PART * FindPart(const wxString &aName) const
Find LIB_PART by aName.
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
int GetFieldCount() const
Return the number of fields in this symbol.
UTF8 Format() const
Definition: lib_id.cpp:237
SCH_CONNECTION * Connection(const SCH_SHEET_PATH &aPath) const
Retrieves the connection associated with this object in the given sheet Note: the returned value can ...
Definition: sch_item.cpp:128
void SetY(int val)
Definition: eda_rect.h:174
const KIID m_Uuid
Definition: base_struct.h:169
wxPoint GetPosition() const override
Definition: lib_pin.h:432
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
A collection of PART_LIB objects.
void Normalize()
Function Normalize ensures that the height ant width are positive.
int m_unit
The unit for multiple part per package components.
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:104
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
wxString GetFieldText(const wxString &aFieldName, SCH_EDIT_FRAME *aFrame) const
Search for a field named aFieldName and returns text associated with this field.
void GetPins(std::vector< LIB_PIN * > &aPinsList)
Populate a vector with all the pins from the library object.
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.
see class PGM_BASE
#define HIGHLIGHTED
item is drawn in normal colors, when the rest is darkened
Definition: base_struct.h:142
const wxChar *const traceFindItem
Flag to enable find debug tracing.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
#define _(s)
Definition: 3d_actions.cpp:33
SCH_PIN_MAP m_pinMap
the component's pins mapped by LIB_PIN*
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
bool HasBrightenedPins()
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:223
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:189
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)
SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:99
int GetY() const
Definition: eda_rect.h:112
void RemoveField(const wxString &aFieldName)
Removes a user field from the symbol.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:166
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:102
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.
virtual wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_item.h:174
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:258
void ClearHighlightedPins()
const wxPoint & GetTextPos() const
Definition: eda_text.h:232
T Convert(const wxString &aValue)
Function Convert converts a wxString to a generic type T.
Definition: eagle_parser.h:175
std::vector< std::pair< int, wxString > > Fields
Definition: sch_screen.h:78
int GetConvert() const
int m_convert
The alternate body style for components that have more than one body style defined.
DANGLING_END_ITEM is a helper class used to store the state of schematic items that can be connected ...
Definition: sch_item.h:76
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
virtual wxString GetShownText() const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:129
Definition for part library class.
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:53
SEARCH_RESULT
Definition: base_struct.h:54
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.
Definition of the NETLIST_OBJECT class.
Message panel definition file.
wxString m_prefix
C, R, U, Q etc - the first character which typically indicates what the component is.
const LIB_ID & GetLibId() const
NETLIST_ITEM m_Type
SCH_COMPONENT & operator=(const SCH_ITEM &aItem)
const EDA_RECT GetBodyBoundingBox(int aUnit, int aConvert) const
Get the symbol bounding box excluding fields.
SCH_ITEM * m_Link
wxPoint GetPinPhysicalPosition(const LIB_PIN *Pin) const
Object used to load, save, search, and otherwise manipulate symbol library files.
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
TRANSFORM m_transform
The rotation/mirror transformation matrix.
SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:123
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
SCH_PIN_PTRS GetSchPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieves a list of the SCH_PINs for the given sheet path.
bool doIsConnected(const wxPoint &aPosition) const override
Function doIsConnected provides the object specific test to see if it is connected to aPosition.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define NATIVE_FIELD_NAME
Definition: lib_field.h:125
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
bool empty() const
Definition: utf8.h:108
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
Definition: colors.h:62