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