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