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