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