KiCad PCB EDA Suite
SCH_REFERENCE_LIST Class Reference

Class SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierarchy, a component can be used more than once and its reference designator is dependent on the sheet path for the same component. More...

#include <sch_reference_list.h>

Public Member Functions

 SCH_REFERENCE_LIST ()
 Constructor. More...
 
SCH_REFERENCEoperator[] (int aIndex)
 
unsigned GetCount ()
 Function GetCount. More...
 
SCH_REFERENCEGetItem (int aIdx)
 Function GetItem. More...
 
void AddItem (SCH_REFERENCE &aItem)
 Function AddItem adds a SCH_REFERENCE object to the list of references. More...
 
void RemoveItem (unsigned int aIndex)
 Function RemoveItem removes an item from the list of references. More...
 
void RemoveSubComponentsFromList ()
 Function RemoveSubComponentsFromList Remove sub components from the list, when multiples parts per package are found in this list. More...
 
void SplitReferences ()
 Function SplitReferences attempts to split all reference designators into a name (U) and number (1). More...
 
void UpdateAnnotation ()
 function UpdateAnnotation Updates the reference components for the schematic project (or the current sheet) Note: this function does not calculate the reference numbers stored in m_NumRef So, it must be called after calculation of new reference numbers More...
 
void Annotate (bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap)
 Function Annotate set the reference designators in the list that have not been annotated. More...
 
int CheckAnnotation (REPORTER &aReporter)
 Function CheckAnnotation check for annotations errors. More...
 
void SortByXCoordinate ()
 Function sortByXCoordinate sorts the list of references by X position. More...
 
void SortByYCoordinate ()
 Function sortByYCoordinate sorts the list of references by Y position. More...
 
void SortByTimeStamp ()
 Function SortComponentsByTimeStamp sort the flat list by Time Stamp. More...
 
void SortByRefAndValue ()
 Function SortByRefAndValue sorts the list of references by value. More...
 
void SortByReferenceOnly ()
 Function SortByReferenceOnly sorts the list of references by reference. More...
 
int FindUnit (size_t aIndex, int aUnit)
 searches the sorted list of components for a another component with the same reference and a given part unit. More...
 
void GetRefsInUse (int aIndex, std::vector< int > &aIdList, int aMinRefId)
 Function GetRefsInUse adds all the reference designator numbers greater than aMinRefId to aIdList skipping the reference at aIndex. More...
 
int GetLastReference (int aIndex, int aMinValue)
 Function GetLastReference returns the last used (greatest) reference number in the reference list for the prefix reference given by aIndex. More...
 

Static Public Member Functions

static wxString Shorthand (std::vector< SCH_REFERENCE > aList)
 Function Shorthand Returns a shorthand string representing all the references in the list. More...
 

Private Member Functions

int CreateFirstFreeRefId (std::vector< int > &aIdList, int aFirstValue)
 Function CreateFirstFreeRefId searches for the first free reference number in aListId of reference numbers in use. More...
 

Static Private Member Functions

static bool sortByRefAndValue (const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
 
static bool sortByXPosition (const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
 
static bool sortByYPosition (const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
 
static bool sortByTimeStamp (const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
 
static bool sortByReferenceOnly (const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
 

Private Attributes

std::vector< SCH_REFERENCEcomponentFlatList
 

Detailed Description

Class SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierarchy, a component can be used more than once and its reference designator is dependent on the sheet path for the same component.

This flattened list is used for netlist generation, BOM generation, and schematic annotation.

Definition at line 199 of file sch_reference_list.h.

Constructor & Destructor Documentation

◆ SCH_REFERENCE_LIST()

SCH_REFERENCE_LIST::SCH_REFERENCE_LIST ( )
inline

Constructor.

Definition at line 207 of file sch_reference_list.h.

208  {
209  }

Member Function Documentation

◆ AddItem()

void SCH_REFERENCE_LIST::AddItem ( SCH_REFERENCE aItem)
inline

Function AddItem adds a SCH_REFERENCE object to the list of references.

Parameters
aItem- a SCH_REFERENCE item to add

Definition at line 239 of file sch_reference_list.h.

240  {
241  componentFlatList.push_back( aItem );
242  }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

Referenced by SCH_SHEET_LIST::AnnotatePowerSymbols(), and SCH_SHEET_PATH::GetComponents().

◆ Annotate()

void SCH_REFERENCE_LIST::Annotate ( bool  aUseSheetNum,
int  aSheetIntervalId,
int  aStartNumber,
SCH_MULTI_UNIT_REFERENCE_MAP  aLockedUnitMap 
)

Function Annotate set the reference designators in the list that have not been annotated.

Parameters
aUseSheetNumSet to true to start annotation for each sheet at the sheet number times aSheetIntervalId. Otherwise annotate incrementally.
aSheetIntervalIdThe per sheet reference designator multiplier.
aStartNumberThe number to start with if NOT numbering based on sheet number.
aLockedUnitMapA SCH_MULTI_UNIT_REFERENCE_MAP of reference designator wxStrings to SCH_REFERENCE_LISTs. May be an empty map. If not empty, any multi-unit parts found in this map will be annotated as a group rather than individually.

If a the sheet number is 2 and aSheetIntervalId is 100, then the first reference designator would be 201 and the last reference designator would be 299 when no overlap occurs with sheet number 3. If there are 150 items in sheet number 2, then items are referenced U201 to U351, and items in sheet 3 start from U352

Definition at line 291 of file component_references_lister.cpp.

293 {
294  if ( componentFlatList.size() == 0 )
295  return;
296 
297  int LastReferenceNumber = 0;
298  int NumberOfUnits, Unit;
299 
300  /* calculate index of the first component with the same reference prefix
301  * than the current component. All components having the same reference
302  * prefix will receive a reference number with consecutive values:
303  * IC .. will be set to IC4, IC4, IC5 ...
304  */
305  unsigned first = 0;
306 
307  // calculate the last used number for this reference prefix:
308 #ifdef USE_OLD_ALGO
309  int minRefId = 0;
310 
311  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
312  if( aUseSheetNum )
313  minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId;
314 
315  LastReferenceNumber = GetLastReference( first, minRefId );
316 #else
317  int minRefId;
318 
319  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
320  if( aUseSheetNum )
321  minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId + 1;
322  else
323  minRefId = aStartNumber + 1;
324 
325  // For multi units components, when "keep order of multi unit" option is selected,
326  // store the list of already used full references.
327  // The algorithm try to allocate the new reference to components having the same
328  // old reference.
329  // This algo works fine as long as the previous annotation has no duplicates.
330  // But when a hierarchy is reannotated with this option, the previous anotation can
331  // have duplicate references, and obviously we must fix these duplicate.
332  // therefore do not try to allocate a full reference more than once when trying
333  // to keep this order of multi units.
334  // inUseRefs keep trace of previously allocated references
335  std::unordered_set<wxString> inUseRefs;
336 
337  // This is the list of all Id already in use for a given reference prefix.
338  // Will be refilled for each new reference prefix.
339  std::vector<int>idList;
340  GetRefsInUse( first, idList, minRefId );
341 #endif
342  for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
343  {
344  auto& ref_unit = componentFlatList[ii];
345 
346  if( ref_unit.m_Flag )
347  continue;
348 
349  // Check whether this component is in aLockedUnitMap.
350  SCH_REFERENCE_LIST* lockedList = NULL;
351  for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : aLockedUnitMap )
352  {
353  unsigned n_refs = pair.second.GetCount();
354 
355  for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
356  {
357  SCH_REFERENCE &thisRef = pair.second[thisRefI];
358 
359  if( thisRef.IsSameInstance( ref_unit ) )
360  {
361  lockedList = &pair.second;
362  break;
363  }
364  }
365  if( lockedList != NULL ) break;
366  }
367 
368  if( ( componentFlatList[first].CompareRef( ref_unit ) != 0 )
369  || ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != ref_unit.m_SheetNum ) ) )
370  {
371  // New reference found: we need a new ref number for this reference
372  first = ii;
373 #ifdef USE_OLD_ALGO
374  minRefId = 0;
375 
376  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
377  if( aUseSheetNum )
378  minRefId = ref_unit.m_SheetNum * aSheetIntervalId;
379 
380  LastReferenceNumber = GetLastReference( ii, minRefId );
381 
382 #else
383  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
384  if( aUseSheetNum )
385  minRefId = ref_unit.m_SheetNum * aSheetIntervalId + 1;
386  else
387  minRefId = aStartNumber + 1;
388 
389  GetRefsInUse( first, idList, minRefId );
390 #endif
391  }
392 
393  // Annotation of one part per package components (trivial case).
394  if( ref_unit.GetLibPart()->GetUnitCount() <= 1 )
395  {
396  if( ref_unit.m_IsNew )
397  {
398 #ifdef USE_OLD_ALGO
399  LastReferenceNumber++;
400 #else
401  LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
402 #endif
403  ref_unit.m_NumRef = LastReferenceNumber;
404  }
405 
406  ref_unit.m_Unit = 1;
407  ref_unit.m_Flag = 1;
408  ref_unit.m_IsNew = false;
409  continue;
410  }
411 
412  // Annotation of multi-unit parts ( n units per part ) (complex case)
413  NumberOfUnits = ref_unit.GetLibPart()->GetUnitCount();
414 
415  if( ref_unit.m_IsNew )
416  {
417 #ifdef USE_OLD_ALGO
418  LastReferenceNumber++;
419 #else
420  LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
421 #endif
422  ref_unit.m_NumRef = LastReferenceNumber;
423 
424  if( !ref_unit.IsUnitsLocked() )
425  ref_unit.m_Unit = 1;
426 
427  ref_unit.m_Flag = 1;
428  }
429 
430  // If this component is in aLockedUnitMap, copy the annotation to all
431  // components that are not it
432  if( lockedList != NULL )
433  {
434  unsigned n_refs = lockedList->GetCount();
435 
436  for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
437  {
438  SCH_REFERENCE &thisRef = (*lockedList)[thisRefI];
439 
440  if( thisRef.IsSameInstance( ref_unit ) )
441  {
442  // This is the component we're currently annotating. Hold the unit!
443  ref_unit.m_Unit = thisRef.m_Unit;
444  // lock this new full reference
445  inUseRefs.insert( buildFullReference( ref_unit ) );
446  }
447 
448  if( thisRef.CompareValue( ref_unit ) != 0 )
449  continue;
450 
451  if( thisRef.CompareLibName( ref_unit ) != 0 )
452  continue;
453 
454  // Find the matching component
455  for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ )
456  {
457  if( ! thisRef.IsSameInstance( componentFlatList[jj] ) )
458  continue;
459 
460  wxString ref_candidate = buildFullReference( ref_unit, thisRef.m_Unit );
461 
462  // propagate the new reference and unit selection to the "old" component,
463  // if this new full reference is not already used (can happens when initial
464  // multiunits components have duplicate references)
465  if( inUseRefs.find( ref_candidate ) == inUseRefs.end() )
466  {
467  componentFlatList[jj].m_NumRef = ref_unit.m_NumRef;
468  componentFlatList[jj].m_Unit = thisRef.m_Unit;
469  componentFlatList[jj].m_IsNew = false;
470  componentFlatList[jj].m_Flag = 1;
471  // lock this new full reference
472  inUseRefs.insert( ref_candidate );
473  break;
474  }
475  }
476  }
477  }
478  else
479  {
480  /* search for others units of this component.
481  * we search for others parts that have the same value and the same
482  * reference prefix (ref without ref number)
483  */
484  for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
485  {
486  if( ref_unit.m_Unit == Unit )
487  continue;
488 
489  int found = FindUnit( ii, Unit );
490 
491  if( found >= 0 )
492  continue; // this unit exists for this reference (unit already annotated)
493 
494  // Search a component to annotate ( same prefix, same value, not annotated)
495  for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ )
496  {
497  auto& cmp_unit = componentFlatList[jj];
498 
499  if( cmp_unit.m_Flag ) // already tested
500  continue;
501 
502  if( cmp_unit.CompareRef( ref_unit ) != 0 )
503  continue;
504 
505  if( cmp_unit.CompareValue( ref_unit ) != 0 )
506  continue;
507 
508  if( cmp_unit.CompareLibName( ref_unit ) != 0 )
509  continue;
510 
511  if( aUseSheetNum &&
512  cmp_unit.GetSheetPath().Cmp( ref_unit.GetSheetPath() ) != 0 )
513  continue;
514 
515  if( !cmp_unit.m_IsNew )
516  continue;
517 
518  // Component without reference number found, annotate it if possible
519  if( !cmp_unit.IsUnitsLocked()
520  || ( cmp_unit.m_Unit == Unit ) )
521  {
522  cmp_unit.m_NumRef = ref_unit.m_NumRef;
523  cmp_unit.m_Unit = Unit;
524  cmp_unit.m_Flag = 1;
525  cmp_unit.m_IsNew = false;
526  break;
527  }
528  }
529  }
530  }
531  }
532 }
std::vector< SCH_REFERENCE > componentFlatList
Class SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierar...
void GetRefsInUse(int aIndex, std::vector< int > &aIdList, int aMinRefId)
Function GetRefsInUse adds all the reference designator numbers greater than aMinRefId to aIdList ski...
int m_Unit
The unit number for components with multiple parts per package.
int CompareValue(const SCH_REFERENCE &item) const
wxString buildFullReference(const SCH_REFERENCE &aItem, int aUnitNumber=-1)
int CompareLibName(const SCH_REFERENCE &item) const
int FindUnit(size_t aIndex, int aUnit)
searches the sorted list of components for a another component with the same reference and a given pa...
bool IsSameInstance(const SCH_REFERENCE &other) const
Function IsSameInstance returns whether this reference refers to the same component instance (compone...
int CreateFirstFreeRefId(std::vector< int > &aIdList, int aFirstValue)
Function CreateFirstFreeRefId searches for the first free reference number in aListId of reference nu...
int GetLastReference(int aIndex, int aMinValue)
Function GetLastReference returns the last used (greatest) reference number in the reference list for...
unsigned GetCount()
Function GetCount.
Class SCH_REFERENCE is used as a helper to define a component's reference designator in a schematic.

References buildFullReference(), SCH_REFERENCE::CompareLibName(), SCH_REFERENCE::CompareValue(), componentFlatList, CreateFirstFreeRefId(), FindUnit(), GetCount(), GetLastReference(), GetRefsInUse(), SCH_REFERENCE::IsSameInstance(), and SCH_REFERENCE::m_Unit.

Referenced by SCH_EDIT_FRAME::AnnotateComponents(), and SCH_SHEET_LIST::AnnotatePowerSymbols().

◆ CheckAnnotation()

int SCH_REFERENCE_LIST::CheckAnnotation ( REPORTER aReporter)

Function CheckAnnotation check for annotations errors.

The following annotation error conditions are tested:

  • Components not annotated.
  • Components having the same reference designator (duplicates).
  • Components with multiple parts per package having different reference designators.
  • Components with multiple parts per package with invalid part count.
Parameters
aReporterA sink for error messages. Use NULL_REPORTER if you don't need errors.
Returns
The number of errors found.

Definition at line 535 of file component_references_lister.cpp.

536 {
537  int error = 0;
538  wxString tmp;
539  wxString msg;
540 
542 
543  // Spiit reference designators into name (prefix) and number: IC1 becomes IC, and 1.
544  SplitReferences();
545 
546  // count not yet annotated items or annotation error.
547  for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
548  {
549  msg.Empty();
550  tmp.Empty();
551 
552  if( componentFlatList[ii].m_IsNew ) // Not yet annotated
553  {
554  if( componentFlatList[ii].m_NumRef >= 0 )
555  tmp << componentFlatList[ii].m_NumRef;
556  else
557  tmp = wxT( "?" );
558 
559 
560  if( ( componentFlatList[ii].m_Unit > 0 )
561  && ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
562  {
563  msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ),
564  componentFlatList[ii].GetRef(),
565  tmp,
566  componentFlatList[ii].m_Unit );
567  }
568  else
569  {
570  msg.Printf( _( "Item not annotated: %s%s\n" ),
571  GetChars( componentFlatList[ii].GetRef() ),
572  GetChars( tmp ) );
573  }
574 
575  aReporter.Report( msg, REPORTER::RPT_WARNING );
576  error++;
577  break;
578  }
579 
580  // Error if unit number selected does not exist ( greater than the number of
581  // parts in the component ). This can happen if a component has changed in a
582  // library after a previous annotation.
583  if( std::max( componentFlatList[ii].GetLibPart()->GetUnitCount(), 1 )
584  < componentFlatList[ii].m_Unit )
585  {
586  if( componentFlatList[ii].m_NumRef >= 0 )
587  tmp << componentFlatList[ii].m_NumRef;
588  else
589  tmp = wxT( "?" );
590 
591  msg.Printf( _( "Error: symbol %s%s unit %d and symbol has only %d units defined\n" ),
592  componentFlatList[ii].GetRef(),
593  tmp,
594  componentFlatList[ii].m_Unit,
595  componentFlatList[ii].GetLibPart()->GetUnitCount() );
596 
597  aReporter.Report( msg, REPORTER::RPT_ERROR );
598  error++;
599  break;
600  }
601  }
602 
603  if( error )
604  return error;
605 
606  // count the duplicated elements (if all are annotated)
607  int imax = componentFlatList.size() - 1;
608 
609  for( int ii = 0; ii < imax; ii++ )
610  {
611  msg.Empty();
612  tmp.Empty();
613 
614  if( ( componentFlatList[ii].CompareRef( componentFlatList[ii + 1] ) != 0 )
615  || ( componentFlatList[ii].m_NumRef != componentFlatList[ii + 1].m_NumRef ) )
616  continue;
617 
618  // Same reference found. If same unit, error!
619  if( componentFlatList[ii].m_Unit == componentFlatList[ii + 1].m_Unit )
620  {
621  if( componentFlatList[ii].m_NumRef >= 0 )
622  tmp << componentFlatList[ii].m_NumRef;
623  else
624  tmp = wxT( "?" );
625 
626  if( ( componentFlatList[ii].m_Unit > 0 )
627  && ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
628  {
629  msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
630  componentFlatList[ii].GetRef(),
631  tmp,
632  componentFlatList[ii].m_Unit );
633  }
634  else
635  {
636  msg.Printf( _( "Multiple item %s%s\n" ),
637  componentFlatList[ii].GetRef(),
638  tmp );
639  }
640 
641  aReporter.Report( msg, REPORTER::RPT_ERROR );
642  error++;
643  continue;
644  }
645 
646  /* Test error if units are different but number of parts per package
647  * too high (ex U3 ( 1 part) and we find U3B this is an error) */
648  if( componentFlatList[ii].GetLibPart()->GetUnitCount()
649  != componentFlatList[ii + 1].GetLibPart()->GetUnitCount() )
650  {
651  if( componentFlatList[ii].m_NumRef >= 0 )
652  tmp << componentFlatList[ii].m_NumRef;
653  else
654  tmp = wxT( "?" );
655 
656  if( ( componentFlatList[ii].m_Unit > 0 )
657  && ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) )
658  {
659  msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
660  GetChars( componentFlatList[ii].GetRef() ),
661  GetChars( tmp ),
662  componentFlatList[ii].m_Unit );
663  }
664  else
665  {
666  msg.Printf( _( "Multiple item %s%s\n" ),
667  GetChars( componentFlatList[ii].GetRef() ),
668  GetChars( tmp ) );
669  }
670 
671  aReporter.Report( msg, REPORTER::RPT_ERROR );
672  error++;
673  }
674 
675  // Error if values are different between units, for the same reference
676  int next = ii + 1;
677 
678  if( componentFlatList[ii].CompareValue( componentFlatList[next] ) != 0 )
679  {
680  msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ),
681  componentFlatList[ii].GetRef(),
682  componentFlatList[ii].m_NumRef,
684  componentFlatList[ii].m_Value->GetText(),
685  componentFlatList[next].GetRef(),
686  componentFlatList[next].m_NumRef,
688  componentFlatList[next].m_Value->GetText() );
689 
690  aReporter.Report( msg, REPORTER::RPT_ERROR );
691  error++;
692  }
693  }
694 
695  // count the duplicated time stamps
696  SortByTimeStamp();
697 
698  for( int ii = 0; ii < imax; ii++ )
699  {
700  if( ( componentFlatList[ii].m_TimeStamp != componentFlatList[ii + 1].m_TimeStamp )
701  || ( componentFlatList[ii].GetSheetPath() != componentFlatList[ii + 1].GetSheetPath() ) )
702  continue;
703 
704  // Same time stamp found.
705  wxString full_path;
706 
707  full_path.Printf( wxT( "%s%8.8X" ),
708  GetChars( componentFlatList[ii].GetSheetPath().Path() ),
709  componentFlatList[ii].m_TimeStamp );
710 
711  msg.Printf( _( "Duplicate time stamp (%s) for %s%d and %s%d" ),
712  full_path,
713  componentFlatList[ii].GetRef(),
714  componentFlatList[ii].m_NumRef,
715  componentFlatList[ii + 1].GetRef(),
716  componentFlatList[ii + 1].m_NumRef );
717 
718  aReporter.Report( msg, REPORTER::RPT_WARNING );
719  error++;
720  }
721 
722  return error;
723 }
CITER next(CITER it)
Definition: ptree.cpp:130
std::vector< SCH_REFERENCE > componentFlatList
void SortByRefAndValue()
Function SortByRefAndValue sorts the list of references by value.
void SortByTimeStamp()
Function SortComponentsByTimeStamp sort the flat list by Time Stamp.
#define _(s)
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:101
#define max(a, b)
Definition: auxiliary.h:86
void SplitReferences()
Function SplitReferences attempts to split all reference designators into a name (U) and number (1).
static wxString SubReference(int aUnit, bool aAddSeparator=true)
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.

References _, componentFlatList, GetChars(), max, next(), REPORTER::Report(), REPORTER::RPT_ERROR, REPORTER::RPT_WARNING, SortByRefAndValue(), SortByTimeStamp(), SplitReferences(), and LIB_PART::SubReference().

Referenced by SCH_EDIT_FRAME::CheckAnnotate().

◆ CreateFirstFreeRefId()

int SCH_REFERENCE_LIST::CreateFirstFreeRefId ( std::vector< int > &  aIdList,
int  aFirstValue 
)
private

Function CreateFirstFreeRefId searches for the first free reference number in aListId of reference numbers in use.

This function just searches for a hole in a list of incremented numbers, this list must be sorted by increasing values and each value can be stored only once. The new value is added to the list.

See also
BuildRefIdInUseList to prepare this list
Parameters
aIdListThe buffer that contains the reference numbers in use.
aFirstValueThe first expected free value
Returns
The first free (not yet used) value.

Definition at line 241 of file component_references_lister.cpp.

242 {
243  int expectedId = aFirstValue;
244 
245  // We search for expected Id a value >= aFirstValue.
246  // Skip existing Id < aFirstValue
247  unsigned ii = 0;
248 
249  for( ; ii < aIdList.size(); ii++ )
250  {
251  if( expectedId <= aIdList[ii] )
252  break;
253  }
254 
255  // Ids are sorted by increasing value, from aFirstValue
256  // So we search from aFirstValue the first not used value, i.e. the first hole in list.
257  for( ; ii < aIdList.size(); ii++ )
258  {
259  if( expectedId != aIdList[ii] ) // This id is not yet used.
260  {
261  // Insert this free Id, in order to keep list sorted
262  aIdList.insert( aIdList.begin() + ii, expectedId );
263  return expectedId;
264  }
265 
266  expectedId++;
267  }
268 
269  // All existing Id are tested, and all values are found in use.
270  // So Create a new one.
271  aIdList.push_back( expectedId );
272  return expectedId;
273 }

Referenced by Annotate().

◆ FindUnit()

int SCH_REFERENCE_LIST::FindUnit ( size_t  aIndex,
int  aUnit 
)

searches the sorted list of components for a another component with the same reference and a given part unit.

Use this method to manage components with multiple parts per package.

Parameters
aIndex= index in aComponentsList for of given SCH_REFERENCE item to test.
aUnit= the given unit number to search
Returns
index in aComponentsList if found or -1 if not found

Definition at line 144 of file component_references_lister.cpp.

145 {
146  int NumRef;
147 
148  NumRef = componentFlatList[aIndex].m_NumRef;
149 
150  for( size_t ii = 0; ii < componentFlatList.size(); ii++ )
151  {
152  if( ( aIndex == ii )
153  || ( componentFlatList[ii].m_IsNew )
154  || ( componentFlatList[ii].m_NumRef != NumRef )
155  || ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) != 0 ) )
156  continue;
157 
158  if( componentFlatList[ii].m_Unit == aUnit )
159  return (int) ii;
160  }
161 
162  return -1;
163 }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

Referenced by Annotate().

◆ GetCount()

◆ GetItem()

SCH_REFERENCE& SCH_REFERENCE_LIST::GetItem ( int  aIdx)
inline

Function GetItem.

Returns
the aIdx item

Definition at line 229 of file sch_reference_list.h.

230  {
231  return componentFlatList[aIdx];
232  }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

◆ GetLastReference()

int SCH_REFERENCE_LIST::GetLastReference ( int  aIndex,
int  aMinValue 
)

Function GetLastReference returns the last used (greatest) reference number in the reference list for the prefix reference given by aIndex.

The component list must be sorted.

Parameters
aIndexThe index of the reference item used for the search pattern.
aMinValueThe minimum value for the current search.

Definition at line 222 of file component_references_lister.cpp.

223 {
224  int lastNumber = aMinValue;
225 
226  for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
227  {
228  // search only for the current reference prefix:
229  if( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) != 0 )
230  continue;
231 
232  // update max value for the current reference prefix
233  if( lastNumber < componentFlatList[ii].m_NumRef )
234  lastNumber = componentFlatList[ii].m_NumRef;
235  }
236 
237  return lastNumber;
238 }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

Referenced by Annotate().

◆ GetRefsInUse()

void SCH_REFERENCE_LIST::GetRefsInUse ( int  aIndex,
std::vector< int > &  aIdList,
int  aMinRefId 
)

Function GetRefsInUse adds all the reference designator numbers greater than aMinRefId to aIdList skipping the reference at aIndex.

Parameters
aIndex= the current component index to use for reference prefix filtering.
aIdList= the buffer to fill
aMinRefId= the min id value to store. all values < aMinRefId are ignored

Definition at line 199 of file component_references_lister.cpp.

200 {
201  aIdList.clear();
202 
203  for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
204  {
205  if( ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) == 0 )
206  && ( componentFlatList[ii].m_NumRef >= aMinRefId ) )
207  aIdList.push_back( componentFlatList[ii].m_NumRef );
208  }
209 
210  sort( aIdList.begin(), aIdList.end() );
211 
212  // Ensure each reference number appears only once. If there are components with
213  // multiple parts per package the same number will be stored for each part.
214  std::vector< int >::iterator it = unique( aIdList.begin(), aIdList.end() );
215 
216  // Using the C++ unique algorithm only moves the duplicate entries to the end of
217  // of the array. This removes the duplicate entries from the array.
218  aIdList.resize( it - aIdList.begin() );
219 }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

Referenced by Annotate().

◆ operator[]()

SCH_REFERENCE& SCH_REFERENCE_LIST::operator[] ( int  aIndex)
inline

Definition at line 211 of file sch_reference_list.h.

212  {
213  return componentFlatList[ aIndex ];
214  }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

◆ RemoveItem()

void SCH_REFERENCE_LIST::RemoveItem ( unsigned int  aIndex)

Function RemoveItem removes an item from the list of references.

Parameters
aIndexis the index of the item to be removed.

Definition at line 49 of file component_references_lister.cpp.

50 {
51  if( aIndex < componentFlatList.size() )
52  componentFlatList.erase( componentFlatList.begin() + aIndex );
53 }
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList.

◆ RemoveSubComponentsFromList()

void SCH_REFERENCE_LIST::RemoveSubComponentsFromList ( )

Function RemoveSubComponentsFromList Remove sub components from the list, when multiples parts per package are found in this list.

Useful to create BOM, when a component must appear only once

Definition at line 166 of file component_references_lister.cpp.

167 {
168  SCH_COMPONENT* libItem;
169  wxString oldName;
170  wxString currName;
171 
172  // The component list **MUST** be sorted by reference and by unit number
173  // in order to find all parts of a component
175 
176  for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
177  {
178 
179  libItem = componentFlatList[ii].m_RootCmp;
180  if( libItem == NULL )
181  continue;
182 
183  currName = componentFlatList[ii].GetRef();
184 
185  if( !oldName.IsEmpty() )
186  {
187  if( oldName == currName ) // currName is a subpart of oldName: remove it
188  {
189  componentFlatList.erase( componentFlatList.begin() + ii );
190  ii--;
191  }
192  }
193 
194  oldName = currName;
195  }
196 }
std::vector< SCH_REFERENCE > componentFlatList
void SortByReferenceOnly()
Function SortByReferenceOnly sorts the list of references by reference.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:73

References componentFlatList, and SortByReferenceOnly().

◆ Shorthand()

wxString SCH_REFERENCE_LIST::Shorthand ( std::vector< SCH_REFERENCE aList)
static

Function Shorthand Returns a shorthand string representing all the references in the list.

For instance, "R1, R2, R4 - R7, U1"

Parameters
aList

Definition at line 824 of file component_references_lister.cpp.

825 {
826  wxString retVal;
827  size_t i = 0;
828 
829  while( i < aList.size() )
830  {
831  wxString ref = aList[ i ].GetRef();
832  int numRef = aList[ i ].m_NumRef;
833 
834  size_t range = 1;
835 
836  while( i + range < aList.size()
837  && aList[ i + range ].GetRef() == ref
838  && aList[ i + range ].m_NumRef == int( numRef + range ) )
839  {
840  range++;
841  }
842 
843  if( !retVal.IsEmpty() )
844  retVal << wxT( ", " );
845 
846  if( range == 1 )
847  {
848  retVal << ref << aList[ i ].GetRefNumber();
849  }
850  else if( range == 2 )
851  {
852  retVal << ref << aList[ i ].GetRefNumber();
853  retVal << wxT( ", " );
854  retVal << ref << aList[ i + 1 ].GetRefNumber();
855  }
856  else
857  {
858  retVal << ref << aList[ i ].GetRefNumber();
859  retVal << wxT( "-" );
860  retVal << ref << aList[ i + ( range - 1 ) ].GetRefNumber();
861  }
862 
863  i+= range;
864  }
865 
866  return retVal;
867 }
size_t i
Definition: json11.cpp:649

References i.

Referenced by FIELDS_EDITOR_GRID_DATA_MODEL::GetValue().

◆ SortByRefAndValue()

void SCH_REFERENCE_LIST::SortByRefAndValue ( )
inline

Function SortByRefAndValue sorts the list of references by value.

Components are sorted in the following order:

  • Numeric value of reference designator.
  • Value of component.
  • Unit number when component has multiple parts.
  • Sheet number.
  • X coordinate position.
  • Y coordinate position.

Definition at line 400 of file sch_reference_list.h.

401  {
402  sort( componentFlatList.begin(), componentFlatList.end(), sortByRefAndValue );
403  }
std::vector< SCH_REFERENCE > componentFlatList
static bool sortByRefAndValue(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)

References componentFlatList, and sortByRefAndValue().

Referenced by CheckAnnotation().

◆ sortByRefAndValue()

bool SCH_REFERENCE_LIST::sortByRefAndValue ( const SCH_REFERENCE item1,
const SCH_REFERENCE item2 
)
staticprivate

Definition at line 91 of file component_references_lister.cpp.

93 {
94  int ii = item1.CompareRef( item2 );
95  if( ii == 0 )
96  ii = item1.CompareValue( item2 );
97  if( ii == 0 )
98  ii = item1.m_Unit - item2.m_Unit;
99  if( ii == 0 )
100  ii = item1.m_SheetNum - item2.m_SheetNum;
101  if( ii == 0 )
102  ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
103  if( ii == 0 )
104  ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
105  if( ii == 0 )
106  ii = item1.m_TimeStamp - item2.m_TimeStamp;
107 
108  return ii < 0;
109 }
wxPoint m_CmpPos
The physical position of the component in schematic used to annotate by X or Y position.
int m_SheetNum
The sheet number for the reference.
int m_Unit
The unit number for components with multiple parts per package.
int CompareValue(const SCH_REFERENCE &item) const
timestamp_t m_TimeStamp
The time stamp for the reference.
int CompareRef(const SCH_REFERENCE &item) const

References SCH_REFERENCE::CompareRef(), SCH_REFERENCE::CompareValue(), SCH_REFERENCE::m_CmpPos, SCH_REFERENCE::m_SheetNum, SCH_REFERENCE::m_TimeStamp, and SCH_REFERENCE::m_Unit.

Referenced by SortByRefAndValue().

◆ SortByReferenceOnly()

void SCH_REFERENCE_LIST::SortByReferenceOnly ( )
inline

Function SortByReferenceOnly sorts the list of references by reference.

Components are sorted in the following order:

  • Numeric value of reference designator.
  • Unit number when component has multiple parts.

Definition at line 416 of file sch_reference_list.h.

417  {
419  }
std::vector< SCH_REFERENCE > componentFlatList
static bool sortByReferenceOnly(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)

References componentFlatList, and sortByReferenceOnly().

Referenced by RemoveSubComponentsFromList().

◆ sortByReferenceOnly()

bool SCH_REFERENCE_LIST::sortByReferenceOnly ( const SCH_REFERENCE item1,
const SCH_REFERENCE item2 
)
staticprivate

Definition at line 112 of file component_references_lister.cpp.

114 {
115  int ii;
116 
117  ii = UTIL::RefDesStringCompare( item1.GetRef(), item2.GetRef() );
118 
119  if( ii == 0 )
120  {
121  ii = item1.m_RootCmp->GetField( VALUE )->GetText().CmpNoCase( item2.m_RootCmp->GetField( VALUE )->GetText() );
122  }
123 
124  if( ii == 0 )
125  {
126  ii = item1.m_Unit - item2.m_Unit;
127  }
128 
129  return ii < 0;
130 }
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
int m_Unit
The unit number for components with multiple parts per package.
int RefDesStringCompare(const wxString &aFirst, const wxString &aSecond)
Acts just like the strcmp function but treats numbers within the string text correctly for sorting.
wxString GetRef() const
#define VALUE
SCH_COMPONENT * m_RootCmp
The component associated the reference object.
virtual const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:124

References SCH_COMPONENT::GetField(), SCH_REFERENCE::GetRef(), EDA_TEXT::GetText(), SCH_REFERENCE::m_RootCmp, SCH_REFERENCE::m_Unit, UTIL::RefDesStringCompare(), and VALUE.

Referenced by SortByReferenceOnly().

◆ SortByTimeStamp()

void SCH_REFERENCE_LIST::SortByTimeStamp ( )
inline

Function SortComponentsByTimeStamp sort the flat list by Time Stamp.

Useful to detect duplicate Time Stamps

Definition at line 380 of file sch_reference_list.h.

381  {
382  sort( componentFlatList.begin(), componentFlatList.end(), sortByTimeStamp );
383  }
static bool sortByTimeStamp(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
std::vector< SCH_REFERENCE > componentFlatList

References componentFlatList, and sortByTimeStamp().

Referenced by CheckAnnotation().

◆ sortByTimeStamp()

bool SCH_REFERENCE_LIST::sortByTimeStamp ( const SCH_REFERENCE item1,
const SCH_REFERENCE item2 
)
staticprivate

Definition at line 133 of file component_references_lister.cpp.

135 {
136  int ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
137 
138  if( ii == 0 )
139  ii = item1.m_TimeStamp - item2.m_TimeStamp;
140 
141  return ii < 0;
142 }
timestamp_t m_TimeStamp
The time stamp for the reference.
SCH_SHEET_PATH m_SheetPath
The sheet path for this reference.
int Cmp(const SCH_SHEET_PATH &aSheetPathToTest) const
Function Cmp Compare if this is the same sheet path as aSheetPathToTest.

References SCH_SHEET_PATH::Cmp(), SCH_REFERENCE::m_SheetPath, and SCH_REFERENCE::m_TimeStamp.

Referenced by SortByTimeStamp().

◆ SortByXCoordinate()

void SCH_REFERENCE_LIST::SortByXCoordinate ( )
inline

Function sortByXCoordinate sorts the list of references by X position.

Components are sorted as follows:

  • Numeric value of reference designator.
  • Sheet number.
  • X coordinate position.
  • Y coordinate position.
  • Time stamp.

Definition at line 351 of file sch_reference_list.h.

352  {
353  sort( componentFlatList.begin(), componentFlatList.end(), sortByXPosition );
354  }
std::vector< SCH_REFERENCE > componentFlatList
static bool sortByXPosition(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)

References componentFlatList, and sortByXPosition().

Referenced by SCH_EDIT_FRAME::AnnotateComponents().

◆ sortByXPosition()

bool SCH_REFERENCE_LIST::sortByXPosition ( const SCH_REFERENCE item1,
const SCH_REFERENCE item2 
)
staticprivate

Definition at line 56 of file component_references_lister.cpp.

58 {
59  int ii = item1.CompareRef( item2 );
60 
61  if( ii == 0 )
62  ii = item1.m_SheetNum - item2.m_SheetNum;
63  if( ii == 0 )
64  ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
65  if( ii == 0 )
66  ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
67  if( ii == 0 )
68  ii = item1.m_TimeStamp - item2.m_TimeStamp;
69 
70  return ii < 0;
71 }
wxPoint m_CmpPos
The physical position of the component in schematic used to annotate by X or Y position.
int m_SheetNum
The sheet number for the reference.
timestamp_t m_TimeStamp
The time stamp for the reference.
int CompareRef(const SCH_REFERENCE &item) const

References SCH_REFERENCE::CompareRef(), SCH_REFERENCE::m_CmpPos, SCH_REFERENCE::m_SheetNum, and SCH_REFERENCE::m_TimeStamp.

Referenced by SortByXCoordinate().

◆ SortByYCoordinate()

void SCH_REFERENCE_LIST::SortByYCoordinate ( )
inline

Function sortByYCoordinate sorts the list of references by Y position.

Components are sorted as follows:

  • Numeric value of reference designator.
  • Sheet number.
  • Y coordinate position.
  • X coordinate position.
  • Time stamp.

Definition at line 370 of file sch_reference_list.h.

371  {
372  sort( componentFlatList.begin(), componentFlatList.end(), sortByYPosition );
373  }
std::vector< SCH_REFERENCE > componentFlatList
static bool sortByYPosition(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)

References componentFlatList, and sortByYPosition().

Referenced by SCH_EDIT_FRAME::AnnotateComponents().

◆ sortByYPosition()

bool SCH_REFERENCE_LIST::sortByYPosition ( const SCH_REFERENCE item1,
const SCH_REFERENCE item2 
)
staticprivate

Definition at line 73 of file component_references_lister.cpp.

75 {
76  int ii = item1.CompareRef( item2 );
77 
78  if( ii == 0 )
79  ii = item1.m_SheetNum - item2.m_SheetNum;
80  if( ii == 0 )
81  ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
82  if( ii == 0 )
83  ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
84  if( ii == 0 )
85  ii = item1.m_TimeStamp - item2.m_TimeStamp;
86 
87  return ii < 0;
88 }
wxPoint m_CmpPos
The physical position of the component in schematic used to annotate by X or Y position.
int m_SheetNum
The sheet number for the reference.
timestamp_t m_TimeStamp
The time stamp for the reference.
int CompareRef(const SCH_REFERENCE &item) const

References SCH_REFERENCE::CompareRef(), SCH_REFERENCE::m_CmpPos, SCH_REFERENCE::m_SheetNum, and SCH_REFERENCE::m_TimeStamp.

Referenced by SortByYCoordinate().

◆ SplitReferences()

void SCH_REFERENCE_LIST::SplitReferences ( )
inline

Function SplitReferences attempts to split all reference designators into a name (U) and number (1).

If the last character is '?' or not a digit, the reference is tagged as not annotated. For components with multiple parts per package that are not already annotated, set m_Unit to a max value (0x7FFFFFFF).

See also
SCH_REFERENCE::Split()

Definition at line 278 of file sch_reference_list.h.

279  {
280  for( unsigned ii = 0; ii < GetCount(); ii++ )
281  componentFlatList[ii].Split();
282  }
std::vector< SCH_REFERENCE > componentFlatList
unsigned GetCount()
Function GetCount.

References componentFlatList, and GetCount().

Referenced by SCH_EDIT_FRAME::AnnotateComponents(), SCH_SHEET_LIST::AnnotatePowerSymbols(), CheckAnnotation(), and FIELDS_EDITOR_GRID_DATA_MODEL::FIELDS_EDITOR_GRID_DATA_MODEL().

◆ UpdateAnnotation()

void SCH_REFERENCE_LIST::UpdateAnnotation ( )
inline

function UpdateAnnotation Updates the reference components for the schematic project (or the current sheet) Note: this function does not calculate the reference numbers stored in m_NumRef So, it must be called after calculation of new reference numbers

See also
SCH_REFERENCE::Annotate()

Definition at line 291 of file sch_reference_list.h.

292  {
293  /* update the reference numbers */
294  for( unsigned ii = 0; ii < GetCount(); ii++ )
295  {
296  componentFlatList[ii].Annotate();
297  }
298  }
std::vector< SCH_REFERENCE > componentFlatList
unsigned GetCount()
Function GetCount.

References componentFlatList, and GetCount().

Referenced by SCH_EDIT_FRAME::AnnotateComponents(), and SCH_SHEET_LIST::AnnotatePowerSymbols().

Member Data Documentation

◆ componentFlatList


The documentation for this class was generated from the following files: