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