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