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