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