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-2021 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_symbol.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 MirrorHorizontally( int aCenter ) override {}
79  void MirrorVertically( int aCenter ) override {}
80  void Rotate( wxPoint aCenter ) 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* symbol = static_cast<SCH_COMPONENT*>( item );
255  symbol->GetField( REFERENCE_FIELD )->SetText( symbol->GetRef( this ) );
256  symbol->GetField( VALUE_FIELD )->SetText( symbol->GetValue( this, false ) );
257  symbol->GetField( FOOTPRINT_FIELD )->SetText( symbol->GetFootprint( this, false ) );
258  symbol->UpdateUnit( symbol->GetUnitSelection( this ) );
259  }
260 }
261 
262 
263 
264 void SCH_SHEET_PATH::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
265  bool aForceIncludeOrphanSymbols ) const
266 {
267  for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
268  {
269  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
270 
271  // Skip pseudo-symbols, which have a reference starting with #. This mainly
272  // affects power symbols.
273  if( aIncludePowerSymbols || symbol->GetRef( this )[0] != wxT( '#' ) )
274  {
275  LIB_PART* part = symbol->GetPartRef().get();
276 
277  if( part || aForceIncludeOrphanSymbols )
278  {
279  SCH_REFERENCE schReference( symbol, 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( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
293  {
294  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
295 
296  // Skip pseudo-symbols, which have a reference starting with #. This mainly
297  // affects power symbols.
298  if( !aIncludePowerSymbols && symbol->GetRef( this )[0] == wxT( '#' ) )
299  continue;
300 
301  LIB_PART* part = symbol->GetPartRef().get();
302 
303  if( part && part->GetUnitCount() > 1 )
304  {
305  SCH_REFERENCE schReference = SCH_REFERENCE( symbol, 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 ) const
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 
518 bool SCH_SHEET_LIST::PageNumberExists( const wxString& aPageNumber ) const
519 {
520  for( const SCH_SHEET_PATH& sheet : *this )
521  {
522  if( sheet.Last()->GetPageNumber( sheet ) == aPageNumber )
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() && sheet.LastScreen()->IsModify() )
535  return true;
536  }
537 
538  return false;
539 }
540 
541 
543 {
544  for( const SCH_SHEET_PATH& sheet : *this )
545  {
546  if( sheet.LastScreen() )
547  sheet.LastScreen()->ClrModify();
548  }
549 }
550 
551 
552 SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) const
553 {
554  for( const SCH_SHEET_PATH& sheet : *this )
555  {
556  SCH_SCREEN* screen = sheet.LastScreen();
557 
558  for( SCH_ITEM* aItem : screen->Items() )
559  {
560  if( aItem->m_Uuid == aID )
561  {
562  if( aPathOut )
563  *aPathOut = sheet;
564 
565  return aItem;
566  }
567 
568  SCH_ITEM* childMatch = nullptr;
569 
570  aItem->RunOnChildren(
571  [&]( SCH_ITEM* aChild )
572  {
573  if( aChild->m_Uuid == aID )
574  childMatch = aChild;
575  } );
576 
577  if( childMatch )
578  {
579  if( aPathOut )
580  *aPathOut = sheet;
581 
582  return childMatch;
583  }
584  }
585  }
586 
587  // Not found; weak reference has been deleted.
589 }
590 
591 
592 void SCH_SHEET_LIST::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
593 {
594  for( const SCH_SHEET_PATH& sheet : *this )
595  {
596  SCH_SCREEN* screen = sheet.LastScreen();
597 
598  for( SCH_ITEM* aItem : screen->Items() )
599  {
600  aMap[ aItem->m_Uuid ] = aItem;
601 
602  aItem->RunOnChildren(
603  [&]( SCH_ITEM* aChild )
604  {
605  aMap[ aChild->m_Uuid ] = aChild;
606  } );
607  }
608  }
609 }
610 
611 
613 {
614  // List of reference for power symbols
615  SCH_REFERENCE_LIST references;
616 
617  // Map of locked symbols (not used, but needed by Annotate()
618  SCH_MULTI_UNIT_REFERENCE_MAP lockedSymbols;
619 
620  // Build the list of power symbols:
621  for( SCH_SHEET_PATH& sheet : *this )
622  {
623  for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
624  {
625  SCH_COMPONENT* symbol = static_cast<SCH_COMPONENT*>( item );
626  LIB_PART* part = symbol->GetPartRef().get();
627 
628  if( part && part->IsPower() )
629  {
630  SCH_REFERENCE schReference( symbol, part, sheet );
631  references.AddItem( schReference );
632  }
633  }
634  }
635 
636  // Find duplicate, and silently clear annotation of duplicate
637  std::map<wxString, int> ref_list; // stores the existing references
638 
639  for( unsigned ii = 0; ii< references.GetCount(); ++ii )
640  {
641  wxString curr_ref = references[ii].GetRef();
642 
643  if( ref_list.find( curr_ref ) == ref_list.end() )
644  {
645  ref_list[curr_ref] = ii;
646  continue;
647  }
648 
649  // Possible duplicate, if the ref ends by a number:
650  if( curr_ref.Last() < '0' && curr_ref.Last() > '9' )
651  continue; // not annotated
652 
653  // Duplicate: clear annotation by removing the number ending the ref
654  while( curr_ref.Last() >= '0' && curr_ref.Last() <= '9' )
655  curr_ref.RemoveLast();
656 
657  references[ii].SetRef( curr_ref );
658  }
659 
660 
661  // Break full symbol reference into name (prefix) and number:
662  // example: IC1 become IC, and 1
663  references.SplitReferences();
664 
665  // Ensure all power symbols have the reference starting by '#'
666  // (Not sure this is really useful)
667  for( unsigned ii = 0; ii< references.GetCount(); ++ii )
668  {
669  if( references[ii].GetRef()[0] != '#' )
670  {
671  wxString new_ref = "#" + references[ii].GetRef();
672  references[ii].SetRef( new_ref );
673  }
674  }
675 
676  // Recalculate and update reference numbers in schematic
677  references.Annotate( false, 0, 100, lockedSymbols );
678  references.UpdateAnnotation();
679 }
680 
681 
682 void SCH_SHEET_LIST::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
683  bool aForceIncludeOrphanSymbols ) const
684 {
685  for( const SCH_SHEET_PATH& sheet : *this )
686  sheet.GetSymbols( aReferences, aIncludePowerSymbols, aForceIncludeOrphanSymbols );
687 }
688 
689 
691  bool aIncludePowerSymbols ) const
692 {
693  for( SCH_SHEET_PATHS::const_iterator it = begin(); it != end(); ++it )
694  {
696  ( *it ).GetMultiUnitSymbols( tempMap );
697 
698  for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : tempMap )
699  {
700  // Merge this list into the main one
701  unsigned n_refs = pair.second.GetCount();
702 
703  for( unsigned thisRef = 0; thisRef < n_refs; ++thisRef )
704  aRefList[pair.first].AddItem( pair.second[thisRef] );
705  }
706  }
707 }
708 
709 
710 bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
711  const wxString& aDestFileName )
712 {
713  if( empty() )
714  return false;
715 
716  SCHEMATIC* sch = at( 0 ).LastScreen()->Schematic();
717 
718  wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_LIST::TestForRecursion!" );
719 
720  wxFileName rootFn = sch->GetFileName();
721  wxFileName destFn = aDestFileName;
722 
723  if( destFn.IsRelative() )
724  destFn.MakeAbsolute( rootFn.GetPath() );
725 
726  // Test each SCH_SHEET_PATH in this SCH_SHEET_LIST for potential recursion.
727  for( unsigned i = 0; i < size(); i++ )
728  {
729  // Test each SCH_SHEET_PATH in the source sheet.
730  for( unsigned j = 0; j < aSrcSheetHierarchy.size(); j++ )
731  {
732  const SCH_SHEET_PATH* sheetPath = &aSrcSheetHierarchy[j];
733 
734  for( unsigned k = 0; k < sheetPath->size(); k++ )
735  {
736  if( at( i ).TestForRecursion( sheetPath->GetSheet( k )->GetFileName(),
737  aDestFileName ) )
738  {
739  return true;
740  }
741  }
742  }
743  }
744 
745  // The source sheet file can safely be added to the destination sheet file.
746  return false;
747 }
748 
749 
751 {
752  for( SCH_SHEET_PATH& sheetpath : *this )
753  {
754  if( sheetpath.LastScreen() == aScreen )
755  return &sheetpath;
756  }
757 
758  return nullptr;
759 }
760 
761 
763  const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbolInstances )
764 {
765  SCH_REFERENCE_LIST symbolInstances;
766 
767  GetSymbols( symbolInstances, true, true );
768 
769  std::map<KIID_PATH, wxString> pathNameCache;
770 
771  // Calculating the name of a path is somewhat expensive; on large designs with many components
772  // this can blow up to a serious amount of time when loading the schematic
773  auto getName = [&pathNameCache]( const KIID_PATH& aPath ) -> const wxString&
774  {
775  if( pathNameCache.count( aPath ) )
776  return pathNameCache.at( aPath );
777 
778  pathNameCache[aPath] = aPath.AsString();
779  return pathNameCache[aPath];
780  };
781 
782  for( size_t i = 0; i < symbolInstances.GetCount(); i++ )
783  {
784  // The instance paths are stored in the file sans root path so the comparison
785  // should not include the root path.
786  wxString path = symbolInstances[i].GetPath();
787 
788  auto it = std::find_if( aSymbolInstances.begin(), aSymbolInstances.end(),
789  [ path, &getName ]( const SYMBOL_INSTANCE_REFERENCE& r ) -> bool
790  {
791  return path == getName( r.m_Path );
792  } );
793 
794  if( it == aSymbolInstances.end() )
795  {
796  wxLogTrace( traceSchSheetPaths, "No symbol instance found for path \"%s\"", path );
797  continue;
798  }
799 
800  SCH_COMPONENT* symbol = symbolInstances[ i ].GetSymbol();
801 
802  wxCHECK2( symbol, continue );
803 
804  // Symbol instance paths are stored and looked up in memory with the root path so use
805  // the full path here.
806  symbol->AddHierarchicalReference( symbolInstances[i].GetSheetPath().Path(),
807  it->m_Reference, it->m_Unit, it->m_Value,
808  it->m_Footprint );
809  symbol->GetField( REFERENCE_FIELD )->SetText( it->m_Reference );
810  }
811 }
812 
813 
814 void SCH_SHEET_LIST::UpdateSheetInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances )
815 {
816 
817  for( const SCH_SHEET_PATH& instance : *this )
818  {
819  auto it = std::find_if( aSheetInstances.begin(), aSheetInstances.end(),
820  [ instance ]( const SCH_SHEET_INSTANCE& r ) -> bool
821  {
822  return instance.PathWithoutRootUuid() == r.m_Path;
823  } );
824 
825  if( it == aSheetInstances.end() )
826  {
827  wxLogTrace( traceSchSheetPaths, "No sheet instance found for path \"%s\"",
828  instance.PathWithoutRootUuid().AsString() );
829  continue;
830  }
831 
832  SCH_SHEET* sheet = instance.Last();
833 
834  wxCHECK2( sheet, continue );
835 
836  sheet->AddInstance( instance.Path() );
837  sheet->SetPageNumber( instance, it->m_PageNumber );
838  }
839 }
840 
841 
842 std::vector<KIID_PATH> SCH_SHEET_LIST::GetPaths() const
843 {
844  std::vector<KIID_PATH> paths;
845 
846  for( const SCH_SHEET_PATH& sheetPath : *this )
847  paths.emplace_back( sheetPath.Path() );
848 
849  return paths;
850 }
851 
852 
854 {
855  for( const SCH_SHEET_PATH& instance : *this )
856  {
857  const SCH_SHEET* sheet = instance.Last();
858 
859  wxCHECK2( sheet, continue );
860 
861  if( !sheet->GetPageNumber( instance ).IsEmpty() )
862  return false;
863  }
864 
865  return true;
866 }
867 
868 
870 {
871  // Don't accidently renumber existing sheets.
872  wxCHECK( AllSheetPageNumbersEmpty(), /* void */ );
873 
874  wxString tmp;
875  int pageNumber = 1;
876 
877  for( const SCH_SHEET_PATH& instance : *this )
878  {
879  SCH_SHEET* sheet = instance.Last();
880 
881  wxCHECK2( sheet, continue );
882 
883  sheet->AddInstance( instance.Path() );
884  tmp.Printf( "%d", pageNumber );
885  sheet->SetPageNumber( instance, tmp );
886  pageNumber += 1;
887  }
888 }
void Move(const wxPoint &aMoveVector) override
Move the item by aMoveVector to a new position.
Field Reference of part, i.e. "IC21".
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:216
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 sh...
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
const wxString & GetFileName() const
Definition: sch_screen.h:133
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:244
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.
Definition: sch_symbol.cpp:332
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:693
SCH_SHEET_PATH * FindSheetForScreen(const SCH_SCREEN *aScreen)
Return a pointer to the first SCH_SHEET_PATH object (not necessarily the only one) using a particular...
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.
Definition: schematic.h:59
void Rotate(wxPoint aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
bool IsModified() const
Check the entire hierarchy for any modifications.
bool operator==(const SCH_SHEET_PATH &d1) const
void GetSheets(std::vector< SCH_ITEM * > *aItems) const
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
Definition: sch_screen.cpp:941
bool PageNumberExists(const wxString &aPageNumber) 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 the sheet names.
the 3d code uses this value
Definition: typeinfo.h:79
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
wxString AsString() const
Definition: kiid.cpp:218
Definition: bitmap.cpp:63
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.
void AddItem(const SCH_REFERENCE &aItem)
static int ComparePageNum(const wxString &aPageNumberA, const wxString aPageNumberB)
Compares page numbers of schematic sheets.
Definition: sch_sheet.cpp:1150
void UpdateAllScreenReferences()
Update all the symbol references for this sheet path.
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:103
wxString GetClass() const override
Return the class name.
void SetPageNumber(const SCH_SHEET_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
Definition: sch_sheet.cpp:1135
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:67
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void Print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset) override
Print a schematic item.
void pop_back()
Forwarded method from std::vector.
const wxString GetFootprint(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific footprint assignment for the given sheet path.
Definition: sch_symbol.cpp:643
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:88
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:453
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()
Update the symbol references for the schematic project (or the current sheet).
SCH_SHEET_PATH & operator=(const SCH_SHEET_PATH &aOther)
Field Value of part, i.e. "3.3K".
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
const wxString GetValue(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific value for the given sheet path.
Definition: sch_symbol.cpp:593
wxString GetName() const
Definition: sch_sheet.h:101
#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 MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
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 BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
Define a library symbol object.
Definition: lib_symbol.h:93
bool NameExists(const wxString &aSheetName) const
A simple container for schematic symbol instance information.
void Annotate(bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap)
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
wxString GetFileName() const override
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:121
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()
Definition: sch_symbol.h:164
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:315
void UpdateSymbolInstances(const std::vector< SYMBOL_INSTANCE_REFERENCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
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.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
const KIID m_Uuid
Definition: eda_item.h:525
unsigned GetCount() const
EDA_UNITS
Definition: eda_units.h:38
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
bool AllSheetPageNumbersEmpty() const
Check all of the sheet instance for empty page numbers.
A simple container for sheet instance information.
const SCH_SHEET * GetSheet(unsigned aIndex) const
bool IsPower() const
Definition: lib_symbol.cpp:411
SCH_SCREEN * LastScreen()
static DELETED_SHEET_ITEM * GetInstance()
void SplitReferences()
Attempt 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:88
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:256
size_t GetCurrentHash() const
EE_RTREE & Items()
Definition: sch_screen.h:103
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Adds SCH_REFERENCE object to aReferences for each symbol in the sheet.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
std::vector< KIID_PATH > GetPaths() const
void ClrModify()
Definition: base_screen.h:60
Schematic symbol object.
Definition: sch_symbol.h:78
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: sch_symbol.cpp:391
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.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
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
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:551
wxString GetPageNumber(const SCH_SHEET_PATH &aInstance) const
Return the sheet page number for aInstance.
Definition: sch_sheet.cpp:1117
A helper to define a symbol's reference designator in a schematic.
bool AddInstance(const KIID_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1093
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
Field Name Module PCB, i.e. "16DIP300".