KiCad PCB EDA Suite
sch_component.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #include <fctsys.h>
31 #include <pgm_base.h>
32 #include <class_drawpanel.h>
33 #include <gr_basic.h>
34 #include <kicad_string.h>
35 #include <richio.h>
36 #include <schframe.h>
37 #include <class_plotter.h>
38 #include <msgpanel.h>
39 #include <bitmaps.h>
40 
41 #include <general.h>
42 #include <class_library.h>
43 #include <lib_rectangle.h>
44 #include <lib_pin.h>
45 #include <lib_text.h>
46 #include <sch_component.h>
47 #include <sch_sheet.h>
48 #include <sch_sheet_path.h>
49 #include <class_netlist_object.h>
50 #include <lib_draw_item.h>
51 #include <symbol_lib_table.h>
52 
54 
55 #include <wx/tokenzr.h>
56 #include <iostream>
57 
58 #include <eeschema_id.h> // for MAX_UNIT_COUNT_PER_PACKAGE definition
59 
60 #define NULL_STRING "_NONAME_"
61 
67 std::string toUTFTildaText( const wxString& txt )
68 {
69  std::string ret = TO_UTF8( txt );
70 
71  for( std::string::iterator it = ret.begin(); it!=ret.end(); ++it )
72  {
73  if( (unsigned char) *it <= ' ' )
74  *it = '~';
75  }
76  return ret;
77 }
78 
79 
93 static LIB_PART* dummy()
94 {
95  static LIB_PART* part;
96 
97  if( !part )
98  {
99  part = new LIB_PART( wxEmptyString );
100 
101  LIB_RECTANGLE* square = new LIB_RECTANGLE( part );
102 
103  square->Move( wxPoint( -200, 200 ) );
104  square->SetEndPosition( wxPoint( 200, -200 ) );
105 
106  LIB_TEXT* text = new LIB_TEXT( part );
107 
108  text->SetTextSize( wxSize( 150, 150 ) );
109  text->SetText( wxString( wxT( "??" ) ) );
110 
111  part->AddDrawItem( square );
112  part->AddDrawItem( text );
113  }
114 
115  return part;
116 }
117 
118 
120  SCH_ITEM( aParent, SCH_COMPONENT_T )
121 {
122  Init( aPos );
123  m_currentSheetPath = NULL;
125 }
126 
127 
129  int convert, const wxPoint& pos, bool setNewItemFlag ) :
130  SCH_ITEM( NULL, SCH_COMPONENT_T )
131 {
132  Init( pos );
133 
134  m_unit = unit;
135  m_convert = convert;
136  m_lib_id.SetLibItemName( aPart.GetName(), false );
137  m_part = aPart.SharedPtr();
138  m_currentSheetPath = NULL;
140 
142 
143  if( setNewItemFlag )
144  m_Flags = IS_NEW | IS_MOVED;
145 
146  // Import user defined fields from the library component
147  UpdateFields( true, true );
148 
149  wxString msg = aPart.GetReferenceField().GetText();
150 
151  if( msg.IsEmpty() )
152  msg = wxT( "U" );
153 
154  m_prefix = msg;
155 
156  // update the reference -- just the prefix for now.
157  msg += wxT( "?" );
158  SetRef( sheet, msg );
159 
160  // Use the schematic component name instead of the library value field name.
161  GetField( VALUE )->SetText( GetLibId().GetLibItemName() );
162 }
163 
164 
166  SCH_ITEM( aComponent )
167 {
168  m_currentSheetPath = NULL;
169  m_Parent = aComponent.m_Parent;
170  m_Pos = aComponent.m_Pos;
171  m_unit = aComponent.m_unit;
172  m_convert = aComponent.m_convert;
173  m_lib_id = aComponent.m_lib_id;
174  m_part = aComponent.m_part;
175 
176  SetTimeStamp( aComponent.m_TimeStamp );
177 
178  m_transform = aComponent.m_transform;
179  m_prefix = aComponent.m_prefix;
181  m_Fields = aComponent.m_Fields;
182 
183  // Re-parent the fields, which before this had aComponent as parent
184  for( int i = 0; i<GetFieldCount(); ++i )
185  {
186  GetField( i )->SetParent( this );
187  }
188 
189  m_isDangling = aComponent.m_isDangling;
191 }
192 
193 
194 void SCH_COMPONENT::Init( const wxPoint& pos )
195 {
196  m_Pos = pos;
197  m_unit = 0; // In multi unit chip - which unit to draw.
198  m_convert = 0; // De Morgan Handling
199 
200  // The rotation/mirror transformation matrix. pos normal
202 
203  // construct only the mandatory fields, which are the first 4 only.
204  for( int i = 0; i < MANDATORY_FIELDS; ++i )
205  {
206  SCH_FIELD field( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
207 
208  if( i == REFERENCE )
209  field.SetLayer( LAYER_REFERENCEPART );
210  else if( i == VALUE )
211  field.SetLayer( LAYER_VALUEPART );
212 
213  // else keep LAYER_FIELDS from SCH_FIELD constructor
214 
215  // SCH_FIELD's implicitly created copy constructor is called in here
216  AddField( field );
217  }
218 
219  m_prefix = wxString( wxT( "U" ) );
220 }
221 
222 
224 {
225  return new SCH_COMPONENT( *this );
226 }
227 
228 
229 void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, PART_LIBS* aLibs )
230 {
231  if( m_lib_id != aLibId )
232  {
233  m_lib_id = aLibId;
234  SetModified();
235 
236  if( aLibs )
237  Resolve( aLibs );
238  else
239  m_part.reset();
240  }
241 }
242 
243 
244 void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTable,
245  PART_LIB* aCacheLib )
246 {
247  if( m_lib_id == aLibId )
248  return;
249 
250  m_lib_id = aLibId;
251  SetModified();
252 
253  LIB_ALIAS* alias = nullptr;
254 
255  if( aSymLibTable && aSymLibTable->HasLibrary( m_lib_id.GetLibNickname() ) )
256  alias = aSymLibTable->LoadSymbol( m_lib_id.GetLibNickname(), m_lib_id.GetLibItemName() );
257 
258  if( !alias && aCacheLib )
259  alias = aCacheLib->FindAlias( m_lib_id.GetLibItemName() );
260 
261  if( alias && alias->GetPart() )
262  m_part = alias->GetPart()->SharedPtr();
263  else
264  m_part.reset();
265 }
266 
267 
269 {
270  if( PART_SPTR part = m_part.lock() )
271  {
272  LIB_ALIAS* alias = part->GetAlias( GetLibId().GetLibItemName() );
273 
274  if( !alias )
275  return wxEmptyString;
276 
277  return alias->GetDescription();
278  }
279 
280  return wxEmptyString;
281 }
282 
283 
285 {
286  if( PART_SPTR part = m_part.lock() )
287  {
288  LIB_ALIAS* alias = part->GetAlias( GetLibId().GetLibItemName() );
289 
290  if( !alias )
291  return wxEmptyString;
292 
293  return alias->GetDocFileName();
294  }
295 
296  return wxEmptyString;
297 }
298 
299 
301 {
302  // I've never been happy that the actual individual PART_LIB is left up to
303  // flimsy search path ordering. None-the-less find a part based on that design:
304  if( LIB_PART* part = aLibs->FindLibPart( m_lib_id ) )
305  {
306  m_part = part->SharedPtr();
307  return true;
308  }
309 
310  return false;
311 }
312 
313 
314 bool SCH_COMPONENT::Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
315 {
316  LIB_ALIAS* alias = nullptr;
317 
318  try
319  {
320  if( m_lib_id.IsValid() )
321  alias = aLibTable.LoadSymbol( m_lib_id );
322 
323  // Fall back to cache library. This is temporary until the new schematic file
324  // format is implemented.
325  if( !alias && aCacheLib )
326  alias = aCacheLib->FindAlias( m_lib_id.GetLibItemName() );
327 
328  if( alias && alias->GetPart() )
329  {
330  m_part = alias->GetPart()->SharedPtr();
331  return true;
332  }
333  }
334  catch( const IO_ERROR& ioe )
335  {
336  wxLogDebug( "Cannot resolve library symbol %s", m_lib_id.Format().wx_str() );
337  }
338 
339  return false;
340 }
341 
342 
343 // Helper sort function, used in SCH_COMPONENT::ResolveAll, to sort
344 // sch component by lib_id
345 static bool sort_by_libid( const SCH_COMPONENT* ref, SCH_COMPONENT* cmp )
346 {
347  return ref->GetLibId() < cmp->GetLibId();
348 }
349 
350 
351 void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLibs )
352 {
353  // Usually, many components use the same part lib.
354  // to avoid too long calculation time the list of components is grouped
355  // and once the lib part is found for one member of a group, it is also
356  // set for all other members of this group
357  std::vector<SCH_COMPONENT*> cmp_list;
358 
359  // build the cmp list.
360  for( int i = 0; i < aComponents.GetCount(); ++i )
361  {
362  SCH_COMPONENT* cmp = dynamic_cast<SCH_COMPONENT*>( aComponents[i] );
363  wxASSERT( cmp );
364 
365  if( cmp ) // cmp == NULL should not occur.
366  cmp_list.push_back( cmp );
367  }
368 
369  // sort it by lib part. Cmp will be grouped by same lib part.
370  std::sort( cmp_list.begin(), cmp_list.end(), sort_by_libid );
371 
372  LIB_ID curr_libid;
373 
374  for( unsigned ii = 0; ii < cmp_list.size (); ++ii )
375  {
376  SCH_COMPONENT* cmp = cmp_list[ii];
377  curr_libid = cmp->m_lib_id;
378  cmp->Resolve( aLibs );
379 
380  // Propagate the m_part pointer to other members using the same lib_id
381  for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj )
382  {
383  SCH_COMPONENT* next_cmp = cmp_list[jj];
384 
385  if( curr_libid != next_cmp->m_lib_id )
386  break;
387 
388  next_cmp->m_part = cmp->m_part;
389  ii = jj;
390  }
391  }
392 }
393 
394 
395 void SCH_COMPONENT::ResolveAll( const SCH_COLLECTOR& aComponents, SYMBOL_LIB_TABLE& aLibTable,
396  PART_LIB* aCacheLib )
397 {
398  std::vector<SCH_COMPONENT*> cmp_list;
399 
400  for( int i = 0; i < aComponents.GetCount(); ++i )
401  {
402  SCH_COMPONENT* cmp = dynamic_cast<SCH_COMPONENT*>( aComponents[i] );
403 
404  wxCHECK2_MSG( cmp, continue, "Invalid SCH_COMPONENT pointer in list." );
405 
406  cmp_list.push_back( cmp );
407  }
408 
409  // sort it by lib part. Cmp will be grouped by same lib part.
410  std::sort( cmp_list.begin(), cmp_list.end(), sort_by_libid );
411 
412  LIB_ID curr_libid;
413 
414  for( unsigned ii = 0; ii < cmp_list.size (); ++ii )
415  {
416  SCH_COMPONENT* cmp = cmp_list[ii];
417  curr_libid = cmp->m_lib_id;
418  cmp->Resolve( aLibTable, aCacheLib );
419 
420  // Propagate the m_part pointer to other members using the same lib_id
421  for( unsigned jj = ii+1; jj < cmp_list.size (); ++jj )
422  {
423  SCH_COMPONENT* next_cmp = cmp_list[jj];
424 
425  if( curr_libid != next_cmp->m_lib_id )
426  break;
427 
428  next_cmp->m_part = cmp->m_part;
429  ii = jj;
430  }
431  }
432 }
433 
434 
435 void SCH_COMPONENT::SetUnit( int aUnit )
436 {
437  if( m_unit != aUnit )
438  {
439  m_unit = aUnit;
440  SetModified();
441  }
442 }
443 
444 
445 void SCH_COMPONENT::UpdateUnit( int aUnit )
446 {
447  m_unit = aUnit;
448 }
449 
450 
451 void SCH_COMPONENT::SetConvert( int aConvert )
452 {
453  if( m_convert != aConvert )
454  {
455  m_convert = aConvert;
456  SetModified();
457  }
458 }
459 
460 
461 void SCH_COMPONENT::SetTransform( const TRANSFORM& aTransform )
462 {
463  if( m_transform != aTransform )
464  {
465  m_transform = aTransform;
466  SetModified();
467  }
468 }
469 
470 
472 {
473  if( PART_SPTR part = m_part.lock() )
474  {
475  return part->GetUnitCount();
476  }
477 
478  return 0;
479 }
480 
481 
482 void SCH_COMPONENT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
483  GR_DRAWMODE aDrawMode, COLOR4D aColor,
484  bool aDrawPinText )
485 {
486  auto opts = PART_DRAW_OPTIONS::Default();
487  opts.draw_mode = aDrawMode;
488  opts.color = aColor;
489  opts.transform = m_transform;
490  opts.show_pin_text = aDrawPinText;
491  opts.draw_visible_fields = false;
492  opts.draw_hidden_fields = false;
493 
494  if( PART_SPTR part = m_part.lock() )
495  {
496  // Draw pin targets if part is being dragged
497  bool dragging = aPanel->GetScreen()->GetCurItem() == this && aPanel->IsMouseCaptured();
498 
499  if( !dragging )
500  {
501  opts.dangling = m_isDangling;
502  }
503 
504  part->Draw( aPanel, aDC, m_Pos + aOffset, m_unit, m_convert, opts );
505  }
506  else // Use dummy() part if the actual cannot be found.
507  {
508  dummy()->Draw( aPanel, aDC, m_Pos + aOffset, 0, 0, opts );
509  }
510 
511  SCH_FIELD* field = GetField( REFERENCE );
512 
513  if( field->IsVisible() && !field->IsMoving() )
514  {
515  field->Draw( aPanel, aDC, aOffset, aDrawMode );
516  }
517 
518  for( int ii = VALUE; ii < GetFieldCount(); ii++ )
519  {
520  field = GetField( ii );
521 
522  if( field->IsMoving() )
523  continue;
524 
525  field->Draw( aPanel, aDC, aOffset, aDrawMode );
526  }
527 
528 #if 0
529  // Only for testing purposes, draw the component bounding box
530  {
532  GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
533 #if 1
534  if( GetField( REFERENCE )->IsVisible() )
535  {
536  boundingBox = GetField( REFERENCE )->GetBoundingBox();
537  GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
538  }
539 
540  if( GetField( VALUE )->IsVisible() )
541  {
542  boundingBox = GetField( VALUE )->GetBoundingBox();
543  GRRect( aPanel->GetClipBox(), aDC, boundingBox, 0, BROWN );
544  }
545 #endif
546  }
547 #endif
548 }
549 
550 
551 void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath,
552  const wxString& aRef,
553  int aMulti )
554 {
555  wxString h_path, h_ref;
556  wxStringTokenizer tokenizer;
557  wxString separators( wxT( " " ) );
558 
559  // Search for an existing path and remove it if found (should not occur)
560  for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
561  {
562  tokenizer.SetString( m_PathsAndReferences[ii], separators );
563  h_path = tokenizer.GetNextToken();
564 
565  if( h_path.Cmp( aPath ) == 0 )
566  {
567  m_PathsAndReferences.RemoveAt( ii );
568  ii--;
569  }
570  }
571 
572  h_ref = aPath + wxT( " " ) + aRef;
573  h_ref << wxT( " " ) << aMulti;
574  m_PathsAndReferences.Add( h_ref );
575 }
576 
577 
578 wxString SCH_COMPONENT::GetPath( const SCH_SHEET_PATH* sheet ) const
579 {
580  wxCHECK_MSG( sheet != NULL, wxEmptyString,
581  wxT( "Cannot get component path with invalid sheet object." ) );
582 
583  wxString str;
584 
585  str.Printf( wxT( "%8.8lX" ), (long unsigned) m_TimeStamp );
586  return sheet->Path() + str;
587 }
588 
589 
590 const wxString SCH_COMPONENT::GetRef( const SCH_SHEET_PATH* sheet )
591 {
592  wxString path = GetPath( sheet );
593  wxString h_path, h_ref;
594  wxStringTokenizer tokenizer;
595  wxString separators( wxT( " " ) );
596 
597  for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
598  {
599  tokenizer.SetString( m_PathsAndReferences[ii], separators );
600  h_path = tokenizer.GetNextToken();
601 
602  if( h_path.Cmp( path ) == 0 )
603  {
604  h_ref = tokenizer.GetNextToken();
605 
606  /* printf( "GetRef hpath: %s\n",
607  * TO_UTF8( m_PathsAndReferences[ii] ) ); */
608  return h_ref;
609  }
610  }
611 
612  // if it was not found in m_Paths array, then see if it is in
613  // m_Field[REFERENCE] -- if so, use this as a default for this path.
614  // this will happen if we load a version 1 schematic file.
615  // it will also mean that multiple instances of the same sheet by default
616  // all have the same component references, but perhaps this is best.
617  if( !GetField( REFERENCE )->GetText().IsEmpty() )
618  {
619  SetRef( sheet, GetField( REFERENCE )->GetText() );
620  return GetField( REFERENCE )->GetText();
621  }
622 
623  return m_prefix;
624 }
625 
626 
627 bool SCH_COMPONENT::IsReferenceStringValid( const wxString& aReferenceString )
628 {
629  wxString text = aReferenceString;
630  bool ok = true;
631 
632  // Try to unannotate this reference
633  while( !text.IsEmpty() && ( text.Last() == '?' || isdigit( text.Last() ) ) )
634  text.RemoveLast();
635 
636  if( text.IsEmpty() )
637  ok = false;
638 
639  // Add here other constraints
640  // Currently:no other constraint
641 
642  return ok;
643 }
644 
645 
646 void SCH_COMPONENT::SetRef( const SCH_SHEET_PATH* sheet, const wxString& ref )
647 {
648  wxString path = GetPath( sheet );
649 
650  bool notInArray = true;
651 
652  wxString h_path, h_ref;
653  wxStringTokenizer tokenizer;
654  wxString separators( wxT( " " ) );
655 
656  // check to see if it is already there before inserting it
657  for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
658  {
659  tokenizer.SetString( m_PathsAndReferences[ii], separators );
660  h_path = tokenizer.GetNextToken();
661 
662  if( h_path.Cmp( path ) == 0 )
663  {
664  // just update the reference text, not the timestamp.
665  h_ref = h_path + wxT( " " ) + ref;
666  h_ref += wxT( " " );
667  tokenizer.GetNextToken(); // Skip old reference
668  h_ref += tokenizer.GetNextToken(); // Add part selection
669 
670  // Add the part selection
671  m_PathsAndReferences[ii] = h_ref;
672  notInArray = false;
673  }
674  }
675 
676  if( notInArray )
677  AddHierarchicalReference( path, ref, m_unit );
678 
679  SCH_FIELD* rf = GetField( REFERENCE );
680 
681  if( rf->GetText().IsEmpty()
682  || ( abs( rf->GetTextPos().x - m_Pos.x ) +
683  abs( rf->GetTextPos().y - m_Pos.y ) > 10000 ) )
684  {
685  // move it to a reasonable position
686  rf->SetTextPos( m_Pos + wxPoint( 50, 50 ) );
687  }
688 
689  rf->SetText( ref ); // for drawing.
690 
691  // Reinit the m_prefix member if needed
692  wxString prefix = ref;
693 
694  if( IsReferenceStringValid( prefix ) )
695  {
696  while( prefix.Last() == '?' || isdigit( prefix.Last() ) )
697  prefix.RemoveLast();
698  }
699  else
700  {
701  prefix = wxT( "U" ); // Set to default ref prefix
702  }
703 
704  if( m_prefix != prefix )
705  m_prefix = prefix;
706 }
707 
708 
709 void SCH_COMPONENT::SetTimeStamp( time_t aNewTimeStamp )
710 {
711  wxString string_timestamp, string_oldtimestamp;
712 
713  string_timestamp.Printf( wxT( "%08lX" ), (long unsigned) aNewTimeStamp );
714  string_oldtimestamp.Printf( wxT( "%08lX" ), (long unsigned) m_TimeStamp );
715  EDA_ITEM::SetTimeStamp( aNewTimeStamp );
716 
717  for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
718  {
719  m_PathsAndReferences[ii].Replace( string_oldtimestamp.GetData(),
720  string_timestamp.GetData() );
721  }
722 }
723 
724 
726 {
727  wxString path = GetPath( aSheet );
728  wxString h_path, h_multi;
729  wxStringTokenizer tokenizer;
730  wxString separators( wxT( " " ) );
731 
732  for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
733  {
734  tokenizer.SetString( m_PathsAndReferences[ii], separators );
735  h_path = tokenizer.GetNextToken();
736 
737  if( h_path.Cmp( path ) == 0 )
738  {
739  tokenizer.GetNextToken(); // Skip reference
740  h_multi = tokenizer.GetNextToken();
741  long imulti = 1;
742  h_multi.ToLong( &imulti );
743  return imulti;
744  }
745  }
746 
747  // if it was not found in m_Paths array, then use m_unit.
748  // this will happen if we load a version 1 schematic file.
749  return m_unit;
750 }
751 
752 
753 void SCH_COMPONENT::SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection )
754 {
755  wxString path = GetPath( aSheet );
756 
757  bool notInArray = true;
758 
759  wxString h_path, h_ref;
760  wxStringTokenizer tokenizer;
761  wxString separators( wxT( " " ) );
762 
763  //check to see if it is already there before inserting it
764  for( unsigned ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
765  {
766  tokenizer.SetString( m_PathsAndReferences[ii], separators );
767  h_path = tokenizer.GetNextToken();
768 
769  if( h_path.Cmp( path ) == 0 )
770  {
771  //just update the unit selection.
772  h_ref = h_path + wxT( " " );
773  h_ref += tokenizer.GetNextToken(); // Add reference
774  h_ref += wxT( " " );
775  h_ref << aUnitSelection; // Add part selection
776 
777  // Ann the part selection
778  m_PathsAndReferences[ii] = h_ref;
779  notInArray = false;
780  }
781  }
782 
783  if( notInArray )
784  AddHierarchicalReference( path, m_prefix, aUnitSelection );
785 }
786 
787 
788 SCH_FIELD* SCH_COMPONENT::GetField( int aFieldNdx ) const
789 {
790  const SCH_FIELD* field;
791 
792  if( (unsigned) aFieldNdx < m_Fields.size() )
793  field = &m_Fields[aFieldNdx];
794  else
795  field = NULL;
796 
797  wxASSERT( field );
798 
799  // use cast to remove const-ness
800  return (SCH_FIELD*) field;
801 }
802 
803 
804 wxString SCH_COMPONENT::GetFieldText( wxString aFieldName, bool aIncludeDefaultFields ) const
805 {
806  // Field name for comparison
807  wxString cmpFieldName;
808 
809  if( aIncludeDefaultFields )
810  {
811 
812  // Default field names
813  for ( unsigned int i=0; i<MANDATORY_FIELDS; i++)
814  {
815  cmpFieldName = TEMPLATE_FIELDNAME::GetDefaultFieldName( i );
816 
817  if( cmpFieldName.Cmp( aFieldName ) == 0 )
818  {
819  return m_Fields[i].GetText();
820  }
821  }
822  }
823 
824  // Search custom fields
825  for( unsigned int ii=MANDATORY_FIELDS; ii<m_Fields.size(); ii++ )
826  {
827  cmpFieldName = m_Fields[ii].GetName();
828 
829  if( cmpFieldName.Cmp( aFieldName ) == 0 )
830  {
831  return m_Fields[ii].GetText();
832  }
833  }
834 
835  return wxEmptyString;
836 }
837 
838 
839 void SCH_COMPONENT::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
840 {
841  for( SCH_FIELD& each_field : m_Fields )
842  {
843  if( !aVisibleOnly || ( each_field.IsVisible() && !each_field.IsVoid() ) )
844  aVector.push_back( &each_field );
845  }
846 }
847 
848 
850 {
851  int newNdx = m_Fields.size();
852 
853  m_Fields.push_back( aField );
854  return &m_Fields[newNdx];
855 }
856 
857 
858 SCH_FIELD* SCH_COMPONENT::FindField( const wxString& aFieldName, bool aIncludeDefaultFields )
859 {
860  unsigned start = aIncludeDefaultFields ? 0 : MANDATORY_FIELDS;
861 
862  for( unsigned i = start; i<m_Fields.size(); ++i )
863  {
864  if( aFieldName == m_Fields[i].GetName( false ) )
865  {
866  return &m_Fields[i];
867  }
868  }
869 
870  return NULL;
871 }
872 
873 
874 void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
875 {
876  if( PART_SPTR part = m_part.lock() )
877  {
878  LIB_FIELDS fields;
879  part->GetFields( fields );
880 
881  for( const LIB_FIELD& field : fields )
882  {
883  // Can no longer insert an empty name, since names are now keys. The
884  // field index is not used beyond the first MANDATORY_FIELDS
885  if( field.GetName().IsEmpty() )
886  continue;
887 
888  // See if field already exists (mandatory fields always exist).
889  // for mandatory fields, the name and field id are fixed, so we use the
890  // known and fixed id to get them (more reliable than names, which can be translated)
891  // for other fields (custom fields), locate the field by same name
892  // (field id has no known meaning for custom fields)
893  int idx = field.GetId();
894  SCH_FIELD* schField;
895 
896  if( idx == REFERENCE && !aResetRef )
897  continue;
898  if( (unsigned) idx < MANDATORY_FIELDS )
899  schField = GetField( idx );
900  else
901  schField = FindField( field.GetName() );
902 
903  if( !schField )
904  {
905  SCH_FIELD fld( wxPoint( 0, 0 ), GetFieldCount(), this, field.GetName() );
906  schField = AddField( fld );
907  }
908 
909  if( aResetStyle )
910  {
911  schField->ImportValues( field );
912  schField->SetTextPos( m_Pos + field.GetTextPos() );
913  }
914 
915  schField->SetText( field.GetText() );
916  }
917  }
918 }
919 
920 
921 LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number )
922 {
923  if( PART_SPTR part = m_part.lock() )
924  {
925  return part->GetPin( number, m_unit, m_convert );
926  }
927  return NULL;
928 }
929 
930 
931 void SCH_COMPONENT::GetPins( std::vector<LIB_PIN*>& aPinsList )
932 {
933  if( PART_SPTR part = m_part.lock() )
934  {
935  part->GetPins( aPinsList, m_unit, m_convert );
936  }
937  else
938  wxFAIL_MSG( "Could not obtain PART_SPTR lock" );
939 }
940 
941 
943 {
944  wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T),
945  wxT( "Cannot swap data with invalid component." ) );
946 
947  SCH_COMPONENT* component = (SCH_COMPONENT*) aItem;
948 
949  std::swap( m_lib_id, component->m_lib_id );
950  std::swap( m_part, component->m_part );
951  std::swap( m_Pos, component->m_Pos );
952  std::swap( m_unit, component->m_unit );
953  std::swap( m_convert, component->m_convert );
954 
955  TRANSFORM tmp = m_transform;
956 
957  m_transform = component->m_transform;
958  component->m_transform = tmp;
959 
960  m_Fields.swap( component->m_Fields ); // std::vector's swap()
961 
962  // Reparent items after copying data
963  // (after swap(), m_Parent member does not point to the right parent):
964  for( int ii = 0; ii < component->GetFieldCount(); ++ii )
965  {
966  component->GetField( ii )->SetParent( component );
967  }
968 
969  for( int ii = 0; ii < GetFieldCount(); ++ii )
970  {
971  GetField( ii )->SetParent( this );
972  }
973 
974  std::swap( m_PathsAndReferences, component->m_PathsAndReferences );
975 }
976 
977 
979 {
980  bool keepMulti = false;
981  wxArrayString reference_fields;
982 
983  static const wxChar separators[] = wxT( " " );
984 
985  PART_SPTR part = m_part.lock();
986 
987  if( part && part->UnitsLocked() )
988  keepMulti = true;
989 
990  // Build a reference with no annotation,
991  // i.e. a reference ended by only one '?'
992  wxString defRef = m_prefix;
993 
994  if( IsReferenceStringValid( defRef ) )
995  {
996  while( defRef.Last() == '?' )
997  defRef.RemoveLast();
998  }
999  else
1000  { // This is a malformed reference: reinit this reference
1001  m_prefix = defRef = wxT("U"); // Set to default ref prefix
1002  }
1003 
1004  defRef.Append( wxT( "?" ) );
1005 
1006  wxString multi = wxT( "1" );
1007 
1008  // For components with units locked,
1009  // we cannot remove all annotations: part selection must be kept
1010  // For all components: if aSheetPath is not NULL,
1011  // remove annotation only for the given path
1012  if( keepMulti || aSheetPath )
1013  {
1014  wxString NewHref;
1015  wxString path;
1016 
1017  if( aSheetPath )
1018  path = GetPath( aSheetPath );
1019 
1020  for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
1021  {
1022  // Break hierarchical reference in path, ref and multi selection:
1023  reference_fields = wxStringTokenize( m_PathsAndReferences[ii], separators );
1024 
1025  if( aSheetPath == NULL || reference_fields[0].Cmp( path ) == 0 )
1026  {
1027  if( keepMulti ) // Get and keep part selection
1028  multi = reference_fields[2];
1029 
1030  NewHref = reference_fields[0];
1031  NewHref << wxT( " " ) << defRef << wxT( " " ) << multi;
1032  m_PathsAndReferences[ii] = NewHref;
1033  }
1034  }
1035  }
1036  else
1037  {
1038  // Clear reference strings, but does not free memory because a new annotation
1039  // will reuse it
1040  m_PathsAndReferences.Empty();
1041  m_unit = 1;
1042  }
1043 
1044  // These 2 changes do not work in complex hierarchy.
1045  // When a clear annotation is made, the calling function must call a
1046  // UpdateAllScreenReferences for the active sheet.
1047  // But this call cannot made here.
1048  m_Fields[REFERENCE].SetText( defRef ); //for drawing.
1049 
1050  SetModified();
1051 }
1052 
1053 
1054 void SCH_COMPONENT::SetOrientation( int aOrientation )
1055 {
1056  TRANSFORM temp = TRANSFORM();
1057  bool transform = false;
1058 
1059  switch( aOrientation )
1060  {
1061  case CMP_ORIENT_0:
1062  case CMP_NORMAL: // default transform matrix
1063  m_transform.x1 = 1;
1064  m_transform.y2 = -1;
1065  m_transform.x2 = m_transform.y1 = 0;
1066  break;
1067 
1068  case CMP_ROTATE_COUNTERCLOCKWISE: // Rotate + (incremental rotation)
1069  temp.x1 = temp.y2 = 0;
1070  temp.y1 = 1;
1071  temp.x2 = -1;
1072  transform = true;
1073  break;
1074 
1075  case CMP_ROTATE_CLOCKWISE: // Rotate - (incremental rotation)
1076  temp.x1 = temp.y2 = 0;
1077  temp.y1 = -1;
1078  temp.x2 = 1;
1079  transform = true;
1080  break;
1081 
1082  case CMP_MIRROR_Y: // Mirror Y (incremental rotation)
1083  temp.x1 = -1;
1084  temp.y2 = 1;
1085  temp.y1 = temp.x2 = 0;
1086  transform = true;
1087  break;
1088 
1089  case CMP_MIRROR_X: // Mirror X (incremental rotation)
1090  temp.x1 = 1;
1091  temp.y2 = -1;
1092  temp.y1 = temp.x2 = 0;
1093  transform = true;
1094  break;
1095 
1096  case CMP_ORIENT_90:
1099  break;
1100 
1101  case CMP_ORIENT_180:
1105  break;
1106 
1107  case CMP_ORIENT_270:
1110  break;
1111 
1112  case ( CMP_ORIENT_0 + CMP_MIRROR_X ):
1115  break;
1116 
1117  case ( CMP_ORIENT_0 + CMP_MIRROR_Y ):
1120  break;
1121 
1122  case ( CMP_ORIENT_90 + CMP_MIRROR_X ):
1125  break;
1126 
1127  case ( CMP_ORIENT_90 + CMP_MIRROR_Y ):
1130  break;
1131 
1132  case ( CMP_ORIENT_180 + CMP_MIRROR_X ):
1135  break;
1136 
1137  case ( CMP_ORIENT_180 + CMP_MIRROR_Y ):
1140  break;
1141 
1142  case ( CMP_ORIENT_270 + CMP_MIRROR_X ):
1145  break;
1146 
1147  case ( CMP_ORIENT_270 + CMP_MIRROR_Y ):
1150  break;
1151 
1152  default:
1153  transform = false;
1154  wxMessageBox( wxT( "SetRotateMiroir() error: ill value" ) );
1155  break;
1156  }
1157 
1158  if( transform )
1159  {
1160  /* The new matrix transform is the old matrix transform modified by the
1161  * requested transformation, which is the temp transform (rot,
1162  * mirror ..) in order to have (in term of matrix transform):
1163  * transform coord = new_m_transform * coord
1164  * where transform coord is the coord modified by new_m_transform from
1165  * the initial value coord.
1166  * new_m_transform is computed (from old_m_transform and temp) to
1167  * have:
1168  * transform coord = old_m_transform * temp
1169  */
1170  TRANSFORM newTransform;
1171 
1172  newTransform.x1 = m_transform.x1 * temp.x1 + m_transform.x2 * temp.y1;
1173  newTransform.y1 = m_transform.y1 * temp.x1 + m_transform.y2 * temp.y1;
1174  newTransform.x2 = m_transform.x1 * temp.x2 + m_transform.x2 * temp.y2;
1175  newTransform.y2 = m_transform.y1 * temp.x2 + m_transform.y2 * temp.y2;
1176  m_transform = newTransform;
1177  }
1178 }
1179 
1180 
1182 {
1183  int type_rotate = CMP_ORIENT_0;
1184  TRANSFORM transform;
1185  int ii;
1186 
1187  #define ROTATE_VALUES_COUNT 12
1188 
1189  // list of all possibilities, but only the first 8 are actually used
1190  int rotate_value[ROTATE_VALUES_COUNT] =
1191  {
1197  CMP_MIRROR_Y + CMP_ORIENT_180, CMP_MIRROR_Y + CMP_ORIENT_270
1198  };
1199 
1200  // Try to find the current transform option:
1201  transform = m_transform;
1202 
1203  for( ii = 0; ii < ROTATE_VALUES_COUNT; ii++ )
1204  {
1205  type_rotate = rotate_value[ii];
1206  SetOrientation( type_rotate );
1207 
1208  if( transform == m_transform )
1209  return type_rotate;
1210  }
1211 
1212  // Error: orientation not found in list (should not happen)
1213  wxMessageBox( wxT( "Component orientation matrix internal error" ) );
1214  m_transform = transform;
1215 
1216  return CMP_NORMAL;
1217 }
1218 
1219 
1221 {
1222  return m_transform.TransformCoordinate( aPoint );
1223 }
1224 
1225 
1226 #if defined(DEBUG)
1227 
1228 void SCH_COMPONENT::Show( int nestLevel, std::ostream& os ) const
1229 {
1230  // for now, make it look like XML:
1231  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1232  << " ref=\"" << TO_UTF8( GetField( 0 )->GetName() )
1233  << '"' << " chipName=\""
1234  << GetLibId().Format() << '"' << m_Pos
1235  << " layer=\"" << m_Layer
1236  << '"' << ">\n";
1237 
1238  // skip the reference, it's been output already.
1239  for( int i = 1; i < GetFieldCount(); ++i )
1240  {
1241  wxString value = GetField( i )->GetText();
1242 
1243  if( !value.IsEmpty() )
1244  {
1245  NestedSpace( nestLevel + 1, os ) << "<field" << " name=\""
1246  << TO_UTF8( GetField( i )->GetName() )
1247  << '"' << " value=\""
1248  << TO_UTF8( value ) << "\"/>\n";
1249  }
1250  }
1251 
1252  NestedSpace( nestLevel, os ) << "</" << TO_UTF8( GetClass().Lower() ) << ">\n";
1253 }
1254 
1255 #endif
1256 
1257 
1259 {
1260  EDA_RECT bBox;
1261 
1262  if( PART_SPTR part = m_part.lock() )
1263  {
1264  bBox = part->GetBodyBoundingBox( m_unit, m_convert );
1265  }
1266  else
1267  {
1268  bBox = dummy()->GetBodyBoundingBox( m_unit, m_convert );
1269  }
1270 
1271  int x0 = bBox.GetX();
1272  int xm = bBox.GetRight();
1273 
1274  // We must reverse Y values, because matrix orientation
1275  // suppose Y axis normal for the library items coordinates,
1276  // m_transform reverse Y values, but bBox is already reversed!
1277  int y0 = -bBox.GetY();
1278  int ym = -bBox.GetBottom();
1279 
1280  // Compute the real Boundary box (rotated, mirrored ...)
1281  int x1 = m_transform.x1 * x0 + m_transform.y1 * y0;
1282  int y1 = m_transform.x2 * x0 + m_transform.y2 * y0;
1283  int x2 = m_transform.x1 * xm + m_transform.y1 * ym;
1284  int y2 = m_transform.x2 * xm + m_transform.y2 * ym;
1285 
1286  // H and W must be > 0:
1287  if( x2 < x1 )
1288  std::swap( x2, x1 );
1289 
1290  if( y2 < y1 )
1291  std::swap( y2, y1 );
1292 
1293  bBox.SetX( x1 );
1294  bBox.SetY( y1 );
1295  bBox.SetWidth( x2 - x1 );
1296  bBox.SetHeight( y2 - y1 );
1297 
1298  bBox.Offset( m_Pos );
1299  return bBox;
1300 }
1301 
1302 
1304 {
1305  EDA_RECT bbox = GetBodyBoundingBox();
1306 
1307  for( size_t i = 0; i < m_Fields.size(); i++ )
1308  {
1309  bbox.Merge( m_Fields[i].GetBoundingBox() );
1310  }
1311 
1312  return bbox;
1313 }
1314 
1315 
1317 {
1318  wxString msg;
1319 
1320  // part and alias can differ if alias is not the root
1321  if( PART_SPTR part = m_part.lock() )
1322  {
1323  if( part.get() != dummy() )
1324  {
1325  LIB_ALIAS* alias = part->GetAlias( GetLibId().GetLibItemName() );
1326 
1327  if( !alias )
1328  return;
1329 
1330  if( m_currentSheetPath )
1331  aList.push_back( MSG_PANEL_ITEM( _( "Reference" ),
1333  DARKCYAN ) );
1334 
1335  msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
1336 
1337  aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetShownText(), DARKCYAN ) );
1338 
1339  // Display component reference in library and library
1340  aList.push_back( MSG_PANEL_ITEM( _( "Component" ), GetLibId().GetLibItemName(),
1341  BROWN ) );
1342 
1343  if( alias->GetName() != part->GetName() )
1344  aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), part->GetName(), BROWN ) );
1345 
1346  if( m_lib_id.GetLibNickname().empty() && alias->GetLib() && alias->GetLib()->IsCache() )
1347  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), alias->GetLibraryName(), RED ) );
1348  else if( !m_lib_id.GetLibNickname().empty() )
1349  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname(),
1350  BROWN ) );
1351  else
1352  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Undefined!!!" ), RED ) );
1353 
1354  // Display the current associated footprint, if exists.
1355  if( !GetField( FOOTPRINT )->IsVoid() )
1356  msg = GetField( FOOTPRINT )->GetShownText();
1357  else
1358  msg = _( "<Unknown>" );
1359 
1360  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) );
1361 
1362  // Display description of the component, and keywords found in lib
1363  aList.push_back( MSG_PANEL_ITEM( _( "Description" ), alias->GetDescription(),
1364  DARKCYAN ) );
1365  aList.push_back( MSG_PANEL_ITEM( _( "Key Words" ), alias->GetKeyWords(), DARKCYAN ) );
1366  }
1367  }
1368  else
1369  {
1370  if( m_currentSheetPath )
1371  aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( m_currentSheetPath ),
1372  DARKCYAN ) );
1373 
1374  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
1375  DARKCYAN ) );
1376  aList.push_back( MSG_PANEL_ITEM( _( "Symbol" ), GetLibId().GetLibItemName(), BROWN ) );
1377 
1378  wxString libNickname = GetLibId().GetLibNickname();
1379 
1380  if( libNickname.empty() )
1381  {
1382  aList.push_back( MSG_PANEL_ITEM( _( "Library" ),
1383  _( "No library defined!!!" ), RED ) );
1384  }
1385  else
1386  {
1387  msg.Printf( _( "Symbol not found in %s!!!" ), libNickname );
1388  aList.push_back( MSG_PANEL_ITEM( _( "Library" ), msg , RED ) );
1389  }
1390  }
1391 }
1392 
1393 
1395 {
1396  return add_component_xpm;
1397 }
1398 
1399 
1400 void SCH_COMPONENT::MirrorY( int aYaxis_position )
1401 {
1402  int dx = m_Pos.x;
1403 
1405  MIRROR( m_Pos.x, aYaxis_position );
1406  dx -= m_Pos.x; // dx,0 is the move vector for this transform
1407 
1408  for( int ii = 0; ii < GetFieldCount(); ii++ )
1409  {
1410  // Move the fields to the new position because the component itself has moved.
1411  wxPoint pos = GetField( ii )->GetTextPos();
1412  pos.x -= dx;
1413  GetField( ii )->SetTextPos( pos );
1414  }
1415 }
1416 
1417 
1418 void SCH_COMPONENT::MirrorX( int aXaxis_position )
1419 {
1420  int dy = m_Pos.y;
1421 
1423  MIRROR( m_Pos.y, aXaxis_position );
1424  dy -= m_Pos.y; // dy,0 is the move vector for this transform
1425 
1426  for( int ii = 0; ii < GetFieldCount(); ii++ )
1427  {
1428  // Move the fields to the new position because the component itself has moved.
1429  wxPoint pos = GetField( ii )->GetTextPos();
1430  pos.y -= dy;
1431  GetField( ii )->SetTextPos( pos );
1432  }
1433 }
1434 
1435 
1437 {
1438  wxPoint prev = m_Pos;
1439 
1440  RotatePoint( &m_Pos, aPosition, 900 );
1441 
1443 
1444  for( int ii = 0; ii < GetFieldCount(); ii++ )
1445  {
1446  // Move the fields to the new position because the component itself has moved.
1447  wxPoint pos = GetField( ii )->GetTextPos();
1448  pos.x -= prev.x - m_Pos.x;
1449  pos.y -= prev.y - m_Pos.y;
1450  GetField( ii )->SetTextPos( pos );
1451  }
1452 }
1453 
1454 
1455 bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData,
1456  wxPoint* aFindLocation )
1457 {
1458  wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
1459 
1460  // Components are searchable via the child field and pin item text.
1461  return false;
1462 }
1463 
1464 
1465 void SCH_COMPONENT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
1466 {
1467  if( PART_SPTR part = m_part.lock() )
1468  {
1469  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
1470  {
1471  wxASSERT( pin->Type() == LIB_PIN_T );
1472 
1473  if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) )
1474  continue;
1475 
1476  if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) )
1477  continue;
1478 
1479  DANGLING_END_ITEM item( PIN_END, pin, GetPinPhysicalPosition( pin ) );
1480  aItemList.push_back( item );
1481  }
1482  }
1483 }
1484 
1485 
1486 bool SCH_COMPONENT::IsPinDanglingStateChanged( std::vector<DANGLING_END_ITEM> &aItemList,
1487  LIB_PINS& aLibPins, unsigned aPin )
1488 {
1489  bool previousState;
1490 
1491  if( aPin < m_isDangling.size() )
1492  {
1493  previousState = m_isDangling[aPin];
1494  m_isDangling[aPin] = true;
1495  }
1496  else
1497  {
1498  previousState = true;
1499  m_isDangling.push_back( true );
1500  }
1501 
1502  wxPoint pin_position = GetPinPhysicalPosition( aLibPins[aPin] );
1503 
1504  for( DANGLING_END_ITEM& each_item : aItemList )
1505  {
1506  // Some people like to stack pins on top of each other in a symbol to indicate
1507  // internal connection. While technically connected, it is not particularly useful
1508  // to display them that way, so skip any pins that are in the same symbol as this
1509  // one.
1510  //
1511  // Do not make this exception for hidden pins, because those actually make internal
1512  // connections to a power net.
1513  const LIB_PIN* item_pin = dynamic_cast<const LIB_PIN*>( each_item.GetItem() );
1514 
1515  if( item_pin
1516  && ( !item_pin->IsPowerConnection() || !IsInNetlist() )
1517  && std::find( aLibPins.begin(), aLibPins.end(), item_pin) != aLibPins.end() )
1518  continue;
1519 
1520  switch( each_item.GetType() )
1521  {
1522  case PIN_END:
1523  case LABEL_END:
1524  case SHEET_LABEL_END:
1525  case WIRE_START_END:
1526  case WIRE_END_END:
1527  case NO_CONNECT_END:
1528  case JUNCTION_END:
1529  if( pin_position == each_item.GetPosition() )
1530  m_isDangling[aPin] = false;
1531  break;
1532  default:
1533  break;
1534  }
1535  if( !m_isDangling[aPin] )
1536  break;
1537  }
1538 
1539  return previousState != m_isDangling[aPin];
1540 }
1541 
1542 
1543 bool SCH_COMPONENT::IsDanglingStateChanged( std::vector<DANGLING_END_ITEM>& aItemList )
1544 {
1545  bool changed = false;
1546  LIB_PINS libPins;
1547  if( PART_SPTR part = m_part.lock() )
1548  part->GetPins( libPins, m_unit, m_convert );
1549  for( size_t i = 0; i < libPins.size(); ++i )
1550  {
1551  if( IsPinDanglingStateChanged( aItemList, libPins, i ) )
1552  changed = true;
1553  }
1554  return changed;
1555 }
1556 
1557 
1559 {
1560  for( bool each : m_isDangling )
1561  {
1562  if( each )
1563  return true;
1564  }
1565  return false;
1566 }
1567 
1568 
1570 {
1571  wxCHECK_MSG( Pin != NULL && Pin->Type() == LIB_PIN_T, wxPoint( 0, 0 ),
1572  wxT( "Cannot get physical position of pin." ) );
1573 
1574  return m_transform.TransformCoordinate( Pin->GetPosition() ) + m_Pos;
1575 }
1576 
1577 
1578 bool SCH_COMPONENT::IsSelectStateChanged( const wxRect& aRect )
1579 {
1580  bool previousState = IsSelected();
1581 
1583 
1584  if( aRect.Intersects( boundingBox ) )
1585  SetFlags( SELECTED );
1586  else
1587  ClearFlags( SELECTED );
1588 
1589  return previousState != IsSelected();
1590 }
1591 
1592 
1593 void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
1594 {
1595  if( PART_SPTR part = m_part.lock() )
1596  {
1597  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
1598  {
1599  wxCHECK_RET( pin->Type() == LIB_PIN_T,
1600  wxT( "GetNextPin() did not return a pin object. Bad programmer!" ) );
1601 
1602  // Skip items not used for this part.
1603  if( m_unit && pin->GetUnit() && ( pin->GetUnit() != m_unit ) )
1604  continue;
1605 
1606  if( m_convert && pin->GetConvert() && ( pin->GetConvert() != m_convert ) )
1607  continue;
1608 
1609  // Calculate the pin position relative to the component position and orientation.
1610  aPoints.push_back( m_transform.TransformCoordinate( pin->GetPosition() ) + m_Pos );
1611  }
1612  }
1613  else
1614  {
1615  wxCHECK_RET( 0,
1616  wxT( "Cannot add connection points to list. Cannot find component <" ) +
1617  GetLibId().GetLibItemName() + wxT( "> in any of the loaded libraries." ) );
1618  }
1619 }
1620 
1621 
1623 {
1624  if( PART_SPTR part = m_part.lock() )
1625  {
1626  // Calculate the position relative to the component.
1627  wxPoint libPosition = aPosition - m_Pos;
1628 
1629  return part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
1630  }
1631 
1632  return NULL;
1633 }
1634 
1635 
1637 {
1638  wxString tmp;
1639  tmp.Printf( _( "Component %s, %s" ),
1640  GetChars( GetLibId().GetLibItemName() ),
1641  GetChars( GetField( REFERENCE )->GetShownText() ) );
1642  return tmp;
1643 }
1644 
1645 
1646 SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR aInspector, void* aTestData,
1647  const KICAD_T aFilterTypes[] )
1648 {
1649  KICAD_T stype;
1650 
1651  for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
1652  {
1653  // If caller wants to inspect component type or and component children types.
1654  if( stype == Type() )
1655  {
1656  if( SEARCH_QUIT == aInspector( this, aTestData ) )
1657  return SEARCH_QUIT;
1658  }
1659 
1660  switch( stype )
1661  {
1662  case SCH_FIELD_T:
1663  // Test the bounding boxes of fields if they are visible and not empty.
1664  for( int ii = 0; ii < GetFieldCount(); ii++ )
1665  {
1666  if( SEARCH_QUIT == aInspector( GetField( ii ), (void*) this ) )
1667  return SEARCH_QUIT;
1668  }
1669  break;
1670 
1672  if( SEARCH_QUIT == aInspector( GetField( REFERENCE ), (void*) this ) )
1673  return SEARCH_QUIT;
1674  break;
1675 
1677  if( SEARCH_QUIT == aInspector( GetField( VALUE ), (void*) this ) )
1678  return SEARCH_QUIT;
1679  break;
1680 
1682  if( SEARCH_QUIT == aInspector( GetField( FOOTPRINT ), (void*) this ) )
1683  return SEARCH_QUIT;
1684  break;
1685 
1686 
1687  case LIB_PIN_T:
1688  if( PART_SPTR part = m_part.lock() )
1689  {
1690  LIB_PINS pins;
1691 
1692  part->GetPins( pins, m_unit, m_convert );
1693 
1694  for( size_t i = 0; i < pins.size(); i++ )
1695  {
1696  if( SEARCH_QUIT == aInspector( pins[ i ], (void*) this ) )
1697  return SEARCH_QUIT;
1698  }
1699  }
1700  break;
1701 
1702  default:
1703  break;
1704  }
1705  }
1706 
1707  return SEARCH_CONTINUE;
1708 }
1709 
1710 
1712  SCH_SHEET_PATH* aSheetPath )
1713 {
1714  if( PART_SPTR part = m_part.lock() )
1715  {
1716  for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
1717  {
1718  wxASSERT( pin->Type() == LIB_PIN_T );
1719 
1720  if( pin->GetUnit() && ( pin->GetUnit() != GetUnitSelection( aSheetPath ) ) )
1721  continue;
1722 
1723  if( pin->GetConvert() && ( pin->GetConvert() != GetConvert() ) )
1724  continue;
1725 
1726  wxPoint pos = GetTransform().TransformCoordinate( pin->GetPosition() ) + m_Pos;
1727 
1728  NETLIST_OBJECT* item = new NETLIST_OBJECT();
1729  item->m_SheetPathInclude = *aSheetPath;
1730  item->m_Comp = (SCH_ITEM*) pin;
1731  item->m_SheetPath = *aSheetPath;
1732  item->m_Type = NET_PIN;
1733  item->m_Link = (SCH_ITEM*) this;
1734  item->m_ElectricalPinType = pin->GetType();
1735  item->m_PinNum = pin->GetNumber();
1736  item->m_Label = pin->GetName();
1737  item->m_Start = item->m_End = pos;
1738 
1739  aNetListItems.push_back( item );
1740 
1741  if( pin->IsPowerConnection() )
1742  {
1743  // There is an associated PIN_LABEL.
1744  item = new NETLIST_OBJECT();
1745  item->m_SheetPathInclude = *aSheetPath;
1746  item->m_Comp = NULL;
1747  item->m_SheetPath = *aSheetPath;
1748  item->m_Type = NET_PINLABEL;
1749  item->m_Label = pin->GetName();
1750  item->m_Start = pos;
1751  item->m_End = item->m_Start;
1752 
1753  aNetListItems.push_back( item );
1754  }
1755  }
1756  }
1757 }
1758 
1759 
1760 bool SCH_COMPONENT::operator <( const SCH_ITEM& aItem ) const
1761 {
1762  if( Type() != aItem.Type() )
1763  return Type() < aItem.Type();
1764 
1765  SCH_COMPONENT* component = (SCH_COMPONENT*) &aItem;
1766 
1767  EDA_RECT rect = GetBodyBoundingBox();
1768 
1769  if( rect.GetArea() != component->GetBodyBoundingBox().GetArea() )
1770  return rect.GetArea() < component->GetBodyBoundingBox().GetArea();
1771 
1772  if( m_Pos.x != component->m_Pos.x )
1773  return m_Pos.x < component->m_Pos.x;
1774 
1775  if( m_Pos.y != component->m_Pos.y )
1776  return m_Pos.y < component->m_Pos.y;
1777 
1778  return false;
1779 }
1780 
1781 
1782 bool SCH_COMPONENT::operator==( const SCH_COMPONENT& aComponent ) const
1783 {
1784  if( GetFieldCount() != aComponent.GetFieldCount() )
1785  return false;
1786 
1787  for( int i = VALUE; i < GetFieldCount(); i++ )
1788  {
1789  if( GetField( i )->GetText().Cmp( aComponent.GetField( i )->GetText() ) != 0 )
1790  return false;
1791  }
1792 
1793  return true;
1794 }
1795 
1796 
1797 bool SCH_COMPONENT::operator!=( const SCH_COMPONENT& aComponent ) const
1798 {
1799  return !( *this == aComponent );
1800 }
1801 
1802 
1804 {
1805  wxCHECK_MSG( Type() == aItem.Type(), *this,
1806  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
1807  GetClass() );
1808 
1809  if( &aItem != this )
1810  {
1811  SCH_ITEM::operator=( aItem );
1812 
1813  SCH_COMPONENT* c = (SCH_COMPONENT*) &aItem;
1814 
1815  m_lib_id = c->m_lib_id;
1816  m_part = c->m_part;
1817  m_Pos = c->m_Pos;
1818  m_unit = c->m_unit;
1819  m_convert = c->m_convert;
1820  m_transform = c->m_transform;
1821 
1823 
1824  m_Fields = c->m_Fields; // std::vector's assignment operator.
1825 
1826  // Reparent fields after assignment to new component.
1827  for( int ii = 0; ii < GetFieldCount(); ++ii )
1828  {
1829  GetField( ii )->SetParent( this );
1830  }
1831  }
1832 
1833  return *this;
1834 }
1835 
1836 
1837 bool SCH_COMPONENT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
1838 {
1839  EDA_RECT bBox = GetBodyBoundingBox();
1840  bBox.Inflate( aAccuracy );
1841 
1842  if( bBox.Contains( aPosition ) )
1843  return true;
1844 
1845  return false;
1846 }
1847 
1848 
1849 bool SCH_COMPONENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
1850 {
1852  return false;
1853 
1854  EDA_RECT rect = aRect;
1855 
1856  rect.Inflate( aAccuracy );
1857 
1858  if( aContained )
1859  return rect.Contains( GetBodyBoundingBox() );
1860 
1861  return rect.Intersects( GetBodyBoundingBox() );
1862 }
1863 
1864 
1865 bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const
1866 {
1867  std::vector< wxPoint > pts;
1868 
1869  GetConnectionPoints( pts );
1870 
1871  for( size_t i = 0; i < pts.size(); i++ )
1872  {
1873  if( pts[i] == aPosition )
1874  return true;
1875  }
1876 
1877  return false;
1878 }
1879 
1880 
1882 {
1883  SCH_FIELD* rf = GetField( REFERENCE );
1884  return ! rf->GetText().StartsWith( wxT( "#" ) );
1885 }
1886 
1887 
1888 void SCH_COMPONENT::Plot( PLOTTER* aPlotter )
1889 {
1890  TRANSFORM temp;
1891 
1892  if( PART_SPTR part = m_part.lock() )
1893  {
1894  temp = GetTransform();
1895 
1896  part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp );
1897 
1898  for( size_t i = 0; i < m_Fields.size(); i++ )
1899  {
1900  m_Fields[i].Plot( aPlotter );
1901  }
1902  }
1903 }
Definition of the SCH_SHEET class for Eeschema.
LIB_ALIAS * LoadSymbol(const wxString &aNickname, const wxString &aAliasName)
Load a LIB_ALIAS having aAliasName from the library given by aNickname.
void UpdateFields(bool aResetStyle, bool aResetRef=false)
Restores fields to the original library values.
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item...
bool IsValid() const
Definition: lib_id.h:155
int GetCount() const
Function GetCount returns the number of objects in the list.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
void Offset(int dx, int dy)
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
Definition: sch_field.h:56
SCH_LAYER_ID m_Layer
void SetModified()
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDc, const wxPoint &aOffset, int aMulti, int aConvert, const PART_DRAW_OPTIONS &aOpts)
Draw part.
Part library alias object definition.
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
bool IsMoving() const
Definition: base_struct.h:232
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:182
wxString GetAliasDescription() const
Return information about the aliased parts.
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
TRANSFORM & GetTransform() const
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
void SetTransform(const TRANSFORM &aTransform)
PNG memory record (file in memory).
Definition: bitmap_types.h:38
void UpdateUnit(int aUnit)
Change the unit number to aUnit without setting any internal flags.
wxString GetPath(const SCH_SHEET_PATH *sheet) const
const wxPoint & GetTextPos() const
Definition: eda_text.h:224
int GetOrientation()
Get the display symbol orientation.
int y2
Definition: transform.h:51
EDA_ITEM * GetCurItem() const
SCH_SHEET_PATH m_SheetPathInclude
Class LIB_TEXT defines a component library graphical text item.
Definition: lib_text.h:45
time_t m_TimeStamp
Time stamp used for logical links.
Definition: base_struct.h:183
bool Contains(const wxPoint &aPoint) const
Function Contains.
SCH_FIELDS m_Fields
Variable length list of fields.
Definition: sch_component.h:91
const SCH_SHEET_PATH * m_currentSheetPath
A temporary sheet path is required to generate the correct reference designator string in complex hie...
wxPoint GetScreenCoord(const wxPoint &aPoint)
Returns the coordinate points relative to the orientation of the symbol to aPoint.
void ImportValues(const LIB_FIELD &aSource)
Function ImportValues copy parameters from a LIB_FIELD source.
Definition: sch_field.cpp:221
bool Resolve(PART_LIBS *aLibs)
Assigns the current LIB_PART from aLibs which this symbol is based on.
static bool sort_by_libid(const SCH_COMPONENT *ref, SCH_COMPONENT *cmp)
const wxString GetLibraryName()
wxArrayString m_PathsAndReferences
Defines the hierarchical path and reference of the component.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:138
wxPoint m_Pos
Name and library where symbol was loaded from, i.e. "74xx:74LS00".
Definition: sch_component.h:77
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors...
Class LIB_FIELD is used in symbol libraries.
Definition: lib_field.h:60
void GetConnectionPoints(std::vector< wxPoint > &aPoints) const override
Function GetConnectionPoints add all the connection points for this item to aPoints.
int GetUnitSelection(SCH_SHEET_PATH *aSheet)
const EDA_RECT GetBodyBoundingBox(int aUnit, int aConvert) const
Function GetBodyBoundingBox.
bool IsCache() const
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Function GetEndPoints adds the schematic item end points to aItemList if the item has end points...
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor=COLOR4D::UNSPECIFIED) override
Function Draw Draw a schematic item.
Definition: sch_field.cpp:118
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:223
time_t GetNewTimeStamp()
Definition: common.cpp:166
int x2
Definition: transform.h:50
void MirrorX(int aXaxis_position) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
bool IsSelected() const
Definition: base_struct.h:235
LIB_PIN * GetPin(const wxString &number)
Find a symbol pin by number.
int x1
Definition: transform.h:48
static const wxString GetDefaultFieldName(int aFieldNdx)
Function GetDefaultFieldName returns a default symbol field name for field aFieldNdx for all componen...
SCH_SHEET_PATH m_SheetPath
LIB_ITEM * GetDrawItem(const wxPoint &aPosition, KICAD_T aType=TYPE_NOT_INIT)
Return the component library item at aPosition that is part of this component.
ELECTRICAL_PINTYPE m_ElectricalPinType
void SetUnitSelection(SCH_SHEET_PATH *aSheet, int aUnitSelection)
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:214
int GetUnitCount() const
Return the number of units per package of the symbol.
std::vector< bool > m_isDangling
One isDangling per pin.
Definition: sch_component.h:95
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
EDA_RECT GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the fields.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
NETLIST_ITEM_T m_Type
PART_LIB * GetLib()
#define abs(a)
Definition: auxiliary.h:84
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
wxString GetFieldText(wxString aFieldName, bool aIncludeDefaultFields=true) const
Search for a field named aFieldName and returns text associated with this field.
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
Definition: colors.h:54
void SetTimeStamp(time_t aNewTimeStamp)
Definition: base_struct.h:217
Class LIB_ITEM is the base class for drawable items used by schematic library components.
Definition: lib_draw_item.h:67
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populates a std::vector with SCH_FIELDs.
wxString GetAliasDocumentation() const
Return the documentation text for the given part alias.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Class NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected item...
wxString Path() const
Function Path the path uses the time stamps which do not changes even when editing sheet parameters a...
void SetConvert(int aConvert)
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
bool IsSelectStateChanged(const wxRect &aRect) override
Function IsSelectStateChanged checks if the selection state of an item inside aRect has changed...
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
#define IS_NEW
New item, just created.
Definition: base_struct.h:127
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:118
Class SCH_COLLECTOR.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
BOX2I boundingBox(T aObject)
boundingBox template method
Definition: shape_index.h:59
int GetConvert() const
int y1
Definition: transform.h:49
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
#define SELECTED
Definition: base_struct.h:134
void SetLibId(const LIB_ID &aName, PART_LIBS *aLibs=NULL)
wxString wx_str() const
Definition: utf8.cpp:48
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1076
void SetTimeStamp(time_t aNewTimeStamp)
Change the time stamp to aNewTimeStamp and updates the reference path.
double GetArea() const
Function GetArea returns the area of the rectangle.
Class for tranforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
PART_REF m_part
points into the PROJECT's libraries to the LIB_PART for this component
Definition: sch_component.h:93
const wxString traceFindItem
Flag to enable finding schematic item debug output.
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:267
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
bool empty() const
Definition: utf8.h:108
void SetHeight(int val)
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:227
static void ResolveAll(const SCH_COLLECTOR &aComponents, PART_LIBS *aLibs)
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
bool IsMouseCaptured() const
const wxString & GetName() const
const UTF8 & GetLibItemName() const
Definition: lib_id.h:115
Subclass of DIALOG_SCH_FIND_BASE, which is generated by wxFormBuilder.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
wxPoint GetPinPhysicalPosition(LIB_PIN *Pin)
std::shared_ptr< LIB_PART > PART_SPTR
shared pointer to LIB_PART
void SetLayer(SCH_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
bool operator<(const SCH_ITEM &aItem) const override
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
wxString GetDescription() const
SCH_COMPONENT(const wxPoint &pos=wxPoint(0, 0), SCH_ITEM *aParent=NULL)
PART_SPTR SharedPtr()
std::string toUTFTildaText(const wxString &txt)
Function toUTFTildaText convert a wxString to UTF8 and replace any control characters with a ~...
Class LIB_PART defines a library part object.
LIB_ALIAS * FindAlias(const wxString &aName) const
Find LIB_ALIAS by aName.
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
bool IsDangling() const override
Return whether any pin in this symbol is dangling.
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:136
EDA_RECT * GetClipBox()
void GetNetListItem(NETLIST_OBJECT_LIST &aNetListItems, SCH_SHEET_PATH *aSheetPath) override
Function GetNetListItem creates a new NETLIST_OBJECT for the schematic object and adds it to aNetList...
void SetX(int val)
LIB_PART * FindLibPart(const LIB_ID &aLibId, const wxString &aLibraryName=wxEmptyString)
Function FindLibPart searches all libraries in the list for a part.
Definition: colors.h:60
wxString GetText(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:33
void SetUnit(int aUnit)
Change the unit number to aUnit.
bool Matches(wxFindReplaceData &aSearchData, void *aAuxData, wxPoint *aFindLocation) override
Function Matches compares the item against the search criteria in aSearchData.
int GetBottom() const
int GetUnit() const
Class SCH_SHEET_PATH.
bool IsInNetlist() const
static PART_DRAW_OPTIONS Default()
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear exiting component annotation.
int GetRight() const
void SetWidth(int val)
const wxString GetRef(const SCH_SHEET_PATH *aSheet)
Return the reference for the given sheet path.
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
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
void SetEndPosition(const wxPoint &aPosition)
Definition: lib_rectangle.h:62
void SetY(int val)
bool operator==(const SCH_COMPONENT &aComponent) const
LIB_PART * GetPart() const
Function GetPart gets the shared LIB_PART.
SCH_ITEM & operator=(const SCH_ITEM &aItem)
wxPoint GetPosition() const override
Function GetPosition returns the current draw object position.
Definition: lib_pin.h:465
void Move(const wxPoint &aPosition) override
Function Move moves a draw object to aPosition.
Class PART_LIBS is a collection of PART_LIBs.
Definition of the NETLIST_OBJECT class.
int m_unit
The unit for multiple part per package components.
Definition: sch_component.h:82
void Init(const wxPoint &pos=wxPoint(0, 0))
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
bool IsDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList) override
Test if the component's dangling state has changed for all pins.
Base plotter engine class.
Definition: class_plotter.h:97
wxString GetDocFileName() const
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Definition the SCH_COMPONENT class for Eeschema.
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_draw_item.h:60
void GetPins(std::vector< LIB_PIN * > &aPinsList)
Populate a vector with all the pins.
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
see class PGM_BASE
const wxString & GetName() const
int GetFieldCount() const
Return the number of fields in this symbol.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_field.cpp:251
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
static double square(int x)
Definition: trigo.cpp:138
void AddHierarchicalReference(const wxString &aPath, const wxString &aRef, int aMulti)
Add a full hierarchical reference to this symbol.
bool IsVisible() const
Definition: eda_text.h:176
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
bool IsPinDanglingStateChanged(std::vector< DANGLING_END_ITEM > &aItemList, LIB_PINS &aLibPins, unsigned aPin)
Test if the symbol's dangling state has changed for one given pin index.
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor=COLOR4D::UNSPECIFIED) override
Function Draw Draw a schematic item.
#define ROTATE_VALUES_COUNT
void SetText(const wxString &aText) override
Sets the text item string to aText.
Definition: lib_text.cpp:484
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:261
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:189
Class EDA_RECT handles the component boundary box.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
int GetX() const
const LIB_ID & GetLibId() const
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:187
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
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...
UTF8 Format() const
Definition: lib_id.cpp:263
int GetY() const
virtual wxString GetClass() const override
Function GetClass returns the class name.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:268
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:366
bool HasLibrary(const wxString &aNickname) const
Test for the existence of aNickname in the library table.
bool operator!=(const SCH_COMPONENT &aComponent) const
int m_convert
The alternate body style for components that have more than one body style defined.
Definition: sch_component.h:83
Class DANGLING_END_ITEM is a helper class used to store the state of schematic items that can be conn...
Definition for part library class.
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
SEARCH_RESULT
Definition: base_struct.h:82
static bool IsReferenceStringValid(const wxString &aReferenceString)
Tests for an acceptable reference string.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:98
wxString GetClass() const override
Function GetClass returns the class name.
Message panel definition file.
AUTOPLACED m_fieldsAutoplaced
indicates status of field autoplacement
Definition: sch_component.h:97
wxString m_prefix
C, R, U, Q etc - the first character which typically indicates what the component is...
Definition: sch_component.h:86
#define VALUE
Class PART_LIB is used to load, save, search, and otherwise manipulate part library files...
wxString GetKeyWords() const
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
TRANSFORM m_transform
The rotation/mirror transformation matrix.
Definition: sch_component.h:90
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
bool doIsConnected(const wxPoint &aPosition) const override
Function doIsConnected provides the object specific test to see if it is connected to aPosition...
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
virtual void SetText(const wxString &aText)
Definition: eda_text.h:141
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
#define IS_MOVED
Item being moved.
Definition: base_struct.h:126
Definition: colors.h:62