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