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