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