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

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

583 {
584  int error = 0;
585  wxString tmp;
586  wxString msg;
587 
589 
590  // Split reference designators into name (prefix) and number: IC1 becomes IC, and 1.
591  SplitReferences();
592 
593  // count not yet annotated items or annotation error.
594  for( unsigned ii = 0; ii < flatList.size(); ii++ )
595  {
596  msg.Empty();
597  tmp.Empty();
598 
599  if( flatList[ii].m_isNew ) // Not yet annotated
600  {
601  if( flatList[ii].m_numRef >= 0 )
602  tmp << flatList[ii].m_numRef;
603  else
604  tmp = wxT( "?" );
605 
606  if( ( flatList[ii].m_unit > 0 ) && ( flatList[ii].m_unit < 0x7FFFFFFF ) )
607  {
608  msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ),
609  flatList[ii].GetRef(),
610  tmp,
611  flatList[ii].m_unit );
612  }
613  else
614  {
615  msg.Printf( _( "Item not annotated: %s%s\n" ), flatList[ii].GetRef(), tmp );
616  }
617 
618  aHandler( ERCE_UNANNOTATED, msg, &flatList[ii], nullptr );
619  error++;
620  break;
621  }
622 
623  // Error if unit number selected does not exist (greater than the number of units in
624  // the symbol). This can happen if a symbol has changed in a library after a
625  // previous annotation.
626  if( std::max( flatList[ii].GetLibPart()->GetUnitCount(), 1 ) < flatList[ii].m_unit )
627  {
628  if( flatList[ii].m_numRef >= 0 )
629  tmp << flatList[ii].m_numRef;
630  else
631  tmp = wxT( "?" );
632 
633  msg.Printf( _( "Error: symbol %s%s%s (unit %d) exceeds units defined (%d)\n" ),
634  flatList[ii].GetRef(),
635  tmp,
636  LIB_SYMBOL::SubReference( flatList[ii].m_unit ),
637  flatList[ii].m_unit,
638  flatList[ii].GetLibPart()->GetUnitCount() );
639 
640  aHandler( ERCE_EXTRA_UNITS, msg, &flatList[ii], nullptr );
641  error++;
642  break;
643  }
644  }
645 
646  // count the duplicated elements (if all are annotated)
647  int imax = flatList.size() - 1;
648 
649  for( int ii = 0; ii < imax; ii++ )
650  {
651  msg.Empty();
652  tmp.Empty();
653 
654  if( ( flatList[ii].CompareRef( flatList[ii + 1] ) != 0 )
655  || ( flatList[ii].m_numRef != flatList[ ii + 1].m_numRef ) )
656  {
657  continue;
658  }
659 
660  // Same reference found. If same unit, error!
661  if( flatList[ii].m_unit == flatList[ ii + 1].m_unit )
662  {
663  if( flatList[ii].m_numRef >= 0 )
664  tmp << flatList[ii].m_numRef;
665  else
666  tmp = wxT( "?" );
667 
668  if( ( flatList[ii].m_unit > 0 ) && ( flatList[ii].m_unit < 0x7FFFFFFF ) )
669  {
670  msg.Printf( _( "Duplicate items %s%s%s\n" ),
671  flatList[ii].GetRef(),
672  tmp,
673  LIB_SYMBOL::SubReference( flatList[ii].m_unit ) );
674  }
675  else
676  {
677  msg.Printf( _( "Duplicate items %s%s\n" ), flatList[ii].GetRef(), tmp );
678  }
679 
680  aHandler( ERCE_DUPLICATE_REFERENCE, msg, &flatList[ii], &flatList[ii+1] );
681  error++;
682  continue;
683  }
684 
685  /* Test error if units are different but number of parts per package
686  * too high (ex U3 ( 1 part) and we find U3B this is an error) */
687  if( flatList[ii].GetLibPart()->GetUnitCount()
688  != flatList[ ii + 1].GetLibPart()->GetUnitCount() )
689  {
690  if( flatList[ii].m_numRef >= 0 )
691  tmp << flatList[ii].m_numRef;
692  else
693  tmp = wxT( "?" );
694 
695  if( ( flatList[ii].m_unit > 0 )
696  && ( flatList[ii].m_unit < 0x7FFFFFFF ) )
697  {
698  msg.Printf( _( "Duplicate items %s%s%s\n" ),
699  flatList[ii].GetRef(),
700  tmp,
701  LIB_SYMBOL::SubReference( flatList[ii].m_unit ) );
702  }
703  else
704  {
705  msg.Printf( _( "Duplicate items %s%s\n" ), flatList[ii].GetRef(), 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_SYMBOL::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
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:445
void SortByRefAndValue()
Sort the list of references by value.
#define _(s)
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).
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_SYMBOL::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 264 of file component_references_lister.cpp.

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

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

226 {
227  int lastNumber = aMinValue;
228 
229  for( const SCH_REFERENCE& ref : flatList )
230  {
231  // search only for the current reference prefix:
232  if( flatList[aIndex].CompareRef( ref ) != 0 )
233  continue;
234 
235  // update max value for the current reference prefix
236  if( lastNumber < ref.m_numRef )
237  lastNumber = ref.m_numRef;
238  }
239 
240  return lastNumber;
241 }
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.

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

245 {
246  std::vector<SYMBOL_INSTANCE_REFERENCE> retval;
247 
248  for( const SCH_REFERENCE& ref : flatList )
249  {
250  SYMBOL_INSTANCE_REFERENCE instance;
251  instance.m_Path = ref.GetPath();
252  instance.m_Reference = ref.GetRef();
253  instance.m_Unit = ref.GetUnit();
254  instance.m_Value = ref.GetValue();
255  instance.m_Footprint = ref.GetFootprint();
256 
257  retval.push_back( instance );
258  }
259 
260  return retval;
261 }
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 314 of file component_references_lister.cpp.

315 {
316  SplitReferences();
317 
318  // All multi-unit symbols always locked to ensure consistent re-annotation
319  SCH_MULTI_UNIT_REFERENCE_MAP lockedSymbols;
320 
321  for( size_t i = 0; i < GetCount(); i++ )
322  {
323  SCH_REFERENCE& ref = flatList[i];
324  wxString refstr = ref.GetSymbol()->GetRef( &ref.GetSheetPath() );
325 
326  // Never lock unassigned references
327  if( refstr[refstr.Len() - 1] == '?' )
328  continue;
329 
330  lockedSymbols[refstr].AddItem( ref );
331 
332  ref.m_isNew = true; // We want to reannotate all references
333  }
334 
335  Annotate( false, 0, 0, lockedSymbols, aAdditionalReferences, true );
336 }
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:432
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.
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.

References Annotate(), flatList, GetCount(), SCH_SYMBOL::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: