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-2017 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 
30 #include <fctsys.h>
31 #include <macros.h>
32 #include <kicad_string.h>
33 #include <class_drawpanel.h>
34 #include <class_plotter.h>
35 #include <gr_basic.h>
36 #include <class_sch_screen.h>
37 #include <richio.h>
38 
39 #include <general.h>
40 #include <template_fieldnames.h>
41 #include <transform.h>
42 #include <class_library.h>
43 #include <class_libentry.h>
44 #include <lib_pin.h>
45 #include <lib_arc.h>
46 #include <lib_bezier.h>
47 #include <lib_circle.h>
48 #include <lib_polyline.h>
49 #include <lib_rectangle.h>
50 #include <lib_text.h>
51 
52 
53 // the separator char between the subpart id and the reference
54 // 0 (no separator) or '.' or some other character
56 
57 // the ascii char value to calculate the subpart symbol id from the part number:
58 // 'A' or '1' usually. (to print U1.A or U1.1)
59 // if this a a digit, a number is used as id symbol
61 
62 
63 const wxChar traceSchLibMem[] = wxT( "KICAD_TRACE_SCH_LIB_MEM" ); // public
64 
65 
66 LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_PART* aRootPart ):
68  shared( aRootPart )
69 {
70  name = aName;
71 }
72 
73 
74 LIB_ALIAS::LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootPart ) :
75  EDA_ITEM( aAlias ),
76  shared( aRootPart )
77 {
78  name = aAlias.name;
79 
80  description = aAlias.description;
81  keyWords = aAlias.keyWords;
82  docFileName = aAlias.docFileName;
83 }
84 
85 
87 {
88  wxASSERT_MSG( shared, wxT( "~LIB_ALIAS() without a LIB_PART" ) );
89 
90  wxLogTrace( traceSchLibMem,
91  wxT( "%s: destroying alias:'%s' of part:'%s'." ),
92  GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( name ),
93  GetChars( shared->GetName() ) );
94 
95  if( shared )
96  shared->RemoveAlias( this );
97 }
98 
99 
101 {
102  wxASSERT_MSG( shared, wxT( "LIB_ALIAS without a LIB_PART" ) );
103 
104  if( shared )
105  return shared->GetLibraryName();
106 
107  return wxString( _( "none" ) );
108 }
109 
110 
111 bool LIB_ALIAS::IsRoot() const
112 {
113  return name == shared->GetName();
114 }
115 
116 
118 {
119  return shared->GetLib();
120 }
121 
122 
123 bool LIB_ALIAS::operator==( const wxChar* aName ) const
124 {
125  return name == aName;
126 }
127 
128 
129 bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 )
130 {
131  return aItem1.GetName() < aItem2.GetName();
132 }
133 
134 
135 int LibraryEntryCompare( const LIB_ALIAS* aItem1, const LIB_ALIAS* aItem2 )
136 {
137  return aItem1->GetName().Cmp( aItem2->GetName() );
138 }
139 
140 
143 {
144  void operator()(void const *) const
145  {
146  }
147 };
148 
149 
150 LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) :
151  EDA_ITEM( LIB_PART_T ),
152  m_me( this, null_deleter() )
153 {
154  m_dateLastEdition = 0;
155  m_unitCount = 1;
156  m_pinNameOffset = 40;
158  m_unitsLocked = false;
159  m_showPinNumbers = true;
160  m_showPinNames = true;
161 
162  // Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
163  // when the field editors are invoked.
168 
169  SetLib( aLibrary );
170  SetName( aName );
171 }
172 
173 
174 LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
175  EDA_ITEM( aPart ),
176  m_me( this, null_deleter() )
177 {
178  LIB_ITEM* newItem;
179 
180  m_library = aLibrary;
182  m_unitCount = aPart.m_unitCount;
188  m_options = aPart.m_options;
189  m_libId = aPart.m_libId;
190 
191  for( LIB_ITEM& oldItem : aPart.m_drawings )
192  {
193  if( oldItem.IsNew() )
194  continue;
195 
196  newItem = (LIB_ITEM*) oldItem.Clone();
197  newItem->SetParent( this );
198  m_drawings.push_back( newItem );
199  }
200 
201  for( size_t i = 0; i < aPart.m_aliases.size(); i++ )
202  {
203  LIB_ALIAS* alias = new LIB_ALIAS( *aPart.m_aliases[i], this );
204  m_aliases.push_back( alias );
205  }
206 }
207 
208 
210 {
211  wxLogTrace( traceSchLibMem,
212  wxT( "%s: destroying part '%s' with alias list count of %llu." ),
213  GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( GetName() ),
214  (long long unsigned) m_aliases.size() );
215 
216  // If the part is being deleted directly rather than through the library,
217  // delete all of the aliases.
218  while( m_aliases.size() )
219  {
220  LIB_ALIAS* alias = m_aliases.back();
221  m_aliases.pop_back();
222  delete alias;
223  }
224 }
225 
226 
227 const wxString LIB_PART::GetLibraryName()
228 {
229  if( m_library )
230  return m_library->GetName();
231 
232  return wxString( _( "none" ) );
233 }
234 
235 
236 wxString LIB_PART::SubReference( int aUnit, bool aAddSeparator )
237 {
238  wxString subRef;
239 
240  if( m_subpartIdSeparator != 0 && aAddSeparator )
241  subRef << wxChar( m_subpartIdSeparator );
242 
243  if( m_subpartFirstId >= '0' && m_subpartFirstId <= '9' )
244  subRef << aUnit;
245  else
246  {
247  // use letters as notation. To allow more than 26 units, the sub ref
248  // use one letter if letter = A .. Z or a ... z, and 2 letters otherwise
249  // first letter is expected to be 'A' or 'a' (i.e. 26 letters are available)
250  int u;
251  aUnit -= 1; // Unit number starts to 1. now to 0.
252 
253  while( aUnit >= 26 ) // more than one letter are needed
254  {
255  u = aUnit / 26;
256  subRef << wxChar( m_subpartFirstId + u -1 );
257  aUnit %= 26;
258  }
259 
260  u = m_subpartFirstId + aUnit;
261  subRef << wxChar( u );
262  }
263 
264  return subRef;
265 }
266 
267 
268 void LIB_PART::SetName( const wxString& aName )
269 {
270  m_libId.SetLibItemName( aName, false );
271 
272  // The LIB_ALIAS that is the LIB_PART name has to be created so create it.
273  if( m_aliases.size() == 0 )
274  m_aliases.push_back( new LIB_ALIAS( aName, this ) );
275  else
276  m_aliases[0]->SetName( aName );
277 
278  LIB_FIELD& valueField = GetValueField();
279 
280  // LIB_FIELD::SetText() calls LIB_PART::SetName(),
281  // the following if-clause is to break an infinite loop
282  if( valueField.GetText() != aName )
283  valueField.SetText( aName );
284 
285 }
286 
287 
288 void LIB_PART::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOffset,
289  int aMulti, int aConvert, const PART_DRAW_OPTIONS& aOpts )
290 {
291  BASE_SCREEN* screen = aPanel ? aPanel->GetScreen() : NULL;
292 
293  GRSetDrawMode( aDc, aOpts.draw_mode );
294 
295  /* draw background for filled items using background option
296  * Solid lines will be drawn after the background
297  * Note also, background is not drawn when:
298  * printing in black and white
299  * If the color is not the default color (aColor != -1 )
300  */
301  if( ! ( screen && screen->m_IsPrinting && GetGRForceBlackPenState() )
302  && ( aOpts.color == COLOR4D::UNSPECIFIED ) )
303  {
304  for( LIB_ITEM& drawItem : m_drawings )
305  {
306  if( drawItem.m_Fill != FILLED_WITH_BG_BODYCOLOR )
307  continue;
308 
309  if( aOpts.only_selected && !drawItem.IsSelected() )
310  continue;
311 
312  // Do not draw an item while moving (the cursor handler does that)
313  if( drawItem.m_Flags & IS_MOVED )
314  continue;
315 
316  // Do not draw items not attached to the current part
317  if( aMulti && drawItem.m_Unit && ( drawItem.m_Unit != aMulti ) )
318  continue;
319 
320  if( aConvert && drawItem.m_Convert && ( drawItem.m_Convert != aConvert ) )
321  continue;
322 
323  if( drawItem.Type() == LIB_FIELD_T )
324  continue;
325 
326  if( drawItem.Type() == LIB_FIELD_T ) // TODO dead code?
327  {
328  drawItem.Draw( aPanel, aDc, aOffset, aOpts.color,
329  aOpts.draw_mode, (void*) NULL, aOpts.transform );
330  }
331 
332  // Now, draw only the background for items with
333  // m_Fill == FILLED_WITH_BG_BODYCOLOR:
334  drawItem.Draw( aPanel, aDc, aOffset, aOpts.color,
335  aOpts.draw_mode, (void*) false, aOpts.transform );
336  }
337  }
338 
339  // Track the index into the dangling pins list
340  size_t pin_index = 0;
341 
342  for( LIB_ITEM& drawItem : m_drawings )
343  {
344  if( aOpts.only_selected && !drawItem.IsSelected() )
345  continue;
346 
347  // Do not draw an item while moving (the cursor handler does that)
348  if( drawItem.m_Flags & IS_MOVED )
349  continue;
350 
351  // Do not draw items not attached to the current part
352  if( aMulti && drawItem.m_Unit && ( drawItem.m_Unit != aMulti ) )
353  continue;
354 
355  if( aConvert && drawItem.m_Convert && ( drawItem.m_Convert != aConvert ) )
356  continue;
357 
358  if( drawItem.Type() == LIB_FIELD_T )
359  {
360  LIB_FIELD& field = dynamic_cast<LIB_FIELD&>( drawItem );
361 
362  if( field.IsVisible() && !aOpts.draw_visible_fields )
363  continue;
364 
365  if( !field.IsVisible() && !aOpts.draw_hidden_fields )
366  continue;
367  }
368 
369  if( drawItem.Type() == LIB_PIN_T )
370  {
371  LIB_PIN& pin = dynamic_cast<LIB_PIN&>( drawItem );
372 
373  uintptr_t flags = 0;
374  if( aOpts.show_pin_text )
375  flags |= PIN_DRAW_TEXTS;
376 
377  if( aOpts.show_elec_type )
379 
380  if( aOpts.PinIsDangling( pin_index ) )
381  flags |= PIN_DRAW_DANGLING;
382 
383  if( pin.IsPowerConnection() && IsPower() )
384  flags |= PIN_DANGLING_HIDDEN;
385 
386  drawItem.Draw( aPanel, aDc, aOffset, aOpts.color,
387  aOpts.draw_mode, (void*) flags, aOpts.transform );
388 
389  ++pin_index;
390  }
391  else if( drawItem.Type() == LIB_FIELD_T )
392  {
393  drawItem.Draw( aPanel, aDc, aOffset, aOpts.color,
394  aOpts.draw_mode, (void*) NULL, aOpts.transform );
395  }
396  else
397  {
398  bool forceNoFill = drawItem.m_Fill == FILLED_WITH_BG_BODYCOLOR;
399  drawItem.Draw( aPanel, aDc, aOffset, aOpts.color,
400  aOpts.draw_mode, (void*) forceNoFill,
401  aOpts.transform );
402  }
403  }
404 
405  // Enable this to draw the anchor of the component.
406 #if 0
407  int len = aDc->DeviceToLogicalXRel( 3 );
408  EDA_RECT* const clipbox = aPanel ? aPanel->GetClipBox() : NULL;
409 
410  GRLine( clipbox, aDc, aOffset.x, aOffset.y - len, aOffset.x,
411  aOffset.y + len, 0, aOpts.color );
412  GRLine( clipbox, aDc, aOffset.x - len, aOffset.y, aOffset.x + len,
413  aOffset.y, 0, aOpts.color );
414 #endif
415 
416  /* Enable this to draw the bounding box around the component to validate
417  * the bounding box calculations. */
418 #if 0
419  EDA_RECT bBox = GetUnitBoundingBox( aMulti, aConvert );
420  bBox.RevertYAxis();
421  bBox = aOpts.transform.TransformCoordinate( bBox );
422  bBox.Move( aOffset );
423  GRRect( aPanel ? aPanel->GetClipBox() : NULL, aDc, bBox, 0, LIGHTMAGENTA );
424 #endif
425 }
426 
427 
428 void LIB_PART::Plot( PLOTTER* aPlotter, int aUnit, int aConvert,
429  const wxPoint& aOffset, const TRANSFORM& aTransform )
430 {
431  wxASSERT( aPlotter != NULL );
432 
433  aPlotter->SetColor( GetLayerColor( LAYER_DEVICE ) );
434  bool fill = aPlotter->GetColorMode();
435 
436  // draw background for filled items using background option
437  // Solid lines will be drawn after the background
438  for( LIB_ITEM& item : m_drawings )
439  {
440  // Lib Fields are not plotted here, because this plot function
441  // is used to plot schematic items, which have they own fields
442  if( item.Type() == LIB_FIELD_T )
443  continue;
444 
445  if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
446  continue;
447 
448  if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
449  continue;
450 
451  if( item.m_Fill == FILLED_WITH_BG_BODYCOLOR )
452  item.Plot( aPlotter, aOffset, fill, aTransform );
453  }
454 
455  // Not filled items and filled shapes are now plotted
456  // (plot only items which are not already plotted)
457  for( LIB_ITEM& item : m_drawings )
458  {
459  if( item.Type() == LIB_FIELD_T )
460  continue;
461 
462  if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
463  continue;
464 
465  if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
466  continue;
467 
468  if( item.m_Fill != FILLED_WITH_BG_BODYCOLOR )
469  item.Plot( aPlotter, aOffset, fill, aTransform );
470  }
471 }
472 
473 
474 void LIB_PART::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert,
475  const wxPoint& aOffset, const TRANSFORM& aTransform )
476 {
477  wxASSERT( aPlotter != NULL );
478 
479  aPlotter->SetColor( GetLayerColor( LAYER_FIELDS ) );
480  bool fill = aPlotter->GetColorMode();
481 
482  for( LIB_ITEM& item : m_drawings )
483  {
484  if( item.Type() != LIB_FIELD_T )
485  continue;
486 
487  if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
488  continue;
489 
490  if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
491  continue;
492 
493  // The reference is a special case: we should change the basic text
494  // to add '?' and the part id
495  LIB_FIELD& field = (LIB_FIELD&) item;
496  wxString tmp = field.GetShownText();
497  if( field.GetId() == REFERENCE )
498  {
499  wxString text = field.GetFullText( aUnit );
500  field.SetText( text );
501  }
502  item.Plot( aPlotter, aOffset, fill, aTransform );
503  field.SetText( tmp );
504  }
505 }
506 
507 
508 void LIB_PART::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxDC* aDc )
509 {
510  wxASSERT( aItem != NULL );
511 
512  // none of the MANDATORY_FIELDS may be removed in RAM, but they may be
513  // omitted when saving to disk.
514  if( aItem->Type() == LIB_FIELD_T )
515  {
516  LIB_FIELD* field = (LIB_FIELD*) aItem;
517 
518  if( field->GetId() < MANDATORY_FIELDS )
519  {
520  wxLogWarning( _(
521  "An attempt was made to remove the %s field from component %s in library %s." ),
522  GetChars( field->GetName() ), GetChars( GetName() ),
523  GetChars( GetLibraryName() ) );
524  return;
525  }
526  }
527 
528  LIB_ITEMS& items = m_drawings[ aItem->Type() ];
529 
530  for( LIB_ITEMS::iterator i = items.begin(); i != items.end(); i++ )
531  {
532  if( *i == aItem )
533  {
534  if( aDc != NULL )
535  aItem->Draw( aPanel, aDc, wxPoint( 0, 0 ), COLOR4D::UNSPECIFIED,
536  g_XorMode, NULL, DefaultTransform );
537 
538  items.erase( i );
539  SetModified();
540  break;
541  }
542  }
543 }
544 
545 
547 {
548  wxASSERT( aItem != NULL );
549 
550  m_drawings.push_back( aItem );
551 }
552 
553 
555 {
556  if( m_drawings.empty( aType ) )
557  return NULL;
558 
559  if( aItem == NULL )
560  return &( *( m_drawings.begin( aType ) ) );
561 
562  // Search for the last item, assume aItem is of type aType
563  wxASSERT( ( aType == TYPE_NOT_INIT ) || ( aType == aItem->Type() ) );
565 
566  while( ( it != m_drawings.end( aType ) ) && ( aItem != &( *it ) ) )
567  ++it;
568 
569  // Search the next item
570  if( it != m_drawings.end( aType ) )
571  {
572  ++it;
573 
574  if( it != m_drawings.end( aType ) )
575  return &( *it );
576  }
577 
578  return NULL;
579 }
580 
581 
582 void LIB_PART::GetPins( LIB_PINS& aList, int aUnit, int aConvert )
583 {
584  if( m_drawings.empty( LIB_PIN_T ) )
585  return;
586 
587  /* Notes:
588  * when aUnit == 0: no unit filtering
589  * when aConvert == 0: no convert (shape selection) filtering
590  * when .m_Unit == 0, the body item is common to units
591  * when .m_Convert == 0, the body item is common to shapes
592  */
593  for( LIB_ITEM& item : m_drawings[ LIB_PIN_T ] )
594  {
595  // Unit filtering:
596  if( aUnit && item.m_Unit && ( item.m_Unit != aUnit ) )
597  continue;
598 
599  // Shape filtering:
600  if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
601  continue;
602 
603  aList.push_back( (LIB_PIN*) &item );
604  }
605 }
606 
607 
608 LIB_PIN* LIB_PART::GetPin( const wxString& aNumber, int aUnit, int aConvert )
609 {
610  LIB_PINS pinList;
611 
612  GetPins( pinList, aUnit, aConvert );
613 
614  for( size_t i = 0; i < pinList.size(); i++ )
615  {
616  wxASSERT( pinList[i]->Type() == LIB_PIN_T );
617 
618  if( aNumber == pinList[i]->GetNumber() )
619  return pinList[i];
620  }
621 
622  return NULL;
623 }
624 
625 
626 bool LIB_PART::PinsConflictWith( LIB_PART& aOtherPart, bool aTestNums, bool aTestNames,
627  bool aTestType, bool aTestOrientation, bool aTestLength )
628 {
629  LIB_PINS thisPinList;
630  GetPins( thisPinList, /* aUnit */ 0, /* aConvert */ 0 );
631 
632  for( LIB_PIN* eachThisPin : thisPinList )
633  {
634  wxASSERT( eachThisPin );
635  LIB_PINS otherPinList;
636  aOtherPart.GetPins( otherPinList, /* aUnit */ 0, /* aConvert */ 0 );
637  bool foundMatch = false;
638 
639  for( LIB_PIN* eachOtherPin : otherPinList )
640  {
641  wxASSERT( eachOtherPin );
642  // Same position?
643  if( eachThisPin->GetPosition() != eachOtherPin->GetPosition() )
644  continue;
645 
646  // Same number?
647  if( aTestNums && ( eachThisPin->GetNumber() != eachOtherPin->GetNumber() ))
648  continue;
649 
650  // Same name?
651  if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ))
652  continue;
653 
654  // Same electrical type?
655  if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ))
656  continue;
657 
658  // Same orientation?
659  if( aTestOrientation && ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ))
660  continue;
661 
662  // Same length?
663  if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ))
664  continue;
665 
666  foundMatch = true;
667  }
668 
669  if( !foundMatch )
670  {
671  // This means there was not an identical (according to the arguments)
672  // pin at the same position in the other component.
673  return true;
674  }
675  }
676 
677  // The loop never gave up, so no conflicts were found.
678  return false;
679 }
680 
681 
682 const EDA_RECT LIB_PART::GetUnitBoundingBox( int aUnit, int aConvert ) const
683 {
684  EDA_RECT bBox;
685  bool initialized = false;
686 
687  for( const LIB_ITEM& item : m_drawings )
688  {
689  if( ( item.m_Unit > 0 ) && ( ( m_unitCount > 1 ) && ( aUnit > 0 )
690  && ( aUnit != item.m_Unit ) ) )
691  continue;
692 
693  if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) )
694  continue;
695 
696  if ( ( item.Type() == LIB_FIELD_T ) && !( ( LIB_FIELD& ) item ).IsVisible() )
697  continue;
698 
699  if( initialized )
700  bBox.Merge( item.GetBoundingBox() );
701  else
702  {
703  bBox = item.GetBoundingBox();
704  initialized = true;
705  }
706  }
707 
708  return bBox;
709 }
710 
711 
712 const EDA_RECT LIB_PART::GetBodyBoundingBox( int aUnit, int aConvert ) const
713 {
714  EDA_RECT bBox;
715  bool initialized = false;
716 
717  for( const LIB_ITEM& item : m_drawings )
718  {
719  if( ( item.m_Unit > 0 ) && ( ( m_unitCount > 1 ) && ( aUnit > 0 )
720  && ( aUnit != item.m_Unit ) ) )
721  continue;
722 
723  if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) )
724  continue;
725 
726  if( item.Type() == LIB_FIELD_T )
727  continue;
728 
729  if( initialized )
730  bBox.Merge( item.GetBoundingBox() );
731  else
732  {
733  bBox = item.GetBoundingBox();
734  initialized = true;
735  }
736  }
737 
738  return bBox;
739 }
740 
741 
743 {
744  m_drawings[ LIB_FIELD_T ].clear();
745 }
746 
747 
748 void LIB_PART::SetFields( const std::vector <LIB_FIELD>& aFields )
749 {
750  deleteAllFields();
751 
752  for( unsigned i=0; i<aFields.size(); ++i )
753  {
754  // drawings is a ptr_vector, new and copy an object on the heap.
755  LIB_FIELD* field = new LIB_FIELD( aFields[i] );
756 
757  field->SetParent( this );
758  m_drawings.push_back( field );
759  }
760 }
761 
762 
764 {
765  LIB_FIELD* field;
766 
767  // The only caller of this function is the library field editor, so it
768  // establishes policy here.
769 
770  // Grab the MANDATORY_FIELDS first, in expected order given by
771  // enum NumFieldType
772  for( int id=0; id<MANDATORY_FIELDS; ++id )
773  {
774  field = GetField( id );
775 
776  // the MANDATORY_FIELDS are exactly that in RAM.
777  wxASSERT( field );
778 
779  aList.push_back( *field );
780  }
781 
782  // Now grab all the rest of fields.
783  for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
784  {
785  field = ( LIB_FIELD* ) &item;
786 
787  if( (unsigned) field->GetId() < MANDATORY_FIELDS )
788  continue; // was added above
789 
790  aList.push_back( *field );
791  }
792 }
793 
794 
796 {
797  for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
798  {
799  LIB_FIELD* field = ( LIB_FIELD* ) &item;
800 
801  if( field->GetId() == aId )
802  return field;
803  }
804 
805  return NULL;
806 }
807 
808 
809 LIB_FIELD* LIB_PART::FindField( const wxString& aFieldName )
810 {
811  for( LIB_ITEM& item : m_drawings[ LIB_FIELD_T ] )
812  {
813  LIB_FIELD* field = ( LIB_FIELD* ) &item;
814 
815  if( field->GetName() == aFieldName )
816  return field;
817  }
818 
819  return NULL;
820 }
821 
822 
824 {
825  LIB_FIELD* field = GetField( VALUE );
826  wxASSERT( field != NULL );
827  return *field;
828 }
829 
830 
832 {
833  LIB_FIELD* field = GetField( REFERENCE );
834  wxASSERT( field != NULL );
835  return *field;
836 }
837 
838 
840 {
841  LIB_FIELD* field = GetField( FOOTPRINT );
842  wxASSERT( field != NULL );
843  return *field;
844 }
845 
846 
848 {
849  int year, mon, day, hour, min, sec;
850 
851  if( m_dateLastEdition == 0 )
852  return true;
853 
854  sec = m_dateLastEdition & 63;
855  min = ( m_dateLastEdition >> 6 ) & 63;
856  hour = ( m_dateLastEdition >> 12 ) & 31;
857  day = ( m_dateLastEdition >> 17 ) & 31;
858  mon = ( m_dateLastEdition >> 22 ) & 15;
859  year = ( m_dateLastEdition >> 26 ) + 1990;
860 
861  aFormatter.Print( 0, "Ti %d/%d/%d %d:%d:%d\n", year, mon, day, hour, min, sec );
862 
863  return true;
864 }
865 
866 
867 bool LIB_PART::LoadDateAndTime( char* aLine )
868 {
869  int year, mon, day, hour, min, sec;
870 
871  year = mon = day = hour = min = sec = 0;
872  strtok( aLine, " \r\t\n" );
873  strtok( NULL, " \r\t\n" );
874 
875  if( sscanf( aLine, "%d/%d/%d %d:%d:%d", &year, &mon, &day, &hour, &min, &sec ) != 6 )
876  return false;
877 
878  m_dateLastEdition = ( sec & 63 ) + ( ( min & 63 ) << 6 ) +
879  ( ( hour & 31 ) << 12 ) + ( ( day & 31 ) << 17 ) +
880  ( ( mon & 15 ) << 22 ) + ( ( year - 1990 ) << 26 );
881 
882  return true;
883 }
884 
885 
886 void LIB_PART::SetOffset( const wxPoint& aOffset )
887 {
888  for( LIB_ITEM& item : m_drawings )
889  item.SetOffset( aOffset );
890 }
891 
892 
894 {
895  m_drawings.unique();
896 }
897 
898 
900 {
901  for( const LIB_ITEM& item : m_drawings )
902  {
903  if( item.m_Convert > 1 )
904  return true;
905  }
906 
907  return false;
908 }
909 
910 
912 {
913  for( LIB_ITEM& item : m_drawings )
914  {
915  item.m_Flags = 0;
916  }
917 }
918 
919 
920 int LIB_PART::SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool aEditPinByPin )
921 {
922  int itemCount = 0;
923 
924  for( LIB_ITEM& item : m_drawings )
925  {
926  item.ClearFlags( SELECTED );
927 
928  if( ( item.m_Unit && item.m_Unit != aUnit )
929  || ( item.m_Convert && item.m_Convert != aConvert ) )
930  {
931  if( item.Type() != LIB_PIN_T )
932  continue;
933 
934  // Specific rules for pins.
935  if( aEditPinByPin || m_unitsLocked
936  || ( item.m_Convert && item.m_Convert != aConvert ) )
937  continue;
938  }
939 
940  if( item.Inside( aRect ) )
941  {
942  item.SetFlags( SELECTED );
943  itemCount++;
944  }
945  }
946 
947  return itemCount;
948 }
949 
950 
951 void LIB_PART::MoveSelectedItems( const wxPoint& aOffset )
952 {
953  for( LIB_ITEM& item : m_drawings )
954  {
955  if( !item.IsSelected() )
956  continue;
957 
958  item.SetOffset( aOffset );
959  item.m_Flags = 0;
960  }
961 }
962 
963 
965 {
966  for( LIB_ITEM& item : m_drawings )
967  {
968  item.m_Flags = 0;
969  }
970 }
971 
972 
974 {
976 
977  // We *do not* remove the 2 mandatory fields: reference and value
978  // so skip them (do not remove) if they are flagged selected.
979  // Skip also not visible items.
980  // But I think fields must not be deleted by a block delete command or other global command
981  // because they are not really graphic items
982  while( item != m_drawings.end() )
983  {
984  if( item->Type() == LIB_FIELD_T )
985  {
986  item->ClearFlags( SELECTED );
987  }
988 
989  if( !item->IsSelected() )
990  ++item;
991  else
992  item = m_drawings.erase( item );
993  }
994 }
995 
996 
997 void LIB_PART::CopySelectedItems( const wxPoint& aOffset )
998 {
999  std::vector< LIB_ITEM* > tmp;
1000 
1001  for( LIB_ITEM& item : m_drawings )
1002  {
1003  // We *do not* copy fields because they are unique for the whole component
1004  // so skip them (do not duplicate) if they are flagged selected.
1005  if( item.Type() == LIB_FIELD_T )
1006  item.ClearFlags( SELECTED );
1007 
1008  if( !item.IsSelected() )
1009  continue;
1010 
1011  item.ClearFlags( SELECTED );
1012  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1013  newItem->SetFlags( SELECTED );
1014 
1015  // When push_back elements in buffer, a memory reallocation can happen
1016  // and will break pointers.
1017  // So, push_back later.
1018  tmp.push_back( newItem );
1019  }
1020 
1021  for( auto item : tmp )
1022  m_drawings.push_back( item );
1023 
1024  MoveSelectedItems( aOffset );
1025 }
1026 
1027 
1029 {
1030  for( LIB_ITEM& item : m_drawings )
1031  {
1032  if( !item.IsSelected() )
1033  continue;
1034 
1035  item.MirrorHorizontal( aCenter );
1036  item.m_Flags = 0;
1037  }
1038 }
1039 
1040 
1042 {
1043  for( LIB_ITEM& item : m_drawings )
1044  {
1045  if( !item.IsSelected() )
1046  continue;
1047 
1048  item.MirrorVertical( aCenter );
1049  item.m_Flags = 0;
1050  }
1051 }
1052 
1053 
1055 {
1056  for( LIB_ITEM& item : m_drawings )
1057  {
1058  if( !item.IsSelected() )
1059  continue;
1060 
1061  item.Rotate( aCenter );
1062  item.m_Flags = 0;
1063  }
1064 }
1065 
1066 
1067 LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert,
1068  KICAD_T aType, const wxPoint& aPoint )
1069 {
1070  for( LIB_ITEM& item : m_drawings )
1071  {
1072  if( ( aUnit && item.m_Unit && ( aUnit != item.m_Unit) )
1073  || ( aConvert && item.m_Convert && ( aConvert != item.m_Convert ) )
1074  || ( ( item.Type() != aType ) && ( aType != TYPE_NOT_INIT ) ) )
1075  continue;
1076 
1077  if( item.HitTest( aPoint ) )
1078  return &item;
1079  }
1080 
1081  return NULL;
1082 }
1083 
1084 
1085 LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType,
1086  const wxPoint& aPoint, const TRANSFORM& aTransform )
1087 {
1088  /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const
1089  * wxPoint& pt ) to search items.
1090  * because this function uses DefaultTransform as orient/mirror matrix
1091  * we temporary copy aTransform in DefaultTransform
1092  */
1093  LIB_ITEM* item;
1094  TRANSFORM transform = DefaultTransform;
1095  DefaultTransform = aTransform;
1096 
1097  item = LocateDrawItem( aUnit, aConvert, aType, aPoint );
1098 
1099  // Restore matrix
1100  DefaultTransform = transform;
1101 
1102  return item;
1103 }
1104 
1105 
1106 void LIB_PART::SetUnitCount( int aCount )
1107 {
1108  if( m_unitCount == aCount )
1109  return;
1110 
1111  if( aCount < m_unitCount )
1112  {
1114 
1115  while( i != m_drawings.end() )
1116  {
1117  if( i->m_Unit > aCount )
1118  i = m_drawings.erase( i );
1119  else
1120  ++i;
1121  }
1122  }
1123  else
1124  {
1125  int prevCount = m_unitCount;
1126 
1127  // Temporary storage for new items, as adding new items directly to
1128  // m_drawings may cause the buffer reallocation which invalidates the
1129  // iterators
1130  std::vector< LIB_ITEM* > tmp;
1131 
1132  for( LIB_ITEM& item : m_drawings )
1133  {
1134  if( item.m_Unit != 1 )
1135  continue;
1136 
1137  for( int j = prevCount + 1; j <= aCount; j++ )
1138  {
1139  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1140  newItem->m_Unit = j;
1141  tmp.push_back( newItem );
1142  }
1143  }
1144 
1145  for( auto item : tmp )
1146  m_drawings.push_back( item );
1147  }
1148 
1149  m_unitCount = aCount;
1150 }
1151 
1152 
1153 void LIB_PART::SetConversion( bool aSetConvert )
1154 {
1155  if( aSetConvert == HasConversion() )
1156  return;
1157 
1158  // Duplicate items to create the converted shape
1159  if( aSetConvert )
1160  {
1161  std::vector< LIB_ITEM* > tmp; // Temporarily store the duplicated pins here.
1162 
1163  for( LIB_ITEM& item : m_drawings )
1164  {
1165  // Only pins are duplicated.
1166  if( item.Type() != LIB_PIN_T )
1167  continue;
1168 
1169  if( item.m_Convert == 1 )
1170  {
1171  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
1172  newItem->m_Convert = 2;
1173  tmp.push_back( newItem );
1174  }
1175  }
1176 
1177  // Transfer the new pins to the LIB_PART.
1178  for( unsigned i = 0; i < tmp.size(); i++ )
1179  m_drawings.push_back( tmp[i] );
1180  }
1181  else
1182  {
1183  // Delete converted shape items because the converted shape does
1184  // not exist
1186 
1187  while( i != m_drawings.end() )
1188  {
1189  if( i->m_Convert > 1 )
1190  i = m_drawings.erase( i );
1191  else
1192  ++i;
1193  }
1194  }
1195 }
1196 
1197 
1198 void LIB_PART::SetLib( PART_LIB* aLibrary )
1199 {
1200  m_library = aLibrary;
1201 
1202  if( aLibrary )
1203  m_libId.SetLibNickname( aLibrary->GetName() );
1204 }
1205 
1206 
1207 wxArrayString LIB_PART::GetAliasNames( bool aIncludeRoot ) const
1208 {
1209  wxArrayString names;
1210 
1211  LIB_ALIASES::const_iterator it;
1212 
1213  for( it=m_aliases.begin(); it != m_aliases.end(); ++it )
1214  {
1215  if( !aIncludeRoot && (*it)->IsRoot() )
1216  continue;
1217 
1218  names.Add( (*it)->GetName() );
1219  }
1220 
1221  return names;
1222 }
1223 
1224 
1225 bool LIB_PART::HasAlias( const wxString& aName ) const
1226 {
1227  wxCHECK2_MSG( !aName.IsEmpty(), return false,
1228  wxT( "Cannot get alias with an empty name, bad programmer." ) );
1229 
1230  for( size_t i = 0; i < m_aliases.size(); i++ )
1231  {
1232  if( aName == m_aliases[i]->GetName() )
1233  return true;
1234  }
1235 
1236  return false;
1237 }
1238 
1239 
1240 void LIB_PART::SetAliases( const wxArrayString& aAliasList )
1241 {
1242  wxCHECK_RET( !m_library,
1243  wxT( "Part aliases cannot be changed when they are owned by a library." ) );
1244  wxCHECK_RET( !aAliasList.IsEmpty(), wxT( "Alias list cannot be empty" ) );
1245 
1246  if( aAliasList == GetAliasNames() )
1247  return;
1248 
1249  // Add names not existing in the current component alias list.
1250  for( size_t i = 0; i < aAliasList.GetCount(); i++ )
1251  {
1252  if( HasAlias( aAliasList[ i ] ) )
1253  continue;
1254 
1255  m_aliases.push_back( new LIB_ALIAS( aAliasList[ i ], this ) );
1256  }
1257 
1258  // Remove names in the current component that are not in the new alias list.
1259  LIB_ALIASES::iterator it = m_aliases.begin();
1260 
1261  while( it != m_aliases.end() )
1262  {
1263  int index = aAliasList.Index( (*it)->GetName(), false );
1264 
1265  if( index != wxNOT_FOUND || (*it)->IsRoot() )
1266  ++it;
1267  else
1268  it = m_aliases.erase( it );
1269  }
1270 }
1271 
1272 
1273 void LIB_PART::RemoveAlias( const wxString& aName )
1274 {
1275  LIB_ALIAS* a = GetAlias( aName );
1276 
1277  if( a )
1278  RemoveAlias( a );
1279 }
1280 
1281 
1283 {
1284  wxCHECK_MSG( aAlias, NULL, wxT( "Cannot remove alias by NULL pointer." ) );
1285 
1286  LIB_ALIAS* nextAlias = NULL;
1287 
1288  LIB_ALIASES::iterator it = find( m_aliases.begin(), m_aliases.end(), aAlias );
1289 
1290  if( it != m_aliases.end() )
1291  {
1292  bool rename = aAlias->IsRoot();
1293 
1294  wxLogTrace( traceSchLibMem,
1295  wxT( "%s: part:'%s', alias:'%s', alias count %llu, reference count %ld." ),
1296  GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
1297  GetChars( GetName() ),
1298  GetChars( aAlias->GetName() ),
1299  (long long unsigned) m_aliases.size(),
1300  m_me.use_count() );
1301 
1302  it = m_aliases.erase( it );
1303 
1304  if( !m_aliases.empty() )
1305  {
1306  if( it == m_aliases.end() )
1307  it = m_aliases.begin();
1308 
1309  nextAlias = *it;
1310 
1311  if( rename )
1312  SetName( nextAlias->GetName() );
1313  }
1314  }
1315 
1316  return nextAlias;
1317 }
1318 
1319 
1321 {
1322  // Remove all of the aliases except the root alias.
1323  while( m_aliases.size() > 1 )
1324  m_aliases.pop_back();
1325 }
1326 
1327 
1328 LIB_ALIAS* LIB_PART::GetAlias( const wxString& aName )
1329 {
1330  wxCHECK2_MSG( !aName.IsEmpty(), return NULL,
1331  wxT( "Cannot get alias with an empty name. Bad programmer!" ) );
1332 
1333  for( size_t i = 0; i < m_aliases.size(); i++ )
1334  {
1335  if( aName == m_aliases[i]->GetName() )
1336  return m_aliases[i];
1337  }
1338 
1339  return NULL;
1340 }
1341 
1342 
1344 {
1345  wxCHECK2_MSG( aIndex < m_aliases.size(), return NULL,
1346  wxT( "Illegal alias list index, bad programmer." ) );
1347 
1348  return m_aliases[aIndex];
1349 }
1350 
1351 
1352 void LIB_PART::AddAlias( const wxString& aName )
1353 {
1354  wxCHECK_RET( !HasAlias( aName ),
1355  wxT( "Part <" ) + GetName() + wxT( "> already has an alias <" ) +
1356  aName + wxT( ">. Bad programmer." ) );
1357 
1358  m_aliases.push_back( new LIB_ALIAS( aName, this ) );
1359 }
1360 
1361 
1362 void LIB_PART::SetSubpartIdNotation( int aSep, int aFirstId )
1363 {
1364  m_subpartFirstId = 'A';
1366 
1367  if( aSep == '.' || aSep == '-' || aSep == '_' )
1368  m_subpartIdSeparator = aSep;
1369 
1370  if( aFirstId == '1' && aSep != 0 )
1371  m_subpartFirstId = aFirstId;
1372 }
timestamp_t m_dateLastEdition
Date of the last modification.
LIB_ALIASES m_aliases
List of alias object pointers associated with the part.
PART_LIB * GetLib()
virtual ~LIB_ALIAS()
LIB_FIELD & GetFootprintField()
Return reference to the footprint field.
GR_DRAWMODE g_XorMode
Definition: gr_basic.cpp:51
void SetLib(PART_LIB *aLibrary)
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
LIB_FIELD * GetField(int aId)
Return pointer to the requested field.
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()
static int m_subpartIdSeparator
the separator char between the subpart id and the reference like U1A ( m_subpartIdSeparator = 0 ) or ...
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDc, const wxPoint &aOffset, int aMulti, int aConvert, const PART_DRAW_OPTIONS &aOpts)
Draw part.
const EDA_RECT GetUnitBoundingBox(int aUnit, int aConvert) const
Get the bounding box for the symbol.
Part library alias object definition.
ITERATOR begin(int aType=UNDEFINED_TYPE)
Definition: multivector.h:183
bool PinIsDangling(size_t aPin) const
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
void SetConversion(bool aSetConvert)
Set or clear the alternate body style (DeMorgan) for the part.
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...
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
bool m_showPinNumbers
Determines if part pin numbers are visible.
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:296
wxString description
documentation for info
int LibraryEntryCompare(const LIB_ALIAS *aItem1, const LIB_ALIAS *aItem2)
bool IsPower() const
LIB_ALIAS * GetAlias(size_t aIndex)
bool IsNew() const
Definition: base_struct.h:243
virtual void SetColor(COLOR4D color)=0
virtual EDA_ITEM * Clone() const
Function Clone creates a duplicate of this item with linked list members set to NULL.
int m_unitCount
Number of units (parts) per package.
const wxString GetLibraryName()
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.
bool empty(int aType=UNDEFINED_TYPE)
Definition: multivector.h:224
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
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:238
const EDA_RECT GetBodyBoundingBox(int aUnit, int aConvert) const
Get the symbol bounding box excluding fields.
bool HasAlias(const wxString &aName) const
Test if alias aName is in part alias list.
LIB_ITEMS_CONTAINER m_drawings
Drawing items of this part.
LIB_FIELD & GetValueField()
Return reference to the value field.
int m_Unit
Unit identification for multiple parts per package.
Class OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a conve...
Definition: richio.h:327
LIB_ALIAS(const wxString &aName, LIB_PART *aRootComponent)
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: lib_field.cpp:358
void ClearSelectedItems()
Clears all the draw items marked by a block select.
void AddAlias(const wxString &aName)
Add an alias aName to the part.
LIBRENTRYOPTIONS m_options
Special part features such as POWER or NORMAL.)
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:167
PART_LIB * GetLib()
void RevertYAxis()
Function RevertYAxis Mirror the rectangle from the X axis (negate Y pos and size) ...
void operator()(void const *) const
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
bool draw_hidden_fields
Whether to draw "hidden" fields.
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...
The base class for drawable items used by schematic library components.
Definition: lib_draw_item.h:66
LIB_ITEMS_CONTAINER::ITEM_PTR_VECTOR LIB_ITEMS
void MirrorSelectedItemsH(const wxPoint &aCenter)
Horizontally (X axis) mirror selected draw items about a point.
This file contains miscellaneous commonly used macros and functions.
wxString name
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.
void MirrorSelectedItemsV(const wxPoint &aCenter)
Vertically (Y axis) mirror selected draw items about a point.
bool LoadDateAndTime(char *aLine)
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.
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:135
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.
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
void deleteAllFields()
#define SELECTED
Definition: base_struct.h:134
bool IsRoot() const
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1076
Class for tranforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
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.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:280
LIB_FIELD * FindField(const wxString &aFieldName)
Findd a field within this part matching aFieldName and returns it or NULL if not found.
void SetText(const wxString &aText) override
Sets the field text to aText.
Definition: lib_field.cpp:504
void SetUnitCount(int count)
Set the units per part count.
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:240
int GetId() const
Definition: lib_field.h:133
wxString docFileName
Associate doc file name.
void CopySelectedItems(const wxPoint &aOffset)
Make a copy of the selected draw items marked by a block select.
Definitions for the Eeschema program SCH_SCREEN class.
const wxString & GetName() const
LIB_PART * shared
Actual LIB_PART referenced by [multiple] aliases.
void RotateSelectedItems(const wxPoint &aCenter)
Rotate CCW selected draw items about a point.
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
void push_back(T *aItem)
Definition: multivector.h:169
Class LIB_ITEM definition.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
const wxString GetName() const
Return the file name without path or extension.
bool operator==(const wxChar *aName) const
KEEPCASE sensitive comparison of the part entry name.
Define a library symbol object.
EDA_RECT * GetClipBox()
void RemoveDuplicateDrawItems()
Remove duplicate draw items from list.
bool operator<(const LIB_ALIAS &aItem1, const LIB_ALIAS &aItem2)
wxArrayString m_FootprintList
List of suitable footprint names for the part (wild card names accepted).
bool GetColorMode() const
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:358
LIB_PART(const wxString &aName, PART_LIB *aLibrary=NULL)
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:232
wxString GetName(bool aTranslate=true) const
Returns the field name.
Definition: lib_field.cpp:434
const wxString GetLibraryName()
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 ...
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:219
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
Base plotter engine class.
Definition: class_plotter.h:96
void SetAliases(const wxArrayString &aAliasList)
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_draw_item.h:60
void ClearStatus()
Clears the status flag all draw objects in this part.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
TRANSFORM DefaultTransform
Definition: eeschema.cpp:58
GR_DRAWMODE draw_mode
Device context drawing mode, see wxDC.
int SelectItems(EDA_RECT &aRect, int aUnit, int aConvert, bool aEditPinByPin)
Checks all draw objects of part to see if they are with block.
COLOR4D color
Color to draw part in.
void RemoveAlias(const wxString &aName)
void RemoveAllAliases()
virtual void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, COLOR4D aColor, GR_DRAWMODE aDrawMode, void *aData, const TRANSFORM &aTransform)
Draw an item.
const wxChar traceSchLibMem[]
Flag to enable schematic library memory deletion debug output.
const wxString & GetName() const
bool IsVisible() const
Definition: lib_field.h:159
static void SetSubpartIdNotation(int aSep, int aFirstId)
Set the separator char between the subpart id and the reference 0 (no separator) or '...
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:252
wxArrayString GetAliasNames(bool aIncludeRoot=true) const
Class EDA_RECT handles the component boundary box.
static wxString SubReference(int aUnit, bool aAddSeparator=true)
bool show_pin_text
Whether to show pin texts.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:187
void RemoveDrawItem(LIB_ITEM *aItem, EDA_DRAW_PANEL *aPanel=NULL, wxDC *aDc=NULL)
Remove draw aItem from list.
bool only_selected
Draws only the body items that are selected, for block moves.
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:178
bool show_elec_type
Whether to show the pin electrical type.
int m_Convert
Shape identification for alternate body styles.
void MoveSelectedItems(const wxPoint &aOffset)
Move the selected draw items marked by a block select.
bool IsPowerConnection() const
Return whether this pin forms an implicit power connection: i.e., is hidden and of type POWER_IN...
Definition: lib_pin.h:355
LIB_ITEM * LocateDrawItem(int aUnit, int aConvert, KICAD_T aType, const wxPoint &aPoint)
Locate a draw object.
virtual void SetName(const wxString &aName)
Definition for part library class.
bool draw_visible_fields
Whether to draw "visible" fields.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Function Print formats and writes text to the output stream.
Definition: richio.cpp:404
bool GetGRForceBlackPenState(void)
Function GetGRForceBlackPenState.
Definition: gr_basic.cpp:287
void DeleteSelectedItems()
Deletes the select draw items marked by a block select.
bool m_showPinNames
Determines if part pin names are visible.
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
#define VALUE
Object used to load, save, search, and otherwise manipulate symbol library files. ...
TRANSFORM transform
Coordinate adjustment settings.
wxString keyWords
keyword list (used for search for parts by keyword)
void GetFields(LIB_FIELDS &aList)
Return a list of fields withing this part.
LIB_PIN * GetPin(const wxString &aNumber, int aUnit=0, int aConvert=0)
Return pin object with the requested pin aNumber.
#define min(a, b)
Definition: auxiliary.h:85
bool SaveDateAndTime(OUTPUTFORMATTER &aFormatter)
Write the date and time of part to aFile in the format: "Ti yy/mm/jj hh:mm:ss".
#define IS_MOVED
Item being moved.
Definition: base_struct.h:126
PART_SPTR m_me
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared ...