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 (C) 2004-2023 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 <template_fieldnames.h>
32#include <transform.h>
33#include <symbol_library.h>
34#include <lib_pin.h>
36#include <lib_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( GetName(), 8 ) );
45
46 wxStringTokenizer keywordTokenizer( GetKeyWords(), wxS( " " ), wxTOKEN_STRTOK );
47
48 while( keywordTokenizer.HasMoreTokens() )
49 terms.emplace_back( SEARCH_TERM( keywordTokenizer.GetNextToken(), 4 ) );
50
51 // TODO(JE) rework this later so we can highlight matches in their column
52 std::map<wxString, wxString> fields;
53 GetChooserFields( fields );
54
55 for( const auto& [ name, text ] : fields )
56 terms.emplace_back( SEARCH_TERM( text, 4 ) );
57
58 // Also include keywords as one long string, just in case
59 terms.emplace_back( SEARCH_TERM( GetKeyWords(), 1 ) );
60 terms.emplace_back( SEARCH_TERM( GetDescription(), 1 ) );
61
62 wxString footprint = GetFootprintField().GetText();
63
64 if( !footprint.IsEmpty() )
65 terms.emplace_back( SEARCH_TERM( GetFootprintField().GetText(), 1 ) );
66
67 return terms;
68}
69
70
71void LIB_SYMBOL::GetChooserFields( std::map<wxString , wxString>& aColumnMap )
72{
73 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
74 {
75 LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
76
77 if( field->ShowInChooser() )
78 aColumnMap[field->GetName()] = field->EDA_TEXT::GetShownText( false );
79 }
80}
81
82
83bool operator<( const LIB_SYMBOL& aItem1, const LIB_SYMBOL& aItem2 )
84{
85 return aItem1.GetName() < aItem2.GetName();
86}
87
88
91{
92 void operator()(void const *) const
93 {
94 }
95};
96
97
98LIB_SYMBOL::LIB_SYMBOL( const wxString& aName, LIB_SYMBOL* aParent, SYMBOL_LIB* aLibrary ) :
100 m_me( this, null_deleter() ),
101 m_excludedFromSim( false ),
102 m_excludedFromBOM( false ),
103 m_excludedFromBoard( false )
104{
105 m_lastModDate = 0;
106 m_unitCount = 1;
109 m_unitsLocked = false;
110 m_showPinNumbers = true;
111 m_showPinNames = true;
112
113 // Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
114 // when the field editors are invoked.
116 for( int i = 0; i < MANDATORY_FIELDS; i++ )
117 m_drawings[LIB_FIELD_T].push_back( new LIB_FIELD( this, i ) );
118
119 SetName( aName );
120
121 if( aParent )
122 SetParent( aParent );
123
124 SetLib( aLibrary );
125}
126
127
128LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
129 EDA_ITEM( aSymbol ),
130 m_me( this, null_deleter() )
131{
132 LIB_ITEM* newItem;
133
134 m_library = aLibrary;
135 m_name = aSymbol.m_name;
136 m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
137 m_unitCount = aSymbol.m_unitCount;
146 m_options = aSymbol.m_options;
147 m_libId = aSymbol.m_libId;
148 m_keyWords = aSymbol.m_keyWords;
149
151
153
154 for( const LIB_ITEM& oldItem : aSymbol.m_drawings )
155 {
156 if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
157 continue;
158
159 try
160 {
161 newItem = (LIB_ITEM*) oldItem.Clone();
162 newItem->ClearSelected();
163 newItem->SetParent( this );
164 m_drawings.push_back( newItem );
165 }
166 catch( ... )
167 {
168 wxFAIL_MSG( "Failed to clone LIB_ITEM." );
169 return;
170 }
171 }
172
173 LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
174
175 if( parent )
176 SetParent( parent.get() );
177}
178
179
181{
182 if( &aSymbol == this )
183 return aSymbol;
184
185 LIB_ITEM* newItem;
186
187 m_library = aSymbol.m_library;
188 m_name = aSymbol.m_name;
189 m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
190 m_unitCount = aSymbol.m_unitCount;
199 m_options = aSymbol.m_options;
200 m_libId = aSymbol.m_libId;
201 m_keyWords = aSymbol.m_keyWords;
202
203 m_unitDisplayNames.clear();
205
207
208 for( const LIB_ITEM& oldItem : aSymbol.m_drawings )
209 {
210 if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
211 continue;
212
213 newItem = (LIB_ITEM*) oldItem.Clone();
214 newItem->SetParent( this );
215 m_drawings.push_back( newItem );
216 }
217
219
220 LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
221
222 if( parent )
223 SetParent( parent.get() );
224
225 return *this;
226}
227
228
230{
231 unsigned depth = 0;
232
233 LIB_SYMBOL_SPTR parent = GetParent().lock();
234
235 while( parent )
236 {
237 depth += 1;
238 parent = parent->GetParent().lock();
239 }
240
241 return depth;
242}
243
244
245#define REPORT( msg ) { if( aReporter ) aReporter->Report( msg ); }
246#define ITEM_DESC( item ) ( item )->GetItemDescription( &unitsProvider )
247
248int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs, int aCompareFlags, REPORTER* aReporter ) const
249{
250 UNITS_PROVIDER unitsProvider( schIUScale, EDA_UNITS::MILLIMETRES );
251
252 if( m_me == aRhs.m_me )
253 return 0;
254
255 if( !aReporter && ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
256 {
257 if( int tmp = m_name.Cmp( aRhs.m_name ) )
258 return tmp;
259
260 if( int tmp = m_libId.compare( aRhs.m_libId ) )
261 return tmp;
262
263 if( m_parent.lock() < aRhs.m_parent.lock() )
264 return -1;
265
266 if( m_parent.lock() > aRhs.m_parent.lock() )
267 return 1;
268 }
269
270 int retv = 0;
271
272 if( m_options != aRhs.m_options )
273 {
274 retv = ( m_options == ENTRY_NORMAL ) ? -1 : 1;
275 REPORT( _( "Power flag differs." ) );
276
277 if( !aReporter )
278 return retv;
279 }
280
281 if( int tmp = m_unitCount - aRhs.m_unitCount )
282 {
283 retv = tmp;
284 REPORT( _( "Unit count differs." ) );
285
286 if( !aReporter )
287 return retv;
288 }
289
290 // Make sure shapes and pins are sorted. No need with fields as those are
291 // matched by id/name.
292
293 std::set<const LIB_ITEM*, LIB_ITEM::cmp_items> aShapes;
294 std::set<const LIB_ITEM*> aFields;
295 std::set<const LIB_ITEM*, LIB_ITEM::cmp_items> aPins;
296
297 for( auto it = m_drawings.begin(); it != m_drawings.end(); ++it )
298 {
299 if( it->Type() == LIB_SHAPE_T )
300 aShapes.insert( &(*it) );
301 else if( it->Type() == LIB_FIELD_T )
302 aFields.insert( &(*it) );
303 else if( it->Type() == LIB_PIN_T )
304 aPins.insert( &(*it) );
305 }
306
307 std::set<const LIB_ITEM*, LIB_ITEM::cmp_items> bShapes;
308 std::set<const LIB_ITEM*> bFields;
309 std::set<const LIB_ITEM*, LIB_ITEM::cmp_items> bPins;
310
311 for( auto it = aRhs.m_drawings.begin(); it != aRhs.m_drawings.end(); ++it )
312 {
313 if( it->Type() == LIB_SHAPE_T )
314 bShapes.insert( &(*it) );
315 else if( it->Type() == LIB_FIELD_T )
316 bFields.insert( &(*it) );
317 else if( it->Type() == LIB_PIN_T )
318 bPins.insert( &(*it) );
319 }
320
321 if( int tmp = static_cast<int>( aShapes.size() - bShapes.size() ) )
322 {
323 retv = tmp;
324 REPORT( _( "Graphic item count differs." ) );
325
326 if( !aReporter )
327 return retv;
328 }
329 else
330 {
331 for( auto aIt = aShapes.begin(), bIt = bShapes.begin(); aIt != aShapes.end(); aIt++, bIt++ )
332 {
333 if( int tmp2 = (*aIt)->compare( *(*bIt), aCompareFlags ) )
334 {
335 retv = tmp2;
336 REPORT( wxString::Format( _( "%s differs." ), ITEM_DESC( *aIt ) ) );
337
338 if( !aReporter )
339 return retv;
340 }
341 }
342 }
343
344 if( int tmp = static_cast<int>( aPins.size() - bPins.size() ) )
345 {
346 retv = tmp;
347 REPORT( _( "Pin count differs." ) );
348
349 if( !aReporter )
350 return retv;
351 }
352 else
353 {
354 for( const LIB_ITEM* aPinItem : aPins )
355 {
356 const LIB_PIN* aPin = static_cast<const LIB_PIN*>( aPinItem );
357 const LIB_PIN* bPin = aRhs.GetPin( aPin->GetNumber(), aPin->GetUnit(),
358 aPin->GetBodyStyle() );
359
360 if( !bPin )
361 {
362 retv = 1;
363 REPORT( wxString::Format( _( "Pin %s not found." ), aPin->GetNumber() ) );
364
365 if( !aReporter )
366 return retv;
367 }
368 else if( int tmp2 = aPinItem->compare( *bPin, aCompareFlags ) )
369 {
370 retv = tmp2;
371 REPORT( wxString::Format( _( "Pin %s differs." ), aPin->GetNumber() ) );
372
373 if( !aReporter )
374 return retv;
375 }
376 }
377 }
378
379 for( const LIB_ITEM* aFieldItem : aFields )
380 {
381 const LIB_FIELD* aField = static_cast<const LIB_FIELD*>( aFieldItem );
382 const LIB_FIELD* bField = nullptr;
383 int tmp = 0;
384
385 if( aField->GetId() >= 0 && aField->GetId() < MANDATORY_FIELDS )
386 bField = aRhs.GetFieldById( aField->GetId() );
387 else
388 bField = aRhs.FindField( aField->GetName() );
389
390 if( !bField )
391 {
392 tmp = 1;
393 }
394 else
395 {
396 tmp = aFieldItem->compare( *bField, aCompareFlags );
397 }
398
399 if( tmp )
400 {
401 retv = tmp;
402 REPORT( wxString::Format( _( "%s field differs." ), aField->GetName( false ) ) );
403
404 if( !aReporter )
405 return retv;
406 }
407 }
408
409 if( int tmp = static_cast<int>( aFields.size() - bFields.size() ) )
410 {
411 retv = tmp;
412 REPORT( _( "Field count differs." ) );
413
414 if( !aReporter )
415 return retv;
416 }
417
418 if( int tmp = static_cast<int>( m_fpFilters.GetCount() - aRhs.m_fpFilters.GetCount() ) )
419 {
420 retv = tmp;
421 REPORT( _( "Footprint filters differs." ) );
422
423 if( !aReporter )
424 return retv;
425 }
426 else
427 {
428 for( size_t i = 0; i < m_fpFilters.GetCount(); i++ )
429 {
430 if( int tmp2 = m_fpFilters[i].Cmp( aRhs.m_fpFilters[i] ) )
431 {
432 retv = tmp2;
433 REPORT( _( "Footprint filters differ." ) );
434
435 if( !aReporter )
436 return retv;
437 }
438 }
439 }
440
441 if( int tmp = m_keyWords.Cmp( aRhs.m_keyWords ) )
442 {
443 retv = tmp;
444 REPORT( _( "Symbol keywords differ." ) );
445
446 if( !aReporter )
447 return retv;
448 }
449
450 if( int tmp = m_pinNameOffset - aRhs.m_pinNameOffset )
451 {
452 retv = tmp;
453 REPORT( _( "Symbol pin name offsets differ." ) );
454
455 if( !aReporter )
456 return retv;
457 }
458
459 if( ( aCompareFlags & LIB_ITEM::COMPARE_FLAGS::ERC ) == 0 )
460 {
461 if( m_showPinNames != aRhs.m_showPinNames )
462 {
463 retv = ( m_showPinNames ) ? 1 : -1;
464 REPORT( _( "Show pin names settings differ." ) );
465
466 if( !aReporter )
467 return retv;
468 }
469
471 {
472 retv = ( m_showPinNumbers ) ? 1 : -1;
473 REPORT( _( "Show pin numbers settings differ." ) );
474
475 if( !aReporter )
476 return retv;
477 }
478
480 {
481 retv = ( m_excludedFromSim ) ? -1 : 1;
482 REPORT( _( "Exclude from simulation settings differ." ) );
483
484 if( !aReporter )
485 return retv;
486 }
487
489 {
490 retv = ( m_excludedFromBOM ) ? -1 : 1;
491 REPORT( _( "Exclude from bill of materials settings differ." ) );
492
493 if( !aReporter )
494 return retv;
495 }
496
498 {
499 retv = ( m_excludedFromBoard ) ? -1 : 1;
500 REPORT( _( "Exclude from board settings differ." ) );
501
502 if( !aReporter )
503 return retv;
504 }
505 }
506
507 if( !aReporter )
508 {
509 if( m_unitsLocked != aRhs.m_unitsLocked )
510 return ( m_unitsLocked ) ? 1 : -1;
511
512 // Compare unit display names
514 {
515 return -1;
516 }
517 else if( m_unitDisplayNames > aRhs.m_unitDisplayNames )
518 {
519 return 1;
520 }
521 }
522
523 return retv;
524}
525
526
528{
529 const LIB_SYMBOL_SPTR sp = m_parent.lock();
530
531 // Recurse until the parent symbol is empty.
532 if( sp )
533 return sp->GetRootSymbol();
534
535 return m_me;
536}
537
538
539wxString LIB_SYMBOL::GetUnitReference( int aUnit )
540{
541 return LIB_SYMBOL::LetterSubReference( aUnit, 'A' );
542}
543
544
546{
547 return ( m_unitDisplayNames.count( aUnit ) == 1 );
548}
549
550
552{
553 if( HasUnitDisplayName( aUnit ) )
554 {
555 return m_unitDisplayNames[aUnit];
556 }
557 else
558 {
559 return wxString::Format( _( "Unit %s" ), GetUnitReference( aUnit ) );
560 }
561}
562
563
564void LIB_SYMBOL::CopyUnitDisplayNames( std::map<int, wxString>& aTarget ) const
565{
566 for( const auto& it : m_unitDisplayNames )
567 {
568 aTarget[it.first] = it.second;
569 }
570}
571
572
573void LIB_SYMBOL::SetUnitDisplayName( int aUnit, const wxString& aName )
574{
575 if( aUnit <= GetUnitCount() )
576 {
577 if( aName.Length() > 0 )
578 {
579 m_unitDisplayNames[aUnit] = aName;
580 }
581 else
582 {
583 m_unitDisplayNames.erase( aUnit );
584 }
585 }
586}
587
588
589void LIB_SYMBOL::SetName( const wxString& aName )
590{
591 m_name = aName;
592 m_libId.SetLibItemName( aName );
593}
594
595
597{
598 if( aParent )
599 m_parent = aParent->SharedPtr();
600 else
601 m_parent.reset();
602}
603
604
605std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
606{
607 std::unique_ptr< LIB_SYMBOL > retv;
608
609 if( IsAlias() )
610 {
611 LIB_SYMBOL_SPTR parent = m_parent.lock();
612
613 wxCHECK_MSG( parent, retv,
614 wxString::Format( "Parent of derived symbol '%s' undefined", m_name ) );
615
616 // Copy the parent.
617 if( parent->IsAlias() )
618 retv = parent->Flatten();
619 else
620 retv = std::make_unique<LIB_SYMBOL>( *parent.get() );
621
622 retv->m_name = m_name;
623 retv->SetLibId( m_libId );
624
625 // Now add the inherited part mandatory field (this) information.
626 for( int i = 0; i < MANDATORY_FIELDS; i++ )
627 {
628 wxString tmp = GetFieldById( i )->GetText();
629
630 // If the field isn't defined then inherit the parent field value.
631 if( tmp.IsEmpty() )
632 retv->GetFieldById( i )->SetText( retv->GetFieldById( i )->GetText() );
633 else
634 *retv->GetFieldById( i ) = *GetFieldById( i );
635 }
636
637 // Grab all the rest of derived symbol fields.
638 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
639 {
640 const LIB_FIELD* aliasField = dynamic_cast<const LIB_FIELD*>( &item );
641
642 wxCHECK2( aliasField, continue );
643
644 // Mandatory fields were already resolved.
645 if( aliasField->IsMandatory() )
646 continue;
647
648 LIB_FIELD* newField = new LIB_FIELD( *aliasField );
649 newField->SetParent( retv.get() );
650
651 LIB_FIELD* parentField = retv->FindField( aliasField->GetName() );
652
653 if( !parentField ) // Derived symbol field does not exist in parent symbol.
654 {
655 retv->AddDrawItem( newField );
656 }
657 else // Derived symbol field overrides the parent symbol field.
658 {
659 retv->RemoveDrawItem( parentField );
660 retv->AddDrawItem( newField );
661 }
662 }
663
664 retv->SetKeyWords( m_keyWords.IsEmpty() ? parent->GetKeyWords() : m_keyWords );
665 retv->SetFPFilters( m_fpFilters.IsEmpty() ? parent->GetFPFilters() : m_fpFilters );
666
667 retv->SetExcludedFromSim( parent->GetExcludedFromSim() );
668 retv->SetExcludedFromBOM( parent->GetExcludedFromBOM() );
669 retv->SetExcludedFromBoard( parent->GetExcludedFromBoard() );
670
671 retv->UpdateFieldOrdinals();
672 }
673 else
674 {
675 retv = std::make_unique<LIB_SYMBOL>( *this );
676 }
677
678 return retv;
679}
680
681
683{
684 for( LIB_ITEM& item : m_drawings )
685 {
686 if( EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( &item ) )
687 {
688 eda_text->ClearBoundingBoxCache();
689 eda_text->ClearRenderCache();
690 }
691 }
692}
693
694
695const wxString LIB_SYMBOL::GetLibraryName() const
696{
697 if( m_library )
698 return m_library->GetName();
699
700 return m_libId.GetLibNickname();
701}
702
703
705{
706 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
707 {
708 if( parent->IsRoot() )
709 return parent->m_options == ENTRY_POWER;
710 else
711 return parent->IsPower();
712 }
713
714 return m_options == ENTRY_POWER;
715}
716
717
719{
720 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
721 {
722 if( parent->IsRoot() )
723 parent->m_options = ENTRY_POWER;
724 else
725 parent->SetPower();
726 }
727
729}
730
731
733{
734 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
735 {
736 if( parent->IsRoot() )
737 return parent->m_options == ENTRY_NORMAL;
738 else
739 return parent->IsNormal();
740 }
741
742 return m_options == ENTRY_NORMAL;
743}
744
745
747{
748 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
749 {
750 if( parent->IsRoot() )
751 parent->m_options = ENTRY_NORMAL;
752 else
753 parent->SetNormal();
754 }
755
757}
758
759
760wxString LIB_SYMBOL::LetterSubReference( int aUnit, int aFirstId )
761{
762 // use letters as notation. To allow more than 26 units, the sub ref
763 // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
764 // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
765 int u;
766 wxString suffix;
767
768 do
769 {
770 u = ( aUnit - 1 ) % 26;
771 suffix = wxChar( aFirstId + u ) + suffix;
772 aUnit = ( aUnit - u ) / 26;
773 } while( aUnit > 0 );
774
775 return suffix;
776}
777
778
779void LIB_SYMBOL::PrintBackground( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
780 int aUnit, int aBodyStyle, const LIB_SYMBOL_OPTIONS& aOpts,
781 bool aDimmed )
782{
783 /* draw background for filled items using background option
784 * Solid lines will be drawn after the background
785 * Note also, background is not drawn when printing in black and white
786 */
788 {
789 for( LIB_ITEM& item : m_drawings )
790 {
791 // Do not print private items
792 if( item.IsPrivate() )
793 continue;
794
795 if( item.Type() == LIB_SHAPE_T )
796 {
797 LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
798
799 // Do not draw items not attached to the current part
800 if( aUnit && shape.m_unit && ( shape.m_unit != aUnit ) )
801 continue;
802
803 if( aBodyStyle && shape.m_bodyStyle && ( shape.m_bodyStyle != aBodyStyle ) )
804 continue;
805
806 if( shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
807 shape.Print( aSettings, aOffset, (void*) false, aOpts.transform, aDimmed );
808 }
809 }
810 }
811}
812
813
814void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset, int aUnit,
815 int aBodyStyle, const LIB_SYMBOL_OPTIONS& aOpts, bool aDimmed )
816{
817
818 for( LIB_ITEM& item : m_drawings )
819 {
820 // Do not print private items
821 if( item.IsPrivate() )
822 continue;
823
824 // Do not draw items not attached to the current part
825 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
826 continue;
827
828 if( aBodyStyle && item.m_bodyStyle && ( item.m_bodyStyle != aBodyStyle ) )
829 continue;
830
831 if( item.Type() == LIB_FIELD_T )
832 {
833 LIB_FIELD& field = static_cast<LIB_FIELD&>( item );
834
835 if( field.IsVisible() && !aOpts.draw_visible_fields )
836 continue;
837
838 if( !field.IsVisible() && !aOpts.draw_hidden_fields )
839 continue;
840 }
841
842 if( item.Type() == LIB_PIN_T )
843 {
844 item.Print( aSettings, aOffset, (void*) &aOpts, aOpts.transform, aDimmed );
845 }
846 else if( item.Type() == LIB_FIELD_T )
847 {
848 item.Print( aSettings, aOffset, nullptr, aOpts.transform, aDimmed );
849 }
850 else if( item.Type() == LIB_SHAPE_T )
851 {
852 LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
853 bool forceNoFill = shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR;
854
855 shape.Print( aSettings, aOffset, (void*) forceNoFill, aOpts.transform, aDimmed );
856 }
857 else
858 {
859 item.Print( aSettings, aOffset, (void*) false, aOpts.transform, aDimmed );
860 }
861 }
862}
863
864
865void LIB_SYMBOL::Plot( PLOTTER *aPlotter, int aUnit, int aBodyStyle, bool aBackground,
866 const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed ) const
867{
868 wxASSERT( aPlotter != nullptr );
869
871 COLOR4D bg = aPlotter->RenderSettings()->GetBackgroundColor();
872
873 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
874 bg = COLOR4D::WHITE;
875
876 if( aDimmed )
877 {
878 color.Desaturate( );
879 color = color.Mix( bg, 0.5f );
880 }
881
882 aPlotter->SetColor( color );
883
884 for( const LIB_ITEM& item : m_drawings )
885 {
886 // Do not plot private items
887 if( item.IsPrivate() )
888 continue;
889
890 // LIB_FIELDs are not plotted here, because this plot function is used to plot schematic
891 // items which have their own SCH_FIELDs
892 if( item.Type() == LIB_FIELD_T )
893 continue;
894
895 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
896 continue;
897
898 if( aBodyStyle && item.m_bodyStyle && ( item.m_bodyStyle != aBodyStyle ) )
899 continue;
900
901 item.Plot( aPlotter, aBackground, aOffset, aTransform, aDimmed );
902 }
903}
904
905
906void LIB_SYMBOL::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aBodyStyle, bool aBackground,
907 const VECTOR2I& aOffset, const TRANSFORM& aTransform, bool aDimmed,
908 bool aPlotHidden )
909{
910 wxASSERT( aPlotter != nullptr );
911
913 COLOR4D bg = aPlotter->RenderSettings()->GetBackgroundColor();
914
915 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
916 bg = COLOR4D::WHITE;
917
918 if( aDimmed )
919 {
920 color.Desaturate( );
921 color = color.Mix( bg, 0.5f );
922 }
923
924 aPlotter->SetColor( color );
925
926 for( LIB_ITEM& item : m_drawings )
927 {
928 if( item.Type() != LIB_FIELD_T )
929 continue;
930
931 if( !aPlotHidden && !( (LIB_FIELD&) item ).IsVisible() )
932 continue;
933
934 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
935 continue;
936
937 if( aBodyStyle && item.m_bodyStyle && ( item.m_bodyStyle != aBodyStyle ) )
938 continue;
939
940 LIB_FIELD& field = (LIB_FIELD&) item;
941
942 // The reference is a special case: we should change the basic text
943 // to add '?' and the part id
944 wxString tmp = field.GetShownText( true );
945
946 if( field.GetId() == REFERENCE_FIELD )
947 {
948 wxString text = field.GetFullText( aUnit );
949 field.SetText( text );
950 }
951
952 item.Plot( aPlotter, aBackground, aOffset, aTransform, aDimmed );
953 field.SetText( tmp );
954 }
955}
956
957
959{
960 std::vector<LIB_SHAPE*> potential_top_items;
961 std::vector<LIB_ITEM*> bottom_items;
962
963 for( LIB_ITEM& item : m_drawings )
964 {
965 if( item.Type() == LIB_SHAPE_T )
966 {
967 LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
968
969 if( shape.GetFillMode() == FILL_T::FILLED_WITH_COLOR )
970 potential_top_items.push_back( &shape );
971 else
972 bottom_items.push_back( &item );
973 }
974 else
975 {
976 bottom_items.push_back( &item );
977 }
978 }
979
980 std::sort( potential_top_items.begin(), potential_top_items.end(),
981 []( LIB_ITEM* a, LIB_ITEM* b )
982 {
983 return a->GetBoundingBox().GetArea() > b->GetBoundingBox().GetArea();
984 } );
985
986
987 for( LIB_SHAPE* item : potential_top_items )
988 {
989 for( LIB_ITEM* bottom_item : bottom_items )
990 {
991 if( item->GetBoundingBox().Contains( bottom_item->GetBoundingBox() ) )
992 {
993 item->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
994 break;
995 }
996 }
997 }
998}
999
1000
1002{
1003 wxASSERT( aItem != nullptr );
1004
1005 // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
1006 // omitted when saving to disk.
1007 if( aItem->Type() == LIB_FIELD_T )
1008 {
1009 if( static_cast<LIB_FIELD*>( aItem )->IsMandatory() )
1010 return;
1011 }
1012
1013 LIB_ITEMS& items = m_drawings[ aItem->Type() ];
1014
1015 for( LIB_ITEMS::iterator i = items.begin(); i != items.end(); i++ )
1016 {
1017 if( &*i == aItem )
1018 {
1019 items.erase( i );
1020 break;
1021 }
1022 }
1023}
1024
1025
1026void LIB_SYMBOL::AddDrawItem( LIB_ITEM* aItem, bool aSort )
1027{
1028 wxCHECK( aItem, /* void */ );
1029
1030 m_drawings.push_back( aItem );
1031
1032 if( aSort )
1033 m_drawings.sort();
1034}
1035
1036
1037void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aBodyStyle ) const
1038{
1039 /* Notes:
1040 * when aUnit == 0: no unit filtering
1041 * when aBodyStyle == 0: no body style filtering
1042 * when m_unit == 0, the item is common to all units
1043 * when m_bodyStyle == 0, the item is common to all body styles
1044 */
1045
1046 LIB_SYMBOL_SPTR parent = m_parent.lock();
1047 const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
1048
1049 for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
1050 {
1051 // Unit filtering:
1052 if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
1053 continue;
1054
1055 // De Morgan variant filtering:
1056 if( aBodyStyle && item.m_bodyStyle && ( item.m_bodyStyle != aBodyStyle ) )
1057 continue;
1058
1059 aList.push_back( (LIB_PIN*) &item );
1060 }
1061}
1062
1063
1064std::vector<LIB_PIN*> LIB_SYMBOL::GetAllLibPins() const
1065{
1066 std::vector<LIB_PIN*> pinList;
1067
1068 GetPins( pinList, 0, 0 );
1069 return pinList;
1070}
1071
1072
1074{
1075 std::vector<LIB_PIN*> pinList;
1076
1077 GetPins( pinList, 0, 1 ); // All units, but a single convert
1078 return pinList.size();
1079}
1080
1081
1082LIB_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aBodyStyle ) const
1083{
1084 LIB_PINS pinList;
1085
1086 GetPins( pinList, aUnit, aBodyStyle );
1087
1088 for( LIB_PIN* pin : pinList )
1089 {
1090 wxASSERT( pin->Type() == LIB_PIN_T );
1091
1092 if( aNumber == pin->GetNumber() )
1093 return pin;
1094 }
1095
1096 return nullptr;
1097}
1098
1099
1100bool LIB_SYMBOL::PinsConflictWith( const LIB_SYMBOL& aOtherPart, bool aTestNums, bool aTestNames,
1101 bool aTestType, bool aTestOrientation, bool aTestLength ) const
1102{
1103 LIB_PINS thisPinList;
1104 GetPins( thisPinList, /* aUnit */ 0, /* aBodyStyle */ 0 );
1105
1106 for( const LIB_PIN* eachThisPin : thisPinList )
1107 {
1108 wxASSERT( eachThisPin );
1109 LIB_PINS otherPinList;
1110 aOtherPart.GetPins( otherPinList, /* aUnit */ 0, /* aBodyStyle */ 0 );
1111 bool foundMatch = false;
1112
1113 for( const LIB_PIN* eachOtherPin : otherPinList )
1114 {
1115 wxASSERT( eachOtherPin );
1116
1117 // Same unit?
1118 if( eachThisPin->GetUnit() != eachOtherPin->GetUnit() )
1119 continue;
1120
1121 // Same body stype?
1122 if( eachThisPin->GetBodyStyle() != eachOtherPin->GetBodyStyle() )
1123 continue;
1124
1125 // Same position?
1126 if( eachThisPin->GetPosition() != eachOtherPin->GetPosition() )
1127 continue;
1128
1129 // Same number?
1130 if( aTestNums && ( eachThisPin->GetNumber() != eachOtherPin->GetNumber() ) )
1131 continue;
1132
1133 // Same name?
1134 if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ) )
1135 continue;
1136
1137 // Same electrical type?
1138 if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ) )
1139 continue;
1140
1141 // Same orientation?
1142 if( aTestOrientation
1143 && ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ) )
1144 continue;
1145
1146 // Same length?
1147 if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ) )
1148 continue;
1149
1150 foundMatch = true;
1151 break; // Match found so search is complete.
1152 }
1153
1154 if( !foundMatch )
1155 {
1156 // This means there was not an identical (according to the arguments)
1157 // pin at the same position in the other symbol.
1158 return true;
1159 }
1160 }
1161
1162 // The loop never gave up, so no conflicts were found.
1163 return false;
1164}
1165
1166
1167const BOX2I LIB_SYMBOL::GetUnitBoundingBox( int aUnit, int aBodyStyle,
1168 bool aIgnoreHiddenFields ) const
1169{
1170 BOX2I bBox; // Start with a fresh BOX2I so the Merge algorithm works
1171
1172 for( const LIB_ITEM& item : m_drawings )
1173 {
1174 if( item.m_unit > 0
1175 && m_unitCount > 1
1176 && aUnit > 0
1177 && aUnit != item.m_unit )
1178 {
1179 continue;
1180 }
1181
1182 if( item.m_bodyStyle > 0 && aBodyStyle > 0 && aBodyStyle != item.m_bodyStyle )
1183 continue;
1184
1185 if( aIgnoreHiddenFields && ( item.Type() == LIB_FIELD_T )
1186 && !( (LIB_FIELD&) item ).IsVisible() )
1187 continue;
1188
1189 bBox.Merge( item.GetBoundingBox() );
1190 }
1191
1192 return bBox;
1193}
1194
1195
1196void LIB_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
1197{
1198 aCount = 0;
1199 aLayers[ aCount++ ] = LAYER_DEVICE;
1200 aLayers[ aCount++ ] = LAYER_DEVICE_BACKGROUND;
1201 aLayers[ aCount++ ] = LAYER_REFERENCEPART;
1202 aLayers[ aCount++ ] = LAYER_VALUEPART;
1203 aLayers[ aCount++ ] = LAYER_FIELDS;
1204 aLayers[ aCount++ ] = LAYER_PRIVATE_NOTES;
1205 aLayers[ aCount++ ] = LAYER_NOTES_BACKGROUND;
1206 aLayers[ aCount++ ] = LAYER_SELECTION_SHADOWS;
1207}
1208
1209
1210const BOX2I LIB_SYMBOL::GetBodyBoundingBox( int aUnit, int aBodyStyle, bool aIncludePins,
1211 bool aIncludePrivateItems ) const
1212{
1213 BOX2I bbox;
1214
1215 for( const LIB_ITEM& item : m_drawings )
1216 {
1217 if( item.m_unit > 0 && aUnit > 0 && aUnit != item.m_unit )
1218 continue;
1219
1220 if( item.m_bodyStyle > 0 && aBodyStyle > 0 && aBodyStyle != item.m_bodyStyle )
1221 continue;
1222
1223 if( item.IsPrivate() && !aIncludePrivateItems )
1224 continue;
1225
1226 if( item.Type() == LIB_FIELD_T )
1227 continue;
1228
1229 if( item.Type() == LIB_PIN_T )
1230 {
1231 const LIB_PIN& pin = static_cast<const LIB_PIN&>( item );
1232
1233 if( pin.IsVisible() )
1234 {
1235 // Note: the roots of the pins are always included for symbols that don't have
1236 // a well-defined body.
1237
1238 if( aIncludePins )
1239 bbox.Merge( pin.GetBoundingBox( false, false, false ) );
1240 else
1241 bbox.Merge( pin.GetPinRoot() );
1242 }
1243 }
1244 else
1245 {
1246 bbox.Merge( item.GetBoundingBox() );
1247 }
1248 }
1249
1250 return bbox;
1251}
1252
1253
1255{
1257}
1258
1259
1261{
1262 AddDrawItem( aField );
1263}
1264
1265
1266void LIB_SYMBOL::SetFields( const std::vector<LIB_FIELD>& aFields )
1267{
1269
1270 for( size_t ii = 0; ii < aFields.size(); ++ii )
1271 {
1272 // drawings is a ptr_vector, new and copy an object on the heap.
1273 LIB_FIELD* field = new LIB_FIELD( aFields[ ii ] );
1274
1275 field->SetParent( this );
1276 m_drawings.push_back( field );
1277 }
1278
1279 m_drawings.sort();
1280}
1281
1282
1283void LIB_SYMBOL::GetFields( std::vector<LIB_FIELD*>& aList )
1284{
1285 // Grab the MANDATORY_FIELDS first, in expected order given by enum MANDATORY_FIELD_T
1286 for( int id = 0; id < MANDATORY_FIELDS; ++id )
1287 aList.push_back( GetFieldById( id ) );
1288
1289 // Now grab all the rest of fields.
1290 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1291 {
1292 LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
1293
1294 if( !field->IsMandatory() )
1295 aList.push_back( field );
1296 }
1297}
1298
1299
1300void LIB_SYMBOL::GetFields( std::vector<LIB_FIELD>& aList )
1301{
1302 // Grab the MANDATORY_FIELDS first, in expected order given by enum MANDATORY_FIELD_T
1303 for( int id = 0; id < MANDATORY_FIELDS; ++id )
1304 aList.push_back( *GetFieldById( id ) );
1305
1306 // Now grab all the rest of fields.
1307 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1308 {
1309 LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
1310
1311 if( !field->IsMandatory() )
1312 aList.push_back( *field );
1313 }
1314}
1315
1316
1318{
1319 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1320 {
1321 LIB_FIELD* field = ( LIB_FIELD* ) &item;
1322
1323 if( field->GetId() == aId )
1324 return field;
1325 }
1326
1327 return nullptr;
1328}
1329
1330
1331LIB_FIELD* LIB_SYMBOL::FindField( const wxString& aFieldName, bool aCaseInsensitive )
1332{
1333 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1334 {
1335 if( aCaseInsensitive )
1336 {
1337 if( static_cast<LIB_FIELD*>( &item )->GetCanonicalName().Upper() == aFieldName.Upper() )
1338 return static_cast<LIB_FIELD*>( &item );
1339 }
1340 else
1341 {
1342 if( static_cast<LIB_FIELD*>( &item )->GetCanonicalName() == aFieldName )
1343 return static_cast<LIB_FIELD*>( &item );
1344 }
1345 }
1346
1347 return nullptr;
1348}
1349
1350
1351const LIB_FIELD* LIB_SYMBOL::FindField( const wxString& aFieldName,
1352 const bool aCaseInsensitive ) const
1353{
1354 for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1355 {
1356 if( aCaseInsensitive )
1357 {
1358 if( static_cast<const LIB_FIELD*>( &item )->GetCanonicalName().Upper()
1359 == aFieldName.Upper() )
1360 return static_cast<const LIB_FIELD*>( &item );
1361 }
1362 else
1363 {
1364 if( static_cast<const LIB_FIELD*>( &item )->GetCanonicalName() == aFieldName )
1365 return static_cast<const LIB_FIELD*>( &item );
1366 }
1367 }
1368
1369 return nullptr;
1370}
1371
1372
1374{
1376 wxASSERT( field != nullptr );
1377 return *field;
1378}
1379
1380
1382{
1384 wxASSERT( field != nullptr );
1385 return *field;
1386}
1387
1388
1390{
1392 wxASSERT( field != nullptr );
1393 return *field;
1394}
1395
1396
1398{
1400 wxASSERT( field != nullptr );
1401 return *field;
1402}
1403
1404
1406{
1408 wxASSERT( field != nullptr );
1409 return *field;
1410}
1411
1412
1414{
1415 wxString refDesignator = GetFieldById( REFERENCE_FIELD )->GetText();
1416
1417 refDesignator.Replace( wxS( "~" ), wxS( " " ) );
1418
1419 wxString prefix = refDesignator;
1420
1421 while( prefix.Length() )
1422 {
1423 wxUniCharRef last = prefix.Last();
1424
1425 if( ( last >= '0' && last <= '9' ) || last == '?' || last == '*' )
1426 prefix.RemoveLast();
1427 else
1428 break;
1429 }
1430
1431 // Avoid a prefix containing trailing/leading spaces
1432 prefix.Trim( true );
1433 prefix.Trim( false );
1434
1435 return prefix;
1436}
1437
1438
1439void LIB_SYMBOL::RunOnChildren( const std::function<void( LIB_ITEM* )>& aFunction )
1440{
1441 for( LIB_ITEM& item : m_drawings )
1442 aFunction( &item );
1443}
1444
1445
1447{
1448 int retv = 0;
1449 int lastOrdinal = MANDATORY_FIELDS;
1450
1451 for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
1452 {
1453 LIB_FIELD* field = dynamic_cast<LIB_FIELD*>( &item );
1454
1455 wxCHECK2( field, continue );
1456
1457 // Mandatory fields were already resolved always have the same ordinal values.
1458 if( field->IsMandatory() )
1459 continue;
1460
1461 if( field->GetId() != lastOrdinal )
1462 {
1463 field->SetId( lastOrdinal );
1464 retv += 1;
1465 }
1466
1467 lastOrdinal += 1;
1468 }
1469
1470 return retv;
1471}
1472
1473
1475{
1476 int retv = MANDATORY_FIELDS;
1477
1478 while( GetFieldById( retv ) )
1479 retv += 1;
1480
1481 return retv;
1482}
1483
1484
1485void LIB_SYMBOL::SetOffset( const VECTOR2I& aOffset )
1486{
1487 for( LIB_ITEM& item : m_drawings )
1488 item.Offset( aOffset );
1489}
1490
1491
1493{
1495}
1496
1497
1499{
1500 for( const LIB_ITEM& item : m_drawings )
1501 {
1502 if( item.m_bodyStyle > LIB_ITEM::BODY_STYLE::BASE )
1503 return true;
1504 }
1505
1506 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1507 {
1508 for( const LIB_ITEM& item : parent->GetDrawItems() )
1509 {
1510 if( item.m_bodyStyle > LIB_ITEM::BODY_STYLE::BASE )
1511 return true;
1512 }
1513 }
1514
1515 return false;
1516}
1517
1518
1520{
1521 int maxPinNumber = 0;
1522 LIB_SYMBOL_SPTR parent = m_parent.lock();
1523 const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
1524
1525 for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
1526 {
1527 const LIB_PIN* pin = static_cast<const LIB_PIN*>( &item );
1528 long currentPinNumber = 0;
1529
1530 if( pin->GetNumber().ToLong( &currentPinNumber ) )
1531 maxPinNumber = std::max( maxPinNumber, (int) currentPinNumber );
1532 }
1533
1534 return maxPinNumber;
1535}
1536
1537
1539{
1540 for( LIB_ITEM& item : m_drawings )
1541 item.ClearTempFlags();
1542}
1543
1544
1546{
1547 for( LIB_ITEM& item : m_drawings )
1548 item.ClearEditFlags();
1549}
1550
1551
1552LIB_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aBodyStyle, KICAD_T aType,
1553 const VECTOR2I& aPoint )
1554{
1555 for( LIB_ITEM& item : m_drawings )
1556 {
1557 if( ( aUnit && item.m_unit && aUnit != item.m_unit )
1558 || ( aBodyStyle && item.m_bodyStyle && aBodyStyle != item.m_bodyStyle )
1559 || ( item.Type() != aType && aType != TYPE_NOT_INIT ) )
1560 {
1561 continue;
1562 }
1563
1564 if( item.HitTest( aPoint ) )
1565 return &item;
1566 }
1567
1568 return nullptr;
1569}
1570
1571
1572LIB_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aBodyStyle, KICAD_T aType,
1573 const VECTOR2I& aPoint, const TRANSFORM& aTransform )
1574{
1575 /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
1576 * VECTOR2I& pt ) to search items.
1577 * because this function uses DefaultTransform as orient/mirror matrix
1578 * we temporary copy aTransform in DefaultTransform
1579 */
1580 LIB_ITEM* item;
1581 TRANSFORM transform = DefaultTransform;
1582 DefaultTransform = aTransform;
1583
1584 item = LocateDrawItem( aUnit, aBodyStyle, aType, aPoint );
1585
1586 // Restore matrix
1587 DefaultTransform = transform;
1588
1589 return item;
1590}
1591
1592
1593INSPECT_RESULT LIB_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
1594 const std::vector<KICAD_T>& aScanTypes )
1595{
1596 // The part itself is never inspected, only its children
1597 for( LIB_ITEM& item : m_drawings )
1598 {
1599 if( item.IsType( aScanTypes ) )
1600 {
1601 if( aInspector( &item, aTestData ) == INSPECT_RESULT::QUIT )
1602 return INSPECT_RESULT::QUIT;
1603 }
1604 }
1605
1606 return INSPECT_RESULT::CONTINUE;
1607}
1608
1609
1610void LIB_SYMBOL::SetUnitCount( int aCount, bool aDuplicateDrawItems )
1611{
1612 if( m_unitCount == aCount )
1613 return;
1614
1615 if( aCount < m_unitCount )
1616 {
1618
1619 while( i != m_drawings.end() )
1620 {
1621 if( i->m_unit > aCount )
1622 i = m_drawings.erase( i );
1623 else
1624 ++i;
1625 }
1626 }
1627 else if( aDuplicateDrawItems )
1628 {
1629 int prevCount = m_unitCount;
1630
1631 // Temporary storage for new items, as adding new items directly to
1632 // m_drawings may cause the buffer reallocation which invalidates the
1633 // iterators
1634 std::vector< LIB_ITEM* > tmp;
1635
1636 for( LIB_ITEM& item : m_drawings )
1637 {
1638 if( item.m_unit != 1 )
1639 continue;
1640
1641 for( int j = prevCount + 1; j <= aCount; j++ )
1642 {
1643 LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
1644 newItem->m_unit = j;
1645 tmp.push_back( newItem );
1646 }
1647 }
1648
1649 for( LIB_ITEM* item : tmp )
1650 m_drawings.push_back( item );
1651 }
1652
1653 m_drawings.sort();
1654 m_unitCount = aCount;
1655}
1656
1657
1659{
1660 if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1661 return parent->GetUnitCount();
1662
1663 return m_unitCount;
1664}
1665
1666
1667void LIB_SYMBOL::SetHasAlternateBodyStyle( bool aHasAlternate, bool aDuplicatePins )
1668{
1669 if( aHasAlternate == HasAlternateBodyStyle() )
1670 return;
1671
1672 // Duplicate items to create the converted shape
1673 if( aHasAlternate )
1674 {
1675 if( aDuplicatePins )
1676 {
1677 std::vector< LIB_ITEM* > tmp; // Temporarily store the duplicated pins here.
1678
1679 for( LIB_ITEM& item : m_drawings )
1680 {
1681 // Only pins are duplicated.
1682 if( item.Type() != LIB_PIN_T )
1683 continue;
1684
1685 if( item.m_bodyStyle == 1 )
1686 {
1687 LIB_ITEM* newItem = (LIB_ITEM*) item.Duplicate();
1688 newItem->m_bodyStyle = 2;
1689 tmp.push_back( newItem );
1690 }
1691 }
1692
1693 // Transfer the new pins to the LIB_SYMBOL.
1694 for( unsigned i = 0; i < tmp.size(); i++ )
1695 m_drawings.push_back( tmp[i] );
1696 }
1697 }
1698 else
1699 {
1700 // Delete converted shape items because the converted shape does
1701 // not exist
1703
1704 while( i != m_drawings.end() )
1705 {
1706 if( i->m_bodyStyle > 1 )
1707 i = m_drawings.erase( i );
1708 else
1709 ++i;
1710 }
1711 }
1712
1713 m_drawings.sort();
1714}
1715
1716
1717std::vector<LIB_ITEM*> LIB_SYMBOL::GetUnitDrawItems( int aUnit, int aBodyStyle )
1718{
1719 std::vector<LIB_ITEM*> unitItems;
1720
1721 for( LIB_ITEM& item : m_drawings )
1722 {
1723 if( item.Type() == LIB_FIELD_T )
1724 continue;
1725
1726 if( ( aBodyStyle == -1 && item.GetUnit() == aUnit )
1727 || ( aUnit == -1 && item.GetBodyStyle() == aBodyStyle )
1728 || ( aUnit == item.GetUnit() && aBodyStyle == item.GetBodyStyle() ) )
1729 {
1730 unitItems.push_back( &item );
1731 }
1732 }
1733
1734 return unitItems;
1735}
1736
1737
1738std::vector<struct LIB_SYMBOL_UNIT> LIB_SYMBOL::GetUnitDrawItems()
1739{
1740 std::vector<struct LIB_SYMBOL_UNIT> units;
1741
1742 for( LIB_ITEM& item : m_drawings )
1743 {
1744 if( item.Type() == LIB_FIELD_T )
1745 continue;
1746
1747 int unit = item.GetUnit();
1748 int bodyStyle = item.GetBodyStyle();
1749
1750 auto it = std::find_if( units.begin(), units.end(),
1751 [unit, bodyStyle]( const LIB_SYMBOL_UNIT& a )
1752 {
1753 return a.m_unit == unit && a.m_bodyStyle == bodyStyle;
1754 } );
1755
1756 if( it == units.end() )
1757 {
1758 struct LIB_SYMBOL_UNIT newUnit;
1759 newUnit.m_unit = item.GetUnit();
1760 newUnit.m_bodyStyle = item.GetBodyStyle();
1761 newUnit.m_items.push_back( &item );
1762 units.emplace_back( newUnit );
1763 }
1764 else
1765 {
1766 it->m_items.push_back( &item );
1767 }
1768 }
1769
1770 return units;
1771}
1772
1773
1774std::vector<struct LIB_SYMBOL_UNIT> LIB_SYMBOL::GetUniqueUnits()
1775{
1776 int unitNum;
1777 size_t i;
1778 struct LIB_SYMBOL_UNIT unit;
1779 std::vector<LIB_ITEM*> compareDrawItems;
1780 std::vector<LIB_ITEM*> currentDrawItems;
1781 std::vector<struct LIB_SYMBOL_UNIT> uniqueUnits;
1782
1783 // The first unit is guaranteed to be unique so always include it.
1784 unit.m_unit = 1;
1785 unit.m_bodyStyle = 1;
1786 unit.m_items = GetUnitDrawItems( 1, 1 );
1787
1788 // There are no unique units if there are no draw items other than fields.
1789 if( unit.m_items.size() == 0 )
1790 return uniqueUnits;
1791
1792 uniqueUnits.emplace_back( unit );
1793
1794 if( ( GetUnitCount() == 1 || UnitsLocked() ) && !HasAlternateBodyStyle() )
1795 return uniqueUnits;
1796
1797 currentDrawItems = unit.m_items;
1798
1799 for( unitNum = 2; unitNum <= GetUnitCount(); unitNum++ )
1800 {
1801 compareDrawItems = GetUnitDrawItems( unitNum, 1 );
1802
1803 wxCHECK2_MSG( compareDrawItems.size() != 0, continue,
1804 "Multiple unit symbol defined with empty units." );
1805
1806 if( currentDrawItems.size() != compareDrawItems.size() )
1807 {
1808 unit.m_unit = unitNum;
1809 unit.m_bodyStyle = 1;
1810 unit.m_items = compareDrawItems;
1811 uniqueUnits.emplace_back( unit );
1812 }
1813 else
1814 {
1815 for( i = 0; i < currentDrawItems.size(); i++ )
1816 {
1817 if( currentDrawItems[i]->compare( *compareDrawItems[i],
1819 {
1820 unit.m_unit = unitNum;
1821 unit.m_bodyStyle = 1;
1822 unit.m_items = compareDrawItems;
1823 uniqueUnits.emplace_back( unit );
1824 }
1825 }
1826 }
1827 }
1828
1829 if( HasAlternateBodyStyle() )
1830 {
1831 currentDrawItems = GetUnitDrawItems( 1, 2 );
1832
1833 if( ( GetUnitCount() == 1 || UnitsLocked() ) )
1834 {
1835 unit.m_unit = 1;
1836 unit.m_bodyStyle = 2;
1837 unit.m_items = currentDrawItems;
1838 uniqueUnits.emplace_back( unit );
1839
1840 return uniqueUnits;
1841 }
1842
1843 for( unitNum = 2; unitNum <= GetUnitCount(); unitNum++ )
1844 {
1845 compareDrawItems = GetUnitDrawItems( unitNum, 2 );
1846
1847 wxCHECK2_MSG( compareDrawItems.size() != 0, continue,
1848 "Multiple unit symbol defined with empty units." );
1849
1850 if( currentDrawItems.size() != compareDrawItems.size() )
1851 {
1852 unit.m_unit = unitNum;
1853 unit.m_bodyStyle = 2;
1854 unit.m_items = compareDrawItems;
1855 uniqueUnits.emplace_back( unit );
1856 }
1857 else
1858 {
1859 for( i = 0; i < currentDrawItems.size(); i++ )
1860 {
1861 if( currentDrawItems[i]->compare( *compareDrawItems[i],
1863 {
1864 unit.m_unit = unitNum;
1865 unit.m_bodyStyle = 2;
1866 unit.m_items = compareDrawItems;
1867 uniqueUnits.emplace_back( unit );
1868 }
1869 }
1870 }
1871 }
1872 }
1873
1874 return uniqueUnits;
1875}
1876
1877
1878bool LIB_SYMBOL::operator==( const LIB_SYMBOL& aOther ) const
1879{
1880 if( m_libId != aOther.m_libId )
1881 return false;
1882
1884 return false;
1885
1886 if( m_excludedFromBOM != aOther.m_excludedFromBOM )
1887 return false;
1888
1889 if( m_excludedFromSim != aOther.m_excludedFromSim )
1890 return false;
1891
1892 if( m_flags != aOther.m_flags )
1893 return false;
1894
1895 if( m_unitCount != aOther.m_unitCount )
1896 return false;
1897
1898 if( m_pinNameOffset != aOther.m_pinNameOffset )
1899 return false;
1900
1901 if( m_showPinNames != aOther.m_showPinNames )
1902 return false;
1903
1904 if( m_showPinNumbers != aOther.m_showPinNumbers )
1905 return false;
1906
1907 if( m_drawings.size() != aOther.m_drawings.size() )
1908 return false;
1909
1910 for( auto it1 = m_drawings.begin(), it2 = aOther.m_drawings.begin();
1911 it1 != m_drawings.end(); ++it1, ++it2 )
1912 {
1913 if( !( *it1 == *it2 ) )
1914 return false;
1915 }
1916
1917 const LIB_PINS thisPinList = GetAllLibPins();
1918 const LIB_PINS otherPinList = aOther.GetAllLibPins();
1919
1920 if( thisPinList.size() != otherPinList.size() )
1921 return false;
1922
1923 for( auto it1 = thisPinList.begin(), it2 = otherPinList.begin();
1924 it1 != thisPinList.end(); ++it1, ++it2 )
1925 {
1926 if( !( **it1 == **it2 ) )
1927 return false;
1928 }
1929 for( size_t ii = 0; ii < thisPinList.size(); ++ii )
1930 {
1931 if( !( *thisPinList[ii] == *otherPinList[ii] ) )
1932 return false;
1933 }
1934
1935 return true;
1936}
1937
1938
1939double LIB_SYMBOL::Similarity( const LIB_SYMBOL& aOther ) const
1940{
1941 double similarity = 0.0;
1942 int totalItems = 0;
1943
1944 if( m_Uuid == aOther.m_Uuid )
1945 return 1.0;
1946
1947 for( const LIB_ITEM& item : m_drawings )
1948 {
1949 totalItems += 1;
1950 double max_similarity = 0.0;
1951
1952 for( const LIB_ITEM& otherItem : aOther.m_drawings )
1953 {
1954 double temp_similarity = item.Similarity( otherItem );
1955 max_similarity = std::max( max_similarity, temp_similarity );
1956
1957 if( max_similarity == 1.0 )
1958 break;
1959 }
1960
1961 similarity += max_similarity;
1962 }
1963
1964 for( const LIB_PIN* pin : GetAllLibPins() )
1965 {
1966 totalItems += 1;
1967 double max_similarity = 0.0;
1968
1969 for( const LIB_PIN* otherPin : aOther.GetAllLibPins() )
1970 {
1971 double temp_similarity = pin->Similarity( *otherPin );
1972 max_similarity = std::max( max_similarity, temp_similarity );
1973
1974 if( max_similarity == 1.0 )
1975 break;
1976 }
1977
1978 similarity += max_similarity;
1979 }
1980
1981 if( totalItems == 0 )
1982 similarity = 0.0;
1983 else
1984 similarity /= totalItems;
1985
1987 similarity *= 0.9;
1988
1989 if( m_excludedFromBOM != aOther.m_excludedFromBOM )
1990 similarity *= 0.9;
1991
1992 if( m_excludedFromSim != aOther.m_excludedFromSim )
1993 similarity *= 0.9;
1994
1995 if( m_flags != aOther.m_flags )
1996 similarity *= 0.9;
1997
1998 if( m_unitCount != aOther.m_unitCount )
1999 similarity *= 0.5;
2000
2001 if( m_pinNameOffset != aOther.m_pinNameOffset )
2002 similarity *= 0.9;
2003
2004 if( m_showPinNames != aOther.m_showPinNames )
2005 similarity *= 0.9;
2006
2007 if( m_showPinNumbers != aOther.m_showPinNumbers )
2008 similarity *= 0.9;
2009
2010 return similarity;
2011}
int color
Definition: DXF_plotter.cpp:58
const char * name
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:589
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
const KIID m_Uuid
Definition: eda_item.h:482
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void ClearSelected()
Definition: eda_item.h:118
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:487
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:126
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:80
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
virtual bool IsVisible() const
Definition: eda_text.h:148
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
virtual const COLOR4D & GetBackgroundColor() const =0
Return current background color settings.
Field object used in symbol libraries.
Definition: lib_field.h:62
bool ShowInChooser() const
Definition: lib_field.h:198
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:336
void SetId(int aId)
Definition: lib_field.cpp:107
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: lib_field.cpp:406
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: lib_field.cpp:485
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: lib_field.cpp:494
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: lib_field.cpp:423
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: lib_field.cpp:434
bool IsMandatory() const
Definition: lib_field.cpp:584
int GetId() const
Definition: lib_field.h:120
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:217
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:110
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:160
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:68
int GetBodyStyle() const
Definition: lib_item.h:346
@ UNIT
Definition: lib_item.h:95
int GetUnit() const
Definition: lib_item.h:343
LIB_ITEM * Duplicate() const
Create a copy of this LIB_ITEM (with a new Uuid).
Definition: lib_item.cpp:131
virtual void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, void *aData, const TRANSFORM &aTransform, bool aDimmed)
Draw an item.
Definition: lib_item.cpp:171
int m_bodyStyle
Shape identification for alternate body styles.
Definition: lib_item.h:408
int m_unit
Unit identification for multiple parts per package.
Definition: lib_item.h:402
@ BASE
Definition: lib_item.h:79
const wxString & GetNumber() const
Definition: lib_pin.h:117
Define a library symbol object.
Definition: lib_symbol.h:99
LIB_ITEMS_CONTAINER m_drawings
Definition: lib_symbol.h:765
bool HasAlternateBodyStyle() const
Test if symbol has more than one body conversion type (DeMorgan).
void ClearTempFlags()
Clears the status flag all draw objects in this symbol.
LIB_PIN * GetPin(const wxString &aNumber, int aUnit=0, int aBodyStyle=0) const
Return pin object with the requested pin aNumber.
LIBRENTRYOPTIONS m_options
Special symbol features such as POWER or NORMAL.)
Definition: lib_symbol.h:763
void PlotLibFields(PLOTTER *aPlotter, int aUnit, int aBodyStyle, 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:906
void RemoveDrawItem(LIB_ITEM *aItem)
Remove draw aItem from list.
void RunOnChildren(const std::function< void(LIB_ITEM *)> &aFunction)
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.
wxString GetPrefix()
wxString GetKeyWords() const
Definition: lib_symbol.h:191
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:286
const BOX2I GetUnitBoundingBox(int aUnit, int aBodyStyle, bool aIgnoreHiddenFields=true) const
Get the bounding box for the symbol.
int GetNextAvailableFieldId() const
bool operator==(const LIB_SYMBOL *aSymbol) const
Definition: lib_symbol.h:679
std::map< int, wxString > m_unitDisplayNames
Definition: lib_symbol.h:773
SYMBOL_LIB * m_library
Definition: lib_symbol.h:767
wxString GetUnitDisplayName(int aUnit) override
Return the user-defined display name for aUnit for symbols with units.
Definition: lib_symbol.cpp:551
const wxString GetLibraryName() const
Definition: lib_symbol.cpp:695
LIB_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
std::vector< SEARCH_TERM > GetSearchTerms() override
Definition: lib_symbol.cpp:40
bool IsAlias() const
Definition: lib_symbol.h:215
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:98
LIB_SYMBOL_SPTR m_me
Definition: lib_symbol.h:745
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
bool IsPower() const
Definition: lib_symbol.cpp:704
int Compare(const LIB_SYMBOL &aRhs, int aCompareFlags=0, REPORTER *aReporter=nullptr) const
Comparison test that can be used for operators.
Definition: lib_symbol.cpp:248
void FixupDrawItems()
This function finds the filled draw items that are covering up smaller draw items and replaces their ...
Definition: lib_symbol.cpp:958
static wxString LetterSubReference(int aUnit, int aFirstId)
Definition: lib_symbol.cpp:760
wxString m_name
Definition: lib_symbol.h:768
void SetPower()
Definition: lib_symbol.cpp:718
wxString m_keyWords
Search keywords.
Definition: lib_symbol.h:769
void GetPins(LIB_PINS &aList, int aUnit=0, int aBodyStyle=0) const
Return a list of pin object pointers from the draw item list.
LIB_FIELD & GetFootprintField()
Return reference to the footprint field.
LIB_FIELD & GetDescriptionField()
Return reference to the description field.
void RemoveDuplicateDrawItems()
Remove duplicate draw items from list.
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:596
wxString GetName() const override
Definition: lib_symbol.h:160
void ClearEditFlags()
int m_pinNameOffset
The offset in mils to draw the pin name.
Definition: lib_symbol.h:755
LIB_FIELD * FindField(const wxString &aFieldName, bool aCaseInsensitive=false)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
bool m_showPinNumbers
Definition: lib_symbol.h:758
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.
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, int aMulti, int aBodyStyle, const LIB_SYMBOL_OPTIONS &aOpts, bool aDimmed)
Print symbol.
Definition: lib_symbol.cpp:814
void 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:71
timestamp_t m_lastModDate
Definition: lib_symbol.h:749
double Similarity(const LIB_SYMBOL &aSymbol) const
Return a measure of similarity between this symbol and aSymbol.
LIB_ID m_libId
Definition: lib_symbol.h:747
void SetLib(SYMBOL_LIB *aLibrary)
Definition: lib_symbol.h:220
std::vector< struct LIB_SYMBOL_UNIT > GetUniqueUnits()
Return a list of unit numbers that are unique to this symbol.
const LIB_SYMBOL & operator=(const LIB_SYMBOL &aSymbol)
Definition: lib_symbol.cpp:180
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:752
wxArrayString m_fpFilters
List of suitable footprint names for the symbol (wild card names accepted).
Definition: lib_symbol.h:770
bool m_excludedFromSim
Definition: lib_symbol.h:760
bool HasUnitDisplayName(int aUnit) override
Return true if the given unit aUnit has a display name defined.
Definition: lib_symbol.cpp:545
bool IsNormal() const
Definition: lib_symbol.cpp:732
void PrintBackground(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, int aMulti, int aBodyStyle, const LIB_SYMBOL_OPTIONS &aOpts, bool aDimmed)
Print just the background fills of a symbol.
Definition: lib_symbol.cpp:779
const BOX2I GetBodyBoundingBox(int aUnit, int aBodyStyle, bool aIncludePins, bool aIncludePrivateItems) const
Get the symbol bounding box excluding fields.
LIB_SYMBOL_SPTR SharedPtr() const
Definition: lib_symbol.h:110
bool m_excludedFromBOM
Definition: lib_symbol.h:761
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:539
wxString GetDescription() override
Definition: lib_symbol.h:178
void Plot(PLOTTER *aPlotter, int aUnit, int aBodyStyle, bool aBackground, const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed) const
Plot lib symbol to plotter.
Definition: lib_symbol.cpp:865
std::vector< LIB_PIN * > GetAllLibPins() const
Return a list of pin pointers for all units / converts.
int m_unitCount
Number of units (parts) per package.
Definition: lib_symbol.h:751
void SetHasAlternateBodyStyle(bool aHasAlternate, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
void ClearCaches()
Definition: lib_symbol.cpp:682
unsigned GetInheritanceDepth() const
Get the number of parents for this symbol.
Definition: lib_symbol.cpp:229
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:746
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:605
LIB_FIELD & GetDatasheetField()
Return reference to the datasheet field.
int GetPinCount() override
void deleteAllFields()
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:127
bool m_excludedFromBoard
Definition: lib_symbol.h:762
LIB_SYMBOL_SPTR GetRootSymbol() const
Get the parent symbol that does not have another parent.
Definition: lib_symbol.cpp:527
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:573
void SetOffset(const VECTOR2I &aOffset)
Move the symbol aOffset.
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:589
bool m_showPinNames
Definition: lib_symbol.h:757
void SetNormal()
Definition: lib_symbol.cpp:746
void CopyUnitDisplayNames(std::map< int, wxString > &aTarget) const
Copy all unit display names into the given map aTarget.
Definition: lib_symbol.cpp:564
LIB_ITEM * LocateDrawItem(int aUnit, int aBodyStyle, KICAD_T aType, const VECTOR2I &aPoint)
Locate a draw object.
size_t size(int aType=UNDEFINED_TYPE) const
Definition: multivector.h:226
void sort()
Definition: multivector.h:248
void unique()
Remove duplicate elements in list.
Definition: multivector.h:257
void push_back(T *aItem)
Definition: multivector.h:175
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:165
ITERATOR end(int aType=UNDEFINED_TYPE)
Definition: multivector.h:195
void clear(int aType=UNDEFINED_TYPE)
Definition: multivector.h:213
ITERATOR erase(const ITERATOR &aIterator)
Definition: multivector.h:180
ITERATOR begin(int aType=UNDEFINED_TYPE)
Definition: multivector.h:189
Base plotter engine class.
Definition: plotter.h:104
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:135
bool GetColorMode() const
Definition: plotter.h:132
virtual void SetColor(const COLOR4D &color)=0
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
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: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
TRANSFORM DefaultTransform
Definition: transform.cpp:32
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
@ LAYER_DEVICE
Definition: layer_ids.h:368
@ LAYER_PRIVATE_NOTES
Definition: layer_ids.h:370
@ LAYER_VALUEPART
Definition: layer_ids.h:364
@ LAYER_FIELDS
Definition: layer_ids.h:365
@ LAYER_DEVICE_BACKGROUND
Definition: layer_ids.h:384
@ LAYER_REFERENCEPART
Definition: layer_ids.h:363
@ LAYER_NOTES_BACKGROUND
Definition: layer_ids.h:371
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:393
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:61
#define REPORT(msg)
Definition: lib_symbol.cpp:245
bool operator<(const LIB_SYMBOL &aItem1, const LIB_SYMBOL &aItem2)
Definition: lib_symbol.cpp:83
#define ITEM_DESC(item)
Definition: lib_symbol.cpp:246
@ 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
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_bodyStyle
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:91
void operator()(void const *) const
Definition: lib_symbol.cpp:92
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 5 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ LIB_SYMBOL_T
Definition: typeinfo.h:202
@ TYPE_NOT_INIT
Definition: typeinfo.h:81
@ LIB_SHAPE_T
Definition: typeinfo.h:203
@ LIB_PIN_T
Definition: typeinfo.h:206
@ LIB_FIELD_T
Definition: typeinfo.h:212