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 ) const
445{
446 wxCHECK( m_part, ( wxString::Format( _( "Unit %s" ), SubReference( aUnit ) ) ) );
447
448 return m_part->GetUnitDisplayName( aUnit );
449}
450
451
452bool SCH_SYMBOL::HasUnitDisplayName( int aUnit ) const
453{
454 wxCHECK( m_part, false );
455
456 return m_part->HasUnitDisplayName( aUnit );
457}
458
459
461 const KIID_PATH& aSheetPath, bool aTestFromEnd ) const
462{
463 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
464 {
465 if( !aTestFromEnd )
466 {
467 if( instance.m_Path == aSheetPath )
468 {
469 aInstance = instance;
470 return true;
471 }
472 }
473 else if( instance.m_Path.EndsWith( aSheetPath ) )
474 {
475 aInstance = instance;
476 return true;
477 }
478 }
479
480 return false;
481}
482
483
484void SCH_SYMBOL::RemoveInstance( const SCH_SHEET_PATH& aInstancePath )
485{
486 RemoveInstance( aInstancePath.Path() );
487}
488
489
490void SCH_SYMBOL::RemoveInstance( const KIID_PATH& aInstancePath )
491{
492 // Search for an existing path and remove it if found
493 // (search from back to avoid invalidating iterator on remove)
494 for( int ii = m_instanceReferences.size() - 1; ii >= 0; --ii )
495 {
496 if( m_instanceReferences[ii].m_Path == aInstancePath )
497 {
498 wxLogTrace( traceSchSheetPaths, wxS( "Removing symbol instance:\n"
499 " sheet path %s\n"
500 " reference %s, unit %d from symbol %s." ),
501 aInstancePath.AsString(),
502 m_instanceReferences[ii].m_Reference,
503 m_instanceReferences[ii].m_Unit,
504 m_Uuid.AsString() );
505
506 m_instanceReferences.erase( m_instanceReferences.begin() + ii );
507 }
508 }
509}
510
511
512void SCH_SYMBOL::AddHierarchicalReference( const KIID_PATH& aPath, const wxString& aRef, int aUnit )
513{
514 SCH_SYMBOL_INSTANCE instance;
515 instance.m_Path = aPath;
516 instance.m_Reference = aRef;
517 instance.m_Unit = aUnit;
518
519 AddHierarchicalReference( instance );
520}
521
522
524{
525 RemoveInstance( aInstance.m_Path );
526
527 SCH_SYMBOL_INSTANCE instance = aInstance;
528
529 wxLogTrace( traceSchSheetPaths, wxS( "Adding symbol '%s' instance:\n"
530 " sheet path '%s'\n"
531 " reference '%s'\n"
532 " unit %d\n" ),
534 instance.m_Path.AsString(),
535 instance.m_Reference,
536 instance.m_Unit );
537
538 m_instanceReferences.push_back( instance );
539
540 // This should set the default instance to the first saved instance data for each symbol
541 // when importing sheets.
542 if( m_instanceReferences.size() == 1 )
543 {
544 GetField( FIELD_T::REFERENCE )->SetText( instance.m_Reference );
545 m_unit = instance.m_Unit;
546 }
547}
548
549
550const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUnit ) const
551{
552 KIID_PATH path = sheet->Path();
553 wxString ref;
554 wxString subRef;
555
556 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
557 {
558 if( instance.m_Path == path )
559 {
560 ref = instance.m_Reference;
561 subRef = SubReference( instance.m_Unit );
562 break;
563 }
564 }
565
566 // If it was not found in m_Paths array, then see if it is in m_Field[REFERENCE] -- if so,
567 // use this as a default for this path. This will happen if we load a version 1 schematic
568 // file. It will also mean that multiple instances of the same sheet by default all have
569 // the same symbol references, but perhaps this is best.
570 if( ref.IsEmpty() && !GetField( FIELD_T::REFERENCE )->GetText().IsEmpty() )
571 ref = GetField( FIELD_T::REFERENCE )->GetText();
572
573 if( ref.IsEmpty() )
575
576 if( aIncludeUnit && GetUnitCount() > 1 )
577 ref += subRef;
578
579 return ref;
580}
581
582
583void SCH_SYMBOL::SetRefProp( const wxString& aRef )
584{
585 FIELD_VALIDATOR validator( FIELD_T::REFERENCE );
586
587 if( validator.DoValidate( aRef, nullptr ) )
588 SetRef( &Schematic()->CurrentSheet(), aRef );
589}
590
591
592void SCH_SYMBOL::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
593{
594 KIID_PATH path = sheet->Path();
595 bool found = false;
596
597 // check to see if it is already there before inserting it
599 {
600 if( instance.m_Path == path )
601 {
602 found = true;
603 instance.m_Reference = ref;
604 break;
605 }
606 }
607
608 if( !found )
610
611 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
612 pin->ClearDefaultNetName( sheet );
613
614 if( Schematic() && *sheet == Schematic()->CurrentSheet() )
615 GetField( FIELD_T::REFERENCE )->SetText( ref );
616
617 // Reinit the m_prefix member if needed
619
620 if( m_prefix.IsEmpty() )
621 m_prefix = wxT( "U" );
622
623 // Power symbols have references starting with # and are not included in netlists
624 m_isInNetlist = ! ref.StartsWith( wxT( "#" ) );
625}
626
627
628bool SCH_SYMBOL::IsAnnotated( const SCH_SHEET_PATH* aSheet ) const
629{
630 KIID_PATH path = aSheet->Path();
631
632 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
633 {
634 if( instance.m_Path == path )
635 return instance.m_Reference.Last() != '?';
636 }
637
638 return false;
639}
640
641
643{
644 wxString refDesignator = GetField( FIELD_T::REFERENCE )->GetText();
645
646 refDesignator.Replace( "~", " " );
647
648 wxString prefix = refDesignator;
649
650 while( prefix.Length() )
651 {
652 wxUniCharRef last = prefix.Last();
653
654 if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
655 prefix.RemoveLast();
656 else
657 break;
658 }
659
660 // Avoid a prefix containing trailing/leading spaces
661 prefix.Trim( true );
662 prefix.Trim( false );
663
664 if( !prefix.IsEmpty() )
665 SetPrefix( prefix );
666}
667
668
669wxString SCH_SYMBOL::SubReference( int aUnit, bool aAddSeparator ) const
670{
671 if( SCHEMATIC* schematic = Schematic() )
672 return schematic->Settings().SubReference( aUnit, aAddSeparator );
673
674 return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
675}
676
677
679{
680 KIID_PATH path = aSheet->Path();
681
682 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
683 {
684 if( instance.m_Path == path )
685 return instance.m_Unit;
686 }
687
688 // If it was not found in m_Paths array, then use m_unit. This will happen if we load a
689 // version 1 schematic file.
690 return m_unit;
691}
692
693
694void SCH_SYMBOL::SetUnitSelection( const SCH_SHEET_PATH* aSheet, int aUnitSelection )
695{
696 KIID_PATH path = aSheet->Path();
697
698 // check to see if it is already there before inserting it
700 {
701 if( instance.m_Path == path )
702 {
703 instance.m_Unit = aUnitSelection;
704 return;
705 }
706 }
707
708 // didn't find it; better add it
710}
711
712
713void SCH_SYMBOL::SetUnitSelection( int aUnitSelection )
714{
716 instance.m_Unit = aUnitSelection;
717}
718
719
720const wxString SCH_SYMBOL::GetValue( bool aResolve, const SCH_SHEET_PATH* aPath,
721 bool aAllowExtraText ) const
722{
723 if( aResolve )
724 return GetField( FIELD_T::VALUE )->GetShownText( aPath, aAllowExtraText );
725
726 return GetField( FIELD_T::VALUE )->GetText();
727}
728
729
730void SCH_SYMBOL::SetValueFieldText( const wxString& aValue )
731{
732 GetField( FIELD_T::VALUE )->SetText( aValue );
733}
734
735
736const wxString SCH_SYMBOL::GetFootprintFieldText( bool aResolve, const SCH_SHEET_PATH* aPath,
737 bool aAllowExtraText ) const
738{
739 if( aResolve )
740 return GetField( FIELD_T::FOOTPRINT )->GetShownText( aPath, aAllowExtraText );
741
742 return GetField( FIELD_T::FOOTPRINT )->GetText();
743}
744
745
746void SCH_SYMBOL::SetFootprintFieldText( const wxString& aFootprint )
747{
748 GetField( FIELD_T::FOOTPRINT )->SetText( aFootprint );
749}
750
751
753{
754 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
755 return field;
756
757 m_fields.emplace_back( this, aFieldType );
758 return &m_fields.back();
759}
760
761
762const SCH_FIELD* SCH_SYMBOL::GetField( FIELD_T aFieldType ) const
763{
764 return FindField( m_fields, aFieldType );
765}
766
767
768SCH_FIELD* SCH_SYMBOL::GetField( const wxString& aFieldName )
769{
770 return FindField( m_fields, aFieldName );
771}
772
773
774const SCH_FIELD* SCH_SYMBOL::GetField( const wxString& aFieldName ) const
775{
776 return FindField( m_fields, aFieldName );
777}
778
779
780void SCH_SYMBOL::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly ) const
781{
782 for( const SCH_FIELD& field : m_fields )
783 {
784 if( aVisibleOnly )
785 {
786 if( !field.IsVisible() || field.GetText().IsEmpty() )
787 continue;
788 }
789
790 aVector.push_back( const_cast<SCH_FIELD*>( &field ) );
791 }
792
793 std::sort( aVector.begin(), aVector.end(),
794 []( SCH_FIELD* lhs, SCH_FIELD* rhs )
795 {
796 return lhs->GetOrdinal() < rhs->GetOrdinal();
797 } );
798}
799
800
802{
803 return NextFieldOrdinal( m_fields );
804}
805
806
808{
809 m_fields.push_back( aField );
810 return &m_fields.back();
811}
812
813
814void SCH_SYMBOL::RemoveField( const wxString& aFieldName )
815{
816 for( unsigned ii = 0; ii < m_fields.size(); ++ii )
817 {
818 if( m_fields[ii].IsMandatory() )
819 continue;
820
821 if( aFieldName == m_fields[ii].GetName( false ) )
822 {
823 m_fields.erase( m_fields.begin() + ii );
824 return;
825 }
826 }
827}
828
829
831{
832 for( SCH_FIELD& field : m_fields )
833 {
834 if( field.GetName().IsSameAs( aFieldName, false ) )
835 return &field;
836 }
837
838 return nullptr;
839}
840
841
842void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, bool aUpdateRef,
843 bool aUpdateOtherFields, bool aResetRef, bool aResetOtherFields )
844{
845 if( m_part )
846 {
847 std::vector<SCH_FIELD*> fields;
848 m_part->GetFields( fields );
849
850 for( const SCH_FIELD* libField : fields )
851 {
852 SCH_FIELD* schField;
853 FIELD_T fieldType = FIELD_T::USER;
854
855 if( libField->IsMandatory() )
856 {
857 fieldType = libField->GetId();
858 schField = GetField( fieldType );
859 }
860 else
861 {
862 schField = GetField( libField->GetCanonicalName() );
863
864 if( !schField )
865 {
866 schField = AddField( SCH_FIELD( this, FIELD_T::USER, libField->GetCanonicalName() ) );
867 schField->ImportValues( *libField );
868 schField->SetTextPos( m_pos + libField->GetTextPos() );
869 }
870 }
871
872 schField->SetPrivate( libField->IsPrivate() );
873
874 if( aUpdateStyle )
875 {
876 schField->ImportValues( *libField );
877 schField->SetTextPos( m_pos + libField->GetTextPos() );
878 }
879
880 if( fieldType == FIELD_T::REFERENCE && aPath )
881 {
882 if( aResetRef )
883 SetRef( aPath, m_part->GetField( FIELD_T::REFERENCE )->GetText() );
884 else if( aUpdateRef )
885 SetRef( aPath, libField->GetText() );
886 }
887 else if( fieldType == FIELD_T::VALUE )
888 {
889 SetValueFieldText( UnescapeString( libField->GetText() ) );
890 }
891 else if( fieldType == FIELD_T::DATASHEET )
892 {
893 if( aResetOtherFields )
894 schField->SetText( GetDatasheet() ); // alias-specific value
895 else if( aUpdateOtherFields )
896 schField->SetText( libField->GetText() );
897 }
898 else
899 {
900 if( aResetOtherFields || aUpdateOtherFields )
901 schField->SetText( libField->GetText() );
902 }
903 }
904 }
905}
906
907
908void SCH_SYMBOL::SyncOtherUnits( const SCH_SHEET_PATH& aSourceSheet, SCH_COMMIT& aCommit,
909 PROPERTY_BASE* aProperty )
910{
911 bool updateValue = true;
912 bool updateExclFromBOM = true;
913 bool updateExclFromBoard = true;
914 bool updateDNP = true;
915 bool updateOtherFields = true;
916 bool updatePins = true;
917
918 if( aProperty )
919 {
920 updateValue = aProperty->Name() == _HKI( "Value" );
921 updateExclFromBoard = aProperty->Name() == _HKI( "Exclude From Board" );
922 updateExclFromBOM = aProperty->Name() == _HKI( "Exclude From Bill of Materials" );
923 updateDNP = aProperty->Name() == _HKI( "Do not Populate" );
924 updateOtherFields = false;
925 updatePins = false;
926 }
927
928 if( !updateValue
929 && !updateExclFromBOM
930 && !updateExclFromBoard
931 && !updateDNP
932 && !updateOtherFields
933 && !updatePins )
934 {
935 return;
936 }
937
938 // Keep fields other than the reference, include/exclude flags, and alternate pin assignments
939 // in sync in multi-unit parts.
940 if( GetUnitCount() > 1 && IsAnnotated( &aSourceSheet ) )
941 {
942 wxString ref = GetRef( &aSourceSheet );
943
944 for( SCH_SHEET_PATH& sheet : Schematic()->Hierarchy() )
945 {
946 SCH_SCREEN* screen = sheet.LastScreen();
947 std::vector<SCH_SYMBOL*> otherUnits;
948
949 CollectOtherUnits( ref, m_unit, m_lib_id, sheet, &otherUnits );
950
951 for( SCH_SYMBOL* otherUnit : otherUnits )
952 {
953 aCommit.Modify( otherUnit, screen );
954
955 if( updateValue )
956 otherUnit->SetValueFieldText( GetField( FIELD_T::VALUE )->GetText() );
957
958 if( updateOtherFields )
959 {
960 for( SCH_FIELD& field : m_fields )
961 {
962 if( field.GetId() == FIELD_T::REFERENCE || field.GetId() == FIELD_T::VALUE )
963 {
964 // already handled
965 continue;
966 }
967
968 SCH_FIELD* otherField;
969
970 if( field.IsMandatory() )
971 otherField = otherUnit->GetField( field.GetId() );
972 else
973 otherField = otherUnit->GetField( field.GetName() );
974
975 if( otherField )
976 {
977 otherField->SetText( field.GetText() );
978 }
979 else
980 {
981 SCH_FIELD newField( field );
982 const_cast<KIID&>( newField.m_Uuid ) = KIID();
983
984 newField.Offset( -GetPosition() );
985 newField.Offset( otherUnit->GetPosition() );
986
987 newField.SetParent( otherUnit );
988 otherUnit->AddField( newField );
989 }
990 }
991
992 for( int ii = (int) otherUnit->GetFields().size() - 1; ii >= 0; ii-- )
993 {
994 SCH_FIELD& otherField = otherUnit->GetFields()[ii];
995
996 if( !otherField.IsMandatory() && !GetField( otherField.GetName() ) )
997 otherUnit->GetFields().erase( otherUnit->GetFields().begin() + ii );
998 }
999 }
1000
1001 if( updateExclFromBOM )
1003
1004 if( updateExclFromBoard )
1005 otherUnit->SetExcludedFromBoard( m_excludedFromBoard );
1006
1007 if( updateDNP )
1008 otherUnit->SetDNP( m_DNP );
1009
1010 if( updatePins )
1011 {
1012 for( const std::unique_ptr<SCH_PIN>& model_pin : m_pins )
1013 {
1014 SCH_PIN* src_pin = otherUnit->GetPin( model_pin->GetNumber() );
1015
1016 if( src_pin )
1017 src_pin->SetAlt( model_pin->GetAlt() );
1018 }
1019 }
1020 }
1021 }
1022 }
1023}
1024
1025
1026void SCH_SYMBOL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
1027{
1028 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1029 aFunction( pin.get() );
1030
1031 for( SCH_FIELD& field : m_fields )
1032 aFunction( &field );
1033}
1034
1035
1036SCH_PIN* SCH_SYMBOL::GetPin( const wxString& aNumber ) const
1037{
1038 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1039 {
1040 if( pin->GetNumber() == aNumber )
1041 return pin.get();
1042 }
1043
1044 return nullptr;
1045}
1046
1047
1048const SCH_PIN* SCH_SYMBOL::GetPin( const VECTOR2I& aPos ) const
1049{
1050 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
1051 {
1052 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
1053 : GetUnit();
1054 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
1055 : GetBodyStyle();
1056
1057 if( pin_unit > 0 && pin_unit != GetUnit() )
1058 continue;
1059
1060 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
1061 continue;
1062
1063 if( pin->GetPosition() == aPos )
1064 return pin.get();
1065 }
1066
1067 return nullptr;
1068}
1069
1070
1071std::vector<SCH_PIN*> SCH_SYMBOL::GetLibPins() const
1072{
1073 if( m_part )
1074 return m_part->GetPins( m_unit, m_bodyStyle );
1075
1076 return std::vector<SCH_PIN*>();
1077}
1078
1079
1080std::vector<SCH_PIN*> SCH_SYMBOL::GetAllLibPins() const
1081{
1082 if( m_part )
1083 return m_part->GetPins();
1084
1085 return std::vector<SCH_PIN*>();
1086}
1087
1088
1090{
1091 return m_part ? m_part->GetPinCount() : 0;
1092}
1093
1094
1096{
1097 auto it = m_pinMap.find( aLibPin );
1098
1099 if( it != m_pinMap.end() )
1100 return it->second;
1101
1102 wxFAIL_MSG_AT( "Pin not found", __FILE__, __LINE__, __FUNCTION__ );
1103 return nullptr;
1104}
1105
1106
1107std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
1108{
1109 std::vector<SCH_PIN*> pins;
1110
1111 if( aSheet == nullptr )
1112 {
1113 wxCHECK_MSG( Schematic(), pins, "Can't call GetPins on a symbol with no schematic" );
1114
1115 aSheet = &Schematic()->CurrentSheet();
1116 }
1117
1118 int unit = GetUnitSelection( aSheet );
1119
1120 for( const std::unique_ptr<SCH_PIN>& p : m_pins )
1121 {
1122 if( unit && p->GetLibPin() && p->GetLibPin()->GetUnit()
1123 && ( p->GetLibPin()->GetUnit() != unit ) )
1124 {
1125 continue;
1126 }
1127
1128 pins.push_back( p.get() );
1129 }
1130
1131 return pins;
1132}
1133
1134
1135std::vector<SCH_PIN*> SCH_SYMBOL::GetPins() const
1136{
1137 return GetPins( nullptr );
1138}
1139
1140
1142{
1143 wxCHECK_RET( aItem != nullptr && aItem->Type() == SCH_SYMBOL_T,
1144 wxT( "Cannot swap data with invalid symbol." ) );
1145
1146 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
1147
1148 std::swap( m_lib_id, symbol->m_lib_id );
1149
1150 m_pins.swap( symbol->m_pins ); // std::vector's swap()
1151
1152 for( std::unique_ptr<SCH_PIN>& pin : symbol->m_pins )
1153 pin->SetParent( symbol );
1154
1155 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1156 pin->SetParent( this );
1157
1158 LIB_SYMBOL* libSymbol = symbol->m_part.release();
1159 symbol->m_part = std::move( m_part );
1160 symbol->UpdatePins();
1161 m_part.reset( libSymbol );
1162 UpdatePins();
1163
1164 std::swap( m_pos, symbol->m_pos );
1165 std::swap( m_unit, symbol->m_unit );
1166 std::swap( m_bodyStyle, symbol->m_bodyStyle );
1167
1168 m_fields.swap( symbol->m_fields ); // std::vector's swap()
1169
1170 for( SCH_FIELD& field : symbol->m_fields )
1171 field.SetParent( symbol );
1172
1173 for( SCH_FIELD& field : m_fields )
1174 field.SetParent( this );
1175
1176 TRANSFORM tmp = m_transform;
1177
1178 m_transform = symbol->m_transform;
1179 symbol->m_transform = tmp;
1180
1181 std::swap( m_excludedFromSim, symbol->m_excludedFromSim );
1182 std::swap( m_excludedFromBOM, symbol->m_excludedFromBOM );
1183 std::swap( m_DNP, symbol->m_DNP );
1184 std::swap( m_excludedFromBoard, symbol->m_excludedFromBoard );
1185
1186 std::swap( m_instanceReferences, symbol->m_instanceReferences );
1187 std::swap( m_schLibSymbolName, symbol->m_schLibSymbolName );
1188}
1189
1190
1191void SCH_SYMBOL::GetContextualTextVars( wxArrayString* aVars ) const
1192{
1193 for( const SCH_FIELD& field : m_fields )
1194 {
1195 if( field.IsPrivate() )
1196 continue;
1197
1198 if( field.IsMandatory() )
1199 aVars->push_back( field.GetCanonicalName().Upper() );
1200 else
1201 aVars->push_back( field.GetName() );
1202 }
1203
1204 aVars->push_back( wxT( "OP" ) );
1205 aVars->push_back( wxT( "FOOTPRINT_LIBRARY" ) );
1206 aVars->push_back( wxT( "FOOTPRINT_NAME" ) );
1207 aVars->push_back( wxT( "UNIT" ) );
1208 aVars->push_back( wxT( "SHORT_REFERENCE" ) );
1209 aVars->push_back( wxT( "SYMBOL_LIBRARY" ) );
1210 aVars->push_back( wxT( "SYMBOL_NAME" ) );
1211 aVars->push_back( wxT( "SYMBOL_DESCRIPTION" ) );
1212 aVars->push_back( wxT( "SYMBOL_KEYWORDS" ) );
1213 aVars->push_back( wxT( "EXCLUDE_FROM_BOM" ) );
1214 aVars->push_back( wxT( "EXCLUDE_FROM_BOARD" ) );
1215 aVars->push_back( wxT( "EXCLUDE_FROM_SIM" ) );
1216 aVars->push_back( wxT( "DNP" ) );
1217 aVars->push_back( wxT( "SHORT_NET_NAME(<pin_number>)" ) );
1218 aVars->push_back( wxT( "NET_NAME(<pin_number>)" ) );
1219 aVars->push_back( wxT( "NET_CLASS(<pin_number>)" ) );
1220 aVars->push_back( wxT( "PIN_NAME(<pin_number>)" ) );
1221}
1222
1223
1224bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
1225{
1226 static wxRegEx operatingPoint( wxT( "^"
1227 "OP"
1228 "(:[^.]*)?" // pin
1229 "(.([0-9])?" // precisionStr
1230 "([a-zA-Z]*))?" // rangeStr
1231 "$" ) );
1232
1233 wxCHECK( aPath, false );
1234
1235 SCHEMATIC* schematic = Schematic();
1236
1237 if( !schematic )
1238 return false;
1239
1240 if( operatingPoint.Matches( *token ) )
1241 {
1242 wxString pin( operatingPoint.GetMatch( *token, 1 ).Lower() );
1243 wxString precisionStr( operatingPoint.GetMatch( *token, 3 ) );
1244 wxString rangeStr( operatingPoint.GetMatch( *token, 4 ) );
1245
1246 int precision = precisionStr.IsEmpty() ? 3 : precisionStr[0] - '0';
1247 wxString range = rangeStr.IsEmpty() ? wxString( wxS( "~A" ) ) : rangeStr;
1248
1249 SIM_LIB_MGR simLibMgr( &schematic->Prj() );
1250
1251 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
1252 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
1253
1254 if( m_part )
1255 embeddedFilesStack.push_back( m_part->GetEmbeddedFiles() );
1256
1257 simLibMgr.SetFilesStack( std::move( embeddedFilesStack ) );
1258
1259 NULL_REPORTER devnull;
1260 SIM_MODEL& model = simLibMgr.CreateModel( aPath, const_cast<SCH_SYMBOL&>( *this ),
1261 true, aDepth + 1, devnull ).model;
1262 SPICE_ITEM spiceItem;
1263 spiceItem.refName = GetRef( aPath );
1264
1265 wxString spiceRef = model.SpiceGenerator().ItemName( spiceItem );
1266 spiceRef = spiceRef.Lower();
1267
1268 if( pin.IsEmpty() )
1269 {
1270 *token = schematic->GetOperatingPoint( spiceRef, precision, range );
1271 return true;
1272 }
1273 else if( pin == wxS( ":power" ) )
1274 {
1275 if( rangeStr.IsEmpty() )
1276 range = wxS( "~W" );
1277
1278 *token = schematic->GetOperatingPoint( spiceRef + wxS( ":power" ), precision, range );
1279 return true;
1280 }
1281 else
1282 {
1283 pin = pin.SubString( 1, -1 ); // Strip ':' from front
1284
1285 for( const std::reference_wrapper<const SIM_MODEL_PIN>& modelPin : model.GetPins() )
1286 {
1287 SCH_PIN* symbolPin = GetPin( modelPin.get().symbolPinNumber );
1288
1289 if( pin == symbolPin->GetName().Lower() || pin == symbolPin->GetNumber().Lower() )
1290 {
1291 if( model.GetPins().size() == 2 )
1292 {
1293 *token = schematic->GetOperatingPoint( spiceRef, precision, range );
1294 }
1295 else
1296 {
1297 wxString signalName = spiceRef + wxS( ":" ) + modelPin.get().modelPinName;
1298 *token = schematic->GetOperatingPoint( signalName, precision, range );
1299 }
1300
1301 return true;
1302 }
1303 }
1304 }
1305
1306 *token = wxS( "?" );
1307 return true;
1308 }
1309
1310 if( token->Contains( ':' ) )
1311 {
1312 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
1313 return true;
1314 }
1315
1316 wxString upperToken = token->Upper();
1317
1318 for( const SCH_FIELD& field : m_fields )
1319 {
1320 wxString fieldName = field.IsMandatory() ? field.GetCanonicalName()
1321 : field.GetName();
1322
1323 wxString textToken = field.GetText();
1324 textToken.Replace( " ", wxEmptyString );
1325 wxString tokenString = "${" + fieldName + "}";
1326
1327 // If the field data is just a reference to the field, don't resolve
1328 if( textToken.IsSameAs( tokenString, false ) )
1329 return true;
1330
1331 if( token->IsSameAs( fieldName, false ) )
1332 {
1333 if( field.GetId() == FIELD_T::REFERENCE )
1334 *token = GetRef( aPath, true );
1335 else
1336 *token = field.GetShownText( aPath, false, aDepth + 1 );
1337
1338 return true;
1339 }
1340 }
1341
1342 // Consider missing simulation fields as empty, not un-resolved
1343 if( token->IsSameAs( wxT( "SIM.DEVICE" ) )
1344 || token->IsSameAs( wxT( "SIM.TYPE" ) )
1345 || token->IsSameAs( wxT( "SIM.PINS" ) )
1346 || token->IsSameAs( wxT( "SIM.PARAMS" ) )
1347 || token->IsSameAs( wxT( "SIM.LIBRARY" ) )
1348 || token->IsSameAs( wxT( "SIM.NAME" ) ) )
1349 {
1350 *token = wxEmptyString;
1351 return true;
1352 }
1353
1354 for( const TEMPLATE_FIELDNAME& templateFieldname :
1356 {
1357 if( token->IsSameAs( templateFieldname.m_Name )
1358 || token->IsSameAs( templateFieldname.m_Name.Upper() ) )
1359 {
1360 // If we didn't find it in the fields list then it isn't set on this symbol.
1361 // Just return an empty string.
1362 *token = wxEmptyString;
1363 return true;
1364 }
1365 }
1366
1367 if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
1368 {
1369 wxString footprint = GetFootprintFieldText( true, aPath, false );
1370
1371 wxArrayString parts = wxSplit( footprint, ':' );
1372
1373 if( parts.Count() > 0 )
1374 *token = parts[ 0 ];
1375 else
1376 *token = wxEmptyString;
1377
1378 return true;
1379 }
1380 else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
1381 {
1382 wxString footprint = GetFootprintFieldText( true, aPath, false );
1383
1384 wxArrayString parts = wxSplit( footprint, ':' );
1385
1386 if( parts.Count() > 1 )
1387 *token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
1388 else
1389 *token = wxEmptyString;
1390
1391 return true;
1392 }
1393 else if( token->IsSameAs( wxT( "UNIT" ) ) )
1394 {
1395 *token = SubReference( GetUnitSelection( aPath ) );
1396 return true;
1397 }
1398 else if( token->IsSameAs( wxT( "SHORT_REFERENCE" ) ) )
1399 {
1400 *token = GetRef( aPath, false );
1401 return true;
1402 }
1403 else if( token->IsSameAs( wxT( "SYMBOL_LIBRARY" ) ) )
1404 {
1406 return true;
1407 }
1408 else if( token->IsSameAs( wxT( "SYMBOL_NAME" ) ) )
1409 {
1411 return true;
1412 }
1413 else if( token->IsSameAs( wxT( "SYMBOL_DESCRIPTION" ) ) )
1414 {
1415 *token = GetDescription();
1416 return true;
1417 }
1418 else if( token->IsSameAs( wxT( "SYMBOL_KEYWORDS" ) ) )
1419 {
1420 *token = GetKeyWords();
1421 return true;
1422 }
1423 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
1424 {
1425 *token = wxEmptyString;
1426
1427 if( aPath->GetExcludedFromBOM() || this->ResolveExcludedFromBOM() )
1428 *token = _( "Excluded from BOM" );
1429
1430 return true;
1431 }
1432 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
1433 {
1434 *token = wxEmptyString;
1435
1436 if( aPath->GetExcludedFromBoard() || this->ResolveExcludedFromBoard() )
1437 *token = _( "Excluded from board" );
1438
1439 return true;
1440 }
1441 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
1442 {
1443 *token = wxEmptyString;
1444
1445 if( aPath->GetExcludedFromSim() || this->ResolveExcludedFromSim() )
1446 *token = _( "Excluded from simulation" );
1447
1448 return true;
1449 }
1450 else if( token->IsSameAs( wxT( "DNP" ) ) )
1451 {
1452 *token = wxEmptyString;
1453
1454 if( aPath->GetDNP() || this->ResolveDNP() )
1455 *token = _( "DNP" );
1456
1457 return true;
1458 }
1459 else if( token->StartsWith( wxT( "SHORT_NET_NAME(" ) )
1460 || token->StartsWith( wxT( "NET_NAME(" ) )
1461 || token->StartsWith( wxT( "NET_CLASS(" ) )
1462 || token->StartsWith( wxT( "PIN_NAME(" ) ) )
1463 {
1464 wxString pinNumber = token->AfterFirst( '(' );
1465 pinNumber = pinNumber.BeforeLast( ')' );
1466
1467 for( SCH_PIN* pin : GetPins( aPath ) )
1468 {
1469 if( pin->GetNumber() == pinNumber )
1470 {
1471 if( token->StartsWith( wxT( "PIN_NAME" ) ) )
1472 {
1473 *token = pin->GetAlt().IsEmpty() ? pin->GetName() : pin->GetAlt();
1474 return true;
1475 }
1476
1477 SCH_CONNECTION* conn = pin->Connection( aPath );
1478
1479 if( !conn )
1480 *token = wxEmptyString;
1481 else if( token->StartsWith( wxT( "SHORT_NET_NAME" ) ) )
1482 *token = conn->LocalName();
1483 else if( token->StartsWith( wxT( "NET_NAME" ) ) )
1484 *token = conn->Name();
1485 else if( token->StartsWith( wxT( "NET_CLASS" ) ) )
1486 *token = pin->GetEffectiveNetClass( aPath )->GetName();
1487
1488 return true;
1489 }
1490 }
1491 }
1492
1493 // See if parent can resolve it (this will recurse to ancestors)
1494 if( aPath->Last() && aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
1495 return true;
1496
1497 return false;
1498}
1499
1500
1501void SCH_SYMBOL::ClearAnnotation( const SCH_SHEET_PATH* aSheetPath, bool aResetPrefix )
1502{
1503 if( aSheetPath )
1504 {
1505 KIID_PATH path = aSheetPath->Path();
1506
1507 for( SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1508 {
1509 if( instance.m_Path == path )
1510 {
1511 if( instance.m_Reference.IsEmpty() || aResetPrefix )
1512 instance.m_Reference = UTIL::GetRefDesUnannotated( m_prefix );
1513 else
1514 instance.m_Reference = UTIL::GetRefDesUnannotated( instance.m_Reference );
1515 }
1516 }
1517 }
1518 else
1519 {
1520 for( SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1521 {
1522 if( instance.m_Reference.IsEmpty() || aResetPrefix)
1523 instance.m_Reference = UTIL::GetRefDesUnannotated( m_prefix );
1524 else
1525 instance.m_Reference = UTIL::GetRefDesUnannotated( instance.m_Reference );
1526 }
1527 }
1528
1529 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
1530 pin->ClearDefaultNetName( aSheetPath );
1531
1532 // These 2 changes do not work in complex hierarchy.
1533 // When a clear annotation is made, the calling function must call a
1534 // UpdateAllScreenReferences for the active sheet.
1535 // But this call cannot made here.
1536 wxString currentReference = GetField( FIELD_T::REFERENCE )->GetText();
1537
1538 if( currentReference.IsEmpty() || aResetPrefix )
1539 GetField( FIELD_T::REFERENCE )->SetText( UTIL::GetRefDesUnannotated( m_prefix ) );
1540 else
1541 GetField( FIELD_T::REFERENCE )->SetText( UTIL::GetRefDesUnannotated( currentReference ) );
1542}
1543
1544
1546{
1547 // An empty sheet path is illegal, at a minimum the root sheet UUID must be present.
1548 wxCHECK( aSheetPath.size() > 0, false );
1549
1550 for( const SCH_SYMBOL_INSTANCE& instance : m_instanceReferences )
1551 {
1552 // if aSheetPath is found, nothing to do:
1553 if( instance.m_Path == aSheetPath )
1554 return false;
1555 }
1556
1557 // This entry does not exist: add it, with its last-used reference
1558 AddHierarchicalReference( aSheetPath, GetField( FIELD_T::REFERENCE )->GetText(), m_unit );
1559 return true;
1560}
1561
1562
1563void SCH_SYMBOL::SetOrientation( int aOrientation )
1564{
1565 TRANSFORM temp = TRANSFORM();
1566 bool transform = false;
1567
1568 switch( aOrientation )
1569 {
1570 case SYM_ORIENT_0:
1571 case SYM_NORMAL: // default transform matrix
1573 break;
1574
1575 case SYM_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1576 temp.x1 = 0;
1577 temp.y1 = 1;
1578 temp.x2 = -1;
1579 temp.y2 = 0;
1580 transform = true;
1581 break;
1582
1583 case SYM_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1584 temp.x1 = 0;
1585 temp.y1 = -1;
1586 temp.x2 = 1;
1587 temp.y2 = 0;
1588 transform = true;
1589 break;
1590
1591 case SYM_MIRROR_Y: // Mirror Y (incremental transform)
1592 temp.x1 = -1;
1593 temp.y1 = 0;
1594 temp.x2 = 0;
1595 temp.y2 = 1;
1596 transform = true;
1597 break;
1598
1599 case SYM_MIRROR_X: // Mirror X (incremental transform)
1600 temp.x1 = 1;
1601 temp.y1 = 0;
1602 temp.x2 = 0;
1603 temp.y2 = -1;
1604 transform = true;
1605 break;
1606
1607 case SYM_ORIENT_90:
1610 break;
1611
1612 case SYM_ORIENT_180:
1616 break;
1617
1618 case SYM_ORIENT_270:
1621 break;
1622
1623 case ( SYM_ORIENT_0 + SYM_MIRROR_X ):
1626 break;
1627
1628 case ( SYM_ORIENT_0 + SYM_MIRROR_Y ):
1631 break;
1632
1637 break;
1638
1639 case ( SYM_ORIENT_90 + SYM_MIRROR_X ):
1642 break;
1643
1644 case ( SYM_ORIENT_90 + SYM_MIRROR_Y ):
1647 break;
1648
1653 break;
1654
1655 case ( SYM_ORIENT_180 + SYM_MIRROR_X ):
1658 break;
1659
1660 case ( SYM_ORIENT_180 + SYM_MIRROR_Y ):
1663 break;
1664
1669 break;
1670
1671 case ( SYM_ORIENT_270 + SYM_MIRROR_X ):
1674 break;
1675
1676 case ( SYM_ORIENT_270 + SYM_MIRROR_Y ):
1679 break;
1680
1685 break;
1686
1687 default:
1688 transform = false;
1689 wxFAIL_MSG( "Invalid schematic symbol orientation type." );
1690 break;
1691 }
1692
1693 if( transform )
1694 {
1695 /* The new matrix transform is the old matrix transform modified by the
1696 * requested transformation, which is the temp transform (rot,
1697 * mirror ..) in order to have (in term of matrix transform):
1698 * transform coord = new_m_transform * coord
1699 * where transform coord is the coord modified by new_m_transform from
1700 * the initial value coord.
1701 * new_m_transform is computed (from old_m_transform and temp) to
1702 * have:
1703 * transform coord = old_m_transform * temp
1704 */
1705 TRANSFORM newTransform;
1706
1707 newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1708 newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1709 newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1710 newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1711 m_transform = newTransform;
1712 }
1713}
1714
1715
1717{
1718 /*
1719 * This is slow, but also a bizarre algorithm. I don't feel like unteasing the algorithm right
1720 * now, so let's just cache it for the moment.
1721 */
1724
1725 int rotate_values[] =
1726 {
1739 };
1740
1741 // Try to find the current transform option:
1742 TRANSFORM transform = m_transform;
1743 SCH_SYMBOL temp( *this );
1744 temp.SetParentGroup( nullptr );
1745
1746 for( int type_rotate : rotate_values )
1747 {
1748 temp.SetOrientation( type_rotate );
1749
1750 if( transform == temp.GetTransform() )
1751 {
1753 return type_rotate;
1754 }
1755 }
1756
1757 // Error: orientation not found in list (should not happen)
1758 wxFAIL_MSG( "Schematic symbol orientation matrix internal error." );
1759
1760 return SYM_NORMAL;
1761}
1762
1763
1764#if defined(DEBUG)
1765
1766void SCH_SYMBOL::Show( int nestLevel, std::ostream& os ) const
1767{
1768 // for now, make it look like XML:
1769 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1770 << " ref=\"" << TO_UTF8( GetField( FIELD_T::REFERENCE )->GetName() )
1771 << '"' << " chipName=\""
1772 << GetLibId().Format().wx_str() << '"' << m_pos
1773 << " layer=\"" << m_layer
1774 << '"' << ">\n";
1775
1776 // skip the reference, it's been output already.
1777 for( int i = 1; i < (int) GetFields().size(); ++i )
1778 {
1779 const wxString& value = GetFields()[i].GetText();
1780
1781 if( !value.IsEmpty() )
1782 {
1783 NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1784 << TO_UTF8( GetFields()[i].GetName() )
1785 << '"' << " value=\""
1786 << TO_UTF8( value ) << "\"/>\n";
1787 }
1788 }
1789
1790 NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1791}
1792
1793#endif
1794
1795
1796BOX2I SCH_SYMBOL::doGetBoundingBox( bool aIncludePins, bool aIncludeFields ) const
1797{
1798 BOX2I bBox;
1799
1800 if( m_part )
1801 bBox = m_part->GetBodyBoundingBox( m_unit, m_bodyStyle, aIncludePins, false );
1802 else
1804 false );
1805
1806 bBox = m_transform.TransformCoordinate( bBox );
1807 bBox.Normalize();
1808
1809 bBox.Offset( m_pos );
1810
1811 if( aIncludeFields )
1812 {
1813 for( const SCH_FIELD& field : m_fields )
1814 {
1815 if( field.IsVisible() )
1816 bBox.Merge( field.GetBoundingBox() );
1817 }
1818 }
1819
1820 return bBox;
1821}
1822
1823
1825{
1826 try
1827 {
1828 return doGetBoundingBox( false, false );
1829 }
1830 catch( const boost::bad_pointer& e )
1831 {
1832 wxFAIL_MSG( wxString::Format( wxT( "Boost pointer exception occurred: %s" ), e.what() ) );
1833 return BOX2I();
1834 }
1835}
1836
1837
1839{
1840 return doGetBoundingBox( true, false );
1841}
1842
1843
1845{
1846 return doGetBoundingBox( true, true );
1847}
1848
1849
1850void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1851{
1852 wxString msg;
1853
1854 SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1855 SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1856
1857 auto addExcludes =
1858 [&]()
1859 {
1860 wxArrayString msgs;
1861
1862 if( GetExcludedFromSim() )
1863 msgs.Add( _( "Simulation" ) );
1864
1865 if( GetExcludedFromBOM() )
1866 msgs.Add( _( "BOM" ) );
1867
1868 if( GetExcludedFromBoard() )
1869 msgs.Add( _( "Board" ) );
1870
1871 if( GetDNP() )
1872 msgs.Add( _( "DNP" ) );
1873
1874 msg = wxJoin( msgs, '|' );
1875 msg.Replace( '|', wxS( ", " ) );
1876
1877 if( !msg.empty() )
1878 aList.emplace_back( _( "Exclude from" ), msg );
1879 };
1880
1881 // part and alias can differ if alias is not the root
1882 if( m_part )
1883 {
1884 if( m_part.get() != LIB_SYMBOL::GetDummy() )
1885 {
1886 if( m_part->IsPower() )
1887 {
1888 // Don't use GetShownText(); we want to see the variable references here
1889 aList.emplace_back( _( "Power symbol" ),
1890 KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::VALUE )->GetText() ) );
1891 }
1892 else
1893 {
1894 aList.emplace_back( _( "Reference" ),
1895 UnescapeString( GetRef( currentSheet ) ) );
1896
1897 // Don't use GetShownText(); we want to see the variable references here
1898 aList.emplace_back( _( "Value" ),
1899 KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::VALUE )->GetText() ) );
1900 addExcludes();
1901 aList.emplace_back( _( "Name" ),
1903 GetLibId().GetLibItemName() ) );
1904 }
1905
1906#if 0 // Display symbol flags, for debug only
1907 aList.emplace_back( _( "flags" ), wxString::Format( "%X", GetEditFlags() ) );
1908#endif
1909
1910 if( !m_part->IsRoot() )
1911 {
1912 msg = _( "Missing parent" );
1913
1914 std::shared_ptr< LIB_SYMBOL > parent = m_part->GetParent().lock();
1915
1916 if( parent )
1917 msg = parent->GetName();
1918
1919 aList.emplace_back( _( "Derived from" ), UnescapeString( msg ) );
1920 }
1921 else if( !m_lib_id.GetLibNickname().empty() )
1922 {
1923 aList.emplace_back( _( "Library" ), m_lib_id.GetLibNickname() );
1924 }
1925 else
1926 {
1927 aList.emplace_back( _( "Library" ), _( "Undefined!!!" ) );
1928 }
1929
1930 // Display the current associated footprint, if exists.
1931 // Don't use GetShownText(); we want to see the variable references here
1932 msg = KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::FOOTPRINT )->GetText() );
1933
1934 if( msg.IsEmpty() )
1935 msg = _( "<Unknown>" );
1936
1937 aList.emplace_back( _( "Footprint" ), msg );
1938
1939 // Display description of the symbol, and keywords found in lib
1940 aList.emplace_back( _( "Description" ) + wxT( ": " )
1941 + GetField( FIELD_T::DESCRIPTION )->GetText(),
1942 _( "Keywords" ) + wxT( ": " ) + m_part->GetKeyWords() );
1943 }
1944 }
1945 else
1946 {
1947 aList.emplace_back( _( "Reference" ), GetRef( currentSheet ) );
1948
1949 // Don't use GetShownText(); we want to see the variable references here
1950 aList.emplace_back( _( "Value" ),
1951 KIUI::EllipsizeStatusText( aFrame, GetField( FIELD_T::VALUE )->GetText() ) );
1952 addExcludes();
1953 aList.emplace_back( _( "Name" ),
1954 KIUI::EllipsizeStatusText( aFrame, GetLibId().GetLibItemName() ) );
1955
1956 wxString libNickname = GetLibId().GetLibNickname();
1957
1958 if( libNickname.empty() )
1959 msg = _( "No library defined!" );
1960 else
1961 msg.Printf( _( "Symbol not found in %s!" ), libNickname );
1962
1963 aList.emplace_back( _( "Library" ), msg );
1964 }
1965}
1966
1967
1969{
1970 return BITMAPS::add_component;
1971}
1972
1973
1975{
1976 return GetLibSymbolRef()->GetEmbeddedFiles();
1977}
1978
1979
1981{
1982 int dx = m_pos.x;
1983
1985 MIRROR( m_pos.x, aCenter );
1986 dx -= m_pos.x; // dx,0 is the move vector for this transform
1987
1988 for( SCH_FIELD& field : m_fields )
1989 {
1990 // Move the fields to the new position because the symbol itself has moved.
1991 VECTOR2I pos = field.GetTextPos();
1992 pos.x -= dx;
1993 field.SetTextPos( pos );
1994 }
1995}
1996
1997
1999{
2000 int dy = m_pos.y;
2001
2003 MIRROR( m_pos.y, aCenter );
2004 dy -= m_pos.y; // 0,dy is the move vector for this transform
2005
2006 for( SCH_FIELD& field : m_fields )
2007 {
2008 // Move the fields to the new position because the symbol itself has moved.
2009 VECTOR2I pos = field.GetTextPos();
2010 pos.y -= dy;
2011 field.SetTextPos( pos );
2012 }
2013}
2014
2015
2016void SCH_SYMBOL::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
2017{
2018 VECTOR2I prev = m_pos;
2019
2020 RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
2021
2023
2024 for( SCH_FIELD& field : m_fields )
2025 {
2026 // Move the fields to the new position because the symbol itself has moved.
2027 VECTOR2I pos = field.GetTextPos();
2028 pos.x -= prev.x - m_pos.x;
2029 pos.y -= prev.y - m_pos.y;
2030 field.SetTextPos( pos );
2031 }
2032}
2033
2034
2035bool SCH_SYMBOL::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
2036{
2037 if( aSearchData.searchMetadata )
2038 {
2039 if( EDA_ITEM::Matches( GetSchSymbolLibraryName(), aSearchData ) )
2040 return true;
2041
2042 if( EDA_ITEM::Matches( GetDescription(), aSearchData ) )
2043 return true;
2044
2045 if( EDA_ITEM::Matches( GetKeyWords(), aSearchData ) )
2046 return true;
2047 }
2048
2049 for( SCH_ITEM& drawItem : GetLibSymbolRef()->GetDrawItems() )
2050 {
2051 if( drawItem.Matches( aSearchData, aAuxData ) )
2052 return true;
2053 }
2054
2055 // Symbols are searchable via the child field and pin item text.
2056 return false;
2057}
2058
2059
2060void SCH_SYMBOL::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
2061{
2062 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2063 {
2064 SCH_PIN* lib_pin = pin->GetLibPin();
2065
2066 if( lib_pin && lib_pin->GetUnit() && m_unit && ( m_unit != lib_pin->GetUnit() ) )
2067 continue;
2068
2069 DANGLING_END_ITEM item( PIN_END, lib_pin, GetPinPhysicalPosition( lib_pin ), this );
2070 aItemList.push_back( item );
2071 }
2072}
2073
2074
2075bool SCH_SYMBOL::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
2076 std::vector<DANGLING_END_ITEM>& aItemListByPos,
2077 const SCH_SHEET_PATH* aPath )
2078{
2079 bool changed = false;
2080
2081 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2082 {
2083 bool previousState = pin->IsDangling();
2084 pin->SetIsDangling( true );
2085
2086 VECTOR2I pos = m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos;
2087
2088 auto lower = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, pos );
2089 bool do_break = false;
2090
2091 for( auto it = lower; it < aItemListByPos.end() && it->GetPosition() == pos; it++ )
2092 {
2093 DANGLING_END_ITEM& each_item = *it;
2094
2095 // Some people like to stack pins on top of each other in a symbol to indicate
2096 // internal connection. While technically connected, it is not particularly useful
2097 // to display them that way, so skip any pins that are in the same symbol as this
2098 // one.
2099 if( each_item.GetParent() == this )
2100 continue;
2101
2102 switch( each_item.GetType() )
2103 {
2104 case PIN_END:
2105 case LABEL_END:
2106 case SHEET_LABEL_END:
2107 case WIRE_END:
2108 case NO_CONNECT_END:
2109 case JUNCTION_END:
2110 pin->SetIsDangling( false );
2111 do_break = true;
2112 break;
2113
2114 default:
2115 break;
2116 }
2117
2118 if( do_break )
2119 break;
2120 }
2121
2122 changed = ( changed || ( previousState != pin->IsDangling() ) );
2123 }
2124
2125 return changed;
2126}
2127
2128
2130{
2131 if( ( aPin == nullptr ) || ( aPin->Type() != SCH_PIN_T ) )
2132 return VECTOR2I( 0, 0 );
2133
2135}
2136
2137
2139 const SCH_SHEET_PATH* aInstance ) const
2140{
2141 // Do not compare to ourself.
2142 if( aItem == this )
2143 return false;
2144
2145 const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( aItem );
2146
2147 // Don't compare against a different SCH_ITEM.
2148 wxCHECK( symbol, false );
2149
2150 // The move algorithm marks any pins that are being moved without something attached
2151 // (during the move) as dangling. We always need to recheck connectivity in this case
2152 // or we will not notice changes when the user places the symbol back in the same position
2153 // it started.
2154 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2155 {
2156 if( pin->IsDangling() )
2157 return true;
2158 }
2159
2160 if( GetPosition() != symbol->GetPosition() )
2161 return true;
2162
2163 if( GetLibId() != symbol->GetLibId() )
2164 return true;
2165
2166 if( GetUnitSelection( aInstance ) != symbol->GetUnitSelection( aInstance ) )
2167 return true;
2168
2169 if( GetRef( aInstance ) != symbol->GetRef( aInstance ) )
2170 return true;
2171
2172 // Power symbol value field changes are connectivity changes.
2173 if( IsPower()
2174 && ( GetValue( true, aInstance, false ) != symbol->GetValue( true, aInstance, false ) ) )
2175 return true;
2176
2177 if( m_pins.size() != symbol->m_pins.size() )
2178 return true;
2179
2180 for( size_t i = 0; i < m_pins.size(); i++ )
2181 {
2182 if( m_pins[i]->HasConnectivityChanges( symbol->m_pins[i].get() ) )
2183 return true;
2184 }
2185
2186 return false;
2187}
2188
2189
2190std::vector<VECTOR2I> SCH_SYMBOL::GetConnectionPoints() const
2191{
2192 std::vector<VECTOR2I> retval;
2193
2194 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2195 {
2196 // Collect only pins attached to the current unit and convert.
2197 // others are not associated to this symbol instance
2198 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2199 : GetUnit();
2200 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2201 : GetBodyStyle();
2202
2203 if( pin_unit > 0 && pin_unit != GetUnit() )
2204 continue;
2205
2206 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2207 continue;
2208
2209 retval.push_back( m_transform.TransformCoordinate( pin->GetLocalPosition() ) + m_pos );
2210 }
2211
2212 return retval;
2213}
2214
2215
2217{
2218 if( m_part )
2219 {
2220 // Calculate the position relative to the symbol.
2221 VECTOR2I libPosition = aPosition - m_pos;
2222
2223 return m_part->LocateDrawItem( m_unit, m_bodyStyle, aType, libPosition, m_transform );
2224 }
2225
2226 return nullptr;
2227}
2228
2229
2230wxString SCH_SYMBOL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2231{
2232 return wxString::Format( _( "Symbol %s [%s]" ),
2233 KIUI::EllipsizeMenuText( GetField( FIELD_T::REFERENCE )->GetText() ),
2234 KIUI::EllipsizeMenuText( GetLibId().GetLibItemName() ) );
2235}
2236
2237
2238INSPECT_RESULT SCH_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
2239 const std::vector<KICAD_T>& aScanTypes )
2240{
2241 for( KICAD_T scanType : aScanTypes )
2242 {
2243 if( scanType == SCH_LOCATE_ANY_T || ( scanType == SCH_SYMBOL_T )
2244 || ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
2245 {
2246 if( INSPECT_RESULT::QUIT == aInspector( this, aTestData ) )
2247 return INSPECT_RESULT::QUIT;
2248 }
2249
2250 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
2251 {
2252 for( SCH_FIELD& field : m_fields )
2253 {
2254 if( INSPECT_RESULT::QUIT == aInspector( &field, (void*) this ) )
2255 return INSPECT_RESULT::QUIT;
2256 }
2257 }
2258
2259 if( scanType == SCH_FIELD_LOCATE_REFERENCE_T )
2260 {
2261 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::REFERENCE ), (void*) this ) )
2262 return INSPECT_RESULT::QUIT;
2263 }
2264
2265 if( scanType == SCH_FIELD_LOCATE_VALUE_T
2266 || ( scanType == SCH_SYMBOL_LOCATE_POWER_T && m_part && m_part->IsPower() ) )
2267 {
2268 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::VALUE ), (void*) this ) )
2269 return INSPECT_RESULT::QUIT;
2270 }
2271
2272 if( scanType == SCH_FIELD_LOCATE_FOOTPRINT_T )
2273 {
2274 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::FOOTPRINT ), (void*) this ) )
2275 return INSPECT_RESULT::QUIT;
2276 }
2277
2278 if( scanType == SCH_FIELD_LOCATE_DATASHEET_T )
2279 {
2280 if( INSPECT_RESULT::QUIT == aInspector( GetField( FIELD_T::DATASHEET ), (void*) this ) )
2281 return INSPECT_RESULT::QUIT;
2282 }
2283
2284 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_PIN_T )
2285 {
2286 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2287 {
2288 // Collect only pins attached to the current unit and convert.
2289 // others are not associated to this symbol instance
2290 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2291 : GetUnit();
2292 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2293 : GetBodyStyle();
2294
2295 if( pin_unit > 0 && pin_unit != GetUnit() )
2296 continue;
2297
2298 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2299 continue;
2300
2301 if( INSPECT_RESULT::QUIT == aInspector( pin.get(), (void*) this ) )
2302 return INSPECT_RESULT::QUIT;
2303 }
2304 }
2305 }
2306
2307 return INSPECT_RESULT::CONTINUE;
2308}
2309
2310
2311bool SCH_SYMBOL::operator <( const SCH_ITEM& aItem ) const
2312{
2313 if( Type() != aItem.Type() )
2314 return Type() < aItem.Type();
2315
2316 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( &aItem );
2317
2319
2320 if( rect.GetArea() != symbol->GetBodyAndPinsBoundingBox().GetArea() )
2321 return rect.GetArea() < symbol->GetBodyAndPinsBoundingBox().GetArea();
2322
2323 if( m_pos.x != symbol->m_pos.x )
2324 return m_pos.x < symbol->m_pos.x;
2325
2326 if( m_pos.y != symbol->m_pos.y )
2327 return m_pos.y < symbol->m_pos.y;
2328
2329 return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
2330}
2331
2332
2333bool SCH_SYMBOL::operator==( const SCH_SYMBOL& aSymbol ) const
2334{
2335 std::vector<SCH_FIELD*> fields, otherFields;
2336
2337 GetFields( fields, false );
2338 aSymbol.GetFields( otherFields, false );
2339
2340 if( fields.size() != otherFields.size() )
2341 return false;
2342
2343 for( int ii = 0; ii < (int) fields.size(); ii++ )
2344 {
2345 if( fields[ii]->GetId() == FIELD_T::REFERENCE )
2346 continue;
2347
2348 if( fields[ii]->GetText().Cmp( otherFields[ii]->GetText() ) != 0 )
2349 return false;
2350 }
2351
2352 return true;
2353}
2354
2355
2356bool SCH_SYMBOL::operator!=( const SCH_SYMBOL& aSymbol ) const
2357{
2358 return !( *this == aSymbol );
2359}
2360
2361
2363{
2364 wxCHECK_MSG( Type() == aSymbol.Type(), *this,
2365 wxT( "Cannot assign object type " ) + aSymbol.GetClass() + wxT( " to type " ) +
2366 GetClass() );
2367
2368 if( &aSymbol != this )
2369 {
2370 SYMBOL::operator=( aSymbol );
2371
2372 m_lib_id = aSymbol.m_lib_id;
2373 m_part.reset( aSymbol.m_part ? new LIB_SYMBOL( *aSymbol.m_part ) : nullptr );
2374 m_pos = aSymbol.m_pos;
2375 m_unit = aSymbol.m_unit;
2376 m_bodyStyle = aSymbol.m_bodyStyle;
2377 m_transform = aSymbol.m_transform;
2378
2380
2381 m_fields = aSymbol.m_fields; // std::vector's assignment operator
2382
2383 // Reparent fields after assignment to new symbol.
2384 for( SCH_FIELD& field : m_fields )
2385 field.SetParent( this );
2386
2387 UpdatePins();
2388 }
2389
2390 return *this;
2391}
2392
2393
2394bool SCH_SYMBOL::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
2395{
2396 BOX2I bBox = GetBodyBoundingBox();
2397 bBox.Inflate( aAccuracy / 2 );
2398
2399 if( bBox.Contains( aPosition ) )
2400 return true;
2401
2402 return false;
2403}
2404
2405
2406bool SCH_SYMBOL::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
2407{
2409 return false;
2410
2411 BOX2I rect = aRect;
2412
2413 rect.Inflate( aAccuracy / 2 );
2414
2415 if( aContained )
2416 return rect.Contains( GetBodyBoundingBox() );
2417
2418 return rect.Intersects( GetBodyBoundingBox() );
2419}
2420
2421
2422bool SCH_SYMBOL::doIsConnected( const VECTOR2I& aPosition ) const
2423{
2425
2426 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2427 {
2428 if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
2429 continue;
2430
2431 // Collect only pins attached to the current unit and convert.
2432 // others are not associated to this symbol instance
2433 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2434 : GetUnit();
2435 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2436 : GetBodyStyle();
2437
2438 if( pin_unit > 0 && pin_unit != GetUnit() )
2439 continue;
2440
2441 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2442 continue;
2443
2444 if( pin->GetLocalPosition() == new_pos )
2445 return true;
2446 }
2447
2448 return false;
2449}
2450
2451
2453{
2454 return m_isInNetlist;
2455}
2456
2457
2458void SCH_SYMBOL::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
2459 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
2460{
2461 if( aBackground )
2462 return;
2463
2464 if( m_part )
2465 {
2466 std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() );
2467
2468 // Copy the source so we can re-orient and translate it.
2469 LIB_SYMBOL tempSymbol( *m_part );
2470 std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
2471
2472 // Copy the pin info from the symbol to the temp pins
2473 for( unsigned i = 0; i < tempPins.size(); ++ i )
2474 {
2475 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
2476 SCH_PIN* tempPin = tempPins[ i ];
2477
2478 tempPin->SetName( symbolPin->GetShownName() );
2479 tempPin->SetType( symbolPin->GetType() );
2480 tempPin->SetShape( symbolPin->GetShape() );
2481
2482 if( symbolPin->IsDangling() )
2483 tempPin->SetFlags( IS_DANGLING );
2484 }
2485
2486 for( SCH_ITEM& item : tempSymbol.GetDrawItems() )
2487 {
2488 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( &item ) )
2489 {
2490 // Use SCH_FIELD's text resolver
2491 SCH_FIELD dummy( this, FIELD_T::USER );
2492 dummy.SetText( text->GetText() );
2493 text->SetText( dummy.GetShownText( false ) );
2494 }
2495 }
2496
2497 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
2498 TRANSFORM savedTransform = renderSettings->m_Transform;
2499 renderSettings->m_Transform = GetTransform();
2500 aPlotter->StartBlock( nullptr );
2501
2502 for( bool local_background : { true, false } )
2503 {
2504 tempSymbol.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
2505 m_pos, GetDNP() );
2506
2507 for( SCH_FIELD field : m_fields )
2508 {
2509 field.ClearRenderCache();
2510 field.Plot( aPlotter, local_background, aPlotOpts, GetUnit(), GetBodyStyle(),
2511 m_pos, GetDNP() );
2512 }
2513 }
2514
2515 if( m_DNP )
2516 PlotDNP( aPlotter );
2517
2518 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
2519
2520 // Plot attributes to a hypertext menu
2521 if( aPlotOpts.m_PDFPropertyPopups )
2522 {
2523 std::vector<wxString> properties;
2524
2525 for( const SCH_FIELD& field : GetFields() )
2526 {
2527 wxString text_field = field.GetShownText( sheet, false);
2528
2529 if( text_field.IsEmpty() )
2530 continue;
2531
2532 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
2533 field.GetName(), text_field ) );
2534 }
2535
2536 if( !m_part->GetKeyWords().IsEmpty() )
2537 {
2538 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
2539 _( "Keywords" ),
2540 m_part->GetKeyWords() ) );
2541 }
2542
2543 aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
2544 }
2545
2546 aPlotter->EndBlock( nullptr );
2547 renderSettings->m_Transform = savedTransform;
2548
2549 if( !m_part->IsPower() )
2550 aPlotter->Bookmark( GetBoundingBox(), GetRef( sheet ), _( "Symbols" ) );
2551 }
2552}
2553
2554
2555void SCH_SYMBOL::PlotDNP( PLOTTER* aPlotter ) const
2556{
2557 BOX2I bbox = GetBodyBoundingBox();
2559 VECTOR2D margins( std::max( bbox.GetX() - pins.GetX(),
2560 pins.GetEnd().x - bbox.GetEnd().x ),
2561 std::max( bbox.GetY() - pins.GetY(),
2562 pins.GetEnd().y - bbox.GetEnd().y ) );
2563 int strokeWidth = 3.0 * schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
2564
2565 margins.x = std::max( margins.x * 0.6, margins.y * 0.3 );
2566 margins.y = std::max( margins.y * 0.6, margins.x * 0.3 );
2567 bbox.Inflate( KiROUND( margins.x ), KiROUND( margins.y ) );
2568
2569 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
2570 aPlotter->SetColor( renderSettings->GetLayerColor( LAYER_DNP_MARKER ) );
2571
2572 aPlotter->ThickSegment( bbox.GetOrigin(), bbox.GetEnd(), strokeWidth, nullptr );
2573
2574 aPlotter->ThickSegment( bbox.GetOrigin() + VECTOR2I( bbox.GetWidth(), 0 ),
2575 bbox.GetOrigin() + VECTOR2I( 0, bbox.GetHeight() ),
2576 strokeWidth, nullptr );
2577}
2578
2579
2580void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const
2581{
2582 if( m_part )
2583 {
2584 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
2585 TRANSFORM savedTransform = renderSettings->m_Transform;
2586 renderSettings->m_Transform = GetTransform();
2587
2588 std::vector<SCH_PIN*> libPins = m_part->GetPins( GetUnit(), GetBodyStyle() );
2589
2590 // Copy the source to stay const
2591 LIB_SYMBOL tempSymbol( *m_part );
2592 std::vector<SCH_PIN*> tempPins = tempSymbol.GetPins( GetUnit(), GetBodyStyle() );
2593 SCH_PLOT_OPTS plotOpts;
2594
2595 // Copy the pin info from the symbol to the temp pins
2596 for( unsigned i = 0; i < tempPins.size(); ++ i )
2597 {
2598 SCH_PIN* symbolPin = GetPin( libPins[ i ] );
2599 SCH_PIN* tempPin = tempPins[ i ];
2600
2601 tempPin->SetName( symbolPin->GetShownName() );
2602 tempPin->SetType( symbolPin->GetType() );
2603 tempPin->SetShape( symbolPin->GetShape() );
2604 tempPin->Plot( aPlotter, false, plotOpts, GetUnit(), GetBodyStyle(), m_pos, GetDNP() );
2605 }
2606
2607 renderSettings->m_Transform = savedTransform;
2608 }
2609}
2610
2611
2613{
2614 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2615 {
2616 if( pin->IsBrightened() )
2617 return true;
2618 }
2619
2620 return false;
2621}
2622
2623
2625{
2626 for( std::unique_ptr<SCH_PIN>& pin : m_pins )
2627 pin->ClearBrightened();
2628}
2629
2630
2631/*
2632 * When modified at the schematic level, we still store the values of these flags in the
2633 * associated m_part. If m_part now diverges from other usages, a new derived LIB_SYMBOL
2634 * will be created and stored locally in the schematic.
2635 */
2637{
2638 return m_part && m_part->GetShowPinNames();
2639}
2640
2641
2643{
2644 if( m_part )
2645 m_part->SetShowPinNames( aShow );
2646}
2647
2648
2650{
2651 return m_part && m_part->GetShowPinNumbers();
2652}
2653
2654
2656{
2657 if( m_part )
2658 m_part->SetShowPinNumbers( aShow );
2659}
2660
2661
2663{
2664 for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
2665 {
2666 int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
2667 : GetUnit();
2668 int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
2669 : GetBodyStyle();
2670
2671 if( pin_unit > 0 && pin_unit != GetUnit() )
2672 continue;
2673
2674 if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
2675 continue;
2676
2677 if( pin->IsPointClickableAnchor( aPos ) )
2678 return true;
2679 }
2680
2681 return false;
2682}
2683
2684
2686{
2687 // return true if the symbol is equivalent to a global label:
2688 // It is a Power symbol
2689 // It has only one pin type Power input
2690
2692 return false;
2693
2694 std::vector<SCH_PIN*> pin_list = GetAllLibPins();
2695
2696 if( pin_list.size() != 1 )
2697 return false;
2698
2699 return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
2700}
2701
2702
2704{
2705 // return true if the symbol is equivalent to a local label:
2706 // It is a Power symbol
2707 // It has only one pin type Power input
2708
2710 return false;
2711
2712 std::vector<SCH_PIN*> pin_list = GetAllLibPins();
2713
2714 if( pin_list.size() != 1 )
2715 return false;
2716
2717 return pin_list[0]->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN;
2718}
2719
2720
2722{
2723 if( !m_part )
2724 return false;
2725
2726 return m_part->IsLocalPower();
2727}
2728
2729
2731{
2732 if( !m_part )
2733 return false;
2734
2735 return m_part->IsGlobalPower();
2736}
2737
2738
2740{
2741 return IsLocalPower() || IsGlobalPower();
2742}
2743
2744
2746{
2747 wxCHECK( m_part, false );
2748
2749 return m_part->IsNormal();
2750}
2751
2752
2753std::unordered_set<wxString> SCH_SYMBOL::GetComponentClassNames( const SCH_SHEET_PATH* aPath ) const
2754{
2755 std::unordered_set<wxString> componentClass;
2756
2757 auto getComponentClassFields =
2758 [&]( const std::vector<SCH_FIELD>& fields )
2759 {
2760 for( const SCH_FIELD& field : fields )
2761 {
2762 if( field.GetCanonicalName() == wxT( "Component Class" ) )
2763 {
2764 if( field.GetShownText( aPath, false ) != wxEmptyString )
2765 componentClass.insert( field.GetShownText( aPath, false ) );
2766 }
2767 }
2768 };
2769
2770 // First get component classes set on the symbol itself
2771 getComponentClassFields( m_fields );
2772
2773 // Now get component classes set on any enclosing rule areas
2774 for( const SCH_RULE_AREA* ruleArea : m_rule_areas_cache )
2775 {
2776 for( const SCH_DIRECTIVE_LABEL* label : ruleArea->GetDirectives() )
2777 {
2778 getComponentClassFields( label->GetFields() );
2779 }
2780 }
2781
2782 return componentClass;
2783}
2784
2785
2786bool SCH_SYMBOL::operator==( const SCH_ITEM& aOther ) const
2787{
2788 if( Type() != aOther.Type() )
2789 return false;
2790
2791 const SCH_SYMBOL& symbol = static_cast<const SCH_SYMBOL&>( aOther );
2792
2793 if( GetLibId() != symbol.GetLibId() )
2794 return false;
2795
2796 if( GetPosition() != symbol.GetPosition() )
2797 return false;
2798
2799 if( GetUnit() != symbol.GetUnit() )
2800 return false;
2801
2802 if( GetBodyStyle() != symbol.GetBodyStyle() )
2803 return false;
2804
2805 if( GetTransform() != symbol.GetTransform() )
2806 return false;
2807
2808 if( GetFields() != symbol.GetFields() )
2809 return false;
2810
2811 if( m_pins.size() != symbol.m_pins.size() )
2812 return false;
2813
2814 for( unsigned i = 0; i < m_pins.size(); ++i )
2815 {
2816 if( *m_pins[i] != *symbol.m_pins[i] )
2817 return false;
2818 }
2819
2820 return true;
2821}
2822
2823
2824double SCH_SYMBOL::Similarity( const SCH_ITEM& aOther ) const
2825{
2826 if( Type() != aOther.Type() )
2827 return 0.0;
2828
2829 const SCH_SYMBOL& symbol = static_cast<const SCH_SYMBOL&>( aOther );
2830
2831 if( GetLibId() != symbol.GetLibId() )
2832 return 0.0;
2833
2834 if( GetPosition() == symbol.GetPosition() )
2835 return 1.0;
2836
2837 return 0.0;
2838}
2839
2840
2841static struct SCH_SYMBOL_DESC
2842{
2844 {
2846 .Map( SYMBOL_ANGLE_0, wxS( "0" ) )
2847 .Map( SYMBOL_ANGLE_90, wxS( "90" ) )
2848 .Map( SYMBOL_ANGLE_180, wxS( "180" ) )
2849 .Map( SYMBOL_ANGLE_270, wxS( "270" ) );
2850
2854
2855 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Position X" ),
2856 &SCH_SYMBOL::SetX, &SCH_SYMBOL::GetX, PROPERTY_DISPLAY::PT_COORD,
2858 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Position Y" ),
2859 &SCH_SYMBOL::SetY, &SCH_SYMBOL::GetY, PROPERTY_DISPLAY::PT_COORD,
2861
2863 _HKI( "Orientation" ),
2865 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror X" ),
2867 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, bool>( _HKI( "Mirror Y" ),
2869
2870 auto hasLibPart =
2871 []( INSPECTABLE* aItem ) -> bool
2872 {
2873 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2874 return symbol->GetLibSymbolRef() != nullptr;
2875
2876 return false;
2877 };
2878
2879 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin numbers" ),
2881 .SetAvailableFunc( hasLibPart );
2882
2883 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Pin names" ),
2885 .SetAvailableFunc( hasLibPart );
2886
2887 const wxString groupFields = _HKI( "Fields" );
2888
2889 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Reference" ),
2891 groupFields );
2892 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Value" ),
2894 groupFields );
2895 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Library Link" ),
2897 groupFields );
2898 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Library Description" ),
2900 groupFields );
2901 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Keywords" ),
2903 groupFields );
2904
2905 auto multiUnit =
2906 [=]( INSPECTABLE* aItem ) -> bool
2907 {
2908 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2909 return symbol->IsMulti();
2910
2911 return false;
2912 };
2913
2914 auto multiBodyStyle =
2915 [=]( INSPECTABLE* aItem ) -> bool
2916 {
2917 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( aItem ) )
2918 return symbol->HasAlternateBodyStyle();
2919
2920 return false;
2921 };
2922
2923 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, wxString>( _HKI( "Unit" ),
2925 .SetAvailableFunc( multiUnit );
2926
2927 propMgr.AddProperty( new PROPERTY<SCH_SYMBOL, int>( _HKI( "Body Style" ),
2929 .SetAvailableFunc( multiBodyStyle );
2930
2931 const wxString groupAttributes = _HKI( "Attributes" );
2932
2933 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Exclude From Board" ),
2935 groupAttributes );
2936 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Exclude From Simulation" ),
2938 groupAttributes );
2939 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Exclude From Bill of Materials" ),
2941 groupAttributes );
2942 propMgr.AddProperty( new PROPERTY<SYMBOL, bool>( _HKI( "Do not Populate" ),
2944 groupAttributes );
2945 }
2947
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:723
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:97
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:147
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:141
const KIID m_Uuid
Definition: eda_item.h:507
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:109
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:518
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:393
virtual void SetParentGroup(EDA_GROUP *aGroup)
Definition: eda_item.h:114
bool IsSelected() const
Definition: eda_item.h:126
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:112
EDA_ITEM * m_parent
Owner.
Definition: eda_item.h:519
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:681
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:800
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:638
static wxString LetterSubReference(int aUnit, int aFirstId)
Definition: lib_symbol.cpp:518
static LIB_SYMBOL * GetDummy()
Returns a dummy LIB_SYMBOL, used when one is missing in the schematic.
Definition: lib_symbol.cpp:237
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:944
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:345
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 & 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:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
Holds all the data relating to one schematic.
Definition: schematic.h:87
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:102
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:748
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:317
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: schematic.cpp:888
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:167
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:447
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:1366
FIELD_T GetId() const
Definition: sch_field.h:115
void ImportValues(const SCH_FIELD &aSource)
Copy parameters from a SCH_FIELD source.
Definition: sch_field.cpp:393
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1106
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:1092
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:739
int m_bodyStyle
Definition: sch_item.h:740
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition: sch_item.h:685
void SetPrivate(bool aPrivate)
Definition: sch_item.h:249
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:218
int GetBodyStyle() const
Definition: sch_item.h:246
friend class LIB_SYMBOL
Definition: sch_item.h:758
int GetUnit() const
Definition: sch_item.h:242
virtual void SetExcludedFromBOM(bool aExcludeFromBOM)
Definition: sch_item.h:256
AUTOPLACE_ALGO m_fieldsAutoplaced
Definition: sch_item.h:742
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:755
SCH_LAYER_ID m_layer
Definition: sch_item.h:738
void SetAlt(const wxString &aAlt)
Set the name of the alternate pin.
Definition: sch_pin.cpp:429
void SetName(const wxString &aName)
Definition: sch_pin.cpp:415
const wxString & GetName() const
Definition: sch_pin.cpp:397
bool IsDangling() const override
Definition: sch_pin.cpp:448
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:1143
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: sch_pin.h:95
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:248
wxString GetShownName() const
Definition: sch_pin.cpp:547
void SetType(ELECTRICAL_PINTYPE aType)
Definition: sch_pin.cpp:325
const wxString & GetNumber() const
Definition: sch_pin.h:123
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:270
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:305
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
void SetValueProp(const wxString &aRef)
Definition: sch_symbol.h:497
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:642
wxString m_prefix
C, R, U, Q etc - the first character(s) which typically indicate what the symbol is.
Definition: sch_symbol.h:860
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:881
void SetMirrorX(bool aMirror)
Definition: sch_symbol.h:322
bool IsSymbolLikePowerGlobalLabel() const
VECTOR2I m_pos
Definition: sch_symbol.h:858
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:859
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:435
BOX2I GetBodyAndPinsBoundingBox() const override
Return a bounding box for the symbol body and pins but not the fields.
void SetRefProp(const wxString &aRef)
Definition: sch_symbol.cpp:583
wxString GetUnitDisplayName(int aUnit) const
Return the display name for a given unit aUnit.
Definition: sch_symbol.cpp:444
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:305
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:783
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:669
wxString GetClass() const override
Return the class name.
Definition: sch_symbol.h:114
void RemoveInstance(const SCH_SHEET_PATH &aInstancePath)
Definition: sch_symbol.cpp:484
void SetUnitProp(const wxString &aUnit)
Definition: sch_symbol.h:512
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:628
void SetMirrorY(bool aMirror)
Definition: sch_symbol.h:339
void PlotPins(PLOTTER *aPlotter) const
Plot just the symbol pins.
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:730
int GetX() const
Definition: sch_symbol.h:780
std::vector< SCH_PIN * > GetPins() const override
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
Definition: sch_symbol.cpp:814
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 SetBodyStyleProp(int aBodyStyle)
Definition: sch_symbol.h:540
void ClearBrightenedPins()
void SetY(int aY)
Definition: sch_symbol.h:784
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:334
wxString GetRefProp() const
Definition: sch_symbol.h:486
wxString GetUnitProp() const
Definition: sch_symbol.h:502
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:891
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:888
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const override
Definition: sch_symbol.cpp:720
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:908
SCH_FIELD * FindFieldCaseInsensitive(const wxString &aFieldName)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:830
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:842
wxString m_schLibSymbolName
The name used to look up a symbol in the symbol library embedded in a schematic.
Definition: sch_symbol.h:872
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:592
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:296
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:780
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
Definition: sch_symbol.cpp:736
std::vector< SCH_FIELD > m_fields
Variable length list of fields.
Definition: sch_symbol.h:874
int GetBodyStyleProp() const
Definition: sch_symbol.h:535
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:746
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:512
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:777
std::unique_ptr< LIB_SYMBOL > m_part
A flattened copy of the LIB_SYMBOL from the PROJECT object's libraries.
Definition: sch_symbol.h:876
int GetNextFieldOrdinal() const
Return the next ordinal for a user field for this symbol.
Definition: sch_symbol.cpp:801
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.
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:460
BOX2I doGetBoundingBox(bool aIncludePins, bool aIncludeFields) const
bool GetMirrorY() const
Definition: sch_symbol.h:351
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
Definition: sch_symbol.cpp:807
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:781
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:878
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:678
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
wxString GetValueProp() const
Definition: sch_symbol.h:492
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:250
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:694
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:880
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:252
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:550
bool HasUnitDisplayName(int aUnit) const
Return true if the given unit aUnit has a display name set.
Definition: sch_symbol.cpp:452
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:752
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:49
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:104
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:406
static constexpr EDA_ANGLE ANGLE_270
Definition: eda_angle.h:409
RECURSE_MODE
Definition: eda_item.h:49
INSPECT_RESULT
Definition: eda_item.h:43
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition: eda_item.h:90
#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:438
@ LAYER_DEVICE
Definition: layer_ids.h:455
@ LAYER_VALUEPART
Definition: layer_ids.h:450
@ LAYER_FIELDS
Definition: layer_ids.h:451
@ LAYER_REFERENCEPART
Definition: layer_ids.h:449
@ LAYER_DNP_MARKER
Definition: layer_ids.h:467
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:792
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:783
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
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:358
int NextFieldOrdinal(const std::vector< SCH_FIELD > &aFields)
Definition: sch_field.h:347
@ 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:84
bool m_PDFPropertyPopups
Definition: sch_plotter.h:63
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:180
@ SCH_FIELD_LOCATE_FOOTPRINT_T
Definition: typeinfo.h:182
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:199
@ SCH_FIELD_LOCATE_VALUE_T
Definition: typeinfo.h:181
@ SCH_FIELD_LOCATE_DATASHEET_T
Definition: typeinfo.h:183
@ SCH_SYMBOL_LOCATE_POWER_T
Definition: typeinfo.h:196
@ SCH_PIN_T
Definition: typeinfo.h:153
Custom text control validator definitions.
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695