KiCad PCB EDA Suite
SCH_REFERENCE_LIST Class Reference

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

#include <sch_reference_list.h>

Public Member Functions

 SCH_REFERENCE_LIST ()
 
SCH_REFERENCEoperator[] (int aIndex)
 
const SCH_REFERENCEoperator[] (int aIndex) const
 
void Clear ()
 
size_t GetCount () const
 
SCH_REFERENCEGetItem (int aIdx)
 
const SCH_REFERENCEGetItem (int aIdx) const
 
void AddItem (const SCH_REFERENCE &aItem)
 
void RemoveItem (unsigned int aIndex)
 Remove an item from the list of references. More...
 
bool Contains (const SCH_REFERENCE &aItem)
 Return true if aItem exists in this list. More...
 
void SplitReferences ()
 Attempt to split all reference designators into a name (U) and number (1). More...
 
void UpdateAnnotation ()
 Update the symbol references for the schematic project (or the current sheet). More...
 
void ReannotateDuplicates (const SCH_REFERENCE_LIST &aAdditionalReferences)
 Replace any duplicate reference designators with the next available number after the present number. More...
 
void Annotate (bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap, const SCH_REFERENCE_LIST &aAdditionalRefs, bool aStartAtCurrent=false)
 Set the reference designators in the list that have not been annotated. More...
 
int CheckAnnotation (ANNOTATION_ERROR_HANDLER aErrorHandler)
 Check for annotations errors. More...
 
void SortByXCoordinate ()
 Sort the list of references by X position. More...
 
void SortByYCoordinate ()
 Sort the list of references by Y position. More...
 
void SortByTimeStamp ()
 Sort the flat list by Time Stamp (sheet path + timestamp). More...
 
void SortByRefAndValue ()
 Sort the list of references by value. More...
 
void SortByReferenceOnly ()
 Sort the list of references by reference. More...
 
int FindRef (const wxString &aPath) const
 Search the list for a symbol with a given reference. More...
 
int FindUnit (size_t aIndex, int aUnit) const
 Search the sorted list of symbols for a another symbol with the same reference and a given part unit. More...
 
int FindRefByPath (const wxString &aPath) const
 Search the list for a symbol with the given KIID path. More...
 
void GetRefsInUse (int aIndex, std::vector< int > &aIdList, int aMinRefId) const
 Add all the reference designator numbers greater than aMinRefId to aIdList skipping the reference at aIndex. More...
 
int GetLastReference (int aIndex, int aMinValue) const
 Return the last used (greatest) reference number in the reference list for the prefix used by the symbol pointed to by aIndex. More...
 
std::vector< SYMBOL_INSTANCE_REFERENCEGetSymbolInstances () const
 

Static Public Member Functions

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

Private Member Functions

int CreateFirstFreeRefId (std::vector< int > &aIdList, int aFirstValue)
 Search 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_REFERENCEflatList
 

Friends

class BACK_ANNOTATION
 
class BACK_ANNOTATE
 

Detailed Description

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

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

Definition at line 203 of file sch_reference_list.h.

Constructor & Destructor Documentation

◆ SCH_REFERENCE_LIST()

SCH_REFERENCE_LIST::SCH_REFERENCE_LIST ( )
inline

Definition at line 210 of file sch_reference_list.h.

211  {
212  }

Member Function Documentation

◆ AddItem()

void SCH_REFERENCE_LIST::AddItem ( const SCH_REFERENCE aItem)
inline

◆ Annotate()

void SCH_REFERENCE_LIST::Annotate ( bool  aUseSheetNum,
int  aSheetIntervalId,
int  aStartNumber,
SCH_MULTI_UNIT_REFERENCE_MAP  aLockedUnitMap,
const SCH_REFERENCE_LIST aAdditionalRefs,
bool  aStartAtCurrent = false 
)

Set the reference designators in the list that have not been annotated.

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

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.
aAdditionalRefsAdditional references to use for checking that there a reference designator doesn't already exist. The caller must ensure that none of the references in aAdditionalRefs exist in this list.
aStartAtCurrentUse m_numRef for each reference as the start number (overrides aStartNumber)

Definition at line 336 of file component_references_lister.cpp.

339 {
340  if ( flatList.size() == 0 )
341  return;
342 
343  size_t originalSize = GetCount();
344 
345  // For multi units components, store the list of already used full references.
346  // The algorithm tries to allocate the new reference to components having the same
347  // old reference.
348  // This algo works fine as long as the previous annotation has no duplicates.
349  // But when a hierarchy is reannotated with this option, the previous anotation can
350  // have duplicate references, and obviously we must fix these duplicate.
351  // therefore do not try to allocate a full reference more than once when trying
352  // to keep this order of multi units.
353  // inUseRefs keep trace of previously allocated references
354  std::unordered_set<wxString> inUseRefs;
355 
356  for( size_t i = 0; i < aAdditionalRefs.GetCount(); i++ )
357  {
358  SCH_REFERENCE additionalRef = aAdditionalRefs[i];
359  additionalRef.Split();
360 
361  // Add the additional reference to the multi-unit set if annotated
362  if( !additionalRef.m_isNew )
363  inUseRefs.insert( buildFullReference( additionalRef ) );
364 
365  // We don't want to reannotate the additional references even if not annotated
366  // so we change the m_isNew flag to be false after splitting
367  additionalRef.m_isNew = false;
368  AddItem( additionalRef ); //add to this container
369  }
370 
371  int LastReferenceNumber = 0;
372  int NumberOfUnits, Unit;
373 
374  /* calculate index of the first component with the same reference prefix
375  * than the current component. All components having the same reference
376  * prefix will receive a reference number with consecutive values:
377  * IC .. will be set to IC4, IC4, IC5 ...
378  */
379  unsigned first = 0;
380 
381  // calculate the last used number for this reference prefix:
382  int minRefId;
383 
384  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
385  if( aUseSheetNum )
386  minRefId = flatList[first].m_sheetNum * aSheetIntervalId + 1;
387  else
388  minRefId = aStartNumber + 1;
389 
390  // This is the list of all Id already in use for a given reference prefix.
391  // Will be refilled for each new reference prefix.
392  std::vector<int>idList;
393  GetRefsInUse( first, idList, minRefId );
394 
395  for( unsigned ii = 0; ii < flatList.size(); ii++ )
396  {
397  auto& ref_unit = flatList[ii];
398 
399  if( ref_unit.m_flag )
400  continue;
401 
402  // Check whether this component is in aLockedUnitMap.
403  SCH_REFERENCE_LIST* lockedList = NULL;
404  for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : aLockedUnitMap )
405  {
406  unsigned n_refs = pair.second.GetCount();
407 
408  for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
409  {
410  SCH_REFERENCE &thisRef = pair.second[thisRefI];
411 
412  if( thisRef.IsSameInstance( ref_unit ) )
413  {
414  lockedList = &pair.second;
415  break;
416  }
417  }
418  if( lockedList != NULL ) break;
419  }
420 
421  if( ( flatList[first].CompareRef( ref_unit ) != 0 )
422  || ( aUseSheetNum && ( flatList[first].m_sheetNum != ref_unit.m_sheetNum ) ) )
423  {
424  // New reference found: we need a new ref number for this reference
425  first = ii;
426 
427  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
428  if( aUseSheetNum )
429  minRefId = ref_unit.m_sheetNum * aSheetIntervalId + 1;
430  else
431  minRefId = aStartNumber + 1;
432 
433  GetRefsInUse( first, idList, minRefId );
434  }
435 
436  // Find references greater than current reference (unless not annotated)
437  if( aStartAtCurrent && ref_unit.m_numRef > 0 )
438  {
439  minRefId = ref_unit.m_numRef;
440  GetRefsInUse( first, idList, minRefId );
441  }
442 
443  // Annotation of one part per package components (trivial case).
444  if( ref_unit.GetLibPart()->GetUnitCount() <= 1 )
445  {
446  if( ref_unit.m_isNew )
447  {
448  LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
449  ref_unit.m_numRef = LastReferenceNumber;
450  }
451 
452  ref_unit.m_flag = 1;
453  ref_unit.m_isNew = false;
454  continue;
455  }
456 
457  // Annotation of multi-unit parts ( n units per part ) (complex case)
458  NumberOfUnits = ref_unit.GetLibPart()->GetUnitCount();
459 
460  if( ref_unit.m_isNew )
461  {
462  LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
463  ref_unit.m_numRef = LastReferenceNumber;
464 
465  ref_unit.m_flag = 1;
466  }
467 
468  // If this component is in aLockedUnitMap, copy the annotation to all
469  // components that are not it
470  if( lockedList != NULL )
471  {
472  unsigned n_refs = lockedList->GetCount();
473 
474  for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
475  {
476  SCH_REFERENCE &thisRef = (*lockedList)[thisRefI];
477 
478  if( thisRef.IsSameInstance( ref_unit ) )
479  {
480  // This is the component we're currently annotating. Hold the unit!
481  ref_unit.m_unit = thisRef.m_unit;
482  // lock this new full reference
483  inUseRefs.insert( buildFullReference( ref_unit ) );
484  }
485 
486  if( thisRef.CompareValue( ref_unit ) != 0 )
487  continue;
488 
489  if( thisRef.CompareLibName( ref_unit ) != 0 )
490  continue;
491 
492  // Find the matching component
493  for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
494  {
495  if( ! thisRef.IsSameInstance( flatList[jj] ) )
496  continue;
497 
498  wxString ref_candidate = buildFullReference( ref_unit, thisRef.m_unit );
499 
500  // propagate the new reference and unit selection to the "old" component,
501  // if this new full reference is not already used (can happens when initial
502  // multiunits components have duplicate references)
503  if( inUseRefs.find( ref_candidate ) == inUseRefs.end() )
504  {
505  flatList[jj].m_numRef = ref_unit.m_numRef;
506  flatList[jj].m_isNew = false;
507  flatList[jj].m_flag = 1;
508  // lock this new full reference
509  inUseRefs.insert( ref_candidate );
510  break;
511  }
512  }
513  }
514  }
515  else
516  {
517  /* search for others units of this component.
518  * we search for others parts that have the same value and the same
519  * reference prefix (ref without ref number)
520  */
521  for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
522  {
523  if( ref_unit.m_unit == Unit )
524  continue;
525 
526  int found = FindUnit( ii, Unit );
527 
528  if( found >= 0 )
529  continue; // this unit exists for this reference (unit already annotated)
530 
531  // Search a component to annotate ( same prefix, same value, not annotated)
532  for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
533  {
534  auto& cmp_unit = flatList[jj];
535 
536  if( cmp_unit.m_flag ) // already tested
537  continue;
538 
539  if( cmp_unit.CompareRef( ref_unit ) != 0 )
540  continue;
541 
542  if( cmp_unit.CompareValue( ref_unit ) != 0 )
543  continue;
544 
545  if( cmp_unit.CompareLibName( ref_unit ) != 0 )
546  continue;
547 
548  if( aUseSheetNum &&
549  cmp_unit.GetSheetPath().Cmp( ref_unit.GetSheetPath() ) != 0 )
550  continue;
551 
552  if( !cmp_unit.m_isNew )
553  continue;
554 
555  // Component without reference number found, annotate it if possible
556  if( cmp_unit.m_unit == Unit )
557  {
558  cmp_unit.m_numRef = ref_unit.m_numRef;
559  cmp_unit.m_flag = 1;
560  cmp_unit.m_isNew = false;
561  break;
562  }
563  }
564  }
565  }
566  }
567 
568  // Remove aAdditionalRefs references
569  for( size_t i = originalSize; i < ( aAdditionalRefs.GetCount() + originalSize ); i++ )
570  RemoveItem( originalSize );
571 
572  wxASSERT( originalSize == GetCount() ); // Make sure we didn't make a mistake
573 }
void RemoveItem(unsigned int aIndex)
Remove an item from the list of references.
void Split()
Attempt to split the reference designator into a name (U) and number (1).
void AddItem(const SCH_REFERENCE &aItem)
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
int FindUnit(size_t aIndex, int aUnit) const
Search the sorted list of symbols for a another symbol with the same reference and a given part unit.
int m_unit
The unit number for symbol with multiple parts per package.
#define NULL
void GetRefsInUse(int aIndex, std::vector< int > &aIdList, int aMinRefId) const
Add all the reference designator numbers greater than aMinRefId to aIdList skipping the reference at ...
int CompareValue(const SCH_REFERENCE &item) const
wxString buildFullReference(const SCH_REFERENCE &aItem, int aUnitNumber=-1)
int CompareLibName(const SCH_REFERENCE &item) const
bool m_isNew
True if not yet annotated.
size_t GetCount() const
bool IsSameInstance(const SCH_REFERENCE &other) const
Return whether this reference refers to the same symbol instance (symbol and sheet) as another.
int CreateFirstFreeRefId(std::vector< int > &aIdList, int aFirstValue)
Search for the first free reference number in aListId of reference numbers in use.
std::vector< SCH_REFERENCE > flatList
A helper to define a symbol's reference designator in a schematic.

References AddItem(), buildFullReference(), SCH_REFERENCE::CompareLibName(), SCH_REFERENCE::CompareValue(), CreateFirstFreeRefId(), FindUnit(), flatList, GetCount(), GetRefsInUse(), SCH_REFERENCE::IsSameInstance(), SCH_REFERENCE::m_isNew, SCH_REFERENCE::m_unit, NULL, RemoveItem(), and SCH_REFERENCE::Split().

Referenced by SCH_SHEET_LIST::AnnotatePowerSymbols(), SCH_EDIT_FRAME::AnnotateSymbols(), ReannotateDuplicates(), and UpdateAnnotation().

◆ CheckAnnotation()

int SCH_REFERENCE_LIST::CheckAnnotation ( ANNOTATION_ERROR_HANDLER  aErrorHandler)

Check for annotations errors.

The following annotation error conditions are tested:

  • Symbols not annotated.
  • Symbols having the same reference designator (duplicates).
  • Symbols with multiple parts per package having different reference designators.
  • Symbols with multiple parts per package with invalid part count.
Parameters
aErrorHandlerA handler for errors.
Returns
The number of errors found.

Definition at line 575 of file component_references_lister.cpp.

576 {
577  int error = 0;
578  wxString tmp;
579  wxString msg;
580 
582 
583  // Spiit reference designators into name (prefix) and number: IC1 becomes IC, and 1.
584  SplitReferences();
585 
586  // count not yet annotated items or annotation error.
587  for( unsigned ii = 0; ii < flatList.size(); ii++ )
588  {
589  msg.Empty();
590  tmp.Empty();
591 
592  if( flatList[ii].m_isNew ) // Not yet annotated
593  {
594  if( flatList[ii].m_numRef >= 0 )
595  tmp << flatList[ii].m_numRef;
596  else
597  tmp = wxT( "?" );
598 
599 
600  if( ( flatList[ii].m_unit > 0 ) && ( flatList[ii].m_unit < 0x7FFFFFFF ) )
601  {
602  msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ),
603  flatList[ii].GetRef(),
604  tmp,
605  flatList[ii].m_unit );
606  }
607  else
608  {
609  msg.Printf( _( "Item not annotated: %s%s\n" ),
610  flatList[ii].GetRef(),
611  tmp );
612  }
613 
614  aHandler( ERCE_UNANNOTATED, msg, &flatList[ii], nullptr );
615  error++;
616  break;
617  }
618 
619  // Error if unit number selected does not exist (greater than the number of units in
620  // the component). This can happen if a component has changed in a library after a
621  // previous annotation.
622  if( std::max( flatList[ii].GetLibPart()->GetUnitCount(), 1 ) < flatList[ii].m_unit )
623  {
624  if( flatList[ii].m_numRef >= 0 )
625  tmp << flatList[ii].m_numRef;
626  else
627  tmp = wxT( "?" );
628 
629  msg.Printf( _( "Error: symbol %s%s%s (unit %d) exceeds units defined (%d)\n" ),
630  flatList[ii].GetRef(),
631  tmp,
632  LIB_PART::SubReference( flatList[ii].m_unit ),
633  flatList[ii].m_unit,
634  flatList[ii].GetLibPart()->GetUnitCount() );
635 
636  aHandler( ERCE_EXTRA_UNITS, msg, &flatList[ii], nullptr );
637  error++;
638  break;
639  }
640  }
641 
642  // count the duplicated elements (if all are annotated)
643  int imax = flatList.size() - 1;
644 
645  for( int ii = 0; ii < imax; ii++ )
646  {
647  msg.Empty();
648  tmp.Empty();
649 
650  if( ( flatList[ii].CompareRef( flatList[ii + 1] ) != 0 )
651  || ( flatList[ii].m_numRef != flatList[ ii + 1].m_numRef ) )
652  {
653  continue;
654  }
655 
656  // Same reference found. If same unit, error!
657  if( flatList[ii].m_unit == flatList[ ii + 1].m_unit )
658  {
659  if( flatList[ii].m_numRef >= 0 )
660  tmp << flatList[ii].m_numRef;
661  else
662  tmp = wxT( "?" );
663 
664  if( ( flatList[ii].m_unit > 0 ) && ( flatList[ii].m_unit < 0x7FFFFFFF ) )
665  {
666  msg.Printf( _( "Duplicate items %s%s%s\n" ),
667  flatList[ii].GetRef(),
668  tmp,
669  LIB_PART::SubReference( flatList[ii].m_unit ) );
670  }
671  else
672  {
673  msg.Printf( _( "Duplicate items %s%s\n" ),
674  flatList[ii].GetRef(),
675  tmp );
676  }
677 
678  aHandler( ERCE_DUPLICATE_REFERENCE, msg, &flatList[ii], &flatList[ii+1] );
679  error++;
680  continue;
681  }
682 
683  /* Test error if units are different but number of parts per package
684  * too high (ex U3 ( 1 part) and we find U3B this is an error) */
685  if( flatList[ii].GetLibPart()->GetUnitCount()
686  != flatList[ ii + 1].GetLibPart()->GetUnitCount() )
687  {
688  if( flatList[ii].m_numRef >= 0 )
689  tmp << flatList[ii].m_numRef;
690  else
691  tmp = wxT( "?" );
692 
693  if( ( flatList[ii].m_unit > 0 )
694  && ( flatList[ii].m_unit < 0x7FFFFFFF ) )
695  {
696  msg.Printf( _( "Duplicate items %s%s%s\n" ),
697  flatList[ii].GetRef(),
698  tmp,
699  LIB_PART::SubReference( flatList[ii].m_unit ) );
700  }
701  else
702  {
703  msg.Printf( _( "Duplicate items %s%s\n" ),
704  flatList[ii].GetRef(),
705  tmp );
706  }
707 
708  aHandler( ERCE_DUPLICATE_REFERENCE, msg, &flatList[ii], &flatList[ii+1] );
709  error++;
710  }
711 
712  // Error if values are different between units, for the same reference
713  int next = ii + 1;
714 
715  if( flatList[ii].CompareValue( flatList[next] ) != 0 )
716  {
717  msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ),
718  flatList[ii].GetRef(),
719  flatList[ii].m_numRef,
720  LIB_PART::SubReference( flatList[ii].m_unit ),
721  flatList[ii].m_value,
722  flatList[next].GetRef(),
723  flatList[next].m_numRef,
725  flatList[next].m_value );
726 
727  aHandler( ERCE_DIFFERENT_UNIT_VALUE, msg, &flatList[ii], &flatList[ii+1] );
728  error++;
729  }
730  }
731 
732  return error;
733 }
CITER next(CITER it)
Definition: ptree.cpp:126
Units of same symbol have different values.
Definition: erc_settings.h:70
void SortByRefAndValue()
Sort the list of references by value.
Symbol has not been annotated.
Definition: erc_settings.h:68
More than one symbol with the same reference.
Definition: erc_settings.h:71
void SplitReferences()
Attempt to split all reference designators into a name (U) and number (1).
#define _(s)
Definition: 3d_actions.cpp:33
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:447
std::vector< SCH_REFERENCE > flatList
Symbol has more units than are defined.
Definition: erc_settings.h:69

References _, ERCE_DIFFERENT_UNIT_VALUE, ERCE_DUPLICATE_REFERENCE, ERCE_EXTRA_UNITS, ERCE_UNANNOTATED, flatList, next(), SortByRefAndValue(), SplitReferences(), and LIB_PART::SubReference().

Referenced by SCH_EDIT_FRAME::CheckAnnotate().

◆ Clear()

void SCH_REFERENCE_LIST::Clear ( )
inline

Definition at line 224 of file sch_reference_list.h.

225  {
226  flatList.clear();
227  }
std::vector< SCH_REFERENCE > flatList

References flatList.

◆ Contains()

bool SCH_REFERENCE_LIST::Contains ( const SCH_REFERENCE aItem)

Return true if aItem exists in this list.

Parameters
aItemReference to check
Returns
true if aItem exists in this list

Definition at line 51 of file component_references_lister.cpp.

52 {
53  for( unsigned ii = 0; ii < GetCount(); ii++ )
54  {
55  if( flatList[ii].IsSameInstance( aItem ) )
56  return true;
57  }
58 
59  return false;
60 }
size_t GetCount() const
std::vector< SCH_REFERENCE > flatList

References flatList, and GetCount().

Referenced by SCH_EDIT_FRAME::AnnotateSymbols().

◆ CreateFirstFreeRefId()

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

Search 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 263 of file component_references_lister.cpp.

264 {
265  int expectedId = aFirstValue;
266 
267  // We search for expected Id a value >= aFirstValue.
268  // Skip existing Id < aFirstValue
269  unsigned ii = 0;
270 
271  for( ; ii < aIdList.size(); ii++ )
272  {
273  if( expectedId <= aIdList[ii] )
274  break;
275  }
276 
277  // Ids are sorted by increasing value, from aFirstValue
278  // So we search from aFirstValue the first not used value, i.e. the first hole in list.
279  for( ; ii < aIdList.size(); ii++ )
280  {
281  if( expectedId != aIdList[ii] ) // This id is not yet used.
282  {
283  // Insert this free Id, in order to keep list sorted
284  aIdList.insert( aIdList.begin() + ii, expectedId );
285  return expectedId;
286  }
287 
288  expectedId++;
289  }
290 
291  // All existing Id are tested, and all values are found in use.
292  // So Create a new one.
293  aIdList.push_back( expectedId );
294  return expectedId;
295 }

Referenced by Annotate().

◆ FindRef()

int SCH_REFERENCE_LIST::FindRef ( const wxString &  aPath) const

Search the list for a symbol with a given reference.

Definition at line 189 of file component_references_lister.cpp.

190 {
191  for( size_t i = 0; i < flatList.size(); ++i )
192  {
193  if( flatList[i].GetRef() == aRef )
194  return i;
195  }
196 
197  return -1;
198 }
std::vector< SCH_REFERENCE > flatList

References flatList.

Referenced by BACK_ANNOTATE::getChangeList().

◆ FindRefByPath()

int SCH_REFERENCE_LIST::FindRefByPath ( const wxString &  aPath) const

Search the list for a symbol with the given KIID path.

Parameters
aPathis the path to search.
Returns
index in aSymbolsList if found or -1 if not found.

Definition at line 177 of file component_references_lister.cpp.

178 {
179  for( size_t i = 0; i < flatList.size(); ++i )
180  {
181  if( flatList[i].GetPath() == aPath )
182  return i;
183  }
184 
185  return -1;
186 }
std::vector< SCH_REFERENCE > flatList

References flatList.

Referenced by BACK_ANNOTATE::getChangeList().

◆ FindUnit()

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

Search the sorted list of symbols for a another symbol with the same reference and a given part unit.

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

Parameters
aIndexis the index in aSymbolsList for of given SCH_REFERENCE item to test.
aUnitis the given unit number to search.
Returns
index in aSymbolsList if found or -1 if not found.

Definition at line 157 of file component_references_lister.cpp.

158 {
159  int NumRef = flatList[aIndex].m_numRef;
160 
161  for( size_t ii = 0; ii < flatList.size(); ii++ )
162  {
163  if( ( aIndex == ii )
164  || ( flatList[ii].m_isNew )
165  || ( flatList[ii].m_numRef != NumRef )
166  || ( flatList[aIndex].CompareRef( flatList[ii] ) != 0 ) )
167  continue;
168 
169  if( flatList[ii].m_unit == aUnit )
170  return (int) ii;
171  }
172 
173  return -1;
174 }
std::vector< SCH_REFERENCE > flatList

References flatList.

Referenced by Annotate().

◆ GetCount()

◆ GetItem() [1/2]

SCH_REFERENCE& SCH_REFERENCE_LIST::GetItem ( int  aIdx)
inline

Definition at line 231 of file sch_reference_list.h.

231 { return flatList[aIdx]; }
std::vector< SCH_REFERENCE > flatList

References flatList.

Referenced by ERC_TESTER::TestMultiunitFootprints().

◆ GetItem() [2/2]

const SCH_REFERENCE& SCH_REFERENCE_LIST::GetItem ( int  aIdx) const
inline

Definition at line 232 of file sch_reference_list.h.

232 { return flatList[aIdx]; }
std::vector< SCH_REFERENCE > flatList

References flatList.

◆ GetLastReference()

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

Return the last used (greatest) reference number in the reference list for the prefix used by the symbol pointed to by aIndex.

The symbol 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 224 of file component_references_lister.cpp.

225 {
226  int lastNumber = aMinValue;
227 
228  for( const SCH_REFERENCE& ref : flatList )
229  {
230  // search only for the current reference prefix:
231  if( flatList[aIndex].CompareRef( ref ) != 0 )
232  continue;
233 
234  // update max value for the current reference prefix
235  if( lastNumber < ref.m_numRef )
236  lastNumber = ref.m_numRef;
237  }
238 
239  return lastNumber;
240 }
std::vector< SCH_REFERENCE > flatList
A helper to define a symbol's reference designator in a schematic.

References flatList.

◆ GetRefsInUse()

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

Add all the reference designator numbers greater than aMinRefId to aIdList skipping the reference at aIndex.

Parameters
aIndexis the current symbol's index to use for reference prefix filtering.
aIdListis the buffer to fill.
aMinRefIdis the minimum ID value to store. All values < aMinRefId are ignored.

Definition at line 201 of file component_references_lister.cpp.

202 {
203  aIdList.clear();
204 
205  for( const SCH_REFERENCE& ref : flatList )
206  {
207  // Don't add new references to the list as we will reannotate those
208  if( flatList[aIndex].CompareRef( ref ) == 0 && ref.m_numRef >= aMinRefId && !ref.m_isNew )
209  aIdList.push_back( ref.m_numRef );
210  }
211 
212  sort( aIdList.begin(), aIdList.end() );
213 
214  // Ensure each reference number appears only once. If there are components with
215  // multiple parts per package the same number will be stored for each part.
216  std::vector< int >::iterator it = unique( aIdList.begin(), aIdList.end() );
217 
218  // Using the C++ unique algorithm only moves the duplicate entries to the end of
219  // of the array. This removes the duplicate entries from the array.
220  aIdList.resize( it - aIdList.begin() );
221 }
std::vector< SCH_REFERENCE > flatList
A helper to define a symbol's reference designator in a schematic.

References flatList.

Referenced by Annotate().

◆ GetSymbolInstances()

std::vector< SYMBOL_INSTANCE_REFERENCE > SCH_REFERENCE_LIST::GetSymbolInstances ( ) const

Definition at line 243 of file component_references_lister.cpp.

244 {
245  std::vector<SYMBOL_INSTANCE_REFERENCE> retval;
246 
247  for( const SCH_REFERENCE& ref : flatList )
248  {
249  SYMBOL_INSTANCE_REFERENCE instance;
250  instance.m_Path = ref.GetPath();
251  instance.m_Reference = ref.GetRef();
252  instance.m_Unit = ref.GetUnit();
253  instance.m_Value = ref.GetValue();
254  instance.m_Footprint = ref.GetFootprint();
255 
256  retval.push_back( instance );
257  }
258 
259  return retval;
260 }
A simple container for schematic symbol instance information.
std::vector< SCH_REFERENCE > flatList
A helper to define a symbol's reference designator in a schematic.

References flatList, SYMBOL_INSTANCE_REFERENCE::m_Footprint, SYMBOL_INSTANCE_REFERENCE::m_Path, SYMBOL_INSTANCE_REFERENCE::m_Reference, SYMBOL_INSTANCE_REFERENCE::m_Unit, and SYMBOL_INSTANCE_REFERENCE::m_Value.

Referenced by SCH_SEXPR_PLUGIN::Format().

◆ operator[]() [1/2]

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

Definition at line 214 of file sch_reference_list.h.

215  {
216  return flatList[ aIndex ];
217  }
std::vector< SCH_REFERENCE > flatList

References flatList.

◆ operator[]() [2/2]

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

Definition at line 219 of file sch_reference_list.h.

220  {
221  return flatList[ aIndex ];
222  }
std::vector< SCH_REFERENCE > flatList

References flatList.

◆ ReannotateDuplicates()

void SCH_REFERENCE_LIST::ReannotateDuplicates ( const SCH_REFERENCE_LIST aAdditionalReferences)

Replace any duplicate reference designators with the next available number after the present number.

Multi-unit symbols are reannotated together.

Parameters
aAdditionalReferencesAdditional references to check for duplicates

Definition at line 312 of file component_references_lister.cpp.

313 {
314  SplitReferences();
315 
316  // All multi-unit symbols always locked to ensure consistent re-annotation
317  SCH_MULTI_UNIT_REFERENCE_MAP lockedSymbols;
318 
319  for( size_t i = 0; i < GetCount(); i++ )
320  {
321  SCH_REFERENCE& ref = flatList[i];
322  wxString refstr = ref.GetSymbol()->GetRef( &ref.GetSheetPath() );
323 
324  // Never lock unassigned references
325  if( refstr[refstr.Len() - 1] == '?' )
326  continue;
327 
328  lockedSymbols[refstr].AddItem( ref );
329 
330  ref.m_isNew = true; // We want to reannotate all references
331  }
332 
333  Annotate( false, 0, 0, lockedSymbols, aAdditionalReferences, true );
334 }
const SCH_SHEET_PATH & GetSheetPath() const
bool m_isNew
True if not yet annotated.
size_t GetCount() const
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Container to map reference designators for multi-unit parts.
SCH_COMPONENT * GetSymbol() const
void Annotate(bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap, const SCH_REFERENCE_LIST &aAdditionalRefs, bool aStartAtCurrent=false)
Set the reference designators in the list that have not been annotated.
void SplitReferences()
Attempt to split all reference designators into a name (U) and number (1).
std::vector< SCH_REFERENCE > flatList
A helper to define a symbol's reference designator in a schematic.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:431

References Annotate(), flatList, GetCount(), SCH_COMPONENT::GetRef(), SCH_REFERENCE::GetSheetPath(), SCH_REFERENCE::GetSymbol(), SCH_REFERENCE::m_isNew, and SplitReferences().

◆ RemoveItem()

void SCH_REFERENCE_LIST::RemoveItem ( unsigned int  aIndex)

Remove an item from the list of references.

Parameters
aIndexis the index of the item to be removed.

Definition at line 44 of file component_references_lister.cpp.

45 {
46  if( aIndex < flatList.size() )
47  flatList.erase( flatList.begin() + aIndex );
48 }
std::vector< SCH_REFERENCE > flatList

References flatList.

Referenced by Annotate().

◆ Shorthand()

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

Return a shorthand string representing all the references in the list.

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

Definition at line 827 of file component_references_lister.cpp.

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

Referenced by FIELDS_EDITOR_GRID_DATA_MODEL::GetValue().

◆ SortByRefAndValue()

void SCH_REFERENCE_LIST::SortByRefAndValue ( )
inline

Sort the list of references by value.

Symbols are sorted in the following order:

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

Definition at line 385 of file sch_reference_list.h.

386  {
387  sort( flatList.begin(), flatList.end(), sortByRefAndValue );
388  }
static bool sortByRefAndValue(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
std::vector< SCH_REFERENCE > flatList

References flatList, and sortByRefAndValue().

Referenced by CheckAnnotation().

◆ sortByRefAndValue()

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

Definition at line 103 of file component_references_lister.cpp.

105 {
106  int ii = item1.CompareRef( item2 );
107 
108  if( ii == 0 )
109  ii = item1.CompareValue( item2 );
110 
111  if( ii == 0 )
112  ii = item1.m_unit - item2.m_unit;
113 
114  if( ii == 0 )
115  ii = item1.m_sheetNum - item2.m_sheetNum;
116 
117  if( ii == 0 )
118  ii = item1.m_symbolPos.x - item2.m_symbolPos.x;
119 
120  if( ii == 0 )
121  ii = item1.m_symbolPos.y - item2.m_symbolPos.y;
122 
123  if( ii == 0 )
124  return item1.m_symbolUuid < item2.m_symbolUuid; // ensure a deterministic sort
125  else
126  return ii < 0;
127 }
wxPoint m_symbolPos
The physical position of the symbol 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 symbol with multiple parts per package.
int CompareValue(const SCH_REFERENCE &item) const
KIID m_symbolUuid
UUID of the symbol.
int CompareRef(const SCH_REFERENCE &item) const

References SCH_REFERENCE::CompareRef(), SCH_REFERENCE::CompareValue(), SCH_REFERENCE::m_sheetNum, SCH_REFERENCE::m_symbolPos, SCH_REFERENCE::m_symbolUuid, and SCH_REFERENCE::m_unit.

Referenced by SortByRefAndValue().

◆ SortByReferenceOnly()

void SCH_REFERENCE_LIST::SortByReferenceOnly ( )
inline

Sort the list of references by reference.

Symbols are sorted in the following order:

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

Definition at line 397 of file sch_reference_list.h.

398  {
399  sort( flatList.begin(), flatList.end(), sortByReferenceOnly );
400  }
static bool sortByReferenceOnly(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
std::vector< SCH_REFERENCE > flatList

References flatList, and sortByReferenceOnly().

Referenced by SCH_SEXPR_PLUGIN::Format(), and SCH_EDITOR_CONTROL::Paste().

◆ sortByReferenceOnly()

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

Definition at line 130 of file component_references_lister.cpp.

132 {
133  int ii = UTIL::RefDesStringCompare( item1.GetRef(), item2.GetRef() );
134 
135  if( ii == 0 )
136  ii = item1.m_unit - item2.m_unit;
137 
138  if( ii == 0 )
139  return item1.m_symbolUuid < item2.m_symbolUuid; // ensure a deterministic sort
140  else
141  return ii < 0;
142 }
int RefDesStringCompare(const wxString &aFirst, const wxString &aSecond)
Acts just like the strcmp function but treats numbers within the string text correctly for sorting.
int m_unit
The unit number for symbol with multiple parts per package.
wxString GetRef() const
KIID m_symbolUuid
UUID of the symbol.

References SCH_REFERENCE::GetRef(), SCH_REFERENCE::m_symbolUuid, SCH_REFERENCE::m_unit, and UTIL::RefDesStringCompare().

Referenced by SortByReferenceOnly().

◆ SortByTimeStamp()

void SCH_REFERENCE_LIST::SortByTimeStamp ( )
inline

Sort the flat list by Time Stamp (sheet path + timestamp).

Useful to detect duplicate Time Stamps

Definition at line 369 of file sch_reference_list.h.

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

References flatList, and sortByTimeStamp().

Referenced by BACK_ANNOTATE::checkForUnusedSymbols().

◆ sortByTimeStamp()

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

Definition at line 145 of file component_references_lister.cpp.

147 {
148  int ii = item1.m_sheetPath.Cmp( item2.m_sheetPath );
149 
150  if( ii == 0 )
151  return item1.m_symbolUuid < item2.m_symbolUuid; // ensure a deterministic sort
152  else
153  return ii < 0;
154 }
KIID m_symbolUuid
UUID of the symbol.
SCH_SHEET_PATH m_sheetPath
The sheet path for this reference.
int Cmp(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare if this is the same sheet path as aSheetPathToTest.

References SCH_SHEET_PATH::Cmp(), SCH_REFERENCE::m_sheetPath, and SCH_REFERENCE::m_symbolUuid.

Referenced by BACK_ANNOTATE::checkForUnusedSymbols(), and SortByTimeStamp().

◆ SortByXCoordinate()

void SCH_REFERENCE_LIST::SortByXCoordinate ( )
inline

Sort the list of references by X position.

Symbols are sorted as follows:

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

Definition at line 344 of file sch_reference_list.h.

345  {
346  sort( flatList.begin(), flatList.end(), sortByXPosition );
347  }
std::vector< SCH_REFERENCE > flatList
static bool sortByXPosition(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)

References flatList, and sortByXPosition().

Referenced by SCH_EDIT_FRAME::AnnotateSymbols().

◆ sortByXPosition()

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

Definition at line 63 of file component_references_lister.cpp.

64 {
65  int ii = item1.CompareRef( item2 );
66 
67  if( ii == 0 )
68  ii = item1.m_sheetNum - item2.m_sheetNum;
69 
70  if( ii == 0 )
71  ii = item1.m_symbolPos.x - item2.m_symbolPos.x;
72 
73  if( ii == 0 )
74  ii = item1.m_symbolPos.y - item2.m_symbolPos.y;
75 
76  if( ii == 0 )
77  return item1.m_symbolUuid < item2.m_symbolUuid; // ensure a deterministic sort
78  else
79  return ii < 0;
80 }
wxPoint m_symbolPos
The physical position of the symbol in schematic used to annotate by X or Y position.
int m_sheetNum
The sheet number for the reference.
KIID m_symbolUuid
UUID of the symbol.
int CompareRef(const SCH_REFERENCE &item) const

References SCH_REFERENCE::CompareRef(), SCH_REFERENCE::m_sheetNum, SCH_REFERENCE::m_symbolPos, and SCH_REFERENCE::m_symbolUuid.

Referenced by SortByXCoordinate().

◆ SortByYCoordinate()

void SCH_REFERENCE_LIST::SortByYCoordinate ( )
inline

Sort the list of references by Y position.

Symbols are sorted as follows:

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

Definition at line 359 of file sch_reference_list.h.

360  {
361  sort( flatList.begin(), flatList.end(), sortByYPosition );
362  }
static bool sortByYPosition(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
std::vector< SCH_REFERENCE > flatList

References flatList, and sortByYPosition().

Referenced by SCH_EDIT_FRAME::AnnotateSymbols().

◆ sortByYPosition()

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

Definition at line 83 of file component_references_lister.cpp.

84 {
85  int ii = item1.CompareRef( item2 );
86 
87  if( ii == 0 )
88  ii = item1.m_sheetNum - item2.m_sheetNum;
89 
90  if( ii == 0 )
91  ii = item1.m_symbolPos.y - item2.m_symbolPos.y;
92 
93  if( ii == 0 )
94  ii = item1.m_symbolPos.x - item2.m_symbolPos.x;
95 
96  if( ii == 0 )
97  return item1.m_symbolUuid < item2.m_symbolUuid; // ensure a deterministic sort
98  else
99  return ii < 0;
100 }
wxPoint m_symbolPos
The physical position of the symbol in schematic used to annotate by X or Y position.
int m_sheetNum
The sheet number for the reference.
KIID m_symbolUuid
UUID of the symbol.
int CompareRef(const SCH_REFERENCE &item) const

References SCH_REFERENCE::CompareRef(), SCH_REFERENCE::m_sheetNum, SCH_REFERENCE::m_symbolPos, and SCH_REFERENCE::m_symbolUuid.

Referenced by SortByYCoordinate().

◆ SplitReferences()

void SCH_REFERENCE_LIST::SplitReferences ( )
inline

Attempt 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 symbols with multiple parts, keeps the unit number intact

See also
SCH_REFERENCE::Split()

Definition at line 266 of file sch_reference_list.h.

267  {
268  for( unsigned ii = 0; ii < GetCount(); ii++ )
269  flatList[ii].Split();
270  }
size_t GetCount() const
std::vector< SCH_REFERENCE > flatList

References flatList, and GetCount().

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

◆ UpdateAnnotation()

void SCH_REFERENCE_LIST::UpdateAnnotation ( )
inline

Update the symbol references 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 280 of file sch_reference_list.h.

281  {
282  /* update the reference numbers */
283  for( unsigned ii = 0; ii < GetCount(); ii++ )
284  flatList[ii].Annotate();
285  }
size_t GetCount() const
void Annotate(bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap, const SCH_REFERENCE_LIST &aAdditionalRefs, bool aStartAtCurrent=false)
Set the reference designators in the list that have not been annotated.
std::vector< SCH_REFERENCE > flatList

References Annotate(), flatList, and GetCount().

Referenced by SCH_SHEET_LIST::AnnotatePowerSymbols().

Friends And Related Function Documentation

◆ BACK_ANNOTATE

friend class BACK_ANNOTATE
friend

Definition at line 498 of file sch_reference_list.h.

◆ BACK_ANNOTATION

friend class BACK_ANNOTATION
friend

Definition at line 470 of file sch_reference_list.h.

Member Data Documentation

◆ flatList


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