KiCad PCB EDA Suite
lib_symbol.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <sch_draw_panel.h>
27 #include <plotters/plotter.h>
28 #include <sch_screen.h>
29 #include <richio.h>
30 #include <general.h>
31 #include <template_fieldnames.h>
32 #include <transform.h>
33 #include <symbol_library.h>
34 #include <lib_pin.h>
35 #include <lib_arc.h>
37 
38 
39 // the separator char between the subpart id and the reference
40 // 0 (no separator) or '.' or some other character
42 
43 // the ascii char value to calculate the subpart symbol id from the part number:
44 // 'A' or '1' usually. (to print U1.A or U1.1)
45 // if this a digit, a number is used as id symbol
47 
48 
50 {
51  // Matches are scored by offset from front of string, so inclusion of this spacer
52  // discounts matches found after it.
53  static const wxString discount( wxT( " " ) );
54 
55  wxString text = GetKeyWords() + discount + GetDescription();
56  wxString footprint = GetFootprintField().GetText();
57 
58  if( !footprint.IsEmpty() )
59  {
60  text += discount + footprint;
61  }
62 
63  return text;
64 }
65 
66 
67 bool operator<( const LIB_SYMBOL& aItem1, const LIB_SYMBOL& aItem2 )
68 {
69  return aItem1.GetName() < aItem2.GetName();
70 }
71 
72 
75 {
76  void operator()(void const *) const
77  {
78  }
79 };
80 
81 
82 LIB_SYMBOL::LIB_SYMBOL( const wxString& aName, LIB_SYMBOL* aParent, SYMBOL_LIB* aLibrary ) :
84  m_me( this, null_deleter() ),
85  m_includeInBom( true ),
86  m_includeOnBoard( true )
87 {
88  m_lastModDate = 0;
89  m_unitCount = 1;
92  m_unitsLocked = false;
93  m_showPinNumbers = true;
94  m_showPinNames = true;
95 
96  // Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
97  // when the field editors are invoked.
98  m_drawings[LIB_FIELD_T].reserve( 4 );
103 
104  SetName( aName );
105 
106  if( aParent )
107  SetParent( aParent );
108 
109  SetLib( aLibrary );
110 }
111 
112 
113 LIB_SYMBOL::LIB_SYMBOL( const LIB_SYMBOL& aSymbol, SYMBOL_LIB* aLibrary ) :
114  EDA_ITEM( aSymbol ),
115  m_me( this, null_deleter() )
116 {
117  LIB_ITEM* newItem;
118 
119  m_library = aLibrary;
120  m_name = aSymbol.m_name;
121  m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
122  m_unitCount = aSymbol.m_unitCount;
123  m_unitsLocked = aSymbol.m_unitsLocked;
126  m_includeInBom = aSymbol.m_includeInBom;
128  m_showPinNames = aSymbol.m_showPinNames;
129  m_lastModDate = aSymbol.m_lastModDate;
130  m_options = aSymbol.m_options;
131  m_libId = aSymbol.m_libId;
132  m_description = aSymbol.m_description;
133  m_keyWords = aSymbol.m_keyWords;
134 
135  ClearSelected();
136 
137  for( const LIB_ITEM& oldItem : aSymbol.m_drawings )
138  {
139  if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
140  continue;
141 
142  try
143  {
144  newItem = (LIB_ITEM*) oldItem.Clone();
145  newItem->ClearSelected();
146  newItem->SetParent( this );
147  m_drawings.push_back( newItem );
148  }
149  catch( ... )
150  {
151  wxFAIL_MSG( "Failed to clone LIB_ITEM." );
152  }
153  }
154 
155  LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
156 
157  if( parent )
158  SetParent( parent.get() );
159 }
160 
161 
163 {
164 }
165 
166 
168 {
169  if( &aSymbol == this )
170  return aSymbol;
171 
172  LIB_ITEM* newItem;
173 
174  m_library = aSymbol.m_library;
175  m_name = aSymbol.m_name;
176  m_fpFilters = wxArrayString( aSymbol.m_fpFilters );
177  m_unitCount = aSymbol.m_unitCount;
178  m_unitsLocked = aSymbol.m_unitsLocked;
181  m_showPinNames = aSymbol.m_showPinNames;
182  m_includeInBom = aSymbol.m_includeInBom;
184  m_lastModDate = aSymbol.m_lastModDate;
185  m_options = aSymbol.m_options;
186  m_libId = aSymbol.m_libId;
187  m_description = aSymbol.m_description;
188  m_keyWords = aSymbol.m_keyWords;
189 
190  m_drawings.clear();
191 
192  for( const LIB_ITEM& oldItem : aSymbol.m_drawings )
193  {
194  if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
195  continue;
196 
197  newItem = (LIB_ITEM*) oldItem.Clone();
198  newItem->SetParent( this );
199  m_drawings.push_back( newItem );
200  }
201 
202  m_drawings.sort();
203 
204  LIB_SYMBOL_SPTR parent = aSymbol.m_parent.lock();
205 
206  if( parent )
207  SetParent( parent.get() );
208 
209  return *this;
210 }
211 
212 
213 int LIB_SYMBOL::Compare( const LIB_SYMBOL& aRhs ) const
214 {
215  if( m_me == aRhs.m_me )
216  return 0;
217 
218  int retv = m_name.Cmp( aRhs.m_name );
219 
220  if( retv )
221  return retv;
222 
223  retv = m_libId.compare( aRhs.m_libId );
224 
225  if( retv )
226  return retv;
227 
228  if( m_parent.lock() < aRhs.m_parent.lock() )
229  return -1;
230 
231  if( m_parent.lock() > aRhs.m_parent.lock() )
232  return 1;
233 
234  if( m_options != aRhs.m_options )
235  return ( m_options == ENTRY_NORMAL ) ? -1 : 1;
236 
237  if( m_unitCount != aRhs.m_unitCount )
238  return m_unitCount - aRhs.m_unitCount;
239 
240  if( m_drawings.size() != aRhs.m_drawings.size() )
241  return m_drawings.size() - aRhs.m_drawings.size();
242 
245 
246  while( lhsItemIt != m_drawings.end() )
247  {
248  const LIB_ITEM* lhsItem = static_cast<const LIB_ITEM*>( &(*lhsItemIt) );
249  const LIB_ITEM* rhsItem = static_cast<const LIB_ITEM*>( &(*rhsItemIt) );
250 
251  wxCHECK( lhsItem && rhsItem, lhsItem - rhsItem );
252 
253  if( lhsItem->Type() != rhsItem->Type() )
254  return lhsItem->Type() - rhsItem->Type();
255 
256  retv = lhsItem->compare( *rhsItem );
257 
258  if( retv )
259  return retv;
260 
261  ++lhsItemIt;
262  ++rhsItemIt;
263  }
264 
265  if( m_fpFilters.GetCount() != aRhs.m_fpFilters.GetCount() )
266  return m_fpFilters.GetCount() - aRhs.m_fpFilters.GetCount();
267 
268  for( size_t i = 0; i < m_fpFilters.GetCount(); i++ )
269  {
270  retv = m_fpFilters[i].Cmp( aRhs.m_fpFilters[i] );
271 
272  if( retv )
273  return retv;
274  }
275 
276  retv = m_description.Cmp( aRhs.m_description );
277 
278  if( retv )
279  return retv;
280 
281  retv = m_keyWords.Cmp( aRhs.m_keyWords );
282 
283  if( retv )
284  return retv;
285 
286  if( m_pinNameOffset != aRhs.m_pinNameOffset )
287  return m_pinNameOffset - aRhs.m_pinNameOffset;
288 
289  if( m_unitsLocked != aRhs.m_unitsLocked )
290  return ( m_unitsLocked ) ? 1 : -1;
291 
292  if( m_showPinNames != aRhs.m_showPinNames )
293  return ( m_showPinNames ) ? 1 : -1;
294 
295  if( m_showPinNumbers != aRhs.m_showPinNumbers )
296  return ( m_showPinNumbers ) ? 1 : -1;
297 
298  if( m_includeInBom != aRhs.m_includeInBom )
299  return ( m_includeInBom ) ? 1 : -1;
300 
301  if( m_includeOnBoard != aRhs.m_includeOnBoard )
302  return ( m_includeOnBoard ) ? 1 : -1;
303 
304  return 0;
305 }
306 
307 
308 wxString LIB_SYMBOL::GetUnitReference( int aUnit )
309 {
310  return LIB_SYMBOL::SubReference( aUnit, false );
311 }
312 
313 
314 void LIB_SYMBOL::SetName( const wxString& aName )
315 {
316  m_name = aName;
317  m_libId.SetLibItemName( aName );
318 
319  GetValueField().SetText( aName );
320 }
321 
322 
324 {
325  if( aParent )
326  m_parent = aParent->SharedPtr();
327  else
328  m_parent.reset();
329 }
330 
331 
332 std::unique_ptr< LIB_SYMBOL > LIB_SYMBOL::Flatten() const
333 {
334  std::unique_ptr< LIB_SYMBOL > retv;
335 
336  if( IsAlias() )
337  {
338  LIB_SYMBOL_SPTR parent = m_parent.lock();
339 
340  wxCHECK_MSG( parent, retv,
341  wxString::Format( "Parent of derived symbol '%s' undefined", m_name ) );
342 
343  // Copy the parent.
344  retv.reset( new LIB_SYMBOL( *parent.get() ) );
345 
346  retv->SetName( m_name );
347 
348  // Now add the inherited part mandatory field (this) information.
349  for( int i = 0; i < MANDATORY_FIELDS; i++ )
350  {
351  wxString tmp = GetFieldById( i )->GetText();
352 
353  // If the field isn't defined then inherit the parent field value.
354  if( tmp.IsEmpty() )
355  retv->GetFieldById( i )->SetText( parent->GetFieldById( i )->GetText() );
356  else
357  *retv->GetFieldById( i ) = *GetFieldById( i );
358  }
359 
360  // Grab all the rest of derived symbol fields.
361  for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
362  {
363  const LIB_FIELD* aliasField = dynamic_cast<const LIB_FIELD*>( &item );
364 
365  wxCHECK2( aliasField, continue );
366 
367  // Mandatory fields were already resolved.
368  if( aliasField->IsMandatory() )
369  continue;
370 
371  LIB_FIELD* newField = new LIB_FIELD( *aliasField );
372  newField->SetParent( retv.get() );
373 
374  LIB_FIELD* parentField = retv->FindField( aliasField->GetName() );
375 
376  if( !parentField ) // Derived symbol field does not exist in parent symbol.
377  {
378  retv->AddDrawItem( newField );
379  }
380  else // Derived symbol field overrides the parent symbol field.
381  {
382  retv->RemoveDrawItem( parentField );
383  retv->AddDrawItem( newField );
384  }
385  }
386 
387  retv->SetKeyWords( m_keyWords.IsEmpty() ? parent->GetKeyWords() : m_keyWords );
388  retv->SetDescription( m_description.IsEmpty() ? parent->GetDescription() : m_description );
389  retv->SetFPFilters( m_fpFilters.IsEmpty() ? parent->GetFPFilters() : m_fpFilters );
390  }
391  else
392  {
393  retv.reset( new LIB_SYMBOL( *this ) );
394  }
395 
396  return retv;
397 }
398 
399 
400 const wxString LIB_SYMBOL::GetLibraryName() const
401 {
402  if( m_library )
403  return m_library->GetName();
404 
405  return m_libId.GetLibNickname();
406 }
407 
408 
410 {
411  if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
412  return parent->m_options == ENTRY_POWER;
413 
414  return m_options == ENTRY_POWER;
415 }
416 
417 
419 {
420  if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
421  parent->m_options = ENTRY_POWER;
422 
424 }
425 
426 
428 {
429  if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
430  return parent->m_options == ENTRY_NORMAL;
431 
432  return m_options == ENTRY_NORMAL;
433 }
434 
435 
437 {
438  if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
439  parent->m_options = ENTRY_NORMAL;
440 
442 }
443 
444 
445 wxString LIB_SYMBOL::SubReference( int aUnit, bool aAddSeparator )
446 {
447  wxString subRef;
448 
449  if( m_subpartIdSeparator != 0 && aAddSeparator )
450  subRef << wxChar( m_subpartIdSeparator );
451 
452  if( m_subpartFirstId >= '0' && m_subpartFirstId <= '9' )
453  subRef << aUnit;
454  else
455  {
456  // use letters as notation. To allow more than 26 units, the sub ref
457  // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
458  // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
459  int u;
460  aUnit -= 1; // Unit number starts to 1. now to 0.
461 
462  while( aUnit >= 26 ) // more than one letter are needed
463  {
464  u = aUnit / 26;
465  subRef << wxChar( m_subpartFirstId + u -1 );
466  aUnit %= 26;
467  }
468 
469  u = m_subpartFirstId + aUnit;
470  subRef << wxChar( u );
471  }
472 
473  return subRef;
474 }
475 
476 
477 void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
478  int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS& aOpts )
479 {
480  /* draw background for filled items using background option
481  * Solid lines will be drawn after the background
482  * Note also, background is not drawn when printing in black and white
483  */
484  if( !GetGRForceBlackPenState() )
485  {
486  for( LIB_ITEM& drawItem : m_drawings )
487  {
488  if( drawItem.m_fill != FILL_TYPE::FILLED_WITH_BG_BODYCOLOR )
489  continue;
490 
491  // Do not draw items not attached to the current part
492  if( aMulti && drawItem.m_unit && ( drawItem.m_unit != aMulti ) )
493  continue;
494 
495  if( aConvert && drawItem.m_convert && ( drawItem.m_convert != aConvert ) )
496  continue;
497 
498  if( drawItem.Type() == LIB_FIELD_T )
499  continue;
500 
501  // Now, draw only the background for items with
502  // m_fill == FILLED_WITH_BG_BODYCOLOR:
503  drawItem.Print( aSettings, aOffset, (void*) false, aOpts.transform );
504  }
505  }
506 
507  for( LIB_ITEM& drawItem : m_drawings )
508  {
509  // Do not draw items not attached to the current part
510  if( aMulti && drawItem.m_unit && ( drawItem.m_unit != aMulti ) )
511  continue;
512 
513  if( aConvert && drawItem.m_convert && ( drawItem.m_convert != aConvert ) )
514  continue;
515 
516  if( drawItem.Type() == LIB_FIELD_T )
517  {
518  LIB_FIELD& field = static_cast<LIB_FIELD&>( drawItem );
519 
520  if( field.IsVisible() && !aOpts.draw_visible_fields )
521  continue;
522 
523  if( !field.IsVisible() && !aOpts.draw_hidden_fields )
524  continue;
525  }
526 
527  if( drawItem.Type() == LIB_PIN_T )
528  {
529  drawItem.Print( aSettings, aOffset, (void*) &aOpts, aOpts.transform );
530  }
531  else if( drawItem.Type() == LIB_FIELD_T )
532  {
533  drawItem.Print( aSettings, aOffset, (void*) nullptr, aOpts.transform );
534  }
535  else
536  {
537  bool forceNoFill = drawItem.m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR;
538  drawItem.Print( aSettings, aOffset, (void*) forceNoFill, aOpts.transform );
539  }
540  }
541 }
542 
543 
544 void LIB_SYMBOL::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset,
545  const TRANSFORM& aTransform ) const
546 {
547  wxASSERT( aPlotter != nullptr );
548 
549  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
550  bool fill = aPlotter->GetColorMode();
551 
552  // draw background for filled items using background option
553  // Solid lines will be drawn after the background
554  for( const LIB_ITEM& item : m_drawings )
555  {
556  // Lib Fields are not plotted here, because this plot function
557  // is used to plot schematic items, which have they own fields
558  if( item.Type() == LIB_FIELD_T )
559  continue;
560 
561  if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
562  continue;
563 
564  if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
565  continue;
566 
567  if( item.m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR )
568  item.Plot( aPlotter, aOffset, fill, aTransform );
569  }
570 
571  // Not filled items and filled shapes are now plotted
572  // Items that have BG fills only get re-stroked to ensure the edges are in the foreground
573  for( const LIB_ITEM& item : m_drawings )
574  {
575  if( item.Type() == LIB_FIELD_T )
576  continue;
577 
578  if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
579  continue;
580 
581  if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
582  continue;
583 
584  item.Plot( aPlotter, aOffset,
585  fill && ( item.m_fill != FILL_TYPE::FILLED_WITH_BG_BODYCOLOR ), aTransform );
586  }
587 }
588 
589 
590 void LIB_SYMBOL::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert,
591  const wxPoint& aOffset, const TRANSFORM& aTransform )
592 {
593  wxASSERT( aPlotter != nullptr );
594 
595  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_FIELDS ) );
596  bool fill = aPlotter->GetColorMode();
597 
598  for( LIB_ITEM& item : m_drawings )
599  {
600  if( item.Type() != LIB_FIELD_T )
601  continue;
602 
603  if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
604  continue;
605 
606  if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
607  continue;
608 
609  LIB_FIELD& field = (LIB_FIELD&) item;
610 
611  // The reference is a special case: we should change the basic text
612  // to add '?' and the part id
613  wxString tmp = field.GetShownText();
614 
615  if( field.GetId() == REFERENCE_FIELD )
616  {
617  wxString text = field.GetFullText( aUnit );
618  field.SetText( text );
619  }
620 
621  item.Plot( aPlotter, aOffset, fill, aTransform );
622  field.SetText( tmp );
623  }
624 }
625 
626 
628 {
629  wxASSERT( aItem != nullptr );
630 
631  // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
632  // omitted when saving to disk.
633  if( aItem->Type() == LIB_FIELD_T )
634  {
635  if( static_cast<LIB_FIELD*>( aItem )->IsMandatory() )
636  return;
637  }
638 
639  LIB_ITEMS& items = m_drawings[ aItem->Type() ];
640 
641  for( LIB_ITEMS::iterator i = items.begin(); i != items.end(); i++ )
642  {
643  if( &*i == aItem )
644  {
645  items.erase( i );
646  SetModified();
647  break;
648  }
649  }
650 }
651 
652 
653 void LIB_SYMBOL::AddDrawItem( LIB_ITEM* aItem, bool aSort )
654 {
655  wxCHECK( aItem, /* void */ );
656 
657  m_drawings.push_back( aItem );
658 
659  if( aSort )
660  m_drawings.sort();
661 }
662 
663 
665 {
666  if( aItem == nullptr )
667  {
669 
670  return (it1 != m_drawings.end( aType ) ) ? &( *( m_drawings.begin( aType ) ) ) : nullptr;
671  }
672 
673  // Search for the last item, assume aItem is of type aType
674  wxASSERT( ( aType == TYPE_NOT_INIT ) || ( aType == aItem->Type() ) );
676 
677  while( ( it != m_drawings.end( aType ) ) && ( aItem != &( *it ) ) )
678  ++it;
679 
680  // Search the next item
681  if( it != m_drawings.end( aType ) )
682  {
683  ++it;
684 
685  if( it != m_drawings.end( aType ) )
686  return &( *it );
687  }
688 
689  return nullptr;
690 }
691 
692 
693 void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
694 {
695  /* Notes:
696  * when aUnit == 0: no unit filtering
697  * when aConvert == 0: no convert (shape selection) filtering
698  * when m_unit == 0, the body item is common to units
699  * when m_convert == 0, the body item is common to shapes
700  */
701 
702  LIB_SYMBOL_SPTR parent = m_parent.lock();
703  const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
704 
705  for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
706  {
707  // Unit filtering:
708  if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
709  continue;
710 
711  // Shape filtering:
712  if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
713  continue;
714 
715  aList.push_back( (LIB_PIN*) &item );
716  }
717 }
718 
719 
720 LIB_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aConvert ) const
721 {
722  LIB_PINS pinList;
723 
724  GetPins( pinList, aUnit, aConvert );
725 
726  for( size_t i = 0; i < pinList.size(); i++ )
727  {
728  wxASSERT( pinList[i]->Type() == LIB_PIN_T );
729 
730  if( aNumber == pinList[i]->GetNumber() )
731  return pinList[i];
732  }
733 
734  return nullptr;
735 }
736 
737 
738 bool LIB_SYMBOL::PinsConflictWith( const LIB_SYMBOL& aOtherPart, bool aTestNums, bool aTestNames,
739  bool aTestType, bool aTestOrientation, bool aTestLength ) const
740 {
741  LIB_PINS thisPinList;
742  GetPins( thisPinList, /* aUnit */ 0, /* aConvert */ 0 );
743 
744  for( const LIB_PIN* eachThisPin : thisPinList )
745  {
746  wxASSERT( eachThisPin );
747  LIB_PINS otherPinList;
748  aOtherPart.GetPins( otherPinList, /* aUnit */ 0, /* aConvert */ 0 );
749  bool foundMatch = false;
750 
751  for( const LIB_PIN* eachOtherPin : otherPinList )
752  {
753  wxASSERT( eachOtherPin );
754 
755  // Same unit?
756  if( eachThisPin->GetUnit() != eachOtherPin->GetUnit() )
757  continue;
758 
759  // Same body stype?
760  if( eachThisPin->GetConvert() != eachOtherPin->GetConvert() )
761  continue;
762 
763  // Same position?
764  if( eachThisPin->GetPosition() != eachOtherPin->GetPosition() )
765  continue;
766 
767  // Same number?
768  if( aTestNums && ( eachThisPin->GetNumber() != eachOtherPin->GetNumber() ) )
769  continue;
770 
771  // Same name?
772  if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ) )
773  continue;
774 
775  // Same electrical type?
776  if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ) )
777  continue;
778 
779  // Same orientation?
780  if( aTestOrientation
781  && ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ) )
782  continue;
783 
784  // Same length?
785  if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ) )
786  continue;
787 
788  foundMatch = true;
789  break; // Match found so search is complete.
790  }
791 
792  if( !foundMatch )
793  {
794  // This means there was not an identical (according to the arguments)
795  // pin at the same position in the other symbol.
796  return true;
797  }
798  }
799 
800  // The loop never gave up, so no conflicts were found.
801  return false;
802 }
803 
804 
805 const EDA_RECT LIB_SYMBOL::GetUnitBoundingBox( int aUnit, int aConvert ) const
806 {
807  EDA_RECT bBox;
808  bool initialized = false;
809 
810  for( const LIB_ITEM& item : m_drawings )
811  {
812  if( item.m_unit > 0
813  && m_unitCount > 1
814  && aUnit > 0
815  && aUnit != item.m_unit )
816  {
817  continue;
818  }
819 
820  if( item.m_convert > 0 && aConvert > 0 && aConvert != item.m_convert )
821  continue;
822 
823  if ( ( item.Type() == LIB_FIELD_T ) && !( ( LIB_FIELD& ) item ).IsVisible() )
824  continue;
825 
826  if( initialized )
827  bBox.Merge( item.GetBoundingBox() );
828  else
829  {
830  bBox = item.GetBoundingBox();
831  initialized = true;
832  }
833  }
834 
835  return bBox;
836 }
837 
838 
839 void LIB_SYMBOL::ViewGetLayers( int aLayers[], int& aCount ) const
840 {
841  aCount = 6;
842  aLayers[0] = LAYER_DEVICE;
843  aLayers[1] = LAYER_DEVICE_BACKGROUND;
844  aLayers[2] = LAYER_REFERENCEPART;
845  aLayers[3] = LAYER_VALUEPART;
846  aLayers[4] = LAYER_FIELDS;
847  aLayers[5] = LAYER_SELECTION_SHADOWS;
848 }
849 
850 
851 const EDA_RECT LIB_SYMBOL::GetBodyBoundingBox( int aUnit, int aConvert ) const
852 {
853  EDA_RECT bbox;
854 
855  for( const LIB_ITEM& item : m_drawings )
856  {
857  if( item.m_unit > 0 && aUnit > 0 && aUnit != item.m_unit )
858  continue;
859 
860  if( item.m_convert > 0 && aConvert > 0 && aConvert != item.m_convert )
861  continue;
862 
863  if( item.Type() == LIB_FIELD_T )
864  continue;
865 
866  if( item.Type() == LIB_PIN_T )
867  bbox.Merge( static_cast<const LIB_PIN&>( item ).GetBoundingBox( false, true ) );
868  else
869  bbox.Merge( item.GetBoundingBox() );
870  }
871 
872  return bbox;
873 }
874 
875 
877 {
879 }
880 
881 
883 {
884  AddDrawItem( aField );
885 }
886 
887 
888 void LIB_SYMBOL::SetFields( const std::vector <LIB_FIELD>& aFields )
889 {
890  deleteAllFields();
891 
892  for( unsigned i=0; i<aFields.size(); ++i )
893  {
894  // drawings is a ptr_vector, new and copy an object on the heap.
895  LIB_FIELD* field = new LIB_FIELD( aFields[i] );
896 
897  field->SetParent( this );
898  m_drawings.push_back( field );
899  }
900 
901  m_drawings.sort();
902 }
903 
904 
905 void LIB_SYMBOL::GetFields( std::vector<LIB_FIELD*>& aList )
906 {
907  // Grab the MANDATORY_FIELDS first, in expected order given by enum MANDATORY_FIELD_T
908  for( int id = 0; id < MANDATORY_FIELDS; ++id )
909  aList.push_back( GetFieldById( id ) );
910 
911  // Now grab all the rest of fields.
912  for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
913  {
914  LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
915 
916  if( !field->IsMandatory() )
917  aList.push_back( field );
918  }
919 }
920 
921 
922 void LIB_SYMBOL::GetFields( std::vector<LIB_FIELD>& aList )
923 {
924  // Grab the MANDATORY_FIELDS first, in expected order given by enum MANDATORY_FIELD_T
925  for( int id = 0; id < MANDATORY_FIELDS; ++id )
926  aList.push_back( *GetFieldById( id ) );
927 
928  // Now grab all the rest of fields.
929  for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
930  {
931  LIB_FIELD* field = static_cast<LIB_FIELD*>( &item );
932 
933  if( !field->IsMandatory() )
934  aList.push_back( *field );
935  }
936 }
937 
938 
940 {
941  for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
942  {
943  LIB_FIELD* field = ( LIB_FIELD* ) &item;
944 
945  if( field->GetId() == aId )
946  return field;
947  }
948 
949  return nullptr;
950 }
951 
952 
953 LIB_FIELD* LIB_SYMBOL::FindField( const wxString& aFieldName )
954 {
955  for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
956  {
957  if( static_cast<LIB_FIELD*>( &item )->GetCanonicalName() == aFieldName )
958  return static_cast<LIB_FIELD*>( &item );
959  }
960 
961  return nullptr;
962 }
963 
964 
965 const LIB_FIELD* LIB_SYMBOL::FindField( const wxString& aFieldName ) const
966 {
967  for( const LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
968  {
969  if( static_cast<const LIB_FIELD*>( &item )->GetCanonicalName() == aFieldName )
970  return static_cast<const LIB_FIELD*>( &item );
971  }
972 
973  return nullptr;
974 }
975 
976 
978 {
979  LIB_FIELD* field = GetFieldById( VALUE_FIELD );
980  wxASSERT( field != nullptr );
981  return *field;
982 }
983 
984 
986 {
988  wxASSERT( field != nullptr );
989  return *field;
990 }
991 
992 
994 {
996  wxASSERT( field != nullptr );
997  return *field;
998 }
999 
1000 
1002 {
1004  wxASSERT( field != nullptr );
1005  return *field;
1006 }
1007 
1008 
1009 void LIB_SYMBOL::SetOffset( const wxPoint& aOffset )
1010 {
1011  for( LIB_ITEM& item : m_drawings )
1012  item.Offset( aOffset );
1013 }
1014 
1015 
1017 {
1018  m_drawings.unique();
1019 }
1020 
1021 
1023 {
1024  for( const LIB_ITEM& item : m_drawings )
1025  {
1026  if( item.m_convert > LIB_ITEM::LIB_CONVERT::BASE )
1027  return true;
1028  }
1029 
1030  if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1031  {
1032  for( const LIB_ITEM& item : parent->GetDrawItems() )
1033  {
1034  if( item.m_convert > LIB_ITEM::LIB_CONVERT::BASE )
1035  return true;
1036  }
1037  }
1038 
1039  return false;
1040 }
1041 
1042 
1044 {
1045  for( LIB_ITEM& item : m_drawings )
1046  item.ClearTempFlags();
1047 }
1048 
1049 
1051 {
1052  for( LIB_ITEM& item : m_drawings )
1053  item.ClearEditFlags();
1054 }
1055 
1056 
1057 LIB_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aConvert,
1058  KICAD_T aType, const wxPoint& aPoint )
1059 {
1060  for( LIB_ITEM& item : m_drawings )
1061  {
1062  if( ( aUnit && item.m_unit && aUnit != item.m_unit )
1063  || ( aConvert && item.m_convert && aConvert != item.m_convert )
1064  || ( item.Type() != aType && aType != TYPE_NOT_INIT ) )
1065  {
1066  continue;
1067  }
1068 
1069  if( item.HitTest( aPoint ) )
1070  return &item;
1071  }
1072 
1073  return nullptr;
1074 }
1075 
1076 
1077 LIB_ITEM* LIB_SYMBOL::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
1078  const wxPoint& aPoint, const TRANSFORM& aTransform )
1079 {
1080  /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
1081  * wxPoint& pt ) to search items.
1082  * because this function uses DefaultTransform as orient/mirror matrix
1083  * we temporary copy aTransform in DefaultTransform
1084  */
1085  LIB_ITEM* item;
1086  TRANSFORM transform = DefaultTransform;
1087  DefaultTransform = aTransform;
1088 
1089  item = LocateDrawItem( aUnit, aConvert, aType, aPoint );
1090 
1091  // Restore matrix
1092  DefaultTransform = transform;
1093 
1094  return item;
1095 }
1096 
1097 
1098 SEARCH_RESULT LIB_SYMBOL::Visit( INSPECTOR aInspector, void* aTestData,
1099  const KICAD_T aFilterTypes[] )
1100 {
1101  // The part itself is never inspected, only its children
1102  for( LIB_ITEM& item : m_drawings )
1103  {
1104  if( item.IsType( aFilterTypes ) )
1105  {
1106  if( aInspector( &item, aTestData ) == SEARCH_RESULT::QUIT )
1107  return SEARCH_RESULT::QUIT;
1108  }
1109  }
1110 
1111  return SEARCH_RESULT::CONTINUE;
1112 }
1113 
1114 
1115 void LIB_SYMBOL::SetUnitCount( int aCount, bool aDuplicateDrawItems )
1116 {
1117  if( m_unitCount == aCount )
1118  return;
1119 
1120  if( aCount < m_unitCount )
1121  {
1123 
1124  while( i != m_drawings.end() )
1125  {
1126  if( i->m_unit > aCount )
1127  i = m_drawings.erase( i );
1128  else
1129  ++i;
1130  }
1131  }
1132  else if( aDuplicateDrawItems )
1133  {
1134  int prevCount = m_unitCount;
1135 
1136  // Temporary storage for new items, as adding new items directly to
1137  // m_drawings may cause the buffer reallocation which invalidates the
1138  // iterators
1139  std::vector< LIB_ITEM* > tmp;
1140 
1141  for( LIB_ITEM& item : m_drawings )
1142  {
1143  if( item.m_unit != 1 )
1144  continue;
1145 
1146  for( int j = prevCount + 1; j <= aCount; j++ )
1147  {
1148  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1149  newItem->m_unit = j;
1150  tmp.push_back( newItem );
1151  }
1152  }
1153 
1154  for( auto item : tmp )
1155  m_drawings.push_back( item );
1156  }
1157 
1158  m_drawings.sort();
1159  m_unitCount = aCount;
1160 }
1161 
1162 
1164 {
1165  if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
1166  return parent->GetUnitCount();
1167 
1168  return m_unitCount;
1169 }
1170 
1171 
1172 void LIB_SYMBOL::SetConversion( bool aSetConvert, bool aDuplicatePins )
1173 {
1174  if( aSetConvert == HasConversion() )
1175  return;
1176 
1177  // Duplicate items to create the converted shape
1178  if( aSetConvert )
1179  {
1180  if( aDuplicatePins )
1181  {
1182  std::vector< LIB_ITEM* > tmp; // Temporarily store the duplicated pins here.
1183 
1184  for( LIB_ITEM& item : m_drawings )
1185  {
1186  // Only pins are duplicated.
1187  if( item.Type() != LIB_PIN_T )
1188  continue;
1189 
1190  if( item.m_convert == 1 )
1191  {
1192  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1193  newItem->m_convert = 2;
1194  tmp.push_back( newItem );
1195  }
1196  }
1197 
1198  // Transfer the new pins to the LIB_SYMBOL.
1199  for( unsigned i = 0; i < tmp.size(); i++ )
1200  m_drawings.push_back( tmp[i] );
1201  }
1202  }
1203  else
1204  {
1205  // Delete converted shape items because the converted shape does
1206  // not exist
1208 
1209  while( i != m_drawings.end() )
1210  {
1211  if( i->m_convert > 1 )
1212  i = m_drawings.erase( i );
1213  else
1214  ++i;
1215  }
1216  }
1217 
1218  m_drawings.sort();
1219 }
1220 
1221 
1222 void LIB_SYMBOL::SetSubpartIdNotation( int aSep, int aFirstId )
1223 {
1224  m_subpartFirstId = 'A';
1226 
1227  if( aSep == '.' || aSep == '-' || aSep == '_' )
1228  m_subpartIdSeparator = aSep;
1229 
1230  if( aFirstId == '1' && aSep != 0 )
1231  m_subpartFirstId = aFirstId;
1232 }
1233 
1234 
1235 std::vector<LIB_ITEM*> LIB_SYMBOL::GetUnitItems( int aUnit, int aConvert )
1236 {
1237  std::vector<LIB_ITEM*> unitItems;
1238 
1239  for( LIB_ITEM& item : m_drawings )
1240  {
1241  if( item.Type() == LIB_FIELD_T )
1242  continue;
1243 
1244  if( ( aConvert == -1 && item.GetUnit() == aUnit )
1245  || ( aUnit == -1 && item.GetConvert() == aConvert )
1246  || ( aUnit == item.GetUnit() && aConvert == item.GetConvert() ) )
1247  unitItems.push_back( &item );
1248  }
1249 
1250  return unitItems;
1251 }
1252 
1253 
1254 std::vector<struct LIB_SYMBOL_UNITS> LIB_SYMBOL::GetUnitDrawItems()
1255 {
1256  std::vector<struct LIB_SYMBOL_UNITS> units;
1257 
1258  for( LIB_ITEM& item : m_drawings )
1259  {
1260  if( item.Type() == LIB_FIELD_T )
1261  continue;
1262 
1263  int unit = item.GetUnit();
1264  int convert = item.GetConvert();
1265 
1266  auto it = std::find_if( units.begin(), units.end(),
1267  [unit, convert] ( const auto& a ) {
1268  return a.m_unit == unit && a.m_convert == convert;
1269  } );
1270 
1271  if( it == units.end() )
1272  {
1273  struct LIB_SYMBOL_UNITS newUnit;
1274  newUnit.m_unit = item.GetUnit();
1275  newUnit.m_convert = item.GetConvert();
1276  newUnit.m_items.push_back( &item );
1277  units.emplace_back( newUnit );
1278  }
1279  else
1280  {
1281  it->m_items.push_back( &item );
1282  }
1283  }
1284 
1285  return units;
1286 }
1287 
1288 
1289 std::vector<struct LIB_SYMBOL_UNITS> LIB_SYMBOL::GetUniqueUnits()
1290 {
1291  int unitNum;
1292  size_t i;
1293  struct LIB_SYMBOL_UNITS unit;
1294  std::vector<LIB_ITEM*> compareDrawItems;
1295  std::vector<LIB_ITEM*> currentDrawItems;
1296  std::vector<struct LIB_SYMBOL_UNITS> uniqueUnits;
1297 
1298  // The first unit is guaranteed to be unique so always include it.
1299  unit.m_unit = 1;
1300  unit.m_convert = 1;
1301  unit.m_items = GetUnitItems( 1, 1 );
1302 
1303  // There are no unique units if there are no draw items other than fields.
1304  if( unit.m_items.size() == 0 )
1305  return uniqueUnits;
1306 
1307  uniqueUnits.emplace_back( unit );
1308 
1309  if( ( GetUnitCount() == 1 || UnitsLocked() ) && !HasConversion() )
1310  return uniqueUnits;
1311 
1312  currentDrawItems = unit.m_items;
1313 
1314  for( unitNum = 2; unitNum <= GetUnitCount(); unitNum++ )
1315  {
1316  compareDrawItems = GetUnitItems( unitNum, 1 );
1317 
1318  wxCHECK2_MSG( compareDrawItems.size() != 0, continue,
1319  "Multiple unit symbol defined with empty units." );
1320 
1321  if( currentDrawItems.size() != compareDrawItems.size() )
1322  {
1323  unit.m_unit = unitNum;
1324  unit.m_convert = 1;
1325  unit.m_items = compareDrawItems;
1326  uniqueUnits.emplace_back( unit );
1327  }
1328  else
1329  {
1330  for( i = 0; i < currentDrawItems.size(); i++ )
1331  {
1332  if( currentDrawItems[i]->compare( *compareDrawItems[i],
1333  LIB_ITEM::COMPARE_FLAGS::UNIT ) != 0 )
1334  {
1335  unit.m_unit = unitNum;
1336  unit.m_convert = 1;
1337  unit.m_items = compareDrawItems;
1338  uniqueUnits.emplace_back( unit );
1339  }
1340  }
1341  }
1342  }
1343 
1344  if( HasConversion() )
1345  {
1346  currentDrawItems = GetUnitItems( 1, 2 );
1347 
1348  if( ( GetUnitCount() == 1 || UnitsLocked() ) )
1349  {
1350  unit.m_unit = 1;
1351  unit.m_convert = 2;
1352  unit.m_items = currentDrawItems;
1353  uniqueUnits.emplace_back( unit );
1354 
1355  return uniqueUnits;
1356  }
1357 
1358  for( unitNum = 2; unitNum <= GetUnitCount(); unitNum++ )
1359  {
1360  compareDrawItems = GetUnitItems( unitNum, 2 );
1361 
1362  wxCHECK2_MSG( compareDrawItems.size() != 0, continue,
1363  "Multiple unit symbol defined with empty units." );
1364 
1365  if( currentDrawItems.size() != compareDrawItems.size() )
1366  {
1367  unit.m_unit = unitNum;
1368  unit.m_convert = 2;
1369  unit.m_items = compareDrawItems;
1370  uniqueUnits.emplace_back( unit );
1371  }
1372  else
1373  {
1374  for( i = 0; i < currentDrawItems.size(); i++ )
1375  {
1376  if( currentDrawItems[i]->compare( *compareDrawItems[i],
1377  LIB_ITEM::COMPARE_FLAGS::UNIT ) != 0 )
1378  {
1379  unit.m_unit = unitNum;
1380  unit.m_convert = 2;
1381  unit.m_items = compareDrawItems;
1382  uniqueUnits.emplace_back( unit );
1383  }
1384  }
1385  }
1386  }
1387  }
1388 
1389  return uniqueUnits;
1390 }
Field Reference of part, i.e. "IC21".
bool m_showPinNumbers
Definition: lib_symbol.h:674
LIB_FIELD * FindField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
Definition: lib_symbol.cpp:953
void GetPins(LIB_PINS &aList, int aUnit=0, int aConvert=0) const
Return a list of pin object pointers from the draw item list.
Definition: lib_symbol.cpp:693
void SetModified()
Definition: eda_item.cpp:65
LIB_SYMBOL_SPTR SharedPtr() const
Definition: lib_symbol.h:107
ITERATOR begin(int aType=UNDEFINED_TYPE)
Definition: multivector.h:188
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
Definition: lib_symbol.cpp:888
bool operator<(const LIB_SYMBOL &aItem1, const LIB_SYMBOL &aItem2)
Definition: lib_symbol.cpp:67
void Merge(const EDA_RECT &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: eda_rect.cpp:432
void AddField(LIB_FIELD *aField)
Add a field.
Definition: lib_symbol.cpp:882
std::vector< LIB_ITEM * > m_items
The items unique to this unit and alternate body style.
Definition: lib_symbol.h:86
LIB_FIELD & GetFootprintField()
Return reference to the footprint field.
Definition: lib_symbol.cpp:993
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
bool m_showPinNames
Definition: lib_symbol.h:673
#define IS_NEW
New item, just created.
Object used to load, save, search, and otherwise manipulate symbol library files.
std::vector< struct LIB_SYMBOL_UNITS > GetUniqueUnits()
Return a list of unit numbers that are unique to this symbol.
wxString GetName() const override
Definition: lib_symbol.h:133
void SetOffset(const wxPoint &aOffset)
Move the symbol aOffset.
void ClearSelected()
Definition: eda_item.h:132
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:55
void SetConversion(bool aSetConvert, bool aDuplicatePins=true)
Set or clear the alternate body style (DeMorgan) for the symbol.
void clear(int aType=UNDEFINED_TYPE)
Definition: multivector.h:212
Field object used in symbol libraries.
Definition: lib_field.h:59
void unique()
Remove duplicate elements in list.
Definition: multivector.h:256
bool IsAlias() const
Definition: lib_symbol.h:172
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per symbol count.
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
Definition: lib_symbol.h:42
void sort()
Definition: multivector.h:247
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxString m_description
Definition: lib_symbol.h:684
bool IsPower() const
Definition: lib_symbol.cpp:409
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:445
int GetId() const
Definition: lib_field.h:115
void SetLib(SYMBOL_LIB *aLibrary)
Definition: lib_symbol.h:177
LIB_FIELD & GetValueField()
Return reference to the value field.
Definition: lib_symbol.cpp:977
void RemoveDrawItem(LIB_ITEM *aItem)
Remove draw aItem from list.
Definition: lib_symbol.cpp:627
wxString m_name
Definition: lib_symbol.h:683
bool draw_visible_fields
Definition: lib_symbol.h:65
LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS
Definition: lib_symbol.h:48
Define a library symbol object.
Definition: lib_symbol.h:96
void PlotLibFields(PLOTTER *aPlotter, int aUnit, int aConvert, const wxPoint &aOffset, const TRANSFORM &aTransform)
Plot Lib Fields only of the symbol to plotter.
Definition: lib_symbol.cpp:590
void ClearEditFlags()
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:332
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:158
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
Definition: lib_symbol.cpp:985
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:94
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:116
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
Definition: lib_field.cpp:362
name of datasheet
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:83
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
Definition: lib_symbol.cpp:905
bool PinsConflictWith(const LIB_SYMBOL &aOtherSymbol, bool aTestNums, bool aTestNames, bool aTestType, bool aTestOrientation, bool aTestLength) const
Return true if this symbol's pins do not match another symbol's pins.
Definition: lib_symbol.cpp:738
timestamp_t m_lastModDate
Definition: lib_symbol.h:665
TRANSFORM transform
Definition: lib_symbol.h:64
ITERATOR end(int aType=UNDEFINED_TYPE)
Definition: multivector.h:194
LIB_SYMBOL_REF m_parent
Use for inherited symbols.
Definition: lib_symbol.h:663
int Compare(const LIB_SYMBOL &aRhs) const
Comparison test that can be used for operators.
Definition: lib_symbol.cpp:213
wxString GetSearchText() override
Definition: lib_symbol.cpp:49
const LIB_SYMBOL & operator=(const LIB_SYMBOL &aSymbol)
Definition: lib_symbol.cpp:167
bool HasConversion() const
Test if symbol has more than one body conversion type (DeMorgan).
int m_unit
Unit identification for multiple parts per package.
Definition: lib_item.h:327
std::vector< struct LIB_SYMBOL_UNITS > GetUnitDrawItems()
Return a list of LIB_ITEM objects separated by unit and convert number.
void operator()(void const *) const
Definition: lib_symbol.cpp:76
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
void RemoveDuplicateDrawItems()
Remove duplicate draw items from list.
wxString GetKeyWords() const
Definition: lib_symbol.h:155
Field Value of part, i.e. "3.3K".
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:114
const wxString GetName() const
Return the file name without path or extension.
virtual bool IsVisible() const
Definition: eda_text.h:186
bool m_unitsLocked
True if symbol has multiple units and changing one unit does not automatically change another unit.
Definition: lib_symbol.h:668
void push_back(T *aItem)
Definition: multivector.h:174
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:314
bool m_includeOnBoard
Definition: lib_symbol.h:677
int m_convert
Shape identification for alternate body styles.
Definition: lib_item.h:333
int GetUnitCount() const override
For items with units, return the number of units.
const EDA_RECT GetUnitBoundingBox(int aUnit, int aConvert) const
Get the bounding box for the symbol.
Definition: lib_symbol.cpp:805
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: lib_symbol.cpp:839
int m_unit
The unit number.
Definition: lib_symbol.h:84
void deleteAllFields()
Definition: lib_symbol.cpp:876
Definition for symbol library class.
#define STRUCT_DELETED
flag indication structures to be erased
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:653
void SetParent(LIB_SYMBOL *aParent=nullptr)
Definition: lib_symbol.cpp:323
#define DEFAULT_PIN_NAME_OFFSET
The intersheets references prefix string.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:108
bool UnitsLocked() const
Check whether symbol units are interchangeable.
Definition: lib_symbol.h:241
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:155
const EDA_RECT GetBodyBoundingBox(int aUnit, int aConvert) const
Get the symbol bounding box excluding fields.
Definition: lib_symbol.cpp:851
void ClearTempFlags()
Clears the status flag all draw objects in this symbol.
ITERATOR erase(const ITERATOR &aIterator)
Definition: multivector.h:179
virtual void SetColor(const COLOR4D &color)=0
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
Definition: lib_symbol.cpp:74
int m_convert
The alternate body style of the unit.
Definition: lib_symbol.h:85
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
ITERATOR_BASE< LIB_ITEM, MULTIVECTOR< LIB_ITEM, FIRST_TYPE_VAL, LAST_TYPE_VAL >, typename ITEM_PTR_VECTOR::iterator > ITERATOR
The const iterator.
Definition: multivector.h:164
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
void Print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset, int aMulti, int aConvert, const LIB_SYMBOL_OPTIONS &aOpts)
Print symbol.
Definition: lib_symbol.cpp:477
LIB_ITEMS_CONTAINER m_drawings
Definition: lib_symbol.h:680
Base plotter engine class.
Definition: plotter.h:121
LIB_ITEM * LocateDrawItem(int aUnit, int aConvert, KICAD_T aType, const wxPoint &aPoint)
Locate a draw object.
LIB_FIELD * GetFieldById(int aId) const
Return pointer to the requested field.
Definition: lib_symbol.cpp:939
bool m_includeInBom
Definition: lib_symbol.h:676
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
TRANSFORM DefaultTransform
Definition: eeschema.cpp:56
std::vector< LIB_ITEM * > GetUnitItems(int aUnit, int aConvert)
Return a list of item pointers for aUnit and aConvert for this symbol.
void SetPower()
Definition: lib_symbol.cpp:418
static int m_subpartFirstId
the ASCII char value to calculate the subpart symbol id from the symbol number: only 'A',...
Definition: lib_symbol.h:692
LIB_FIELD & GetDatasheetField()
Return reference to the datasheet field.
Handle the component boundary box.
Definition: eda_rect.h:42
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: lib_field.cpp:294
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
const wxString GetLibraryName() const
Definition: lib_symbol.cpp:400
wxString GetUnitReference(int aUnit) override
Return an identifier for aUnit for symbols with units.
Definition: lib_symbol.cpp:308
LIB_SYMBOL(const wxString &aName, LIB_SYMBOL *aParent=nullptr, SYMBOL_LIB *aLibrary=nullptr)
Definition: lib_symbol.cpp:82
ITERATOR_BASE< const LIB_ITEM, const MULTIVECTOR< LIB_ITEM, FIRST_TYPE_VAL, LAST_TYPE_VAL >, typename ITEM_PTR_VECTOR::const_iterator > CONST_ITERATOR
Definition: multivector.h:167
LIB_ITEM * GetNextDrawItem(const LIB_ITEM *aItem=nullptr, KICAD_T aType=TYPE_NOT_INIT)
Return the next draw object pointer.
Definition: lib_symbol.cpp:664
virtual ~LIB_SYMBOL()
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
Definition: lib_symbol.cpp:162
LIB_SYMBOL_SPTR m_me
Definition: lib_symbol.h:662
int m_pinNameOffset
The offset in mils to draw the pin name.
Definition: lib_symbol.h:671
wxArrayString m_fpFilters
List of suitable footprint names for the symbol (wild card names accepted).
Definition: lib_symbol.h:686
bool IsNormal() const
Definition: lib_symbol.cpp:427
LIB_ID m_libId
Definition: lib_symbol.h:664
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:196
wxString m_keyWords
Search keywords.
Definition: lib_symbol.h:685
SEARCH_RESULT
Definition: eda_item.h:41
wxString GetDescription() override
Definition: lib_symbol.h:142
static void SetSubpartIdNotation(int aSep, int aFirstId)
Set the separator char between the subpart id and the reference 0 (no separator) or '.
void Plot(PLOTTER *aPlotter, int aUnit, int aConvert, const wxPoint &aOffset, const TRANSFORM &aTransform) const
Plot lib symbol to plotter.
Definition: lib_symbol.cpp:544
LIBRENTRYOPTIONS m_options
Special symbol features such as POWER or NORMAL.)
Definition: lib_symbol.h:678
int m_unitCount
Number of units (parts) per package.
Definition: lib_symbol.h:667
static int m_subpartIdSeparator
the separator char between the subpart id and the reference like U1A ( m_subpartIdSeparator = 0 ) or ...
Definition: lib_symbol.h:689
virtual int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:74
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
size_t size(int aType=UNDEFINED_TYPE) const
Definition: multivector.h:225
LIB_PIN * GetPin(const wxString &aNumber, int aUnit=0, int aConvert=0) const
Return pin object with the requested pin aNumber.
Definition: lib_symbol.cpp:720
virtual wxString GetShownText(int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:141
SYMBOL_LIB * m_library
Definition: lib_symbol.h:682
void SetNormal()
Definition: lib_symbol.cpp:436
bool IsMandatory() const
Definition: lib_field.cpp:450
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
Field Name Module PCB, i.e. "16DIP300".
bool GetColorMode() const
Definition: plotter.h:153