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