KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <[email protected]>
6 * Copyright (C) 1992-2023 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_label.h>
30#include <sch_reference_list.h>
31#include <symbol_library.h>
32#include <sch_sheet_path.h>
33#include <sch_symbol.h>
34#include <sch_sheet.h>
35#include <schematic.h>
36#include <template_fieldnames.h>
37#include <trace_helpers.h>
38
39#include <boost/functional/hash.hpp>
40#include <wx/filename.h>
41#include <wx/log.h>
42
43
49{
50public:
52 SCH_ITEM( nullptr, NOT_USED )
53 {}
54
55 wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const override
56 {
57 return _( "(Deleted Item)" );
58 }
59
60 wxString GetClass() const override
61 {
62 return wxT( "DELETED_SHEET_ITEM" );
63 }
64
66 {
67 static DELETED_SHEET_ITEM* item = nullptr;
68
69 if( !item )
70 item = new DELETED_SHEET_ITEM();
71
72 return item;
73 }
74
75 // pure virtuals:
76 void SetPosition( const VECTOR2I& ) override {}
77 void Move( const VECTOR2I& aMoveVector ) override {}
78 void MirrorHorizontally( int aCenter ) override {}
79 void MirrorVertically( int aCenter ) override {}
80 void Rotate( const VECTOR2I& aCenter, bool aRotateCCW ) override {}
81
82 double Similarity( const SCH_ITEM& aOther ) const override
83 {
84 return 0.0;
85 }
86
87 bool operator==( const SCH_ITEM& aOther ) const override
88 {
89 return false;
90 }
91
92#if defined(DEBUG)
93 void Show( int , std::ostream& ) const override {}
94#endif
95};
96
97namespace std
98{
99 size_t hash<SCH_SHEET_PATH>::operator()( const SCH_SHEET_PATH& path ) const
100 {
101 return path.GetCurrentHash();
102 }
103}
104
105
107{
109 m_current_hash = 0;
110}
111
112
114{
115 initFromOther( aOther );
116}
117
118
120{
121 initFromOther( aOther );
122 return *this;
123}
124
125
127{
128 SCH_SHEET_PATH retv = *this;
129
130 size_t size = aOther.size();
131
132 for( size_t i = 0; i < size; i++ )
133 retv.push_back( aOther.at( i ) );
134
135 return retv;
136}
137
138
140{
141 m_sheets = aOther.m_sheets;
145
146 // Note: don't copy m_recursion_test_cache as it is slow and we want std::vector<SCH_SHEET_PATH> to be
147 // very fast to construct for use in the connectivity algorithm.
148}
149
150
152{
153 // The root sheet path is empty. All other sheet paths must start with the root sheet path.
154 return ( m_sheets.size() == 0 ) || ( GetSheet( 0 )->IsRootSheet() );
155}
156
157
159{
160 m_current_hash = 0;
161
162 for( SCH_SHEET* sheet : m_sheets )
163 boost::hash_combine( m_current_hash, sheet->m_Uuid.Hash() );
164}
165
166
167int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
168{
169 if( size() > aSheetPathToTest.size() )
170 return 1;
171
172 if( size() < aSheetPathToTest.size() )
173 return -1;
174
175 //otherwise, same number of sheets.
176 for( unsigned i = 0; i < size(); i++ )
177 {
178 if( at( i )->m_Uuid < aSheetPathToTest.at( i )->m_Uuid )
179 return -1;
180
181 if( at( i )->m_Uuid != aSheetPathToTest.at( i )->m_Uuid )
182 return 1;
183 }
184
185 return 0;
186}
187
188
189int SCH_SHEET_PATH::ComparePageNum( const SCH_SHEET_PATH& aSheetPathToTest ) const
190{
191 wxString pageA = this->GetPageNumber();
192 wxString pageB = aSheetPathToTest.GetPageNumber();
193
194 int pageNumComp = SCH_SHEET::ComparePageNum( pageA, pageB );
195
196 if( pageNumComp == 0 )
197 {
198 int virtualPageA = GetVirtualPageNumber();
199 int virtualPageB = aSheetPathToTest.GetVirtualPageNumber();
200
201 if( virtualPageA > virtualPageB )
202 pageNumComp = 1;
203 else if( virtualPageA < virtualPageB )
204 pageNumComp = -1;
205 }
206
207 return pageNumComp;
208}
209
210
211bool SCH_SHEET_PATH::IsContainedWithin( const SCH_SHEET_PATH& aSheetPathToTest ) const
212{
213 if( aSheetPathToTest.size() > size() )
214 return false;
215
216 for( size_t i = 0; i < aSheetPathToTest.size(); ++i )
217 {
218 if( at( i )->m_Uuid != aSheetPathToTest.at( i )->m_Uuid )
219 {
220 wxLogTrace( traceSchSheetPaths, "Sheet path '%s' is not within path '%s'.",
221 aSheetPathToTest.Path().AsString(), Path().AsString() );
222
223 return false;
224 }
225 }
226
227 wxLogTrace( traceSchSheetPaths, "Sheet path '%s' is within path '%s'.",
228 aSheetPathToTest.Path().AsString(), Path().AsString() );
229
230 return true;
231}
232
233
235{
236 if( !empty() )
237 return m_sheets.back();
238
239 return nullptr;
240}
241
242
244{
245 SCH_SHEET* lastSheet = Last();
246
247 if( lastSheet )
248 return lastSheet->GetScreen();
249
250 return nullptr;
251}
252
253
255{
256 SCH_SHEET* lastSheet = Last();
257
258 if( lastSheet )
259 return lastSheet->GetScreen();
260
261 return nullptr;
262}
263
264
266{
267 for( SCH_SHEET* sheet : m_sheets )
268 {
269 if( sheet->GetExcludedFromSim() )
270 return true;
271 }
272
273 return false;
274}
275
276
278{
279 for( SCH_SHEET* sheet : m_sheets )
280 {
281 if( sheet->GetExcludedFromBOM() )
282 return true;
283 }
284
285 return false;
286}
287
288
290{
291 for( SCH_SHEET* sheet : m_sheets )
292 {
293 if( sheet->GetExcludedFromBoard() )
294 return true;
295 }
296
297 return false;
298}
299
300
302{
303 for( SCH_SHEET* sheet : m_sheets )
304 {
305 if( sheet->GetDNP() )
306 return true;
307 }
308
309 return false;
310}
311
312
314{
315 wxString s;
316
317 s = wxT( "/" ); // This is the root path
318
319 // Start at 1 to avoid the root sheet, which does not need to be added to the path.
320 // Its timestamp changes anyway.
321 for( unsigned i = 1; i < size(); i++ )
322 s += at( i )->m_Uuid.AsString() + "/";
323
324 return s;
325}
326
327
329{
331 path.reserve( m_sheets.size() );
332
333 for( const SCH_SHEET* sheet : m_sheets )
334 path.push_back( sheet->m_Uuid );
335
336 return path;
337}
338
339
340wxString SCH_SHEET_PATH::PathHumanReadable( bool aUseShortRootName,
341 bool aStripTrailingSeparator ) const
342{
343 wxString s;
344
345 if( aUseShortRootName )
346 {
347 s = wxS( "/" ); // Use only the short name in netlists
348 }
349 else
350 {
351 wxString fileName;
352
353 if( !empty() && at( 0 )->GetScreen() )
354 fileName = at( 0 )->GetScreen()->GetFileName();
355
356 wxFileName fn = fileName;
357
358 s = fn.GetName() + wxS( "/" );
359 }
360
361 // Start at 1 since we've already processed the root sheet.
362 for( unsigned i = 1; i < size(); i++ )
363 s << at( i )->GetFields()[SHEETNAME].GetShownText( false ) << wxS( "/" );
364
365 if( aStripTrailingSeparator && s.EndsWith( "/" ) )
366 s = s.Left( s.length() - 1 );
367
368 return s;
369}
370
371
373{
374 std::vector<SCH_ITEM*> items;
375
376 std::copy_if( LastScreen()->Items().begin(), LastScreen()->Items().end(),
377 std::back_inserter( items ),
378 []( SCH_ITEM* aItem )
379 {
380 return ( aItem->Type() == SCH_SYMBOL_T || aItem->Type() == SCH_GLOBAL_LABEL_T );
381 } );
382
383 for( SCH_ITEM* item : items )
384 {
385 if( item->Type() == SCH_SYMBOL_T )
386 {
387 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
388
389 symbol->GetField( REFERENCE_FIELD )->SetText( symbol->GetRef( this ) );
390 symbol->SetUnit( symbol->GetUnitSelection( this ) );
391 LastScreen()->Update( item, false );
392 }
393 else if( item->Type() == SCH_GLOBAL_LABEL_T )
394 {
395 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( item );
396
397 if( label->GetFields().size() > 0 ) // Possible when reading a legacy .sch schematic
398 {
399 SCH_FIELD& intersheetRefs = label->GetFields()[0];
400
401 // Fixup for legacy files which didn't store a position for the intersheet refs
402 // unless they were shown.
403 if( label->GetFields().size() == 1
404 && intersheetRefs.GetInternalName() == wxT( "Intersheet References" )
405 && intersheetRefs.GetPosition() == VECTOR2I( 0, 0 )
406 && !intersheetRefs.IsVisible() )
407 {
408 label->AutoplaceFields( LastScreen(), false );
409 }
410
411 intersheetRefs.SetVisible( label->Schematic()->Settings().m_IntersheetRefsShow );
412 LastScreen()->Update( &intersheetRefs );
413 }
414 }
415 }
416}
417
418
419
420void SCH_SHEET_PATH::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
421 bool aForceIncludeOrphanSymbols ) const
422{
423 for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
424 {
425 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
426 AppendSymbol( aReferences, symbol, aIncludePowerSymbols, aForceIncludeOrphanSymbols );
427 }
428}
429
430
432 bool aIncludePowerSymbols,
433 bool aForceIncludeOrphanSymbols ) const
434{
435 // Skip pseudo-symbols, which have a reference starting with #. This mainly
436 // affects power symbols.
437 if( aIncludePowerSymbols || aSymbol->GetRef( this )[0] != wxT( '#' ) )
438 {
439 if( aSymbol->GetLibSymbolRef() || aForceIncludeOrphanSymbols )
440 {
441 SCH_REFERENCE schReference( aSymbol, *this );
442
443 schReference.SetSheetNumber( m_virtualPageNumber );
444 aReferences.AddItem( schReference );
445 }
446 }
447}
448
449
451 bool aIncludePowerSymbols ) const
452{
453 for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
454 {
455 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
456 AppendMultiUnitSymbol( aRefList, symbol, aIncludePowerSymbols );
457 }
458}
459
460
462 SCH_SYMBOL* aSymbol,
463 bool aIncludePowerSymbols ) const
464{
465 // Skip pseudo-symbols, which have a reference starting with #. This mainly
466 // affects power symbols.
467 if( !aIncludePowerSymbols && aSymbol->GetRef( this )[0] == wxT( '#' ) )
468 return;
469
470 LIB_SYMBOL* symbol = aSymbol->GetLibSymbolRef().get();
471
472 if( symbol && symbol->GetUnitCount() > 1 )
473 {
474 SCH_REFERENCE schReference = SCH_REFERENCE( aSymbol, *this );
475 schReference.SetSheetNumber( m_virtualPageNumber );
476 wxString reference_str = schReference.GetRef();
477
478 // Never lock unassigned references
479 if( reference_str[reference_str.Len() - 1] == '?' )
480 return;
481
482 aRefList[reference_str].AddItem( schReference );
483 }
484}
485
486
488{
489 return m_current_hash == d1.GetCurrentHash();
490}
491
492
493bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName, const wxString& aDestFileName )
494{
495 auto pair = std::make_pair( aSrcFileName, aDestFileName );
496
497 if( m_recursion_test_cache.count( pair ) )
498 return m_recursion_test_cache.at( pair );
499
500 SCHEMATIC* sch = LastScreen()->Schematic();
501
502 wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_PATH::TestForRecursion!" );
503
504 wxFileName rootFn = sch->GetFileName();
505 wxFileName srcFn = aSrcFileName;
506 wxFileName destFn = aDestFileName;
507
508 if( srcFn.IsRelative() )
509 srcFn.MakeAbsolute( rootFn.GetPath() );
510
511 if( destFn.IsRelative() )
512 destFn.MakeAbsolute( rootFn.GetPath() );
513
514 // The source and destination sheet file names cannot be the same.
515 if( srcFn == destFn )
516 {
517 m_recursion_test_cache[pair] = true;
518 return true;
519 }
520
524 unsigned i = 0;
525
526 while( i < size() )
527 {
528 wxFileName cmpFn = at( i )->GetFileName();
529
530 if( cmpFn.IsRelative() )
531 cmpFn.MakeAbsolute( rootFn.GetPath() );
532
533 // Test if the file name of the destination sheet is in anywhere in this sheet path.
534 if( cmpFn == destFn )
535 break;
536
537 i++;
538 }
539
540 // The destination sheet file name was not found in the sheet path or the destination
541 // sheet file name is the root sheet so no recursion is possible.
542 if( i >= size() || i == 0 )
543 {
544 m_recursion_test_cache[pair] = false;
545 return false;
546 }
547
548 // Walk back up to the root sheet to see if the source file name is already a parent in
549 // the sheet path. If so, recursion will occur.
550 do
551 {
552 i -= 1;
553
554 wxFileName cmpFn = at( i )->GetFileName();
555
556 if( cmpFn.IsRelative() )
557 cmpFn.MakeAbsolute( rootFn.GetPath() );
558
559 if( cmpFn == srcFn )
560 {
561 m_recursion_test_cache[pair] = true;
562 return true;
563 }
564
565 } while( i != 0 );
566
567 // The source sheet file name is not a parent of the destination sheet file name.
568 m_recursion_test_cache[pair] = false;
569 return false;
570}
571
572
574{
575 SCH_SHEET* sheet = Last();
576
577 wxCHECK( sheet, wxEmptyString );
578
579 KIID_PATH tmpPath = Path();
580 tmpPath.pop_back();
581
582 return sheet->getPageNumber( tmpPath );
583}
584
585
586void SCH_SHEET_PATH::SetPageNumber( const wxString& aPageNumber )
587{
588 SCH_SHEET* sheet = Last();
589
590 wxCHECK( sheet, /* void */ );
591
592 KIID_PATH tmpPath = Path();
593
594 tmpPath.pop_back();
595
596 sheet->addInstance( tmpPath );
597 sheet->setPageNumber( tmpPath, aPageNumber );
598}
599
600
602 const wxString& aProjectName )
603{
604 wxCHECK( !aProjectName.IsEmpty(), /* void */ );
605
606 SCH_SHEET_PATH newSheetPath( aPrefixSheetPath );
607 SCH_SHEET_PATH currentSheetPath( *this );
608
609 // Prefix the new hierarchical path.
610 newSheetPath = newSheetPath + currentSheetPath;
611
612 for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
613 {
614 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
615
616 wxCHECK2( symbol, continue );
617
618 SCH_SYMBOL_INSTANCE newSymbolInstance;
619
620 if( symbol->GetInstance( newSymbolInstance, Path(), true ) )
621 {
622 newSymbolInstance.m_ProjectName = aProjectName;
623 // Use an existing symbol instance for this path if it exists.
624
625 newSymbolInstance.m_Path = newSheetPath.Path();
626 symbol->AddHierarchicalReference( newSymbolInstance );
627 }
628 else if( !symbol->GetInstances().empty() )
629 {
630 newSymbolInstance.m_ProjectName = aProjectName;
631
632 // Use the first symbol instance if any symbol instance data exists.
633 newSymbolInstance = symbol->GetInstances()[0];
634 newSymbolInstance.m_Path = newSheetPath.Path();
635 symbol->AddHierarchicalReference( newSymbolInstance );
636 }
637 else
638 {
639 newSymbolInstance.m_ProjectName = aProjectName;
640
641 // Fall back to the last saved symbol field and unit settings if there is no
642 // instance data.
643 newSymbolInstance.m_Path = newSheetPath.Path();
644 newSymbolInstance.m_Reference = symbol->GetField( REFERENCE_FIELD )->GetText();
645 newSymbolInstance.m_Unit = symbol->GetUnit();
646 symbol->AddHierarchicalReference( newSymbolInstance );
647 }
648 }
649}
650
651
653{
654 for( SCH_ITEM* item : LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
655 {
656 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
657
658 wxCHECK2( symbol, continue );
659
660 SCH_SHEET_PATH fullSheetPath( aPrefixSheetPath );
661 SCH_SHEET_PATH currentSheetPath( *this );
662
663 // Prefix the hierarchical path of the symbol instance to be removed.
664 fullSheetPath = fullSheetPath + currentSheetPath;
665 symbol->RemoveInstance( fullSheetPath );
666 }
667}
668
669
671{
672 wxCHECK( m_sheets.size() > 1, /* void */ );
673
674 wxFileName sheetFileName = Last()->GetFileName();
675
676 // If the sheet file name is absolute, then the user requested is so don't make it relative.
677 if( sheetFileName.IsAbsolute() )
678 return;
679
680 SCH_SCREEN* screen = LastScreen();
681 SCH_SCREEN* parentScreen = m_sheets[ m_sheets.size() - 2 ]->GetScreen();
682
683 wxCHECK( screen && parentScreen, /* void */ );
684
685 wxFileName fileName = screen->GetFileName();
686 wxFileName parentFileName = parentScreen->GetFileName();
687
688 // SCH_SCREEN file names must be absolute. If they are not, someone set them incorrectly
689 // on load or on creation.
690 wxCHECK( fileName.IsAbsolute() && parentFileName.IsAbsolute(), /* void */ );
691
692 if( fileName.GetPath() == parentFileName.GetPath() )
693 {
694 Last()->SetFileName( fileName.GetFullName() );
695 }
696 else if( fileName.MakeRelativeTo( parentFileName.GetPath() ) )
697 {
698 Last()->SetFileName( fileName.GetFullPath() );
699 }
700 else
701 {
702 Last()->SetFileName( screen->GetFileName() );
703 }
704
705 wxLogTrace( tracePathsAndFiles,
706 wxT( "\n File name: '%s'"
707 "\n parent file name '%s',"
708 "\n sheet '%s' file name '%s'." ),
709 screen->GetFileName(), parentScreen->GetFileName(), PathHumanReadable(),
710 Last()->GetFileName() );
711}
712
713
715{
716 if( aSheet != nullptr )
717 BuildSheetList( aSheet, false );
718}
719
720
721void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity )
722{
723 wxCHECK_RET( aSheet != nullptr, wxT( "Cannot build sheet list from undefined sheet." ) );
724
725 std::vector<SCH_SHEET*> badSheets;
726
728 m_currentSheetPath.SetVirtualPageNumber( static_cast<int>( size() ) + 1 );
729 push_back( m_currentSheetPath );
730
732 {
733 wxString parentFileName = aSheet->GetFileName();
734 std::vector<SCH_ITEM*> childSheets;
735 m_currentSheetPath.LastScreen()->GetSheets( &childSheets );
736
737 for( SCH_ITEM* item : childSheets )
738 {
739 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
740
741 if( aCheckIntegrity )
742 {
743 if( !m_currentSheetPath.TestForRecursion( sheet->GetFileName(), parentFileName ) )
744 BuildSheetList( sheet, true );
745 else
746 badSheets.push_back( sheet );
747 }
748 else
749 {
750 // If we are not performing a full recursion test, at least check if we are in
751 // a simple recursion scenario to prevent stack overflow crashes
752 wxCHECK2_MSG( sheet->GetFileName() != aSheet->GetFileName(), continue,
753 wxT( "Recursion prevented in SCH_SHEET_LIST::BuildSheetList" ) );
754
755 BuildSheetList( sheet, false );
756 }
757 }
758 }
759
760 if( aCheckIntegrity )
761 {
762 for( SCH_SHEET* sheet : badSheets )
763 {
766 }
767 }
768
770}
771
772
773void SCH_SHEET_LIST::SortByPageNumbers( bool aUpdateVirtualPageNums )
774{
775 for( const SCH_SHEET_PATH& path : *this )
776 path.CachePageNumber();
777
778 std::sort( begin(), end(),
779 []( const SCH_SHEET_PATH& a, const SCH_SHEET_PATH& b ) -> bool
780 {
783
784 if( retval < 0 )
785 return true;
786 else if( retval > 0 )
787 return false;
788
790 return true;
791 else if( a.GetVirtualPageNumber() > b.GetVirtualPageNumber() )
792 return false;
793
795 return a.GetCurrentHash() < b.GetCurrentHash();
796 } );
797
798 if( aUpdateVirtualPageNums )
799 {
800 int virtualPageNum = 1;
801
802 for( SCH_SHEET_PATH& sheet : *this )
803 sheet.SetVirtualPageNumber( virtualPageNum++ );
804 }
805}
806
807
808bool SCH_SHEET_LIST::NameExists( const wxString& aSheetName ) const
809{
810 for( const SCH_SHEET_PATH& sheet : *this )
811 {
812 if( sheet.Last()->GetName() == aSheetName )
813 return true;
814 }
815
816 return false;
817}
818
819
820bool SCH_SHEET_LIST::PageNumberExists( const wxString& aPageNumber ) const
821{
822 for( const SCH_SHEET_PATH& sheet : *this )
823 {
824 if( sheet.GetPageNumber() == aPageNumber )
825 return true;
826 }
827
828 return false;
829}
830
831
832void SCH_SHEET_LIST::TrimToPageNumbers( const std::vector<wxString>& aPageInclusions )
833{
834 auto it = std::remove_if( begin(), end(),
835 [&]( SCH_SHEET_PATH sheet )
836 {
837 return std::find( aPageInclusions.begin(), aPageInclusions.end(),
838 sheet.GetPageNumber() )
839 == aPageInclusions.end();
840 } );
841
842 erase( it, end() );
843}
844
845
847{
848 for( const SCH_SHEET_PATH& sheet : *this )
849 {
850 if( sheet.LastScreen() && sheet.LastScreen()->IsContentModified() )
851 return true;
852 }
853
854 return false;
855}
856
857
859{
860 for( const SCH_SHEET_PATH& sheet : *this )
861 {
862 if( sheet.LastScreen() )
863 sheet.LastScreen()->SetContentModified( false );
864 }
865}
866
867
869{
870 for( const SCH_SHEET_PATH& sheet : *this )
871 {
872 SCH_ITEM* item = sheet.GetItem( aID );
873
874 if( item )
875 {
876 if( aPathOut )
877 *aPathOut = sheet;
878
879 return item;
880 }
881 }
882
883 // Not found; weak reference has been deleted.
885}
886
887
889{
890 for( SCH_ITEM* aItem : LastScreen()->Items() )
891 {
892 if( aItem->m_Uuid == aID )
893 return aItem;
894
895 SCH_ITEM* childMatch = nullptr;
896
897 aItem->RunOnChildren(
898 [&]( SCH_ITEM* aChild )
899 {
900 if( aChild->m_Uuid == aID )
901 childMatch = aChild;
902 } );
903
904 if( childMatch )
905 return childMatch;
906 }
907
908 return nullptr;
909}
910
911
912void SCH_SHEET_LIST::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
913{
914 for( const SCH_SHEET_PATH& sheet : *this )
915 {
916 SCH_SCREEN* screen = sheet.LastScreen();
917
918 for( SCH_ITEM* aItem : screen->Items() )
919 {
920 aMap[ aItem->m_Uuid ] = aItem;
921
922 aItem->RunOnChildren(
923 [&]( SCH_ITEM* aChild )
924 {
925 aMap[ aChild->m_Uuid ] = aChild;
926 } );
927 }
928 }
929}
930
931
933{
934 // List of reference for power symbols
935 SCH_REFERENCE_LIST references;
936 SCH_REFERENCE_LIST additionalreferences; // Todo: add as a parameter to this function
937
938 // Map of locked symbols (not used, but needed by Annotate()
939 SCH_MULTI_UNIT_REFERENCE_MAP lockedSymbols;
940
941 // Build the list of power symbols:
942 for( SCH_SHEET_PATH& sheet : *this )
943 {
944 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
945 {
946 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
947 LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get();
948
949 if( libSymbol && libSymbol->IsPower() )
950 {
951 SCH_REFERENCE schReference( symbol, sheet );
952 references.AddItem( schReference );
953 }
954 }
955 }
956
957 // Find duplicate, and silently clear annotation of duplicate
958 std::map<wxString, int> ref_list; // stores the existing references
959
960 for( unsigned ii = 0; ii< references.GetCount(); ++ii )
961 {
962 wxString curr_ref = references[ii].GetRef();
963
964 if( ref_list.find( curr_ref ) == ref_list.end() )
965 {
966 ref_list[curr_ref] = ii;
967 continue;
968 }
969
970 // Possible duplicate, if the ref ends by a number:
971 if( curr_ref.Last() < '0' && curr_ref.Last() > '9' )
972 continue; // not annotated
973
974 // Duplicate: clear annotation by removing the number ending the ref
975 while( curr_ref.Last() >= '0' && curr_ref.Last() <= '9' )
976 curr_ref.RemoveLast();
977
978 references[ii].SetRef( curr_ref );
979 }
980
981 // Break full symbol reference into name (prefix) and number:
982 // example: IC1 become IC, and 1
983 references.SplitReferences();
984
985 // Ensure all power symbols have the reference starting by '#'
986 // (Not sure this is really useful)
987 for( unsigned ii = 0; ii< references.GetCount(); ++ii )
988 {
989 if( references[ii].GetRef()[0] != '#' )
990 {
991 wxString new_ref = "#" + references[ii].GetRef();
992 references[ii].SetRef( new_ref );
993 }
994 }
995
996 // Recalculate and update reference numbers in schematic
997 references.Annotate( false, 0, 100, lockedSymbols, additionalreferences );
998 references.UpdateAnnotation();
999}
1000
1001
1002void SCH_SHEET_LIST::GetSymbols( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols,
1003 bool aForceIncludeOrphanSymbols ) const
1004{
1005 for( const SCH_SHEET_PATH& sheet : *this )
1006 sheet.GetSymbols( aReferences, aIncludePowerSymbols, aForceIncludeOrphanSymbols );
1007}
1008
1009
1011 const SCH_SHEET_PATH& aSheetPath,
1012 bool aIncludePowerSymbols,
1013 bool aForceIncludeOrphanSymbols ) const
1014{
1015 for( const SCH_SHEET_PATH& sheet : *this )
1016 {
1017 if( sheet.IsContainedWithin( aSheetPath ) )
1018 sheet.GetSymbols( aReferences, aIncludePowerSymbols, aForceIncludeOrphanSymbols );
1019 }
1020}
1021
1022
1023void SCH_SHEET_LIST::GetSheetsWithinPath( std::vector<SCH_SHEET_PATH>& aSheets,
1024 const SCH_SHEET_PATH& aSheetPath ) const
1025{
1026 for( const SCH_SHEET_PATH& sheet : *this )
1027 {
1028 if( sheet.IsContainedWithin( aSheetPath ) )
1029 aSheets.push_back( sheet );
1030 }
1031}
1032
1033
1034std::optional<SCH_SHEET_PATH> SCH_SHEET_LIST::GetSheetPathByKIIDPath( const KIID_PATH& aPath,
1035 bool aIncludeLastSheet ) const
1036{
1037 for( const SCH_SHEET_PATH& sheet : *this )
1038 {
1039 KIID_PATH testPath = sheet.Path();
1040
1041 if( !aIncludeLastSheet )
1042 testPath.pop_back();
1043
1044 if( testPath == aPath )
1045 return SCH_SHEET_PATH( sheet );
1046 }
1047
1048 return std::nullopt;
1049}
1050
1051
1053 bool aIncludePowerSymbols ) const
1054{
1055 for( auto it = begin(); it != end(); ++it )
1056 {
1058 ( *it ).GetMultiUnitSymbols( tempMap, aIncludePowerSymbols );
1059
1060 for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : tempMap )
1061 {
1062 // Merge this list into the main one
1063 unsigned n_refs = pair.second.GetCount();
1064
1065 for( unsigned thisRef = 0; thisRef < n_refs; ++thisRef )
1066 aRefList[pair.first].AddItem( pair.second[thisRef] );
1067 }
1068 }
1069}
1070
1071
1072bool SCH_SHEET_LIST::TestForRecursion( const SCH_SHEET_LIST& aSrcSheetHierarchy,
1073 const wxString& aDestFileName )
1074{
1075 if( empty() )
1076 return false;
1077
1078 SCHEMATIC* sch = at( 0 ).LastScreen()->Schematic();
1079
1080 wxCHECK_MSG( sch, false, "No SCHEMATIC found in SCH_SHEET_LIST::TestForRecursion!" );
1081
1082 wxFileName rootFn = sch->GetFileName();
1083 wxFileName destFn = aDestFileName;
1084
1085 if( destFn.IsRelative() )
1086 destFn.MakeAbsolute( rootFn.GetPath() );
1087
1088 // Test each SCH_SHEET_PATH in this SCH_SHEET_LIST for potential recursion.
1089 for( unsigned i = 0; i < size(); i++ )
1090 {
1091 // Test each SCH_SHEET_PATH in the source sheet.
1092 for( unsigned j = 0; j < aSrcSheetHierarchy.size(); j++ )
1093 {
1094 const SCH_SHEET_PATH* sheetPath = &aSrcSheetHierarchy[j];
1095
1096 for( unsigned k = 0; k < sheetPath->size(); k++ )
1097 {
1098 if( at( i ).TestForRecursion( sheetPath->GetSheet( k )->GetFileName(),
1099 aDestFileName ) )
1100 {
1101 return true;
1102 }
1103 }
1104 }
1105 }
1106
1107 // The source sheet file can safely be added to the destination sheet file.
1108 return false;
1109}
1110
1111
1113{
1114 for( SCH_SHEET_PATH& path : *this )
1115 {
1116 if( path.Path() == aPath->Path() )
1117 return &path;
1118 }
1119
1120 return nullptr;
1121}
1122
1123
1125{
1126 for( SCH_SHEET_PATH& sheetpath : *this )
1127 {
1128 if( sheetpath.LastScreen() == aScreen )
1129 return sheetpath;
1130 }
1131
1132 return SCH_SHEET_PATH();
1133}
1134
1135
1137{
1138 SCH_SHEET_LIST retval;
1139
1140 for( const SCH_SHEET_PATH& sheetpath : *this )
1141 {
1142 if( sheetpath.LastScreen() == aScreen )
1143 retval.push_back( sheetpath );
1144 }
1145
1146 return retval;
1147}
1148
1149
1151 const std::vector<SCH_SYMBOL_INSTANCE>& aSymbolInstances )
1152{
1153 for( SCH_SHEET_PATH& sheetPath : *this )
1154 {
1155 for( SCH_ITEM* item : sheetPath.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
1156 {
1157 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1158
1159 wxCHECK2( symbol, continue );
1160
1161 KIID_PATH sheetPathWithSymbolUuid = sheetPath.Path();
1162 sheetPathWithSymbolUuid.push_back( symbol->m_Uuid );
1163
1164 auto it = std::find_if( aSymbolInstances.begin(), aSymbolInstances.end(),
1165 [ sheetPathWithSymbolUuid ]( const SCH_SYMBOL_INSTANCE& r ) -> bool
1166 {
1167 return sheetPathWithSymbolUuid == r.m_Path;
1168 } );
1169
1170 if( it == aSymbolInstances.end() )
1171 {
1172 wxLogTrace( traceSchSheetPaths, "No symbol instance found for symbol '%s'",
1173 sheetPathWithSymbolUuid.AsString() );
1174 continue;
1175 }
1176
1177 // Symbol instance paths are stored and looked up in memory with the root path so use
1178 // the full path here.
1179 symbol->AddHierarchicalReference( sheetPath.Path(), it->m_Reference, it->m_Unit );
1180 symbol->GetField( REFERENCE_FIELD )->SetText( it->m_Reference );
1181
1182 if( !it->m_Value.IsEmpty() )
1183 symbol->SetValueFieldText( it->m_Value );
1184
1185 if( !it->m_Footprint.IsEmpty() )
1186 symbol->SetFootprintFieldText( it->m_Footprint );
1187
1188 symbol->UpdatePrefix();
1189 }
1190 }
1191}
1192
1193
1194void SCH_SHEET_LIST::UpdateSheetInstanceData( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances )
1195{
1196
1197 for( SCH_SHEET_PATH& path : *this )
1198 {
1199 SCH_SHEET* sheet = path.Last();
1200
1201 wxCHECK2( sheet && path.Last(), continue );
1202
1203 auto it = std::find_if( aSheetInstances.begin(), aSheetInstances.end(),
1204 [ path ]( const SCH_SHEET_INSTANCE& r ) -> bool
1205 {
1206 return path.Path() == r.m_Path;
1207 } );
1208
1209 if( it == aSheetInstances.end() )
1210 {
1211 wxLogTrace( traceSchSheetPaths, "No sheet instance found for path '%s'",
1212 path.Path().AsString() );
1213 continue;
1214 }
1215
1216 wxLogTrace( traceSchSheetPaths, "Setting sheet '%s' instance '%s' page number '%s'",
1217 ( sheet->GetName().IsEmpty() ) ? wxString( wxT( "root" ) ) : sheet->GetName(),
1218 path.Path().AsString(), it->m_PageNumber );
1219 path.SetPageNumber( it->m_PageNumber );
1220 }
1221}
1222
1223
1224std::vector<KIID_PATH> SCH_SHEET_LIST::GetPaths() const
1225{
1226 std::vector<KIID_PATH> paths;
1227
1228 for( const SCH_SHEET_PATH& sheetPath : *this )
1229 paths.emplace_back( sheetPath.Path() );
1230
1231 return paths;
1232}
1233
1234
1235std::vector<SCH_SHEET_INSTANCE> SCH_SHEET_LIST::GetSheetInstances() const
1236{
1237 std::vector<SCH_SHEET_INSTANCE> retval;
1238
1239 for( const SCH_SHEET_PATH& path : *this )
1240 {
1241 const SCH_SHEET* sheet = path.Last();
1242
1243 wxCHECK2( sheet, continue );
1244
1245 SCH_SHEET_INSTANCE instance;
1246 SCH_SHEET_PATH tmpPath = path;
1247
1248 tmpPath.pop_back();
1249 instance.m_Path = tmpPath.Path();
1250 instance.m_PageNumber = path.GetPageNumber();
1251
1252 retval.push_back( instance );
1253 }
1254
1255 return retval;
1256}
1257
1258
1260{
1261 for( const SCH_SHEET_PATH& instance : *this )
1262 {
1263 if( !instance.GetPageNumber().IsEmpty() )
1264 return false;
1265 }
1266
1267 return true;
1268}
1269
1270
1272{
1273 // Don't accidentally renumber existing sheets.
1274 wxCHECK( AllSheetPageNumbersEmpty(), /* void */ );
1275
1276 wxString tmp;
1277 int pageNumber = 1;
1278
1279 for( SCH_SHEET_PATH& instance : *this )
1280 {
1281 tmp.Printf( "%d", pageNumber );
1282 instance.SetPageNumber( tmp );
1283 pageNumber += 1;
1284 }
1285}
1286
1287
1289 const wxString& aProjectName )
1290{
1291 for( SCH_SHEET_PATH& sheetPath : *this )
1292 sheetPath.AddNewSymbolInstances( aPrefixSheetPath, aProjectName );
1293}
1294
1295
1297{
1298 for( SCH_SHEET_PATH& sheetPath : *this )
1299 sheetPath.RemoveSymbolInstances( aPrefixSheetPath );
1300}
1301
1302
1304 int aLastVirtualPageNumber )
1305{
1306 wxString pageNumber;
1307 int lastUsedPageNumber = 1;
1308 int nextVirtualPageNumber = aLastVirtualPageNumber;
1309
1310 // Fetch the list of page numbers already in use.
1311 std::vector< wxString > usedPageNumbers;
1312
1313 if( aPrefixSheetPath.size() )
1314 {
1315 SCH_SHEET_LIST prefixHierarchy( aPrefixSheetPath.at( 0 ) );
1316
1317 for( const SCH_SHEET_PATH& path : prefixHierarchy )
1318 {
1319 pageNumber = path.GetPageNumber();
1320
1321 if( !pageNumber.IsEmpty() )
1322 usedPageNumbers.emplace_back( pageNumber );
1323 }
1324 }
1325
1326 for( SCH_SHEET_PATH& sheetPath : *this )
1327 {
1328 KIID_PATH tmp = sheetPath.Path();
1329 SCH_SHEET_PATH newSheetPath( aPrefixSheetPath );
1330
1331 // Prefix the new hierarchical path.
1332 newSheetPath = newSheetPath + sheetPath;
1333
1334 // Sheets cannot have themselves in the path.
1335 tmp.pop_back();
1336
1337 SCH_SHEET* sheet = sheetPath.Last();
1338
1339 wxCHECK2( sheet, continue );
1340
1341 nextVirtualPageNumber += 1;
1342
1343 SCH_SHEET_INSTANCE instance;
1344
1345 // Add the instance if it doesn't already exist
1346 if( !sheet->getInstance( instance, tmp, true ) )
1347 {
1348 sheet->addInstance( tmp );
1349 sheet->getInstance( instance, tmp, true );
1350 }
1351
1352 // Get a new page number if we don't have one
1353 if( instance.m_PageNumber.IsEmpty() )
1354 {
1355 // Generate the next available page number.
1356 do
1357 {
1358 pageNumber.Printf( wxT( "%d" ), lastUsedPageNumber );
1359 lastUsedPageNumber += 1;
1360 } while( std::find( usedPageNumbers.begin(), usedPageNumbers.end(), pageNumber ) !=
1361 usedPageNumbers.end() );
1362
1363 instance.m_PageNumber = pageNumber;
1364 newSheetPath.SetVirtualPageNumber( nextVirtualPageNumber );
1365 }
1366
1367 newSheetPath.SetPageNumber( instance.m_PageNumber );
1368 usedPageNumbers.push_back( instance.m_PageNumber );
1369 }
1370}
1371
1372
1374{
1375 int lastVirtualPageNumber = 1;
1376
1377 for( const SCH_SHEET_PATH& sheetPath : *this )
1378 {
1379 if( sheetPath.GetVirtualPageNumber() > lastVirtualPageNumber )
1380 lastVirtualPageNumber = sheetPath.GetVirtualPageNumber();
1381 }
1382
1383 return lastVirtualPageNumber;
1384}
1385
1386
1387bool SCH_SHEET_LIST::HasPath( const KIID_PATH& aPath ) const
1388{
1389 for( const SCH_SHEET_PATH& path : *this )
1390 {
1391 if( path.Path() == aPath )
1392 return true;
1393 }
1394
1395 return false;
1396}
1397
1398
1399bool SCH_SHEET_LIST::ContainsSheet( const SCH_SHEET* aSheet ) const
1400{
1401 for( const SCH_SHEET_PATH& path : *this )
1402 {
1403 for( size_t i = 0; i < path.size(); i++ )
1404 {
1405 if( path.at( i ) == aSheet )
1406 return true;
1407 }
1408 }
1409
1410 return false;
1411}
bool IsContentModified() const
Definition: base_screen.h:60
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
A singleton item of this class is returned for a weak reference that no longer exists.
wxString GetClass() const override
Return the class name.
void SetPosition(const VECTOR2I &) override
static DELETED_SHEET_ITEM * GetInstance()
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool operator==(const SCH_ITEM &aOther) const override
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
const KIID m_Uuid
Definition: eda_item.h:489
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
virtual bool IsVisible() const
Definition: eda_text.h:147
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:244
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
wxString AsString() const
Definition: kiid.cpp:356
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:246
Define a library symbol object.
Definition: lib_symbol.h:78
bool IsPower() const override
Definition: lib_symbol.cpp:389
int GetUnitCount() const override
Holds all the data relating to one schematic.
Definition: schematic.h:76
wxString GetFileName() const override
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:291
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:297
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
VECTOR2I GetPosition() const override
Definition: sch_field.cpp:1462
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1189
const wxString & GetInternalName()
Get the initial name of the field set at creation (or set by SetName()).
Definition: sch_field.h:131
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
int GetUnit() const
Definition: sch_item.h:229
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction)
Definition: sch_item.h:568
virtual void SetUnit(int aUnit)
Definition: sch_item.h:228
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:614
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:201
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void Annotate(bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap, const SCH_REFERENCE_LIST &aAdditionalRefs, bool aStartAtCurrent=false)
Set the reference designators in the list that have not been annotated.
size_t GetCount() const
void SplitReferences()
Attempt to split all reference designators into a name (U) and number (1).
void AddItem(const SCH_REFERENCE &aItem)
void UpdateAnnotation()
Update the symbol references for the schematic project (or the current sheet).
A helper to define a symbol's reference designator in a schematic.
wxString GetRef() const
void SetSheetNumber(int aSheetNumber)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
const wxString & GetFileName() const
Definition: sch_screen.h:143
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:322
SCHEMATIC * Schematic() const
Definition: sch_screen.cpp:99
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:315
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,...
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
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...
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Fill an item cache for temporary use when many items need to be fetched.
SCH_SHEET_PATH m_currentSheetPath
void TrimToPageNumbers(const std::vector< wxString > &aPageInclusions)
Truncates the list by removing sheet's with page numbers not in the given list.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
void AddNewSymbolInstances(const SCH_SHEET_PATH &aPrefixSheetPath, const wxString &aProjectName)
Attempt to add new symbol instances for all symbols in this list of sheet paths prefixed with aPrefix...
bool NameExists(const wxString &aSheetName) const
std::vector< SCH_SHEET_INSTANCE > GetSheetInstances() const
Fetch the instance information for all of the sheets in the hiearchy.
void UpdateSheetInstanceData(const std::vector< SCH_SHEET_INSTANCE > &aSheetInstances)
Update all of the sheet instance information using aSheetInstances.
void SetInitialPageNumbers()
Set initial sheet page numbers.
void RemoveSymbolInstances(const SCH_SHEET_PATH &aPrefixSheetPath)
SCH_SHEET_LIST FindAllSheetsForScreen(const SCH_SCREEN *aScreen) const
Return a SCH_SHEET_LIST with a copy of all the SCH_SHEET_PATH using a particular screen.
bool AllSheetPageNumbersEmpty() const
Check all of the sheet instance for empty page numbers.
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.
bool IsModified() const
Check the entire hierarchy for any modifications.
SCH_SHEET_LIST(SCH_SHEET *aSheet=nullptr)
Construct a flattened list of SCH_SHEET_PATH objects from aSheet.
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
int GetLastVirtualPageNumber() const
void UpdateSymbolInstanceData(const std::vector< SCH_SYMBOL_INSTANCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
void GetSheetsWithinPath(std::vector< SCH_SHEET_PATH > &aSheets, const SCH_SHEET_PATH &aSheetPath) const
Add a SCH_SHEET_PATH object to aSheets for each sheet in the list that are contained within aSheetPat...
bool PageNumberExists(const wxString &aPageNumber) const
void AddNewSheetInstances(const SCH_SHEET_PATH &aPrefixSheetPath, int aLastVirtualPageNumber)
bool ContainsSheet(const SCH_SHEET *aSheet) const
std::vector< KIID_PATH > GetPaths() const
void GetSymbolsWithinPath(SCH_REFERENCE_LIST &aReferences, const SCH_SHEET_PATH &aSheetPath, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets that are contained wi...
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
SCH_SHEET_PATH FindSheetForScreen(const SCH_SCREEN *aScreen)
Return the first SCH_SHEET_PATH object (not necessarily the only one) using a particular screen.
bool HasPath(const KIID_PATH &aPath) const
SCH_SHEET_PATH * FindSheetForPath(const SCH_SHEET_PATH *aPath)
Return a pointer to the first SCH_SHEET_PATH object (not necessarily the only one) matching the provi...
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...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool GetExcludedFromBOM() const
SCH_ITEM * GetItem(const KIID &aID) const
Fetch a SCH_ITEM by ID.
void AppendMultiUnitSymbol(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, SCH_SYMBOL *aSymbol, bool aIncludePowerSymbols=true) const
Append a SCH_REFERENCE_LIST object to aRefList based on aSymbol, storing same-reference set of multi-...
const SCH_SHEET * GetSheet(unsigned aIndex) const
bool empty() 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.
int ComparePageNum(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare sheets by their page number.
size_t GetCurrentHash() const
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
bool operator==(const SCH_SHEET_PATH &d1) const
void AddNewSymbolInstances(const SCH_SHEET_PATH &aPrefixSheetPath, const wxString &aProjectName)
Attempt to add new symbol instances for all symbols in this sheet path prefixed with aPrefixSheetPath...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
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...
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
bool IsFullPath() const
void MakeFilePathRelativeToParentSheet()
Make the sheet file name relative to its parent sheet.
wxString GetCachedPageNumber() const
std::vector< SCH_SHEET * > m_sheets
SCH_SCREEN * LastScreen()
int Cmp(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare if this is the same sheet path as aSheetPathToTest.
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...
void initFromOther(const SCH_SHEET_PATH &aOther)
wxString m_cached_page_number
wxString GetPageNumber() const
void RemoveSymbolInstances(const SCH_SHEET_PATH &aPrefixSheetPath)
bool IsContainedWithin(const SCH_SHEET_PATH &aSheetPathToTest) const
Check if this path is contained inside aSheetPathToTest.
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
void SetVirtualPageNumber(int aPageNumber)
Set the sheet instance virtual page number.
void AppendSymbol(SCH_REFERENCE_LIST &aReferences, SCH_SYMBOL *aSymbol, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Append a SCH_REFERENCE object to aReferences based on aSymbol.
std::map< std::pair< wxString, wxString >, bool > m_recursion_test_cache
Page numbers are maintained by the sheet load order.
bool GetExcludedFromSim() const
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
bool GetExcludedFromBoard() const
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET_PATH & operator=(const SCH_SHEET_PATH &aOther)
bool GetDNP() const
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
SCH_SHEET_PATH operator+(const SCH_SHEET_PATH &aOther)
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
int GetVirtualPageNumber() const
void pop_back()
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:312
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:306
bool IsRootSheet() const
Definition: sch_sheet.cpp:204
bool getInstance(SCH_SHEET_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
Definition: sch_sheet.cpp:1453
bool addInstance(const KIID_PATH &aInstance)
Add a new instance aSheetPath to the instance list.
Definition: sch_sheet.cpp:1430
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:93
wxString GetName() const
Definition: sch_sheet.h:107
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:110
static int ComparePageNum(const wxString &aPageNumberA, const wxString &aPageNumberB)
Compares page numbers of schematic sheets.
Definition: sch_sheet.cpp:1535
void setPageNumber(const KIID_PATH &aInstance, const wxString &aPageNumber)
Set the page number for the sheet instance aInstance.
Definition: sch_sheet.cpp:1522
wxString getPageNumber(const KIID_PATH &aInstance) const
Return the sheet page number for aInstance.
Definition: sch_sheet.cpp:1505
Schematic symbol object.
Definition: sch_symbol.h:105
void UpdatePrefix()
Set the prefix based on the current reference designator.
Definition: sch_symbol.cpp:809
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition: sch_symbol.h:164
void RemoveInstance(const SCH_SHEET_PATH &aInstancePath)
Definition: sch_symbol.cpp:592
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:897
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:919
void SetFootprintFieldText(const wxString &aFootprint)
Definition: sch_symbol.cpp:913
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
Definition: sch_symbol.cpp:620
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
Definition: sch_symbol.cpp:568
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:845
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:213
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:720
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
STL namespace.
@ SHEETNAME
Definition: sch_sheet.h:45
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Container to map reference designators for multi-unit parts.
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
Definition for symbol library class.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
wxLogTrace helper definitions.
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ NOT_USED
the 3d code uses this value
Definition: typeinfo.h:79
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:673