KiCad PCB EDA Suite
sch_sheet_path.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <sch_screen.h>
27 #include <sch_item.h>
28 #include <sch_marker.h>
29 #include <sch_reference_list.h>
30 #include <class_library.h>
31 #include <sch_sheet_path.h>
32 #include <sch_component.h>
33 #include <sch_sheet.h>
34 #include <schematic.h>
35 #include <template_fieldnames.h>
36 #include <trace_helpers.h>
37 
38 #include <boost/functional/hash.hpp>
39 #include <wx/filename.h>
40 #include "erc_item.h"
41 
42 
48 {
49 public:
51  SCH_ITEM( nullptr, NOT_USED )
52  {}
53 
54  wxString GetSelectMenuText( EDA_UNITS aUnits ) const override
55  {
56  return _( "(Deleted Item)" );
57  }
58 
59  wxString GetClass() const override
60  {
61  return wxT( "DELETED_SHEET_ITEM" );
62  }
63 
65  {
66  static DELETED_SHEET_ITEM* item = nullptr;
67 
68  if( !item )
69  item = new DELETED_SHEET_ITEM();
70 
71  return item;
72  }
73 
74  // pure virtuals:
75  void SetPosition( const wxPoint& ) override {}
76  void Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset ) override {}
77  void Move( const wxPoint& aMoveVector ) override {}
78  void MirrorY( int aYaxis_position ) override {}
79  void MirrorX( int aXaxis_position ) override {}
80  void Rotate( wxPoint aPosition ) override {}
81 
82 #if defined(DEBUG)
83  void Show( int , std::ostream& ) const override {}
84 #endif
85 };
86 
87 
88 namespace std
89 {
91  {
92  return path.GetCurrentHash();
93  }
94 }
95 
96 
98 {
100  m_current_hash = 0;
101 }
102 
103 
105 {
106  initFromOther( aOther );
107 }
108 
109 
111 {
112  initFromOther( aOther );
113  return *this;
114 }
115 
116 
118 {
119  m_sheets = aOther.m_sheets;
122 
123  // Note: don't copy m_recursion_test_cache as it is slow and we want SCH_SHEET_PATHS to be
124  // very fast to construct for use in the connectivity algorithm.
125 }
126 
127 
129 {
130  m_current_hash = 0;
131 
132  for( auto sheet : m_sheets )
133  boost::hash_combine( m_current_hash, sheet->m_Uuid.Hash() );
134 }
135 
136 
137 int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
138 {
139  if( size() > aSheetPathToTest.size() )
140  return 1;
141 
142  if( size() < aSheetPathToTest.size() )
143  return -1;
144 
145  //otherwise, same number of sheets.
146  for( unsigned i = 0; i < size(); i++ )
147  {
148  if( at( i )->m_Uuid < aSheetPathToTest.at( i )->m_Uuid )
149  return -1;
150 
151  if( at( i )->m_Uuid != aSheetPathToTest.at( i )->m_Uuid )
152  return 1;
153  }
154 
155  return 0;
156 }
157 
158 
160 {
161  if( !empty() )
162  return m_sheets.back();
163 
164  return nullptr;
165 }
166 
167 
169 {
170  SCH_SHEET* lastSheet = Last();
171 
172  if( lastSheet )
173  return lastSheet->GetScreen();
174 
175  return nullptr;
176 }
177 
178 
180 {
181  SCH_SHEET* lastSheet = Last();
182 
183  if( lastSheet )
184  return lastSheet->GetScreen();
185 
186  return nullptr;
187 }
188 
189 
191 {
192  wxString s;
193 
194  s = wxT( "/" ); // This is the root path
195 
196  // Start at 1 to avoid the root sheet, which does not need to be added to the path.
197  // It's timestamp changes anyway.
198  for( unsigned i = 1; i < size(); i++ )
199  s += at( i )->m_Uuid.AsString() + "/";
200 
201  return s;
202 }
203 
204 
206 {
207  KIID_PATH path;
208 
209  for( const SCH_SHEET* sheet : m_sheets )
210  path.push_back( sheet->m_Uuid );
211 
212  return path;
213 }
214 
215 
217 {
218  KIID_PATH path;
219 
220  for( size_t i = 1; i < size(); i++ )
221  path.push_back( at( i )->m_Uuid );
222 
223  return path;
224 }
225 
226 
227 wxString SCH_SHEET_PATH::PathHumanReadable( bool aUseShortRootName ) const
228 {
229  wxString s;
230  wxString fileName;
231 
232  if( !empty() && at( 0 )->GetScreen() )
233  fileName = at( 0 )->GetScreen()->GetFileName();
234 
235  wxFileName fn = fileName;
236 
237  if( aUseShortRootName )
238  s = wxT( "/" ); // Use only the short name in netlists
239  else
240  s = fn.GetName() + wxT( "/" );
241 
242  // Start at 1 since we've already processed the root sheet.
243  for( unsigned i = 1; i < size(); i++ )
244  s = s + at( i )->GetFields()[ SHEETNAME ].GetShownText() + wxT( "/" );
245 
246  return s;
247 }
248 
249 
251 {
252  for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
253  {
254  SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
255  component->GetField( REFERENCE_FIELD )->SetText( component->GetRef( this ) );
256  component->GetField( VALUE_FIELD )->SetText( component->GetValue( this, false ) );
257  component->GetField( FOOTPRINT_FIELD )->SetText( component->GetFootprint( this, false ) );
258  component->UpdateUnit( component->GetUnitSelection( this ) );
259  }
260 }
261 
262 
263 
264 void SCH_SHEET_PATH::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
265  bool aForceIncludeOrphanComponents ) const
266 {
267  for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
268  {
269  SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
270 
271  // Skip pseudo components, which have a reference starting with #. This mainly
272  // affects power symbols.
273  if( aIncludePowerSymbols || component->GetRef( this )[0] != wxT( '#' ) )
274  {
275  LIB_PART* part = component->GetPartRef().get();
276 
277  if( part || aForceIncludeOrphanComponents )
278  {
279  SCH_REFERENCE schReference( component, part, *this );
280 
281  schReference.SetSheetNumber( m_virtualPageNumber );
282  aReferences.AddItem( schReference );
283  }
284  }
285  }
286 }
287 
288 
290  bool aIncludePowerSymbols ) const
291 {
292  for( auto item : LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
293  {
294  auto component = static_cast<SCH_COMPONENT*>( item );
295 
296  // Skip pseudo components, which have a reference starting with #. This mainly
297  // affects power symbols.
298  if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) )
299  continue;
300 
301  LIB_PART* part = component->GetPartRef().get();
302 
303  if( part && part->GetUnitCount() > 1 )
304  {
305  SCH_REFERENCE schReference = SCH_REFERENCE( component, part, *this );
306  schReference.SetSheetNumber( m_virtualPageNumber );
307  wxString reference_str = schReference.GetRef();
308 
309  // Never lock unassigned references
310  if( reference_str[reference_str.Len() - 1] == '?' )
311  continue;
312 
313  aRefList[reference_str].AddItem( schReference );
314  }
315  }
316 }
317 
318 
320 {
321  return m_current_hash == d1.GetCurrentHash();
322 }
323 
324 
325 bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName, const wxString& aDestFileName )
326 {
327  auto pair = std::make_pair( aSrcFileName, aDestFileName );
328 
329  if( m_recursion_test_cache.count( pair ) )
330  return m_recursion_test_cache.at( pair );
331 
332  SCHEMATIC* sch = LastScreen()->Schematic();
333 
334  wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_PATH::TestForRecursion!" );
335 
336  wxFileName rootFn = sch->GetFileName();
337  wxFileName srcFn = aSrcFileName;
338  wxFileName destFn = aDestFileName;
339 
340  if( srcFn.IsRelative() )
341  srcFn.MakeAbsolute( rootFn.GetPath() );
342 
343  if( destFn.IsRelative() )
344  destFn.MakeAbsolute( rootFn.GetPath() );
345 
346 
347  // The source and destination sheet file names cannot be the same.
348  if( srcFn == destFn )
349  {
350  m_recursion_test_cache[pair] = true;
351  return true;
352  }
353 
357  unsigned i = 0;
358 
359  while( i < size() )
360  {
361  wxFileName cmpFn = at( i )->GetFileName();
362 
363  if( cmpFn.IsRelative() )
364  cmpFn.MakeAbsolute( rootFn.GetPath() );
365 
366  // Test if the file name of the destination sheet is in anywhere in this sheet path.
367  if( cmpFn == destFn )
368  break;
369 
370  i++;
371  }
372 
373  // The destination sheet file name was not found in the sheet path or the destination
374  // sheet file name is the root sheet so no recursion is possible.
375  if( i >= size() || i == 0 )
376  {
377  m_recursion_test_cache[pair] = false;
378  return false;
379  }
380 
381  // Walk back up to the root sheet to see if the source file name is already a parent in
382  // the sheet path. If so, recursion will occur.
383  do
384  {
385  i -= 1;
386 
387  wxFileName cmpFn = at( i )->GetFileName();
388 
389  if( cmpFn.IsRelative() )
390  cmpFn.MakeAbsolute( rootFn.GetPath() );
391 
392  if( cmpFn == srcFn )
393  {
394  m_recursion_test_cache[pair] = true;
395  return true;
396  }
397 
398  } while( i != 0 );
399 
400  // The source sheet file name is not a parent of the destination sheet file name.
401  m_recursion_test_cache[pair] = false;
402  return false;
403 }
404 
405 
407 {
408  SCH_SHEET* sheet = Last();
409 
410  wxCHECK( sheet, wxEmptyString );
411 
412  return sheet->GetPageNumber( *this );
413 }
414 
415 
416 void SCH_SHEET_PATH::SetPageNumber( const wxString& aPageNumber )
417 {
418  SCH_SHEET* sheet = Last();
419 
420  wxCHECK( sheet, /* void */ );
421 
422  sheet->SetPageNumber( *this, aPageNumber );
423 }
424 
425 
426 SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet, bool aCheckIntegrity )
427 {
428  if( aSheet != NULL )
429  {
430  BuildSheetList( aSheet, aCheckIntegrity );
432  }
433 }
434 
435 
436 void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity )
437 {
438  wxCHECK_RET( aSheet != NULL, wxT( "Cannot build sheet list from undefined sheet." ) );
439 
440  std::vector<SCH_SHEET*> badSheets;
441 
442  m_currentSheetPath.push_back( aSheet );
443  m_currentSheetPath.SetVirtualPageNumber( static_cast<int>( size() ) + 1 );
444  push_back( m_currentSheetPath );
445 
447  {
448  wxString parentFileName = aSheet->GetFileName();
449  std::vector<SCH_ITEM*> childSheets;
450  m_currentSheetPath.LastScreen()->GetSheets( &childSheets );
451 
452  for( SCH_ITEM* item : childSheets )
453  {
454  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
455 
456  if( aCheckIntegrity )
457  {
458  if( !m_currentSheetPath.TestForRecursion( sheet->GetFileName(), parentFileName ) )
459  BuildSheetList( sheet, true );
460  else
461  badSheets.push_back( sheet );
462  }
463  else
464  {
465  BuildSheetList( sheet, false );
466  }
467  }
468  }
469 
470  if( aCheckIntegrity )
471  {
472  for( SCH_SHEET* sheet : badSheets )
473  {
476  }
477  }
478 
480 }
481 
482 
483 void SCH_SHEET_LIST::SortByPageNumbers( bool aUpdateVirtualPageNums )
484 {
485  std::sort( begin(), end(),
486  []( SCH_SHEET_PATH a, SCH_SHEET_PATH b ) -> bool
487  {
488  wxString pageA = a.GetPageNumber();
489  wxString pageB = b.GetPageNumber();
490 
491  return SCH_SHEET::ComparePageNum( pageA, pageB ) < 0;
492  } );
493 
494  if( aUpdateVirtualPageNums )
495  {
496  int virtualPageNum = 1;
497 
498  for( SCH_SHEET_PATH& sheet : *this )
499  {
500  sheet.SetVirtualPageNumber( virtualPageNum++ );
501  }
502  }
503 }
504 
505 
506 bool SCH_SHEET_LIST::NameExists( const wxString& aSheetName )
507 {
508  for( const SCH_SHEET_PATH& sheet : *this )
509  {
510  if( sheet.Last()->GetName() == aSheetName )
511  return true;
512  }
513 
514  return false;
515 }
516 
517 
519 {
520  for( const SCH_SHEET_PATH& sheet : *this )
521  {
522  if( sheet.LastScreen() && sheet.LastScreen()->IsModify() )
523  return true;
524  }
525 
526  return false;
527 }
528 
529 
531 {
532  for( const SCH_SHEET_PATH& sheet : *this )
533  {
534  if( sheet.LastScreen() )
535  sheet.LastScreen()->ClrModify();
536  }
537 }
538 
539 
541 {
542  for( const SCH_SHEET_PATH& sheet : *this )
543  {
544  SCH_SCREEN* screen = sheet.LastScreen();
545 
546  for( SCH_ITEM* aItem : screen->Items() )
547  {
548  if( aItem->m_Uuid == aID )
549  {
550  if( aPathOut )
551  *aPathOut = sheet;
552 
553  return aItem;
554  }
555 
556  SCH_ITEM* childMatch = nullptr;
557 
558  aItem->RunOnChildren(
559  [&]( SCH_ITEM* aChild )
560  {
561  if( aChild->m_Uuid == aID )
562  childMatch = aChild;
563  } );
564 
565  if( childMatch )
566  {
567  if( aPathOut )
568  *aPathOut = sheet;
569 
570  return childMatch;
571  }
572  }
573  }
574 
575  // Not found; weak reference has been deleted.
577 }
578 
579 
580 void SCH_SHEET_LIST::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
581 {
582  for( const SCH_SHEET_PATH& sheet : *this )
583  {
584  SCH_SCREEN* screen = sheet.LastScreen();
585 
586  for( SCH_ITEM* aItem : screen->Items() )
587  {
588  aMap[ aItem->m_Uuid ] = aItem;
589 
590  aItem->RunOnChildren(
591  [&]( SCH_ITEM* aChild )
592  {
593  aMap[ aChild->m_Uuid ] = aChild;
594  } );
595  }
596  }
597 }
598 
599 
601 {
602  // List of reference for power symbols
603  SCH_REFERENCE_LIST references;
604 
605  // Map of locked components (not used, but needed by Annotate()
606  SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
607 
608  // Build the list of power components:
609  for( SCH_SHEET_PATH& sheet : *this )
610  {
611  for( auto item : sheet.LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
612  {
613  auto component = static_cast<SCH_COMPONENT*>( item );
614  LIB_PART* part = component->GetPartRef().get();
615 
616  if( !part || !part->IsPower() )
617  continue;
618 
619  if( part )
620  {
621  SCH_REFERENCE schReference( component, part, sheet );
622  references.AddItem( schReference );
623  }
624  }
625  }
626 
627  // Find duplicate, and silently clear annotation of duplicate
628  std::map<wxString, int> ref_list; // stores the existing references
629 
630  for( unsigned ii = 0; ii< references.GetCount(); ++ii )
631  {
632  wxString curr_ref = references[ii].GetRef();
633 
634  if( ref_list.find( curr_ref ) == ref_list.end() )
635  {
636  ref_list[curr_ref] = ii;
637  continue;
638  }
639 
640  // Possible duplicate, if the ref ends by a number:
641  if( curr_ref.Last() < '0' && curr_ref.Last() > '9' )
642  continue; // not annotated
643 
644  // Duplicate: clear annotation by removing the number ending the ref
645  while( curr_ref.Last() >= '0' && curr_ref.Last() <= '9' )
646  curr_ref.RemoveLast();
647 
648  references[ii].SetRef( curr_ref );
649  }
650 
651 
652  // Break full components reference in name (prefix) and number:
653  // example: IC1 become IC, and 1
654  references.SplitReferences();
655 
656  // Ensure all power symbols have the reference starting by '#'
657  // (No sure this is really useful)
658  for( unsigned ii = 0; ii< references.GetCount(); ++ii )
659  {
660  if( references[ii].GetRef()[0] != '#' )
661  {
662  wxString new_ref = "#" + references[ii].GetRef();
663  references[ii].SetRef( new_ref );
664  }
665  }
666 
667  // Recalculate and update reference numbers in schematic
668  references.Annotate( false, 0, 100, lockedComponents );
669  references.UpdateAnnotation();
670 }
671 
672 
673 void SCH_SHEET_LIST::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
674  bool aForceIncludeOrphanComponents ) const
675 {
676  for( const SCH_SHEET_PATH& sheet : *this )
677  sheet.GetSymbols( aReferences, aIncludePowerSymbols, aForceIncludeOrphanComponents );
678 }
679 
680 
682  bool aIncludePowerSymbols ) const
683 {
684  for( SCH_SHEET_PATHS::const_iterator it = begin(); it != end(); ++it )
685  {
687  (*it).GetMultiUnitComponents( tempMap );
688 
689  for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : tempMap )
690  {
691  // Merge this list into the main one
692  unsigned n_refs = pair.second.GetCount();
693 
694  for( unsigned thisRef = 0; thisRef < n_refs; ++thisRef )
695  {
696  aRefList[pair.first].AddItem( pair.second[thisRef] );
697  }
698  }
699  }
700 }
701 
702 
703 bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
704  const wxString& aDestFileName )
705 {
706  if( empty() )
707  return false;
708 
709  SCHEMATIC* sch = at( 0 ).LastScreen()->Schematic();
710 
711  wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_LIST::TestForRecursion!" );
712 
713  wxFileName rootFn = sch->GetFileName();
714  wxFileName destFn = aDestFileName;
715 
716  if( destFn.IsRelative() )
717  destFn.MakeAbsolute( rootFn.GetPath() );
718 
719  // Test each SCH_SHEET_PATH in this SCH_SHEET_LIST for potential recursion.
720  for( unsigned i = 0; i < size(); i++ )
721  {
722  // Test each SCH_SHEET_PATH in the source sheet.
723  for( unsigned j = 0; j < aSrcSheetHierarchy.size(); j++ )
724  {
725  const SCH_SHEET_PATH* sheetPath = &aSrcSheetHierarchy[j];
726 
727  for( unsigned k = 0; k < sheetPath->size(); k++ )
728  {
729  if( at( i ).TestForRecursion( sheetPath->GetSheet( k )->GetFileName(),
730  aDestFileName ) )
731  return true;
732  }
733  }
734  }
735 
736  // The source sheet file can safely be added to the destination sheet file.
737  return false;
738 }
739 
740 
742 {
743  for( SCH_SHEET_PATH& sheetpath : *this )
744  {
745  if( sheetpath.LastScreen() == aScreen )
746  return &sheetpath;
747  }
748 
749  return nullptr;
750 }
751 
752 
754  const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbolInstances )
755 {
756  SCH_REFERENCE_LIST symbolInstances;
757 
758  GetSymbols( symbolInstances, true, true );
759 
760  std::map<KIID_PATH, wxString> pathNameCache;
761 
762  // Calculating the name of a path is somewhat expensive; on large designs with many components
763  // this can blow up to a serious amount of time when loading the schematic
764  auto getName = [&pathNameCache]( const KIID_PATH& aPath ) -> const wxString&
765  {
766  if( pathNameCache.count( aPath ) )
767  return pathNameCache.at( aPath );
768 
769  pathNameCache[aPath] = aPath.AsString();
770  return pathNameCache[aPath];
771  };
772 
773  for( size_t i = 0; i < symbolInstances.GetCount(); i++ )
774  {
775  // The instance paths are stored in the file sans root path so the comparison
776  // should not include the root path.
777  wxString path = symbolInstances[i].GetPath();
778 
779  auto it = std::find_if( aSymbolInstances.begin(), aSymbolInstances.end(),
780  [ path, &getName ]( const SYMBOL_INSTANCE_REFERENCE& r ) -> bool
781  {
782  return path == getName( r.m_Path );
783  } );
784 
785  if( it == aSymbolInstances.end() )
786  {
787  wxLogTrace( traceSchSheetPaths, "No symbol instance found for path \"%s\"", path );
788  continue;
789  }
790 
791  SCH_COMPONENT* symbol = symbolInstances[ i ].GetSymbol();
792 
793  wxCHECK2( symbol, continue );
794 
795  // Symbol instance paths are stored and looked up in memory with the root path so use
796  // the full path here.
797  symbol->AddHierarchicalReference( symbolInstances[i].GetSheetPath().Path(),
798  it->m_Reference, it->m_Unit, it->m_Value,
799  it->m_Footprint );
800  symbol->GetField( REFERENCE_FIELD )->SetText( it->m_Reference );
801  }
802 }
803 
804 
805 void SCH_SHEET_LIST::UpdateSheetInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances )
806 {
807 
808  for( const SCH_SHEET_PATH& instance : *this )
809  {
810  auto it = std::find_if( aSheetInstances.begin(), aSheetInstances.end(),
811  [ instance ]( const SCH_SHEET_INSTANCE& r ) -> bool
812  {
813  return instance.PathWithoutRootUuid() == r.m_Path;
814  } );
815 
816  if( it == aSheetInstances.end() )
817  {
818  wxLogTrace( traceSchSheetPaths, "No sheet instance found for path \"%s\"",
819  instance.PathWithoutRootUuid().AsString() );
820  continue;
821  }
822 
823  SCH_SHEET* sheet = instance.Last();
824 
825  wxCHECK2( sheet, continue );
826 
827  sheet->AddInstance( instance.Path() );
828  sheet->SetPageNumber( instance, it->m_PageNumber );
829  }
830 }
831 
832 
833 std::vector<KIID_PATH> SCH_SHEET_LIST::GetPaths() const
834 {
835  std::vector<KIID_PATH> paths;
836 
837  for( const SCH_SHEET_PATH& sheetPath : *this )
838  paths.emplace_back( sheetPath.Path() );
839 
840  return paths;
841 }
842 
843 
844 void SCH_SHEET_LIST::ReplaceLegacySheetPaths( const std::vector<KIID_PATH>& aOldSheetPaths )
845 {
846  wxCHECK( size() == aOldSheetPaths.size(), /* void */ );
847 
848  for( size_t i = 0; i < size(); i++ )
849  {
850  const KIID_PATH oldSheetPath = aOldSheetPaths.at( i );
851  const KIID_PATH newSheetPath = at( i ).Path();
852  SCH_SCREEN* screen = at(i).LastScreen();
853 
854  wxCHECK( screen, /* void */ );
855 
856  for( SCH_ITEM* symbol : screen->Items().OfType( SCH_COMPONENT_T ) )
857  {
858  static_cast<SCH_COMPONENT*>( symbol )->ReplaceInstanceSheetPath( oldSheetPath,
859  newSheetPath );
860  }
861  }
862 }
863 
864 
866 {
867  for( const SCH_SHEET_PATH& instance : *this )
868  {
869  const SCH_SHEET* sheet = instance.Last();
870 
871  wxCHECK2( sheet, continue );
872 
873  if( !sheet->GetPageNumber( instance ).IsEmpty() )
874  return false;
875  }
876 
877  return true;
878 }
879 
880 
882 {
883  // Don't accidently renumber existing sheets.
884  wxCHECK( AllSheetPageNumbersEmpty(), /* void */ );
885 
886  wxString tmp;
887  int pageNumber = 1;
888 
889  for( const SCH_SHEET_PATH& instance : *this )
890  {
891  SCH_SHEET* sheet = instance.Last();
892 
893  wxCHECK2( sheet, continue );
894 
895  sheet->AddInstance( instance.Path() );
896  tmp.Printf( "%d", pageNumber );
897  sheet->SetPageNumber( instance, tmp );
898  pageNumber += 1;
899  }
900 }
void Move(const wxPoint &aMoveVector) override
Move the item by aMoveVector to a new position.
void SetSheetNumber(int aSheetNumber)
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:219
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
bool IsModified()
Check the entire hierarchy for any modifications.
const wxString & GetFileName() const
Definition: sch_screen.h:186
void initFromOther(const SCH_SHEET_PATH &aOther)
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:241
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
void UpdateUnit(int aUnit)
Change the unit number to aUnit without setting any internal flags.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Add a SCH_REFERENCE object to aReferences for each component in the list of sheets.
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr)
Fetch a SCH_ITEM by ID.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
Holds all the data relating to one schematic A schematic may consist of one or more sheets (and one r...
Definition: schematic.h:44
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
bool operator==(const SCH_SHEET_PATH &d1) const
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
wxString PathHumanReadable(bool aUseShortRootName=true) const
Return the sheet path in a human readable form made from thesheet names.
the 3d code uses this value
Definition: typeinfo.h:79
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
void AddItem(SCH_REFERENCE &aItem)
void GetSheets(std::vector< SCH_ITEM * > *aItems)
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
Definition: sch_screen.cpp:969
wxString AsString() const
Definition: kiid.cpp:213
Template specialization to enable wxStrings for certain containers (e.g. unordered_map)
Definition: bitmap.cpp:58
std::map< std::pair< wxString, wxString >, bool > m_recursion_test_cache
Page numbers are maintained by the sheet load order.
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
A singleton item of this class is returned for a weak reference that no longer exists.
static int ComparePageNum(const wxString &aPageNumberA, const wxString aPageNumberB)
Compares page numbers of schematic sheets.
Definition: sch_sheet.cpp:1125
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:119
void UpdateAllScreenReferences()
Update all the symbol references for this sheet path.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:285
wxString GetClass() const override
Return the class name.
SCH_SHEET_PATH * FindSheetForScreen(SCH_SCREEN *aScreen)
Return a pointer to the first SCH_SHEET_PATH object (not necessarily the only one) using a particular...
void SetPageNumber(const SCH_SHEET_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
Definition: sch_sheet.cpp:1110
void UpdateSheetInstances(const std::vector< SCH_SHEET_INSTANCE > &aSheetInstances)
Update all of the sheet instance information using aSheetInstances.
static void hash_combine(std::size_t &seed)
This is a dummy function to take the final case of hash_combine below.
Definition: hash_eda.h:64
void GetMultiUnitComponents(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the sh...
SCH_REFERENCE_LIST is used to create a flattened list of symbols because in a complex hierarchy,...
void Print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset) override
Print a schematic item.
Field Value of part, i.e. "3.3K".
void pop_back()
Forwarded method from std::vector.
const wxString GetFootprint(const SCH_SHEET_PATH *sheet, bool aResolve) const
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:270
wxString GetRef() const
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Fill an item cache for temporary use when many items need to be fetched.
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction)
Definition: sch_item.h:475
Definition: kiid.h:44
bool TestForRecursion(const SCH_SHEET_LIST &aSrcSheetHierarchy, const wxString &aDestFileName)
Test every SCH_SHEET_PATH in this SCH_SHEET_LIST to verify if adding the sheets stored in aSrcSheetHi...
void UpdateAnnotation()
function UpdateAnnotation Updates the symbol references for the schematic project (or the current she...
SCH_SHEET_PATH & operator=(const SCH_SHEET_PATH &aOther)
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
const wxString GetValue(const SCH_SHEET_PATH *sheet, bool aResolve) const
wxString GetName() const
Definition: sch_sheet.h:283
#define NULL
int GetUnitCount() const override
For items with units, return the number of units.
size_t size() const
Forwarded method from std::vector.
SCH_SHEET_PATH m_currentSheetPath
void SetVirtualPageNumber(int aPageNumber)
Set the sheet instance virtual page number.
std::vector< SCH_SHEET * > m_sheets
wxString GetPageNumber() const
size_t operator()(const SCH_SHEET_PATH &path) const
void Rotate(wxPoint aPosition) override
Rotate the item around aPosition 90 degrees in the clockwise direction.
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
Define a library symbol object.
A simple container for schematic symbol instance infromation.
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.
wxLogTrace helper definitions.
void SetPosition(const wxPoint &) override
bool IsModify() const
Definition: base_screen.h:63
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::unique_ptr< LIB_PART > & GetPartRef()
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:499
void UpdateSymbolInstances(const std::vector< SYMBOL_INSTANCE_REFERENCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
void MirrorX(int aXaxis_position) override
Mirror item relative to the X axis about aXaxis_position.
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Container to map reference designators for multi-unit parts.
KIID_PATH PathWithoutRootUuid() const
Get the sheet path as an KIID_PATH without the root sheet UUID prefix.
bool NameExists(const wxString &aSheetName)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:219
Field Name Module PCB, i.e. "16DIP300".
void MirrorY(int aYaxis_position) override
Mirror item relative to the Y axis about aYaxis_position.
const KIID m_Uuid
Definition: eda_item.h:523
unsigned GetCount() const
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
EDA_UNITS
Definition: eda_units.h:38
bool AllSheetPageNumbersEmpty() const
Check all of the sheet instance for empty page numbers.
A simple container for sheet instance infromation.
const SCH_SHEET * GetSheet(unsigned aIndex) const
bool IsPower() const
SCH_SCREEN * LastScreen()
static DELETED_SHEET_ITEM * GetInstance()
void SplitReferences()
Function SplitReferences attempts to split all reference designators into a name (U) and number (1).
#define _(s)
Definition: 3d_actions.cpp:33
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:89
SCH_SHEET_LIST(SCH_SHEET *aSheet=nullptr, bool aCheckIntegrity=false)
Construct a flattened list of SCH_SHEET_PATH objects from aSheet.
wxString AsString() const
Definition: kiid.cpp:245
size_t GetCurrentHash() const
EE_RTREE & Items()
Definition: sch_screen.h:159
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sorts the list of sheets by page number.
std::vector< KIID_PATH > GetPaths() const
void ReplaceLegacySheetPaths(const std::vector< KIID_PATH > &aOldSheetPaths)
Update all of the symbol sheet paths to the sheet paths defined in aOldSheetPaths.
void ClrModify()
Definition: base_screen.h:60
Schematic symbol object.
Definition: sch_component.h:79
static bool empty(const wxTextEntryBase *aCtrl)
bool empty() const
Forwarded method from std::vector.
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit, const wxString &aValue=wxEmptyString, const wxString &aFootprint=wxEmptyString)
Add a full hierarchical reference to this symbol.
Definition for part library class.
void SetModify()
Definition: base_screen.h:59
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
Field Reference of part, i.e. "IC21".
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
bool TestForRecursion(const wxString &aSrcFileName, const wxString &aDestFileName)
Test the SCH_SHEET_PATH file names to check adding the sheet stored in the file aSrcFileName to the s...
int Cmp(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare if this is the same sheet path as aSheetPathToTest.
void SetInitialPageNumbers()
Set initial sheet page numbers.
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
wxString GetPageNumber(const SCH_SHEET_PATH &aInstance) const
Return the sheet page number for aInstance.
Definition: sch_sheet.cpp:1092
SCH_REFERENCE is used as a helper to define a symbol's reference designator in a schematic.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Adds SCH_REFERENCE object to aReferences for each component in the sheet.
bool AddInstance(const KIID_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1068
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.