KiCad PCB EDA Suite
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 (C) 2004-2022 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 <sch_draw_panel.h>
28#include <plotters/plotter.h>
29#include <sch_screen.h>
30#include <richio.h>
31#include <general.h>
32#include <template_fieldnames.h>
33#include <transform.h>
34#include <symbol_library.h>
35#include <lib_pin.h>
37#include <lib_shape.h>
38
39// the separator char between the subpart id and the reference
40// 0 (no separator) or '.' or some other character
42
43// the ascii char value to calculate the subpart symbol id from the part number:
44// 'A' or '1' usually. (to print U1.A or U1.1)
45// if this a digit, a number is used as id symbol
47
48
50{
51 // Matches are scored by offset from front of string, so inclusion of this spacer
52 // discounts matches found after it.
53 static const wxString discount( wxT( " " ) );
54
55 wxString text = GetKeyWords() + discount + GetDescription();
56 wxString footprint = GetFootprintField().GetText();
57
58 if( !footprint.IsEmpty() )
59 {
60 text += discount + footprint;
61 }
62
63 // TODO(JE) rework this later so we can highlight matches in their column
64 std::map<wxString, wxString> fields;
65 GetChooserFields( fields );
66
67 for( const auto& it : fields )
68 text += discount + it.second;
69
70 return text;
71}
72
73
74void LIB_SYMBOL::GetChooserFields( std::map<wxString , wxString>& aColumnMap )
75{
76 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
77 {
78 LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
79
80 if( field->ShowInChooser() )
81 aColumnMap[field->GetName()] = field->EDA_TEXT::GetShownText();
82 }
83}
84
85
86bool operator<( const LIB_SYMBOL& aItem1, const LIB_SYMBOL& aItem2 )
87{
88 return aItem1.GetName() < aItem2.GetName();
89}
90
91
94{
95 void operator()(void const *) const
96 {
97 }
98};
99
100
101LIB_SYMBOL::LIB_SYMBOL( const wxString& aName, LIB_SYMBOL* aParent, SYMBOL_LIB* aLibrary ) :
103 m_me( this, null_deleter() ),
104 m_includeInBom( true ),
105 m_includeOnBoard( true )
106{
107 m_lastModDate = 0;
108 m_unitCount = 1;
111 m_unitsLocked = false;
112 m_showPinNumbers = true;
113 m_showPinNames = true;
114
115 // Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
116 // when the field editors are invoked.
117 m_drawings[LIB_FIELD_T].reserve( 4 );
122
123 SetName( aName );
124
125 if( aParent )
126 SetParent( aParent );
127
128 SetLib( aLibrary );
129}
130
131
132LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
133 EDA_ITEM( aSymbol ),
134 m_me( this, null_deleter() )
135{
136 LIB_ITEM* newItem;
137
138 m_library = aLibrary;
139 m_name = aSymbol.m_name;
140 m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
141 m_unitCount = aSymbol.m_unitCount;
149 m_options = aSymbol.m_options;
150 m_libId = aSymbol.m_libId;
152 m_keyWords = aSymbol.m_keyWords;
153
155
157
158 for( const LIB_ITEM& oldItem : aSymbol.m_drawings )
159 {
160 if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
161 continue;
162
163 try
164 {
165 newItem = (LIB_ITEM*) oldItem.Clone();
166 newItem->ClearSelected();
167 newItem->SetParent( this );
168 m_drawings.push_back( newItem );
169 }
170 catch( ... )
171 {
172 wxFAIL_MSG( "Failed to clone LIB_ITEM." );
173 return;
174 }
175 }
176
177 LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
178
179 if( parent )
180 SetParent( parent.get() );
181}
182
183
185{
186 if( &aSymbol == this )
187 return aSymbol;
188
189 LIB_ITEM* newItem;
190
191 m_library = aSymbol.m_library;
192 m_name = aSymbol.m_name;
193 m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
194 m_unitCount = aSymbol.m_unitCount;
202 m_options = aSymbol.m_options;
203 m_libId = aSymbol.m_libId;
205 m_keyWords = aSymbol.m_keyWords;
206
207 m_unitDisplayNames.clear();
209
211
212 for( const LIB_ITEM& oldItem : aSymbol.m_drawings )
213 {
214 if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
215 continue;
216
217 newItem = (LIB_ITEM*) oldItem.Clone();
218 newItem->SetParent( this );
219 m_drawings.push_back( newItem );
220 }
221
223
224 LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
225
226 if( parent )
227 SetParent( parent.get() );
228
229 return *this;
230}
231
232
233int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags ) const
234{
235 if( m_me == aRhs.m_me )
236 return 0;
237
238 int retv = 0;
239
240 if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
241 {
242 retv = m_name.Cmp( aRhs.m_name );
243
244 if( retv )
245 return retv;
246
247 retv = m_libId.compare( aRhs.m_libId );
248
249 if( retv )
250 return retv;
251 }
252
253 if( m_parent.lock() < aRhs.m_parent.lock() )
254 return -1;
255
256 if( m_parent.lock() > aRhs.m_parent.lock() )
257 return 1;
258
259 if( m_options != aRhs.m_options )
260 return ( m_options == ENTRY_NORMAL ) ? -1 : 1;
261
262 if( m_unitCount != aRhs.m_unitCount )
263 return m_unitCount - aRhs.m_unitCount;
264
265 if( m_drawings.size() != aRhs.m_drawings.size() )
266 return m_drawings.size() - aRhs.m_drawings.size();
267
270
271 while( lhsItemIt != m_drawings.end() )
272 {
273 const LIB_ITEM* lhsItem = static_cast<const LIB_ITEM*>( &(*lhsItemIt) );
274 const LIB_ITEM* rhsItem = static_cast<const LIB_ITEM*>( &(*rhsItemIt) );
275
276 wxCHECK( lhsItem && rhsItem, lhsItem - rhsItem );
277
278 if( lhsItem->Type() != rhsItem->Type() )
279 return lhsItem->Type() - rhsItem->Type();
280
281 // Non-mandatory fields are a special case. They can have different ordinal numbers
282 // and are compared separately below.
283 if( lhsItem->Type() == LIB_FIELD_T )
284 {
285 const LIB_FIELD* lhsField = static_cast<const LIB_FIELD*>( lhsItem );
286
287 if( lhsField->GetId() == VALUE_FIELD )
288 {
289 if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 || IsPower() )
290 retv = lhsItem->compare( *rhsItem, aCompareFlags );
291 }
292 else if( lhsField->IsMandatory() )
293 {
294 retv = lhsItem->compare( *rhsItem, aCompareFlags );
295 }
296 }
297 else
298 {
299 retv = lhsItem->compare( *rhsItem, aCompareFlags );
300 }
301
302 if( retv )
303 return retv;
304
305 ++lhsItemIt;
306 ++rhsItemIt;
307 }
308
309 // Compare the optional fields.
310 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
311 {
312 const LIB_FIELD* field = dynamic_cast<const LIB_FIELD*>( &item );
313
314 wxCHECK2( field, continue );
315
316 // Mandatory fields were already compared above.
317 if( field->IsMandatory() )
318 continue;
319
320 const LIB_FIELD* foundField = aRhs.FindField( field->GetName() );
321
322 if( foundField == nullptr )
323 return 1;
324
325 retv = item.compare( static_cast<const LIB_ITEM&>( *foundField ), aCompareFlags );
326
327 if( retv )
328 return retv;
329 }
330
331 if( m_fpFilters.GetCount() != aRhs.m_fpFilters.GetCount() )
332 return m_fpFilters.GetCount() - aRhs.m_fpFilters.GetCount();
333
334 for( size_t i = 0; i < m_fpFilters.GetCount(); i++ )
335 {
336 retv = m_fpFilters[i].Cmp( aRhs.m_fpFilters[i] );
337
338 if( retv )
339 return retv;
340 }
341
342 retv = m_description.Cmp( aRhs.m_description );
343
344 if( retv )
345 return retv;
346
347 retv = m_keyWords.Cmp( aRhs.m_keyWords );
348
349 if( retv )
350 return retv;
351
352 if( m_pinNameOffset != aRhs.m_pinNameOffset )
353 return m_pinNameOffset - aRhs.m_pinNameOffset;
354
355 if( m_unitsLocked != aRhs.m_unitsLocked )
356 return ( m_unitsLocked ) ? 1 : -1;
357
358 if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
359 {
360 if( m_showPinNames != aRhs.m_showPinNames )
361 return ( m_showPinNames ) ? 1 : -1;
362
364 return ( m_showPinNumbers ) ? 1 : -1;
365
366 if( m_includeInBom != aRhs.m_includeInBom )
367 return ( m_includeInBom ) ? 1 : -1;
368
370 return ( m_includeOnBoard ) ? 1 : -1;
371 }
372
373 // Compare unit display names
375 {
376 return -1;
377 }
378 else if( m_unitDisplayNames > aRhs.m_unitDisplayNames )
379 {
380 return 1;
381 }
382
383 return 0;
384}
385
386
387wxString LIB_SYMBOL::GetUnitReference( int aUnit )
388{
389 return LIB_SYMBOL::SubReference( aUnit, false );
390}
391
392
394{
395 return ( m_unitDisplayNames.count( aUnit ) == 1 );
396}
397
398
400{
401 if( HasUnitDisplayName( aUnit ) )
402 {
403 return m_unitDisplayNames[aUnit];
404 }
405 else
406 {
407 return wxString::Format( _( "Unit %s" ), GetUnitReference( aUnit ) );
408 }
409}
410
411
412void LIB_SYMBOL::CopyUnitDisplayNames( std::map<int, wxString>& aTarget ) const
413{
414 for( const auto& it : m_unitDisplayNames )
415 {
416 aTarget[it.first] = it.second;
417 }
418}
419
420
421void LIB_SYMBOL::SetUnitDisplayName( int aUnit, const wxString& aName )
422{
423 if( aUnit <= GetUnitCount() )
424 {
425 if( aName.Length() > 0 )
426 {
427 m_unitDisplayNames[aUnit] = aName;
428 }
429 else
430 {
431 m_unitDisplayNames.erase( aUnit );
432 }
433 }
434}
435
436
437void LIB_SYMBOL::SetName( const wxString& aName )
438{
439 m_name = aName;
440 m_libId.SetLibItemName( aName );
441}
442
443
445{
446 if( aParent )
447 m_parent = aParent->SharedPtr();
448 else
449 m_parent.reset();
450}
451
452
453std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
454{
455 std::unique_ptr< LIB_SYMBOL > retv;
456
457 if( IsAlias() )
458 {
459 LIB_SYMBOL_SPTR parent = m_parent.lock();
460
461 wxCHECK_MSG( parent, retv,
462 wxString::Format( "Parent of derived symbol '%s' undefined", m_name ) );
463
464 // Copy the parent.
465 retv.reset( new LIB_SYMBOL( *parent.get() ) );
466
467 retv->m_name = m_name;
468 retv->SetLibId( m_libId );
469
470 // Now add the inherited part mandatory field (this) information.
471 for( int i = 0; i < MANDATORY_FIELDS; i++ )
472 {
473 wxString tmp = GetFieldById( i )->GetText();
474
475 // If the field isn't defined then inherit the parent field value.
476 if( tmp.IsEmpty() )
477 retv->GetFieldById( i )->SetText( parent->GetFieldById( i )->GetText() );
478 else
479 *retv->GetFieldById( i ) = *GetFieldById( i );
480 }
481
482 // Grab all the rest of derived symbol fields.
483 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
484 {
485 const LIB_FIELD* aliasField = dynamic_cast<const LIB_FIELD*>( &item );
486
487 wxCHECK2( aliasField, continue );
488
489 // Mandatory fields were already resolved.
490 if( aliasField->IsMandatory() )
491 continue;
492
493 LIB_FIELD* newField = new LIB_FIELD( *aliasField );
494 newField->SetParent( retv.get() );
495
496 LIB_FIELD* parentField = retv->FindField( aliasField->GetName() );
497
498 if( !parentField ) // Derived symbol field does not exist in parent symbol.
499 {
500 retv->AddDrawItem( newField );
501 }
502 else // Derived symbol field overrides the parent symbol field.
503 {
504 retv->RemoveDrawItem( parentField );
505 retv->AddDrawItem( newField );
506 }
507 }
508
509 retv->SetKeyWords( m_keyWords.IsEmpty() ? parent->GetKeyWords() : m_keyWords );
510 retv->SetDescription( m_description.IsEmpty() ? parent->GetDescription() : m_description );
511 retv->SetFPFilters( m_fpFilters.IsEmpty() ? parent->GetFPFilters() : m_fpFilters );
512 retv->UpdateFieldOrdinals();
513 }
514 else
515 {
516 retv.reset( new LIB_SYMBOL( *this ) );
517 }
518
519 return retv;
520}
521
522
524{
525 for( LIB_ITEM& item : m_drawings )
526 {
527 if( EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( &item ) )
528 {
529 eda_text->ClearBoundingBoxCache();
530 eda_text->ClearRenderCache();
531 }
532 }
533}
534
535
536const wxString LIB_SYMBOL::GetLibraryName() const
537{
538 if( m_library )
539 return m_library->GetName();
540
541 return m_libId.GetLibNickname();
542}
543
544
546{
547 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
548 return parent->m_options == ENTRY_POWER;
549
550 return m_options == ENTRY_POWER;
551}
552
553
555{
556 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
557 parent->m_options = ENTRY_POWER;
558
560}
561
562
564{
565 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
566 return parent->m_options == ENTRY_NORMAL;
567
568 return m_options == ENTRY_NORMAL;
569}
570
571
573{
574 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
575 parent->m_options = ENTRY_NORMAL;
576
578}
579
580
581wxString LIB_SYMBOL::SubReference( int aUnit, bool aAddSeparator )
582{
583 wxString subRef;
584
585 if( aUnit < 1 )
586 return subRef;
587
588 if( m_subpartIdSeparator != 0 && aAddSeparator )
589 subRef << wxChar( m_subpartIdSeparator );
590
591 if( m_subpartFirstId >= '0' && m_subpartFirstId <= '9' )
592 {
593 subRef << aUnit;
594 }
595 else
596 {
597 // use letters as notation. To allow more than 26 units, the sub ref
598 // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
599 // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
600 int u;
601 wxString suffix;
602
603 do
604 {
605 u = ( aUnit - 1 ) % 26;
606 suffix = wxChar( m_subpartFirstId + u ) + suffix;
607 aUnit = ( aUnit - u ) / 26;
608 } while( aUnit > 0 );
609
610 subRef << suffix;
611 }
612
613 return subRef;
614}
615
616
617void LIB_SYMBOL::PrintBackground( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
618 int aUnit, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts, bool aDimmed )
619{
620 /* draw background for filled items using background option
621 * Solid lines will be drawn after the background
622 * Note also, background is not drawn when printing in black and white
623 */
625 {
626 for( LIB_ITEM& item : m_drawings )
627 {
628 // Do not print private items
629 if( item.IsPrivate() )
630 continue;
631
632 if( item.Type() == LIB_SHAPE_T )
633 {
634 LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
635
636 // Do not draw items not attached to the current part
637 if( aUnit && shape.m_unit && ( shape.m_unit != aUnit ) )
638 continue;
639
640 if( aConvert && shape.m_convert && ( shape.m_convert != aConvert ) )
641 continue;
642
644 shape.Print( aSettings, aOffset, (void*) false, aOpts.transform, aDimmed );
645 }
646 }
647 }
648}
649
650
651void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset, int aUnit,
652 int aConvert, const LIB_SYMBOL_OPTIONS& aOpts, bool aDimmed )
653{
654
655 for( LIB_ITEM& item : m_drawings )
656 {
657 // Do not print private items
658 if( item.IsPrivate() )
659 continue;
660
661 // Do not draw items not attached to the current part
662 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
663 continue;
664
665 if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
666 continue;
667
668 if( item.Type() == LIB_FIELD_T )
669 {
670 LIB_FIELD& field = static_cast<LIB_FIELD&>( item );
671
672 if( field.IsVisible() && !aOpts.draw_visible_fields )
673 continue;
674
675 if( !field.IsVisible() && !aOpts.draw_hidden_fields )
676 continue;
677 }
678
679 if( item.Type() == LIB_PIN_T )
680 {
681 item.Print( aSettings, aOffset, (void*) &aOpts, aOpts.transform, aDimmed );
682 }
683 else if( item.Type() == LIB_FIELD_T )
684 {
685 item.Print( aSettings, aOffset, nullptr, aOpts.transform, aDimmed );
686 }
687 else if( item.Type() == LIB_SHAPE_T )
688 {
689 LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
690 bool forceNoFill = shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR;
691
692 shape.Print( aSettings, aOffset, (void*) forceNoFill, aOpts.transform, aDimmed );
693 }
694 else
695 {
696 item.Print( aSettings, aOffset, (void*) false, aOpts.transform, aDimmed );
697 }
698 }
699}
700
701
702void LIB_SYMBOL::Plot( PLOTTER *aPlotter, int aUnit, int aConvert, bool aBackground,
703 const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed ) const
704{
705 wxASSERT( aPlotter != nullptr );
706
708 COLOR4D bg = aPlotter->RenderSettings()->GetBackgroundColor();
709
710 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
711 bg = COLOR4D::WHITE;
712
713 if( aDimmed )
714 {
715 color.Desaturate( );
716 color = color.Mix( bg, 0.5f );
717 }
718 aPlotter->SetColor( color );
719
720 for( const LIB_ITEM& item : m_drawings )
721 {
722 // Do not plot private items
723 if( item.IsPrivate() )
724 continue;
725
726 // LIB_FIELDs are not plotted here, because this plot function is used to plot schematic
727 // items which have their own SCH_FIELDs
728 if( item.Type() == LIB_FIELD_T )
729 continue;
730
731 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
732 continue;
733
734 if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
735 continue;
736
737 item.Plot( aPlotter, aBackground, aOffset, aTransform, aDimmed );
738 }
739}
740
741
742void LIB_SYMBOL::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert, bool aBackground,
743 const VECTOR2I& aOffset, const TRANSFORM& aTransform, bool aDimmed,
744 bool aPlotHidden )
745{
746 wxASSERT( aPlotter != nullptr );
747
749 COLOR4D bg = aPlotter->RenderSettings()->GetBackgroundColor();
750
751 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
752 bg = COLOR4D::WHITE;
753
754 if( aDimmed )
755 {
756 color.Desaturate( );
757 color = color.Mix( bg, 0.5f );
758 }
759
760 aPlotter->SetColor( color );
761
762 for( LIB_ITEM& item : m_drawings )
763 {
764 if( item.Type() != LIB_FIELD_T )
765 continue;
766
767 if( !aPlotHidden && !( (LIB_FIELD&) item ).IsVisible() )
768 continue;
769
770 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
771 continue;
772
773 if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
774 continue;
775
776 LIB_FIELD& field = (LIB_FIELD&) item;
777
778 // The reference is a special case: we should change the basic text
779 // to add '?' and the part id
780 wxString tmp = field.GetShownText();
781
782 if( field.GetId() == REFERENCE_FIELD )
783 {
784 wxString text = field.GetFullText( aUnit );
785 field.SetText( text );
786 }
787
788 item.Plot( aPlotter, aBackground, aOffset, aTransform, aDimmed );
789 field.SetText( tmp );
790 }
791}
792
793
795{
796 wxASSERT( aItem != nullptr );
797
798 // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
799 // omitted when saving to disk.
800 if( aItem->Type() == LIB_FIELD_T )
801 {
802 if( static_cast<LIB_FIELD*>( aItem )->IsMandatory() )
803 return;
804 }
805
806 LIB_ITEMS& items = m_drawings[ aItem->Type() ];
807
808 for( LIB_ITEMS::iterator i = items.begin(); i != items.end(); i++ )
809 {
810 if( &*i == aItem )
811 {
812 items.erase( i );
813 SetModified();
814 break;
815 }
816 }
817}
818
819
820void LIB_SYMBOL::AddDrawItem( LIB_ITEM* aItem, bool aSort )
821{
822 wxCHECK( aItem, /* void */ );
823
824 m_drawings.push_back( aItem );
825
826 if( aSort )
828}
829
830
831void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
832{
833 /* Notes:
834 * when aUnit == 0: no unit filtering
835 * when aConvert == 0: no convert (shape selection) filtering
836 * when m_unit == 0, the body item is common to units
837 * when m_convert == 0, the body item is common to shapes
838 */
839
840 LIB_SYMBOL_SPTR parent = m_parent.lock();
841 const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
842
843 for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
844 {
845 // Unit filtering:
846 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
847 continue;
848
849 // Shape filtering:
850 if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
851 continue;
852
853 aList.push_back( (LIB_PIN*) &item );
854 }
855}
856
857
858std::vector<LIB_PIN*> LIB_SYMBOL::GetAllLibPins() const
859{
860 std::vector<LIB_PIN*> pinList;
861
862 GetPins( pinList, 0, 0 );
863 return pinList;
864}
865
866
867
868LIB_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aConvert ) const
869{
870 LIB_PINS pinList;
871
872 GetPins( pinList, aUnit, aConvert );
873
874 for( LIB_PIN* pin : pinList )
875 {
876 wxASSERT( pin->Type() == LIB_PIN_T );
877
878 if( aNumber == pin->GetNumber() )
879 return pin;
880 }
881
882 return nullptr;
883}
884
885
886bool LIB_SYMBOL::PinsConflictWith( const LIB_SYMBOL& aOtherPart, bool aTestNums, bool aTestNames,
887 bool aTestType, bool aTestOrientation, bool aTestLength ) const
888{
889 LIB_PINS thisPinList;
890 GetPins( thisPinList, /* aUnit */ 0, /* aConvert */ 0 );
891
892 for( const LIB_PIN* eachThisPin : thisPinList )
893 {
894 wxASSERT( eachThisPin );
895 LIB_PINS otherPinList;
896 aOtherPart.GetPins( otherPinList, /* aUnit */ 0, /* aConvert */ 0 );
897 bool foundMatch = false;
898
899 for( const LIB_PIN* eachOtherPin : otherPinList )
900 {
901 wxASSERT( eachOtherPin );
902
903 // Same unit?
904 if( eachThisPin->GetUnit() != eachOtherPin->GetUnit() )
905 continue;
906
907 // Same body stype?
908 if( eachThisPin->GetConvert() != eachOtherPin->GetConvert() )
909 continue;
910
911 // Same position?
912 if( eachThisPin->GetPosition() != eachOtherPin->GetPosition() )
913 continue;
914
915 // Same number?
916 if( aTestNums && ( eachThisPin->GetNumber() != eachOtherPin->GetNumber() ) )
917 continue;
918
919 // Same name?
920 if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ) )
921 continue;
922
923 // Same electrical type?
924 if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ) )
925 continue;
926
927 // Same orientation?
928 if( aTestOrientation
929 && ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ) )
930 continue;
931
932 // Same length?
933 if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ) )
934 continue;
935
936 foundMatch = true;
937 break; // Match found so search is complete.
938 }
939
940 if( !foundMatch )
941 {
942 // This means there was not an identical (according to the arguments)
943 // pin at the same position in the other symbol.
944 return true;
945 }
946 }
947
948 // The loop never gave up, so no conflicts were found.
949 return false;
950}
951
952
953const BOX2I LIB_SYMBOL::GetUnitBoundingBox( int aUnit, int aConvert,
954 bool aIgnoreHiddenFields ) const
955{
956 BOX2I bBox; // Start with a fresh BOX2I so the Merge algorithm works
957
958 for( const LIB_ITEM& item : m_drawings )
959 {
960 if( item.m_unit > 0
961 && m_unitCount > 1
962 && aUnit > 0
963 && aUnit != item.m_unit )
964 {
965 continue;
966 }
967
968 if( item.m_convert > 0 && aConvert > 0 && aConvert != item.m_convert )
969 continue;
970
971 if( aIgnoreHiddenFields && ( item.Type() == LIB_FIELD_T )
972 && !( (LIB_FIELD&) item ).IsVisible() )
973 continue;
974
975 bBox.Merge( item.GetBoundingBox() );
976 }
977
978 return bBox;
979}
980
981
982void LIB_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
983{
984 aCount = 6;
985 aLayers[0] = LAYER_DEVICE;
986 aLayers[1] = LAYER_DEVICE_BACKGROUND;
987 aLayers[2] = LAYER_REFERENCEPART;
988 aLayers[3] = LAYER_VALUEPART;
989 aLayers[4] = LAYER_FIELDS;
990 aLayers[5] = LAYER_SELECTION_SHADOWS;
991}
992
993
994const BOX2I LIB_SYMBOL::GetBodyBoundingBox( int aUnit, int aConvert, bool aIncludePins,
995 bool aIncludePrivateItems ) const
996{
997 BOX2I bbox;
998
999 for( const LIB_ITEM& item : m_drawings )
1000 {
1001 if( item.m_unit > 0 && aUnit > 0 && aUnit != item.m_unit )
1002 continue;
1003
1004 if( item.m_convert > 0 && aConvert > 0 && aConvert != item.m_convert )
1005 continue;
1006
1007 if( item.IsPrivate() && !aIncludePrivateItems )
1008 continue;
1009
1010 if( item.Type() == LIB_FIELD_T )
1011 continue;
1012
1013 if( item.Type() == LIB_PIN_T )
1014 {
1015 const LIB_PIN& pin = static_cast<const LIB_PIN&>( item );
1016
1017 if( pin.IsVisible() )
1018 {
1019 // Note: the roots of the pins are always included for symbols that don't have
1020 // a well-defined body.
1021
1022 if( aIncludePins )
1023 bbox.Merge( pin.GetBoundingBox( false, false, false ) );
1024 else
1025 bbox.Merge( pin.GetPinRoot() );
1026 }
1027 }
1028 else
1029 {
1030 bbox.Merge( item.GetBoundingBox() );
1031 }
1032 }
1033
1034 return bbox;
1035}
1036
1037
1039{
1041}
1042
1043
1045{
1046 AddDrawItem( aField );
1047}
1048
1049
1050void LIB_SYMBOL::SetFields( const std::vector<LIB_FIELD>& aFields )
1051{
1053
1054 for( size_t ii = 0; ii < aFields.size(); ++ii )
1055 {
1056 // drawings is a ptr_vector, new and copy an object on the heap.
1057 LIB_FIELD* field = new LIB_FIELD( aFields[ ii ] );
1058
1059 field->SetParent( this );
1060 m_drawings.push_back( field );
1061 }
1062
1063 m_drawings.sort();
1064}
1065
1066
1067void LIB_SYMBOL::GetFields( std::vector<LIB_FIELD*>& aList )
1068{
1069 // Grab the MANDATORY_FIELDS first, in expected order given by enum MANDATORY_FIELD_T
1070 for( int id = 0; id < MANDATORY_FIELDS; ++id )
1071 aList.push_back( GetFieldById( id ) );
1072
1073 // Now grab all the rest of fields.
1074 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1075 {
1076 LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
1077
1078 if( !field->IsMandatory() )
1079 aList.push_back( field );
1080 }
1081}
1082
1083
1084void LIB_SYMBOL::GetFields( std::vector<LIB_FIELD>& aList )
1085{
1086 // Grab the MANDATORY_FIELDS first, in expected order given by enum MANDATORY_FIELD_T
1087 for( int id = 0; id < MANDATORY_FIELDS; ++id )
1088 aList.push_back( *GetFieldById( id ) );
1089
1090 // Now grab all the rest of fields.
1091 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1092 {
1093 LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
1094
1095 if( !field->IsMandatory() )
1096 aList.push_back( *field );
1097 }
1098}
1099
1100
1102{
1103 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1104 {
1105 LIB_FIELD* field = ( LIB_FIELD* ) &item;
1106
1107 if( field->GetId() == aId )
1108 return field;
1109 }
1110
1111 return nullptr;
1112}
1113
1114
1115LIB_FIELD* LIB_SYMBOL::FindField( const wxString& aFieldName )
1116{
1117 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1118 {
1119 if( static_cast<LIB_FIELD*>( &item )->GetCanonicalName() == aFieldName )
1120 return static_cast<LIB_FIELD*>( &item );
1121 }
1122
1123 return nullptr;
1124}
1125
1126
1127const LIB_FIELD* LIB_SYMBOL::FindField( const wxString& aFieldName ) const
1128{
1129 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1130 {
1131 if( static_cast<const LIB_FIELD*>( &item )->GetCanonicalName() == aFieldName )
1132 return static_cast<const LIB_FIELD*>( &item );
1133 }
1134
1135 return nullptr;
1136}
1137
1138
1140{
1142 wxASSERT( field != nullptr );
1143 return *field;
1144}
1145
1146
1148{
1150 wxASSERT( field != nullptr );
1151 return *field;
1152}
1153
1154
1156{
1158 wxASSERT( field != nullptr );
1159 return *field;
1160}
1161
1162
1164{
1166 wxASSERT( field != nullptr );
1167 return *field;
1168}
1169
1170
1172{
1173 wxString refDesignator = GetFieldById( REFERENCE_FIELD )->GetText();
1174
1175 refDesignator.Replace( wxS( "~" ), wxS( " " ) );
1176
1177 wxString prefix = refDesignator;
1178
1179 while( prefix.Length() )
1180 {
1181 wxUniCharRef last = prefix.Last();
1182
1183 if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
1184 prefix.RemoveLast();
1185 else
1186 break;
1187 }
1188
1189 // Avoid a prefix containing trailing/leading spaces
1190 prefix.Trim( true );
1191 prefix.Trim( false );
1192
1193 return prefix;
1194}
1195
1196
1198{
1199 int retv = 0;
1200 int lastOrdinal = MANDATORY_FIELDS;
1201
1202 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1203 {
1204 LIB_FIELD* field = dynamic_cast<LIB_FIELD*>( &item );
1205
1206 wxCHECK2( field, continue );
1207
1208 // Mandatory fields were already resolved always have the same ordinal values.
1209 if( field->IsMandatory() )
1210 continue;
1211
1212 if( field->GetId() != lastOrdinal )
1213 {
1214 field->SetId( lastOrdinal );
1215 retv += 1;
1216 }
1217
1218 lastOrdinal += 1;
1219 }
1220
1221 return retv;
1222}
1223
1224
1226{
1227 int retv = MANDATORY_FIELDS;
1228
1229 while( GetFieldById( retv ) )
1230 retv += 1;
1231
1232 return retv;
1233}
1234
1235
1236void LIB_SYMBOL::SetOffset( const VECTOR2I& aOffset )
1237{
1238 for( LIB_ITEM& item : m_drawings )
1239 item.Offset( aOffset );
1240}
1241
1242
1244{
1246}
1247
1248
1250{
1251 for( const LIB_ITEM& item : m_drawings )
1252 {
1253 if( item.m_convert > LIB_ITEM::LIB_CONVERT::BASE )
1254 return true;
1255 }
1256
1257 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1258 {
1259 for( const LIB_ITEM& item : parent->GetDrawItems() )
1260 {
1261 if( item.m_convert > LIB_ITEM::LIB_CONVERT::BASE )
1262 return true;
1263 }
1264 }
1265
1266 return false;
1267}
1268
1270{
1271 int maxPinNumber = 0;
1272 LIB_SYMBOL_SPTR parent = m_parent.lock();
1273 const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
1274
1275 for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
1276 {
1277 const LIB_PIN* pin = static_cast<const LIB_PIN*>( &item );
1278 long currentPinNumber = 0;
1279 bool isNum = pin->GetNumber().ToLong( &currentPinNumber );
1280
1281 if( isNum && currentPinNumber > maxPinNumber )
1282 {
1283 maxPinNumber = currentPinNumber;
1284 }
1285 }
1286
1287 return maxPinNumber;
1288}
1289
1290
1292{
1293 for( LIB_ITEM& item : m_drawings )
1294 item.ClearTempFlags();
1295}
1296
1297
1299{
1300 for( LIB_ITEM& item : m_drawings )
1301 item.ClearEditFlags();
1302}
1303
1304
1305LIB_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
1306 const VECTOR2I& aPoint )
1307{
1308 for( LIB_ITEM& item : m_drawings )
1309 {
1310 if( ( aUnit && item.m_unit && aUnit != item.m_unit )
1311 || ( aConvert && item.m_convert && aConvert != item.m_convert )
1312 || ( item.Type() != aType && aType != TYPE_NOT_INIT ) )
1313 {
1314 continue;
1315 }
1316
1317 if( item.HitTest( aPoint ) )
1318 return &item;
1319 }
1320
1321 return nullptr;
1322}
1323
1324
1325LIB_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
1326 const VECTOR2I& aPoint, const TRANSFORM& aTransform )
1327{
1328 /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
1329 * VECTOR2I& pt ) to search items.
1330 * because this function uses DefaultTransform as orient/mirror matrix
1331 * we temporary copy aTransform in DefaultTransform
1332 */
1333 LIB_ITEM* item;
1334 TRANSFORM transform = DefaultTransform;
1335 DefaultTransform = aTransform;
1336
1337 item = LocateDrawItem( aUnit, aConvert, aType, aPoint );
1338
1339 // Restore matrix
1340 DefaultTransform = transform;
1341
1342 return item;
1343}
1344
1345
1346INSPECT_RESULT LIB_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
1347 const std::vector<KICAD_T>& aScanTypes )
1348{
1349 // The part itself is never inspected, only its children
1350 for( LIB_ITEM& item : m_drawings )
1351 {
1352 if( item.IsType( aScanTypes ) )
1353 {
1354 if( aInspector( &item, aTestData ) == INSPECT_RESULT::QUIT )
1355 return INSPECT_RESULT::QUIT;
1356 }
1357 }
1358
1360}
1361
1362
1363void LIB_SYMBOL::SetUnitCount( int aCount, bool aDuplicateDrawItems )
1364{
1365 if( m_unitCount == aCount )
1366 return;
1367
1368 if( aCount < m_unitCount )
1369 {
1371
1372 while( i != m_drawings.end() )
1373 {
1374 if( i->m_unit > aCount )
1375 i = m_drawings.erase( i );
1376 else
1377 ++i;
1378 }
1379 }
1380 else if( aDuplicateDrawItems )
1381 {
1382 int prevCount = m_unitCount;
1383
1384 // Temporary storage for new items, as adding new items directly to
1385 // m_drawings may cause the buffer reallocation which invalidates the
1386 // iterators
1387 std::vector< LIB_ITEM* > tmp;
1388
1389 for( LIB_ITEM& item : m_drawings )
1390 {
1391 if( item.m_unit != 1 )
1392 continue;
1393
1394 for( int j = prevCount + 1; j <= aCount; j++ )
1395 {
1396 LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1397 newItem->m_unit = j;
1398 tmp.push_back( newItem );
1399 }
1400 }
1401
1402 for( LIB_ITEM* item : tmp )
1403 m_drawings.push_back( item );
1404 }
1405
1406 m_drawings.sort();
1407 m_unitCount = aCount;
1408}
1409
1410
1412{
1413 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1414 return parent->GetUnitCount();
1415
1416 return m_unitCount;
1417}
1418
1419
1420void LIB_SYMBOL::SetConversion( bool aSetConvert, bool aDuplicatePins )
1421{
1422 if( aSetConvert == HasConversion() )
1423 return;
1424
1425 // Duplicate items to create the converted shape
1426 if( aSetConvert )
1427 {
1428 if( aDuplicatePins )
1429 {
1430 std::vector< LIB_ITEM* > tmp; // Temporarily store the duplicated pins here.
1431
1432 for( LIB_ITEM& item : m_drawings )
1433 {
1434 // Only pins are duplicated.
1435 if( item.Type() != LIB_PIN_T )
1436 continue;
1437
1438 if( item.m_convert == 1 )
1439 {
1440 LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1441 newItem->m_convert = 2;
1442 tmp.push_back( newItem );
1443 }
1444 }
1445
1446 // Transfer the new pins to the LIB_SYMBOL.
1447 for( unsigned i = 0; i < tmp.size(); i++ )
1448 m_drawings.push_back( tmp[i] );
1449 }
1450 }
1451 else
1452 {
1453 // Delete converted shape items because the converted shape does
1454 // not exist
1456
1457 while( i != m_drawings.end() )
1458 {
1459 if( i->m_convert > 1 )
1460 i = m_drawings.erase( i );
1461 else
1462 ++i;
1463 }
1464 }
1465
1466 m_drawings.sort();
1467}
1468
1469
1470void LIB_SYMBOL::SetSubpartIdNotation( int aSep, int aFirstId )
1471{
1472 m_subpartFirstId = 'A';
1474
1475 if( aSep == '.' || aSep == '-' || aSep == '_' )
1476 m_subpartIdSeparator = aSep;
1477
1478 if( aFirstId == '1' && aSep != 0 )
1479 m_subpartFirstId = aFirstId;
1480}
1481
1482
1483std::vector<LIB_ITEM*> LIB_SYMBOL::GetUnitDrawItems( int aUnit, int aConvert )
1484{
1485 std::vector<LIB_ITEM*> unitItems;
1486
1487 for( LIB_ITEM& item : m_drawings )
1488 {
1489 if( item.Type() == LIB_FIELD_T )
1490 continue;
1491
1492 if( ( aConvert == -1 && item.GetUnit() == aUnit )
1493 || ( aUnit == -1 && item.GetConvert() == aConvert )
1494 || ( aUnit == item.GetUnit() && aConvert == item.GetConvert() ) )
1495 {
1496 unitItems.push_back( &item );
1497 }
1498 }
1499
1500 return unitItems;
1501}
1502
1503
1504std::vector<struct LIB_SYMBOL_UNIT> LIB_SYMBOL::GetUnitDrawItems()
1505{
1506 std::vector<struct LIB_SYMBOL_UNIT> units;
1507
1508 for( LIB_ITEM& item : m_drawings )
1509 {
1510 if( item.Type() == LIB_FIELD_T )
1511 continue;
1512
1513 int unit = item.GetUnit();
1514 int convert = item.GetConvert();
1515
1516 auto it = std::find_if( units.begin(), units.end(),
1517 [unit, convert]( const LIB_SYMBOL_UNIT& a )
1518 {
1519 return a.m_unit == unit && a.m_convert == convert;
1520 } );
1521
1522 if( it == units.end() )
1523 {
1524 struct LIB_SYMBOL_UNIT newUnit;
1525 newUnit.m_unit = item.GetUnit();
1526 newUnit.m_convert = item.GetConvert();
1527 newUnit.m_items.push_back( &item );
1528 units.emplace_back( newUnit );
1529 }
1530 else
1531 {
1532 it->m_items.push_back( &item );
1533 }
1534 }
1535
1536 return units;
1537}
1538
1539
1540std::vector<struct LIB_SYMBOL_UNIT> LIB_SYMBOL::GetUniqueUnits()
1541{
1542 int unitNum;
1543 size_t i;
1544 struct LIB_SYMBOL_UNIT unit;
1545 std::vector<LIB_ITEM*> compareDrawItems;
1546 std::vector<LIB_ITEM*> currentDrawItems;
1547 std::vector<struct LIB_SYMBOL_UNIT> uniqueUnits;
1548
1549 // The first unit is guaranteed to be unique so always include it.
1550 unit.m_unit = 1;
1551 unit.m_convert = 1;
1552 unit.m_items = GetUnitDrawItems( 1, 1 );
1553
1554 // There are no unique units if there are no draw items other than fields.
1555 if( unit.m_items.size() == 0 )
1556 return uniqueUnits;
1557
1558 uniqueUnits.emplace_back( unit );
1559
1560 if( ( GetUnitCount() == 1 || UnitsLocked() ) && !HasConversion() )
1561 return uniqueUnits;
1562
1563 currentDrawItems = unit.m_items;
1564
1565 for( unitNum = 2; unitNum <= GetUnitCount(); unitNum++ )
1566 {
1567 compareDrawItems = GetUnitDrawItems( unitNum, 1 );
1568
1569 wxCHECK2_MSG( compareDrawItems.size() != 0, continue,
1570 "Multiple unit symbol defined with empty units." );
1571
1572 if( currentDrawItems.size() != compareDrawItems.size() )
1573 {
1574 unit.m_unit = unitNum;
1575 unit.m_convert = 1;
1576 unit.m_items = compareDrawItems;
1577 uniqueUnits.emplace_back( unit );
1578 }
1579 else
1580 {
1581 for( i = 0; i < currentDrawItems.size(); i++ )
1582 {
1583 if( currentDrawItems[i]->compare( *compareDrawItems[i],
1584 LIB_ITEM::COMPARE_FLAGS::UNIT ) != 0 )
1585 {
1586 unit.m_unit = unitNum;
1587 unit.m_convert = 1;
1588 unit.m_items = compareDrawItems;
1589 uniqueUnits.emplace_back( unit );
1590 }
1591 }
1592 }
1593 }
1594
1595 if( HasConversion() )
1596 {
1597 currentDrawItems = GetUnitDrawItems( 1, 2 );
1598
1599 if( ( GetUnitCount() == 1 || UnitsLocked() ) )
1600 {
1601 unit.m_unit = 1;
1602 unit.m_convert = 2;
1603 unit.m_items = currentDrawItems;
1604 uniqueUnits.emplace_back( unit );
1605
1606 return uniqueUnits;
1607 }
1608
1609 for( unitNum = 2; unitNum <= GetUnitCount(); unitNum++ )
1610 {
1611 compareDrawItems = GetUnitDrawItems( unitNum, 2 );
1612
1613 wxCHECK2_MSG( compareDrawItems.size() != 0, continue,
1614 "Multiple unit symbol defined with empty units." );
1615
1616 if( currentDrawItems.size() != compareDrawItems.size() )
1617 {
1618 unit.m_unit = unitNum;
1619 unit.m_convert = 2;
1620 unit.m_items = compareDrawItems;
1621 uniqueUnits.emplace_back( unit );
1622 }
1623 else
1624 {
1625 for( i = 0; i < currentDrawItems.size(); i++ )
1626 {
1627 if( currentDrawItems[i]->compare( *compareDrawItems[i],
1628 LIB_ITEM::COMPARE_FLAGS::UNIT ) != 0 )
1629 {
1630 unit.m_unit = unitNum;
1631 unit.m_convert = 2;
1632 unit.m_items = compareDrawItems;
1633 uniqueUnits.emplace_back( unit );
1634 }
1635 }
1636 }
1637 }
1638 }
1639
1640 return uniqueUnits;
1641}
int color
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
void SetModified()
Definition: eda_item.cpp:64
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void ClearSelected()
Definition: eda_item.h:118
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:82
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:142
FILL_T GetFillMode() const
Definition: eda_shape.h:101
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:87
virtual bool IsVisible() const
Definition: eda_text.h:136
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:165
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:102
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.
virtual const COLOR4D & GetBackgroundColor() const =0
Return current background color settings.
Field object used in symbol libraries.
Definition: lib_field.h:61
bool ShowInChooser() const
Definition: lib_field.h:186
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_field.cpp:327
void SetId(int aId)
Definition: lib_field.cpp:108
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: lib_field.cpp:397
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: lib_field.cpp:476
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: lib_field.cpp:425
bool IsMandatory() const
Definition: lib_field.cpp:580
int GetId() const
Definition: lib_field.h:114
wxString GetShownText(int aDepth=0, bool aAllowExtraText=true) const override
Return the string actually shown after processing of the base text.
Definition: lib_field.cpp:414
int compare(const LIB_ITEM &aOther, int aCompareFlags=0) const override
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_field.cpp:222
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:109
int compare(const LIB_ID &aLibId) const
Compare the contents of LIB_ID objects by performing a std::string comparison of the library nickname...
Definition: lib_id.cpp:159
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:61
int m_convert
Shape identification for alternate body styles.
Definition: lib_item.h:333
virtual int compare(const LIB_ITEM &aOther, int aCompareFlags=0) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:74
virtual void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, void *aData, const TRANSFORM &aTransform, bool aDimmed)
Draw an item.
Definition: lib_item.cpp:136
int m_unit
Unit identification for multiple parts per package.
Definition: lib_item.h:327
Define a library symbol object.
Definition: lib_symbol.h:99
LIB_ITEMS_CONTAINER m_drawings
Definition: lib_symbol.h:744
void Plot(PLOTTER *aPlotter, int aUnit, int aConvert, bool aBackground, const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed) const
Plot lib symbol to plotter.
Definition: lib_symbol.cpp:702
void PrintBackground(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS &aOpts, bool aDimmed)
Print just the background fills of a symbol.
Definition: lib_symbol.cpp:617
void ClearTempFlags()
Clears the status flag all draw objects in this symbol.
LIBRENTRYOPTIONS m_options
Special symbol features such as POWER or NORMAL.)
Definition: lib_symbol.h:742
void RemoveDrawItem(LIB_ITEM *aItem)
Remove draw aItem from list.
Definition: lib_symbol.cpp:794
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.
Definition: lib_symbol.cpp:886
wxString GetPrefix()
wxString GetKeyWords() const
Definition: lib_symbol.h:164
void SetConversion(bool aSetConvert, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
static int m_subpartFirstId
the ASCII char value to calculate the subpart symbol id from the symbol number: only 'A',...
Definition: lib_symbol.h:756
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:258
int GetNextAvailableFieldId() const
std::map< int, wxString > m_unitDisplayNames
Definition: lib_symbol.h:759
SYMBOL_LIB * m_library
Definition: lib_symbol.h:746
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:399
const wxString GetLibraryName() const
Definition: lib_symbol.cpp:536
LIB_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
bool IsAlias() const
Definition: lib_symbol.h:188
std::vector< struct LIB_SYMBOL_UNIT > GetUnitDrawItems()
Return a list of LIB_ITEM objects separated by unit and convert number.
int GetMaxPinNumber() const
LIB_SYMBOL(const wxString &aName, LIB_SYMBOL *aParent=nullptr, SYMBOL_LIB *aLibrary=nullptr)
Definition: lib_symbol.cpp:101
LIB_SYMBOL_SPTR m_me
Definition: lib_symbol.h:725
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: lib_symbol.cpp:982
bool IsPower() const
Definition: lib_symbol.cpp:545
wxString m_name
Definition: lib_symbol.h:747
void SetPower()
Definition: lib_symbol.cpp:554
wxString m_keyWords
Search keywords.
Definition: lib_symbol.h:749
bool m_includeInBom
Definition: lib_symbol.h:740
LIB_FIELD & GetFootprintField()
Return reference to the footprint field.
void RemoveDuplicateDrawItems()
Remove duplicate draw items from list.
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:444
wxString GetName() const override
Definition: lib_symbol.h:138
static int m_subpartIdSeparator
the separator char between the subpart id and the reference like U1A ( m_subpartIdSeparator = 0 ) or ...
Definition: lib_symbol.h:753
void ClearEditFlags()
int m_pinNameOffset
The offset in mils to draw the pin name.
Definition: lib_symbol.h:735
bool m_showPinNumbers
Definition: lib_symbol.h:738
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:820
LIB_FIELD * FindField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
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...
Definition: lib_symbol.cpp:74
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:581
void PlotLibFields(PLOTTER *aPlotter, int aUnit, int aConvert, bool aBackground, const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed, bool aPlotHidden=true)
Plot Lib Fields only of the symbol to plotter.
Definition: lib_symbol.cpp:742
timestamp_t m_lastModDate
Definition: lib_symbol.h:729
bool m_includeOnBoard
Definition: lib_symbol.h:741
LIB_ID m_libId
Definition: lib_symbol.h:727
void SetLib(SYMBOL_LIB *aLibrary)
Definition: lib_symbol.h:193
wxString m_description
Definition: lib_symbol.h:748
std::vector< struct LIB_SYMBOL_UNIT > GetUniqueUnits()
Return a list of unit numbers that are unique to this symbol.
const BOX2I GetBodyBoundingBox(int aUnit, int aConvert, bool aIncludePins, bool aIncludePrivateItems) const
Get the symbol bounding box excluding fields.
Definition: lib_symbol.cpp:994
static void SetSubpartIdNotation(int aSep, int aFirstId)
Set the separator char between the subpart id and the reference 0 (no separator) or '.
const LIB_SYMBOL & operator=(const LIB_SYMBOL &aSymbol)
Definition: lib_symbol.cpp:184
LIB_FIELD & GetValueField()
Return reference to the value field.
bool m_unitsLocked
True if symbol has multiple units and changing one unit does not automatically change another unit.
Definition: lib_symbol.h:732
wxArrayString m_fpFilters
List of suitable footprint names for the symbol (wild card names accepted).
Definition: lib_symbol.h:750
bool HasUnitDisplayName(int aUnit) override
Return true if the given unit aUnit has a display name defined.
Definition: lib_symbol.cpp:393
bool IsNormal() const
Definition: lib_symbol.cpp:563
LIB_SYMBOL_SPTR SharedPtr() const
Definition: lib_symbol.h:110
LIB_ITEM * LocateDrawItem(int aUnit, int aConvert, KICAD_T aType, const VECTOR2I &aPoint)
Locate a draw object.
const BOX2I GetUnitBoundingBox(int aUnit, int aConvert, bool aIgnoreHiddenFields=true) const
Get the bounding box for the symbol.
Definition: lib_symbol.cpp:953
int UpdateFieldOrdinals()
Order optional field indices.
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...
wxString GetUnitReference(int aUnit) override
Return an identifier for aUnit for symbols with units.
Definition: lib_symbol.cpp:387
wxString GetDescription() override
Definition: lib_symbol.h:151
std::vector< LIB_PIN * > GetAllLibPins() const
Return a list of pin pointers for all units / converts.
Definition: lib_symbol.cpp:858
int m_unitCount
Number of units (parts) per package.
Definition: lib_symbol.h:731
void ClearCaches()
Definition: lib_symbol.cpp:523
int GetUnitCount() const override
For items with units, return the number of units.
void AddField(LIB_FIELD *aField)
Add a field.
LIB_SYMBOL_REF m_parent
Use for inherited symbols.
Definition: lib_symbol.h:726
void GetPins(LIB_PINS &aList, int aUnit=0, int aConvert=0) const
Return a list of pin object pointers from the draw item list.
Definition: lib_symbol.cpp:831
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:453
int Compare(const LIB_SYMBOL &aRhs, int aCompareFlags=0) const
Comparison test that can be used for operators.
Definition: lib_symbol.cpp:233
LIB_FIELD & GetDatasheetField()
Return reference to the datasheet field.
void deleteAllFields()
bool HasConversion() const
Test if symbol has more than one body conversion type (DeMorgan).
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS &aOpts, bool aDimmed)
Print symbol.
Definition: lib_symbol.cpp:651
LIB_PIN * GetPin(const wxString &aNumber, int aUnit=0, int aConvert=0) const
Return pin object with the requested pin aNumber.
Definition: lib_symbol.cpp:868
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
void SetUnitDisplayName(int aUnit, const wxString &aName)
Set the user-defined display name for aUnit to aName for symbols with units.
Definition: lib_symbol.cpp:421
void SetOffset(const VECTOR2I &aOffset)
Move the symbol aOffset.
wxString GetSearchText() override
Definition: lib_symbol.cpp:49
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:437
bool m_showPinNames
Definition: lib_symbol.h:737
void SetNormal()
Definition: lib_symbol.cpp:572
void CopyUnitDisplayNames(std::map< int, wxString > &aTarget) const
Copy all unit display names into the given map aTarget.
Definition: lib_symbol.cpp:412
size_t size(int aType=UNDEFINED_TYPE) const
Definition: multivector.h:225
void sort()
Definition: multivector.h:247
ITERATOR_BASE< const LIB_ITEM, const MULTIVECTOR< LIB_ITEM, FIRST_TYPE_VAL, LAST_TYPE_VAL >, typename ITEM_PTR_VECTOR::const_iterator > CONST_ITERATOR
Definition: multivector.h:167
void unique()
Remove duplicate elements in list.
Definition: multivector.h:256
void push_back(T *aItem)
Definition: multivector.h:174
ITERATOR_BASE< LIB_ITEM, MULTIVECTOR< LIB_ITEM, FIRST_TYPE_VAL, LAST_TYPE_VAL >, typename ITEM_PTR_VECTOR::iterator > ITERATOR
The const iterator.
Definition: multivector.h:164
ITERATOR end(int aType=UNDEFINED_TYPE)
Definition: multivector.h:194
void clear(int aType=UNDEFINED_TYPE)
Definition: multivector.h:212
ITERATOR erase(const ITERATOR &aIterator)
Definition: multivector.h:179
ITERATOR begin(int aType=UNDEFINED_TYPE)
Definition: multivector.h:188
Base plotter engine class.
Definition: plotter.h:110
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:141
bool GetColorMode() const
Definition: plotter.h:138
virtual void SetColor(const COLOR4D &color)=0
Object used to load, save, search, and otherwise manipulate symbol library files.
const wxString GetName() const
Return the file name without path or extension.
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:47
@ WHITE
Definition: color4d.h:46
#define DEFAULT_PIN_NAME_OFFSET
The intersheets references prefix string.
#define _(s)
INSPECT_RESULT
Definition: eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:78
#define IS_NEW
New item, just created.
#define STRUCT_DELETED
flag indication structures to be erased
@ FILLED_WITH_BG_BODYCOLOR
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
@ LAYER_DEVICE
Definition: layer_ids.h:357
@ LAYER_VALUEPART
Definition: layer_ids.h:353
@ LAYER_FIELDS
Definition: layer_ids.h:354
@ LAYER_DEVICE_BACKGROUND
Definition: layer_ids.h:372
@ LAYER_REFERENCEPART
Definition: layer_ids.h:352
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:381
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:54
bool operator<(const LIB_SYMBOL &aItem1, const LIB_SYMBOL &aItem2)
Definition: lib_symbol.cpp:86
@ ENTRY_NORMAL
Definition: lib_symbol.h:54
@ ENTRY_POWER
Definition: lib_symbol.h:55
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:45
LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS
Definition: lib_symbol.h:48
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
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:200
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< LIB_ITEM * > m_items
The items unique to this unit and alternate body style.
Definition: lib_symbol.h:88
int m_convert
The alternate body style of the unit.
Definition: lib_symbol.h:87
int m_unit
The unit number.
Definition: lib_symbol.h:86
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
Definition: lib_symbol.cpp:94
void operator()(void const *) const
Definition: lib_symbol.cpp:95
Definition for symbol library class.
@ 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 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
TRANSFORM DefaultTransform
Definition: transform.cpp:34
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ LIB_SYMBOL_T
Definition: typeinfo.h:198
@ TYPE_NOT_INIT
Definition: typeinfo.h:81
@ LIB_SHAPE_T
Definition: typeinfo.h:199
@ LIB_PIN_T
Definition: typeinfo.h:202
@ LIB_FIELD_T
Definition: typeinfo.h:208