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