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