KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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 <pgm_base.h>
33#include <sch_symbol.h>
34#include <sch_sheet_path.h>
35#include <schematic.h>
36#include <trace_helpers.h>
37#include <trigo.h>
38#include <refdes_utils.h>
39#include <wx/log.h>
41#include <sch_plotter.h>
42#include <string_utils.h>
43
44#include <utility>
45
46
47std::unordered_map<TRANSFORM, int> SCH_SYMBOL::s_transformToOrientationCache;
48
49
54std::string toUTFTildaText( const wxString& txt )
55{
56 std::string ret = TO_UTF8( txt );
57
58 for( std::string::iterator it = ret.begin(); it!=ret.end(); ++it )
59 {
60 if( (unsigned char) *it <= ' ' )
61 *it = '~';
62 }
63
64 return ret;
65}
66
67
74{
75 static LIB_SYMBOL* symbol;
76
77 if( !symbol )
78 {
79 symbol = new LIB_SYMBOL( wxEmptyString );
80
82
83 square->MoveTo( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
84 square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
85
86 LIB_TEXT* text = new LIB_TEXT( symbol );
87
88 text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
89 text->SetText( wxString( wxT( "??" ) ) );
90
91 symbol->AddDrawItem( square );
92 symbol->AddDrawItem( text );
93 }
94
95 return symbol;
96}
97
98
100 SCH_ITEM( nullptr, SCH_SYMBOL_T )
101{
102 m_DNP = false;
103 Init( VECTOR2I( 0, 0 ) );
104}
105
106
107SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
108 const SCH_SHEET_PATH* aSheet, int aUnit, int aBodyStyle,
109 const VECTOR2I& aPosition, EDA_ITEM* aParent ) :
110 SCH_ITEM( aParent, SCH_SYMBOL_T )
111{
112 Init( aPosition );
113
114 m_unit = aUnit;
115 m_bodyStyle = aBodyStyle;
116 m_lib_id = aLibId;
117
118 std::unique_ptr< LIB_SYMBOL > part;
119
120 part = aSymbol.Flatten();
121 part->SetParent();
122 SetLibSymbol( part.release() );
123
124 // Copy fields from the library symbol
125 UpdateFields( aSheet,
126 true, /* update style */
127 false, /* update ref */
128 false, /* update other fields */
129 true, /* reset ref */
130 true /* reset other fields */ );
131
132 m_prefix = UTIL::GetRefDesPrefix( m_part->GetReferenceField().GetText() );
133
134 if( aSheet )
136
137 // Inherit the include in bill of materials and board netlist settings from flattened
138 // library symbol.
139 m_excludedFromSim = m_part->GetExcludedFromSim();
140 m_excludedFromBOM = m_part->GetExcludedFromBOM();
141 m_excludedFromBoard = m_part->GetExcludedFromBoard();
142 m_DNP = false;
143
144}
145
146
147SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const SCH_SHEET_PATH* aSheet,
148 const PICKED_SYMBOL& aSel, const VECTOR2I& aPosition,
149 EDA_ITEM* aParent ) :
150 SCH_SYMBOL( aSymbol, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, aPosition, aParent )
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 if( i.first == REFERENCE_FIELD )
156 SetRef( aSheet, i.second );
157 else if( SCH_FIELD* field = GetFieldById( i.first ) )
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_bodyStyle = aSymbol.m_bodyStyle;
170 m_lib_id = aSymbol.m_lib_id;
175 m_DNP = aSymbol.m_DNP;
176
177 const_cast<KIID&>( m_Uuid ) = aSymbol.m_Uuid;
178
179 m_transform = aSymbol.m_transform;
180 m_prefix = aSymbol.m_prefix;
182 m_fields = aSymbol.m_fields;
183
184 // Re-parent the fields, which before this had aSymbol as parent
185 for( SCH_FIELD& field : m_fields )
186 field.SetParent( this );
187
188 m_pins.clear();
189
190 // Copy (and re-parent) the pins
191 for( const std::unique_ptr<SCH_PIN>& pin : aSymbol.m_pins )
192 {
193 m_pins.emplace_back( std::make_unique<SCH_PIN>( *pin ) );
194 m_pins.back()->SetParent( this );
195 }
196
197 if( aSymbol.m_part )
198 SetLibSymbol( new LIB_SYMBOL( *aSymbol.m_part ) );
199
202}
203
204
205void SCH_SYMBOL::Init( const VECTOR2I& pos )
206{
208 m_pos = pos;
209 m_unit = 1; // In multi unit chip - which unit to draw.
210 m_bodyStyle = LIB_ITEM::BODY_STYLE::BASE; // De Morgan Handling
211
212 // The rotation/mirror transformation matrix. pos normal
214
215 // construct only the mandatory fields, which are the first 4 only.
216 for( int i = 0; i < MANDATORY_FIELDS; ++i )
217 {
218 m_fields.emplace_back( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
219
220 if( i == REFERENCE_FIELD )
221 m_fields.back().SetLayer( LAYER_REFERENCEPART );
222 else if( i == VALUE_FIELD )
223 m_fields.back().SetLayer( LAYER_VALUEPART );
224 else
225 m_fields.back().SetLayer( LAYER_FIELDS );
226 }
227
228 m_prefix = wxString( wxT( "U" ) );
229 m_isInNetlist = true;
230 m_excludedFromSim = false;
231 m_excludedFromBOM = false;
232 m_excludedFromBoard = false;
233}
234
235
237{
238 return new SCH_SYMBOL( *this );
239}
240
241
243{
244 if( !m_part )
245 return true;
246
247 return false;
248}
249
250
251void SCH_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
252{
253 aCount = 8;
254 aLayers[0] = LAYER_DANGLING; // Pins are drawn by their parent symbol, so the parent
255 // symbol needs to draw to LAYER_DANGLING
256 aLayers[1] = LAYER_OP_CURRENTS; // Same for pin operating points
257 aLayers[2] = LAYER_DEVICE;
258 aLayers[3] = LAYER_REFERENCEPART;
259 aLayers[4] = LAYER_VALUEPART;
260 aLayers[5] = LAYER_FIELDS;
261 aLayers[6] = LAYER_DEVICE_BACKGROUND;
262 aLayers[7] = LAYER_SELECTION_SHADOWS;
263}
264
265
267{
268 // If a symbol's anchor is not grid-aligned to its pins then moving from the anchor is
269 // going to end up moving the symbol's pins off-grid.
270
271 // The minimal grid size allowed to place a pin is 25 mils
272 const int min_grid_size = schIUScale.MilsToIU( 25 );
273
274 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
275 {
276 if( ( ( pin->GetPosition().x - m_pos.x ) % min_grid_size ) != 0 )
277 return false;
278
279 if( ( ( pin->GetPosition().y - m_pos.y ) % min_grid_size ) != 0 )
280 return false;
281 }
282
283 return true;
284}
285
286
287void SCH_SYMBOL::SetLibId( const LIB_ID& aLibId )
288{
289 m_lib_id = aLibId;
290}
291
292
294{
295 if( !m_schLibSymbolName.IsEmpty() )
296 return m_schLibSymbolName;
297 else
298 return m_lib_id.Format();
299}
300
301
303{
304 wxCHECK2( ( aLibSymbol == nullptr ) || ( aLibSymbol->IsRoot() ), aLibSymbol = nullptr );
305
306 m_part.reset( aLibSymbol );
307 UpdatePins();
308}
309
310
312{
313 if( m_part )
314 return m_part->GetDescription();
315
316 return wxEmptyString;
317}
318
319
321{
322 if( m_part )
323 return m_part->GetKeyWords();
324
325 return wxEmptyString;
326}
327
328
330{
331 if( m_part )
332 return m_part->GetDatasheetField().GetText();
333
334 return wxEmptyString;
335}
336
337
339{
340 std::map<wxString, wxString> altPinMap;
341 std::map<wxString, std::set<SCH_PIN*>> pinUuidMap;
342 std::set<SCH_PIN*> unassignedSchPins;
343 std::set<LIB_PIN*> unassignedLibPins;
344
345 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
346 {
347 pinUuidMap[ pin->GetNumber() ].insert( pin.get() );
348
349 unassignedSchPins.insert( pin.get() );
350
351 if( !pin->GetAlt().IsEmpty() )
352 altPinMap[ pin->GetNumber() ] = pin->GetAlt();
353
354 pin->SetLibPin( nullptr );
355 }
356
357 m_pinMap.clear();
358
359 if( !m_part )
360 return;
361
362 std::vector<LIB_PIN*> pins = m_part->GetAllLibPins();
363
364 for( LIB_PIN* libPin : pins )
365 {
366 // NW: Don't filter by unit: this data-structure is used for all instances,
367 // some of which might have different units.
368 if( libPin->GetBodyStyle() && m_bodyStyle && m_bodyStyle != libPin->GetBodyStyle() )
369 continue;
370
371 SCH_PIN* pin = nullptr;
372
373 auto ii = pinUuidMap.find( libPin->GetNumber() );
374
375 if( ii == pinUuidMap.end() || ii->second.empty() )
376 {
377 unassignedLibPins.insert( libPin );
378 continue;
379 }
380
381 auto it = ii->second.begin();
382 pin = *it;
383 ii->second.erase( it );
384 pin->SetLibPin( libPin );
385 pin->SetPosition( libPin->GetPosition() );
386
387 unassignedSchPins.erase( pin );
388
389 auto iii = altPinMap.find( libPin->GetNumber() );
390
391 if( iii != altPinMap.end() )
392 pin->SetAlt( iii->second );
393
394 m_pinMap[ libPin ] = pin;
395 }
396
397 // Add any pins that were not found in the symbol
398 for( LIB_PIN* libPin : unassignedLibPins )
399 {
400 SCH_PIN* pin = nullptr;
401
402 // First try to re-use an existing pin
403 if( !unassignedSchPins.empty() )
404 {
405 auto it = unassignedSchPins.begin();
406 pin = *it;
407 unassignedSchPins.erase( it );
408 }
409 else
410 {
411 // This is a pin that was not found in the symbol, so create a new one.
412 pin = m_pins.emplace_back( std::make_unique<SCH_PIN>( SCH_PIN( libPin, this ) ) ).get();
413 }
414
415 m_pinMap[ libPin ] = pin;
416 pin->SetLibPin( libPin );
417 pin->SetPosition( libPin->GetPosition() );
418 pin->SetNumber( libPin->GetNumber() );
419
420 auto iii = altPinMap.find( libPin->GetNumber() );
421
422 if( iii != altPinMap.end() )
423 pin->SetAlt( iii->second );
424 }
425
426 // If we have any pins left in the symbol that were not found in the library, remove them.
427 for( auto it1 = m_pins.begin(); it1 != m_pins.end() && !unassignedSchPins.empty(); )
428 {
429 auto it2 = unassignedSchPins.find( it1->get() );
430
431 if( it2 != unassignedSchPins.end() )
432 {
433 it1 = m_pins.erase( it1 );
434 unassignedSchPins.erase( it2 );
435 }
436 else
437 {
438 ++it1;
439 }
440 }
441
442 // If the symbol is selected, then its pins are selected.
443 if( IsSelected() )
444 {
445 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
446 pin->SetSelected();
447 }
448
449}
450
451
452void SCH_SYMBOL::SetUnit( int aUnit )
453{
454 UpdateUnit( aUnit );
455}
456
457
458void SCH_SYMBOL::UpdateUnit( int aUnit )
459{
460 m_unit = aUnit;
461}
462
463
464void SCH_SYMBOL::SetBodyStyle( int aBodyStyle )
465{
466 if( m_bodyStyle != aBodyStyle )
467 {
468 m_bodyStyle = aBodyStyle;
469
470 // The convert may have a different pin layout so the update the pin map.
471 UpdatePins();
472 }
473}
474
475
476void SCH_SYMBOL::SetTransform( const TRANSFORM& aTransform )
477{
478 if( m_transform != aTransform )
479 m_transform = aTransform;
480}
481
482
484{
485 if( m_part )
486 return m_part->GetUnitCount();
487
488 return 0;
489}
490
491
493{
494 wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), SubReference( aUnit ) ) ) );
495
496 return m_part->GetUnitDisplayName( aUnit );
497}
498
499
501{
502 wxCHECK( m_part, false );
503
504 return m_part->HasUnitDisplayName( aUnit );
505}
506
507
508void SCH_SYMBOL::PrintBackground( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset )
509{
511 opts.transform = m_transform;
512 opts.draw_visible_fields = false;
513 opts.draw_hidden_fields = false;
514
515 if( m_part )
516 m_part->PrintBackground( aSettings, m_pos + aOffset, m_unit, m_bodyStyle, opts, GetDNP() );
517}
518
519
520void SCH_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset )
521{
523 opts.transform = m_transform;
524 opts.draw_visible_fields = false;
525 opts.draw_hidden_fields = false;
526
527 if( m_part )
528 {
529 LIB_PINS libPins;
530 m_part->GetPins( libPins, m_unit, m_bodyStyle );
531
532 LIB_SYMBOL tempSymbol( *m_part );
533 LIB_PINS tempPins;
534 tempSymbol.GetPins( tempPins, m_unit, m_bodyStyle );
535
536 // Copy the pin info from the symbol to the temp pins
537 for( unsigned i = 0; i < tempPins.size(); ++ i )
538 {
539 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
540 LIB_PIN* tempPin = tempPins[ i ];
541
542 tempPin->SetName( symbolPin->GetShownName() );
543 tempPin->SetType( symbolPin->GetType() );
544 tempPin->SetShape( symbolPin->GetShape() );
545 }
546
547 for( LIB_ITEM& item : tempSymbol.GetDrawItems() )
548 {
549 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
550 {
551 // Use SCH_FIELD's text resolver
552 SCH_FIELD dummy( (SCH_ITEM*) this, -1 );
553 dummy.SetText( text->GetText() );
554 text->SetText( dummy.GetShownText( false ) );
555 }
556 }
557
558 tempSymbol.Print( aSettings, m_pos + aOffset, m_unit, m_bodyStyle, opts, GetDNP() );
559 }
560 else // Use dummy() part if the actual cannot be found.
561 {
562 dummy()->Print( aSettings, m_pos + aOffset, 0, 0, opts, GetDNP() );
563 }
564
565 for( SCH_FIELD& field : m_fields )
566 field.Print( aSettings, aOffset );
567
568 if( m_DNP )
569 {
571 wxDC* DC = aSettings->GetPrintDC();
572 COLOR4D dnp_color = aSettings->GetLayerColor( LAYER_DNP_MARKER );
573
574 GRFilledSegment( DC, bbox.GetOrigin(), bbox.GetEnd(),
576 dnp_color );
577
578 GRFilledSegment( DC, bbox.GetOrigin() + VECTOR2I( bbox.GetWidth(), 0 ),
579 bbox.GetOrigin() + VECTOR2I( 0, bbox.GetHeight() ),
581 dnp_color );
582 }
583}
584
585
587 const KIID_PATH& aSheetPath, bool aTestFromEnd ) const
588{
589 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
590 {
591 if( !aTestFromEnd )
592 {
593 if( instance.m_Path == aSheetPath )
594 {
595 aInstance = instance;
596 return true;
597 }
598 }
599 else if( instance.m_Path.EndsWith( aSheetPath ) )
600 {
601 aInstance = instance;
602 return true;
603 }
604 }
605
606 return false;
607}
608
609
610void SCH_SYMBOL::RemoveInstance( const SCH_SHEET_PATH& aInstancePath )
611{
612 RemoveInstance( aInstancePath.Path() );
613}
614
615
616void SCH_SYMBOL::RemoveInstance( const KIID_PATH& aInstancePath )
617{
618 // Search for an existing path and remove it if found (should not occur)
619 for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
620 {
621 if( m_instanceReferences[ii].m_Path == aInstancePath )
622 {
623 wxLogTrace( traceSchSheetPaths, "Removing symbol instance:\n"
624 " sheet path %s\n"
625 " reference %s, unit %d from symbol %s.",
626 aInstancePath.AsString(),
627 m_instanceReferences[ii].m_Reference,
628 m_instanceReferences[ii].m_Unit,
629 m_Uuid.AsString() );
630
631 m_instanceReferences.erase( m_instanceReferences.begin() + ii );
632 ii--;
633 }
634 }
635}
636
637
638void SCH_SYMBOL::SortInstances( bool (*aSortFunction)( const SCH_SYMBOL_INSTANCE& aLhs,
639 const SCH_SYMBOL_INSTANCE& aRhs ) )
640{
641 if( m_instanceReferences.size() > 1 )
642 std::sort( m_instanceReferences.begin(), m_instanceReferences.end(), aSortFunction );
643}
644
645
646void SCH_SYMBOL::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef, int aUnit )
647{
648 // Search for an existing path and remove it if found (should not occur)
649 for( unsigned ii = 0; ii < m_instanceReferences.size(); ii++ )
650 {
651 if( m_instanceReferences[ii].m_Path == aPath )
652 {
653 wxLogTrace( traceSchSheetPaths, "Removing symbol instance:\n"
654 " sheet path %s\n"
655 " reference %s, unit %d from symbol %s.",
656 aPath.AsString(),
657 m_instanceReferences[ii].m_Reference,
658 m_instanceReferences[ii].m_Unit,
659 m_Uuid.AsString() );
660
661 m_instanceReferences.erase( m_instanceReferences.begin() + ii );
662 ii--;
663 }
664 }
665
666 SCH_SYMBOL_INSTANCE instance;
667 instance.m_Path = aPath;
668 instance.m_Reference = aRef;
669 instance.m_Unit = aUnit;
670
671 wxLogTrace( traceSchSheetPaths,
672 "Adding symbol '%s' instance:\n"
673 " sheet path '%s'\n"
674 " reference '%s'\n"
675 " unit %d\n",
677 aPath.AsString(),
678 aRef,
679 aUnit );
680
681 m_instanceReferences.push_back( instance );
682
683 // This should set the default instance to the first saved instance data for each symbol
684 // when importing sheets.
685 if( m_instanceReferences.size() == 1 )
686 {
687 m_fields[ REFERENCE_FIELD ].SetText( aRef );
688 m_unit = aUnit;
689 }
690}
691
692
694{
695 KIID_PATH searchPath( aInstance.m_Path );
696
697 std::vector<SCH_SYMBOL_INSTANCE>::iterator resultIt;
698
699 do
700 {
701 resultIt = std::find_if( m_instanceReferences.begin(), m_instanceReferences.end(),
702 [searchPath]( const auto& it )
703 {
704 return it.m_Path == searchPath;
705 } );
706
707 if( resultIt != m_instanceReferences.end() )
708 {
709 wxLogTrace( traceSchSheetPaths, "Removing symbol instance:\n"
710 " sheet path %s\n"
711 " reference %s, unit %d from symbol %s.",
712 aInstance.m_Path.AsString(),
713 resultIt->m_Reference,
714 resultIt->m_Unit,
715 m_Uuid.AsString() );
716
717 // Instance data should be unique by path. Double check just in case there was
718 // some buggy code in the past.
719 resultIt = m_instanceReferences.erase( resultIt );
720 }
721 }
722 while( resultIt != m_instanceReferences.end() );
723
724 SCH_SYMBOL_INSTANCE instance = aInstance;
725
726 wxLogTrace( traceSchSheetPaths,
727 "Adding symbol '%s' instance:\n"
728 " sheet path '%s'\n"
729 " reference '%s'\n"
730 " unit %d\n",
732 instance.m_Path.AsString(),
733 instance.m_Reference,
734 instance.m_Unit );
735
736 m_instanceReferences.push_back( instance );
737
738 // This should set the default instance to the first saved instance data for each symbol
739 // when importing sheets.
740 if( m_instanceReferences.size() == 1 )
741 {
742 m_fields[ REFERENCE_FIELD ].SetText( instance.m_Reference );
743 m_unit = instance.m_Unit;
744 }
745}
746
747
748const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit ) const
749{
750 KIID_PATH path = sheet->Path();
751 wxString ref;
752 wxString subRef;
753
754 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
755 {
756 if( instance.m_Path == path )
757 {
758 ref = instance.m_Reference;
759 subRef = SubReference( instance.m_Unit );
760 break;
761 }
762 }
763
764 // If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
765 // use this as a default for this path. This will happen if we load a version 1 schematic
766 // file. It will also mean that multiple instances of the same sheet by default all have
767 // the same symbol references, but perhaps this is best.
768 if( ref.IsEmpty() && !GetField( REFERENCE_FIELD )->GetText().IsEmpty() )
769 {
770 const_cast<SCH_SYMBOL*>( this )->SetRef( sheet, GetField( REFERENCE_FIELD )->GetText() );
771 ref = GetField( REFERENCE_FIELD )->GetText();
772 }
773
774 if( ref.IsEmpty() )
776
777 if( aIncludeUnit && GetUnitCount() > 1 )
778 ref += subRef;
779
780 return ref;
781}
782
783
784bool SCH_SYMBOL::IsReferenceStringValid( const wxString& aReferenceString )
785{
786 return !UTIL::GetRefDesPrefix( aReferenceString ).IsEmpty();
787}
788
789
790void SCH_SYMBOL::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
791{
792 KIID_PATH path = sheet->Path();
793 bool found = false;
794
795 // check to see if it is already there before inserting it
797 {
798 if( instance.m_Path == path )
799 {
800 found = true;
801 instance.m_Reference = ref;
802 break;
803 }
804 }
805
806 if( !found )
808
809 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
810 pin->ClearDefaultNetName( sheet );
811
812 if( Schematic() && *sheet == Schematic()->CurrentSheet() )
813 m_fields[ REFERENCE_FIELD ].SetText( ref );
814
815 // Reinit the m_prefix member if needed
817
818 if( m_prefix.IsEmpty() )
819 m_prefix = wxT( "U" );
820
821 // Power symbols have references starting with # and are not included in netlists
822 m_isInNetlist = ! ref.StartsWith( wxT( "#" ) );
823}
824
825
827{
828 KIID_PATH path = aSheet->Path();
829
830 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
831 {
832 if( instance.m_Path == path )
833 return instance.m_Reference.Last() != '?';
834 }
835
836 return false;
837}
838
839
841{
842 wxString refDesignator = GetField( REFERENCE_FIELD )->GetText();
843
844 refDesignator.Replace( "~", " " );
845
846 wxString prefix = refDesignator;
847
848 while( prefix.Length() )
849 {
850 wxUniCharRef last = prefix.Last();
851
852 if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
853 prefix.RemoveLast();
854 else
855 break;
856 }
857
858 // Avoid a prefix containing trailing/leading spaces
859 prefix.Trim( true );
860 prefix.Trim( false );
861
862 if( !prefix.IsEmpty() )
863 SetPrefix( prefix );
864}
865
866
867wxString SCH_SYMBOL::SubReference( int aUnit, bool aAddSeparator ) const
868{
869 if( SCHEMATIC* schematic = Schematic() )
870 return schematic->Settings().SubReference( aUnit, aAddSeparator );
871
872 return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
873}
874
875
877{
878 KIID_PATH path = aSheet->Path();
879
880 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
881 {
882 if( instance.m_Path == path )
883 return instance.m_Unit;
884 }
885
886 // If it was not found in m_Paths array, then use m_unit. This will happen if we load a
887 // version 1 schematic file.
888 return m_unit;
889}
890
891
892void SCH_SYMBOL::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
893{
894 KIID_PATH path = aSheet->Path();
895
896 // check to see if it is already there before inserting it
898 {
899 if( instance.m_Path == path )
900 {
901 instance.m_Unit = aUnitSelection;
902 return;
903 }
904 }
905
906 // didn't find it; better add it
908}
909
910
911void SCH_SYMBOL::SetUnitSelection( int aUnitSelection )
912{
914 instance.m_Unit = aUnitSelection;
915}
916
917
918const wxString SCH_SYMBOL::GetValueFieldText( bool aResolve, const SCH_SHEET_PATH* aPath,
919 bool aAllowExtraText ) const
920{
921 if( aResolve )
922 return GetField( VALUE_FIELD )->GetShownText( aPath, aAllowExtraText );
923
924 return GetField( VALUE_FIELD )->GetText();
925}
926
927
928void SCH_SYMBOL::SetValueFieldText( const wxString& aValue )
929{
930 m_fields[ VALUE_FIELD ].SetText( aValue );
931}
932
933
934const wxString SCH_SYMBOL::GetFootprintFieldText( bool aResolve, const SCH_SHEET_PATH* aPath,
935 bool aAllowExtraText ) const
936{
937 if( aResolve )
938 return GetField( FOOTPRINT_FIELD )->GetShownText( aPath, aAllowExtraText );
939
940 return GetField( FOOTPRINT_FIELD )->GetText();
941}
942
943
944void SCH_SYMBOL::SetFootprintFieldText( const wxString& aFootprint )
945{
946 m_fields[ FOOTPRINT_FIELD ].SetText( aFootprint );
947}
948
949
951{
952 return &m_fields[aFieldType];
953}
954
955
957{
958 return &m_fields[aFieldType];
959}
960
961
963{
964 for( size_t ii = 0; ii < m_fields.size(); ++ii )
965 {
966 if( m_fields[ii].GetId() == aFieldId )
967 return &m_fields[ii];
968 }
969
970 return nullptr;
971}
972
973
974SCH_FIELD* SCH_SYMBOL::GetFieldByName( const wxString& aFieldName )
975{
976 for( SCH_FIELD& field : m_fields )
977 {
978 if( field.GetName() == aFieldName )
979 return &field;
980 }
981
982 return nullptr;
983}
984
985
986const SCH_FIELD* SCH_SYMBOL::GetFieldByName( const wxString& aFieldName ) const
987{
988 for( const SCH_FIELD& field : m_fields )
989 {
990 if( field.GetName() == aFieldName )
991 return &field;
992 }
993
994 return nullptr;
995}
996
997
998void SCH_SYMBOL::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
999{
1000 for( SCH_FIELD& field : m_fields )
1001 {
1002 if( aVisibleOnly )
1003 {
1004 if( !field.IsVisible() || field.GetText().IsEmpty() )
1005 continue;
1006 }
1007
1008 aVector.push_back( &field );
1009 }
1010}
1011
1012
1014{
1015 m_fields.push_back( aField );
1016 return &m_fields.back();
1017}
1018
1019
1020void SCH_SYMBOL::RemoveField( const wxString& aFieldName )
1021{
1022 for( unsigned i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
1023 {
1024 if( aFieldName == m_fields[i].GetName( false ) )
1025 {
1026 m_fields.erase( m_fields.begin() + i );
1027 return;
1028 }
1029 }
1030}
1031
1032
1033SCH_FIELD* SCH_SYMBOL::FindField( const wxString& aFieldName, bool aIncludeDefaultFields,
1034 bool aCaseInsensitive )
1035{
1036 unsigned start = aIncludeDefaultFields ? 0 : MANDATORY_FIELDS;
1037
1038 for( unsigned i = start; i < m_fields.size(); ++i )
1039 {
1040 if( aCaseInsensitive )
1041 {
1042 if( aFieldName.Upper() == m_fields[i].GetName( false ).Upper() )
1043 return &m_fields[i];
1044 }
1045 else
1046 {
1047 if( aFieldName == m_fields[i].GetName( false ) )
1048 return &m_fields[i];
1049 }
1050 }
1051
1052 return nullptr;
1053}
1054
1055
1056void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef,
1057 bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields )
1058{
1059 if( m_part )
1060 {
1061 std::vector<LIB_FIELD*> fields;
1062
1063 m_part->GetFields( fields );
1064
1065 for( const LIB_FIELD* libField : fields )
1066 {
1067 int id = libField->GetId();
1068 SCH_FIELD* schField;
1069
1070 if( id >= 0 && id < MANDATORY_FIELDS )
1071 {
1072 schField = GetFieldById( id );
1073 }
1074 else
1075 {
1076 schField = FindField( libField->GetCanonicalName() );
1077
1078 if( !schField )
1079 {
1080 wxString fieldName = libField->GetCanonicalName();
1081 SCH_FIELD newField( VECTOR2I( 0, 0 ), GetFieldCount(), this, fieldName );
1082 schField = AddField( newField );
1083 }
1084 }
1085
1086 if( aUpdateStyle )
1087 {
1088 schField->ImportValues( *libField );
1089 schField->SetTextPos( m_pos + libField->GetTextPos() );
1090 }
1091
1092 if( id == REFERENCE_FIELD && aPath )
1093 {
1094 if( aResetRef )
1095 SetRef( aPath, m_part->GetReferenceField().GetText() );
1096 else if( aUpdateRef )
1097 SetRef( aPath, libField->GetText() );
1098 }
1099 else if( id == VALUE_FIELD )
1100 {
1101 SetValueFieldText( UnescapeString( libField->GetText() ) );
1102 }
1103 else if( id == FOOTPRINT_FIELD )
1104 {
1105 if( aResetOtherFields || aUpdateOtherFields )
1106 SetFootprintFieldText( libField->GetText() );
1107 }
1108 else if( id == DATASHEET_FIELD )
1109 {
1110 if( aResetOtherFields )
1111 schField->SetText( GetDatasheet() ); // alias-specific value
1112 else if( aUpdateOtherFields )
1113 schField->SetText( libField->GetText() );
1114 }
1115 else
1116 {
1117 if( aResetOtherFields || aUpdateOtherFields )
1118 schField->SetText( libField->GetText() );
1119 }
1120 }
1121 }
1122}
1123
1124
1125void SCH_SYMBOL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
1126{
1127 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1128 aFunction( pin.get() );
1129
1130 for( SCH_FIELD& field : m_fields )
1131 aFunction( &field );
1132}
1133
1134
1135SCH_PIN* SCH_SYMBOL::GetPin( const wxString& aNumber ) const
1136{
1137 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1138 {
1139 if( pin->GetNumber() == aNumber )
1140 return pin.get();
1141 }
1142
1143 return nullptr;
1144}
1145
1146
1147void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
1148{
1149 if( m_part )
1150 m_part->GetPins( aPinsList, m_unit, m_bodyStyle );
1151}
1152
1153
1154std::vector<LIB_PIN*> SCH_SYMBOL::GetAllLibPins() const
1155{
1156 std::vector<LIB_PIN*> pinList;
1157
1158 if( m_part )
1159 m_part->GetPins( pinList, 0, 0 );
1160
1161 return pinList;
1162}
1163
1164
1166{
1167 auto it = m_pinMap.find( aLibPin );
1168
1169 if( it != m_pinMap.end() )
1170 return it->second;
1171
1172 wxFAIL_MSG_AT( "Pin not found", __FILE__, __LINE__, __FUNCTION__ );
1173 return nullptr;
1174}
1175
1176
1177std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
1178{
1179 std::vector<SCH_PIN*> pins;
1180
1181 if( aSheet == nullptr )
1182 {
1183 wxCHECK_MSG( Schematic(), pins, "Can't call GetPins on a symbol with no schematic" );
1184
1185 aSheet = &Schematic()->CurrentSheet();
1186 }
1187
1188 int unit = GetUnitSelection( aSheet );
1189
1190 for( const std::unique_ptr<SCH_PIN>& p : m_pins )
1191 {
1192 if( unit && p->GetLibPin() && p->GetLibPin()->GetUnit()
1193 && ( p->GetLibPin()->GetUnit() != unit ) )
1194 {
1195 continue;
1196 }
1197
1198 pins.push_back( p.get() );
1199 }
1200
1201 return pins;
1202}
1203
1204
1206{
1207 SCH_ITEM::SwapFlags( aItem );
1208
1209 wxCHECK_RET( aItem != nullptr && aItem->Type() == SCH_SYMBOL_T,
1210 wxT( "Cannot swap data with invalid symbol." ) );
1211
1212 SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
1213
1214 std::swap( m_lib_id, symbol->m_lib_id );
1215
1216 m_pins.swap( symbol->m_pins ); // std::vector's swap()
1217
1218 for( std::unique_ptr<SCH_PIN>& pin : symbol->m_pins )
1219 pin->SetParent( symbol );
1220
1221 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1222 pin->SetParent( this );
1223
1224 LIB_SYMBOL* libSymbol = symbol->m_part.release();
1225 symbol->m_part = std::move( m_part );
1226 symbol->UpdatePins();
1227 m_part.reset( libSymbol );
1228 UpdatePins();
1229
1230 std::swap( m_pos, symbol->m_pos );
1231 std::swap( m_unit, symbol->m_unit );
1232 std::swap( m_bodyStyle, symbol->m_bodyStyle );
1233
1234 m_fields.swap( symbol->m_fields ); // std::vector's swap()
1235
1236 for( SCH_FIELD& field : symbol->m_fields )
1237 field.SetParent( symbol );
1238
1239 for( SCH_FIELD& field : m_fields )
1240 field.SetParent( this );
1241
1242 TRANSFORM tmp = m_transform;
1243
1244 m_transform = symbol->m_transform;
1245 symbol->m_transform = tmp;
1246
1247 std::swap( m_excludedFromSim, symbol->m_excludedFromSim );
1248 std::swap( m_excludedFromBOM, symbol->m_excludedFromBOM );
1249 std::swap( m_DNP, symbol->m_DNP );
1250 std::swap( m_excludedFromBoard, symbol->m_excludedFromBoard );
1251
1252 std::swap( m_instanceReferences, symbol->m_instanceReferences );
1253 std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName );
1254}
1255
1256
1257void SCH_SYMBOL::GetContextualTextVars( wxArrayString* aVars ) const
1258{
1259 for( int i = 0; i < MANDATORY_FIELDS; ++i )
1260 aVars->push_back( m_fields[i].GetCanonicalName().Upper() );
1261
1262 for( size_t i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
1263 aVars->push_back( m_fields[i].GetName() );
1264
1265 aVars->push_back( wxT( "OP" ) );
1266 aVars->push_back( wxT( "FOOTPRINT_LIBRARY" ) );
1267 aVars->push_back( wxT( "FOOTPRINT_NAME" ) );
1268 aVars->push_back( wxT( "UNIT" ) );
1269 aVars->push_back( wxT( "SYMBOL_LIBRARY" ) );
1270 aVars->push_back( wxT( "SYMBOL_NAME" ) );
1271 aVars->push_back( wxT( "SYMBOL_DESCRIPTION" ) );
1272 aVars->push_back( wxT( "SYMBOL_KEYWORDS" ) );
1273 aVars->push_back( wxT( "EXCLUDE_FROM_BOM" ) );
1274 aVars->push_back( wxT( "EXCLUDE_FROM_BOARD" ) );
1275 aVars->push_back( wxT( "EXCLUDE_FROM_SIM" ) );
1276 aVars->push_back( wxT( "DNP" ) );
1277 aVars->push_back( wxT( "SHORT_NET_NAME(<pin_number>)" ) );
1278 aVars->push_back( wxT( "NET_NAME(<pin_number>)" ) );
1279 aVars->push_back( wxT( "NET_CLASS(<pin_number>)" ) );
1280 aVars->push_back( wxT( "PIN_NAME(<pin_number>)" ) );
1281}
1282
1283
1284bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
1285{
1286 static wxRegEx operatingPoint( wxT( "^"
1287 "OP"
1288 "(:[a-zA-Z]*)?" // port
1289 "(.([0-9])?([a-zA-Z]*))?" // format
1290 "$" ) );
1291
1292 wxCHECK( aPath, false );
1293
1294 SCHEMATIC* schematic = Schematic();
1295
1296 if( !schematic )
1297 return false;
1298
1299 if( operatingPoint.Matches( *token ) )
1300 {
1301 wxString port( operatingPoint.GetMatch( *token, 1 ) );
1302 wxString precisionStr( operatingPoint.GetMatch( *token, 3 ) );
1303 wxString range( operatingPoint.GetMatch( *token, 4 ) );
1304
1305 wxString signal = GetRef( aPath ) + port;
1306 int precision = 3;
1307
1308 if( !precisionStr.IsEmpty() )
1309 precision = precisionStr[0] - '0';
1310
1311 if( range.IsEmpty() )
1312 {
1313 if( port == wxS( ":power" ) )
1314 range = wxS( "~W" );
1315 else
1316 range = wxS( "~A" );
1317 }
1318
1319 *token = schematic->GetOperatingPoint( signal.Lower(), precision, range );
1320
1321 return true;
1322 }
1323
1324 if( token->Contains( ':' ) )
1325 {
1326 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
1327 return true;
1328 }
1329
1330 for( int i = 0; i < MANDATORY_FIELDS; ++i )
1331 {
1332 if( token->IsSameAs( m_fields[ i ].GetCanonicalName().Upper() ) )
1333 {
1334 if( i == REFERENCE_FIELD )
1335 *token = GetRef( aPath, true );
1336 else
1337 *token = m_fields[ i ].GetShownText( aPath, false, aDepth + 1 );
1338
1339 return true;
1340 }
1341 }
1342
1343 for( size_t i = MANDATORY_FIELDS; i < m_fields.size(); ++i )
1344 {
1345 if( token->IsSameAs( m_fields[ i ].GetName() )
1346 || token->IsSameAs( m_fields[ i ].GetName().Upper() ) )
1347 {
1348 *token = m_fields[ i ].GetShownText( aPath, false, aDepth + 1 );
1349 return true;
1350 }
1351 }
1352
1353 // Consider missing simulation fields as empty, not un-resolved
1354 if( token->IsSameAs( wxT( "SIM.DEVICE" ) )
1355 || token->IsSameAs( wxT( "SIM.TYPE" ) )
1356 || token->IsSameAs( wxT( "SIM.PINS" ) )
1357 || token->IsSameAs( wxT( "SIM.PARAMS" ) )
1358 || token->IsSameAs( wxT( "SIM.LIBRARY" ) )
1359 || token->IsSameAs( wxT( "SIM.NAME" ) ) )
1360 {
1361 *token = wxEmptyString;
1362 return true;
1363 }
1364
1365 for( const TEMPLATE_FIELDNAME& templateFieldname :
1367 {
1368 if( token->IsSameAs( templateFieldname.m_Name )
1369 || token->IsSameAs( templateFieldname.m_Name.Upper() ) )
1370 {
1371 // If we didn't find it in the fields list then it isn't set on this symbol.
1372 // Just return an empty string.
1373 *token = wxEmptyString;
1374 return true;
1375 }
1376 }
1377
1378 if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
1379 {
1380 wxString footprint = GetFootprintFieldText( true, aPath, false );
1381
1382 wxArrayString parts = wxSplit( footprint, ':' );
1383
1384 if( parts.Count() > 0 )
1385 *token = parts[ 0 ];
1386 else
1387 *token = wxEmptyString;
1388
1389 return true;
1390 }
1391 else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
1392 {
1393 wxString footprint = GetFootprintFieldText( true, aPath, false );
1394
1395 wxArrayString parts = wxSplit( footprint, ':' );
1396
1397 if( parts.Count() > 1 )
1398 *token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
1399 else
1400 *token = wxEmptyString;
1401
1402 return true;
1403 }
1404 else if( token->IsSameAs( wxT( "UNIT" ) ) )
1405 {
1406 *token = SubReference( GetUnitSelection( aPath ) );
1407 return true;
1408 }
1409 else if( token->IsSameAs( wxT( "SYMBOL_LIBRARY" ) ) )
1410 {
1412 return true;
1413 }
1414 else if( token->IsSameAs( wxT( "SYMBOL_NAME" ) ) )
1415 {
1417 return true;
1418 }
1419 else if( token->IsSameAs( wxT( "SYMBOL_DESCRIPTION" ) ) )
1420 {
1421 *token = GetDescription();
1422 return true;
1423 }
1424 else if( token->IsSameAs( wxT( "SYMBOL_KEYWORDS" ) ) )
1425 {
1426 *token = GetKeyWords();
1427 return true;
1428 }
1429 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
1430 {
1431 *token = this->GetExcludedFromBOM() ? _( "Excluded from BOM" )
1432 : wxString( wxT( "" ) );
1433 return true;
1434 }
1435 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
1436 {
1437 *token = this->GetExcludedFromBoard() ? _( "Excluded from board" )
1438 : wxString( wxT( "" ) );
1439 return true;
1440 }
1441 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
1442 {
1443 *token = this->GetExcludedFromSim() ? _( "Excluded from simulation" )
1444 : wxString( wxT( "" ) );
1445 return true;
1446 }
1447 else if( token->IsSameAs( wxT( "DNP" ) ) )
1448 {
1449 *token = this->GetDNP() ? _( "DNP" ) : wxString( wxT( "" ) );
1450 return true;
1451 }
1452 else if( token->StartsWith( wxT( "SHORT_NET_NAME(" ) )
1453 || token->StartsWith( wxT( "NET_NAME(" ) )
1454 || token->StartsWith( wxT( "NET_CLASS(" ) )
1455 || token->StartsWith( wxT( "PIN_NAME(" ) ) )
1456 {
1457 wxString pinNumber = token->AfterFirst( '(' );
1458 pinNumber = pinNumber.BeforeLast( ')' );
1459
1460 for( SCH_PIN* pin : GetPins( aPath ) )
1461 {
1462 if( pin->GetNumber() == pinNumber )
1463 {
1464 if( token->StartsWith( wxT( "PIN_NAME" ) ) )
1465 {
1466 *token = pin->GetAlt().IsEmpty() ? pin->GetName() : pin->GetAlt();
1467 return true;
1468 }
1469
1470 SCH_CONNECTION* conn = pin->Connection( aPath );
1471
1472 if( !conn )
1473 *token = wxEmptyString;
1474 else if( token->StartsWith( wxT( "SHORT_NET_NAME" ) ) )
1475 *token = conn->LocalName();
1476 else if( token->StartsWith( wxT( "NET_NAME" ) ) )
1477 *token = conn->Name();
1478 else if( token->StartsWith( wxT( "NET_CLASS" ) ) )
1479 *token = pin->GetEffectiveNetClass( aPath )->GetName();
1480
1481 return true;
1482 }
1483 }
1484 }
1485
1486 // See if parent can resolve it (this will recurse to ancestors)
1487 if( aPath->Last() && aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
1488 return true;
1489
1490 return false;
1491}
1492
1493
1494void SCH_SYMBOL::ClearAnnotation( const SCH_SHEET_PATH* aSheetPath, bool aResetPrefix )
1495{
1496 if( aSheetPath )
1497 {
1498 KIID_PATH path = aSheetPath->Path();
1499
1500 for( SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1501 {
1502 if( instance.m_Path == path )
1503 {
1504 if( instance.m_Reference.IsEmpty() || aResetPrefix )
1505 instance.m_Reference = UTIL::GetRefDesUnannotated( m_prefix );
1506 else
1507 instance.m_Reference = UTIL::GetRefDesUnannotated( instance.m_Reference );
1508 }
1509 }
1510 }
1511 else
1512 {
1513 for( SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1514 {
1515 if( instance.m_Reference.IsEmpty() || aResetPrefix)
1516 instance.m_Reference = UTIL::GetRefDesUnannotated( m_prefix );
1517 else
1518 instance.m_Reference = UTIL::GetRefDesUnannotated( instance.m_Reference );
1519 }
1520 }
1521
1522 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1523 pin->ClearDefaultNetName( aSheetPath );
1524
1525 // These 2 changes do not work in complex hierarchy.
1526 // When a clear annotation is made, the calling function must call a
1527 // UpdateAllScreenReferences for the active sheet.
1528 // But this call cannot made here.
1529 wxString currentReference = m_fields[REFERENCE_FIELD].GetText();
1530
1531 if( currentReference.IsEmpty() || aResetPrefix )
1533 else
1534 m_fields[REFERENCE_FIELD].SetText( UTIL::GetRefDesUnannotated( currentReference ) );
1535}
1536
1537
1539{
1540 // An empty sheet path is illegal, at a minimum the root sheet UUID must be present.
1541 wxCHECK( aSheetPath.size() > 0, false );
1542
1543 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1544 {
1545 // if aSheetPath is found, nothing to do:
1546 if( instance.m_Path == aSheetPath )
1547 return false;
1548 }
1549
1550 // This entry does not exist: add it, with its last-used reference
1551 AddHierarchicalReference( aSheetPath, m_fields[REFERENCE_FIELD].GetText(), m_unit );
1552 return true;
1553}
1554
1555
1556void SCH_SYMBOL::SetOrientation( int aOrientation )
1557{
1558 TRANSFORM temp = TRANSFORM();
1559 bool transform = false;
1560
1561 switch( aOrientation )
1562 {
1563 case SYM_ORIENT_0:
1564 case SYM_NORMAL: // default transform matrix
1565 m_transform.x1 = 1;
1566 m_transform.y2 = -1;
1568 break;
1569
1570 case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1571 temp.x1 = temp.y2 = 0;
1572 temp.y1 = 1;
1573 temp.x2 = -1;
1574 transform = true;
1575 break;
1576
1577 case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1578 temp.x1 = temp.y2 = 0;
1579 temp.y1 = -1;
1580 temp.x2 = 1;
1581 transform = true;
1582 break;
1583
1584 case SYM_MIRROR_Y: // Mirror Y (incremental rotation)
1585 temp.x1 = -1;
1586 temp.y2 = 1;
1587 temp.y1 = temp.x2 = 0;
1588 transform = true;
1589 break;
1590
1591 case SYM_MIRROR_X: // Mirror X (incremental rotation)
1592 temp.x1 = 1;
1593 temp.y2 = -1;
1594 temp.y1 = temp.x2 = 0;
1595 transform = true;
1596 break;
1597
1598 case SYM_ORIENT_90:
1601 break;
1602
1603 case SYM_ORIENT_180:
1607 break;
1608
1609 case SYM_ORIENT_270:
1612 break;
1613
1614 case ( SYM_ORIENT_0 + SYM_MIRROR_X ):
1617 break;
1618
1619 case ( SYM_ORIENT_0 + SYM_MIRROR_Y ):
1622 break;
1623
1628 break;
1629
1630 case ( SYM_ORIENT_90 + SYM_MIRROR_X ):
1633 break;
1634
1635 case ( SYM_ORIENT_90 + SYM_MIRROR_Y ):
1638 break;
1639
1644 break;
1645
1646 case ( SYM_ORIENT_180 + SYM_MIRROR_X ):
1649 break;
1650
1651 case ( SYM_ORIENT_180 + SYM_MIRROR_Y ):
1654 break;
1655
1660 break;
1661
1662 case ( SYM_ORIENT_270 + SYM_MIRROR_X ):
1665 break;
1666
1667 case ( SYM_ORIENT_270 + SYM_MIRROR_Y ):
1670 break;
1671
1676 break;
1677
1678 default:
1679 transform = false;
1680 wxFAIL_MSG( "Invalid schematic symbol orientation type." );
1681 break;
1682 }
1683
1684 if( transform )
1685 {
1686 /* The new matrix transform is the old matrix transform modified by the
1687 * requested transformation, which is the temp transform (rot,
1688 * mirror ..) in order to have (in term of matrix transform):
1689 * transform coord = new_m_transform * coord
1690 * where transform coord is the coord modified by new_m_transform from
1691 * the initial value coord.
1692 * new_m_transform is computed (from old_m_transform and temp) to
1693 * have:
1694 * transform coord = old_m_transform * temp
1695 */
1696 TRANSFORM newTransform;
1697
1698 newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1699 newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1700 newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1701 newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1702 m_transform = newTransform;
1703 }
1704}
1705
1706
1708{
1709 /*
1710 * This is slow, but also a bizarre algorithm. I don't feel like unteasing the algorithm right
1711 * now, so let's just cache it for the moment.
1712 */
1715
1716 int rotate_values[] =
1717 {
1730 };
1731
1732 // Try to find the current transform option:
1733 TRANSFORM transform = m_transform;
1734 SCH_SYMBOL temp( *this );
1735
1736 for( int type_rotate : rotate_values )
1737 {
1738 temp.SetOrientation( type_rotate );
1739
1740 if( transform == temp.GetTransform() )
1741 {
1743 return type_rotate;
1744 }
1745 }
1746
1747 // Error: orientation not found in list (should not happen)
1748 wxFAIL_MSG( "Schematic symbol orientation matrix internal error." );
1749
1750 return SYM_NORMAL;
1751}
1752
1753
1754#if defined(DEBUG)
1755
1756void SCH_SYMBOL::Show( int nestLevel, std::ostream& os ) const
1757{
1758 // for now, make it look like XML:
1759 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1760 << " ref=\"" << TO_UTF8( GetField( REFERENCE_FIELD )->GetName() )
1761 << '"' << " chipName=\""
1762 << GetLibId().Format() << '"' << m_pos
1763 << " layer=\"" << m_layer
1764 << '"' << ">\n";
1765
1766 // skip the reference, it's been output already.
1767 for( int i = 1; i < GetFieldCount(); ++i )
1768 {
1769 const wxString& value = GetFields()[i].GetText();
1770
1771 if( !value.IsEmpty() )
1772 {
1773 NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1774 << TO_UTF8( GetFields()[i].GetName() )
1775 << '"' << " value=\""
1776 << TO_UTF8( value ) << "\"/>\n";
1777 }
1778 }
1779
1780 NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1781}
1782
1783#endif
1784
1785
1786BOX2I SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) const
1787{
1788 BOX2I bBox;
1789
1790 if( m_part )
1791 bBox = m_part->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
1792 else
1793 bBox = dummy()->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
1794
1795 int x0 = bBox.GetX();
1796 int xm = bBox.GetRight();
1797
1798 // We must reverse Y values, because matrix orientation
1799 // suppose Y axis normal for the library items coordinates,
1800 // m_transform reverse Y values, but bBox is already reversed!
1801 int y0 = -bBox.GetY();
1802 int ym = -bBox.GetBottom();
1803
1804 // Compute the real Boundary box (rotated, mirrored ...)
1805 int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
1806 int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
1807 int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
1808 int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
1809
1810 bBox.SetX( x1 );
1811 bBox.SetY( y1 );
1812 bBox.SetWidth( x2 - x1 );
1813 bBox.SetHeight( y2 - y1 );
1814 bBox.Normalize();
1815
1816 bBox.Offset( m_pos );
1817
1818 if( aIncludeFields )
1819 {
1820 for( const SCH_FIELD& field : m_fields )
1821 {
1822 if( field.IsVisible() )
1823 bBox.Merge( field.GetBoundingBox() );
1824 }
1825 }
1826
1827 return bBox;
1828}
1829
1830
1832{
1833 try
1834 {
1835 return doGetBoundingBox( false, false );
1836 }
1837 catch( const boost::bad_pointer& exc )
1838 {
1839 // This may be overkill and could be an assertion but we are more likely to
1840 // find any boost pointer container errors this way.
1841 wxLogError( wxT( "Boost bad pointer exception '%s' occurred." ), exc.what() );
1842 return BOX2I();
1843 }
1844}
1845
1846
1848{
1849 return doGetBoundingBox( true, false );
1850}
1851
1852
1854{
1855 return doGetBoundingBox( true, true );
1856}
1857
1858
1859void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1860{
1861 wxString msg;
1862
1863 SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1864 SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1865
1866 auto addExcludes =
1867 [&]()
1868 {
1869 wxArrayString msgs;
1870
1871 if( GetExcludedFromSim() )
1872 msgs.Add( _( "Simulation" ) );
1873
1874 if( GetExcludedFromBOM() )
1875 msgs.Add( _( "BOM" ) );
1876
1877 if( GetExcludedFromBoard() )
1878 msgs.Add( _( "Board" ) );
1879
1880 if( GetDNP() )
1881 msgs.Add( _( "DNP" ) );
1882
1883 msg = wxJoin( msgs, '|' );
1884 msg.Replace( '|', wxS( ", " ) );
1885
1886 if( !msg.empty() )
1887 aList.emplace_back( _( "Exclude from" ), msg );
1888 };
1889
1890 // part and alias can differ if alias is not the root
1891 if( m_part )
1892 {
1893 if( m_part.get() != dummy() )
1894 {
1895 if( m_part->IsPower() )
1896 {
1897 // Don't use GetShownText(); we want to see the variable references here
1898 aList.emplace_back( _( "Power symbol" ),
1899 KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) );
1900 }
1901 else
1902 {
1903 aList.emplace_back( _( "Reference" ),
1904 UnescapeString( GetRef( currentSheet ) ) );
1905
1906 // Don't use GetShownText(); we want to see the variable references here
1907 aList.emplace_back( _( "Value" ),
1908 KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) );
1909 addExcludes();
1910 aList.emplace_back( _( "Name" ),
1911 KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) );
1912 }
1913
1914#if 0 // Display symbol flags, for debug only
1915 aList.emplace_back( _( "flags" ), wxString::Format( "%X", GetEditFlags() ) );
1916#endif
1917
1918 if( !m_part->IsRoot() )
1919 {
1920 msg = _( "Missing parent" );
1921
1922 std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock();
1923
1924 if( parent )
1925 msg = parent->GetName();
1926
1927 aList.emplace_back( _( "Derived from" ), UnescapeString( msg ) );
1928 }
1929 else if( !m_lib_id.GetLibNickname().empty() )
1930 {
1931 aList.emplace_back( _( "Library" ), m_lib_id.GetLibNickname() );
1932 }
1933 else
1934 {
1935 aList.emplace_back( _( "Library" ), _( "Undefined!!!" ) );
1936 }
1937
1938 // Display the current associated footprint, if exists.
1939 // Don't use GetShownText(); we want to see the variable references here
1940 msg = KIUI::EllipsizeStatusText( aFrame, GetField( FOOTPRINT_FIELD )->GetText() );
1941
1942 if( msg.IsEmpty() )
1943 msg = _( "<Unknown>" );
1944
1945 aList.emplace_back( _( "Footprint" ), msg );
1946
1947 // Display description of the symbol, and keywords found in lib
1948 aList.emplace_back( _( "Description" ) + wxT( ": " )
1949 + GetField( DESCRIPTION_FIELD )->GetText(),
1950 _( "Keywords" ) + wxT( ": " ) + m_part->GetKeyWords() );
1951 }
1952 }
1953 else
1954 {
1955 aList.emplace_back( _( "Reference" ), GetRef( currentSheet ) );
1956 // Don't use GetShownText(); we want to see the variable references here
1957 aList.emplace_back( _( "Value" ),
1958 KIUI::EllipsizeStatusText( aFrame, GetField( VALUE_FIELD )->GetText() ) );
1959 addExcludes();
1960 aList.emplace_back( _( "Name" ),
1961 KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) );
1962
1963 wxString libNickname = GetLibId().GetLibNickname();
1964
1965 if( libNickname.empty() )
1966 msg = _( "No library defined!" );
1967 else
1968 msg.Printf( _( "Symbol not found in %s!" ), libNickname );
1969
1970 aList.emplace_back( _( "Library" ), msg );
1971 }
1972}
1973
1974
1976{
1977 return BITMAPS::add_component;
1978}
1979
1980
1982{
1983 int dx = m_pos.x;
1984
1986 MIRROR( m_pos.x, aCenter );
1987 dx -= m_pos.x; // dx,0 is the move vector for this transform
1988
1989 for( SCH_FIELD& field : m_fields )
1990 {
1991 // Move the fields to the new position because the symbol itself has moved.
1992 VECTOR2I pos = field.GetTextPos();
1993 pos.x -= dx;
1994 field.SetTextPos( pos );
1995 }
1996}
1997
1998
2000{
2001 int dy = m_pos.y;
2002
2004 MIRROR( m_pos.y, aCenter );
2005 dy -= m_pos.y; // 0,dy is the move vector for this transform
2006
2007 for( SCH_FIELD& field : m_fields )
2008 {
2009 // Move the fields to the new position because the symbol itself has moved.
2010 VECTOR2I pos = field.GetTextPos();
2011 pos.y -= dy;
2012 field.SetTextPos( pos );
2013 }
2014}
2015
2016
2017void SCH_SYMBOL::Rotate( const VECTOR2I& aCenter )
2018{
2019 VECTOR2I prev = m_pos;
2020
2021 RotatePoint( m_pos, aCenter, ANGLE_90 );
2022
2024
2025 for( SCH_FIELD& field : m_fields )
2026 {
2027 // Move the fields to the new position because the symbol itself has moved.
2028 VECTOR2I pos = field.GetTextPos();
2029 pos.x -= prev.x - m_pos.x;
2030 pos.y -= prev.y - m_pos.y;
2031 field.SetTextPos( pos );
2032 }
2033}
2034
2035
2036bool SCH_SYMBOL::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
2037{
2038 // Symbols are searchable via the child field and pin item text.
2039 return false;
2040}
2041
2042
2043void SCH_SYMBOL::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
2044{
2045 for( auto& pin : m_pins )
2046 {
2047 LIB_PIN* lib_pin = pin->GetLibPin();
2048
2049 if( lib_pin && lib_pin->GetUnit() && m_unit && ( m_unit != lib_pin->GetUnit() ) )
2050 continue;
2051
2052 DANGLING_END_ITEM item( PIN_END, lib_pin, GetPinPhysicalPosition( lib_pin ), this );
2053 aItemList.push_back( item );
2054 }
2055}
2056
2057
2058bool SCH_SYMBOL::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
2059 std::vector<DANGLING_END_ITEM>& aItemListByPos,
2060 const SCH_SHEET_PATH* aPath )
2061{
2062 bool changed = false;
2063
2064 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2065 {
2066 bool previousState = pin->IsDangling();
2067 pin->SetIsDangling( true );
2068
2069 VECTOR2I pos = m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos;
2070
2071 auto lower = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, pos );
2072 bool do_break = false;
2073
2074 for( auto it = lower; it < aItemListByPos.end() && it->GetPosition() == pos; it++ )
2075 {
2076 DANGLING_END_ITEM& each_item = *it;
2077 // Some people like to stack pins on top of each other in a symbol to indicate
2078 // internal connection. While technically connected, it is not particularly useful
2079 // to display them that way, so skip any pins that are in the same symbol as this
2080 // one.
2081 if( each_item.GetParent() == this )
2082 continue;
2083
2084 switch( each_item.GetType() )
2085 {
2086 case PIN_END:
2087 case LABEL_END:
2088 case SHEET_LABEL_END:
2089 case WIRE_END:
2090 case NO_CONNECT_END:
2091 case JUNCTION_END:
2092 pin->SetIsDangling( false );
2093 do_break = true;
2094 break;
2095
2096 default:
2097 break;
2098 }
2099
2100 if( do_break )
2101 break;
2102 }
2103
2104 changed = ( changed || ( previousState != pin->IsDangling() ) );
2105 }
2106
2107 return changed;
2108}
2109
2110
2112{
2113 wxCHECK_MSG( Pin != nullptr && Pin->Type() == LIB_PIN_T, VECTOR2I( 0, 0 ),
2114 wxT( "Cannot get physical position of pin." ) );
2115
2117}
2118
2119
2120std::vector<VECTOR2I> SCH_SYMBOL::GetConnectionPoints() const
2121{
2122 std::vector<VECTOR2I> retval;
2123
2124 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2125 {
2126 // Collect only pins attached to the current unit and convert.
2127 // others are not associated to this symbol instance
2128 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2129 : GetUnit();
2130 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2131 : GetBodyStyle();
2132
2133 if( pin_unit > 0 && pin_unit != GetUnit() )
2134 continue;
2135
2136 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2137 continue;
2138
2139 retval.push_back( m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos );
2140 }
2141
2142 return retval;
2143}
2144
2145
2147{
2148 if( m_part )
2149 {
2150 // Calculate the position relative to the symbol.
2151 VECTOR2I libPosition = aPosition - m_pos;
2152
2153 return m_part->LocateDrawItem( m_unit, m_bodyStyle, aType, libPosition, m_transform );
2154 }
2155
2156 return nullptr;
2157}
2158
2159
2160wxString SCH_SYMBOL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
2161{
2162 return wxString::Format( _( "Symbol %s [%s]" ),
2164 KIUI::EllipsizeMenuText( GetLibId().GetLibItemName() ) );
2165}
2166
2167
2168INSPECT_RESULT SCH_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
2169 const std::vector<KICAD_T>& aScanTypes )
2170{
2171 for( KICAD_T scanType : aScanTypes )
2172 {
2173 if( scanType == SCH_LOCATE_ANY_T
2174 || ( scanType == SCH_SYMBOL_T )
2175 || ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
2176 {
2177 if( INSPECT_RESULT::QUIT == aInspector( this, aTestData ) )
2178 return INSPECT_RESULT::QUIT;
2179 }
2180
2181 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
2182 {
2183 for( SCH_FIELD& field : m_fields )
2184 {
2185 if( INSPECT_RESULT::QUIT == aInspector( &field, (void*) this ) )
2186 return INSPECT_RESULT::QUIT;
2187 }
2188 }
2189
2190 if( scanType == SCH_FIELD_LOCATE_REFERENCE_T )
2191 {
2192 if( INSPECT_RESULT::QUIT == aInspector( GetField( REFERENCE_FIELD ), (void*) this ) )
2193 return INSPECT_RESULT::QUIT;
2194 }
2195
2196 if( scanType == SCH_FIELD_LOCATE_VALUE_T
2197 || ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
2198 {
2199 if( INSPECT_RESULT::QUIT == aInspector( GetField( VALUE_FIELD ), (void*) this ) )
2200 return INSPECT_RESULT::QUIT;
2201 }
2202
2203 if( scanType == SCH_FIELD_LOCATE_FOOTPRINT_T )
2204 {
2205 if( INSPECT_RESULT::QUIT == aInspector( GetField( FOOTPRINT_FIELD ), (void*) this ) )
2206 return INSPECT_RESULT::QUIT;
2207 }
2208
2209 if( scanType == SCH_FIELD_LOCATE_DATASHEET_T )
2210 {
2211 if( INSPECT_RESULT::QUIT == aInspector( GetField( DATASHEET_FIELD ), (void*) this ) )
2212 return INSPECT_RESULT::QUIT;
2213 }
2214
2215 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_PIN_T )
2216 {
2217 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2218 {
2219 // Collect only pins attached to the current unit and convert.
2220 // others are not associated to this symbol instance
2221 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2222 : GetUnit();
2223 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2224 : GetBodyStyle();
2225
2226 if( pin_unit > 0 && pin_unit != GetUnit() )
2227 continue;
2228
2229 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2230 continue;
2231
2232 if( INSPECT_RESULT::QUIT == aInspector( pin.get(), (void*) this ) )
2233 return INSPECT_RESULT::QUIT;
2234 }
2235 }
2236 }
2237
2238 return INSPECT_RESULT::CONTINUE;
2239}
2240
2241
2242bool SCH_SYMBOL::operator <( const SCH_ITEM& aItem ) const
2243{
2244 if( Type() != aItem.Type() )
2245 return Type() < aItem.Type();
2246
2247 auto symbol = static_cast<const SCH_SYMBOL*>( &aItem );
2248
2250
2251 if( rect.GetArea() != symbol->GetBodyAndPinsBoundingBox().GetArea() )
2252 return rect.GetArea() < symbol->GetBodyAndPinsBoundingBox().GetArea();
2253
2254 if( m_pos.x != symbol->m_pos.x )
2255 return m_pos.x < symbol->m_pos.x;
2256
2257 if( m_pos.y != symbol->m_pos.y )
2258 return m_pos.y < symbol->m_pos.y;
2259
2260 return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
2261}
2262
2263
2264bool SCH_SYMBOL::operator==( const SCH_SYMBOL& aSymbol ) const
2265{
2266 if( GetFieldCount() != aSymbol.GetFieldCount() )
2267 return false;
2268
2269 for( int i = VALUE_FIELD; i < GetFieldCount(); i++ )
2270 {
2271 if( GetFields()[i].GetText().Cmp( aSymbol.GetFields()[i].GetText() ) != 0 )
2272 return false;
2273 }
2274
2275 return true;
2276}
2277
2278
2279bool SCH_SYMBOL::operator!=( const SCH_SYMBOL& aSymbol ) const
2280{
2281 return !( *this == aSymbol );
2282}
2283
2284
2286{
2287 wxCHECK_MSG( Type() == aItem.Type(), *this,
2288 wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
2289 GetClass() );
2290
2291 if( &aItem != this )
2292 {
2293 SCH_ITEM::operator=( aItem );
2294
2295 SCH_SYMBOL* c = (SCH_SYMBOL*) &aItem;
2296
2297 m_lib_id = c->m_lib_id;
2298
2299 LIB_SYMBOL* libSymbol = c->m_part ? new LIB_SYMBOL( *c->m_part.get() ) : nullptr;
2300
2301 m_part.reset( libSymbol );
2302 m_pos = c->m_pos;
2303 m_unit = c->m_unit;
2306
2308
2309 m_fields = c->m_fields; // std::vector's assignment operator
2310
2311 // Reparent fields after assignment to new symbol.
2312 for( SCH_FIELD& field : m_fields )
2313 field.SetParent( this );
2314
2315 UpdatePins();
2316 }
2317
2318 return *this;
2319}
2320
2321
2322bool SCH_SYMBOL::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
2323{
2324 BOX2I bBox = GetBodyBoundingBox();
2325 bBox.Inflate( aAccuracy / 2 );
2326
2327 if( bBox.Contains( aPosition ) )
2328 return true;
2329
2330 return false;
2331}
2332
2333
2334bool SCH_SYMBOL::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
2335{
2337 return false;
2338
2339 BOX2I rect = aRect;
2340
2341 rect.Inflate( aAccuracy / 2 );
2342
2343 if( aContained )
2344 return rect.Contains( GetBodyBoundingBox() );
2345
2346 return rect.Intersects( GetBodyBoundingBox() );
2347}
2348
2349
2350bool SCH_SYMBOL::doIsConnected( const VECTOR2I& aPosition ) const
2351{
2353
2354 for( const auto& pin : m_pins )
2355 {
2356 if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
2357 continue;
2358
2359 // Collect only pins attached to the current unit and convert.
2360 // others are not associated to this symbol instance
2361 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2362 : GetUnit();
2363 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2364 : GetBodyStyle();
2365
2366 if( pin_unit > 0 && pin_unit != GetUnit() )
2367 continue;
2368
2369 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2370 continue;
2371
2372 if( pin->GetLocalPosition() == new_pos )
2373 return true;
2374 }
2375
2376 return false;
2377}
2378
2379
2381{
2382 return m_isInNetlist;
2383}
2384
2385
2386void SCH_SYMBOL::Plot( PLOTTER* aPlotter, bool aBackground,
2387 const SCH_PLOT_SETTINGS& aPlotSettings ) const
2388{
2389 if( aBackground )
2390 return;
2391
2392 if( m_part )
2393 {
2394 LIB_PINS libPins;
2395 m_part->GetPins( libPins, GetUnit(), GetBodyStyle() );
2396
2397 // Copy the source so we can re-orient and translate it.
2398 LIB_SYMBOL tempSymbol( *m_part );
2399 LIB_PINS tempPins;
2400 tempSymbol.GetPins( tempPins, GetUnit(), GetBodyStyle() );
2401
2402 // Copy the pin info from the symbol to the temp pins
2403 for( unsigned i = 0; i < tempPins.size(); ++ i )
2404 {
2405 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
2406 LIB_PIN* tempPin = tempPins[ i ];
2407
2408 tempPin->SetName( symbolPin->GetShownName() );
2409 tempPin->SetType( symbolPin->GetType() );
2410 tempPin->SetShape( symbolPin->GetShape() );
2411
2412 if( symbolPin->IsDangling() )
2413 tempPin->SetFlags( IS_DANGLING );
2414 }
2415
2416 for( LIB_ITEM& item : tempSymbol.GetDrawItems() )
2417 {
2418 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
2419 {
2420 // Use SCH_FIELD's text resolver
2421 SCH_FIELD dummy( (SCH_ITEM*) this, -1 );
2422 dummy.SetText( text->GetText() );
2423 text->SetText( dummy.GetShownText( false ) );
2424 }
2425 }
2426
2427 TRANSFORM temp = GetTransform();
2428 aPlotter->StartBlock( nullptr );
2429
2430 for( bool local_background : { true, false } )
2431 {
2432 tempSymbol.Plot( aPlotter, GetUnit(), GetBodyStyle(), local_background, m_pos, temp,
2433 GetDNP() );
2434
2435 for( SCH_FIELD field : m_fields )
2436 {
2437 field.ClearRenderCache();
2438 field.Plot( aPlotter, local_background, aPlotSettings );
2439 }
2440 }
2441
2442 if( m_DNP )
2443 PlotDNP( aPlotter );
2444
2445 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
2446
2447 // Plot attributes to a hypertext menu
2448 if( aPlotSettings.m_PDFPropertyPopups )
2449 {
2450 std::vector<wxString> properties;
2451
2452 for( const SCH_FIELD& field : GetFields() )
2453 {
2454 wxString text_field = field.GetShownText( sheet, false);
2455
2456 if( text_field.IsEmpty() )
2457 continue;
2458
2459 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
2460 field.GetName(), text_field ) );
2461 }
2462
2463 if( !m_part->GetKeyWords().IsEmpty() )
2464 {
2465 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
2466 _( "Keywords" ),
2467 m_part->GetKeyWords() ) );
2468 }
2469
2470 aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
2471 }
2472
2473 aPlotter->EndBlock( nullptr );
2474
2475 if( !m_part->IsPower() )
2476 aPlotter->Bookmark( GetBoundingBox(), GetRef( sheet ), _( "Symbols" ) );
2477 }
2478}
2479
2480
2481void SCH_SYMBOL::PlotDNP( PLOTTER* aPlotter ) const
2482{
2484
2485 COLOR_SETTINGS* colors = Pgm().GetSettingsManager().GetColorSettings();
2486
2487 aPlotter->SetColor( colors->GetColor( LAYER_DNP_MARKER ) );
2488
2489 aPlotter->ThickSegment( bbox.GetOrigin(), bbox.GetEnd(),
2491 FILLED, nullptr );
2492
2493 aPlotter->ThickSegment( bbox.GetOrigin() + VECTOR2I( bbox.GetWidth(), 0 ),
2494 bbox.GetOrigin() + VECTOR2I( 0, bbox.GetHeight() ),
2496 FILLED, nullptr );
2497}
2498
2499
2500void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const
2501{
2502 if( m_part )
2503 {
2504 LIB_PINS libPins;
2505 m_part->GetPins( libPins, GetUnit(), GetBodyStyle() );
2506
2507 // Copy the source to stay const
2508 LIB_SYMBOL tempSymbol( *m_part );
2509 LIB_PINS tempPins;
2510 tempSymbol.GetPins( tempPins, GetUnit(), GetBodyStyle() );
2511
2512 TRANSFORM transform = GetTransform();
2513
2514 // Copy the pin info from the symbol to the temp pins
2515 for( unsigned i = 0; i < tempPins.size(); ++ i )
2516 {
2517 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
2518 LIB_PIN* tempPin = tempPins[ i ];
2519
2520 tempPin->SetName( symbolPin->GetShownName() );
2521 tempPin->SetType( symbolPin->GetType() );
2522 tempPin->SetShape( symbolPin->GetShape() );
2523 tempPin->Plot( aPlotter, false, m_pos, transform, GetDNP() );
2524 }
2525 }
2526}
2527
2528
2530{
2531 for( const auto& pin : m_pins )
2532 {
2533 if( pin->IsBrightened() )
2534 return true;
2535 }
2536
2537 return false;
2538}
2539
2540
2542{
2543 for( auto& pin : m_pins )
2544 pin->ClearBrightened();
2545}
2546
2547
2549{
2550 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2551 {
2552 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2553 : GetUnit();
2554 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2555 : GetBodyStyle();
2556
2557 if( pin_unit > 0 && pin_unit != GetUnit() )
2558 continue;
2559
2560 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2561 continue;
2562
2563 if( pin->IsPointClickableAnchor( aPos ) )
2564 return true;
2565 }
2566
2567 return false;
2568}
2569
2570
2572{
2573 // return true if the symbol is equivalent to a global label:
2574 // It is a Power symbol
2575 // It has only one pin type Power input
2576
2577 if( !GetLibSymbolRef() || !GetLibSymbolRef()->IsPower() )
2578 return false;
2579
2580 std::vector<LIB_PIN*> pin_list = GetAllLibPins();
2581
2582 if( pin_list.size() != 1 )
2583 return false;
2584
2585 return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
2586}
2587
2588
2590{
2591 wxCHECK( m_part, false );
2592
2593 return m_part->IsPower();
2594}
2595
2596
2597bool SCH_SYMBOL::operator==( const SCH_ITEM& aOther ) const
2598{
2599 if( Type() != aOther.Type() )
2600 return false;
2601
2602 auto symbol = static_cast<const SCH_SYMBOL&>( aOther );
2603
2604 if( GetLibId() != symbol.GetLibId() )
2605 return false;
2606
2607 if( GetPosition() != symbol.GetPosition() )
2608 return false;
2609
2610 if( GetUnit() != symbol.GetUnit() )
2611 return false;
2612
2613 if( GetBodyStyle() != symbol.GetBodyStyle() )
2614 return false;
2615
2616 if( GetTransform() != symbol.GetTransform() )
2617 return false;
2618
2619 if( GetFields() != symbol.GetFields() )
2620 return false;
2621
2622 if( m_pins.size() != symbol.m_pins.size() )
2623 return false;
2624
2625 for( unsigned i = 0; i < m_pins.size(); ++i )
2626 {
2627 if( !( *m_pins[i] == *symbol.m_pins[i] ) )
2628 return false;
2629 }
2630
2631 return true;
2632}
2633
2634
2635double SCH_SYMBOL::Similarity( const SCH_ITEM& aOther ) const
2636{
2637 if( Type() != aOther.Type() )
2638 return 0.0;
2639
2640 auto symbol = static_cast<const SCH_SYMBOL&>( aOther );
2641
2642 if( GetLibId() != symbol.GetLibId() )
2643 return 0.0;
2644
2645 if( GetPosition() == symbol.GetPosition() )
2646 return 1.0;
2647
2648 return 0.0;
2649}
2650
2651
2652static struct SCH_SYMBOL_DESC
2653{
2655 {
2657 .Map( SYMBOL_ANGLE_0, wxS( "0" ) )
2658 .Map( SYMBOL_ANGLE_90, wxS( "90" ) )
2659 .Map( SYMBOL_ANGLE_180, wxS( "180" ) )
2660 .Map( SYMBOL_ANGLE_270, wxS( "270" ) );
2661
2665
2666 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Position X" ),
2667 &SCH_SYMBOL::SetX, &SCH_SYMBOL::GetX, PROPERTY_DISPLAY::PT_COORD,
2669 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Position Y" ),
2670 &SCH_SYMBOL::SetY, &SCH_SYMBOL::GetY, PROPERTY_DISPLAY::PT_COORD,
2672
2674 _HKI( "Orientation" ),
2676 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror X" ),
2678 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror Y" ),
2680
2681 auto hasLibPart = []( INSPECTABLE* aItem ) -> bool
2682 {
2683 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2684 return symbol->GetLibSymbolRef().get() != nullptr;
2685
2686 return false;
2687 };
2688
2689 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Pin numbers" ),
2692 .SetAvailableFunc( hasLibPart );
2693
2694 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Pin names" ),
2697 .SetAvailableFunc( hasLibPart );
2698
2699 auto isMultiUnitSymbol =
2700 []( INSPECTABLE* aItem ) -> bool
2701 {
2702 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2703 return symbol->GetUnitCount() > 1;
2704
2705 return false;
2706 };
2707
2708 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Unit" ),
2710 .SetAvailableFunc( isMultiUnitSymbol );
2711
2712 const wxString groupFields = _HKI( "Fields" );
2713
2714 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Reference" ),
2716 groupFields );
2717 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Value" ),
2719 groupFields );
2720 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Library Link" ),
2722 groupFields );
2723 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Library Description" ),
2725 groupFields );
2726 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Keywords" ),
2728 groupFields );
2729
2730 const wxString groupAttributes = _HKI( "Attributes" );
2731
2732 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Exclude From Board" ),
2734 groupAttributes );
2735 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Exclude From Simulation" ),
2737 groupAttributes );
2738 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Exclude From Bill of Materials" ),
2740 groupAttributes );
2741 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Do not Populate" ),
2743 groupAttributes );
2744 }
2746
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
double square(double x)
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
BOX2< VECTOR2I > BOX2I
Definition: box2.h:853
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:120
const Vec & GetOrigin() const
Definition: box2.h:184
void Offset(coord_type dx, coord_type dy)
Definition: box2.h:225
void SetX(coord_type val)
Definition: box2.h:236
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:270
void SetY(coord_type val)
Definition: box2.h:241
coord_type GetHeight() const
Definition: box2.h:189
coord_type GetY() const
Definition: box2.h:182
coord_type GetWidth() const
Definition: box2.h:188
void SetWidth(coord_type val)
Definition: box2.h:246
const Vec GetEnd() const
Definition: box2.h:186
bool Contains(const Vec &aPoint) const
Definition: box2.h:142
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:507
coord_type GetX() const
Definition: box2.h:181
coord_type GetRight() const
Definition: box2.h:190
ecoord_type GetArea() const
Return the area of the rectangle.
Definition: box2.h:702
void SetHeight(coord_type val)
Definition: box2.h:251
coord_type GetBottom() const
Definition: box2.h:191
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:589
Color settings are a bit different than most of the settings objects in that there can be more than o...
COLOR4D GetColor(int aLayer) const
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition: sch_item.cpp:412
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:86
DANGLING_END_T GetType() const
Definition: sch_item.h:130
const EDA_ITEM * GetParent() const
Definition: sch_item.h:129
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:129
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
const KIID m_Uuid
Definition: eda_item.h:482
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:487
bool IsSelected() const
Definition: eda_item.h:106
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:485
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:80
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:419
static ENUM_MAP< T > & Instance()
Definition: property.h:653
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
wxString AsString() const
Definition: kiid.cpp:362
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:257
Field object used in symbol libraries.
Definition: lib_field.h:62
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
UTF8 Format() const
Definition: lib_id.cpp:118
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
Definition: lib_id.h:112
const wxString GetUniStringLibNickname() const
Definition: lib_id.h:88
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:68
int GetUnit() const
Definition: lib_item.h:343
@ BASE
Definition: lib_item.h:79
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: lib_pin.h:72
void SetName(const wxString &aName)
Definition: lib_pin.h:108
void SetType(ELECTRICAL_PINTYPE aType)
Definition: lib_pin.h:85
VECTOR2I GetPosition() const override
Definition: lib_pin.h:232
void Plot(PLOTTER *aPlotter, bool aBackground, const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed) const override
Plot the draw item using the plot object.
Definition: lib_pin.cpp:1171
Define a library symbol object.
Definition: lib_symbol.h:99
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:214
static wxString LetterSubReference(int aUnit, int aFirstId)
Definition: lib_symbol.cpp:760
void GetPins(LIB_PINS &aList, int aUnit=0, int aBodyStyle=0) const
Return a list of pin object pointers from the draw item list.
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:545
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, int aMulti, int aBodyStyle, const LIB_SYMBOL_OPTIONS &aOpts, bool aDimmed)
Print symbol.
Definition: lib_symbol.cpp:814
void Plot(PLOTTER *aPlotter, int aUnit, int aBodyStyle, bool aBackground, const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed) const
Plot lib symbol to plotter.
Definition: lib_symbol.cpp:865
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:605
Define a symbol library graphical text item.
Definition: lib_text.h:40
Base plotter engine class.
Definition: plotter.h:104
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:554
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition: plotter.h:474
virtual void StartBlock(void *aData)
calling this function allows one to define the beginning of a group of drawing items,...
Definition: plotter.h:535
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:463
virtual void SetColor(const COLOR4D &color)=0
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:544
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition: property.h:252
T get(const void *aObject) const
Definition: property.h:378
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
Holds all the data relating to one schematic.
Definition: schematic.h:75
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:136
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:718
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:287
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:411
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString LocalName() const
wxString Name(bool aIgnoreSheet=false) const
Schematic editor (Eeschema) main window.
SCH_SHEET_PATH & GetCurrentSheet() const
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:52
void ImportValues(const LIB_FIELD &aSource)
Copy parameters from a LIB_FIELD source.
Definition: sch_field.cpp:420
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
Definition: sch_field.cpp:188
void SetText(const wxString &aText) override
Definition: sch_field.cpp:991
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:165
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:71
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:175
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:540
void SwapFlags(SCH_ITEM *aItem)
Swap the non-temp and non-edit flags.
Definition: sch_item.cpp:267
SCH_LAYER_ID m_layer
Definition: sch_item.h:538
bool IsDangling() const override
Definition: sch_pin.h:103
wxString GetShownName() const
Definition: sch_pin.cpp:104
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:138
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:127
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:237
Schematic symbol object.
Definition: sch_symbol.h:109
void UpdatePrefix()
Set the prefix based on the current reference designator.
Definition: sch_symbol.cpp:840
wxString m_prefix
C, R, U, Q etc - the first character(s) which typically indicate what the symbol is.
Definition: sch_symbol.h:914
SCH_FIELD * GetFieldByName(const wxString &aFieldName)
Return a field in this symbol.
Definition: sch_symbol.cpp:974
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
void GetLibPins(std::vector< LIB_PIN * > &aPinsList) const
Populate a vector with all the pins from the library object.
int GetUnitCount() const
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:483
void SetMirrorX(bool aMirror)
Definition: sch_symbol.h:380
bool IsSymbolLikePowerGlobalLabel() const
VECTOR2I m_pos
Definition: sch_symbol.h:908
wxString GetSymbolIDAsString() const
Definition: sch_symbol.h:205
LIB_ID m_lib_id
Name and library the symbol was loaded from, i.e. 74xx:74LS00.
Definition: sch_symbol.h:909
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
wxString GetDatasheet() const
Return the documentation text for the given part alias.
Definition: sch_symbol.cpp:329
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
void SetLibId(const LIB_ID &aName)
Definition: sch_symbol.cpp:287
bool HasBrightenedPins()
std::vector< SCH_FIELD > & GetFields()
Return a vector of fields from the symbol.
Definition: sch_symbol.h:511
bool GetShowPinNumbers() const
Definition: sch_symbol.h:867
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset) override
Print a symbol.
Definition: sch_symbol.cpp:520
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &aScanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
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.
void PlotDNP(PLOTTER *aPlotter) const
Plot the red 'X' over the symbol.
bool operator!=(const SCH_SYMBOL &aSymbol) const
LIB_ITEM * GetDrawItem(const VECTOR2I &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
int GetUnit() const
Definition: sch_symbol.h:258
SYMBOL_ORIENTATION_PROP GetOrientationProp() const
Definition: sch_symbol.h:363
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:588
void SetDNP(bool aDNP)
Definition: sch_symbol.h:865
void SetBodyStyle(int aBodyStyle)
Definition: sch_symbol.cpp:464
void UpdateUnit(int aUnit)
Change the unit number to aUnit without setting any internal flags.
Definition: sch_symbol.cpp:458
int GetY() const
Definition: sch_symbol.h:819
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:867
wxString GetClass() const override
Return the class name.
Definition: sch_symbol.h:148
void RemoveInstance(const SCH_SHEET_PATH &aInstancePath)
Definition: sch_symbol.cpp:610
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:784
void SetMirrorY(bool aMirror)
Definition: sch_symbol.h:397
void PlotPins(PLOTTER *aPlotter) const
Plot just the symbol pins.
void SetRefProp(const wxString aRef)
Definition: sch_symbol.h:559
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:928
int GetX() const
Definition: sch_symbol.h:816
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:293
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true, bool aCaseInsensitive=false)
Search for a SCH_FIELD with aFieldName.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:748
bool GetShowPinNames() const
Definition: sch_symbol.h:878
bool IsInNetlist() const
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
void ClearBrightenedPins()
void SetY(int aY)
Definition: sch_symbol.h:820
void SetShowPinNumbers(bool aShow)
Definition: sch_symbol.h:872
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_symbol.cpp:236
void SetExcludedFromSim(bool aExclude) override
Definition: sch_symbol.h:856
bool GetMirrorX() const
Definition: sch_symbol.h:392
wxString GetRefProp() const
Definition: sch_symbol.h:555
bool m_excludedFromSim
True to exclude from simulation.
Definition: sch_symbol.h:937
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:950
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
bool m_excludedFromBoard
True to exclude from netlist when updating board.
Definition: sch_symbol.h:939
static std::unordered_map< TRANSFORM, int > s_transformToOrientationCache
Definition: sch_symbol.h:947
VECTOR2I GetPinPhysicalPosition(const LIB_PIN *Pin) const
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
Definition: sch_symbol.cpp:338
std::vector< SCH_SYMBOL_INSTANCE > m_instanceReferences
Definition: sch_symbol.h:944
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void SetValueProp(const wxString aRef)
Definition: sch_symbol.h:567
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_SETTINGS &aPlotSettings) const override
Plot the schematic item to aPlotter.
bool IsPointClickableAnchor(const VECTOR2I &aPos) const override
void UpdateFields(const SCH_SHEET_PATH *aPath, bool aUpdateStyle, bool aUpdateRef, bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields)
Restore fields to the original library values.
wxString m_schLibSymbolName
The name used to look up a symbol in the symbol library embedded in a schematic.
Definition: sch_symbol.h:926
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:790
void ClearAnnotation(const SCH_SHEET_PATH *aSheetPath, bool aResetPrefix)
Clear exiting symbol annotation.
void SetOrientationProp(SYMBOL_ORIENTATION_PROP aAngle)
Orientation/mirroring access for property manager.
Definition: sch_symbol.h:354
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
Definition: sch_symbol.cpp:934
void PrintBackground(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset) override
Print only the background parts of a symbol (if any)
Definition: sch_symbol.cpp:508
wxString GetDescription() const
Definition: sch_symbol.cpp:311
std::vector< SCH_FIELD > m_fields
Variable length list of fields.
Definition: sch_symbol.h:929
std::unordered_map< LIB_PIN *, SCH_PIN * > m_pinMap
library pin pointer : SCH_PIN's index
Definition: sch_symbol.h:934
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
int m_unit
The unit for multiple part per package symbols.
Definition: sch_symbol.h:910
void SetFootprintFieldText(const wxString &aFootprint)
Definition: sch_symbol.cpp:944
bool doIsConnected(const VECTOR2I &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
bool GetExcludedFromBOM() const
Definition: sch_symbol.h:858
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:646
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:242
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:813
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
void SetTransform(const TRANSFORM &aTransform)
Definition: sch_symbol.cpp:476
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
void Init(const VECTOR2I &pos=VECTOR2I(0, 0))
Definition: sch_symbol.cpp:205
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:251
bool GetExcludedFromSim() const override
Definition: sch_symbol.h:855
bool operator<(const SCH_ITEM &aItem) const override
bool m_DNP
True if symbol is set to 'Do Not Populate'.
Definition: sch_symbol.h:940
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
wxString GetKeyWords() const
Definition: sch_symbol.cpp:320
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
SCH_FIELD * GetFieldById(int aFieldId)
Return a field in this symbol.
Definition: sch_symbol.cpp:962
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos, const SCH_SHEET_PATH *aPath=nullptr) override
Test if the symbol's dangling state has changed for all pins.
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
Definition: sch_symbol.cpp:586
TRANSFORM & GetTransform()
Definition: sch_symbol.h:314
bool HasUnitDisplayName(int aUnit)
Return true if the given unit aUnit has a display name set.
Definition: sch_symbol.cpp:500
void SetExcludedFromBOM(bool aIncludeInBOM)
Definition: sch_symbol.h:859
BOX2I doGetBoundingBox(bool aIncludePins, bool aIncludeFields) const
bool GetMirrorY() const
Definition: sch_symbol.h:409
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
const wxString GetValueFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
Definition: sch_symbol.cpp:918
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
int GetOrientation() const
Get the display symbol orientation.
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:826
void SetX(int aX)
Definition: sch_symbol.h:817
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
void SetShowPinNames(bool aShow)
Definition: sch_symbol.h:880
bool m_isInNetlist
True if the symbol should appear in the netlist.
Definition: sch_symbol.h:936
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:876
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:452
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:203
wxString GetUnitDisplayName(int aUnit)
Return the display name for a given unit aUnit.
Definition: sch_symbol.cpp:492
BOX2I GetBodyAndPinsBoundingBox() const
Return a bounding box for the symbol body and pins but not the fields.
TRANSFORM m_transform
The rotation/mirror transformation.
Definition: sch_symbol.h:928
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
wxString GetValueProp() const
Definition: sch_symbol.h:563
SCH_SYMBOL & operator=(const SCH_ITEM &aItem)
std::vector< LIB_PIN * > GetAllLibPins() const
bool GetExcludedFromBoard() const
Definition: sch_symbol.h:861
void SetPrefix(const wxString &aPrefix)
Definition: sch_symbol.h:305
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:998
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:892
bool m_excludedFromBOM
True to exclude from bill of materials export.
Definition: sch_symbol.h:938
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:222
std::vector< std::unique_ptr< SCH_PIN > > m_pins
a SCH_PIN for every LIB_PIN (all units)
Definition: sch_symbol.h:933
void SetExcludedFromBoard(bool aIncludeOnBoard)
Definition: sch_symbol.h:862
int m_bodyStyle
The alternate body style for symbols that have more than one body style defined.
Definition: sch_symbol.h:911
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:302
int GetBodyStyle() const
Definition: sch_symbol.h:300
BOX2I GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the pins or fields.
void SortInstances(bool(*aSortFunction)(const SCH_SYMBOL_INSTANCE &aLhs, const SCH_SYMBOL_INSTANCE &aRhs))
Definition: sch_symbol.cpp:638
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:266
bool IsPower() const
std::unique_ptr< LIB_SYMBOL > m_part
a flattened copy of the LIB_SYMBOL from the PROJECT's libraries.
Definition: sch_symbol.h:931
bool operator==(const SCH_SYMBOL &aSymbol) const
bool GetDNP() const
Definition: sch_symbol.h:864
const TEMPLATE_FIELDNAMES & GetTemplateFieldNames()
Return a template field name list for read only access.
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:46
int x2
Definition: transform.h:50
int y1
Definition: transform.h:49
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition: transform.cpp:59
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:44
int y2
Definition: transform.h:51
int x1
Definition: transform.h:48
bool empty() const
Definition: utf8.h:103
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _HKI(x)
T Convert(const wxString &aValue)
Convert a wxString to a generic type T.
Definition: eagle_parser.h:181
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:437
INSPECT_RESULT
Definition: eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:78
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define IS_DANGLING
indicates a pin is dangling
void GRFilledSegment(wxDC *aDC, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:278
static const bool FILLED
Definition: gr_basic.cpp:30
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
@ LAYER_DANGLING
Definition: layer_ids.h:379
@ LAYER_DEVICE
Definition: layer_ids.h:368
@ LAYER_VALUEPART
Definition: layer_ids.h:364
@ LAYER_FIELDS
Definition: layer_ids.h:365
@ LAYER_DEVICE_BACKGROUND
Definition: layer_ids.h:384
@ LAYER_REFERENCEPART
Definition: layer_ids.h:363
@ LAYER_OP_CURRENTS
Definition: layer_ids.h:400
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:393
@ LAYER_DNP_MARKER
Definition: layer_ids.h:380
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:61
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
Message panel definition file.
wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:210
wxString EllipsizeStatusText(wxWindow *aWindow, const wxString &aString)
Ellipsize text (at the end) to be no more than 1/3 of the window width.
Definition: ui_common.cpp:192
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
wxString GetRefDesUnannotated(const wxString &aSource)
Return an unannotated refdes from either a prefix or an existing refdes.
see class PGM_BASE
#define TYPE_HASH(x)
Definition: property.h:67
#define NO_SETTER(owner, type)
Definition: property.h:764
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:755
#define REGISTER_TYPE(x)
Definition: property_mgr.h:366
Collection of utility functions for component reference designators (refdes)
@ NO_CONNECT_END
Definition: sch_item.h:77
@ SHEET_LABEL_END
Definition: sch_item.h:76
@ LABEL_END
Definition: sch_item.h:73
@ JUNCTION_END
Definition: sch_item.h:71
@ PIN_END
Definition: sch_item.h:72
@ WIRE_END
Definition: sch_item.h:69
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
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:54
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:73
static struct SCH_SYMBOL_DESC _SCH_SYMBOL_DESC
SYMBOL_ORIENTATION_PROP
Definition: sch_symbol.h:97
@ SYMBOL_ANGLE_180
Definition: sch_symbol.h:100
@ SYMBOL_ANGLE_0
Definition: sch_symbol.h:98
@ SYMBOL_ANGLE_90
Definition: sch_symbol.h:99
@ SYMBOL_ANGLE_270
Definition: sch_symbol.h:101
@ SYM_ORIENT_270
Definition: sch_symbol.h:88
@ SYM_ROTATE_CLOCKWISE
Definition: sch_symbol.h:83
@ SYM_ROTATE_COUNTERCLOCKWISE
Definition: sch_symbol.h:84
@ SYM_MIRROR_Y
Definition: sch_symbol.h:90
@ SYM_ORIENT_180
Definition: sch_symbol.h:87
@ SYM_MIRROR_X
Definition: sch_symbol.h:89
@ SYM_NORMAL
Definition: sch_symbol.h:82
@ SYM_ORIENT_90
Definition: sch_symbol.h:86
@ SYM_ORIENT_0
Definition: sch_symbol.h:85
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:391
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
bool draw_visible_fields
Definition: lib_symbol.h:66
TRANSFORM transform
Definition: lib_symbol.h:64
std::vector< std::pair< int, wxString > > Fields
Definition: sch_screen.h:84
bool m_PDFPropertyPopups
Definition: sch_plotter.h:90
A simple container for schematic symbol instance information.
Hold a name of a symbol's field, field value, and default visibility.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
MANDATORY_FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
wxLogTrace helper definitions.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:228
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_FIELD_LOCATE_REFERENCE_T
Definition: typeinfo.h:168
@ SCH_FIELD_LOCATE_FOOTPRINT_T
Definition: typeinfo.h:170
@ SCH_SYMBOL_T
Definition: typeinfo.h:160
@ SCH_FIELD_T
Definition: typeinfo.h:159
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:187
@ SCH_FIELD_LOCATE_VALUE_T
Definition: typeinfo.h:169
@ LIB_PIN_T
Definition: typeinfo.h:206
@ SCH_FIELD_LOCATE_DATASHEET_T
Definition: typeinfo.h:171
@ SCH_SYMBOL_LOCATE_POWER_T
Definition: typeinfo.h:184
@ SCH_PIN_T
Definition: typeinfo.h:163
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588