KiCad PCB EDA Suite
Loading...
Searching...
No Matches
schematic.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) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <bus_alias.h>
21#include <commit.h>
22#include <connection_graph.h>
23#include <core/ignore.h>
24#include <core/kicad_algo.h>
25#include <ee_collectors.h>
26#include <erc_settings.h>
27#include <sch_marker.h>
28#include <project.h>
31#include <schematic.h>
32#include <sch_junction.h>
33#include <sch_line.h>
34#include <sch_screen.h>
35#include <sim/spice_settings.h>
36#include <sch_label.h>
37#include <sim/spice_value.h>
39
41 EDA_ITEM( nullptr, SCHEMATIC_T ),
42 m_project( nullptr ),
43 m_rootSheet( nullptr )
44{
47
48 SetProject( aPrj );
49
51 [&]( INSPECTABLE* aItem, PROPERTY_BASE* aProperty, COMMIT* aCommit )
52 {
53 // Special case: propagate value, footprint, and datasheet fields to other units
54 // of a given symbol if they aren't in the selection
55
56 SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem );
57
58 if( !field || !IsValid() )
59 return;
60
61 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( field->GetParent() );
62
63 if( !symbol || aProperty->Name() != _HKI( "Text" ) )
64 return;
65
66 // TODO(JE) This will need to get smarter to enable API access
67 SCH_SHEET_PATH sheetPath = CurrentSheet();
68
69 wxString newValue = aItem->Get<wxString>( aProperty );
70
71 wxString ref = symbol->GetRef( &sheetPath );
72 int unit = symbol->GetUnit();
73 LIB_ID libId = symbol->GetLibId();
74
75 for( SCH_SHEET_PATH& sheet : GetSheets() )
76 {
77 std::vector<SCH_SYMBOL*> otherUnits;
78
79 CollectOtherUnits( ref, unit, libId, sheet, &otherUnits );
80
81 for( SCH_SYMBOL* otherUnit : otherUnits )
82 {
83 switch( field->GetId() )
84 {
85 case VALUE_FIELD:
86 {
87 if( aCommit )
88 aCommit->Modify( otherUnit, sheet.LastScreen() );
89
90 otherUnit->SetValueFieldText( newValue );
91 break;
92 }
93
94 case FOOTPRINT_FIELD:
95 {
96 if( aCommit )
97 aCommit->Modify( otherUnit, sheet.LastScreen() );
98
99 otherUnit->SetFootprintFieldText( newValue );
100 break;
101 }
102
103 case DATASHEET_FIELD:
104 {
105 if( aCommit )
106 aCommit->Modify( otherUnit, sheet.LastScreen() );
107
108 otherUnit->GetField( DATASHEET_FIELD )->SetText( newValue );
109 break;
110 }
111
112 default:
113 break;
114 }
115 }
116 }
117 } );
118}
119
120
122{
123 delete m_currentSheet;
124 delete m_connectionGraph;
125}
126
127
129{
130 if( m_project )
131 {
133
134 // d'tor will save settings to file
135 delete project.m_ErcSettings;
136 project.m_ErcSettings = nullptr;
137
138 // d'tor will save settings to file
139 delete project.m_SchematicSettings;
140 project.m_SchematicSettings = nullptr;
141
142 m_project = nullptr; // clear the project, so we don't do this again when setting a new one
143 }
144
145 delete m_rootSheet;
146
147 m_rootSheet = nullptr;
148
151}
152
153
155{
156 if( m_project )
157 {
159
160 // d'tor will save settings to file
161 delete project.m_ErcSettings;
162 project.m_ErcSettings = nullptr;
163
164 // d'tor will save settings to file
165 delete project.m_SchematicSettings;
166 project.m_SchematicSettings = nullptr;
167 }
168
169 m_project = aPrj;
170
171 if( m_project )
172 {
174 project.m_ErcSettings = new ERC_SETTINGS( &project, "erc" );
175 project.m_SchematicSettings = new SCHEMATIC_SETTINGS( &project, "schematic" );
176
177 project.m_SchematicSettings->LoadFromFile();
178 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
179 project.m_ErcSettings->LoadFromFile();
180 }
181}
182
183
184void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet )
185{
186 wxCHECK_RET( aRootSheet, wxS( "Call to SetRoot with null SCH_SHEET!" ) );
187
188 m_rootSheet = aRootSheet;
189
192
194}
195
196
198{
199 return IsValid() ? m_rootSheet->GetScreen() : nullptr;
200}
201
202
203void SCHEMATIC::GetContextualTextVars( wxArrayString* aVars ) const
204{
205 auto add =
206 [&]( const wxString& aVar )
207 {
208 if( !alg::contains( *aVars, aVar ) )
209 aVars->push_back( aVar );
210 };
211
212 add( wxT( "#" ) );
213 add( wxT( "##" ) );
214 add( wxT( "SHEETPATH" ) );
215 add( wxT( "SHEETNAME" ) );
216 add( wxT( "FILENAME" ) );
217 add( wxT( "FILEPATH" ) );
218 add( wxT( "PROJECTNAME" ) );
219
220 if( !CurrentSheet().empty() )
222
223 for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
224 add( entry.first );
225}
226
227
228bool SCHEMATIC::ResolveTextVar( const SCH_SHEET_PATH* aSheetPath, wxString* token,
229 int aDepth ) const
230{
231 wxCHECK( aSheetPath, false );
232
233 if( token->IsSameAs( wxT( "#" ) ) )
234 {
235 *token = aSheetPath->GetPageNumber();
236 return true;
237 }
238 else if( token->IsSameAs( wxT( "##" ) ) )
239 {
240 *token = wxString::Format( "%i", Root().CountSheets() );
241 return true;
242 }
243 else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
244 {
245 *token = aSheetPath->PathHumanReadable();
246 return true;
247 }
248 else if( token->IsSameAs( wxT( "SHEETNAME" ) ) )
249 {
250 *token = aSheetPath->Last()->GetName();
251 return true;
252 }
253 else if( token->IsSameAs( wxT( "FILENAME" ) ) )
254 {
255 wxFileName fn( GetFileName() );
256 *token = fn.GetFullName();
257 return true;
258 }
259 else if( token->IsSameAs( wxT( "FILEPATH" ) ) )
260 {
261 wxFileName fn( GetFileName() );
262 *token = fn.GetFullPath();
263 return true;
264 }
265 else if( token->IsSameAs( wxT( "PROJECTNAME" ) ) )
266 {
267 *token = Prj().GetProjectName();
268 return true;
269 }
270
271 if( aSheetPath->LastScreen()->GetTitleBlock().TextVarResolver( token, m_project ) )
272 return true;
273
274 if( Prj().TextVarResolver( token ) )
275 return true;
276
277 return false;
278}
279
280
282{
283 return IsValid() ? m_rootSheet->GetScreen()->GetFileName() : wxString( wxEmptyString );
284}
285
286
288{
289 wxASSERT( m_project );
291}
292
293
295{
296 wxASSERT( m_project );
298}
299
300
301std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
302{
303 SCH_SHEET_LIST sheetList = GetSheets();
304 ERC_SETTINGS& settings = ErcSettings();
305
306 // Migrate legacy marker exclusions to new format to ensure exclusion matching functions across
307 // file versions. Silently drops any legacy exclusions which can not be mapped to the new format
308 // without risking an incorrect exclusion - this is preferable to silently dropping
309 // new ERC errors / warnings due to an incorrect match between a legacy and new
310 // marker serialization format
311 std::set<wxString> migratedExclusions;
312
313 for( auto it = settings.m_ErcExclusions.begin(); it != settings.m_ErcExclusions.end(); )
314 {
315 SCH_MARKER* testMarker = SCH_MARKER::Deserialize( this, *it );
316
317 if( testMarker->IsLegacyMarker() )
318 {
319 const wxString settingsKey = testMarker->GetRCItem()->GetSettingsKey();
320
321 if( settingsKey != wxT( "pin_to_pin" )
322 && settingsKey != wxT( "hier_label_mismatch" )
323 && settingsKey != wxT( "different_unit_net" ) )
324 {
325 migratedExclusions.insert( testMarker->Serialize() );
326 }
327
328 it = settings.m_ErcExclusions.erase( it );
329 }
330 else
331 {
332 ++it;
333 }
334
335 delete testMarker;
336 }
337
338 settings.m_ErcExclusions.insert( migratedExclusions.begin(), migratedExclusions.end() );
339
340 // End of legacy exclusion removal / migrations
341
342 for( const SCH_SHEET_PATH& sheet : sheetList )
343 {
344 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_MARKER_T ) )
345 {
346 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
347 wxString serialized = marker->Serialize();
348 std::set<wxString>::iterator it = settings.m_ErcExclusions.find( serialized );
349
350 if( it != settings.m_ErcExclusions.end() )
351 {
352 marker->SetExcluded( true, settings.m_ErcExclusionComments[serialized] );
353 settings.m_ErcExclusions.erase( it );
354 }
355 }
356 }
357
358 std::vector<SCH_MARKER*> newMarkers;
359
360 for( const wxString& serialized : settings.m_ErcExclusions )
361 {
362 SCH_MARKER* marker = SCH_MARKER::Deserialize( this, serialized );
363
364 if( marker )
365 {
366 marker->SetExcluded( true, settings.m_ErcExclusionComments[serialized] );
367 newMarkers.push_back( marker );
368 }
369 }
370
371 settings.m_ErcExclusions.clear();
372
373 return newMarkers;
374}
375
376
377std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) const
378{
379 for( const SCH_SHEET_PATH& sheet : GetSheets() )
380 {
381 for( const std::shared_ptr<BUS_ALIAS>& alias : sheet.LastScreen()->GetBusAliases() )
382 {
383 if( alias->GetName() == aLabel )
384 return alias;
385 }
386 }
387
388 return nullptr;
389}
390
391
393{
394 std::set<wxString> names;
395
396 for( const auto& [ key, subgraphList ] : m_connectionGraph->GetNetMap() )
397 {
398 CONNECTION_SUBGRAPH* firstSubgraph = subgraphList[0];
399
400 if( !firstSubgraph->GetDriverConnection()->IsBus()
402 {
403 names.insert( key.Name );
404 }
405 }
406
407 return names;
408}
409
410
411bool SCHEMATIC::ResolveCrossReference( wxString* token, int aDepth ) const
412{
413 SCH_SHEET_LIST sheetList = GetSheets();
414 wxString remainder;
415 wxString ref = token->BeforeFirst( ':', &remainder );
416 SCH_SHEET_PATH sheetPath;
417 SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &sheetPath );
418
419 if( refItem && refItem->Type() == SCH_SYMBOL_T )
420 {
421 SCH_SYMBOL* refSymbol = static_cast<SCH_SYMBOL*>( refItem );
422
423 if( refSymbol->ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
424 *token = remainder;
425 else
426 *token = refSymbol->GetRef( &sheetPath, true ) + wxS( ":" ) + remainder;
427
428 return true; // Cross-reference is resolved whether or not the actual textvar was
429 }
430 else if( refItem && refItem->Type() == SCH_SHEET_T )
431 {
432 SCH_SHEET* refSheet = static_cast<SCH_SHEET*>( refItem );
433
434 sheetPath.push_back( refSheet );
435
436 if( refSheet->ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
437 *token = remainder;
438
439 return true; // Cross-reference is resolved whether or not the actual textvar was
440 }
441
442 return false;
443}
444
445
446std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetNamesMap() const
447{
448 std::map<int, wxString> namesMap;
449
450 for( const SCH_SHEET_PATH& sheet : GetSheets() )
451 {
452 if( sheet.size() == 1 )
453 namesMap[sheet.GetVirtualPageNumber()] = _( "<root sheet>" );
454 else
455 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
456 }
457
458 return namesMap;
459}
460
461
462std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetPagesMap() const
463{
464 std::map<int, wxString> pagesMap;
465
466 for( const SCH_SHEET_PATH& sheet : GetSheets() )
467 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
468
469 return pagesMap;
470}
471
472
473wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const
474{
475 wxString newbuf;
476 size_t sourceLen = aSource.length();
477
478 for( size_t i = 0; i < sourceLen; ++i )
479 {
480 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
481 {
482 wxString token;
483 bool isCrossRef = false;
484 int nesting = 0;
485
486 for( i = i + 2; i < sourceLen; ++i )
487 {
488 if( aSource[i] == '{'
489 && ( aSource[i-1] == '_' || aSource[i-1] == '^' || aSource[i-1] == '~' ) )
490 {
491 nesting++;
492 }
493
494 if( aSource[i] == '}' )
495 {
496 nesting--;
497
498 if( nesting < 0 )
499 break;
500 }
501
502 if( aSource[i] == ':' )
503 isCrossRef = true;
504
505 token.append( aSource[i] );
506 }
507
508 if( isCrossRef )
509 {
510 SCH_SHEET_LIST sheetList = GetSheets();
511 wxString remainder;
512 wxString ref = token.BeforeFirst( ':', &remainder );
513 SCH_REFERENCE_LIST references;
514
515 sheetList.GetSymbols( references );
516
517 for( size_t jj = 0; jj < references.GetCount(); jj++ )
518 {
519 SCH_SYMBOL* refSymbol = references[ jj ].GetSymbol();
520
521 if( ref == refSymbol->GetRef( &references[ jj ].GetSheetPath(), true ) )
522 {
523 token = refSymbol->m_Uuid.AsString() + wxS( ":" ) + remainder;
524 break;
525 }
526 }
527 }
528
529 newbuf.append( wxS( "${" ) + token + wxS( "}" ) );
530 }
531 else
532 {
533 newbuf.append( aSource[i] );
534 }
535 }
536
537 return newbuf;
538}
539
540
541wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const
542{
543 wxString newbuf;
544 size_t sourceLen = aSource.length();
545
546 for( size_t i = 0; i < sourceLen; ++i )
547 {
548 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
549 {
550 wxString token;
551 bool isCrossRef = false;
552
553 for( i = i + 2; i < sourceLen; ++i )
554 {
555 if( aSource[i] == '}' )
556 break;
557
558 if( aSource[i] == ':' )
559 isCrossRef = true;
560
561 token.append( aSource[i] );
562 }
563
564 if( isCrossRef )
565 {
566 SCH_SHEET_LIST sheetList = GetSheets();
567 wxString remainder;
568 wxString ref = token.BeforeFirst( ':', &remainder );
569
570 SCH_SHEET_PATH refSheetPath;
571 SCH_ITEM* refItem = sheetList.GetItem( KIID( ref ), &refSheetPath );
572
573 if( refItem && refItem->Type() == SCH_SYMBOL_T )
574 {
575 SCH_SYMBOL* refSymbol = static_cast<SCH_SYMBOL*>( refItem );
576 token = refSymbol->GetRef( &refSheetPath, true ) + wxS( ":" ) + remainder;
577 }
578 }
579
580 newbuf.append( wxS( "${" ) + token + wxS( "}" ) );
581 }
582 else
583 {
584 newbuf.append( aSource[i] );
585 }
586 }
587
588 return newbuf;
589}
590
591
593{
594 static SCH_SHEET_LIST hierarchy;
595
596 hierarchy.clear();
597 hierarchy.BuildSheetList( m_rootSheet, false );
598
599 return hierarchy;
600}
601
602
604{
605 SCH_SCREENS screens( m_rootSheet );
606
608}
609
610
612{
613 // Filename is rootSheetName-sheetName-...-sheetName
614 // Note that we need to fetch the rootSheetName out of its filename, as the root SCH_SHEET's
615 // name is just a timestamp.
616
617 wxFileName rootFn( CurrentSheet().at( 0 )->GetFileName() );
618 wxString filename = rootFn.GetName();
619
620 for( unsigned i = 1; i < CurrentSheet().size(); i++ )
621 filename += wxT( "-" ) + CurrentSheet().at( i )->GetName();
622
623 return filename;
624}
625
626
628{
629 SCH_SCREEN* screen;
630 SCH_SCREENS s_list( Root() );
631
632 // Set the sheet count, and the sheet number (1 for root sheet)
633 int sheet_count = Root().CountSheets();
634 int sheet_number = 1;
635 const KIID_PATH& current_sheetpath = CurrentSheet().Path();
636
637 // @todo Remove all pseudo page number system is left over from prior to real page number
638 // implementation.
639 for( const SCH_SHEET_PATH& sheet : GetSheets() )
640 {
641 if( sheet.Path() == current_sheetpath ) // Current sheet path found
642 break;
643
644 sheet_number++; // Not found, increment before this current path
645 }
646
647 for( screen = s_list.GetFirst(); screen != nullptr; screen = s_list.GetNext() )
648 screen->SetPageCount( sheet_count );
649
650 CurrentSheet().SetVirtualPageNumber( sheet_number );
651 CurrentSheet().LastScreen()->SetVirtualPageNumber( sheet_number );
652 CurrentSheet().LastScreen()->SetPageNumber( CurrentSheet().GetPageNumber() );
653}
654
655
656void SCHEMATIC::RecomputeIntersheetRefs( const std::function<void( SCH_GLOBALLABEL* )>& aItemCallback )
657{
658 std::map<wxString, std::set<int>>& pageRefsMap = GetPageRefsMap();
659
660 pageRefsMap.clear();
661
662 SCH_SCREENS screens( Root() );
663 std::vector<int> virtualPageNumbers;
664
665 /* Iterate over screens */
666 for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
667 {
668 virtualPageNumbers.clear();
669
670 /* Find in which sheets this screen is used */
671 for( const SCH_SHEET_PATH& sheet : GetSheets() )
672 {
673 if( sheet.LastScreen() == screen )
674 virtualPageNumbers.push_back( sheet.GetVirtualPageNumber() );
675 }
676
677 for( SCH_ITEM* item : screen->Items() )
678 {
679 if( item->Type() == SCH_GLOBAL_LABEL_T )
680 {
681 SCH_GLOBALLABEL* globalLabel = static_cast<SCH_GLOBALLABEL*>( item );
682 std::set<int>& virtualpageList = pageRefsMap[globalLabel->GetText()];
683
684 for( const int& pageNo : virtualPageNumbers )
685 virtualpageList.insert( pageNo );
686 }
687 }
688 }
689
690 bool show = Settings().m_IntersheetRefsShow;
691
692 // Refresh all global labels. Note that we have to collect them first as the
693 // SCH_SCREEN::Update() call is going to invalidate the RTree iterator.
694
695 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
696
697 for( EDA_ITEM* item : CurrentSheet().LastScreen()->Items().OfType( SCH_GLOBAL_LABEL_T ) )
698 currentSheetGlobalLabels.push_back( static_cast<SCH_GLOBALLABEL*>( item ) );
699
700 for( SCH_GLOBALLABEL* globalLabel : currentSheetGlobalLabels )
701 {
702 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
703
704 fields[0].SetVisible( show );
705
706 if( show )
707 {
708 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
709 globalLabel->AutoplaceFields( CurrentSheet().LastScreen(), false );
710
711 CurrentSheet().LastScreen()->Update( globalLabel );
712 aItemCallback( globalLabel );
713 }
714 }
715}
716
717
718wxString SCHEMATIC::GetOperatingPoint( const wxString& aNetName, int aPrecision,
719 const wxString& aRange )
720{
721 std::string spiceNetName( aNetName.Lower().ToStdString() );
723
724 if( spiceNetName == "gnd" || spiceNetName == "0" )
725 return wxEmptyString;
726
727 auto it = m_operatingPoints.find( spiceNetName );
728
729 if( it != m_operatingPoints.end() )
730 return SPICE_VALUE( it->second ).ToString( { aPrecision, aRange } );
731 else if( m_operatingPoints.empty() )
732 return wxS( "--" );
733 else
734 return wxS( "?" );
735}
736
737
739{
740 for( const SCH_SHEET_PATH& sheet : GetSheets() )
741 {
742 SCH_SCREEN* screen = sheet.LastScreen();
743
744 std::deque<EDA_ITEM*> allItems;
745
746 for( auto item : screen->Items() )
747 allItems.push_back( item );
748
749 // Add missing junctions and breakup wires as needed
750 for( const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
751 {
752 SCH_JUNCTION* junction = new SCH_JUNCTION( point );
753 screen->Append( junction );
754
755 // Breakup wires
756 for( SCH_LINE* wire : screen->GetBusesAndWires( point, true ) )
757 {
758 SCH_LINE* newSegment = wire->BreakAt( point );
759 screen->Append( newSegment );
760 }
761 }
762 }
763}
764
765
766void SCHEMATIC::OnItemsAdded( std::vector<SCH_ITEM*>& aNewItems )
767{
769}
770
771
772void SCHEMATIC::OnItemsRemoved( std::vector<SCH_ITEM*>& aRemovedItems )
773{
775}
776
777
778void SCHEMATIC::OnItemsChanged( std::vector<SCH_ITEM*>& aItems )
779{
781}
782
783
785{
787}
788
789
791{
792 if( !alg::contains( m_listeners, aListener ) )
793 m_listeners.push_back( aListener );
794}
795
796
798{
799 auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
800
801 if( i != m_listeners.end() )
802 {
803 std::iter_swap( i, m_listeners.end() - 1 );
804 m_listeners.pop_back();
805 }
806}
807
808
810{
811 m_listeners.clear();
812}
813
814
816{
817 SCH_SHEET_LIST sheetList = GetSheets();
818 ERC_SETTINGS& ercSettings = ErcSettings();
819
820 ercSettings.m_ErcExclusions.clear();
821 ercSettings.m_ErcExclusionComments.clear();
822
823 for( unsigned i = 0; i < sheetList.size(); i++ )
824 {
825 for( SCH_ITEM* item : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
826 {
827 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
828
829 if( marker->IsExcluded() )
830 {
831 wxString serialized = marker->Serialize();
832 ercSettings.m_ErcExclusions.insert( serialized );
833 ercSettings.m_ErcExclusionComments[ serialized ] = marker->GetComment();
834 }
835 }
836 }
837}
838
839
841{
842 SCH_SHEET_LIST sheetList = GetSheets();
843
844 for( SCH_MARKER* marker : ResolveERCExclusions() )
845 {
846 SCH_SHEET_PATH errorPath;
847 ignore_unused( sheetList.GetItem( marker->GetRCItem()->GetMainItemID(), &errorPath ) );
848
849 if( errorPath.LastScreen() )
850 errorPath.LastScreen()->Append( marker );
851 else
852 RootScreen()->Append( marker );
853 }
854}
void SetPageCount(int aPageCount)
Definition: base_screen.cpp:63
void SetPageNumber(const wxString &aPageNumber)
Definition: base_screen.h:79
void SetVirtualPageNumber(int aPageNumber)
Definition: base_screen.h:76
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition: commit.h:74
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
Calculate the connectivity of a schematic and generates netlists.
const NET_MAP & GetNetMap() const
A subgraph is a set of items that are electrically connected on a single sheet.
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
const SCH_CONNECTION * GetDriverConnection() const
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
const KIID m_Uuid
Definition: eda_item.h:482
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
Container for ERC settings.
Definition: erc_settings.h:117
std::map< wxString, wxString > m_ErcExclusionComments
Definition: erc_settings.h:178
std::set< wxString > m_ErcExclusions
Definition: erc_settings.h:177
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
wxAny Get(PROPERTY_BASE *aProperty) const
Definition: inspectable.h:99
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:257
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
bool IsExcluded() const
Definition: marker_base.h:98
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:112
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
Definition: marker_base.h:99
wxString GetComment() const
Definition: marker_base.h:105
static void ConvertToSpiceMarkup(std::string &aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:70
ERC_SETTINGS * m_ErcSettings
Eeschema params.
Definition: project_file.h:132
SCHEMATIC_SETTINGS * m_SchematicSettings
Definition: project_file.h:135
Container for project specific data.
Definition: project.h:62
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:147
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
const wxString & Name() const
Definition: property.h:212
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
void RegisterListener(TYPE_ID aType, PROPERTY_LISTENER aListenerFunc)
Registers a listener for the given type.
Definition: property_mgr.h:275
virtual void OnSchItemsRemoved(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
Definition: schematic.h:60
virtual void OnSchItemsChanged(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
Definition: schematic.h:61
virtual void OnSchSheetChanged(SCHEMATIC &aSch)
Definition: schematic.h:64
virtual void OnSchItemsAdded(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
Definition: schematic.h:59
These settings were stored in SCH_BASE_FRAME previously.
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:128
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
Definition: schematic.cpp:603
void OnItemsAdded(std::vector< SCH_ITEM * > &aNewItems)
Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for listeners.
Definition: schematic.cpp:766
CONNECTION_GRAPH * m_connectionGraph
Holds and calculates connectivity information of this schematic.
Definition: schematic.h:329
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:136
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
Definition: schematic.cpp:840
void RemoveListener(SCHEMATIC_LISTENER *aListener)
Remove the specified listener.
Definition: schematic.cpp:797
void OnSchSheetChanged()
Notify the schematic and its listeners that the current sheet has been changed.
Definition: schematic.cpp:784
SCH_SHEET_PATH * m_currentSheet
The sheet path of the sheet currently being edited or displayed.
Definition: schematic.h:326
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:718
void OnItemsRemoved(std::vector< SCH_ITEM * > &aRemovedItems)
Must be used if Remove() is used using a BULK_x REMOVE_MODE to generate a change event for listeners.
Definition: schematic.cpp:772
virtual ~SCHEMATIC()
Definition: schematic.cpp:121
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aLabel) const
Return a pointer to a bus alias object for the given label, or null if one doesn't exist.
Definition: schematic.cpp:377
std::vector< SCH_MARKER * > ResolveERCExclusions()
Definition: schematic.cpp:301
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
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:541
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: schematic.cpp:815
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition: schematic.h:177
SCH_SHEET_LIST & GetFullHierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:592
void FixupJunctions()
Add junctions to this schematic where required.
Definition: schematic.cpp:738
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:100
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:473
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
Definition: schematic.cpp:184
void SetProject(PROJECT *aPrj)
Definition: schematic.cpp:154
void AddListener(SCHEMATIC_LISTENER *aListener)
Add a listener to the schematic to receive calls whenever something on the schematic has been modifie...
Definition: schematic.cpp:790
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
Definition: schematic.cpp:462
PROJECT * m_project
Definition: schematic.h:315
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:197
SCHEMATIC(PROJECT *aPrj)
Definition: schematic.cpp:40
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
Definition: schematic.cpp:228
std::set< wxString > GetNetClassAssignmentCandidates()
Return the set of netname candidates for netclass assignment.
Definition: schematic.cpp:392
void RecomputeIntersheetRefs(const std::function< void(SCH_GLOBALLABEL *)> &aItemCallback)
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
Definition: schematic.cpp:656
void InvokeListeners(Func &&aFunc, Args &&... args)
Definition: schematic.h:309
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:121
void RemoveAllListeners()
Remove all listeners.
Definition: schematic.cpp:809
void GetContextualTextVars(wxArrayString *aVars) const
Definition: schematic.cpp:203
SCH_SHEET & Root() const
Definition: schematic.h:105
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
Definition: schematic.cpp:446
wxString GetUniqueFilenameForCurrentSheet()
Definition: schematic.cpp:611
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
Definition: schematic.cpp:627
std::vector< SCHEMATIC_LISTENER * > m_listeners
Currently installed listeners.
Definition: schematic.h:350
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:90
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:411
std::map< wxString, double > m_operatingPoints
Simulation operating points for text variable substitution.
Definition: schematic.h:345
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:294
void OnItemsChanged(std::vector< SCH_ITEM * > &aItems)
Notify the schematic and its listeners that an item on the schematic has been modified in some way.
Definition: schematic.cpp:778
SCH_SHEET * m_rootSheet
The top-level sheet in this schematic hierarchy (or potentially the only one)
Definition: schematic.h:318
bool IsBus() const
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:52
int GetId() const
Definition: sch_field.h:128
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:165
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
SCH_LINE * BreakAt(const VECTOR2I &aPoint)
Break this segment into two at the specified point.
Definition: sch_line.cpp:591
wxString Serialize() const
Definition: sch_marker.cpp:91
bool IsLegacyMarker() const
Determines if this marker is legacy (i.e.
Definition: sch_marker.h:122
static SCH_MARKER * Deserialize(SCHEMATIC *schematic, const wxString &data)
Definition: sch_marker.cpp:112
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
size_t GetCount() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:704
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:150
std::vector< SCH_LINE * > GetBusesAndWires(const VECTOR2I &aPosition, bool aIgnoreEndpoints=false) const
Return buses and wires passing through aPosition.
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
const wxString & GetFileName() const
Definition: sch_screen.h:144
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:155
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:313
std::vector< VECTOR2I > GetNeededJunctions(const std::deque< EDA_ITEM * > &aItems) const
Return the unique set of points belonging to aItems where a junction is needed.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
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.
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
void SetVirtualPageNumber(int aPageNumber)
Set the sheet instance virtual page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void clear()
Forwarded method from std::vector.
size_t size() const
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
wxString GetName() const
Definition: sch_sheet.h:107
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
Definition: sch_sheet.cpp:788
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:110
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:237
Schematic symbol object.
Definition: sch_symbol.h:109
int GetUnit() const
Definition: sch_symbol.h:258
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:748
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:203
Helper class to recognize Spice formatted values.
Definition: spice_value.h:56
wxString ToString() const
Return string value as when converting double to string (e.g.
bool TextVarResolver(wxString *aToken, const PROJECT *aProject) const
Definition: title_block.cpp:96
static void GetContextualTextVars(wxArrayString *aVars)
Definition: title_block.cpp:74
wxString GetTextVars(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition: common.cpp:115
#define _HKI(x)
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
void ignore_unused(const T &)
Definition: ignore.h:24
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
#define TYPE_HASH(x)
Definition: property.h:67
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ SCH_SYMBOL_T
Definition: typeinfo.h:160
@ SCH_SHEET_T
Definition: typeinfo.h:162
@ SCH_MARKER_T
Definition: typeinfo.h:143
@ SCHEMATIC_T
Definition: typeinfo.h:192
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:156