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 The 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_collectors.h>
26#include <sch_commit.h>
27#include <sch_edit_frame.h>
28#include <widgets/msgpanel.h>
29#include <bitmaps.h>
30#include <core/mirror.h>
31#include <sch_shape.h>
32#include <pgm_base.h>
33#include <sim/sim_model.h>
34#include <sim/spice_generator.h>
35#include <sim/sim_lib_mgr.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#include <sch_rule_area.h>
44
45#include <utility>
46#include <validators.h>
47
48
49std::unordered_map<TRANSFORM, int> SCH_SYMBOL::s_transformToOrientationCache;
50
51
56std::string toUTFTildaText( const wxString& txt )
57{
58 std::string ret = TO_UTF8( txt );
59
60 for( char& c : ret )
61 {
62 if( (unsigned char) c <= ' ' )
63 c = '~';
64 }
65
66 return ret;
67}
68
69
71 SYMBOL( nullptr, SCH_SYMBOL_T )
72{
73 Init( VECTOR2I( 0, 0 ) );
74}
75
76
77SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const LIB_ID& aLibId,
78 const SCH_SHEET_PATH* aSheet, int aUnit, int aBodyStyle,
79 const VECTOR2I& aPosition, EDA_ITEM* aParent ) :
80 SYMBOL( aParent, SCH_SYMBOL_T )
81{
82 Init( aPosition );
83
84 m_unit = aUnit;
85 m_bodyStyle = aBodyStyle;
86 m_lib_id = aLibId;
87
88 std::unique_ptr< LIB_SYMBOL > part;
89
90 part = aSymbol.Flatten();
91 part->SetParent();
92 SetLibSymbol( part.release() );
93
94 // Copy fields from the library symbol
95 UpdateFields( aSheet,
96 true, /* update style */
97 false, /* update ref */
98 false, /* update other fields */
99 true, /* reset ref */
100 true /* reset other fields */ );
101
102 m_prefix = UTIL::GetRefDesPrefix( m_part->GetReferenceField().GetText() );
103
104 if( aSheet )
106
107 // Inherit the include in bill of materials and board netlist settings from flattened
108 // library symbol.
109 m_excludedFromSim = m_part->GetExcludedFromSim();
110 m_excludedFromBOM = m_part->GetExcludedFromBOM();
111 m_excludedFromBoard = m_part->GetExcludedFromBoard();
112}
113
114
115SCH_SYMBOL::SCH_SYMBOL( const LIB_SYMBOL& aSymbol, const SCH_SHEET_PATH* aSheet,
116 const PICKED_SYMBOL& aSel, const VECTOR2I& aPosition, EDA_ITEM* aParent ) :
117 SCH_SYMBOL( aSymbol, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, aPosition, aParent )
118{
119 // Set any fields that were modified as part of the symbol selection
120 for( const auto& [fieldId, fieldValue] : aSel.Fields )
121 {
122 if( fieldId == FIELD_T::REFERENCE )
123 SetRef( aSheet, fieldValue );
124 else if( SCH_FIELD* field = GetField( fieldId ) )
125 field->SetText( fieldValue );
126 }
127}
128
129
131 SYMBOL( aSymbol )
132{
133 m_parent = aSymbol.m_parent;
134 m_pos = aSymbol.m_pos;
135 m_unit = aSymbol.m_unit;
136 m_bodyStyle = aSymbol.m_bodyStyle;
137 m_lib_id = aSymbol.m_lib_id;
139 m_DNP = aSymbol.m_DNP;
140
141 const_cast<KIID&>( m_Uuid ) = aSymbol.m_Uuid;
142
143 m_transform = aSymbol.m_transform;
144 m_prefix = aSymbol.m_prefix;
146 m_fields = aSymbol.m_fields;
147
148 // Re-parent the fields, which before this had aSymbol as parent
149 for( SCH_FIELD& field : m_fields )
150 field.SetParent( this );
151
152 m_pins.clear();
153
154 // Copy (and re-parent) the pins
155 for( const std::unique_ptr<SCH_PIN>& pin : aSymbol.m_pins )
156 {
157 m_pins.emplace_back( std::make_unique<SCH_PIN>( *pin ) );
158 m_pins.back()->SetParent( this );
159 }
160
161 if( aSymbol.m_part )
162 SetLibSymbol( new LIB_SYMBOL( *aSymbol.m_part ) );
163
166}
167
168
170{
171}
172
173
174void SCH_SYMBOL::Init( const VECTOR2I& pos )
175{
177 m_pos = pos;
178 m_unit = 1; // In multi unit chip - which unit to draw.
179 m_bodyStyle = BODY_STYLE::BASE; // De Morgan Handling
180
181 // The rotation/mirror transformation matrix. pos normal
183
184 auto addField =
185 [&]( FIELD_T id, SCH_LAYER_ID layer )
186 {
187 m_fields.emplace_back( this, id, GetCanonicalFieldName( id ) );
188 m_fields.back().SetTextPos( pos );
189 m_fields.back().SetLayer( layer );
190 };
191
192 // construct only the mandatory fields
193 addField( FIELD_T::REFERENCE, LAYER_REFERENCEPART );
194 addField( FIELD_T::VALUE, LAYER_VALUEPART );
195 addField( FIELD_T::FOOTPRINT, LAYER_FIELDS );
196 addField( FIELD_T::DATASHEET, LAYER_FIELDS );
197 addField( FIELD_T::DESCRIPTION, LAYER_FIELDS );
198
199 m_prefix = wxString( wxT( "U" ) );
200 m_isInNetlist = true;
201}
202
203
205{
206 return new SCH_SYMBOL( *this );
207}
208
209
211{
212 return m_part == nullptr;
213}
214
215
217{
218 // If a symbol's anchor is not grid-aligned to its pins then moving from the anchor is
219 // going to end up moving the symbol's pins off-grid.
220
221 // The minimal grid size allowed to place a pin is 25 mils
222 const int min_grid_size = schIUScale.MilsToIU( 25 );
223
224 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
225 {
226 if( ( ( pin->GetPosition().x - m_pos.x ) % min_grid_size ) != 0 )
227 return false;
228
229 if( ( ( pin->GetPosition().y - m_pos.y ) % min_grid_size ) != 0 )
230 return false;
231 }
232
233 return true;
234}
235
236
237void SCH_SYMBOL::SetLibId( const LIB_ID& aLibId )
238{
239 m_lib_id = aLibId;
240}
241
242
244{
245 if( !m_schLibSymbolName.IsEmpty() )
246 return m_schLibSymbolName;
247 else
248 return m_lib_id.Format();
249}
250
251
253{
254 wxCHECK2( !aLibSymbol || aLibSymbol->IsRoot(), aLibSymbol = nullptr );
255
256 m_part.reset( aLibSymbol );
257 UpdatePins();
258}
259
260
262{
263 if( m_part )
264 return m_part->GetDescription();
265
266 return wxEmptyString;
267}
268
269
271{
272 if( m_part )
273 return m_part->GetKeyWords();
274
275 return wxEmptyString;
276}
277
278
280{
281 if( m_part )
282 return m_part->GetDatasheetField().GetText();
283
284 return wxEmptyString;
285}
286
287
289{
290 std::map<wxString, wxString> altPinMap;
291 std::map<wxString, std::set<SCH_PIN*>> pinUuidMap;
292 std::set<SCH_PIN*> unassignedSchPins;
293 std::set<SCH_PIN*> unassignedLibPins;
294
295 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
296 {
297 pinUuidMap[ pin->GetNumber() ].insert( pin.get() );
298
299 unassignedSchPins.insert( pin.get() );
300
301 if( !pin->GetAlt().IsEmpty() )
302 altPinMap[ pin->GetNumber() ] = pin->GetAlt();
303
304 pin->SetLibPin( nullptr );
305 }
306
307 m_pinMap.clear();
308
309 if( !m_part )
310 return;
311
312 for( SCH_PIN* libPin : m_part->GetPins() )
313 {
314 // NW: Don't filter by unit: this data-structure is used for all instances,
315 // some of which might have different units.
316 if( libPin->GetBodyStyle() && m_bodyStyle && m_bodyStyle != libPin->GetBodyStyle() )
317 continue;
318
319 SCH_PIN* pin = nullptr;
320
321 auto ii = pinUuidMap.find( libPin->GetNumber() );
322
323 if( ii == pinUuidMap.end() || ii->second.empty() )
324 {
325 unassignedLibPins.insert( libPin );
326 continue;
327 }
328
329 auto it = ii->second.begin();
330 pin = *it;
331 ii->second.erase( it );
332 pin->SetLibPin( libPin );
333 pin->SetPosition( libPin->GetPosition() );
334
335 unassignedSchPins.erase( pin );
336
337 auto iii = altPinMap.find( libPin->GetNumber() );
338
339 if( iii != altPinMap.end() )
340 pin->SetAlt( iii->second );
341
342 m_pinMap[ libPin ] = pin;
343 }
344
345 // Add any pins that were not found in the symbol
346 for( SCH_PIN* libPin : unassignedLibPins )
347 {
348 SCH_PIN* pin = nullptr;
349
350 // First try to re-use an existing pin
351 if( !unassignedSchPins.empty() )
352 {
353 auto it = unassignedSchPins.begin();
354 pin = *it;
355 unassignedSchPins.erase( it );
356 }
357 else
358 {
359 // This is a pin that was not found in the symbol, so create a new one.
360 pin = m_pins.emplace_back( std::make_unique<SCH_PIN>( SCH_PIN( this, libPin ) ) ).get();
361 }
362
363 m_pinMap[ libPin ] = pin;
364 pin->SetLibPin( libPin );
365 pin->SetPosition( libPin->GetPosition() );
366 pin->SetNumber( libPin->GetNumber() );
367
368 auto iii = altPinMap.find( libPin->GetNumber() );
369
370 if( iii != altPinMap.end() )
371 pin->SetAlt( iii->second );
372 }
373
374 // If we have any pins left in the symbol that were not found in the library, remove them.
375 for( auto it1 = m_pins.begin(); it1 != m_pins.end() && !unassignedSchPins.empty(); )
376 {
377 auto it2 = unassignedSchPins.find( it1->get() );
378
379 if( it2 != unassignedSchPins.end() )
380 {
381 it1 = m_pins.erase( it1 );
382 unassignedSchPins.erase( it2 );
383 }
384 else
385 {
386 ++it1;
387 }
388 }
389
390 // If the symbol is selected, then its pins are selected.
391 if( IsSelected() )
392 {
393 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
394 pin->SetSelected();
395 }
396
397}
398
399
401{
402 if( m_bodyStyle != aBodyStyle )
403 {
404 m_bodyStyle = ( m_bodyStyle == BODY_STYLE::BASE ) ? BODY_STYLE::DEMORGAN
405 : BODY_STYLE::BASE;
406
407 // The body style may have a different pin layout so the update the pin map.
408 UpdatePins();
409 }
410}
411
412
413void SCH_SYMBOL::SetBodyStyle( int aBodyStyle )
414{
415 if( HasAlternateBodyStyle() && m_bodyStyle != aBodyStyle )
416 {
417 m_bodyStyle = ( m_bodyStyle == BODY_STYLE::BASE ) ? BODY_STYLE::DEMORGAN
418 : BODY_STYLE::BASE;
419
420 // The body style may have a different pin layout so the update the pin map.
421 UpdatePins();
422 }
423}
424
425
427{
428 if( m_part )
429 return m_part->HasAlternateBodyStyle();
430
431 return false;
432}
433
434
436{
437 if( m_part )
438 return m_part->GetUnitCount();
439
440 return 0;
441}
442
443
444wxString SCH_SYMBOL::GetUnitDisplayName( int aUnit, bool aLabel ) const
445{
446 if( m_part )
447 return m_part->GetUnitDisplayName( aUnit, aLabel );
448 else if( aLabel )
449 return wxString::Format( _( "Unit %s" ), SubReference( aUnit ) );
450 else
451 return SubReference( aUnit );
452}
453
454
455wxString SCH_SYMBOL::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
456{
457 if( m_part )
458 return m_part->GetBodyStyleDescription( aBodyStyle, aLabel );
459 else if( aBodyStyle == BODY_STYLE::DEMORGAN )
460 return aLabel ? _( "Alternate" ) : wxString( _HKI( "Alternate" ) );
461 else if( aBodyStyle == BODY_STYLE::BASE )
462 return aLabel ? _( "Standard" ) : wxString( _HKI( "Standard" ) );
463 else
464 return wxT( "?" );
465}
466
467
468bool SCH_SYMBOL::GetInstance( SCH_SYMBOL_INSTANCE& aInstance, const KIID_PATH& aSheetPath,
469 bool aTestFromEnd ) const
470{
471 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
472 {
473 if( !aTestFromEnd )
474 {
475 if( instance.m_Path == aSheetPath )
476 {
477 aInstance = instance;
478 return true;
479 }
480 }
481 else if( instance.m_Path.EndsWith( aSheetPath ) )
482 {
483 aInstance = instance;
484 return true;
485 }
486 }
487
488 return false;
489}
490
491
492void SCH_SYMBOL::RemoveInstance( const SCH_SHEET_PATH& aInstancePath )
493{
494 RemoveInstance( aInstancePath.Path() );
495}
496
497
498void SCH_SYMBOL::RemoveInstance( const KIID_PATH& aInstancePath )
499{
500 // Search for an existing path and remove it if found
501 // (search from back to avoid invalidating iterator on remove)
502 for( int ii = m_instanceReferences.size() - 1; ii >= 0; --ii )
503 {
504 if( m_instanceReferences[ii].m_Path == aInstancePath )
505 {
506 wxLogTrace( traceSchSheetPaths, wxS( "Removing symbol instance:\n"
507 " sheet path %s\n"
508 " reference %s, unit %d from symbol %s." ),
509 aInstancePath.AsString(),
510 m_instanceReferences[ii].m_Reference,
511 m_instanceReferences[ii].m_Unit,
512 m_Uuid.AsString() );
513
514 m_instanceReferences.erase( m_instanceReferences.begin() + ii );
515 }
516 }
517}
518
519
520void SCH_SYMBOL::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef, int aUnit )
521{
522 SCH_SYMBOL_INSTANCE instance;
523 instance.m_Path = aPath;
524 instance.m_Reference = aRef;
525 instance.m_Unit = aUnit;
526
527 AddHierarchicalReference( instance );
528}
529
530
532{
533 RemoveInstance( aInstance.m_Path );
534
535 SCH_SYMBOL_INSTANCE instance = aInstance;
536
537 wxLogTrace( traceSchSheetPaths, wxS( "Adding symbol '%s' instance:\n"
538 " sheet path '%s'\n"
539 " reference '%s'\n"
540 " unit %d\n" ),
542 instance.m_Path.AsString(),
543 instance.m_Reference,
544 instance.m_Unit );
545
546 m_instanceReferences.push_back( instance );
547
548 // This should set the default instance to the first saved instance data for each symbol
549 // when importing sheets.
550 if( m_instanceReferences.size() == 1 )
551 {
552 GetField( FIELD_T::REFERENCE )->SetText( instance.m_Reference );
553 m_unit = instance.m_Unit;
554 }
555}
556
557
558const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit ) const
559{
560 KIID_PATH path = sheet->Path();
561 wxString ref;
562 wxString subRef;
563
564 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
565 {
566 if( instance.m_Path == path )
567 {
568 ref = instance.m_Reference;
569 subRef = SubReference( instance.m_Unit );
570 break;
571 }
572 }
573
574 // If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
575 // use this as a default for this path. This will happen if we load a version 1 schematic
576 // file. It will also mean that multiple instances of the same sheet by default all have
577 // the same symbol references, but perhaps this is best.
578 if( ref.IsEmpty() && !GetField( FIELD_T::REFERENCE )->GetText().IsEmpty() )
579 ref = GetField( FIELD_T::REFERENCE )->GetText();
580
581 if( ref.IsEmpty() )
583
584 if( aIncludeUnit && GetUnitCount() > 1 )
585 ref += subRef;
586
587 return ref;
588}
589
590
591void SCH_SYMBOL::SetRefProp( const wxString& aRef )
592{
593 FIELD_VALIDATOR validator( FIELD_T::REFERENCE );
594
595 if( validator.DoValidate( aRef, nullptr ) )
596 SetRef( &Schematic()->CurrentSheet(), aRef );
597}
598
599
600void SCH_SYMBOL::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
601{
602 KIID_PATH path = sheet->Path();
603 bool found = false;
604
605 // check to see if it is already there before inserting it
607 {
608 if( instance.m_Path == path )
609 {
610 found = true;
611 instance.m_Reference = ref;
612 break;
613 }
614 }
615
616 if( !found )
618
619 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
620 pin->ClearDefaultNetName( sheet );
621
622 if( Schematic() && *sheet == Schematic()->CurrentSheet() )
623 GetField( FIELD_T::REFERENCE )->SetText( ref );
624
625 // Reinit the m_prefix member if needed
627
628 if( m_prefix.IsEmpty() )
629 m_prefix = wxT( "U" );
630
631 // Power symbols have references starting with # and are not included in netlists
632 m_isInNetlist = ! ref.StartsWith( wxT( "#" ) );
633}
634
635
636bool SCH_SYMBOL::IsAnnotated( const SCH_SHEET_PATH* aSheet ) const
637{
638 KIID_PATH path = aSheet->Path();
639
640 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
641 {
642 if( instance.m_Path == path )
643 return !instance.m_Reference.IsEmpty() && instance.m_Reference.Last() != '?';
644 }
645
646 return false;
647}
648
649
651{
652 wxString refDesignator = GetField( FIELD_T::REFERENCE )->GetText();
653
654 refDesignator.Replace( "~", " " );
655
656 wxString prefix = refDesignator;
657
658 while( prefix.Length() )
659 {
660 wxUniCharRef last = prefix.Last();
661
662 if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
663 prefix.RemoveLast();
664 else
665 break;
666 }
667
668 // Avoid a prefix containing trailing/leading spaces
669 prefix.Trim( true );
670 prefix.Trim( false );
671
672 if( !prefix.IsEmpty() )
673 SetPrefix( prefix );
674}
675
676
677wxString SCH_SYMBOL::SubReference( int aUnit, bool aAddSeparator ) const
678{
679 if( SCHEMATIC* schematic = Schematic() )
680 return schematic->Settings().SubReference( aUnit, aAddSeparator );
681
682 return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
683}
684
685
687{
688 KIID_PATH path = aSheet->Path();
689
690 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
691 {
692 if( instance.m_Path == path )
693 return instance.m_Unit;
694 }
695
696 // If it was not found in m_Paths array, then use m_unit. This will happen if we load a
697 // version 1 schematic file.
698 return m_unit;
699}
700
701
702void SCH_SYMBOL::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
703{
704 KIID_PATH path = aSheet->Path();
705
706 // check to see if it is already there before inserting it
708 {
709 if( instance.m_Path == path )
710 {
711 instance.m_Unit = aUnitSelection;
712 return;
713 }
714 }
715
716 // didn't find it; better add it
718}
719
720
721void SCH_SYMBOL::SetUnitSelection( int aUnitSelection )
722{
724 instance.m_Unit = aUnitSelection;
725}
726
727
728const wxString SCH_SYMBOL::GetValue( bool aResolve, const SCH_SHEET_PATH* aPath,
729 bool aAllowExtraText ) const
730{
731 if( aResolve )
732 return GetField( FIELD_T::VALUE )->GetShownText( aPath, aAllowExtraText );
733
734 return GetField( FIELD_T::VALUE )->GetText();
735}
736
737
738void SCH_SYMBOL::SetValueFieldText( const wxString& aValue )
739{
740 GetField( FIELD_T::VALUE )->SetText( aValue );
741}
742
743
744const wxString SCH_SYMBOL::GetFootprintFieldText( bool aResolve, const SCH_SHEET_PATH* aPath,
745 bool aAllowExtraText ) const
746{
747 if( aResolve )
748 return GetField( FIELD_T::FOOTPRINT )->GetShownText( aPath, aAllowExtraText );
749
750 return GetField( FIELD_T::FOOTPRINT )->GetText();
751}
752
753
754void SCH_SYMBOL::SetFootprintFieldText( const wxString& aFootprint )
755{
756 GetField( FIELD_T::FOOTPRINT )->SetText( aFootprint );
757}
758
759
761{
762 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
763 return field;
764
765 m_fields.emplace_back( this, aFieldType );
766 return &m_fields.back();
767}
768
769
770const SCH_FIELD* SCH_SYMBOL::GetField( FIELD_T aFieldType ) const
771{
772 return FindField( m_fields, aFieldType );
773}
774
775
776SCH_FIELD* SCH_SYMBOL::GetField( const wxString& aFieldName )
777{
778 return FindField( m_fields, aFieldName );
779}
780
781
782const SCH_FIELD* SCH_SYMBOL::GetField( const wxString& aFieldName ) const
783{
784 return FindField( m_fields, aFieldName );
785}
786
787
788void SCH_SYMBOL::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly ) const
789{
790 for( const SCH_FIELD& field : m_fields )
791 {
792 if( aVisibleOnly )
793 {
794 if( !field.IsVisible() || field.GetText().IsEmpty() )
795 continue;
796 }
797
798 aVector.push_back( const_cast<SCH_FIELD*>( &field ) );
799 }
800
801 std::sort( aVector.begin(), aVector.end(),
802 []( SCH_FIELD* lhs, SCH_FIELD* rhs )
803 {
804 return lhs->GetOrdinal() < rhs->GetOrdinal();
805 } );
806}
807
808
810{
811 return NextFieldOrdinal( m_fields );
812}
813
814
816{
817 m_fields.push_back( aField );
818 return &m_fields.back();
819}
820
821
822void SCH_SYMBOL::RemoveField( const wxString& aFieldName )
823{
824 for( unsigned ii = 0; ii < m_fields.size(); ++ii )
825 {
826 if( m_fields[ii].IsMandatory() )
827 continue;
828
829 if( aFieldName == m_fields[ii].GetName( false ) )
830 {
831 m_fields.erase( m_fields.begin() + ii );
832 return;
833 }
834 }
835}
836
837
839{
840 for( SCH_FIELD& field : m_fields )
841 {
842 if( field.GetName().IsSameAs( aFieldName, false ) )
843 return &field;
844 }
845
846 return nullptr;
847}
848
849
850void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef,
851 bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields )
852{
853 if( m_part )
854 {
855 std::vector<SCH_FIELD*> fields;
856 m_part->GetFields( fields );
857
858 for( const SCH_FIELD* libField : fields )
859 {
860 SCH_FIELD* schField;
861 FIELD_T fieldType = FIELD_T::USER;
862
863 if( libField->IsMandatory() )
864 {
865 fieldType = libField->GetId();
866 schField = GetField( fieldType );
867 }
868 else
869 {
870 schField = GetField( libField->GetCanonicalName() );
871
872 if( !schField )
873 {
874 schField = AddField( SCH_FIELD( this, FIELD_T::USER, libField->GetCanonicalName() ) );
875 schField->ImportValues( *libField );
876 schField->SetTextPos( m_pos + libField->GetTextPos() );
877 }
878 }
879
880 schField->SetPrivate( libField->IsPrivate() );
881
882 if( aUpdateStyle )
883 {
884 schField->ImportValues( *libField );
885 schField->SetTextPos( m_pos + libField->GetTextPos() );
886 }
887
888 if( fieldType == FIELD_T::REFERENCE && aPath )
889 {
890 if( aResetRef )
891 SetRef( aPath, m_part->GetField( FIELD_T::REFERENCE )->GetText() );
892 else if( aUpdateRef )
893 SetRef( aPath, libField->GetText() );
894 }
895 else if( fieldType == FIELD_T::VALUE )
896 {
897 SetValueFieldText( UnescapeString( libField->GetText() ) );
898 }
899 else if( fieldType == FIELD_T::DATASHEET )
900 {
901 if( aResetOtherFields )
902 schField->SetText( GetDatasheet() ); // alias-specific value
903 else if( aUpdateOtherFields )
904 schField->SetText( libField->GetText() );
905 }
906 else
907 {
908 if( aResetOtherFields || aUpdateOtherFields )
909 schField->SetText( libField->GetText() );
910 }
911 }
912 }
913}
914
915
916void SCH_SYMBOL::SyncOtherUnits( const SCH_SHEET_PATH& aSourceSheet, SCH_COMMIT& aCommit,
917 PROPERTY_BASE* aProperty )
918{
919 bool updateValue = true;
920 bool updateExclFromBOM = true;
921 bool updateExclFromBoard = true;
922 bool updateDNP = true;
923 bool updateOtherFields = true;
924 bool updatePins = true;
925
926 if( aProperty )
927 {
928 updateValue = aProperty->Name() == _HKI( "Value" );
929 updateExclFromBoard = aProperty->Name() == _HKI( "Exclude From Board" );
930 updateExclFromBOM = aProperty->Name() == _HKI( "Exclude From Bill of Materials" );
931 updateDNP = aProperty->Name() == _HKI( "Do not Populate" );
932 updateOtherFields = false;
933 updatePins = false;
934 }
935
936 if( !updateValue
937 && !updateExclFromBOM
938 && !updateExclFromBoard
939 && !updateDNP
940 && !updateOtherFields
941 && !updatePins )
942 {
943 return;
944 }
945
946 // Keep fields other than the reference, include/exclude flags, and alternate pin assignments
947 // in sync in multi-unit parts.
948 if( GetUnitCount() > 1 && IsAnnotated( &aSourceSheet ) )
949 {
950 wxString ref = GetRef( &aSourceSheet );
951
952 for( SCH_SHEET_PATH& sheet : Schematic()->Hierarchy() )
953 {
954 SCH_SCREEN* screen = sheet.LastScreen();
955 std::vector<SCH_SYMBOL*> otherUnits;
956
957 CollectOtherUnits( ref, m_unit, m_lib_id, sheet, &otherUnits );
958
959 for( SCH_SYMBOL* otherUnit : otherUnits )
960 {
961 aCommit.Modify( otherUnit, screen );
962
963 if( updateValue )
964 otherUnit->SetValueFieldText( GetField( FIELD_T::VALUE )->GetText() );
965
966 if( updateOtherFields )
967 {
968 for( SCH_FIELD& field : m_fields )
969 {
970 if( field.GetId() == FIELD_T::REFERENCE || field.GetId() == FIELD_T::VALUE )
971 {
972 // already handled
973 continue;
974 }
975
976 SCH_FIELD* otherField;
977
978 if( field.IsMandatory() )
979 otherField = otherUnit->GetField( field.GetId() );
980 else
981 otherField = otherUnit->GetField( field.GetName() );
982
983 if( otherField )
984 {
985 otherField->SetText( field.GetText() );
986 }
987 else
988 {
989 SCH_FIELD newField( field );
990 const_cast<KIID&>( newField.m_Uuid ) = KIID();
991
992 newField.Offset( -GetPosition() );
993 newField.Offset( otherUnit->GetPosition() );
994
995 newField.SetParent( otherUnit );
996 otherUnit->AddField( newField );
997 }
998 }
999
1000 for( int ii = (int) otherUnit->GetFields().size() - 1; ii >= 0; ii-- )
1001 {
1002 SCH_FIELD& otherField = otherUnit->GetFields()[ii];
1003
1004 if( !otherField.IsMandatory() && !GetField( otherField.GetName() ) )
1005 otherUnit->GetFields().erase( otherUnit->GetFields().begin() + ii );
1006 }
1007 }
1008
1009 if( updateExclFromBOM )
1011
1012 if( updateExclFromBoard )
1013 otherUnit->SetExcludedFromBoard( m_excludedFromBoard );
1014
1015 if( updateDNP )
1016 otherUnit->SetDNP( m_DNP );
1017
1018 if( updatePins )
1019 {
1020 for( const std::unique_ptr<SCH_PIN>& model_pin : m_pins )
1021 {
1022 SCH_PIN* src_pin = otherUnit->GetPin( model_pin->GetNumber() );
1023
1024 if( src_pin )
1025 src_pin->SetAlt( model_pin->GetAlt() );
1026 }
1027 }
1028 }
1029 }
1030 }
1031}
1032
1033
1034void SCH_SYMBOL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
1035{
1036 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1037 aFunction( pin.get() );
1038
1039 for( SCH_FIELD& field : m_fields )
1040 aFunction( &field );
1041}
1042
1043
1044SCH_PIN* SCH_SYMBOL::GetPin( const wxString& aNumber ) const
1045{
1046 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1047 {
1048 if( pin->GetNumber() == aNumber )
1049 return pin.get();
1050 }
1051
1052 return nullptr;
1053}
1054
1055
1056const SCH_PIN* SCH_SYMBOL::GetPin( const VECTOR2I& aPos ) const
1057{
1058 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1059 {
1060 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
1061 : GetUnit();
1062 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
1063 : GetBodyStyle();
1064
1065 if( pin_unit > 0 && pin_unit != GetUnit() )
1066 continue;
1067
1068 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
1069 continue;
1070
1071 if( pin->GetPosition() == aPos )
1072 return pin.get();
1073 }
1074
1075 return nullptr;
1076}
1077
1078
1079std::vector<SCH_PIN*> SCH_SYMBOL::GetLibPins() const
1080{
1081 if( m_part )
1082 return m_part->GetPins( m_unit, m_bodyStyle );
1083
1084 return std::vector<SCH_PIN*>();
1085}
1086
1087
1088std::vector<SCH_PIN*> SCH_SYMBOL::GetAllLibPins() const
1089{
1090 if( m_part )
1091 return m_part->GetPins();
1092
1093 return std::vector<SCH_PIN*>();
1094}
1095
1096
1098{
1099 return m_part ? m_part->GetPinCount() : 0;
1100}
1101
1102
1104{
1105 auto it = m_pinMap.find( aLibPin );
1106
1107 if( it != m_pinMap.end() )
1108 return it->second;
1109
1110 wxFAIL_MSG_AT( "Pin not found", __FILE__, __LINE__, __FUNCTION__ );
1111 return nullptr;
1112}
1113
1114
1115std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
1116{
1117 std::vector<SCH_PIN*> pins;
1118 int unit = m_unit;
1119
1120 if( !aSheet && Schematic() )
1121 aSheet = &Schematic()->CurrentSheet();
1122
1123 if( aSheet )
1124 unit = GetUnitSelection( aSheet );
1125
1126 for( const std::unique_ptr<SCH_PIN>& p : m_pins )
1127 {
1128 if( unit && p->GetLibPin() && p->GetLibPin()->GetUnit()
1129 && ( p->GetLibPin()->GetUnit() != unit ) )
1130 {
1131 continue;
1132 }
1133
1134 pins.push_back( p.get() );
1135 }
1136
1137 return pins;
1138}
1139
1140
1141std::vector<SCH_PIN*> SCH_SYMBOL::GetPins() const
1142{
1143 return GetPins( nullptr );
1144}
1145
1146
1148{
1149 wxCHECK_RET( aItem != nullptr && aItem->Type() == SCH_SYMBOL_T,
1150 wxT( "Cannot swap data with invalid symbol." ) );
1151
1152 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
1153
1154 std::swap( m_lib_id, symbol->m_lib_id );
1155
1156 m_pins.swap( symbol->m_pins ); // std::vector's swap()
1157
1158 for( std::unique_ptr<SCH_PIN>& pin : symbol->m_pins )
1159 pin->SetParent( symbol );
1160
1161 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1162 pin->SetParent( this );
1163
1164 LIB_SYMBOL* libSymbol = symbol->m_part.release();
1165 symbol->m_part = std::move( m_part );
1166 symbol->UpdatePins();
1167 m_part.reset( libSymbol );
1168 UpdatePins();
1169
1170 std::swap( m_pos, symbol->m_pos );
1171 std::swap( m_unit, symbol->m_unit );
1172 std::swap( m_bodyStyle, symbol->m_bodyStyle );
1173
1174 m_fields.swap( symbol->m_fields ); // std::vector's swap()
1175
1176 for( SCH_FIELD& field : symbol->m_fields )
1177 field.SetParent( symbol );
1178
1179 for( SCH_FIELD& field : m_fields )
1180 field.SetParent( this );
1181
1182 TRANSFORM tmp = m_transform;
1183
1184 m_transform = symbol->m_transform;
1185 symbol->m_transform = tmp;
1186
1187 std::swap( m_excludedFromSim, symbol->m_excludedFromSim );
1188 std::swap( m_excludedFromBOM, symbol->m_excludedFromBOM );
1189 std::swap( m_DNP, symbol->m_DNP );
1190 std::swap( m_excludedFromBoard, symbol->m_excludedFromBoard );
1191
1192 std::swap( m_instanceReferences, symbol->m_instanceReferences );
1193 std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName );
1194}
1195
1196
1197void SCH_SYMBOL::GetContextualTextVars( wxArrayString* aVars ) const
1198{
1199 for( const SCH_FIELD& field : m_fields )
1200 {
1201 if( field.IsPrivate() )
1202 continue;
1203
1204 if( field.IsMandatory() )
1205 aVars->push_back( field.GetCanonicalName().Upper() );
1206 else
1207 aVars->push_back( field.GetName() );
1208 }
1209
1210 aVars->push_back( wxT( "OP" ) );
1211 aVars->push_back( wxT( "FOOTPRINT_LIBRARY" ) );
1212 aVars->push_back( wxT( "FOOTPRINT_NAME" ) );
1213 aVars->push_back( wxT( "UNIT" ) );
1214 aVars->push_back( wxT( "SHORT_REFERENCE" ) );
1215 aVars->push_back( wxT( "SYMBOL_LIBRARY" ) );
1216 aVars->push_back( wxT( "SYMBOL_NAME" ) );
1217 aVars->push_back( wxT( "SYMBOL_DESCRIPTION" ) );
1218 aVars->push_back( wxT( "SYMBOL_KEYWORDS" ) );
1219 aVars->push_back( wxT( "EXCLUDE_FROM_BOM" ) );
1220 aVars->push_back( wxT( "EXCLUDE_FROM_BOARD" ) );
1221 aVars->push_back( wxT( "EXCLUDE_FROM_SIM" ) );
1222 aVars->push_back( wxT( "DNP" ) );
1223 aVars->push_back( wxT( "SHORT_NET_NAME(<pin_number>)" ) );
1224 aVars->push_back( wxT( "NET_NAME(<pin_number>)" ) );
1225 aVars->push_back( wxT( "NET_CLASS(<pin_number>)" ) );
1226 aVars->push_back( wxT( "PIN_NAME(<pin_number>)" ) );
1227}
1228
1229
1230bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
1231{
1232 static wxRegEx operatingPoint( wxT( "^"
1233 "OP"
1234 "(:[^.]*)?" // pin
1235 "(.([0-9])?" // precisionStr
1236 "([a-zA-Z]*))?" // rangeStr
1237 "$" ) );
1238
1239 wxCHECK( aPath, false );
1240
1241 SCHEMATIC* schematic = Schematic();
1242
1243 if( !schematic )
1244 return false;
1245
1246 if( operatingPoint.Matches( *token ) )
1247 {
1248 wxString pin( operatingPoint.GetMatch( *token, 1 ).Lower() );
1249 wxString precisionStr( operatingPoint.GetMatch( *token, 3 ) );
1250 wxString rangeStr( operatingPoint.GetMatch( *token, 4 ) );
1251
1252 int precision = precisionStr.IsEmpty() ? 3 : precisionStr[0] - '0';
1253 wxString range = rangeStr.IsEmpty() ? wxString( wxS( "~A" ) ) : rangeStr;
1254
1255 SIM_LIB_MGR simLibMgr( &schematic->Project() );
1256
1257 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
1258 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
1259
1260 if( m_part )
1261 embeddedFilesStack.push_back( m_part->GetEmbeddedFiles() );
1262
1263 simLibMgr.SetFilesStack( std::move( embeddedFilesStack ) );
1264
1265 NULL_REPORTER devnull;
1266 SIM_MODEL& model = simLibMgr.CreateModel( aPath, const_cast<SCH_SYMBOL&>( *this ),
1267 true, aDepth + 1, devnull ).model;
1268 SPICE_ITEM spiceItem;
1269 spiceItem.refName = GetRef( aPath );
1270
1271 wxString spiceRef = model.SpiceGenerator().ItemName( spiceItem );
1272 spiceRef = spiceRef.Lower();
1273
1274 if( pin.IsEmpty() )
1275 {
1276 *token = schematic->GetOperatingPoint( spiceRef, precision, range );
1277 return true;
1278 }
1279 else if( pin == wxS( ":power" ) )
1280 {
1281 if( rangeStr.IsEmpty() )
1282 range = wxS( "~W" );
1283
1284 *token = schematic->GetOperatingPoint( spiceRef + wxS( ":power" ), precision, range );
1285 return true;
1286 }
1287 else
1288 {
1289 pin = pin.SubString( 1, -1 ); // Strip ':' from front
1290
1291 for( const std::reference_wrapper<const SIM_MODEL_PIN>& modelPin : model.GetPins() )
1292 {
1293 SCH_PIN* symbolPin = GetPin( modelPin.get().symbolPinNumber );
1294
1295 if( pin == symbolPin->GetName().Lower() || pin == symbolPin->GetNumber().Lower() )
1296 {
1297 if( model.GetPins().size() == 2 )
1298 {
1299 *token = schematic->GetOperatingPoint( spiceRef, precision, range );
1300 }
1301 else
1302 {
1303 wxString signalName = spiceRef + wxS( ":" ) + modelPin.get().modelPinName;
1304 *token = schematic->GetOperatingPoint( signalName, precision, range );
1305 }
1306
1307 return true;
1308 }
1309 }
1310 }
1311
1312 *token = wxS( "?" );
1313 return true;
1314 }
1315
1316 if( token->Contains( ':' ) )
1317 {
1318 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
1319 return true;
1320 }
1321
1322 for( const SCH_FIELD& field : m_fields )
1323 {
1324 wxString fieldName = field.IsMandatory() ? field.GetCanonicalName()
1325 : field.GetName();
1326
1327 wxString textToken = field.GetText();
1328 textToken.Replace( " ", wxEmptyString );
1329 wxString tokenString = "${" + fieldName + "}";
1330
1331 // If the field data is just a reference to the field, don't resolve
1332 if( textToken.IsSameAs( tokenString, false ) )
1333 return true;
1334
1335 if( token->IsSameAs( fieldName, false ) )
1336 {
1337 if( field.GetId() == FIELD_T::REFERENCE )
1338 *token = GetRef( aPath, true );
1339 else
1340 *token = field.GetShownText( aPath, false, aDepth + 1 );
1341
1342 return true;
1343 }
1344 }
1345
1346 // Consider missing simulation fields as empty, not un-resolved
1347 if( token->IsSameAs( wxT( "SIM.DEVICE" ) )
1348 || token->IsSameAs( wxT( "SIM.TYPE" ) )
1349 || token->IsSameAs( wxT( "SIM.PINS" ) )
1350 || token->IsSameAs( wxT( "SIM.PARAMS" ) )
1351 || token->IsSameAs( wxT( "SIM.LIBRARY" ) )
1352 || token->IsSameAs( wxT( "SIM.NAME" ) ) )
1353 {
1354 *token = wxEmptyString;
1355 return true;
1356 }
1357
1358 for( const TEMPLATE_FIELDNAME& templateFieldname :
1360 {
1361 if( token->IsSameAs( templateFieldname.m_Name )
1362 || token->IsSameAs( templateFieldname.m_Name.Upper() ) )
1363 {
1364 // If we didn't find it in the fields list then it isn't set on this symbol.
1365 // Just return an empty string.
1366 *token = wxEmptyString;
1367 return true;
1368 }
1369 }
1370
1371 if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
1372 {
1373 wxString footprint = GetFootprintFieldText( true, aPath, false );
1374
1375 wxArrayString parts = wxSplit( footprint, ':' );
1376
1377 if( parts.Count() > 0 )
1378 *token = parts[ 0 ];
1379 else
1380 *token = wxEmptyString;
1381
1382 return true;
1383 }
1384 else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
1385 {
1386 wxString footprint = GetFootprintFieldText( true, aPath, false );
1387
1388 wxArrayString parts = wxSplit( footprint, ':' );
1389
1390 if( parts.Count() > 1 )
1391 *token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
1392 else
1393 *token = wxEmptyString;
1394
1395 return true;
1396 }
1397 else if( token->IsSameAs( wxT( "UNIT" ) ) )
1398 {
1399 *token = SubReference( GetUnitSelection( aPath ) );
1400 return true;
1401 }
1402 else if( token->IsSameAs( wxT( "SHORT_REFERENCE" ) ) )
1403 {
1404 *token = GetRef( aPath, false );
1405 return true;
1406 }
1407 else if( token->IsSameAs( wxT( "SYMBOL_LIBRARY" ) ) )
1408 {
1410 return true;
1411 }
1412 else if( token->IsSameAs( wxT( "SYMBOL_NAME" ) ) )
1413 {
1415 return true;
1416 }
1417 else if( token->IsSameAs( wxT( "SYMBOL_DESCRIPTION" ) ) )
1418 {
1419 *token = GetDescription();
1420 return true;
1421 }
1422 else if( token->IsSameAs( wxT( "SYMBOL_KEYWORDS" ) ) )
1423 {
1424 *token = GetKeyWords();
1425 return true;
1426 }
1427 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
1428 {
1429 *token = wxEmptyString;
1430
1431 if( aPath->GetExcludedFromBOM() || this->ResolveExcludedFromBOM() )
1432 *token = _( "Excluded from BOM" );
1433
1434 return true;
1435 }
1436 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
1437 {
1438 *token = wxEmptyString;
1439
1440 if( aPath->GetExcludedFromBoard() || this->ResolveExcludedFromBoard() )
1441 *token = _( "Excluded from board" );
1442
1443 return true;
1444 }
1445 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
1446 {
1447 *token = wxEmptyString;
1448
1449 if( aPath->GetExcludedFromSim() || this->ResolveExcludedFromSim() )
1450 *token = _( "Excluded from simulation" );
1451
1452 return true;
1453 }
1454 else if( token->IsSameAs( wxT( "DNP" ) ) )
1455 {
1456 *token = wxEmptyString;
1457
1458 if( aPath->GetDNP() || this->ResolveDNP() )
1459 *token = _( "DNP" );
1460
1461 return true;
1462 }
1463 else if( token->StartsWith( wxT( "SHORT_NET_NAME(" ) )
1464 || token->StartsWith( wxT( "NET_NAME(" ) )
1465 || token->StartsWith( wxT( "NET_CLASS(" ) )
1466 || token->StartsWith( wxT( "PIN_NAME(" ) ) )
1467 {
1468 wxString pinNumber = token->AfterFirst( '(' );
1469 pinNumber = pinNumber.BeforeLast( ')' );
1470
1471 for( SCH_PIN* pin : GetPins( aPath ) )
1472 {
1473 if( pin->GetNumber() == pinNumber )
1474 {
1475 if( token->StartsWith( wxT( "PIN_NAME" ) ) )
1476 {
1477 *token = pin->GetAlt().IsEmpty() ? pin->GetName() : pin->GetAlt();
1478 return true;
1479 }
1480
1481 SCH_CONNECTION* conn = pin->Connection( aPath );
1482
1483 if( !conn )
1484 *token = wxEmptyString;
1485 else if( token->StartsWith( wxT( "SHORT_NET_NAME" ) ) )
1486 *token = conn->LocalName();
1487 else if( token->StartsWith( wxT( "NET_NAME" ) ) )
1488 *token = conn->Name();
1489 else if( token->StartsWith( wxT( "NET_CLASS" ) ) )
1490 *token = pin->GetEffectiveNetClass( aPath )->GetName();
1491
1492 return true;
1493 }
1494 }
1495 }
1496
1497 // See if parent can resolve it (this will recurse to ancestors)
1498 if( aPath->Last() && aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
1499 return true;
1500
1501 return false;
1502}
1503
1504
1505void SCH_SYMBOL::ClearAnnotation( const SCH_SHEET_PATH* aSheetPath, bool aResetPrefix )
1506{
1507 if( aSheetPath )
1508 {
1509 KIID_PATH path = aSheetPath->Path();
1510
1511 for( SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1512 {
1513 if( instance.m_Path == path )
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 else
1523 {
1524 for( SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1525 {
1526 if( instance.m_Reference.IsEmpty() || aResetPrefix)
1527 instance.m_Reference = UTIL::GetRefDesUnannotated( m_prefix );
1528 else
1529 instance.m_Reference = UTIL::GetRefDesUnannotated( instance.m_Reference );
1530 }
1531 }
1532
1533 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1534 pin->ClearDefaultNetName( aSheetPath );
1535
1536 // These 2 changes do not work in complex hierarchy.
1537 // When a clear annotation is made, the calling function must call a
1538 // UpdateAllScreenReferences for the active sheet.
1539 // But this call cannot made here.
1540 wxString currentReference = GetField( FIELD_T::REFERENCE )->GetText();
1541
1542 if( currentReference.IsEmpty() || aResetPrefix )
1543 GetField( FIELD_T::REFERENCE )->SetText( UTIL::GetRefDesUnannotated( m_prefix ) );
1544 else
1545 GetField( FIELD_T::REFERENCE )->SetText( UTIL::GetRefDesUnannotated( currentReference ) );
1546}
1547
1548
1550{
1551 // An empty sheet path is illegal, at a minimum the root sheet UUID must be present.
1552 wxCHECK( aSheetPath.size() > 0, false );
1553
1554 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1555 {
1556 // if aSheetPath is found, nothing to do:
1557 if( instance.m_Path == aSheetPath )
1558 return false;
1559 }
1560
1561 // This entry does not exist: add it, with its last-used reference
1562 AddHierarchicalReference( aSheetPath, GetField( FIELD_T::REFERENCE )->GetText(), m_unit );
1563 return true;
1564}
1565
1566
1567void SCH_SYMBOL::SetOrientation( int aOrientation )
1568{
1569 TRANSFORM temp = TRANSFORM();
1570 bool transform = false;
1571
1572 switch( aOrientation )
1573 {
1574 case SYM_ORIENT_0:
1575 case SYM_NORMAL: // default transform matrix
1577 break;
1578
1579 case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1580 temp.x1 = 0;
1581 temp.y1 = 1;
1582 temp.x2 = -1;
1583 temp.y2 = 0;
1584 transform = true;
1585 break;
1586
1587 case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1588 temp.x1 = 0;
1589 temp.y1 = -1;
1590 temp.x2 = 1;
1591 temp.y2 = 0;
1592 transform = true;
1593 break;
1594
1595 case SYM_MIRROR_Y: // Mirror Y (incremental transform)
1596 temp.x1 = -1;
1597 temp.y1 = 0;
1598 temp.x2 = 0;
1599 temp.y2 = 1;
1600 transform = true;
1601 break;
1602
1603 case SYM_MIRROR_X: // Mirror X (incremental transform)
1604 temp.x1 = 1;
1605 temp.y1 = 0;
1606 temp.x2 = 0;
1607 temp.y2 = -1;
1608 transform = true;
1609 break;
1610
1611 case SYM_ORIENT_90:
1614 break;
1615
1616 case SYM_ORIENT_180:
1620 break;
1621
1622 case SYM_ORIENT_270:
1625 break;
1626
1627 case ( SYM_ORIENT_0 + SYM_MIRROR_X ):
1630 break;
1631
1632 case ( SYM_ORIENT_0 + SYM_MIRROR_Y ):
1635 break;
1636
1641 break;
1642
1643 case ( SYM_ORIENT_90 + SYM_MIRROR_X ):
1646 break;
1647
1648 case ( SYM_ORIENT_90 + SYM_MIRROR_Y ):
1651 break;
1652
1657 break;
1658
1659 case ( SYM_ORIENT_180 + SYM_MIRROR_X ):
1662 break;
1663
1664 case ( SYM_ORIENT_180 + SYM_MIRROR_Y ):
1667 break;
1668
1673 break;
1674
1675 case ( SYM_ORIENT_270 + SYM_MIRROR_X ):
1678 break;
1679
1680 case ( SYM_ORIENT_270 + SYM_MIRROR_Y ):
1683 break;
1684
1689 break;
1690
1691 default:
1692 transform = false;
1693 wxFAIL_MSG( "Invalid schematic symbol orientation type." );
1694 break;
1695 }
1696
1697 if( transform )
1698 {
1699 /* The new matrix transform is the old matrix transform modified by the
1700 * requested transformation, which is the temp transform (rot,
1701 * mirror ..) in order to have (in term of matrix transform):
1702 * transform coord = new_m_transform * coord
1703 * where transform coord is the coord modified by new_m_transform from
1704 * the initial value coord.
1705 * new_m_transform is computed (from old_m_transform and temp) to
1706 * have:
1707 * transform coord = old_m_transform * temp
1708 */
1709 TRANSFORM newTransform;
1710
1711 newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1712 newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1713 newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1714 newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1715 m_transform = newTransform;
1716 }
1717}
1718
1719
1721{
1722 /*
1723 * This is slow, but also a bizarre algorithm. I don't feel like unteasing the algorithm right
1724 * now, so let's just cache it for the moment.
1725 */
1728
1729 int rotate_values[] =
1730 {
1743 };
1744
1745 // Try to find the current transform option:
1746 TRANSFORM transform = m_transform;
1747 SCH_SYMBOL temp( *this );
1748 temp.SetParentGroup( nullptr );
1749
1750 for( int type_rotate : rotate_values )
1751 {
1752 temp.SetOrientation( type_rotate );
1753
1754 if( transform == temp.GetTransform() )
1755 {
1757 return type_rotate;
1758 }
1759 }
1760
1761 // Error: orientation not found in list (should not happen)
1762 wxFAIL_MSG( "Schematic symbol orientation matrix internal error." );
1763
1764 return SYM_NORMAL;
1765}
1766
1767
1768#if defined(DEBUG)
1769
1770void SCH_SYMBOL::Show( int nestLevel, std::ostream& os ) const
1771{
1772 // for now, make it look like XML:
1773 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1774 << " ref=\"" << TO_UTF8( GetField( FIELD_T::REFERENCE )->GetName() )
1775 << '"' << " chipName=\""
1776 << GetLibId().Format().wx_str() << '"' << m_pos
1777 << " layer=\"" << m_layer
1778 << '"' << ">\n";
1779
1780 // skip the reference, it's been output already.
1781 for( int i = 1; i < (int) GetFields().size(); ++i )
1782 {
1783 const wxString& value = GetFields()[i].GetText();
1784
1785 if( !value.IsEmpty() )
1786 {
1787 NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1788 << TO_UTF8( GetFields()[i].GetName() )
1789 << '"' << " value=\""
1790 << TO_UTF8( value ) << "\"/>\n";
1791 }
1792 }
1793
1794 NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1795}
1796
1797#endif
1798
1799
1800BOX2I SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) const
1801{
1802 BOX2I bBox;
1803
1804 if( m_part )
1805 bBox = m_part->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
1806 else
1808 false );
1809
1810 bBox = m_transform.TransformCoordinate( bBox );
1811 bBox.Normalize();
1812
1813 bBox.Offset( m_pos );
1814
1815 if( aIncludeFields )
1816 {
1817 for( const SCH_FIELD& field : m_fields )
1818 {
1819 if( field.IsVisible() )
1820 bBox.Merge( field.GetBoundingBox() );
1821 }
1822 }
1823
1824 return bBox;
1825}
1826
1827
1829{
1830 try
1831 {
1832 return doGetBoundingBox( false, false );
1833 }
1834 catch( const boost::bad_pointer& e )
1835 {
1836 wxFAIL_MSG( wxString::Format( wxT( "Boost pointer exception occurred: %s" ), e.what() ) );
1837 return BOX2I();
1838 }
1839}
1840
1841
1843{
1844 return doGetBoundingBox( true, false );
1845}
1846
1847
1849{
1850 return doGetBoundingBox( true, true );
1851}
1852
1853
1854void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1855{
1856 wxString msg;
1857
1858 SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1859 SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1860
1861 auto addExcludes =
1862 [&]()
1863 {
1864 wxArrayString msgs;
1865
1866 if( GetExcludedFromSim() )
1867 msgs.Add( _( "Simulation" ) );
1868
1869 if( GetExcludedFromBOM() )
1870 msgs.Add( _( "BOM" ) );
1871
1872 if( GetExcludedFromBoard() )
1873 msgs.Add( _( "Board" ) );
1874
1875 if( GetDNP() )
1876 msgs.Add( _( "DNP" ) );
1877
1878 msg = wxJoin( msgs, '|' );
1879 msg.Replace( '|', wxS( ", " ) );
1880
1881 if( !msg.empty() )
1882 aList.emplace_back( _( "Exclude from" ), msg );
1883 };
1884
1885 // part and alias can differ if alias is not the root
1886 if( m_part )
1887 {
1888 if( m_part.get() != LIB_SYMBOL::GetDummy() )
1889 {
1890 if( m_part->IsPower() )
1891 {
1892 // Don't use GetShownText(); we want to see the variable references here
1893 aList.emplace_back( _( "Power symbol" ),
1894 KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::VALUE )->GetText() ) );
1895 }
1896 else
1897 {
1898 aList.emplace_back( _( "Reference" ),
1899 UnescapeString( GetRef( currentSheet ) ) );
1900
1901 // Don't use GetShownText(); we want to see the variable references here
1902 aList.emplace_back( _( "Value" ),
1903 KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::VALUE )->GetText() ) );
1904 addExcludes();
1905 aList.emplace_back( _( "Name" ),
1907 GetLibId().GetLibItemName() ) );
1908 }
1909
1910#if 0 // Display symbol flags, for debug only
1911 aList.emplace_back( _( "flags" ), wxString::Format( "%X", GetEditFlags() ) );
1912#endif
1913
1914 if( !m_part->IsRoot() )
1915 {
1916 msg = _( "Missing parent" );
1917
1918 std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock();
1919
1920 if( parent )
1921 msg = parent->GetName();
1922
1923 aList.emplace_back( _( "Derived from" ), UnescapeString( msg ) );
1924 }
1925 else if( !m_lib_id.GetLibNickname().empty() )
1926 {
1927 aList.emplace_back( _( "Library" ), m_lib_id.GetLibNickname() );
1928 }
1929 else
1930 {
1931 aList.emplace_back( _( "Library" ), _( "Undefined!!!" ) );
1932 }
1933
1934 // Display the current associated footprint, if exists.
1935 // Don't use GetShownText(); we want to see the variable references here
1936 msg = KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::FOOTPRINT )->GetText() );
1937
1938 if( msg.IsEmpty() )
1939 msg = _( "<Unknown>" );
1940
1941 aList.emplace_back( _( "Footprint" ), msg );
1942
1943 // Display description of the symbol, and keywords found in lib
1944 aList.emplace_back( _( "Description" ) + wxT( ": " )
1945 + GetField( FIELD_T::DESCRIPTION )->GetText(),
1946 _( "Keywords" ) + wxT( ": " ) + m_part->GetKeyWords() );
1947 }
1948 }
1949 else
1950 {
1951 aList.emplace_back( _( "Reference" ), GetRef( currentSheet ) );
1952
1953 // Don't use GetShownText(); we want to see the variable references here
1954 aList.emplace_back( _( "Value" ),
1955 KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::VALUE )->GetText() ) );
1956 addExcludes();
1957 aList.emplace_back( _( "Name" ),
1958 KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) );
1959
1960 wxString libNickname = GetLibId().GetLibNickname();
1961
1962 if( libNickname.empty() )
1963 msg = _( "No library defined!" );
1964 else
1965 msg.Printf( _( "Symbol not found in %s!" ), libNickname );
1966
1967 aList.emplace_back( _( "Library" ), msg );
1968 }
1969}
1970
1971
1973{
1974 return BITMAPS::add_component;
1975}
1976
1977
1979{
1980 return GetLibSymbolRef()->GetEmbeddedFiles();
1981}
1982
1983
1985{
1986 int dx = m_pos.x;
1987
1989 MIRROR( m_pos.x, aCenter );
1990 dx -= m_pos.x; // dx,0 is the move vector for this transform
1991
1992 for( SCH_FIELD& field : m_fields )
1993 {
1994 // Move the fields to the new position because the symbol itself has moved.
1995 VECTOR2I pos = field.GetTextPos();
1996 pos.x -= dx;
1997 field.SetTextPos( pos );
1998 }
1999}
2000
2001
2003{
2004 int dy = m_pos.y;
2005
2007 MIRROR( m_pos.y, aCenter );
2008 dy -= m_pos.y; // 0,dy is the move vector for this transform
2009
2010 for( SCH_FIELD& field : m_fields )
2011 {
2012 // Move the fields to the new position because the symbol itself has moved.
2013 VECTOR2I pos = field.GetTextPos();
2014 pos.y -= dy;
2015 field.SetTextPos( pos );
2016 }
2017}
2018
2019
2020void SCH_SYMBOL::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
2021{
2022 VECTOR2I prev = m_pos;
2023
2024 RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
2025
2027
2028 for( SCH_FIELD& field : m_fields )
2029 {
2030 // Move the fields to the new position because the symbol itself has moved.
2031 VECTOR2I pos = field.GetTextPos();
2032 pos.x -= prev.x - m_pos.x;
2033 pos.y -= prev.y - m_pos.y;
2034 field.SetTextPos( pos );
2035 }
2036}
2037
2038
2039bool SCH_SYMBOL::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
2040{
2041 if( aSearchData.searchMetadata )
2042 {
2043 if( EDA_ITEM::Matches( GetSchSymbolLibraryName(), aSearchData ) )
2044 return true;
2045
2046 if( EDA_ITEM::Matches( GetDescription(), aSearchData ) )
2047 return true;
2048
2049 if( EDA_ITEM::Matches( GetKeyWords(), aSearchData ) )
2050 return true;
2051 }
2052
2053 for( SCH_ITEM& drawItem : GetLibSymbolRef()->GetDrawItems() )
2054 {
2055 if( drawItem.Matches( aSearchData, aAuxData ) )
2056 return true;
2057 }
2058
2059 // Symbols are searchable via the child field and pin item text.
2060 return false;
2061}
2062
2063
2064void SCH_SYMBOL::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
2065{
2066 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2067 {
2068 SCH_PIN* lib_pin = pin->GetLibPin();
2069
2070 if( lib_pin && lib_pin->GetUnit() && m_unit && ( m_unit != lib_pin->GetUnit() ) )
2071 continue;
2072
2073 DANGLING_END_ITEM item( PIN_END, lib_pin, GetPinPhysicalPosition( lib_pin ), this );
2074 aItemList.push_back( item );
2075 }
2076}
2077
2078
2079bool SCH_SYMBOL::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
2080 std::vector<DANGLING_END_ITEM>& aItemListByPos,
2081 const SCH_SHEET_PATH* aPath )
2082{
2083 bool changed = false;
2084
2085 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2086 {
2087 bool previousState = pin->IsDangling();
2088 pin->SetIsDangling( true );
2089
2090 VECTOR2I pos = m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos;
2091
2092 auto lower = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, pos );
2093 bool do_break = false;
2094
2095 for( auto it = lower; it < aItemListByPos.end() && it->GetPosition() == pos; it++ )
2096 {
2097 DANGLING_END_ITEM& each_item = *it;
2098
2099 // Some people like to stack pins on top of each other in a symbol to indicate
2100 // internal connection. While technically connected, it is not particularly useful
2101 // to display them that way, so skip any pins that are in the same symbol as this
2102 // one.
2103 if( each_item.GetParent() == this )
2104 continue;
2105
2106 switch( each_item.GetType() )
2107 {
2108 case PIN_END:
2109 case LABEL_END:
2110 case SHEET_LABEL_END:
2111 case WIRE_END:
2112 case NO_CONNECT_END:
2113 case JUNCTION_END:
2114 pin->SetIsDangling( false );
2115 do_break = true;
2116 break;
2117
2118 default:
2119 break;
2120 }
2121
2122 if( do_break )
2123 break;
2124 }
2125
2126 changed = ( changed || ( previousState != pin->IsDangling() ) );
2127 }
2128
2129 return changed;
2130}
2131
2132
2134{
2135 if( ( aPin == nullptr ) || ( aPin->Type() != SCH_PIN_T ) )
2136 return VECTOR2I( 0, 0 );
2137
2139}
2140
2141
2143 const SCH_SHEET_PATH* aInstance ) const
2144{
2145 // Do not compare to ourself.
2146 if( aItem == this )
2147 return false;
2148
2149 const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( aItem );
2150
2151 // Don't compare against a different SCH_ITEM.
2152 wxCHECK( symbol, false );
2153
2154 // The move algorithm marks any pins that are being moved without something attached
2155 // (during the move) as dangling. We always need to recheck connectivity in this case
2156 // or we will not notice changes when the user places the symbol back in the same position
2157 // it started.
2158 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2159 {
2160 if( pin->IsDangling() )
2161 return true;
2162 }
2163
2164 if( GetPosition() != symbol->GetPosition() )
2165 return true;
2166
2167 if( GetLibId() != symbol->GetLibId() )
2168 return true;
2169
2170 if( GetUnitSelection( aInstance ) != symbol->GetUnitSelection( aInstance ) )
2171 return true;
2172
2173 if( GetRef( aInstance ) != symbol->GetRef( aInstance ) )
2174 return true;
2175
2176 // Power symbol value field changes are connectivity changes.
2177 if( IsPower()
2178 && ( GetValue( true, aInstance, false ) != symbol->GetValue( true, aInstance, false ) ) )
2179 return true;
2180
2181 if( m_pins.size() != symbol->m_pins.size() )
2182 return true;
2183
2184 for( size_t i = 0; i < m_pins.size(); i++ )
2185 {
2186 if( m_pins[i]->HasConnectivityChanges( symbol->m_pins[i].get() ) )
2187 return true;
2188 }
2189
2190 return false;
2191}
2192
2193
2194std::vector<VECTOR2I> SCH_SYMBOL::GetConnectionPoints() const
2195{
2196 std::vector<VECTOR2I> retval;
2197
2198 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2199 {
2200 // Collect only pins attached to the current unit and convert.
2201 // others are not associated to this symbol instance
2202 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2203 : GetUnit();
2204 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2205 : GetBodyStyle();
2206
2207 if( pin_unit > 0 && pin_unit != GetUnit() )
2208 continue;
2209
2210 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2211 continue;
2212
2213 retval.push_back( m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos );
2214 }
2215
2216 return retval;
2217}
2218
2219
2221{
2222 if( m_part )
2223 {
2224 // Calculate the position relative to the symbol.
2225 VECTOR2I libPosition = aPosition - m_pos;
2226
2227 return m_part->LocateDrawItem( m_unit, m_bodyStyle, aType, libPosition, m_transform );
2228 }
2229
2230 return nullptr;
2231}
2232
2233
2234wxString SCH_SYMBOL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2235{
2236 return wxString::Format( _( "Symbol %s [%s]" ),
2237 KIUI::EllipsizeMenuText( GetField( FIELD_T::REFERENCE )->GetText() ),
2238 KIUI::EllipsizeMenuText( GetLibId().GetLibItemName() ) );
2239}
2240
2241
2242INSPECT_RESULT SCH_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
2243 const std::vector<KICAD_T>& aScanTypes )
2244{
2245 for( KICAD_T scanType : aScanTypes )
2246 {
2247 if( scanType == SCH_LOCATE_ANY_T || ( scanType == SCH_SYMBOL_T )
2248 || ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
2249 {
2250 if( INSPECT_RESULT::QUIT == aInspector( this, aTestData ) )
2251 return INSPECT_RESULT::QUIT;
2252 }
2253
2254 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
2255 {
2256 for( SCH_FIELD& field : m_fields )
2257 {
2258 if( INSPECT_RESULT::QUIT == aInspector( &field, (void*) this ) )
2259 return INSPECT_RESULT::QUIT;
2260 }
2261 }
2262
2263 if( scanType == SCH_FIELD_LOCATE_REFERENCE_T )
2264 {
2265 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::REFERENCE ), (void*) this ) )
2266 return INSPECT_RESULT::QUIT;
2267 }
2268
2269 if( scanType == SCH_FIELD_LOCATE_VALUE_T
2270 || ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
2271 {
2272 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::VALUE ), (void*) this ) )
2273 return INSPECT_RESULT::QUIT;
2274 }
2275
2276 if( scanType == SCH_FIELD_LOCATE_FOOTPRINT_T )
2277 {
2278 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::FOOTPRINT ), (void*) this ) )
2279 return INSPECT_RESULT::QUIT;
2280 }
2281
2282 if( scanType == SCH_FIELD_LOCATE_DATASHEET_T )
2283 {
2284 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::DATASHEET ), (void*) this ) )
2285 return INSPECT_RESULT::QUIT;
2286 }
2287
2288 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_PIN_T )
2289 {
2290 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2291 {
2292 // Collect only pins attached to the current unit and convert.
2293 // others are not associated to this symbol instance
2294 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2295 : GetUnit();
2296 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2297 : GetBodyStyle();
2298
2299 if( pin_unit > 0 && pin_unit != GetUnit() )
2300 continue;
2301
2302 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2303 continue;
2304
2305 if( INSPECT_RESULT::QUIT == aInspector( pin.get(), (void*) this ) )
2306 return INSPECT_RESULT::QUIT;
2307 }
2308 }
2309 }
2310
2311 return INSPECT_RESULT::CONTINUE;
2312}
2313
2314
2315bool SCH_SYMBOL::operator <( const SCH_ITEM& aItem ) const
2316{
2317 if( Type() != aItem.Type() )
2318 return Type() < aItem.Type();
2319
2320 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( &aItem );
2321
2323
2324 if( rect.GetArea() != symbol->GetBodyAndPinsBoundingBox().GetArea() )
2325 return rect.GetArea() < symbol->GetBodyAndPinsBoundingBox().GetArea();
2326
2327 if( m_pos.x != symbol->m_pos.x )
2328 return m_pos.x < symbol->m_pos.x;
2329
2330 if( m_pos.y != symbol->m_pos.y )
2331 return m_pos.y < symbol->m_pos.y;
2332
2333 return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
2334}
2335
2336
2337bool SCH_SYMBOL::operator==( const SCH_SYMBOL& aSymbol ) const
2338{
2339 std::vector<SCH_FIELD*> fields, otherFields;
2340
2341 GetFields( fields, false );
2342 aSymbol.GetFields( otherFields, false );
2343
2344 if( fields.size() != otherFields.size() )
2345 return false;
2346
2347 for( int ii = 0; ii < (int) fields.size(); ii++ )
2348 {
2349 if( fields[ii]->GetId() == FIELD_T::REFERENCE )
2350 continue;
2351
2352 if( fields[ii]->GetText().Cmp( otherFields[ii]->GetText() ) != 0 )
2353 return false;
2354 }
2355
2356 return true;
2357}
2358
2359
2360bool SCH_SYMBOL::operator!=( const SCH_SYMBOL& aSymbol ) const
2361{
2362 return !( *this == aSymbol );
2363}
2364
2365
2367{
2368 wxCHECK_MSG( Type() == aSymbol.Type(), *this,
2369 wxT( "Cannot assign object type " ) + aSymbol.GetClass() + wxT( " to type " ) +
2370 GetClass() );
2371
2372 if( &aSymbol != this )
2373 {
2374 SYMBOL::operator=( aSymbol );
2375
2376 m_lib_id = aSymbol.m_lib_id;
2377 m_part.reset( aSymbol.m_part ? new LIB_SYMBOL( *aSymbol.m_part ) : nullptr );
2378 m_pos = aSymbol.m_pos;
2379 m_unit = aSymbol.m_unit;
2380 m_bodyStyle = aSymbol.m_bodyStyle;
2381 m_transform = aSymbol.m_transform;
2382
2384
2385 m_fields = aSymbol.m_fields; // std::vector's assignment operator
2386
2387 // Reparent fields after assignment to new symbol.
2388 for( SCH_FIELD& field : m_fields )
2389 field.SetParent( this );
2390
2391 UpdatePins();
2392 }
2393
2394 return *this;
2395}
2396
2397
2398bool SCH_SYMBOL::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
2399{
2400 BOX2I bBox = GetBodyBoundingBox();
2401 bBox.Inflate( aAccuracy / 2 );
2402
2403 if( bBox.Contains( aPosition ) )
2404 return true;
2405
2406 return false;
2407}
2408
2409
2410bool SCH_SYMBOL::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
2411{
2413 return false;
2414
2415 BOX2I rect = aRect;
2416
2417 rect.Inflate( aAccuracy / 2 );
2418
2419 if( aContained )
2420 return rect.Contains( GetBodyBoundingBox() );
2421
2422 return rect.Intersects( GetBodyBoundingBox() );
2423}
2424
2425
2426bool SCH_SYMBOL::doIsConnected( const VECTOR2I& aPosition ) const
2427{
2429
2430 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2431 {
2432 if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
2433 continue;
2434
2435 // Collect only pins attached to the current unit and convert.
2436 // others are not associated to this symbol instance
2437 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2438 : GetUnit();
2439 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2440 : GetBodyStyle();
2441
2442 if( pin_unit > 0 && pin_unit != GetUnit() )
2443 continue;
2444
2445 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2446 continue;
2447
2448 if( pin->GetLocalPosition() == new_pos )
2449 return true;
2450 }
2451
2452 return false;
2453}
2454
2455
2457{
2458 return m_isInNetlist;
2459}
2460
2461
2462void SCH_SYMBOL::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
2463 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
2464{
2465 if( aBackground )
2466 return;
2467
2468 if( m_part )
2469 {
2470 std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() );
2471
2472 // Copy the source so we can re-orient and translate it.
2473 LIB_SYMBOL tempSymbol( *m_part );
2474 std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
2475
2476 // Copy the pin info from the symbol to the temp pins
2477 for( unsigned i = 0; i < tempPins.size(); ++ i )
2478 {
2479 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
2480 SCH_PIN* tempPin = tempPins[ i ];
2481
2482 tempPin->SetName( symbolPin->GetShownName() );
2483 tempPin->SetType( symbolPin->GetType() );
2484 tempPin->SetShape( symbolPin->GetShape() );
2485
2486 if( symbolPin->IsDangling() )
2487 tempPin->SetFlags( IS_DANGLING );
2488 }
2489
2490 for( SCH_ITEM& item : tempSymbol.GetDrawItems() )
2491 {
2492 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
2493 {
2494 // Use SCH_FIELD's text resolver
2495 SCH_FIELD dummy( this, FIELD_T::USER );
2496 dummy.SetText( text->GetText() );
2497 text->SetText( dummy.GetShownText( false ) );
2498 }
2499 }
2500
2501 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
2502 TRANSFORM savedTransform = renderSettings->m_Transform;
2503 renderSettings->m_Transform = GetTransform();
2504 aPlotter->StartBlock( nullptr );
2505
2506 for( bool local_background : { true, false } )
2507 {
2508 tempSymbol.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
2509 m_pos, GetDNP() );
2510
2511 for( SCH_FIELD field : m_fields )
2512 {
2513 field.ClearRenderCache();
2514 field.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
2515 m_pos, GetDNP() );
2516 }
2517 }
2518
2519 if( m_DNP )
2520 PlotDNP( aPlotter );
2521
2522 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
2523
2524 // Plot attributes to a hypertext menu
2525 if( aPlotOpts.m_PDFPropertyPopups )
2526 {
2527 std::vector<wxString> properties;
2528
2529 for( const SCH_FIELD& field : GetFields() )
2530 {
2531 wxString text_field = field.GetShownText( sheet, false);
2532
2533 if( text_field.IsEmpty() )
2534 continue;
2535
2536 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
2537 field.GetName(), text_field ) );
2538 }
2539
2540 if( !m_part->GetKeyWords().IsEmpty() )
2541 {
2542 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
2543 _( "Keywords" ),
2544 m_part->GetKeyWords() ) );
2545 }
2546
2547 aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
2548 }
2549
2550 aPlotter->EndBlock( nullptr );
2551 renderSettings->m_Transform = savedTransform;
2552
2553 if( !m_part->IsPower() )
2554 aPlotter->Bookmark( GetBoundingBox(), GetRef( sheet ), _( "Symbols" ) );
2555 }
2556}
2557
2558
2559void SCH_SYMBOL::PlotDNP( PLOTTER* aPlotter ) const
2560{
2561 BOX2I bbox = GetBodyBoundingBox();
2563 VECTOR2D margins( std::max( bbox.GetX() - pins.GetX(),
2564 pins.GetEnd().x - bbox.GetEnd().x ),
2565 std::max( bbox.GetY() - pins.GetY(),
2566 pins.GetEnd().y - bbox.GetEnd().y ) );
2567 int strokeWidth = 3.0 * schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
2568
2569 margins.x = std::max( margins.x * 0.6, margins.y * 0.3 );
2570 margins.y = std::max( margins.y * 0.6, margins.x * 0.3 );
2571 bbox.Inflate( KiROUND( margins.x ), KiROUND( margins.y ) );
2572
2573 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
2574 aPlotter->SetColor( renderSettings->GetLayerColor( LAYER_DNP_MARKER ) );
2575
2576 aPlotter->ThickSegment( bbox.GetOrigin(), bbox.GetEnd(), strokeWidth, nullptr );
2577
2578 aPlotter->ThickSegment( bbox.GetOrigin() + VECTOR2I( bbox.GetWidth(), 0 ),
2579 bbox.GetOrigin() + VECTOR2I( 0, bbox.GetHeight() ),
2580 strokeWidth, nullptr );
2581}
2582
2583
2584void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const
2585{
2586 if( m_part )
2587 {
2588 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
2589 TRANSFORM savedTransform = renderSettings->m_Transform;
2590 renderSettings->m_Transform = GetTransform();
2591
2592 std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() );
2593
2594 // Copy the source to stay const
2595 LIB_SYMBOL tempSymbol( *m_part );
2596 std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
2597 SCH_PLOT_OPTS plotOpts;
2598
2599 // Copy the pin info from the symbol to the temp pins
2600 for( unsigned i = 0; i < tempPins.size(); ++ i )
2601 {
2602 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
2603 SCH_PIN* tempPin = tempPins[ i ];
2604
2605 tempPin->SetName( symbolPin->GetShownName() );
2606 tempPin->SetType( symbolPin->GetType() );
2607 tempPin->SetShape( symbolPin->GetShape() );
2608 tempPin->Plot( aPlotter, false, plotOpts, GetUnit(), GetBodyStyle(), m_pos, GetDNP() );
2609 }
2610
2611 renderSettings->m_Transform = savedTransform;
2612 }
2613}
2614
2615
2617{
2618 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2619 {
2620 if( pin->IsBrightened() )
2621 return true;
2622 }
2623
2624 return false;
2625}
2626
2627
2629{
2630 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2631 pin->ClearBrightened();
2632}
2633
2634
2635/*
2636 * When modified at the schematic level, we still store the values of these flags in the
2637 * associated m_part. If m_part now diverges from other usages, a new derived LIB_SYMBOL
2638 * will be created and stored locally in the schematic.
2639 */
2641{
2642 return m_part && m_part->GetShowPinNames();
2643}
2644
2645
2647{
2648 if( m_part )
2649 m_part->SetShowPinNames( aShow );
2650}
2651
2652
2654{
2655 return m_part && m_part->GetShowPinNumbers();
2656}
2657
2658
2660{
2661 if( m_part )
2662 m_part->SetShowPinNumbers( aShow );
2663}
2664
2665
2667{
2668 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2669 {
2670 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2671 : GetUnit();
2672 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2673 : GetBodyStyle();
2674
2675 if( pin_unit > 0 && pin_unit != GetUnit() )
2676 continue;
2677
2678 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2679 continue;
2680
2681 if( pin->IsPointClickableAnchor( aPos ) )
2682 return true;
2683 }
2684
2685 return false;
2686}
2687
2688
2690{
2691 // return true if the symbol is equivalent to a global label:
2692 // It is a Power symbol
2693 // It has only one pin type Power input
2694
2696 return false;
2697
2698 std::vector<SCH_PIN*> pin_list = GetAllLibPins();
2699
2700 if( pin_list.size() != 1 )
2701 return false;
2702
2703 return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
2704}
2705
2706
2708{
2709 // return true if the symbol is equivalent to a local label:
2710 // It is a Power symbol
2711 // It has only one pin type Power input
2712
2714 return false;
2715
2716 std::vector<SCH_PIN*> pin_list = GetAllLibPins();
2717
2718 if( pin_list.size() != 1 )
2719 return false;
2720
2721 return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
2722}
2723
2724
2726{
2727 if( !m_part )
2728 return false;
2729
2730 return m_part->IsLocalPower();
2731}
2732
2733
2735{
2736 if( !m_part )
2737 return false;
2738
2739 return m_part->IsGlobalPower();
2740}
2741
2742
2744{
2745 return IsLocalPower() || IsGlobalPower();
2746}
2747
2748
2750{
2751 wxCHECK( m_part, false );
2752
2753 return m_part->IsNormal();
2754}
2755
2756
2757std::unordered_set<wxString> SCH_SYMBOL::GetComponentClassNames( const SCH_SHEET_PATH* aPath ) const
2758{
2759 std::unordered_set<wxString> componentClass;
2760
2761 auto getComponentClassFields =
2762 [&]( const std::vector<SCH_FIELD>& fields )
2763 {
2764 for( const SCH_FIELD& field : fields )
2765 {
2766 if( field.GetCanonicalName() == wxT( "Component Class" ) )
2767 {
2768 if( field.GetShownText( aPath, false ) != wxEmptyString )
2769 componentClass.insert( field.GetShownText( aPath, false ) );
2770 }
2771 }
2772 };
2773
2774 // First get component classes set on the symbol itself
2775 getComponentClassFields( m_fields );
2776
2777 // Now get component classes set on any enclosing rule areas
2778 for( const SCH_RULE_AREA* ruleArea : m_rule_areas_cache )
2779 {
2780 for( const SCH_DIRECTIVE_LABEL* label : ruleArea->GetDirectives() )
2781 {
2782 getComponentClassFields( label->GetFields() );
2783 }
2784 }
2785
2786 return componentClass;
2787}
2788
2789
2790bool SCH_SYMBOL::operator==( const SCH_ITEM& aOther ) const
2791{
2792 if( Type() != aOther.Type() )
2793 return false;
2794
2795 const SCH_SYMBOL& symbol = static_cast<const SCH_SYMBOL&>( aOther );
2796
2797 if( GetLibId() != symbol.GetLibId() )
2798 return false;
2799
2800 if( GetPosition() != symbol.GetPosition() )
2801 return false;
2802
2803 if( GetUnit() != symbol.GetUnit() )
2804 return false;
2805
2806 if( GetBodyStyle() != symbol.GetBodyStyle() )
2807 return false;
2808
2809 if( GetTransform() != symbol.GetTransform() )
2810 return false;
2811
2812 if( GetFields() != symbol.GetFields() )
2813 return false;
2814
2815 if( m_pins.size() != symbol.m_pins.size() )
2816 return false;
2817
2818 for( unsigned i = 0; i < m_pins.size(); ++i )
2819 {
2820 if( *m_pins[i] != *symbol.m_pins[i] )
2821 return false;
2822 }
2823
2824 return true;
2825}
2826
2827
2828double SCH_SYMBOL::Similarity( const SCH_ITEM& aOther ) const
2829{
2830 if( Type() != aOther.Type() )
2831 return 0.0;
2832
2833 const SCH_SYMBOL& symbol = static_cast<const SCH_SYMBOL&>( aOther );
2834
2835 if( GetLibId() != symbol.GetLibId() )
2836 return 0.0;
2837
2838 if( GetPosition() == symbol.GetPosition() )
2839 return 1.0;
2840
2841 return 0.0;
2842}
2843
2844
2845static struct SCH_SYMBOL_DESC
2846{
2848 {
2850 .Map( SYMBOL_ANGLE_0, wxS( "0" ) )
2851 .Map( SYMBOL_ANGLE_90, wxS( "90" ) )
2852 .Map( SYMBOL_ANGLE_180, wxS( "180" ) )
2853 .Map( SYMBOL_ANGLE_270, wxS( "270" ) );
2854
2858
2859 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Position X" ),
2860 &SCH_SYMBOL::SetX, &SCH_SYMBOL::GetX, PROPERTY_DISPLAY::PT_COORD,
2862 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Position Y" ),
2863 &SCH_SYMBOL::SetY, &SCH_SYMBOL::GetY, PROPERTY_DISPLAY::PT_COORD,
2865
2867 _HKI( "Orientation" ),
2869 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror X" ),
2871 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror Y" ),
2873
2874 auto hasLibPart =
2875 []( INSPECTABLE* aItem ) -> bool
2876 {
2877 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2878 return symbol->GetLibSymbolRef() != nullptr;
2879
2880 return false;
2881 };
2882
2883 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin numbers" ),
2885 .SetAvailableFunc( hasLibPart );
2886
2887 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin names" ),
2889 .SetAvailableFunc( hasLibPart );
2890
2891 const wxString groupFields = _HKI( "Fields" );
2892
2893 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Reference" ),
2895 groupFields );
2896 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Value" ),
2898 groupFields );
2899 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Library Link" ),
2901 groupFields );
2902 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Library Description" ),
2904 groupFields );
2905 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Keywords" ),
2907 groupFields );
2908
2909 auto multiUnit =
2910 [=]( INSPECTABLE* aItem ) -> bool
2911 {
2912 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2913 return symbol->IsMulti();
2914
2915 return false;
2916 };
2917
2918 auto multiBodyStyle =
2919 [=]( INSPECTABLE* aItem ) -> bool
2920 {
2921 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2922 return symbol->HasAlternateBodyStyle();
2923
2924 return false;
2925 };
2926
2927 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Unit" ),
2929 .SetAvailableFunc( multiUnit )
2930 .SetChoicesFunc( []( INSPECTABLE* aItem )
2931 {
2932 wxPGChoices choices;
2933
2934 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2935 {
2936 for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
2937 choices.Add( symbol->GetUnitDisplayName( ii, false ) );
2938 }
2939
2940 return choices;
2941 } );
2942
2943 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Body Style" ),
2945 .SetAvailableFunc( multiBodyStyle )
2946 .SetChoicesFunc( []( INSPECTABLE* aItem )
2947 {
2948 wxPGChoices choices;
2949
2950 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2951 {
2952 for( int ii : { BODY_STYLE::BASE, BODY_STYLE::DEMORGAN } )
2953 choices.Add( symbol->GetBodyStyleDescription( ii, false ) );
2954 }
2955
2956 return choices;
2957 } );
2958
2959 const wxString groupAttributes = _HKI( "Attributes" );
2960
2961 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Exclude From Board" ),
2963 groupAttributes );
2964 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Exclude From Simulation" ),
2966 groupAttributes );
2967 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Exclude From Bill of Materials" ),
2969 groupAttributes );
2970 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Do not Populate" ),
2972 groupAttributes );
2973 }
2975
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:114
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
BOX2< VECTOR2I > BOX2I
Definition: box2.h:922
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr const Vec GetEnd() const
Definition: box2.h:212
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:146
constexpr coord_type GetY() const
Definition: box2.h:208
constexpr size_type GetWidth() const
Definition: box2.h:214
constexpr coord_type GetX() const
Definition: box2.h:207
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
constexpr ecoord_type GetArea() const
Return the area of the rectangle.
Definition: box2.h:761
constexpr size_type GetHeight() const
Definition: box2.h:215
constexpr bool Contains(const Vec &aPoint) const
Definition: box2.h:168
constexpr const Vec & GetOrigin() const
Definition: box2.h:210
constexpr void Offset(coord_type dx, coord_type dy)
Definition: box2.h:259
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:311
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition: sch_item.cpp:795
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:97
DANGLING_END_T GetType() const
Definition: sch_item.h:133
const EDA_ITEM * GetParent() const
Definition: sch_item.h:132
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:98
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:148
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:527
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:401
virtual void SetParentGroup(EDA_GROUP *aGroup)
Definition: eda_item.h:115
bool IsSelected() const
Definition: eda_item.h:127
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:113
EDA_ITEM * m_parent
Owner.
Definition: eda_item.h:528
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:97
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:578
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:596
static ENUM_MAP< T > & Instance()
Definition: property.h:697
A text control validator used for validating the text allowed in fields.
Definition: validators.h:142
bool DoValidate(const wxString &aValue, wxWindow *aParent)
Definition: validators.cpp:292
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:37
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxString AsString() const
Definition: kiid.cpp:356
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:246
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:119
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
Define a library symbol object.
Definition: lib_symbol.h:85
std::vector< SCH_PIN * > GetPins(int aUnit, int aBodyStyle) const
Return a list of pin object pointers from the draw item list.
Definition: lib_symbol.cpp:799
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition: lib_symbol.h:206
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
Definition: lib_symbol.cpp:637
static wxString LetterSubReference(int aUnit, wxChar aInitialLetter)
Definition: lib_symbol.cpp:517
static LIB_SYMBOL * GetDummy()
Returns a dummy LIB_SYMBOL, used when one is missing in the schematic.
Definition: lib_symbol.cpp:229
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition: lib_symbol.h:519
const BOX2I GetBodyBoundingBox(int aUnit, int aBodyStyle, bool aIncludePins, bool aIncludePrivateItems) const
Get the symbol bounding box excluding fields.
Definition: lib_symbol.cpp:943
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:344
A singleton reporter that reports to nowhere.
Definition: reporter.h:217
Base plotter engine class.
Definition: plotter.h:121
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition: plotter.h:482
virtual void StartBlock(void *aData)
calling this function allows one to define the beginning of a group of drawing items,...
Definition: plotter.h:544
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
Definition: plotter.cpp:538
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:471
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:553
PROPERTY_BASE & SetChoicesFunc(std::function< wxPGChoices(INSPECTABLE *)> aFunc)
Definition: property.h:272
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition: property.h:258
const wxString & Name() const
Definition: property.h:218
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:74
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
TEMPLATES m_TemplateFieldNames
Holds all the data relating to one schematic.
Definition: schematic.h:88
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:787
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:356
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:103
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: schematic.cpp:927
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:171
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:486
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
bool IsMandatory() const
Definition: sch_field.cpp:1359
FIELD_T GetId() const
Definition: sch_field.h:116
void ImportValues(const SCH_FIELD &aSource)
Copy parameters from a SCH_FIELD source.
Definition: sch_field.cpp:390
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1103
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
Definition: sch_field.cpp:191
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1089
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:168
int m_unit
Definition: sch_item.h:745
int m_bodyStyle
Definition: sch_item.h:746
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition: sch_item.h:693
void SetPrivate(bool aPrivate)
Definition: sch_item.h:253
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:246
int GetBodyStyle() const
Definition: sch_item.h:248
friend class LIB_SYMBOL
Definition: sch_item.h:764
int GetUnit() const
Definition: sch_item.h:239
virtual void SetExcludedFromBOM(bool aExcludeFromBOM)
Definition: sch_item.h:260
AUTOPLACE_ALGO m_fieldsAutoplaced
Definition: sch_item.h:748
std::unordered_set< SCH_RULE_AREA * > m_rule_areas_cache
Store pointers to rule areas which this item is contained within.
Definition: sch_item.h:761
SCH_LAYER_ID m_layer
Definition: sch_item.h:744
void SetAlt(const wxString &aAlt)
Set the name of the alternate pin.
Definition: sch_pin.cpp:389
void SetName(const wxString &aName)
Definition: sch_pin.cpp:375
const wxString & GetName() const
Definition: sch_pin.cpp:357
bool IsDangling() const override
Definition: sch_pin.cpp:417
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
Definition: sch_pin.cpp:1120
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: sch_pin.h:95
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:212
wxString GetShownName() const
Definition: sch_pin.cpp:524
void SetType(ELECTRICAL_PINTYPE aType)
Definition: sch_pin.cpp:289
const wxString & GetNumber() const
Definition: sch_pin.h:123
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:234
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:269
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool GetExcludedFromBOM() const
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
bool GetExcludedFromSim() const
bool GetExcludedFromBoard() const
bool GetDNP() const
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:220
Schematic symbol object.
Definition: sch_symbol.h:75
wxString GetUnitDisplayName(int aUnit, bool aLabel) const override
Return the display name for a given unit aUnit.
Definition: sch_symbol.cpp:444
void SetValueProp(const wxString &aRef)
Definition: sch_symbol.h:493
SCH_SYMBOL & operator=(const SCH_SYMBOL &aItem)
size_t GetFullPinCount() const
void UpdatePrefix()
Set the prefix based on the current reference designator.
Definition: sch_symbol.cpp:650
wxString m_prefix
C, R, U, Q etc - the first character(s) which typically indicate what the symbol is.
Definition: sch_symbol.h:850
wxString GetDescription() const override
Definition: sch_symbol.cpp:261
std::unordered_map< SCH_PIN *, SCH_PIN * > m_pinMap
Library pin pointer : SCH_PIN indices.
Definition: sch_symbol.h:871
void SetMirrorX(bool aMirror)
Definition: sch_symbol.h:317
bool IsSymbolLikePowerGlobalLabel() const
VECTOR2I m_pos
Definition: sch_symbol.h:848
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_SYMBOLs don't currently support embedded files, but their LIB_SYMBOL counterparts do.
wxString GetSymbolIDAsString() const
Definition: sch_symbol.h:166
LIB_ID m_lib_id
Name and library the symbol was loaded from, i.e. 74xx:74LS00.
Definition: sch_symbol.h:849
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
bool GetShowPinNumbers() const override
wxString GetDatasheet() const
Return the documentation text for the given part alias.
Definition: sch_symbol.cpp:279
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:237
bool HasBrightenedPins()
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the symbol's fields.
Definition: sch_symbol.h:430
BOX2I GetBodyAndPinsBoundingBox() const override
Return a bounding box for the symbol body and pins but not the fields.
wxString GetBodyStyleProp() const override
Definition: sch_symbol.h:518
void SetRefProp(const wxString &aRef)
Definition: sch_symbol.cpp:591
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...
SCH_ITEM * GetDrawItem(const VECTOR2I &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the symbol library item at aPosition that is part of this symbol.
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
void SetShowPinNumbers(bool aShow) override
Set or clear the pin number visibility flag.
SYMBOL_ORIENTATION_PROP GetOrientationProp() const
Definition: sch_symbol.h:300
void SetBodyStyleUnconditional(int aBodyStyle)
Similar to SetBodyStyle(), but always set the body style, regardless the lib symbol properties (the L...
Definition: sch_symbol.cpp:400
int GetY() const
Definition: sch_symbol.h:773
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:677
wxString GetClass() const override
Return the class name.
Definition: sch_symbol.h:114
void RemoveInstance(const SCH_SHEET_PATH &aInstancePath)
Definition: sch_symbol.cpp:492
bool IsAnnotated(const SCH_SHEET_PATH *aSheet) const
Check if the symbol has a valid annotation (reference) for the given sheet path.
Definition: sch_symbol.cpp:636
void SetMirrorY(bool aMirror)
Definition: sch_symbol.h:334
void PlotPins(PLOTTER *aPlotter) const
Plot just the symbol pins.
void SetBodyStyleProp(const wxString &aBodyStyle) override
Definition: sch_symbol.h:523
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:738
int GetX() const
Definition: sch_symbol.h:770
std::vector< SCH_PIN * > GetPins() const override
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
Definition: sch_symbol.cpp:822
void SetBodyStyle(int aBodyStyle) override
Definition: sch_symbol.cpp:413
void SetShowPinNames(bool aShow) override
Set or clear the pin name visibility flag.
wxString GetKeyWords() const override
Definition: sch_symbol.cpp:270
wxString GetSchSymbolLibraryName() const
Definition: sch_symbol.cpp:243
bool IsInNetlist() const
void ClearBrightenedPins()
void SetY(int aY)
Definition: sch_symbol.h:774
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_symbol.cpp:204
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
bool IsGlobalPower() const override
bool GetMirrorX() const
Definition: sch_symbol.h:329
wxString GetRefProp() const
Definition: sch_symbol.h:481
wxString GetBodyStyleDescription(int aBodyStyle, bool aLabel) const override
Definition: sch_symbol.cpp:455
bool AddSheetPathReferenceEntryIfMissing(const KIID_PATH &aSheetPath)
Add an instance to the alternate references list (m_instanceReferences), if this entry does not alrea...
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
static std::unordered_map< TRANSFORM, int > s_transformToOrientationCache
Definition: sch_symbol.h:881
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
Definition: sch_symbol.cpp:288
std::vector< SCH_SYMBOL_INSTANCE > m_instanceReferences
Define the hierarchical path and reference of the symbol.
Definition: sch_symbol.h:878
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const override
Definition: sch_symbol.cpp:728
void SyncOtherUnits(const SCH_SHEET_PATH &aSourceSheet, SCH_COMMIT &aCommit, PROPERTY_BASE *aProperty)
Keep fields other than the reference, include/exclude flags, and alternate pin assignments in sync in...
Definition: sch_symbol.cpp:916
SCH_FIELD * FindFieldCaseInsensitive(const wxString &aFieldName)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:838
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
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.
Definition: sch_symbol.cpp:850
wxString m_schLibSymbolName
The name used to look up a symbol in the symbol library embedded in a schematic.
Definition: sch_symbol.h:862
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:600
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:291
bool GetShowPinNames() const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
Definition: sch_symbol.cpp:788
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
Definition: sch_symbol.cpp:744
std::vector< SCH_FIELD > m_fields
Variable length list of fields.
Definition: sch_symbol.h:864
std::vector< SCH_PIN * > GetAllLibPins() const
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.
void SetFootprintFieldText(const wxString &aFootprint)
Definition: sch_symbol.cpp:754
bool doIsConnected(const VECTOR2I &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:520
bool IsMissingLibSymbol() const
Check to see if the library symbol is set to the dummy library symbol.
Definition: sch_symbol.cpp:210
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:767
std::unique_ptr< LIB_SYMBOL > m_part
A flattened copy of the LIB_SYMBOL from the PROJECT object's libraries.
Definition: sch_symbol.h:866
int GetNextFieldOrdinal() const
Return the next ordinal for a user field for this symbol.
Definition: sch_symbol.cpp:809
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
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:174
bool HasAlternateBodyStyle() const override
Test if symbol has more than one body conversion type (DeMorgan).
Definition: sch_symbol.cpp:426
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:164
bool operator<(const SCH_ITEM &aItem) const override
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
wxString GetUnitProp() const override
Definition: sch_symbol.h:498
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
std::vector< SCH_PIN * > GetLibPins() const
Populate a vector with all the pins from the library object that match the current unit and bodyStyle...
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:468
BOX2I doGetBoundingBox(bool aIncludePins, bool aIncludeFields) const
bool GetMirrorY() const
Definition: sch_symbol.h:346
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
Definition: sch_symbol.cpp:815
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
void SetX(int aX)
Definition: sch_symbol.h:771
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.
bool m_isInNetlist
True if the symbol should appear in netlist.
Definition: sch_symbol.h:868
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:686
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
wxString GetValueProp() const
Definition: sch_symbol.h:488
bool IsLocalPower() const override
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
int GetUnitCount() const override
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:435
void SetPrefix(const wxString &aPrefix)
Definition: sch_symbol.h:245
int GetOrientation() const override
Get the display symbol orientation.
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
bool IsSymbolLikePowerLocalLabel() const
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:702
bool IsNormal() const override
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:183
std::unordered_set< wxString > GetComponentClassNames(const SCH_SHEET_PATH *aPath) const
Return the component classes this symbol belongs in.
std::vector< std::unique_ptr< SCH_PIN > > m_pins
A SCH_PIN for every #LIB_PIN.
Definition: sch_symbol.h:870
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:252
void SetUnitProp(const wxString &aUnit) override
Definition: sch_symbol.h:505
VECTOR2I GetPinPhysicalPosition(const SCH_PIN *Pin) const
BOX2I GetBodyBoundingBox() const override
Return a bounding box for the symbol body but not the pins or fields.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:558
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
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:216
bool IsPower() const override
bool operator==(const SCH_SYMBOL &aSymbol) const
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:760
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
void SetFilesStack(std::vector< EMBEDDED_FILES * > aFilesStack)
Definition: sim_lib_mgr.h:48
const SPICE_GENERATOR & SpiceGenerator() const
Definition: sim_model.h:431
std::vector< std::reference_wrapper< const SIM_MODEL_PIN > > GetPins() const
Definition: sim_model.cpp:686
virtual std::string ItemName(const SPICE_ITEM &aItem) const
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition: symbol.h:63
bool m_DNP
True if symbol is set to 'Do Not Populate'.
Definition: symbol.h:227
void SetExcludedFromBoard(bool aExcludeFromBoard) override
Set or clear exclude from board netlist flag.
Definition: symbol.h:186
bool m_excludedFromSim
Definition: symbol.h:224
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:164
void SetDNP(bool aDNP) override
Definition: symbol.h:193
const TRANSFORM & GetTransform() const
Definition: symbol.h:197
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
Definition: symbol.h:170
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: symbol.h:158
bool GetExcludedFromBoard() const override
Definition: symbol.h:187
bool m_excludedFromBOM
Definition: symbol.h:225
void SetExcludedFromBOM(bool aExcludeFromBOM) override
Set or clear the exclude from schematic bill of materials flag.
Definition: symbol.h:180
bool m_excludedFromBoard
Definition: symbol.h:226
virtual bool GetShowPinNames() const
Definition: symbol.h:159
bool GetDNP() const override
Set or clear the 'Do Not Populate' flag.
Definition: symbol.h:192
SYMBOL & operator=(const SYMBOL &aItem)
Definition: symbol.h:91
virtual bool GetShowPinNumbers() const
Definition: symbol.h:165
TRANSFORM m_transform
The rotation/mirror transformation.
Definition: symbol.h:217
bool GetExcludedFromBOM() const override
Definition: symbol.h:181
bool GetExcludedFromSim() const override
Definition: symbol.h:175
const std::vector< TEMPLATE_FIELDNAME > & 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:110
wxString wx_str() const
Definition: utf8.cpp:45
#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:186
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_270
Definition: eda_angle.h:416
RECURSE_MODE
Definition: eda_item.h:50
INSPECT_RESULT
Definition: eda_item.h:44
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition: eda_item.h:91
#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
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:439
@ LAYER_DEVICE
Definition: layer_ids.h:456
@ LAYER_VALUEPART
Definition: layer_ids.h:451
@ LAYER_FIELDS
Definition: layer_ids.h:452
@ LAYER_REFERENCEPART
Definition: layer_ids.h:450
@ LAYER_DNP_MARKER
Definition: layer_ids.h:468
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:45
Message panel definition file.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:221
KICOMMON_API 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:203
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:72
#define NO_SETTER(owner, type)
Definition: property.h:808
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:799
#define REGISTER_TYPE(x)
Definition: property_mgr.h:351
Collection of utility functions for component reference designators (refdes)
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
Definition: sch_field.h:359
int NextFieldOrdinal(const std::vector< SCH_FIELD > &aFields)
Definition: sch_field.h:348
@ NO_CONNECT_END
Definition: sch_item.h:88
@ SHEET_LABEL_END
Definition: sch_item.h:87
@ LABEL_END
Definition: sch_item.h:84
@ JUNCTION_END
Definition: sch_item.h:82
@ PIN_END
Definition: sch_item.h:83
@ WIRE_END
Definition: sch_item.h:80
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:56
static struct SCH_SYMBOL_DESC _SCH_SYMBOL_DESC
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:429
constexpr int MilsToIU(int mils) const
Definition: base_units.h:97
std::vector< std::pair< FIELD_T, wxString > > Fields
Definition: sch_screen.h:87
bool m_PDFPropertyPopups
Definition: sch_plotter.h:64
A simple container for schematic symbol instance information.
std::string refName
Hold a name of a symbol's field, field value, and default visibility.
SYMBOL_ORIENTATION_PROP
Definition: symbol.h:51
@ SYMBOL_ANGLE_180
Definition: symbol.h:54
@ SYMBOL_ANGLE_0
Definition: symbol.h:52
@ SYMBOL_ANGLE_90
Definition: symbol.h:53
@ SYMBOL_ANGLE_270
Definition: symbol.h:55
@ SYM_ORIENT_270
Definition: symbol.h:42
@ SYM_ROTATE_CLOCKWISE
Definition: symbol.h:37
@ SYM_ROTATE_COUNTERCLOCKWISE
Definition: symbol.h:38
@ SYM_MIRROR_Y
Definition: symbol.h:44
@ SYM_ORIENT_180
Definition: symbol.h:41
@ SYM_MIRROR_X
Definition: symbol.h:43
@ SYM_NORMAL
Definition: symbol.h:36
@ SYM_ORIENT_90
Definition: symbol.h:40
@ SYM_ORIENT_0
Definition: symbol.h:39
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
wxString GetCanonicalFieldName(FIELD_T aFieldType)
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:229
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:181
@ SCH_FIELD_LOCATE_FOOTPRINT_T
Definition: typeinfo.h:183
@ SCH_SYMBOL_T
Definition: typeinfo.h:173
@ SCH_FIELD_T
Definition: typeinfo.h:151
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:200
@ SCH_FIELD_LOCATE_VALUE_T
Definition: typeinfo.h:182
@ SCH_FIELD_LOCATE_DATASHEET_T
Definition: typeinfo.h:184
@ SCH_SYMBOL_LOCATE_POWER_T
Definition: typeinfo.h:197
@ SCH_PIN_T
Definition: typeinfo.h:154
Custom text control validator definitions.
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695