KiCad PCB EDA Suite
component_references_lister.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 1992-2018 jean-pierre Charras <jp.charras at wanadoo.fr>
10  * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
11  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, you may find one here:
25  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
26  * or you may search the http://www.gnu.org website for the version 2 license,
27  * or you may write to the Free Software Foundation, Inc.,
28  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
29  */
30 
31 #include <sch_reference_list.h>
32 
33 #include <wx/regex.h>
34 #include <algorithm>
35 #include <vector>
36 #include <unordered_set>
37 
38 #include <fctsys.h>
39 #include <refdes_utils.h>
40 #include <reporter.h>
41 
42 #include <sch_component.h>
43 #include <sch_edit_frame.h>
44 
45 
46 void SCH_REFERENCE_LIST::RemoveItem( unsigned int aIndex )
47 {
48  if( aIndex < flatList.size() )
49  flatList.erase( flatList.begin() + aIndex );
50 }
51 
52 
54 {
55  int ii = item1.CompareRef( item2 );
56 
57  if( ii == 0 )
58  ii = item1.m_SheetNum - item2.m_SheetNum;
59 
60  if( ii == 0 )
61  ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
62 
63  if( ii == 0 )
64  ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
65 
66  if( ii == 0 )
67  return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
68  else
69  return ii < 0;
70 }
71 
72 
74 {
75  int ii = item1.CompareRef( item2 );
76 
77  if( ii == 0 )
78  ii = item1.m_SheetNum - item2.m_SheetNum;
79 
80  if( ii == 0 )
81  ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
82 
83  if( ii == 0 )
84  ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
85 
86  if( ii == 0 )
87  return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
88  else
89  return ii < 0;
90 }
91 
92 
94  const SCH_REFERENCE& item2 )
95 {
96  int ii = item1.CompareRef( item2 );
97 
98  if( ii == 0 )
99  ii = item1.CompareValue( item2 );
100 
101  if( ii == 0 )
102  ii = item1.m_Unit - item2.m_Unit;
103 
104  if( ii == 0 )
105  ii = item1.m_SheetNum - item2.m_SheetNum;
106 
107  if( ii == 0 )
108  ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
109 
110  if( ii == 0 )
111  ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
112 
113  if( ii == 0 )
114  return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
115  else
116  return ii < 0;
117 }
118 
119 
121  const SCH_REFERENCE& item2 )
122 {
123  int ii = UTIL::RefDesStringCompare( item1.GetRef(), item2.GetRef() );
124 
125  if( ii == 0 )
126  ii = item1.m_Unit - item2.m_Unit;
127 
128  if( ii == 0 )
129  return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
130  else
131  return ii < 0;
132 }
133 
134 
136  const SCH_REFERENCE& item2 )
137 {
138  int ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
139 
140  if( ii == 0 )
141  return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
142  else
143  return ii < 0;
144 }
145 
146 
147 int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit )
148 {
149  int NumRef;
150 
151  NumRef = flatList[aIndex].m_NumRef;
152 
153  for( size_t ii = 0; ii < flatList.size(); ii++ )
154  {
155  if( ( aIndex == ii )
156  || ( flatList[ii].m_IsNew )
157  || ( flatList[ii].m_NumRef != NumRef )
158  || ( flatList[aIndex].CompareRef( flatList[ii] ) != 0 ) )
159  continue;
160 
161  if( flatList[ii].m_Unit == aUnit )
162  return (int) ii;
163  }
164 
165  return -1;
166 }
167 
168 
169 int SCH_REFERENCE_LIST::FindRefByPath( const wxString& aPath ) const
170 {
171  for( size_t i = 0; i < flatList.size(); ++i )
172  {
173  if( flatList[i].GetPath() == aPath )
174  return i;
175  }
176 
177  return -1;
178 }
179 
180 
181 void SCH_REFERENCE_LIST::GetRefsInUse( int aIndex, std::vector< int >& aIdList, int aMinRefId )
182 {
183  aIdList.clear();
184 
185  for( SCH_REFERENCE& ref : flatList )
186  {
187  if( flatList[aIndex].CompareRef( ref ) == 0 && ref.m_NumRef >= aMinRefId )
188  aIdList.push_back( ref.m_NumRef );
189  }
190 
191  sort( aIdList.begin(), aIdList.end() );
192 
193  // Ensure each reference number appears only once. If there are components with
194  // multiple parts per package the same number will be stored for each part.
195  std::vector< int >::iterator it = unique( aIdList.begin(), aIdList.end() );
196 
197  // Using the C++ unique algorithm only moves the duplicate entries to the end of
198  // of the array. This removes the duplicate entries from the array.
199  aIdList.resize( it - aIdList.begin() );
200 }
201 
202 
203 int SCH_REFERENCE_LIST::GetLastReference( int aIndex, int aMinValue )
204 {
205  int lastNumber = aMinValue;
206 
207  for( SCH_REFERENCE& ref : flatList )
208  {
209  // search only for the current reference prefix:
210  if( flatList[aIndex].CompareRef( ref ) != 0 )
211  continue;
212 
213  // update max value for the current reference prefix
214  if( lastNumber < ref.m_NumRef )
215  lastNumber = ref.m_NumRef;
216  }
217 
218  return lastNumber;
219 }
220 
221 
222 int SCH_REFERENCE_LIST::CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue )
223 {
224  int expectedId = aFirstValue;
225 
226  // We search for expected Id a value >= aFirstValue.
227  // Skip existing Id < aFirstValue
228  unsigned ii = 0;
229 
230  for( ; ii < aIdList.size(); ii++ )
231  {
232  if( expectedId <= aIdList[ii] )
233  break;
234  }
235 
236  // Ids are sorted by increasing value, from aFirstValue
237  // So we search from aFirstValue the first not used value, i.e. the first hole in list.
238  for( ; ii < aIdList.size(); ii++ )
239  {
240  if( expectedId != aIdList[ii] ) // This id is not yet used.
241  {
242  // Insert this free Id, in order to keep list sorted
243  aIdList.insert( aIdList.begin() + ii, expectedId );
244  return expectedId;
245  }
246 
247  expectedId++;
248  }
249 
250  // All existing Id are tested, and all values are found in use.
251  // So Create a new one.
252  aIdList.push_back( expectedId );
253  return expectedId;
254 }
255 
256 
257 // A helper function to build a full reference string of a SCH_REFERENCE item
258 wxString buildFullReference( const SCH_REFERENCE& aItem, int aUnitNumber = -1 )
259 {
260  wxString fullref;
261  fullref = aItem.GetRef() + aItem.GetRefNumber();
262 
263  if( aUnitNumber < 0 )
264  fullref << ".." << aItem.GetUnit();
265  else
266  fullref << ".." << aUnitNumber;
267 
268  return fullref;
269 }
270 
271 
272 void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int aStartNumber,
273  SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap )
274 {
275  if ( flatList.size() == 0 )
276  return;
277 
278  int LastReferenceNumber = 0;
279  int NumberOfUnits, Unit;
280 
281  /* calculate index of the first component with the same reference prefix
282  * than the current component. All components having the same reference
283  * prefix will receive a reference number with consecutive values:
284  * IC .. will be set to IC4, IC4, IC5 ...
285  */
286  unsigned first = 0;
287 
288  // calculate the last used number for this reference prefix:
289  int minRefId;
290 
291  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
292  if( aUseSheetNum )
293  minRefId = flatList[first].m_SheetNum * aSheetIntervalId + 1;
294  else
295  minRefId = aStartNumber + 1;
296 
297  // For multi units components, when "keep order of multi unit" option is selected,
298  // store the list of already used full references.
299  // The algorithm try to allocate the new reference to components having the same
300  // old reference.
301  // This algo works fine as long as the previous annotation has no duplicates.
302  // But when a hierarchy is reannotated with this option, the previous anotation can
303  // have duplicate references, and obviously we must fix these duplicate.
304  // therefore do not try to allocate a full reference more than once when trying
305  // to keep this order of multi units.
306  // inUseRefs keep trace of previously allocated references
307  std::unordered_set<wxString> inUseRefs;
308 
309  // This is the list of all Id already in use for a given reference prefix.
310  // Will be refilled for each new reference prefix.
311  std::vector<int>idList;
312  GetRefsInUse( first, idList, minRefId );
313 
314  for( unsigned ii = 0; ii < flatList.size(); ii++ )
315  {
316  auto& ref_unit = flatList[ii];
317 
318  if( ref_unit.m_Flag )
319  continue;
320 
321  // Check whether this component is in aLockedUnitMap.
322  SCH_REFERENCE_LIST* lockedList = NULL;
323  for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : aLockedUnitMap )
324  {
325  unsigned n_refs = pair.second.GetCount();
326 
327  for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
328  {
329  SCH_REFERENCE &thisRef = pair.second[thisRefI];
330 
331  if( thisRef.IsSameInstance( ref_unit ) )
332  {
333  lockedList = &pair.second;
334  break;
335  }
336  }
337  if( lockedList != NULL ) break;
338  }
339 
340  if( ( flatList[first].CompareRef( ref_unit ) != 0 )
341  || ( aUseSheetNum && ( flatList[first].m_SheetNum != ref_unit.m_SheetNum ) ) )
342  {
343  // New reference found: we need a new ref number for this reference
344  first = ii;
345 
346  // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
347  if( aUseSheetNum )
348  minRefId = ref_unit.m_SheetNum * aSheetIntervalId + 1;
349  else
350  minRefId = aStartNumber + 1;
351 
352  GetRefsInUse( first, idList, minRefId );
353  }
354 
355  // Annotation of one part per package components (trivial case).
356  if( ref_unit.GetLibPart()->GetUnitCount() <= 1 )
357  {
358  if( ref_unit.m_IsNew )
359  {
360  LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
361  ref_unit.m_NumRef = LastReferenceNumber;
362  }
363 
364  ref_unit.m_Unit = 1;
365  ref_unit.m_Flag = 1;
366  ref_unit.m_IsNew = false;
367  continue;
368  }
369 
370  // Annotation of multi-unit parts ( n units per part ) (complex case)
371  NumberOfUnits = ref_unit.GetLibPart()->GetUnitCount();
372 
373  if( ref_unit.m_IsNew )
374  {
375  LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
376  ref_unit.m_NumRef = LastReferenceNumber;
377 
378  if( !ref_unit.IsUnitsLocked() )
379  ref_unit.m_Unit = 1;
380 
381  ref_unit.m_Flag = 1;
382  }
383 
384  // If this component is in aLockedUnitMap, copy the annotation to all
385  // components that are not it
386  if( lockedList != NULL )
387  {
388  unsigned n_refs = lockedList->GetCount();
389 
390  for( unsigned thisRefI = 0; thisRefI < n_refs; ++thisRefI )
391  {
392  SCH_REFERENCE &thisRef = (*lockedList)[thisRefI];
393 
394  if( thisRef.IsSameInstance( ref_unit ) )
395  {
396  // This is the component we're currently annotating. Hold the unit!
397  ref_unit.m_Unit = thisRef.m_Unit;
398  // lock this new full reference
399  inUseRefs.insert( buildFullReference( ref_unit ) );
400  }
401 
402  if( thisRef.CompareValue( ref_unit ) != 0 )
403  continue;
404 
405  if( thisRef.CompareLibName( ref_unit ) != 0 )
406  continue;
407 
408  // Find the matching component
409  for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
410  {
411  if( ! thisRef.IsSameInstance( flatList[jj] ) )
412  continue;
413 
414  wxString ref_candidate = buildFullReference( ref_unit, thisRef.m_Unit );
415 
416  // propagate the new reference and unit selection to the "old" component,
417  // if this new full reference is not already used (can happens when initial
418  // multiunits components have duplicate references)
419  if( inUseRefs.find( ref_candidate ) == inUseRefs.end() )
420  {
421  flatList[jj].m_NumRef = ref_unit.m_NumRef;
422  flatList[jj].m_Unit = thisRef.m_Unit;
423  flatList[jj].m_IsNew = false;
424  flatList[jj].m_Flag = 1;
425  // lock this new full reference
426  inUseRefs.insert( ref_candidate );
427  break;
428  }
429  }
430  }
431  }
432  else
433  {
434  /* search for others units of this component.
435  * we search for others parts that have the same value and the same
436  * reference prefix (ref without ref number)
437  */
438  for( Unit = 1; Unit <= NumberOfUnits; Unit++ )
439  {
440  if( ref_unit.m_Unit == Unit )
441  continue;
442 
443  int found = FindUnit( ii, Unit );
444 
445  if( found >= 0 )
446  continue; // this unit exists for this reference (unit already annotated)
447 
448  // Search a component to annotate ( same prefix, same value, not annotated)
449  for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
450  {
451  auto& cmp_unit = flatList[jj];
452 
453  if( cmp_unit.m_Flag ) // already tested
454  continue;
455 
456  if( cmp_unit.CompareRef( ref_unit ) != 0 )
457  continue;
458 
459  if( cmp_unit.CompareValue( ref_unit ) != 0 )
460  continue;
461 
462  if( cmp_unit.CompareLibName( ref_unit ) != 0 )
463  continue;
464 
465  if( aUseSheetNum &&
466  cmp_unit.GetSheetPath().Cmp( ref_unit.GetSheetPath() ) != 0 )
467  continue;
468 
469  if( !cmp_unit.m_IsNew )
470  continue;
471 
472  // Component without reference number found, annotate it if possible
473  if( !cmp_unit.IsUnitsLocked()
474  || ( cmp_unit.m_Unit == Unit ) )
475  {
476  cmp_unit.m_NumRef = ref_unit.m_NumRef;
477  cmp_unit.m_Unit = Unit;
478  cmp_unit.m_Flag = 1;
479  cmp_unit.m_IsNew = false;
480  break;
481  }
482  }
483  }
484  }
485  }
486 }
487 
489 {
490  int error = 0;
491  wxString tmp;
492  wxString msg;
493 
495 
496  // Spiit reference designators into name (prefix) and number: IC1 becomes IC, and 1.
497  SplitReferences();
498 
499  // count not yet annotated items or annotation error.
500  for( unsigned ii = 0; ii < flatList.size(); ii++ )
501  {
502  msg.Empty();
503  tmp.Empty();
504 
505  if( flatList[ii].m_IsNew ) // Not yet annotated
506  {
507  if( flatList[ii].m_NumRef >= 0 )
508  tmp << flatList[ii].m_NumRef;
509  else
510  tmp = wxT( "?" );
511 
512 
513  if( ( flatList[ii].m_Unit > 0 )
514  && ( flatList[ii].m_Unit < 0x7FFFFFFF ) )
515  {
516  msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ),
517  flatList[ii].GetRef(),
518  tmp,
519  flatList[ii].m_Unit );
520  }
521  else
522  {
523  msg.Printf( _( "Item not annotated: %s%s\n" ),
524  flatList[ii].GetRef(),
525  tmp );
526  }
527 
528  aReporter.Report( msg, RPT_SEVERITY_WARNING );
529  error++;
530  break;
531  }
532 
533  // Error if unit number selected does not exist ( greater than the number of
534  // parts in the component ). This can happen if a component has changed in a
535  // library after a previous annotation.
536  if( std::max( flatList[ii].GetLibPart()->GetUnitCount(), 1 )
537  < flatList[ii].m_Unit )
538  {
539  if( flatList[ii].m_NumRef >= 0 )
540  tmp << flatList[ii].m_NumRef;
541  else
542  tmp = wxT( "?" );
543 
544  msg.Printf( _( "Error: symbol %s%s unit %d and symbol has only %d units defined\n" ),
545  flatList[ii].GetRef(),
546  tmp,
547  flatList[ii].m_Unit,
548  flatList[ii].GetLibPart()->GetUnitCount() );
549 
550  aReporter.Report( msg, RPT_SEVERITY_ERROR );
551  error++;
552  break;
553  }
554  }
555 
556  if( error )
557  return error;
558 
559  // count the duplicated elements (if all are annotated)
560  int imax = flatList.size() - 1;
561 
562  for( int ii = 0; ii < imax; ii++ )
563  {
564  msg.Empty();
565  tmp.Empty();
566 
567  if( ( flatList[ii].CompareRef( flatList[ii + 1] ) != 0 )
568  || ( flatList[ii].m_NumRef != flatList[ii + 1].m_NumRef ) )
569  continue;
570 
571  // Same reference found. If same unit, error!
572  if( flatList[ii].m_Unit == flatList[ii + 1].m_Unit )
573  {
574  if( flatList[ii].m_NumRef >= 0 )
575  tmp << flatList[ii].m_NumRef;
576  else
577  tmp = wxT( "?" );
578 
579  if( ( flatList[ii].m_Unit > 0 )
580  && ( flatList[ii].m_Unit < 0x7FFFFFFF ) )
581  {
582  msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
583  flatList[ii].GetRef(),
584  tmp,
585  flatList[ii].m_Unit );
586  }
587  else
588  {
589  msg.Printf( _( "Multiple item %s%s\n" ),
590  flatList[ii].GetRef(),
591  tmp );
592  }
593 
594  aReporter.Report( msg, RPT_SEVERITY_ERROR );
595  error++;
596  continue;
597  }
598 
599  /* Test error if units are different but number of parts per package
600  * too high (ex U3 ( 1 part) and we find U3B this is an error) */
601  if( flatList[ii].GetLibPart()->GetUnitCount()
602  != flatList[ ii + 1].GetLibPart()->GetUnitCount() )
603  {
604  if( flatList[ii].m_NumRef >= 0 )
605  tmp << flatList[ii].m_NumRef;
606  else
607  tmp = wxT( "?" );
608 
609  if( ( flatList[ii].m_Unit > 0 )
610  && ( flatList[ii].m_Unit < 0x7FFFFFFF ) )
611  {
612  msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
613  flatList[ii].GetRef(),
614  tmp,
615  flatList[ii].m_Unit );
616  }
617  else
618  {
619  msg.Printf( _( "Multiple item %s%s\n" ),
620  flatList[ii].GetRef(),
621  tmp );
622  }
623 
624  aReporter.Report( msg, RPT_SEVERITY_ERROR );
625  error++;
626  }
627 
628  // Error if values are different between units, for the same reference
629  int next = ii + 1;
630 
631  if( flatList[ii].CompareValue( flatList[next] ) != 0 )
632  {
633  msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ),
634  flatList[ii].GetRef(),
635  flatList[ii].m_NumRef,
636  LIB_PART::SubReference( flatList[ii].m_Unit ),
637  flatList[ii].m_Value->GetText(),
638  flatList[next].GetRef(),
639  flatList[next].m_NumRef,
641  flatList[next].m_Value->GetText() );
642 
643  aReporter.Report( msg, RPT_SEVERITY_ERROR );
644  error++;
645  }
646  }
647 
648  return error;
649 }
650 
651 
653  const SCH_SHEET_PATH& aSheetPath )
654 {
655  wxASSERT( aComponent != NULL );
656 
657  m_RootCmp = aComponent;
658  m_Entry = aLibPart; // Warning: can be nullptr for orphan components
659  // (i.e. with a symbol library not found)
660  m_Unit = aComponent->GetUnitSelection( &aSheetPath );
661  m_SheetPath = aSheetPath;
662  m_IsNew = false;
663  m_Flag = 0;
664  m_Uuid = aComponent->m_Uuid;
665  m_CmpPos = aComponent->GetPosition();
666  m_SheetNum = 0;
667 
668  if( aComponent->GetRef( &aSheetPath ).IsEmpty() )
669  aComponent->SetRef( &aSheetPath, wxT( "DefRef?" ) );
670 
671  wxString ref = aComponent->GetRef( &aSheetPath );
672  SetRef( ref );
673 
674  m_NumRef = -1;
675 
676  if( aComponent->GetField( VALUE )->GetText().IsEmpty() )
677  aComponent->GetField( VALUE )->SetText( wxT( "~" ) );
678 
679  m_Value = aComponent->GetField( VALUE );
680 }
681 
682 
684 {
685  if( m_NumRef < 0 )
686  m_Ref += '?';
687  else
688  m_Ref = TO_UTF8( GetRef() << GetRefNumber() );
689 
693 }
694 
695 
697 {
698  std::string refText = GetRefStr();
699 
700  m_NumRef = -1;
701 
702  int ll = refText.length() - 1;
703 
704  if( refText[ll] == '?' )
705  {
706  m_IsNew = true;
707 
708  if( !IsUnitsLocked() )
709  m_Unit = 0x7FFFFFFF;
710 
711  refText.erase( ll ); // delete last char
712 
713  SetRefStr( refText );
714  }
715  else if( isdigit( refText[ll] ) == 0 )
716  {
717  m_IsNew = true;
718 
719  if( !IsUnitsLocked() )
720  m_Unit = 0x7FFFFFFF;
721  }
722  else
723  {
724  while( ll >= 0 )
725  {
726  if( (refText[ll] <= ' ' ) || isdigit( refText[ll] ) )
727  ll--;
728  else
729  {
730  if( isdigit( refText[ll + 1] ) )
731  {
732  // null terminated C string into cp
733  const char* cp = refText.c_str() + ll + 1;
734 
735  m_NumRef = atoi( cp );
736  }
737 
738  refText.erase( ll+1 ); // delete from ll+1 to end
739  break;
740  }
741  }
742 
743  SetRefStr( refText );
744  }
745 }
746 
747 
748 wxString SCH_REFERENCE_LIST::Shorthand( std::vector<SCH_REFERENCE> aList )
749 {
750  wxString retVal;
751  size_t i = 0;
752 
753  while( i < aList.size() )
754  {
755  wxString ref = aList[ i ].GetRef();
756  int numRef = aList[ i ].m_NumRef;
757 
758  size_t range = 1;
759 
760  while( i + range < aList.size()
761  && aList[ i + range ].GetRef() == ref
762  && aList[ i + range ].m_NumRef == int( numRef + range ) )
763  {
764  range++;
765  }
766 
767  if( !retVal.IsEmpty() )
768  retVal << wxT( ", " );
769 
770  if( range == 1 )
771  {
772  retVal << ref << aList[ i ].GetRefNumber();
773  }
774  else if( range == 2 )
775  {
776  retVal << ref << aList[ i ].GetRefNumber();
777  retVal << wxT( ", " );
778  retVal << ref << aList[ i + 1 ].GetRefNumber();
779  }
780  else
781  {
782  retVal << ref << aList[ i ].GetRefNumber();
783  retVal << wxT( "-" );
784  retVal << ref << aList[ i + ( range - 1 ) ].GetRefNumber();
785  }
786 
787  i+= range;
788  }
789 
790  return retVal;
791 }
CITER next(CITER it)
Definition: ptree.cpp:130
wxPoint m_CmpPos
The physical position of the component in schematic used to annotate by X or Y position.
static bool sortByTimeStamp(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
KIID m_Uuid
UUID of the component.
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:114
void RemoveItem(unsigned int aIndex)
Function RemoveItem removes an item from the list of references.
void Split()
Function Split attempts to split the reference designator into a name (U) and number (1).
int FindRefByPath(const wxString &aPath) const
Searches unit with designated path.
UTF8 m_Ref
Component reference prefix, without number (for IC1, this is IC) )
int m_NumRef
The numeric part of the reference designator.
Collection of utility functions for component reference designators (refdes)
static wxString Shorthand(std::vector< SCH_REFERENCE > aList)
Function Shorthand Returns a shorthand string representing all the references in the list.
int GetUnit() const
wxString GetRefNumber() const
int m_SheetNum
The sheet number for the reference.
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
void SortByRefAndValue()
Function SortByRefAndValue sorts the list of references by value.
SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierarchy,...
void SetRefStr(const std::string &aReference)
const char * c_str() const
Definition: utf8.h:107
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 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
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
#define NULL
int CompareValue(const SCH_REFERENCE &item) const
wxString buildFullReference(const SCH_REFERENCE &aItem, int aUnitNumber=-1)
SCH_COMPONENT * m_RootCmp
The component associated the reference object.
EDA_TEXT * m_Value
The component value of the reference.
int CompareLibName(const SCH_REFERENCE &item) const
static bool sortByRefAndValue(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
LIB_PART * m_Entry
The source component from a library.
void Annotate()
Function Annotate updates the annotation of the component according the the current object state.
Define a library symbol object.
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.
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...
void SetUnit(int aUnit)
Change the unit number to aUnit.
static bool sortByYPosition(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
SCH_SHEET_PATH.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
static bool sortByReferenceOnly(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Type SCH_MULTI_UNIT_REFERENCE_MAP is used to create a map of reference designators for multi-unit par...
const KIID m_Uuid
Definition: base_struct.h:162
unsigned GetCount() const
Function GetCount.
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
Field Value of part, i.e. "3.3K".
SCH_SHEET_PATH m_SheetPath
The sheet path for this reference.
int CompareRef(const SCH_REFERENCE &item) const
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
const char * GetRefStr() const
void SplitReferences()
Function SplitReferences attempts to split all reference designators into a name (U) and number (1).
#define _(s)
Definition: 3d_actions.cpp:33
bool IsSameInstance(const SCH_REFERENCE &other) const
Function IsSameInstance returns whether this reference refers to the same component instance (compone...
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Schematic symbol object.
Definition: sch_component.h:88
wxPoint GetPosition() const override
#define TO_UTF8(wxstring)
int CreateFirstFreeRefId(std::vector< int > &aIdList, int aFirstValue)
Function CreateFirstFreeRefId searches for the first free reference number in aListId of reference nu...
void SetRef(const wxString &aReference)
std::vector< SCH_REFERENCE > flatList
int GetLastReference(int aIndex, int aMinValue)
Function GetLastReference returns the last used (greatest) reference number in the reference list for...
int CheckAnnotation(REPORTER &aReporter)
Function CheckAnnotation check for annotations errors.
int Cmp(const SCH_SHEET_PATH &aSheetPathToTest) const
Function Cmp Compare if this is the same sheet path as aSheetPathToTest.
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
SCH_REFERENCE is used as a helper to define a component's reference designator in a schematic.
bool m_IsNew
True if not yet annotated.
static bool sortByXPosition(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)