KiCad PCB EDA Suite
Loading...
Searching...
No Matches
lib_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) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2022 CERN
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <font/outline_font.h>
28#include <sch_draw_panel.h>
29#include <plotters/plotter.h>
30#include <sch_screen.h>
31#include <template_fieldnames.h>
32#include <transform.h>
33#include <symbol_library.h>
35#include <sch_pin.h>
36#include <sch_shape.h>
37
38#include <memory>
39
40std::vector<SEARCH_TERM> LIB_SYMBOL::GetSearchTerms()
41{
42 std::vector<SEARCH_TERM> terms;
43
44 terms.emplace_back( SEARCH_TERM( GetLibNickname(), 4 ) );
45 terms.emplace_back( SEARCH_TERM( GetName(), 8 ) );
46 terms.emplace_back( SEARCH_TERM( GetLIB_ID().Format(), 16 ) );
47
48 wxStringTokenizer keywordTokenizer( GetKeyWords(), " \t\r\n", wxTOKEN_STRTOK );
49
50 while( keywordTokenizer.HasMoreTokens() )
51 terms.emplace_back( SEARCH_TERM( keywordTokenizer.GetNextToken(), 4 ) );
52
53 // Also include keywords as one long string, just in case
54 terms.emplace_back( SEARCH_TERM( GetKeyWords(), 1 ) );
55 terms.emplace_back( SEARCH_TERM( GetDescription(), 1 ) );
56
57 wxString footprint = GetFootprint();
58
59 if( !footprint.IsEmpty() )
60 terms.emplace_back( SEARCH_TERM( GetFootprintField().GetText(), 1 ) );
61
62 return terms;
63}
64
65
66void LIB_SYMBOL::GetChooserFields( std::map<wxString, wxString>& aColumnMap )
67{
68 for( SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
69 {
70 SCH_FIELD* field = static_cast<SCH_FIELD*>( &item );
71
72 if( field->ShowInChooser() )
73 aColumnMap[field->GetName()] = field->EDA_TEXT::GetShownText( false );
74 }
75}
76
77
78bool operator<( const LIB_SYMBOL& aItem1, const LIB_SYMBOL& aItem2 )
79{
80 return aItem1.GetName() < aItem2.GetName();
81}
82
83
86{
87 void operator()(void const *) const
88 {
89 }
90};
91
92
93LIB_SYMBOL::LIB_SYMBOL( const wxString& aName, LIB_SYMBOL* aParent, SYMBOL_LIB* aLibrary ) :
95 m_me( this, null_deleter() )
96{
97 m_lastModDate = 0;
98 m_unitCount = 1;
99 m_demorgan = false;
102 m_unitsLocked = false;
104
105 auto addField =
106 [&]( FIELD_T id, bool visible )
107 {
108 SCH_FIELD* field = new SCH_FIELD( this, id );
109 field->SetVisible( visible );
110 m_drawings[SCH_FIELD_T].push_back( field );
111 };
112
113 // construct only the mandatory fields
114 addField( FIELD_T::REFERENCE, true );
115 addField( FIELD_T::VALUE, true );
116 addField( FIELD_T::FOOTPRINT, false );
117 addField( FIELD_T::DATASHEET, false );
118 addField( FIELD_T::DESCRIPTION, false );
119
120 SetName( aName );
121
122 if( aParent )
123 SetParent( aParent );
124
125 SetLib( aLibrary );
126}
127
128
129LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
130 SYMBOL( aSymbol ),
131 EMBEDDED_FILES( aSymbol ),
132 m_me( this, null_deleter() )
133{
134 m_library = aLibrary;
135 m_name = aSymbol.m_name;
136 m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
137 m_unitCount = aSymbol.m_unitCount;
138 m_demorgan = aSymbol.m_demorgan;
141 m_options = aSymbol.m_options;
142 m_libId = aSymbol.m_libId;
143 m_keyWords = aSymbol.m_keyWords;
144
145 std::ranges::copy( aSymbol.m_jumperPinGroups, std::back_inserter( m_jumperPinGroups ) );
147
150
152
153 for( const SCH_ITEM& oldItem : aSymbol.m_drawings )
154 {
155 if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
156 continue;
157
158 try
159 {
160 SCH_ITEM* newItem = (SCH_ITEM*) oldItem.Clone();
161 newItem->ClearSelected();
162 newItem->SetParent( this );
163 m_drawings.push_back( newItem );
164 }
165 catch( ... )
166 {
167 wxFAIL_MSG( "Failed to clone SCH_ITEM." );
168 return;
169 }
170 }
171
172 LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
173
174 if( parent )
175 SetParent( parent.get() );
176}
177
178
180{
181 if( &aSymbol == this )
182 return aSymbol;
183
184 SYMBOL::operator=( aSymbol );
185
186 m_library = aSymbol.m_library;
187 m_name = aSymbol.m_name;
188 m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
189 m_unitCount = aSymbol.m_unitCount;
190 m_demorgan = aSymbol.m_demorgan;
193 m_options = aSymbol.m_options;
194 m_libId = aSymbol.m_libId;
195 m_keyWords = aSymbol.m_keyWords;
196
197 std::ranges::copy( aSymbol.m_jumperPinGroups, std::back_inserter( m_jumperPinGroups ) );
199
202
203 m_drawings.clear();
204
205 for( const SCH_ITEM& oldItem : aSymbol.m_drawings )
206 {
207 if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
208 continue;
209
210 SCH_ITEM* newItem = (SCH_ITEM*) oldItem.Clone();
211 newItem->SetParent( this );
212 m_drawings.push_back( newItem );
213 }
214
215 m_drawings.sort();
216
217 LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
218
219 SetParent( parent.get() );
220
221 EMBEDDED_FILES::operator=( aSymbol );
222
223 return *this;
224}
225
226
233{
234 static LIB_SYMBOL* symbol;
235
236 if( !symbol )
237 {
238 symbol = new LIB_SYMBOL( wxEmptyString );
239
241
242 square->SetPosition( VECTOR2I( schIUScale.MilsToIU( -200 ), schIUScale.MilsToIU( 200 ) ) );
243 square->SetEnd( VECTOR2I( schIUScale.MilsToIU( 200 ), schIUScale.MilsToIU( -200 ) ) );
244 symbol->AddDrawItem( square );
245
246 SCH_TEXT* text = new SCH_TEXT( { 0, 0 }, wxT( "??" ), LAYER_DEVICE );
247
248 text->SetTextSize( VECTOR2I( schIUScale.MilsToIU( 150 ), schIUScale.MilsToIU( 150 ) ) );
249 symbol->AddDrawItem( text );
250 }
251
252 return symbol;
253}
254
255
257{
258 unsigned depth = 0;
259
260 LIB_SYMBOL_SPTR parent = GetParent().lock();
261
262 while( parent )
263 {
264 depth += 1;
265 parent = parent->GetParent().lock();
266 }
267
268 return depth;
269}
270
271
273{
274 const LIB_SYMBOL_SPTR sp = m_parent.lock();
275
276 // Recurse until the parent symbol is empty.
277 if( sp )
278 return sp->GetRootSymbol();
279
280 return m_me;
281}
282
283
284wxString LIB_SYMBOL::GetUnitDisplayName( int aUnit, bool aLabel ) const
285{
286 if( m_unitDisplayNames.contains( aUnit ) )
287 return m_unitDisplayNames.at( aUnit );
288 else if( aLabel )
289 return wxString::Format( _( "Unit %s" ), LIB_SYMBOL::LetterSubReference( aUnit, 'A' ) );
290 else
291 return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
292}
293
294
295wxString LIB_SYMBOL::GetBodyStyleDescription( int aBodyStyle, bool aLabel ) const
296{
298 {
299 if( aBodyStyle == BODY_STYLE::DEMORGAN )
300 return aLabel ? _( "Alternate" ) : wxString( _HKI( "Alternate" ) );
301 else if( aBodyStyle == BODY_STYLE::BASE )
302 return aLabel ? _( "Standard" ) : wxString( _HKI( "Standard" ) );
303 }
304 else if( IsMultiBodyStyle() )
305 {
306 if( aBodyStyle <= (int) m_bodyStyleNames.size() )
307 return m_bodyStyleNames[aBodyStyle-1];
308 }
309
310 return wxT( "?" );
311}
312
313
314void LIB_SYMBOL::SetName( const wxString& aName )
315{
316 m_name = aName;
317 m_libId.SetLibItemName( aName );
318}
319
320
322{
323 if( aParent )
324 m_parent = aParent->SharedPtr();
325 else
326 m_parent.reset();
327}
328
329
330std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
331{
332 std::unique_ptr< LIB_SYMBOL > retv;
333
334 if( IsDerived() )
335 {
336 LIB_SYMBOL_SPTR parent = m_parent.lock();
337
338 wxCHECK_MSG( parent, retv,
339 wxString::Format( "Parent of derived symbol '%s' undefined", m_name ) );
340
341 // Copy the parent.
342 if( parent->IsDerived() )
343 retv = parent->Flatten();
344 else
345 retv = std::make_unique<LIB_SYMBOL>( *parent.get() );
346
347 retv->m_name = m_name;
348 retv->SetLibId( m_libId );
349
350 // Overwrite parent's mandatory fields for fields which are defined in this.
351 for( FIELD_T fieldId : MANDATORY_FIELDS )
352 {
353 if( !GetField( fieldId )->GetText().IsEmpty() )
354 *retv->GetField( fieldId ) = *GetField( fieldId );
355 }
356
357 // Grab all the rest of derived symbol fields.
358 for( const SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
359 {
360 const SCH_FIELD* field = static_cast<const SCH_FIELD*>( &item );
361
362 // Mandatory fields were already resolved.
363 if( field->IsMandatory() )
364 continue;
365
366 SCH_FIELD* newField = new SCH_FIELD( *field );
367 newField->SetParent( retv.get() );
368
369 SCH_FIELD* parentField = retv->GetField( field->GetName() );
370
371 if( !parentField ) // Derived symbol field does not exist in parent symbol.
372 {
373 retv->AddDrawItem( newField );
374 }
375 else // Derived symbol field overrides the parent symbol field.
376 {
377 retv->RemoveDrawItem( parentField );
378 retv->AddDrawItem( newField );
379 }
380 }
381
382 retv->SetKeyWords( m_keyWords.IsEmpty() ? parent->GetKeyWords() : m_keyWords );
383 retv->SetFPFilters( m_fpFilters.IsEmpty() ? parent->GetFPFilters() : m_fpFilters );
384
385 retv->SetExcludedFromSim( parent->GetExcludedFromSim() );
386 retv->SetExcludedFromBOM( parent->GetExcludedFromBOM() );
388
389 retv->m_parent.reset();
390 }
391 else
392 {
393 retv = std::make_unique<LIB_SYMBOL>( *this );
394 }
395
396 return retv;
397}
398
399
400const wxString LIB_SYMBOL::GetLibraryName() const
401{
402 if( m_library )
403 return m_library->GetName();
404
405 return m_libId.GetLibNickname();
406}
407
408
410{
411 std::shared_ptr<LIB_SYMBOL> parent;
412
413 if( !m_parent.expired() && ( parent = m_parent.lock() ) )
414 {
415 if( parent->IsRoot() )
416 return parent->m_options == ENTRY_LOCAL_POWER;
417 else
418 return parent->IsLocalPower();
419 }
420
422}
423
424
426{
427 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
428 {
429 if( parent->IsRoot() )
430 parent->m_options = ENTRY_LOCAL_POWER;
431 else
432 parent->SetLocalPower();
433 }
434
436}
437
438
440{
441 std::shared_ptr<LIB_SYMBOL> parent;
442
443 if( !m_parent.expired() && ( parent = m_parent.lock() ) )
444 {
445 if( parent->IsRoot() )
446 return parent->m_options == ENTRY_GLOBAL_POWER;
447 else
448 return parent->IsGlobalPower();
449 }
450
452}
453
454
456{
457 return IsLocalPower() || IsGlobalPower();
458}
459
460
462{
463 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
464 {
465 if( parent->IsRoot() )
466 parent->m_options = ENTRY_GLOBAL_POWER;
467 else
468 parent->SetGlobalPower();
469 }
470
472}
473
474
476{
477 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
478 {
479 if( parent->IsRoot() )
480 return parent->m_options == ENTRY_NORMAL;
481 else
482 return parent->IsNormal();
483 }
484
485 return m_options == ENTRY_NORMAL;
486}
487
488
490{
491 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
492 {
493 if( parent->IsRoot() )
494 parent->m_options = ENTRY_NORMAL;
495 else
496 parent->SetNormal();
497 }
498
500}
501
502
503wxString LIB_SYMBOL::LetterSubReference( int aUnit, wxChar aInitialLetter )
504{
505 // use letters as notation. To allow more than 26 units, the sub ref
506 // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
507 // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
508 int u;
509 wxString suffix;
510
511 do
512 {
513 u = ( aUnit - 1 ) % 26;
514 suffix = wxChar( aInitialLetter + u ) + suffix;
515 aUnit = ( aUnit - u ) / 26;
516 } while( aUnit > 0 );
517
518 return suffix;
519}
520
521
522bool LIB_SYMBOL::ResolveTextVar( wxString* token, int aDepth ) const
523{
524 wxString footprint;
525
526 for( const SCH_ITEM& item : m_drawings )
527 {
528 if( item.Type() == SCH_FIELD_T )
529 {
530 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( item );
531
532 if( field.GetId() == FIELD_T::FOOTPRINT )
533 footprint = field.GetShownText( nullptr, false, aDepth + 1 );
534
535 if( token->IsSameAs( field.GetCanonicalName().Upper() )
536 || token->IsSameAs( field.GetName(), false ) )
537 {
538 *token = field.GetShownText( nullptr, false, aDepth + 1 );
539 return true;
540 }
541 }
542 }
543
544 // Consider missing simulation fields as empty, not un-resolved
545 if( token->IsSameAs( wxT( "SIM.DEVICE" ) )
546 || token->IsSameAs( wxT( "SIM.TYPE" ) )
547 || token->IsSameAs( wxT( "SIM.PINS" ) )
548 || token->IsSameAs( wxT( "SIM.PARAMS" ) )
549 || token->IsSameAs( wxT( "SIM.LIBRARY" ) )
550 || token->IsSameAs( wxT( "SIM.NAME" ) ) )
551 {
552 *token = wxEmptyString;
553 return true;
554 }
555
556 if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) )
557 {
558 wxArrayString parts = wxSplit( footprint, ':' );
559
560 if( parts.Count() > 0 )
561 *token = parts[ 0 ];
562 else
563 *token = wxEmptyString;
564
565 return true;
566 }
567 else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) )
568 {
569 wxArrayString parts = wxSplit( footprint, ':' );
570
571 if( parts.Count() > 1 )
572 *token = parts[ std::min( 1, (int) parts.size() - 1 ) ];
573 else
574 *token = wxEmptyString;
575
576 return true;
577 }
578 else if( token->IsSameAs( wxT( "SYMBOL_LIBRARY" ) ) )
579 {
580 *token = m_libId.GetUniStringLibNickname();
581 return true;
582 }
583 else if( token->IsSameAs( wxT( "SYMBOL_NAME" ) ) )
584 {
585 *token = m_libId.GetUniStringLibItemName();
586 return true;
587 }
588 else if( token->IsSameAs( wxT( "SYMBOL_DESCRIPTION" ) ) )
589 {
590 *token = GetDescription();
591 return true;
592 }
593 else if( token->IsSameAs( wxT( "SYMBOL_KEYWORDS" ) ) )
594 {
595 *token = GetKeyWords();
596 return true;
597 }
598 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
599 {
600 *token = this->GetExcludedFromBOM() ? _( "Excluded from BOM" ) : wxString( "" );
601 return true;
602 }
603 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
604 {
605 *token = this->GetExcludedFromBoard() ? _( "Excluded from board" ) : wxString( "" );
606 return true;
607 }
608 else if( token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
609 {
610 *token = this->GetExcludedFromSim() ? _( "Excluded from simulation" ) : wxString( "" );
611 return true;
612 }
613 else if( token->IsSameAs( wxT( "DNP" ) ) )
614 {
615 *token = this->GetDNP() ? _( "DNP" ) : wxString( "" );
616 return true;
617 }
618
619 return false;
620}
621
622
623void LIB_SYMBOL::Plot( PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
624 int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed )
625{
626 wxASSERT( aPlotter != nullptr );
627
628 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
629 COLOR4D color = renderSettings->GetLayerColor( LAYER_DEVICE );
630 COLOR4D bg = renderSettings->GetBackgroundColor();
631
632 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
633 bg = COLOR4D::WHITE;
634
635 if( aDimmed )
636 {
637 color.Desaturate( );
638 color = color.Mix( bg, 0.5f );
639 }
640
641 aPlotter->SetColor( color );
642
643 for( SCH_ITEM& item : m_drawings )
644 {
645 // Do not plot private items
646 if( item.IsPrivate() )
647 continue;
648
649 // LIB_FIELDs are not plotted here, because this plot function is used to plot schematic
650 // items which have their own SCH_FIELDs
651 if( item.Type() == SCH_FIELD_T )
652 continue;
653
654 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
655 continue;
656
657 if( aBodyStyle && item.m_bodyStyle && ( item.m_bodyStyle != aBodyStyle ) )
658 continue;
659
660 item.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
661 }
662}
663
664
665void LIB_SYMBOL::PlotFields( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
666 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
667{
668 wxASSERT( aPlotter != nullptr );
669
670 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
671 COLOR4D color = renderSettings->GetLayerColor( LAYER_FIELDS );
672 COLOR4D bg = renderSettings->GetBackgroundColor();
673
674 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
675 bg = COLOR4D::WHITE;
676
677 if( aDimmed )
678 {
679 color.Desaturate( );
680 color = color.Mix( bg, 0.5f );
681 }
682
683 aPlotter->SetColor( color );
684
685 for( SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
686 {
687 SCH_FIELD& field = static_cast<SCH_FIELD&>( item );
688
689 if( !renderSettings->m_ShowHiddenFields && !field.IsVisible() )
690 continue;
691
692 // The reference is a special case: we should change the basic text
693 // to add '?' and the part id
694 wxString tmp = field.GetText();
695
696 field.SetText( field.GetFullText( aUnit ) );
697 item.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
698
699 field.SetText( tmp );
700 }
701}
702
703
705{
706 std::vector<SCH_SHAPE*> potential_top_items;
707 std::vector<SCH_ITEM*> bottom_items;
708
709 for( SCH_ITEM& item : m_drawings )
710 {
711 if( item.Type() == SCH_SHAPE_T )
712 {
713 SCH_SHAPE& shape = static_cast<SCH_SHAPE&>( item );
714
716 potential_top_items.push_back( &shape );
717 else
718 bottom_items.push_back( &item );
719 }
720 else
721 {
722 bottom_items.push_back( &item );
723 }
724 }
725
726 std::sort( potential_top_items.begin(), potential_top_items.end(),
727 []( SCH_ITEM* a, SCH_ITEM* b )
728 {
729 return a->GetBoundingBox().GetArea() > b->GetBoundingBox().GetArea();
730 } );
731
732 for( SCH_SHAPE* item : potential_top_items )
733 {
734 for( SCH_ITEM* bottom_item : bottom_items )
735 {
736 if( item->GetBoundingBox().Contains( bottom_item->GetBoundingBox() ) )
737 {
738 item->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
739 break;
740 }
741 }
742 }
743}
744
745
747{
748 wxASSERT( aItem != nullptr );
749
750 // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
751 // omitted when saving to disk.
752 if( aItem->Type() == SCH_FIELD_T )
753 {
754 if( static_cast<SCH_FIELD*>( aItem )->IsMandatory() )
755 return;
756 }
757
758 LIB_ITEMS& items = m_drawings[ aItem->Type() ];
759
760 for( LIB_ITEMS::iterator i = items.begin(); i != items.end(); i++ )
761 {
762 if( &*i == aItem )
763 {
764 items.erase( i );
765 break;
766 }
767 }
768}
769
770
771void LIB_SYMBOL::AddDrawItem( SCH_ITEM* aItem, bool aSort )
772{
773 if( aItem )
774 {
775 aItem->SetParent( this );
776
777 m_drawings.push_back( aItem );
778
779 if( aSort )
780 m_drawings.sort();
781 }
782}
783
784
785std::vector<SCH_PIN*> LIB_SYMBOL::GetGraphicalPins( int aUnit, int aBodyStyle ) const
786{
787 std::vector<SCH_PIN*> pins;
788
789 /* Notes:
790 * when aUnit == 0: no unit filtering
791 * when aBodyStyle == 0: no body style filtering
792 * when m_unit == 0, the item is common to all units
793 * when m_bodyStyle == 0, the item is common to all body styles
794 */
795
796 LIB_SYMBOL_SPTR parent = m_parent.lock();
797 const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
798
799 for( const SCH_ITEM& item : drawItems[SCH_PIN_T] )
800 {
801 // Unit filtering:
802 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
803 continue;
804
805 // De Morgan variant filtering:
806 if( aBodyStyle && item.m_bodyStyle && ( item.m_bodyStyle != aBodyStyle ) )
807 continue;
808
809 // TODO: get rid of const_cast. (It used to be a C-style cast so was less noticeable.)
810 SCH_PIN* pin = const_cast<SCH_PIN*>( static_cast<const SCH_PIN*>( &item ) );
811 wxLogTrace( "KICAD_STACKED_PINS",
812 wxString::Format( "GetGraphicalPins: lib='%s' unit=%d body=%d -> include pin name='%s' number='%s' shownNum='%s'",
813 GetLibId().Format().wx_str(), aUnit, aBodyStyle,
814 pin->GetName(), pin->GetNumber(), pin->GetShownNumber() ) );
815 pins.push_back( pin );
816 }
817
818 return pins;
819}
820
821
822std::vector<LIB_SYMBOL::LOGICAL_PIN> LIB_SYMBOL::GetLogicalPins( int aUnit, int aBodyStyle ) const
823{
824 std::vector<LOGICAL_PIN> out;
825
826 for( SCH_PIN* pin : GetGraphicalPins( aUnit, aBodyStyle ) )
827 {
828 bool valid = false;
829 std::vector<wxString> expanded = pin->GetStackedPinNumbers( &valid );
830
831 if( valid && !expanded.empty() )
832 {
833 for( const wxString& num : expanded )
834 {
835 out.push_back( LOGICAL_PIN{ pin, num } );
836 wxLogTrace( "KICAD_STACKED_PINS",
837 wxString::Format( "GetLogicalPins: base='%s' -> '%s'",
838 pin->GetShownNumber(), num ) );
839 }
840 }
841 else
842 {
843 out.push_back( LOGICAL_PIN{ pin, pin->GetShownNumber() } );
844 wxLogTrace( "KICAD_STACKED_PINS",
845 wxString::Format( "GetLogicalPins: base='%s' (no expansion)",
846 pin->GetShownNumber() ) );
847 }
848 }
849
850 return out;
851}
852
853
855{
856 int count = 0;
857
858 for( SCH_PIN* pin : GetGraphicalPins( 0 /* all units */, 1 /* single body style */ ) )
859 {
860 bool valid;
861 std::vector<wxString> numbers = pin->GetStackedPinNumbers( &valid );
862 wxLogTrace( "CVPCB_PINCOUNT",
863 wxString::Format( "LIB_SYMBOL::GetPinCount lib='%s' pin base='%s' shown='%s' valid=%d +%zu",
864 GetLibId().Format().wx_str(), pin->GetName(),
865 pin->GetShownNumber(), valid, numbers.size() ) );
866 count += numbers.size();
867 }
868
869 wxLogTrace( "CVPCB_PINCOUNT",
870 wxString::Format( "LIB_SYMBOL::GetPinCount total for lib='%s' => %d",
871 GetLibId().Format().wx_str(), count ) );
872 return count;
873}
874
875
876SCH_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aBodyStyle ) const
877{
878 for( SCH_PIN* pin : GetGraphicalPins( aUnit, aBodyStyle ) )
879 {
880 if( aNumber == pin->GetNumber() )
881 return pin;
882 }
883
884 return nullptr;
885}
886
887
888bool LIB_SYMBOL::PinsConflictWith( const LIB_SYMBOL& aOtherPart, bool aTestNums, bool aTestNames,
889 bool aTestType, bool aTestOrientation, bool aTestLength ) const
890{
891 for( const SCH_PIN* pin : GetGraphicalPins() )
892 {
893 wxASSERT( pin );
894 bool foundMatch = false;
895
896 for( const SCH_PIN* otherPin : aOtherPart.GetGraphicalPins() )
897 {
898 wxASSERT( otherPin );
899
900 // Same unit?
901 if( pin->GetUnit() != otherPin->GetUnit() )
902 continue;
903
904 // Same body stype?
905 if( pin->GetBodyStyle() != otherPin->GetBodyStyle() )
906 continue;
907
908 // Same position?
909 if( pin->GetPosition() != otherPin->GetPosition() )
910 continue;
911
912 // Same number?
913 if( aTestNums && ( pin->GetNumber() != otherPin->GetNumber() ) )
914 continue;
915
916 // Same name?
917 if( aTestNames && ( pin->GetName() != otherPin->GetName() ) )
918 continue;
919
920 // Same electrical type?
921 if( aTestType && ( pin->GetType() != otherPin->GetType() ) )
922 continue;
923
924 // Same orientation?
925 if( aTestOrientation
926 && ( pin->GetOrientation() != otherPin->GetOrientation() ) )
927 continue;
928
929 // Same length?
930 if( aTestLength && ( pin->GetLength() != otherPin->GetLength() ) )
931 continue;
932
933 foundMatch = true;
934 break; // Match found so search is complete.
935 }
936
937 if( !foundMatch )
938 {
939 // This means there was not an identical (according to the arguments)
940 // pin at the same position in the other symbol.
941 return true;
942 }
943 }
944
945 // The loop never gave up, so no conflicts were found.
946 return false;
947}
948
949std::vector<SCH_PIN*> LIB_SYMBOL::GetPins() const
950{
951 // Back-compat shim: return graphical pins for all units/body styles
952 return GetGraphicalPins( 0, 0 );
953}
954
955
956const BOX2I LIB_SYMBOL::GetUnitBoundingBox( int aUnit, int aBodyStyle,
957 bool aIgnoreHiddenFields,
958 bool aIgnoreLabelsOnInvisiblePins ) const
959{
960 BOX2I bBox; // Start with a fresh BOX2I so the Merge algorithm works
961
962 for( const SCH_ITEM& item : m_drawings )
963 {
964 if( item.m_unit > 0 && m_unitCount > 1 && aUnit > 0 && aUnit != item.m_unit )
965 continue;
966
967 if( item.m_bodyStyle > 0 && aBodyStyle > 0 && aBodyStyle != item.m_bodyStyle )
968 continue;
969
970 if( aIgnoreHiddenFields && item.Type() == SCH_FIELD_T )
971 {
972 if( !static_cast<const SCH_FIELD&>( item ).IsVisible() )
973 continue;
974 }
975
976 if( item.Type() == SCH_PIN_T && !aIgnoreLabelsOnInvisiblePins )
977 {
978 const SCH_PIN& pin = static_cast<const SCH_PIN&>( item );
979 bBox.Merge( pin.GetBoundingBox( true, true, false ) );
980 }
981 else
982 bBox.Merge( item.GetBoundingBox() );
983 }
984
985 return bBox;
986}
987
988
989const BOX2I LIB_SYMBOL::GetBodyBoundingBox( int aUnit, int aBodyStyle, bool aIncludePins,
990 bool aIncludePrivateItems ) const
991{
992 BOX2I bbox;
993
994 for( const SCH_ITEM& item : m_drawings )
995 {
996 if( item.m_unit > 0 && aUnit > 0 && aUnit != item.m_unit )
997 continue;
998
999 if( item.m_bodyStyle > 0 && aBodyStyle > 0 && aBodyStyle != item.m_bodyStyle )
1000 continue;
1001
1002 if( item.IsPrivate() && !aIncludePrivateItems )
1003 continue;
1004
1005 if( item.Type() == SCH_FIELD_T )
1006 continue;
1007
1008 if( item.Type() == SCH_PIN_T )
1009 {
1010 const SCH_PIN& pin = static_cast<const SCH_PIN&>( item );
1011
1012 if( pin.IsVisible() )
1013 {
1014 // Note: the roots of the pins are always included for symbols that don't have
1015 // a well-defined body.
1016
1017 if( aIncludePins )
1018 bbox.Merge( pin.GetBoundingBox( false, false, false ) );
1019 else
1020 bbox.Merge( pin.GetPinRoot() );
1021 }
1022 }
1023 else
1024 {
1025 bbox.Merge( item.GetBoundingBox() );
1026 }
1027 }
1028
1029 return bbox;
1030}
1031
1032
1034{
1035 m_drawings[ SCH_FIELD_T ].clear();
1036}
1037
1038
1040{
1041 AddDrawItem( aField );
1042}
1043
1044
1045void LIB_SYMBOL::SetFields( const std::vector<SCH_FIELD>& aFieldsList )
1046{
1048
1049 for( const SCH_FIELD& src : aFieldsList )
1050 {
1051 // drawings is a ptr_vector, new and copy an object on the heap.
1052 SCH_FIELD* field = new SCH_FIELD( src );
1053
1054 field->SetParent( this );
1055 m_drawings.push_back( field );
1056 }
1057
1058 m_drawings.sort();
1059}
1060
1061
1062void LIB_SYMBOL::GetFields( std::vector<SCH_FIELD*>& aList, bool aVisibleOnly ) const
1063{
1064 for( const SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1065 {
1066 const SCH_FIELD* field = static_cast<const SCH_FIELD*>( &item );
1067
1068 if( aVisibleOnly )
1069 {
1070 if( !field->IsVisible() || field->GetText().IsEmpty() )
1071 continue;
1072 }
1073
1074 aList.push_back( const_cast<SCH_FIELD*>( field ) );
1075 }
1076
1077 std::sort( aList.begin(), aList.end(),
1078 []( SCH_FIELD* lhs, SCH_FIELD* rhs )
1079 {
1080 return lhs->GetOrdinal() < rhs->GetOrdinal();
1081 } );
1082}
1083
1084
1085void LIB_SYMBOL::CopyFields( std::vector<SCH_FIELD>& aList )
1086{
1087 std::vector<SCH_FIELD*> orderedFields;
1088
1089 GetFields( orderedFields );
1090
1091 for( SCH_FIELD* field : orderedFields )
1092 aList.emplace_back( *field );
1093}
1094
1095
1097{
1098 int ordinal = 42; // Arbitrarily larger than any mandatory FIELD_T id
1099
1100 for( const SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1101 ordinal = std::max( ordinal, static_cast<const SCH_FIELD*>( &item )->GetOrdinal() + 1 );
1102
1103 return ordinal;
1104}
1105
1106
1107const SCH_FIELD* LIB_SYMBOL::GetField( FIELD_T aFieldType ) const
1108{
1109 for( const SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1110 {
1111 const SCH_FIELD* field = static_cast<const SCH_FIELD*>( &item );
1112
1113 if( field->GetId() == aFieldType )
1114 return field;
1115 }
1116
1117 return nullptr;
1118}
1119
1120
1122{
1123 for( SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1124 {
1125 SCH_FIELD* field = static_cast<SCH_FIELD*>( &item );
1126
1127 if( field->GetId() == aFieldType )
1128 return field;
1129 }
1130
1131 return nullptr;
1132}
1133
1134
1135const SCH_FIELD* LIB_SYMBOL::GetField( const wxString& aFieldName ) const
1136{
1137 for( const SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1138 {
1139 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( item );
1140
1141 if( field.GetName() == aFieldName )
1142 return &field;
1143 }
1144
1145 return nullptr;
1146}
1147
1148
1149SCH_FIELD* LIB_SYMBOL::GetField( const wxString& aFieldName )
1150{
1151 for( SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1152 {
1153 SCH_FIELD& field = static_cast<SCH_FIELD&>( item );
1154
1155 if( field.GetName() == aFieldName )
1156 return &field;
1157 }
1158
1159 return nullptr;
1160}
1161
1162
1164{
1165 for( SCH_ITEM& item : m_drawings[ SCH_FIELD_T ] )
1166 {
1167 SCH_FIELD& field = static_cast<SCH_FIELD&>( item );
1168
1169 if( field.GetCanonicalName().IsSameAs( aFieldName, false ) )
1170 return &field;
1171 }
1172
1173 return nullptr;
1174}
1175
1176
1178{
1179 const SCH_FIELD* field = GetField( FIELD_T::VALUE );
1180 wxASSERT( field != nullptr );
1181 return *field;
1182}
1183
1184
1186{
1187 const SCH_FIELD* field = GetField( FIELD_T::REFERENCE );
1188 wxASSERT( field != nullptr );
1189 return *field;
1190}
1191
1192
1194{
1195 const SCH_FIELD* field = GetField( FIELD_T::FOOTPRINT );
1196 wxASSERT( field != nullptr );
1197 return *field;
1198}
1199
1200
1202{
1203 const SCH_FIELD* field = GetField( FIELD_T::DATASHEET );
1204 wxASSERT( field != nullptr );
1205 return *field;
1206}
1207
1208
1210{
1211 const SCH_FIELD* field = GetField( FIELD_T::DESCRIPTION );
1212 wxASSERT( field != nullptr );
1213 return *field;
1214}
1215
1216
1218{
1219 wxString refDesignator = GetField( FIELD_T::REFERENCE )->GetText();
1220
1221 refDesignator.Replace( wxS( "~" ), wxS( " " ) );
1222
1223 wxString prefix = refDesignator;
1224
1225 while( prefix.Length() )
1226 {
1227 wxUniCharRef last = prefix.Last();
1228
1229 if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
1230 prefix.RemoveLast();
1231 else
1232 break;
1233 }
1234
1235 // Avoid a prefix containing trailing/leading spaces
1236 prefix.Trim( true );
1237 prefix.Trim( false );
1238
1239 return prefix;
1240}
1241
1242
1243void LIB_SYMBOL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
1244{
1245 for( SCH_ITEM& item : m_drawings )
1246 aFunction( &item );
1247}
1248
1249
1250void LIB_SYMBOL::Move( const VECTOR2I& aOffset )
1251{
1252 for( SCH_ITEM& item : m_drawings )
1253 item.Move( aOffset );
1254}
1255
1256
1257// Before V10 we didn't store the number of body styles in a symbol -- we just looked through all
1258// its drawings each time we wanted to know. This is now only used to set the count when a legacy
1259// symbol is first read. (Legacy symbols also didn't support arbitrary body styles, so the count
1260// is always 1 or 2, and when 2 it is always a De Morgan pair.)
1262{
1263 for( const SCH_ITEM& item : m_drawings )
1264 {
1265 if( item.m_bodyStyle > BODY_STYLE::BASE )
1266 return true;
1267 }
1268
1269 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1270 {
1271 for( const SCH_ITEM& item : parent->GetDrawItems() )
1272 {
1273 if( item.m_bodyStyle > BODY_STYLE::BASE )
1274 return true;
1275 }
1276 }
1277
1278 return false;
1279}
1280
1281
1283{
1284 int maxPinNumber = 0;
1285 LIB_SYMBOL_SPTR parent = m_parent.lock();
1286 const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
1287
1288 for( const SCH_ITEM& item : drawItems[SCH_PIN_T] )
1289 {
1290 const SCH_PIN* pin = static_cast<const SCH_PIN*>( &item );
1291 long currentPinNumber = 0;
1292
1293 if( pin->GetNumber().ToLong( &currentPinNumber ) )
1294 maxPinNumber = std::max( maxPinNumber, (int) currentPinNumber );
1295 }
1296
1297 return maxPinNumber;
1298}
1299
1300
1302{
1304
1305 for( SCH_ITEM& item : m_drawings )
1306 item.ClearTempFlags();
1307}
1308
1309
1311{
1313
1314 for( SCH_ITEM& item : m_drawings )
1315 item.ClearEditFlags();
1316}
1317
1318
1319SCH_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aBodyStyle, KICAD_T aType,
1320 const VECTOR2I& aPoint )
1321{
1322 for( SCH_ITEM& item : m_drawings )
1323 {
1324 if( ( aUnit && item.m_unit && aUnit != item.m_unit )
1325 || ( aBodyStyle && item.m_bodyStyle && aBodyStyle != item.m_bodyStyle )
1326 || ( item.Type() != aType && aType != TYPE_NOT_INIT ) )
1327 {
1328 continue;
1329 }
1330
1331 if( item.HitTest( aPoint ) )
1332 return &item;
1333 }
1334
1335 return nullptr;
1336}
1337
1338
1339SCH_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aBodyStyle, KICAD_T aType,
1340 const VECTOR2I& aPoint, const TRANSFORM& aTransform )
1341{
1342 /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
1343 * VECTOR2I& pt ) to search items.
1344 * because this function uses DefaultTransform as orient/mirror matrix
1345 * we temporary copy aTransform in DefaultTransform
1346 */
1347 TRANSFORM transform = DefaultTransform;
1348 DefaultTransform = aTransform;
1349
1350 SCH_ITEM* item = LocateDrawItem( aUnit, aBodyStyle, aType, aPoint );
1351
1352 // Restore matrix
1353 DefaultTransform = transform;
1354
1355 return item;
1356}
1357
1358
1359INSPECT_RESULT LIB_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
1360 const std::vector<KICAD_T>& aScanTypes )
1361{
1362 // The part itself is never inspected, only its children
1363 for( SCH_ITEM& item : m_drawings )
1364 {
1365 if( item.IsType( aScanTypes ) )
1366 {
1367 if( aInspector( &item, aTestData ) == INSPECT_RESULT::QUIT )
1368 return INSPECT_RESULT::QUIT;
1369 }
1370 }
1371
1373}
1374
1375
1376void LIB_SYMBOL::SetUnitCount( int aCount, bool aDuplicateDrawItems )
1377{
1378 if( m_unitCount == aCount )
1379 return;
1380
1381 if( aCount < m_unitCount )
1382 {
1383 // Iterate each drawing-type bucket and erase items that belong to units > aCount.
1384 for( int type = LIB_ITEMS_CONTAINER::FIRST_TYPE; type <= LIB_ITEMS_CONTAINER::LAST_TYPE; ++type )
1385 {
1386 auto it = m_drawings.begin( type );
1387
1388 while( it != m_drawings.end( type ) )
1389 {
1390 if( it->m_unit > aCount )
1391 it = m_drawings.erase( it ); // returns next iterator
1392 else
1393 ++it;
1394 }
1395 }
1396 }
1397 else if( aDuplicateDrawItems )
1398 {
1399 int prevCount = m_unitCount;
1400
1401 // Temporary storage for new items, as adding new items directly to
1402 // m_drawings may cause the buffer reallocation which invalidates the
1403 // iterators
1404 std::vector<SCH_ITEM*> tmp;
1405
1406 for( SCH_ITEM& item : m_drawings )
1407 {
1408 if( item.m_unit != 1 )
1409 continue;
1410
1411 for( int j = prevCount + 1; j <= aCount; j++ )
1412 {
1413 SCH_ITEM* newItem = item.Duplicate( IGNORE_PARENT_GROUP );
1414 newItem->m_unit = j;
1415 tmp.push_back( newItem );
1416 }
1417 }
1418
1419 for( SCH_ITEM* item : tmp )
1420 m_drawings.push_back( item );
1421 }
1422
1423 m_drawings.sort();
1424 m_unitCount = aCount;
1425}
1426
1427
1429{
1430 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1431 return parent->GetUnitCount();
1432
1433 return m_unitCount;
1434}
1435
1436
1437void LIB_SYMBOL::SetBodyStyleCount( int aCount, bool aDuplicateDrawItems, bool aDuplicatePins )
1438{
1439 if( GetBodyStyleCount() == aCount )
1440 return;
1441
1442 // Duplicate items to create the converted shape
1443 if( GetBodyStyleCount() < aCount )
1444 {
1445 if( aDuplicateDrawItems || aDuplicatePins )
1446 {
1447 std::vector<SCH_ITEM*> tmp; // Temporarily store the duplicated pins here.
1448
1449 for( SCH_ITEM& item : m_drawings )
1450 {
1451 if( item.Type() != SCH_PIN_T && !aDuplicateDrawItems )
1452 continue;
1453
1454 if( item.m_bodyStyle == 1 )
1455 {
1456 SCH_ITEM* newItem = item.Duplicate( IGNORE_PARENT_GROUP );
1457 newItem->m_bodyStyle = 2;
1458 tmp.push_back( newItem );
1459 }
1460 }
1461
1462 // Transfer the new pins to the LIB_SYMBOL.
1463 for( SCH_ITEM* item : tmp )
1464 m_drawings.push_back( item );
1465 }
1466 }
1467 else
1468 {
1469 // Delete converted shape items because the converted shape does not exist
1471
1472 while( i != m_drawings.end() )
1473 {
1474 if( i->m_bodyStyle > 1 )
1475 i = m_drawings.erase( i );
1476 else
1477 ++i;
1478 }
1479 }
1480
1481 m_drawings.sort();
1482}
1483
1484
1485std::vector<SCH_ITEM*> LIB_SYMBOL::GetUnitDrawItems( int aUnit, int aBodyStyle )
1486{
1487 std::vector<SCH_ITEM*> unitItems;
1488
1489 for( SCH_ITEM& item : m_drawings )
1490 {
1491 if( item.Type() == SCH_FIELD_T )
1492 continue;
1493
1494 if( ( aBodyStyle == -1 && item.GetUnit() == aUnit )
1495 || ( aUnit == -1 && item.GetBodyStyle() == aBodyStyle )
1496 || ( aUnit == item.GetUnit() && aBodyStyle == item.GetBodyStyle() ) )
1497 {
1498 unitItems.push_back( &item );
1499 }
1500 }
1501
1502 return unitItems;
1503}
1504
1505
1506std::vector<LIB_SYMBOL_UNIT> LIB_SYMBOL::GetUnitDrawItems()
1507{
1508 std::vector<LIB_SYMBOL_UNIT> units;
1509
1510 for( SCH_ITEM& item : m_drawings )
1511 {
1512 if( item.Type() == SCH_FIELD_T )
1513 continue;
1514
1515 int unit = item.GetUnit();
1516 int bodyStyle = item.GetBodyStyle();
1517
1518 auto it = std::find_if( units.begin(), units.end(),
1519 [unit, bodyStyle]( const LIB_SYMBOL_UNIT& a )
1520 {
1521 return a.m_unit == unit && a.m_bodyStyle == bodyStyle;
1522 } );
1523
1524 if( it == units.end() )
1525 {
1526 LIB_SYMBOL_UNIT newUnit;
1527 newUnit.m_unit = item.GetUnit();
1528 newUnit.m_bodyStyle = item.GetBodyStyle();
1529 newUnit.m_items.push_back( &item );
1530 units.emplace_back( newUnit );
1531 }
1532 else
1533 {
1534 it->m_items.push_back( &item );
1535 }
1536 }
1537
1538 return units;
1539}
1540
1541
1542
1543
1544#define REPORT( msg ) { if( aReporter ) aReporter->Report( msg ); }
1545#define ITEM_DESC( item ) ( item )->GetItemDescription( &unitsProvider, false )
1546
1547int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aReporter ) const
1548{
1549 UNITS_PROVIDER unitsProvider( schIUScale, EDA_UNITS::MM );
1550
1551 if( m_me == aRhs.m_me )
1552 return 0;
1553
1554 if( !aReporter && ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) == 0 )
1555 {
1556 if( int tmp = m_name.Cmp( aRhs.m_name ) )
1557 return tmp;
1558
1559 if( int tmp = m_libId.compare( aRhs.m_libId ) )
1560 return tmp;
1561
1562 if( m_parent.lock() < aRhs.m_parent.lock() )
1563 return -1;
1564
1565 if( m_parent.lock() > aRhs.m_parent.lock() )
1566 return 1;
1567 }
1568
1569 int retv = 0;
1570
1571 if( m_options != aRhs.m_options )
1572 {
1573 retv = ( m_options == ENTRY_NORMAL ) ? -1 : 1;
1574 REPORT( _( "Power flag differs." ) );
1575
1576 if( !aReporter )
1577 return retv;
1578 }
1579
1580 if( int tmp = m_unitCount - aRhs.m_unitCount )
1581 {
1582 retv = tmp;
1583 REPORT( _( "Unit count differs." ) );
1584
1585 if( !aReporter )
1586 return retv;
1587 }
1588
1589 // Make sure shapes are sorted. No need with fields or pins as those are matched by id/name and number.
1590
1591 std::set<const SCH_ITEM*, SCH_ITEM::cmp_items> aShapes;
1592 std::set<const SCH_FIELD*> aFields;
1593 std::set<const SCH_PIN*> aPins;
1594
1595 for( auto it = m_drawings.begin(); it != m_drawings.end(); ++it )
1596 {
1597 if( it->Type() == SCH_SHAPE_T )
1598 aShapes.insert( &(*it) );
1599 else if( it->Type() == SCH_FIELD_T )
1600 aFields.insert( static_cast<const SCH_FIELD*>( &(*it) ) );
1601 else if( it->Type() == SCH_PIN_T )
1602 aPins.insert( static_cast<const SCH_PIN*>( &(*it) ) );
1603 }
1604
1605 std::set<const SCH_ITEM*, SCH_ITEM::cmp_items> bShapes;
1606 std::set<const SCH_FIELD*> bFields;
1607 std::set<const SCH_PIN*> bPins;
1608
1609 for( auto it = aRhs.m_drawings.begin(); it != aRhs.m_drawings.end(); ++it )
1610 {
1611 if( it->Type() == SCH_SHAPE_T )
1612 bShapes.insert( &(*it) );
1613 else if( it->Type() == SCH_FIELD_T )
1614 bFields.insert( static_cast<const SCH_FIELD*>( &(*it) ) );
1615 else if( it->Type() == SCH_PIN_T )
1616 bPins.insert( static_cast<const SCH_PIN*>( &(*it) ) );
1617 }
1618
1619 if( int tmp = static_cast<int>( aShapes.size() - bShapes.size() ) )
1620 {
1621 retv = tmp;
1622 REPORT( _( "Graphic item count differs." ) );
1623
1624 if( !aReporter )
1625 return retv;
1626 }
1627 else
1628 {
1629 for( auto aIt = aShapes.begin(), bIt = bShapes.begin(); aIt != aShapes.end(); aIt++, bIt++ )
1630 {
1631 if( int tmp2 = (*aIt)->compare( *(*bIt), aCompareFlags ) )
1632 {
1633 retv = tmp2;
1634 REPORT( wxString::Format( _( "Graphic item differs: %s; %s." ),
1635 ITEM_DESC( *aIt ),
1636 ITEM_DESC( *bIt ) ) );
1637
1638 if( !aReporter )
1639 return retv;
1640 }
1641 }
1642 }
1643
1644 for( const SCH_PIN* aPin : aPins )
1645 {
1646 const SCH_PIN* bPin = aRhs.GetPin( aPin->GetNumber(), aPin->GetUnit(), aPin->GetBodyStyle() );
1647
1648 if( !bPin )
1649 {
1650 retv = 1;
1651 REPORT( wxString::Format( _( "Extra pin in schematic symbol: %s." ), ITEM_DESC( aPin ) ) );
1652
1653 if( !aReporter )
1654 return retv;
1655 }
1656 else if( int tmp = aPin->SCH_ITEM::compare( *bPin, aCompareFlags ) )
1657 {
1658 retv = tmp;
1659 REPORT( wxString::Format( _( "Pin %s differs: %s; %s" ),
1660 aPin->GetNumber(),
1661 ITEM_DESC( aPin ),
1662 ITEM_DESC( bPin ) ) );
1663
1664 if( !aReporter )
1665 return retv;
1666 }
1667 }
1668
1669 for( const SCH_PIN* bPin : bPins )
1670 {
1671 const SCH_PIN* aPin = aRhs.GetPin( bPin->GetNumber(), bPin->GetUnit(), bPin->GetBodyStyle() );
1672
1673 if( !aPin )
1674 {
1675 retv = 1;
1676 REPORT( wxString::Format( _( "Missing pin in schematic symbol: %s." ), ITEM_DESC( bPin ) ) );
1677
1678 if( !aReporter )
1679 return retv;
1680 }
1681 }
1682
1683 for( const SCH_FIELD* aField : aFields )
1684 {
1685 const SCH_FIELD* bField = nullptr;
1686
1687 if( aField->IsMandatory() )
1688 bField = aRhs.GetField( aField->GetId() );
1689 else
1690 bField = aRhs.GetField( aField->GetName() );
1691
1692 if( !bField )
1693 {
1694 retv = 1;
1695 REPORT( wxString::Format( _( "Extra field in schematic symbol: %s." ), ITEM_DESC( aField ) ) );
1696
1697 if( !aReporter )
1698 return retv;
1699 }
1700 else
1701 {
1702 int tmp = 0;
1703
1704 // For EQUALITY comparison, we need to compare field content directly
1705 // since SCH_ITEM::compare() returns 0 for EQUALITY flag
1706 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1707 {
1708 // Compare field text content
1709 tmp = aField->GetText().compare( bField->GetText() );
1710 }
1711
1712 if( tmp == 0 )
1713 {
1714 // Fall back to base class comparison for other properties
1715 tmp = aField->SCH_ITEM::compare( *bField, aCompareFlags );
1716 }
1717
1718 if( tmp != 0 )
1719 {
1720 retv = tmp;
1721 REPORT( wxString::Format( _( "Field '%s' differs: %s; %s." ),
1722 aField->GetName( false ),
1723 ITEM_DESC( aField ),
1724 ITEM_DESC( bField ) ) );
1725
1726 if( !aReporter )
1727 return retv;
1728 }
1729 }
1730 }
1731
1732 for( const SCH_FIELD* bField : bFields )
1733 {
1734 const SCH_FIELD* aField = nullptr;
1735
1736 if( bField->IsMandatory() )
1737 aField = aRhs.GetField( bField->GetId() );
1738 else
1739 aField = aRhs.GetField( bField->GetName() );
1740
1741 if( !aField )
1742 {
1743 retv = 1;
1744 REPORT( wxString::Format( _( "Missing field in schematic symbol: %s." ), ITEM_DESC( bField ) ) );
1745
1746 if( !aReporter )
1747 return retv;
1748 }
1749 }
1750
1751 if( int tmp = static_cast<int>( m_fpFilters.GetCount() - aRhs.m_fpFilters.GetCount() ) )
1752 {
1753 retv = tmp;
1754 REPORT( _( "Footprint filter count differs." ) );
1755
1756 if( !aReporter )
1757 return retv;
1758 }
1759 else
1760 {
1761 for( size_t i = 0; i < m_fpFilters.GetCount(); i++ )
1762 {
1763 if( int tmp2 = m_fpFilters[i].Cmp( aRhs.m_fpFilters[i] ) )
1764 {
1765 retv = tmp2;
1766 REPORT( _( "Footprint filters differ." ) );
1767
1768 if( !aReporter )
1769 return retv;
1770 }
1771 }
1772 }
1773
1774 if( int tmp = m_keyWords.Cmp( aRhs.m_keyWords ) )
1775 {
1776 retv = tmp;
1777 REPORT( _( "Symbol keywords differ." ) );
1778
1779 if( !aReporter )
1780 return retv;
1781 }
1782
1783 if( int tmp = m_pinNameOffset - aRhs.m_pinNameOffset )
1784 {
1785 retv = tmp;
1786 REPORT( _( "Symbol pin name offsets differ." ) );
1787
1788 if( !aReporter )
1789 return retv;
1790 }
1791
1792 if( ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) == 0 )
1793 {
1794 if( m_showPinNames != aRhs.m_showPinNames )
1795 {
1796 retv = ( m_showPinNames ) ? 1 : -1;
1797 REPORT( _( "Show pin names settings differ." ) );
1798
1799 if( !aReporter )
1800 return retv;
1801 }
1802
1804 {
1805 retv = ( m_showPinNumbers ) ? 1 : -1;
1806 REPORT( _( "Show pin numbers settings differ." ) );
1807
1808 if( !aReporter )
1809 return retv;
1810 }
1811
1813 {
1814 retv = ( m_excludedFromSim ) ? -1 : 1;
1815 REPORT( _( "Exclude from simulation settings differ." ) );
1816
1817 if( !aReporter )
1818 return retv;
1819 }
1820
1822 {
1823 retv = ( m_excludedFromBOM ) ? -1 : 1;
1824 REPORT( _( "Exclude from bill of materials settings differ." ) );
1825
1826 if( !aReporter )
1827 return retv;
1828 }
1829
1831 {
1832 retv = ( m_excludedFromBoard ) ? -1 : 1;
1833 REPORT( _( "Exclude from board settings differ." ) );
1834
1835 if( !aReporter )
1836 return retv;
1837 }
1838 }
1839
1840 if( !aReporter )
1841 {
1842 if( m_unitsLocked != aRhs.m_unitsLocked )
1843 return ( m_unitsLocked ) ? 1 : -1;
1844
1845 // Compare unit display names...
1847 return -1;
1848 else if( m_unitDisplayNames > aRhs.m_unitDisplayNames )
1849 return 1;
1850
1851 // ... and body style names.
1853 return -1;
1854 else if( m_bodyStyleNames > aRhs.m_bodyStyleNames )
1855 return 1;
1856 }
1857
1858 return retv;
1859}
1860
1861
1862int LIB_SYMBOL::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1863{
1864 if( Type() != aOther.Type() )
1865 return Type() - aOther.Type();
1866
1867 const LIB_SYMBOL* tmp = static_cast<const LIB_SYMBOL*>( &aOther );
1868
1869 return Compare( *tmp, aCompareFlags );
1870}
1871
1872
1873double LIB_SYMBOL::Similarity( const SCH_ITEM& aOther ) const
1874{
1875 wxCHECK( aOther.Type() == LIB_SYMBOL_T, 0.0 );
1876
1877 const LIB_SYMBOL& other = static_cast<const LIB_SYMBOL&>( aOther );
1878 double similarity = 0.0;
1879 int totalItems = 0;
1880
1881 if( m_Uuid == aOther.m_Uuid )
1882 return 1.0;
1883
1884 for( const SCH_ITEM& item : m_drawings )
1885 {
1886 totalItems += 1;
1887 double max_similarity = 0.0;
1888
1889 for( const SCH_ITEM& otherItem : other.m_drawings )
1890 {
1891 double temp_similarity = item.Similarity( otherItem );
1892 max_similarity = std::max( max_similarity, temp_similarity );
1893
1894 if( max_similarity == 1.0 )
1895 break;
1896 }
1897
1898 similarity += max_similarity;
1899 }
1900
1901 for( const SCH_PIN* pin : GetPins() )
1902 {
1903 totalItems += 1;
1904 double max_similarity = 0.0;
1905
1906 for( const SCH_PIN* otherPin : other.GetPins() )
1907 {
1908 double temp_similarity = pin->Similarity( *otherPin );
1909 max_similarity = std::max( max_similarity, temp_similarity );
1910
1911 if( max_similarity == 1.0 )
1912 break;
1913 }
1914
1915 similarity += max_similarity;
1916 }
1917
1918 if( totalItems == 0 )
1919 similarity = 0.0;
1920 else
1921 similarity /= totalItems;
1922
1924 similarity *= 0.9;
1925
1927 similarity *= 0.9;
1928
1930 similarity *= 0.9;
1931
1932 if( m_flags != other.m_flags )
1933 similarity *= 0.9;
1934
1935 if( m_unitCount != other.m_unitCount )
1936 similarity *= 0.5;
1937
1938 if( GetBodyStyleCount() != other.GetBodyStyleCount() )
1939 similarity *= 0.5;
1940 else if( m_bodyStyleNames != other.m_bodyStyleNames )
1941 similarity *= 0.9;
1942
1943 if( m_pinNameOffset != other.m_pinNameOffset )
1944 similarity *= 0.9;
1945
1946 if( m_showPinNames != other.m_showPinNames )
1947 similarity *= 0.9;
1948
1949 if( m_showPinNumbers != other.m_showPinNumbers )
1950 similarity *= 0.9;
1951
1952 return similarity;
1953}
1954
1955
1957{
1958 return static_cast<EMBEDDED_FILES*>( this );
1959}
1960
1961
1963{
1964 return static_cast<const EMBEDDED_FILES*>( this );
1965}
1966
1967
1968std::set<KIFONT::OUTLINE_FONT*> LIB_SYMBOL::GetFonts() const
1969{
1970 using EMBEDDING_PERMISSION = KIFONT::OUTLINE_FONT::EMBEDDING_PERMISSION;
1971
1972 std::set<KIFONT::OUTLINE_FONT*> fonts;
1973
1974 for( const SCH_ITEM& item : m_drawings )
1975 {
1976 if( item.Type() == SCH_TEXT_T )
1977 {
1978 const SCH_TEXT& text = static_cast<const SCH_TEXT&>( item );
1979
1980 if( auto* font = text.GetFont(); font && !font->IsStroke() )
1981 {
1982 auto* outline = static_cast<KIFONT::OUTLINE_FONT*>( font );
1983 auto permission = outline->GetEmbeddingPermission();
1984
1985 if( permission == EMBEDDING_PERMISSION::EDITABLE
1986 || permission == EMBEDDING_PERMISSION::INSTALLABLE )
1987 {
1988 fonts.insert( outline );
1989 }
1990 }
1991 }
1992 }
1993
1994 return fonts;
1995}
1996
1997
1999{
2000 std::set<KIFONT::OUTLINE_FONT*> fonts = GetFonts();
2001
2002 for( KIFONT::OUTLINE_FONT* font : fonts )
2003 {
2004 auto file = GetEmbeddedFiles()->AddFile( font->GetFileName(), false );
2006 }
2007}
2008
2009
2010std::optional<const std::set<wxString>> LIB_SYMBOL::GetJumperPinGroup( const wxString& aPinNumber ) const
2011{
2012 for( const std::set<wxString>& group : m_jumperPinGroups )
2013 {
2014 if( group.contains( aPinNumber ) )
2015 return group;
2016 }
2017
2018 return std::nullopt;
2019}
int color
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
double square(double x)
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:658
static const COLOR4D WHITE
Definition color4d.h:401
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
virtual void ClearEditFlags()
Definition eda_item.h:156
const KIID m_Uuid
Definition eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
void ClearSelected()
Definition eda_item.h:137
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:527
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition eda_item.cpp:118
EDA_ITEM_FLAGS GetFlags() const
Definition eda_item.h:145
virtual void ClearTempFlags()
Definition eda_item.h:169
FILL_T GetFillMode() const
Definition eda_shape.h:142
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:97
virtual bool IsVisible() const
Definition eda_text.h:186
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:387
bool IsEmpty() const
EMBEDDED_FILES & operator=(EMBEDDED_FILES &&other) noexcept
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
EMBEDDED_FILES()=default
Class OUTLINE_FONT implements outline font drawing.
EMBEDDING_PERMISSION GetEmbeddingPermission() const
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
Define a library symbol object.
Definition lib_symbol.h:85
LIB_ITEMS_CONTAINER m_drawings
Definition lib_symbol.h:708
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
SCH_FIELD & GetDescriptionField()
Return reference to the description field.
Definition lib_symbol.h:352
wxString GetDescription() const override
Definition lib_symbol.h:169
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:154
const BOX2I GetUnitBoundingBox(int aUnit, int aBodyStyle, bool aIgnoreHiddenFields=true, bool aIgnoreLabelsOnInvisiblePins=true) const
Get the bounding box for the symbol.
wxString GetKeyWords() const override
Definition lib_symbol.h:182
void SetGlobalPower()
LIBRENTRYOPTIONS m_options
Special symbol features such as POWER or NORMAL.
Definition lib_symbol.h:706
bool PinsConflictWith(const LIB_SYMBOL &aOtherSymbol, bool aTestNums, bool aTestNames, bool aTestType, bool aTestOrientation, bool aTestLength) const
Return true if this symbol's pins do not match another symbol's pins.
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
bool IsPower() const override
wxString GetPrefix()
SCH_FIELD & GetDatasheetField()
Return reference to the datasheet field.
Definition lib_symbol.h:348
std::vector< struct LIB_SYMBOL_UNIT > GetUnitDrawItems()
Return a list of SCH_ITEM objects separated by unit and convert number.
std::map< int, wxString > m_unitDisplayNames
Definition lib_symbol.h:724
std::vector< std::set< wxString > > m_jumperPinGroups
A list of jumper pin groups, each of which is a set of pin numbers that should be jumpered together (...
Definition lib_symbol.h:718
void ClearTempFlags() override
Clears the status flag all draw objects in this symbol.
bool IsDerived() const
Definition lib_symbol.h:206
std::map< int, wxString > & GetUnitDisplayNames()
Definition lib_symbol.h:570
SYMBOL_LIB * m_library
Definition lib_symbol.h:710
bool m_demorgan
True if there are two body styles: normal and De Morgan If false, the body style count is taken from ...
Definition lib_symbol.h:702
wxString GetFootprint() override
For items with footprint fields.
Definition lib_symbol.h:195
const wxString GetLibraryName() const
void SetFields(const std::vector< SCH_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
std::vector< SEARCH_TERM > GetSearchTerms() override
bool IsMultiBodyStyle() const override
Definition lib_symbol.h:594
int GetMaxPinNumber() const
LIB_SYMBOL(const wxString &aName, LIB_SYMBOL *aParent=nullptr, SYMBOL_LIB *aLibrary=nullptr)
LIB_SYMBOL_SPTR m_me
Definition lib_symbol.h:692
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
SCH_FIELD * GetField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName; return nullptr if not found.
SCH_FIELD & GetFootprintField()
Return reference to the footprint field.
Definition lib_symbol.h:344
int Compare(const LIB_SYMBOL &aRhs, int aCompareFlags=0, REPORTER *aReporter=nullptr) const
Comparison test that can be used for operators.
void FixupDrawItems()
This function finds the filled draw items that are covering up smaller draw items and replaces their ...
SCH_PIN * GetPin(const wxString &aNumber, int aUnit=0, int aBodyStyle=0) const
Return pin object with the requested pin aNumber.
bool IsNormal() const override
wxString m_name
Definition lib_symbol.h:711
std::set< KIFONT::OUTLINE_FONT * > GetFonts() const override
SCH_FIELD * FindFieldCaseInsensitive(const wxString &aFieldName)
wxString m_keyWords
Search keywords.
Definition lib_symbol.h:712
SCH_ITEM * LocateDrawItem(int aUnit, int aBodyStyle, KICAD_T aType, const VECTOR2I &aPoint)
Locate a draw object.
static wxString LetterSubReference(int aUnit, wxChar aInitialLetter)
double Similarity(const SCH_ITEM &aSymbol) const override
Return a measure of similarity between this symbol and aSymbol.
static LIB_SYMBOL * GetDummy()
Returns a dummy LIB_SYMBOL, used when one is missing in the schematic.
void PlotFields(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed)
Plot symbol fields.
void SetParent(LIB_SYMBOL *aParent=nullptr)
wxString GetName() const override
Definition lib_symbol.h:148
void SetUnitCount(int aCount, bool aDuplicateDrawItems)
Set the units per symbol count.
void SetKeyWords(const wxString &aKeyWords)
Definition lib_symbol.h:180
SCH_FIELD & GetValueField()
Return reference to the value field.
Definition lib_symbol.h:336
bool IsLocalPower() const override
wxArrayString GetFPFilters() const
Definition lib_symbol.h:217
void RemoveDrawItem(SCH_ITEM *aItem)
Remove draw aItem from list.
void GetChooserFields(std::map< wxString, wxString > &aColumnMap) override
Retrieves a key/value map of the fields on this item that should be exposed to the library browser/ch...
bool HasLegacyAlternateBodyStyle() const
Before V10 we didn't store the number of body styles in a symbol – we just looked through all its dra...
const std::vector< wxString > & GetBodyStyleNames() const
Definition lib_symbol.h:607
int compare(const SCH_ITEM &aOther, int aCompareFlags=SCH_ITEM::COMPARE_FLAGS::EQUALITY) const override
The library symbol specific sort order is as follows:
timestamp_t m_lastModDate
Definition lib_symbol.h:696
std::optional< const std::set< wxString > > GetJumperPinGroup(const wxString &aPinNumber) const
Retrieves the jumper group containing the specified pin number, if one exists.
LIB_ID m_libId
Definition lib_symbol.h:694
void SetLocalPower()
void SetLib(SYMBOL_LIB *aLibrary)
Definition lib_symbol.h:211
std::vector< SCH_PIN * > GetPins() const override
void SetBodyStyleCount(int aCount, bool aDuplicateDrawItems, bool aDuplicatePins)
Set or clear the alternate body style (DeMorgan) for the symbol.
wxString GetLibNickname() const override
Sets the Description field text value.
Definition lib_symbol.h:160
std::vector< LOGICAL_PIN > GetLogicalPins(int aUnit, int aBodyStyle) const
Return all logical pins (expanded) filtered by unit/body.
bool HasDeMorganBodyStyles() const override
Definition lib_symbol.h:604
const LIB_SYMBOL & operator=(const LIB_SYMBOL &aSymbol)
bool m_unitsLocked
True if symbol has multiple units and changing one unit does not automatically change another unit.
Definition lib_symbol.h:699
wxArrayString m_fpFilters
List of suitable footprint names for the symbol (wild card names accepted).
Definition lib_symbol.h:713
void Move(const VECTOR2I &aOffset) override
Move the symbol aOffset.
void SetFPFilters(const wxArrayString &aFilters)
Definition lib_symbol.h:215
void CopyFields(std::vector< SCH_FIELD > &aList)
Create a copy of the SCH_FIELDs, sorted in ordinal order.
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
LIB_SYMBOL_SPTR SharedPtr() const
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared.
Definition lib_symbol.h:95
int GetBodyStyleCount() const override
Definition lib_symbol.h:596
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...
EMBEDDED_FILES * GetEmbeddedFiles() override
int m_unitCount
Number of units (parts) per package.
Definition lib_symbol.h:698
bool IsGlobalPower() const override
wxString GetBodyStyleDescription(int aBodyStyle, bool aLabel) const override
unsigned GetInheritanceDepth() const
Get the number of parents for this symbol.
int GetUnitCount() const override
LIB_SYMBOL_REF m_parent
Use for inherited symbols.
Definition lib_symbol.h:693
std::vector< wxString > m_bodyStyleNames
Definition lib_symbol.h:725
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
BOX2I GetBodyBoundingBox() const override
Return a bounding box for the symbol body but not the pins or fields.
Definition lib_symbol.h:262
int GetPinCount() override
void SetLibId(const LIB_ID &aLibId)
Definition lib_symbol.h:155
void AddField(SCH_FIELD *aField)
Add a field.
void ClearEditFlags() override
void deleteAllFields()
LIB_ID GetLIB_ID() const override
Definition lib_symbol.h:150
LIB_SYMBOL_REF & GetParent()
Definition lib_symbol.h:117
bool m_duplicatePinNumbersAreJumpers
Flag that this symbol should automatically treat sets of two or more pins with the same number as jum...
Definition lib_symbol.h:722
LIB_SYMBOL_SPTR GetRootSymbol() const
Get the parent symbol that does not have another parent.
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
wxString GetUnitDisplayName(int aUnit, bool aLabel) const override
Return the user-defined display name for aUnit for symbols with units.
void EmbedFonts() override
virtual void SetName(const wxString &aName)
void SetNormal()
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
Definition lib_symbol.h:340
int GetNextFieldOrdinal() const
Return the next ordinal for a user field for this symbol.
ITERATOR_BASE< SCH_ITEM, MULTIVECTOR< SCH_ITEM, FIRST_TYPE_VAL, LAST_TYPE_VAL >, typename ITEM_PTR_VECTOR::iterator > ITERATOR
ITERATOR end(int aType=UNDEFINED_TYPE)
ITERATOR begin(int aType=UNDEFINED_TYPE)
Base plotter engine class.
Definition plotter.h:121
bool GetColorMode() const
Definition plotter.h:149
virtual void SetColor(const COLOR4D &color)=0
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
bool IsMandatory() const
wxString GetFullText(int unit=1) const
Return the text of a field.
FIELD_T GetId() const
Definition sch_field.h:116
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
bool ShowInChooser() const
Definition sch_field.h:223
void SetText(const wxString &aText) override
int m_unit
Definition sch_item.h:740
int m_bodyStyle
Definition sch_item.h:741
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:688
friend class LIB_SYMBOL
Definition sch_item.h:759
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:51
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
Object used to load, save, search, and otherwise manipulate symbol library files.
bool m_showPinNumbers
Definition symbol.h:227
void SetExcludedFromBoard(bool aExcludeFromBoard) override
Set or clear exclude from board netlist flag.
Definition symbol.h:191
SYMBOL(KICAD_T idType)
Definition symbol.h:65
bool m_excludedFromSim
Definition symbol.h:229
bool m_showPinNames
Definition symbol.h:226
void SetExcludedFromSim(bool aExcludeFromSim) override
Set or clear the exclude from simulation flag.
Definition symbol.h:175
bool GetExcludedFromBoard() const override
Definition symbol.h:192
bool m_excludedFromBOM
Definition symbol.h:230
void SetExcludedFromBOM(bool aExcludeFromBOM) override
Set or clear the exclude from schematic bill of materials flag.
Definition symbol.h:185
bool m_excludedFromBoard
Definition symbol.h:231
bool GetDNP() const override
Set or clear the 'Do Not Populate' flag.
Definition symbol.h:197
SYMBOL & operator=(const SYMBOL &aItem)
Definition symbol.h:91
bool GetExcludedFromBOM() const override
Definition symbol.h:186
int m_pinNameOffset
The offset in mils to draw the pin name.
Definition symbol.h:224
bool GetExcludedFromSim() const override
Definition symbol.h:180
for transforming drawing coordinates for a wxDC device context.
Definition transform.h:46
#define DEFAULT_PIN_NAME_OFFSET
The intersheets references prefix string.
#define _(s)
RECURSE_MODE
Definition eda_item.h:50
INSPECT_RESULT
Definition eda_item.h:44
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:91
#define IGNORE_PARENT_GROUP
Definition eda_item.h:55
#define IS_NEW
New item, just created.
#define STRUCT_DELETED
flag indication structures to be erased
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:46
@ FILLED_WITH_COLOR
Definition eda_shape.h:60
@ FILLED_WITH_BG_BODYCOLOR
Definition eda_shape.h:59
TRANSFORM DefaultTransform
Definition transform.cpp:32
@ LAYER_DEVICE
Definition layer_ids.h:465
@ LAYER_FIELDS
Definition layer_ids.h:461
#define REPORT(msg)
bool operator<(const LIB_SYMBOL &aItem1, const LIB_SYMBOL &aItem2)
#define ITEM_DESC(item)
@ ENTRY_NORMAL
Definition lib_symbol.h:61
@ ENTRY_LOCAL_POWER
Definition lib_symbol.h:63
@ ENTRY_GLOBAL_POWER
Definition lib_symbol.h:62
MULTIVECTOR< SCH_ITEM, SCH_SHAPE_T, SCH_PIN_T > LIB_ITEMS_CONTAINER
Definition lib_symbol.h:54
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition lib_symbol.h:52
LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS
Definition lib_symbol.h:55
#define _HKI(x)
Definition page_info.cpp:44
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition ptree.cpp:198
@ BASE
Definition sch_item.h:59
@ DEMORGAN
Definition sch_item.h:60
Logical pins: Return expanded logical pins based on stacked-pin notation.
Definition lib_symbol.h:433
int m_bodyStyle
The alternate body style of the unit.
Definition lib_symbol.h:73
std::vector< SCH_ITEM * > m_items
The items unique to this unit and alternate body style.
Definition lib_symbol.h:74
int m_unit
The unit number.
Definition lib_symbol.h:72
A structure for storing weighted search terms.
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
void operator()(void const *) const
Definition for symbol library class.
#define MANDATORY_FIELDS
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:78
@ LIB_SYMBOL_T
Definition typeinfo.h:150
@ TYPE_NOT_INIT
Definition typeinfo.h:81
@ SCH_FIELD_T
Definition typeinfo.h:152
@ SCH_SHAPE_T
Definition typeinfo.h:151
@ SCH_TEXT_T
Definition typeinfo.h:153
@ SCH_PIN_T
Definition typeinfo.h:155
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695