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