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