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