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