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 The 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 <core/profile.h>
26#include <sch_collectors.h>
27#include <erc/erc_settings.h>
28#include <font/outline_font.h>
30#include <progress_reporter.h>
31#include <project.h>
34#include <refdes_tracker.h>
35#include <schematic.h>
36#include <sch_bus_entry.h>
37#include <sch_commit.h>
38#include <sch_junction.h>
39#include <sch_label.h>
40#include <sch_line.h>
41#include <sch_marker.h>
42#include <sch_no_connect.h>
43#include <sch_rule_area.h>
44#include <sch_screen.h>
45#include <sch_sheet_pin.h>
46#include <sch_selection_tool.h>
47#include <sim/spice_settings.h>
48#include <sim/spice_value.h>
49#include <tool/tool_manager.h>
50#include <undo_redo_container.h>
51
52#include <wx/log.h>
53
55
57 EDA_ITEM( nullptr, SCHEMATIC_T ),
58 m_project( nullptr ),
59 m_rootSheet( nullptr ),
60 m_schematicHolder( nullptr )
61{
65
66 SetProject( aPrj );
67
69 [&]( INSPECTABLE* aItem, PROPERTY_BASE* aProperty, COMMIT* aCommit )
70 {
71 // Special case: propagate value, footprint, and datasheet fields to other units
72 // of a given symbol if they aren't in the selection
73
74 SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem );
75
76 if( !field || !IsValid() )
77 return;
78
79 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( field->GetParent() );
80
81 if( !symbol || aProperty->Name() != _HKI( "Text" ) )
82 return;
83
84 // TODO(JE) This will need to get smarter to enable API access
85 SCH_SHEET_PATH sheetPath = CurrentSheet();
86
87 wxString newValue = aItem->Get<wxString>( aProperty );
88
89 if( field->GetId() == FIELD_T::REFERENCE )
90 {
91 symbol->SetRef( &sheetPath, newValue );
92
93 // The user might want to change all the units to the new ref. Or they
94 // might not. Since we have no way of knowing, we default to the most
95 // concrete action (change only the selected reference).
96 return;
97 }
98
99 wxString ref = symbol->GetRef( &sheetPath );
100 int unit = symbol->GetUnit();
101 LIB_ID libId = symbol->GetLibId();
102
103 for( SCH_SHEET_PATH& sheet : Hierarchy() )
104 {
105 std::vector<SCH_SYMBOL*> otherUnits;
106
107 CollectOtherUnits( ref, unit, libId, sheet, &otherUnits );
108
109 for( SCH_SYMBOL* otherUnit : otherUnits )
110 {
111 switch( field->GetId() )
112 {
113 case FIELD_T::VALUE:
114 case FIELD_T::FOOTPRINT:
115 case FIELD_T::DATASHEET:
116 {
117 if( aCommit )
118 aCommit->Modify( otherUnit, sheet.LastScreen() );
119
120 otherUnit->GetField( field->GetId() )->SetText( newValue );
121 break;
122 }
123
124 default:
125 break;
126 }
127 }
128 }
129 } );
130}
131
132
134{
136
137 delete m_currentSheet;
138 delete m_connectionGraph;
139
140 m_IsSchematicExists = false;
141}
142
143
145{
147 {
149
150 // d'tor will save settings to file
151 delete project.m_ErcSettings;
152 project.m_ErcSettings = nullptr;
153
154 // d'tor will save settings to file
155 delete project.m_SchematicSettings;
156 project.m_SchematicSettings = nullptr;
157
158 m_project = nullptr; // clear the project, so we don't do this again when setting a new one
159 }
160
161 delete m_rootSheet;
162
163 m_rootSheet = nullptr;
164
167}
168
169
171{
172 if( m_project )
173 {
175
176 // d'tor will save settings to file
177 delete project.m_ErcSettings;
178 project.m_ErcSettings = nullptr;
179
180 // d'tor will save settings to file
181 delete project.m_SchematicSettings;
182 project.m_SchematicSettings = nullptr;
183 }
184
185 m_project = aPrj;
186
187 if( m_project )
188 {
190 project.m_ErcSettings = new ERC_SETTINGS( &project, "erc" );
191 project.m_SchematicSettings = new SCHEMATIC_SETTINGS( &project, "schematic" );
192
193 project.m_SchematicSettings->LoadFromFile();
194 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
195 project.m_ErcSettings->LoadFromFile();
196 }
197}
198
199
201{
202 wxASSERT( m_project );
203
204 // Cache all existing annotations in the REFDES_TRACKER
205 std::shared_ptr<REFDES_TRACKER> refdesTracker = m_project->GetProjectFile().m_SchematicSettings->m_refDesTracker;
206
207 SCH_SHEET_LIST sheets = Hierarchy();
208 SCH_REFERENCE_LIST references;
209
210 sheets.GetSymbols( references );
211
212 for( const SCH_REFERENCE& ref : references )
213 {
214 refdesTracker->Insert( ref.GetFullRef( false ).ToStdString() );
215 }
216}
217
218
219bool SCHEMATIC::Contains( const SCH_REFERENCE& aRef ) const
220{
221 SCH_SHEET_LIST sheets = Hierarchy();
222 SCH_REFERENCE_LIST references;
223
228 sheets.GetSymbols( references );
229
230 return std::any_of( references.begin(), references.end(),
231 [&]( const SCH_REFERENCE& ref )
232 {
233 return ref.GetFullRef( true ) == aRef.GetFullRef( true );
234 } );
235}
236
237
238void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet )
239{
240 wxCHECK_RET( aRootSheet, wxS( "Call to SetRoot with null SCH_SHEET!" ) );
241
242 m_rootSheet = aRootSheet;
243
246
249}
250
251
253{
254 return IsValid() ? m_rootSheet->GetScreen() : nullptr;
255}
256
257
259{
260 wxCHECK( !m_hierarchy.empty(), m_hierarchy );
261
262 return m_hierarchy;
263}
264
265
267{
269}
270
271
272void SCHEMATIC::GetContextualTextVars( wxArrayString* aVars ) const
273{
274 auto add =
275 [&]( const wxString& aVar )
276 {
277 if( !alg::contains( *aVars, aVar ) )
278 aVars->push_back( aVar );
279 };
280
281 add( wxT( "#" ) );
282 add( wxT( "##" ) );
283 add( wxT( "SHEETPATH" ) );
284 add( wxT( "SHEETNAME" ) );
285 add( wxT( "FILENAME" ) );
286 add( wxT( "FILEPATH" ) );
287 add( wxT( "PROJECTNAME" ) );
288
289 if( !CurrentSheet().empty() )
291
292 for( std::pair<wxString, wxString> entry : m_project->GetTextVars() )
293 add( entry.first );
294}
295
296
297bool SCHEMATIC::ResolveTextVar( const SCH_SHEET_PATH* aSheetPath, wxString* token,
298 int aDepth ) const
299{
300 wxCHECK( aSheetPath, false );
301
302 if( token->IsSameAs( wxT( "#" ) ) )
303 {
304 *token = aSheetPath->GetPageNumber();
305 return true;
306 }
307 else if( token->IsSameAs( wxT( "##" ) ) )
308 {
309 *token = wxString::Format( "%i", Root().CountSheets() );
310 return true;
311 }
312 else if( token->IsSameAs( wxT( "SHEETPATH" ) ) )
313 {
314 *token = aSheetPath->PathHumanReadable();
315 return true;
316 }
317 else if( token->IsSameAs( wxT( "SHEETNAME" ) ) )
318 {
319 *token = aSheetPath->Last()->GetName();
320 return true;
321 }
322 else if( token->IsSameAs( wxT( "FILENAME" ) ) )
323 {
324 wxFileName fn( GetFileName() );
325 *token = fn.GetFullName();
326 return true;
327 }
328 else if( token->IsSameAs( wxT( "FILEPATH" ) ) )
329 {
330 wxFileName fn( GetFileName() );
331 *token = fn.GetFullPath();
332 return true;
333 }
334 else if( token->IsSameAs( wxT( "PROJECTNAME" ) ) )
335 {
336 *token = m_project->GetProjectName();
337 return true;
338 }
339
340 if( aSheetPath->LastScreen()->GetTitleBlock().TextVarResolver( token, m_project ) )
341 return true;
342
343 if( m_project->TextVarResolver( token ) )
344 return true;
345
346 return false;
347}
348
349
351{
352 return IsValid() ? m_rootSheet->GetScreen()->GetFileName() : wxString( wxEmptyString );
353}
354
355
357{
358 wxASSERT( m_project );
360}
361
362
364{
365 wxASSERT( m_project );
367}
368
369
370std::vector<SCH_MARKER*> SCHEMATIC::ResolveERCExclusions()
371{
372 SCH_SHEET_LIST sheetList = Hierarchy();
373 ERC_SETTINGS& settings = ErcSettings();
374
375 // Migrate legacy marker exclusions to new format to ensure exclusion matching functions across
376 // file versions. Silently drops any legacy exclusions which can not be mapped to the new format
377 // without risking an incorrect exclusion - this is preferable to silently dropping
378 // new ERC errors / warnings due to an incorrect match between a legacy and new
379 // marker serialization format
380 std::set<wxString> migratedExclusions;
381
382 for( auto it = settings.m_ErcExclusions.begin(); it != settings.m_ErcExclusions.end(); )
383 {
384 SCH_MARKER* testMarker = SCH_MARKER::DeserializeFromString( sheetList, *it );
385
386 if( !testMarker )
387 {
388 it = settings.m_ErcExclusions.erase( it );
389 continue;
390 }
391
392 if( testMarker->IsLegacyMarker() )
393 {
394 const wxString settingsKey = testMarker->GetRCItem()->GetSettingsKey();
395
396 if( settingsKey != wxT( "pin_to_pin" )
397 && settingsKey != wxT( "hier_label_mismatch" )
398 && settingsKey != wxT( "different_unit_net" ) )
399 {
400 migratedExclusions.insert( testMarker->SerializeToString() );
401 }
402
403 it = settings.m_ErcExclusions.erase( it );
404 }
405 else
406 {
407 ++it;
408 }
409
410 delete testMarker;
411 }
412
413 settings.m_ErcExclusions.insert( migratedExclusions.begin(), migratedExclusions.end() );
414
415 // End of legacy exclusion removal / migrations
416
417 for( const SCH_SHEET_PATH& sheet : sheetList )
418 {
419 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_MARKER_T ) )
420 {
421 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
422 wxString serialized = marker->SerializeToString();
423 std::set<wxString>::iterator it = settings.m_ErcExclusions.find( serialized );
424
425 if( it != settings.m_ErcExclusions.end() )
426 {
427 marker->SetExcluded( true, settings.m_ErcExclusionComments[serialized] );
428 settings.m_ErcExclusions.erase( it );
429 }
430 }
431 }
432
433 std::vector<SCH_MARKER*> newMarkers;
434
435 for( const wxString& serialized : settings.m_ErcExclusions )
436 {
437 SCH_MARKER* marker = SCH_MARKER::DeserializeFromString( sheetList, serialized );
438
439 if( marker )
440 {
441 marker->SetExcluded( true, settings.m_ErcExclusionComments[serialized] );
442 newMarkers.push_back( marker );
443 }
444 }
445
446 settings.m_ErcExclusions.clear();
447
448 return newMarkers;
449}
450
451
452std::shared_ptr<BUS_ALIAS> SCHEMATIC::GetBusAlias( const wxString& aLabel ) const
453{
454 for( const SCH_SHEET_PATH& sheet : Hierarchy() )
455 {
456 for( const std::shared_ptr<BUS_ALIAS>& alias : sheet.LastScreen()->GetBusAliases() )
457 {
458 if( alias->GetName() == aLabel )
459 return alias;
460 }
461 }
462
463 return nullptr;
464}
465
466
468{
469 std::set<wxString> names;
470
471 for( const auto& [ key, subgraphList ] : m_connectionGraph->GetNetMap() )
472 {
473 CONNECTION_SUBGRAPH* firstSubgraph = subgraphList[0];
474
475 if( !firstSubgraph->GetDriverConnection()->IsBus()
477 {
478 names.insert( key.Name );
479 }
480 }
481
482 return names;
483}
484
485
486bool SCHEMATIC::ResolveCrossReference( wxString* token, int aDepth ) const
487{
488 wxString remainder;
489 wxString ref = token->BeforeFirst( ':', &remainder );
490 KIID_PATH path( ref );
491 KIID uuid = path.back();
492 SCH_SHEET_PATH sheetPath;
493 SCH_ITEM* refItem = ResolveItem( KIID( uuid ), &sheetPath, true );
494
495 if( path.size() > 1 )
496 {
497 path.pop_back();
498 sheetPath = Hierarchy().GetSheetPathByKIIDPath( path ).value_or( sheetPath );
499 }
500
501 if( refItem && refItem->Type() == SCH_SYMBOL_T )
502 {
503 SCH_SYMBOL* refSymbol = static_cast<SCH_SYMBOL*>( refItem );
504
505 if( refSymbol->ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
506 *token = std::move( remainder );
507 else
508 *token = refSymbol->GetRef( &sheetPath, true ) + wxS( ":" ) + remainder;
509
510 return true; // Cross-reference is resolved whether or not the actual textvar was
511 }
512 else if( refItem && refItem->Type() == SCH_SHEET_T )
513 {
514 SCH_SHEET* refSheet = static_cast<SCH_SHEET*>( refItem );
515
516 sheetPath.push_back( refSheet );
517
518 if( refSheet->ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
519 *token = std::move( remainder );
520
521 return true; // Cross-reference is resolved whether or not the actual textvar was
522 }
523
524 return false;
525}
526
527
528std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetNamesMap() const
529{
530 std::map<int, wxString> namesMap;
531
532 for( const SCH_SHEET_PATH& sheet : Hierarchy() )
533 {
534 if( sheet.size() == 1 )
535 namesMap[sheet.GetVirtualPageNumber()] = _( "<root sheet>" );
536 else
537 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
538 }
539
540 return namesMap;
541}
542
543
544std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetPagesMap() const
545{
546 std::map<int, wxString> pagesMap;
547
548 for( const SCH_SHEET_PATH& sheet : Hierarchy() )
549 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
550
551 return pagesMap;
552}
553
554
555wxString SCHEMATIC::ConvertRefsToKIIDs( const wxString& aSource ) const
556{
557 wxString newbuf;
558 size_t sourceLen = aSource.length();
559
560 for( size_t i = 0; i < sourceLen; ++i )
561 {
562 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
563 {
564 wxString token;
565 bool isCrossRef = false;
566 int nesting = 0;
567
568 for( i = i + 2; i < sourceLen; ++i )
569 {
570 if( aSource[i] == '{'
571 && ( aSource[i-1] == '_' || aSource[i-1] == '^' || aSource[i-1] == '~' ) )
572 {
573 nesting++;
574 }
575
576 if( aSource[i] == '}' )
577 {
578 nesting--;
579
580 if( nesting < 0 )
581 break;
582 }
583
584 if( aSource[i] == ':' )
585 isCrossRef = true;
586
587 token.append( aSource[i] );
588 }
589
590 if( isCrossRef )
591 {
592 wxString remainder;
593 wxString ref = token.BeforeFirst( ':', &remainder );
594 SCH_REFERENCE_LIST references;
595
596 Hierarchy().GetSymbols( references );
597
598 for( size_t jj = 0; jj < references.GetCount(); jj++ )
599 {
600 SCH_SYMBOL* refSymbol = references[ jj ].GetSymbol();
601
602 if( ref == refSymbol->GetRef( &references[ jj ].GetSheetPath(), true ) )
603 {
604 KIID_PATH path = references[ jj ].GetSheetPath().Path();
605 path.push_back( refSymbol->m_Uuid );
606
607 token = path.AsString() + wxS( ":" ) + remainder;
608 break;
609 }
610 }
611 }
612
613 newbuf.append( wxS( "${" ) + token + wxS( "}" ) );
614 }
615 else
616 {
617 newbuf.append( aSource[i] );
618 }
619 }
620
621 return newbuf;
622}
623
624
625wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const
626{
627 wxString newbuf;
628 size_t sourceLen = aSource.length();
629
630 for( size_t i = 0; i < sourceLen; ++i )
631 {
632 if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
633 {
634 wxString token;
635 bool isCrossRef = false;
636
637 for( i = i + 2; i < sourceLen; ++i )
638 {
639 if( aSource[i] == '}' )
640 break;
641
642 if( aSource[i] == ':' )
643 isCrossRef = true;
644
645 token.append( aSource[i] );
646 }
647
648 if( isCrossRef )
649 {
650 wxString remainder;
651 wxString ref = token.BeforeFirst( ':', &remainder );
652 KIID_PATH path( ref );
653 KIID uuid = path.back();
654 SCH_SHEET_PATH sheetPath;
655 SCH_ITEM* refItem = ResolveItem( uuid, &sheetPath, true );
656
657 if( path.size() > 1 )
658 {
659 path.pop_back();
660 sheetPath = Hierarchy().GetSheetPathByKIIDPath( path ).value_or( sheetPath );
661 }
662
663 if( refItem && refItem->Type() == SCH_SYMBOL_T )
664 {
665 SCH_SYMBOL* refSymbol = static_cast<SCH_SYMBOL*>( refItem );
666 token = refSymbol->GetRef( &sheetPath, true ) + wxS( ":" ) + remainder;
667 }
668 }
669
670 newbuf.append( wxS( "${" ) + token + wxS( "}" ) );
671 }
672 else
673 {
674 newbuf.append( aSource[i] );
675 }
676 }
677
678 return newbuf;
679}
680
681
683{
684 SCH_SCREENS screens( m_rootSheet );
685
687}
688
689
691{
692 // Filename is rootSheetName-sheetName-...-sheetName
693 // Note that we need to fetch the rootSheetName out of its filename, as the root SCH_SHEET's
694 // name is just a timestamp.
695
696 wxFileName rootFn( CurrentSheet().at( 0 )->GetFileName() );
697 wxString filename = rootFn.GetName();
698
699 for( unsigned i = 1; i < CurrentSheet().size(); i++ )
700 filename += wxT( "-" ) + CurrentSheet().at( i )->GetName();
701
702 return filename;
703}
704
705
707{
708 SCH_SCREEN* screen;
709 SCH_SCREENS s_list( Root() );
710
711 // Set the sheet count, and the sheet number (1 for root sheet)
712 int sheet_count = Root().CountSheets();
713 int sheet_number = 1;
714 const KIID_PATH& current_sheetpath = CurrentSheet().Path();
715
716 // @todo Remove all pseudo page number system is left over from prior to real page number
717 // implementation.
718 for( const SCH_SHEET_PATH& sheet : Hierarchy() )
719 {
720 if( sheet.Path() == current_sheetpath ) // Current sheet path found
721 break;
722
723 sheet_number++; // Not found, increment before this current path
724 }
725
726 for( screen = s_list.GetFirst(); screen != nullptr; screen = s_list.GetNext() )
727 screen->SetPageCount( sheet_count );
728
729 CurrentSheet().SetVirtualPageNumber( sheet_number );
730 CurrentSheet().LastScreen()->SetVirtualPageNumber( sheet_number );
731 CurrentSheet().LastScreen()->SetPageNumber( CurrentSheet().GetPageNumber() );
732}
733
734
736{
737 std::map<wxString, std::set<int>>& pageRefsMap = GetPageRefsMap();
738
739 pageRefsMap.clear();
740
741 for( const SCH_SHEET_PATH& sheet : Hierarchy() )
742 {
743 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_GLOBAL_LABEL_T ) )
744 {
745 SCH_GLOBALLABEL* global = static_cast<SCH_GLOBALLABEL*>( item );
746 wxString resolvedLabel = global->GetShownText( &sheet, false );
747
748 pageRefsMap[ resolvedLabel ].insert( sheet.GetVirtualPageNumber() );
749 }
750 }
751
752 bool show = Settings().m_IntersheetRefsShow;
753
754 // Refresh all visible global labels. Note that we have to collect them first as the
755 // SCH_SCREEN::Update() call is going to invalidate the RTree iterator.
756
757 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
758
759 for( EDA_ITEM* item : CurrentSheet().LastScreen()->Items().OfType( SCH_GLOBAL_LABEL_T ) )
760 currentSheetGlobalLabels.push_back( static_cast<SCH_GLOBALLABEL*>( item ) );
761
762 for( SCH_GLOBALLABEL* globalLabel : currentSheetGlobalLabels )
763 {
764 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
765
766 fields[0].SetVisible( show );
767
768 if( show )
769 {
770 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
771 globalLabel->AutoplaceFields( CurrentSheet().LastScreen(), AUTOPLACE_AUTO );
772
773 CurrentSheet().LastScreen()->Update( globalLabel );
774
775 for( SCH_FIELD& field : globalLabel->GetFields() )
776 field.ClearBoundingBoxCache();
777
778 globalLabel->ClearBoundingBoxCache();
779
782 }
783 }
784}
785
786
787wxString SCHEMATIC::GetOperatingPoint( const wxString& aNetName, int aPrecision,
788 const wxString& aRange )
789{
790 wxString spiceNetName( aNetName.Lower() );
792
793 if( spiceNetName == wxS( "gnd" ) || spiceNetName == wxS( "0" ) )
794 return wxEmptyString;
795
796 auto it = m_operatingPoints.find( spiceNetName );
797
798 if( it != m_operatingPoints.end() )
799 return SPICE_VALUE( it->second ).ToString( { aPrecision, aRange } );
800 else if( m_operatingPoints.empty() )
801 return wxS( "--" );
802 else
803 return wxS( "?" );
804}
805
806
808{
809 SCH_SCREENS screens( Root() );
810
811 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
812 {
813 std::deque<EDA_ITEM*> allItems;
814
815 for( SCH_ITEM* item : screen->Items() )
816 allItems.push_back( item );
817
818 // Add missing junctions and breakup wires as needed
819 for( const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
820 {
821 SCH_JUNCTION* junction = new SCH_JUNCTION( point );
822 screen->Append( junction );
823
824 // Breakup wires
825 for( SCH_LINE* wire : screen->GetBusesAndWires( point, true ) )
826 {
827 SCH_LINE* newSegment = wire->NonGroupAware_BreakAt( point );
828 screen->Append( newSegment );
829 }
830 }
831 }
832}
833
834
835void SCHEMATIC::OnItemsAdded( std::vector<SCH_ITEM*>& aNewItems )
836{
838}
839
840
841void SCHEMATIC::OnItemsRemoved( std::vector<SCH_ITEM*>& aRemovedItems )
842{
844}
845
846
847void SCHEMATIC::OnItemsChanged( std::vector<SCH_ITEM*>& aItems )
848{
850}
851
852
854{
856}
857
858
860{
861 if( !alg::contains( m_listeners, aListener ) )
862 m_listeners.push_back( aListener );
863}
864
865
867{
868 auto i = std::find( m_listeners.begin(), m_listeners.end(), aListener );
869
870 if( i != m_listeners.end() )
871 {
872 std::iter_swap( i, m_listeners.end() - 1 );
873 m_listeners.pop_back();
874 }
875}
876
877
879{
880 m_listeners.clear();
881}
882
883
885{
886 // Use a sorted sheetList to reduce file churn
887 SCH_SHEET_LIST sheetList = Hierarchy();
888 ERC_SETTINGS& ercSettings = ErcSettings();
889
890 ercSettings.m_ErcExclusions.clear();
891 ercSettings.m_ErcExclusionComments.clear();
892
893 for( unsigned i = 0; i < sheetList.size(); i++ )
894 {
895 for( SCH_ITEM* item : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
896 {
897 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
898
899 if( marker->IsExcluded() )
900 {
901 wxString serialized = marker->SerializeToString();
902 ercSettings.m_ErcExclusions.insert( serialized );
903 ercSettings.m_ErcExclusionComments[ serialized ] = marker->GetComment();
904 }
905 }
906 }
907}
908
909
911{
912 SCH_SHEET_LIST sheetList = Hierarchy();
913
914 for( SCH_MARKER* marker : ResolveERCExclusions() )
915 {
916 SCH_SHEET_PATH errorPath;
917 ignore_unused( sheetList.ResolveItem( marker->GetRCItem()->GetMainItemID(), &errorPath ) );
918
919 if( errorPath.LastScreen() )
920 errorPath.LastScreen()->Append( marker );
921 else
922 RootScreen()->Append( marker );
923 }
924}
925
926
928{
929 return static_cast<EMBEDDED_FILES*>( this );
930}
931
932
934{
935 return static_cast<const EMBEDDED_FILES*>( this );
936}
937
938
939void SCHEMATIC::RunOnNestedEmbeddedFiles( const std::function<void( EMBEDDED_FILES* )>& aFunction )
940{
941 SCH_SCREENS screens( Root() );
942
943 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
944 {
945 for( auto& [name, libSym] : screen->GetLibSymbols() )
946 aFunction( libSym->GetEmbeddedFiles() );
947 }
948}
949
950
951std::set<KIFONT::OUTLINE_FONT*> SCHEMATIC::GetFonts() const
952{
953 std::set<KIFONT::OUTLINE_FONT*> fonts;
954
955 SCH_SHEET_LIST sheetList = Hierarchy();
956
957 for( const SCH_SHEET_PATH& sheet : sheetList )
958 {
959 for( SCH_ITEM* item : sheet.LastScreen()->Items() )
960 {
961 if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item ) )
962 {
963 KIFONT::FONT* font = text->GetFont();
964
965 if( !font || font->IsStroke() )
966 continue;
967
968 using EMBEDDING_PERMISSION = KIFONT::OUTLINE_FONT::EMBEDDING_PERMISSION;
969 auto* outline = static_cast<KIFONT::OUTLINE_FONT*>( font );
970
971 if( outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::EDITABLE
972 || outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::INSTALLABLE )
973 {
974 fonts.insert( outline );
975 }
976 }
977 }
978 }
979
980 return fonts;
981}
982
983
985{
986 std::set<KIFONT::OUTLINE_FONT*> fonts = GetFonts();
987
988 for( KIFONT::OUTLINE_FONT* font : fonts )
989 {
990 auto file = GetEmbeddedFiles()->AddFile( font->GetFileName(), false );
991
992 if( !file )
993 {
994 wxLogTrace( "EMBED", "Failed to add font file: %s", font->GetFileName() );
995 continue;
996 }
997
999 }
1000}
1001
1002
1003std::set<const SCH_SCREEN*> SCHEMATIC::GetSchematicsSharedByMultipleProjects() const
1004{
1005 std::set<const SCH_SCREEN*> retv;
1006
1007 wxCHECK( m_rootSheet, retv );
1008
1009 SCH_SHEET_LIST hierarchy( m_rootSheet );
1010 SCH_SCREENS screens( m_rootSheet );
1011
1012 for( const SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
1013 {
1014 for( const SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
1015 {
1016 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
1017
1018 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->GetInstances();
1019
1020 for( const SCH_SYMBOL_INSTANCE& instance : symbolInstances )
1021 {
1022 if( !hierarchy.HasPath( instance.m_Path ) )
1023 {
1024 retv.insert( screen );
1025 break;
1026 }
1027 }
1028
1029 if( retv.count( screen ) )
1030 break;
1031 }
1032 }
1033
1034 return retv;
1035}
1036
1037
1039{
1040 wxCHECK( m_rootSheet, false );
1041
1042 SCH_SCREENS screens( m_rootSheet );
1043
1044 for( const SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
1045 {
1046 wxCHECK2( screen, continue );
1047
1048 if( screen->GetRefCount() > 1 )
1049 return true;
1050 }
1051
1052 return false;
1053}
1054
1055
1056void SCHEMATIC::BreakSegment( SCH_COMMIT* aCommit, SCH_LINE* aSegment, const VECTOR2I& aPoint,
1057 SCH_LINE** aNewSegment, SCH_SCREEN* aScreen )
1058{
1059 // Save the copy of aSegment before breaking it
1060 aCommit->Modify( aSegment, aScreen );
1061
1062 SCH_LINE* newSegment = aSegment->BreakAt( aCommit, aPoint );
1063
1064 aSegment->SetFlags( IS_CHANGED | IS_BROKEN );
1065 newSegment->SetFlags( IS_NEW | IS_BROKEN );
1066
1067 if( m_schematicHolder )
1068 m_schematicHolder->AddToScreen( newSegment, aScreen );
1069
1070 aCommit->Added( newSegment, aScreen );
1071
1072 *aNewSegment = newSegment;
1073}
1074
1075
1076bool SCHEMATIC::BreakSegments( SCH_COMMIT* aCommit, const VECTOR2I& aPos, SCH_SCREEN* aScreen )
1077{
1078 bool brokenSegments = false;
1079 SCH_LINE* new_line;
1080
1081 for( SCH_LINE* wire : aScreen->GetBusesAndWires( aPos, true ) )
1082 {
1083 BreakSegment( aCommit, wire, aPos, &new_line, aScreen );
1084 brokenSegments = true;
1085 }
1086
1087 return brokenSegments;
1088}
1089
1090
1092{
1093 bool brokenSegments = false;
1094
1095 std::set<VECTOR2I> point_set;
1096
1097 for( SCH_ITEM* item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
1098 point_set.insert( item->GetPosition() );
1099
1100 for( SCH_ITEM* item : aScreen->Items().OfType( SCH_BUS_WIRE_ENTRY_T ) )
1101 {
1102 SCH_BUS_WIRE_ENTRY* entry = static_cast<SCH_BUS_WIRE_ENTRY*>( item );
1103 point_set.insert( entry->GetPosition() );
1104 point_set.insert( entry->GetEnd() );
1105 }
1106
1107 for( const VECTOR2I& pt : point_set )
1108 {
1109 BreakSegments( aCommit, pt, aScreen );
1110 brokenSegments = true;
1111 }
1112
1113 return brokenSegments;
1114}
1115
1116
1117void SCHEMATIC::CleanUp( SCH_COMMIT* aCommit, SCH_SCREEN* aScreen )
1118{
1120 std::vector<SCH_LINE*> lines;
1121 std::vector<SCH_JUNCTION*> junctions;
1122 std::vector<SCH_NO_CONNECT*> ncs;
1123 std::vector<SCH_ITEM*> items_to_remove;
1124 bool changed = true;
1125
1126 if( aScreen == nullptr )
1127 aScreen = GetCurrentScreen();
1128
1129 auto remove_item = [&]( SCH_ITEM* aItem ) -> void
1130 {
1131 changed = true;
1132
1133 if( !( aItem->GetFlags() & STRUCT_DELETED ) )
1134 {
1135 aItem->SetFlags( STRUCT_DELETED );
1136
1137 if( aItem->IsSelected() && selectionTool )
1138 selectionTool->RemoveItemFromSel( aItem, true /*quiet mode*/ );
1139
1140 if( m_schematicHolder )
1141 {
1142 m_schematicHolder->RemoveFromScreen( aItem, aScreen );
1143 }
1144 aCommit->Removed( aItem, aScreen );
1145 }
1146 };
1147
1148 BreakSegmentsOnJunctions( aCommit, aScreen );
1149
1150 for( SCH_ITEM* item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
1151 {
1152 if( !aScreen->IsExplicitJunction( item->GetPosition() ) )
1153 items_to_remove.push_back( item );
1154 else
1155 junctions.push_back( static_cast<SCH_JUNCTION*>( item ) );
1156 }
1157
1158 for( SCH_ITEM* item : items_to_remove )
1159 remove_item( item );
1160
1161 for( SCH_ITEM* item : aScreen->Items().OfType( SCH_NO_CONNECT_T ) )
1162 ncs.push_back( static_cast<SCH_NO_CONNECT*>( item ) );
1163
1164 alg::for_all_pairs( junctions.begin(), junctions.end(),
1165 [&]( SCH_JUNCTION* aFirst, SCH_JUNCTION* aSecond )
1166 {
1167 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1168 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1169 {
1170 return;
1171 }
1172
1173 if( aFirst->GetPosition() == aSecond->GetPosition() )
1174 remove_item( aSecond );
1175 } );
1176
1177 alg::for_all_pairs( ncs.begin(), ncs.end(),
1178 [&]( SCH_NO_CONNECT* aFirst, SCH_NO_CONNECT* aSecond )
1179 {
1180 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1181 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1182 {
1183 return;
1184 }
1185
1186 if( aFirst->GetPosition() == aSecond->GetPosition() )
1187 remove_item( aSecond );
1188 } );
1189
1190
1191 auto minX = []( const SCH_LINE* l )
1192 {
1193 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
1194 };
1195
1196 auto maxX = []( const SCH_LINE* l )
1197 {
1198 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
1199 };
1200
1201 auto minY = []( const SCH_LINE* l )
1202 {
1203 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
1204 };
1205
1206 auto maxY = []( const SCH_LINE* l )
1207 {
1208 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
1209 };
1210
1211 // Would be nice to put lines in a canonical form here by swapping
1212 // start <-> end as needed but I don't know what swapping breaks.
1213 while( changed )
1214 {
1215 changed = false;
1216 lines.clear();
1217
1218 for( SCH_ITEM* item : aScreen->Items().OfType( SCH_LINE_T ) )
1219 {
1220 if( item->GetLayer() == LAYER_WIRE || item->GetLayer() == LAYER_BUS )
1221 lines.push_back( static_cast<SCH_LINE*>( item ) );
1222 }
1223
1224 // Sort by minimum X position
1225 std::sort( lines.begin(), lines.end(),
1226 [&]( const SCH_LINE* a, const SCH_LINE* b )
1227 {
1228 return minX( a ) < minX( b );
1229 } );
1230
1231 for( auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
1232 {
1233 SCH_LINE* firstLine = *it1;
1234
1235 if( firstLine->GetEditFlags() & STRUCT_DELETED )
1236 continue;
1237
1238 if( firstLine->IsNull() )
1239 {
1240 remove_item( firstLine );
1241 continue;
1242 }
1243
1244 int firstRightXEdge = maxX( firstLine );
1245 auto it2 = it1;
1246
1247 for( ++it2; it2 != lines.end(); ++it2 )
1248 {
1249 SCH_LINE* secondLine = *it2;
1250 int secondLeftXEdge = minX( secondLine );
1251
1252 // impossible to overlap remaining lines
1253 if( secondLeftXEdge > firstRightXEdge )
1254 break;
1255
1256 // No Y axis overlap
1257 if( !( std::max( minY( firstLine ), minY( secondLine ) )
1258 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
1259 {
1260 continue;
1261 }
1262
1263 if( secondLine->GetFlags() & STRUCT_DELETED )
1264 continue;
1265
1266 if( !secondLine->IsParallel( firstLine )
1267 || !secondLine->IsStrokeEquivalent( firstLine )
1268 || secondLine->GetLayer() != firstLine->GetLayer() )
1269 {
1270 continue;
1271 }
1272
1273 // Remove identical lines
1274 if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
1275 && firstLine->IsEndPoint( secondLine->GetEndPoint() ) )
1276 {
1277 remove_item( secondLine );
1278 continue;
1279 }
1280
1281 // See if we can merge an overlap (or two colinear touching segments with
1282 // no junction where they meet).
1283 SCH_LINE* mergedLine = secondLine->MergeOverlap( aScreen, firstLine, true );
1284
1285 if( mergedLine != nullptr )
1286 {
1287 remove_item( firstLine );
1288 remove_item( secondLine );
1289
1290 if( m_schematicHolder )
1291 {
1292 m_schematicHolder->AddToScreen( mergedLine, aScreen );
1293 }
1294
1295 aCommit->Added( mergedLine, aScreen );
1296
1297 if( firstLine->IsSelected() || secondLine->IsSelected() )
1298 selectionTool->AddItemToSel( mergedLine, true /*quiet mode*/ );
1299
1300 break;
1301 }
1302 }
1303 }
1304 }
1305}
1306
1307
1309 TOOL_MANAGER* aToolManager,
1310 PROGRESS_REPORTER* aProgressReporter,
1311 KIGFX::SCH_VIEW* aSchView,
1312 std::function<void( SCH_ITEM* )>* aChangedItemHandler,
1313 PICKED_ITEMS_LIST* aLastChangeList )
1314{
1315 SCHEMATIC_SETTINGS& settings = Settings();
1316 SCH_SHEET_LIST list = Hierarchy();
1317 SCH_COMMIT localCommit( aToolManager );
1318
1319 if( !aCommit )
1320 aCommit = &localCommit;
1321
1322 PROF_TIMER timer;
1323
1324 // Ensure schematic graph is accurate
1325 if( aCleanupFlags == LOCAL_CLEANUP )
1326 {
1327 CleanUp( aCommit, GetCurrentScreen() );
1328 }
1329 else if( aCleanupFlags == GLOBAL_CLEANUP )
1330 {
1331 for( const SCH_SHEET_PATH& sheet : list )
1332 CleanUp( aCommit, sheet.LastScreen() );
1333 }
1334
1335 timer.Stop();
1336 wxLogTrace( "CONN_PROFILE", "SchematicCleanUp() %0.4f ms", timer.msecs() );
1337
1338 if( settings.m_IntersheetRefsShow )
1340
1341 if( !ADVANCED_CFG::GetCfg().m_IncrementalConnectivity
1342 || aCleanupFlags == GLOBAL_CLEANUP
1343 || aLastChangeList == nullptr
1344 || ConnectionGraph()->IsMinor() )
1345 {
1346 // Clear all resolved netclass caches in case labels have changed
1347 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
1348
1349 // Update all rule areas so we can cascade implied connectivity changes
1350 std::unordered_set<SCH_SCREEN*> all_screens;
1351
1352 for( const SCH_SHEET_PATH& path : list )
1353 all_screens.insert( path.LastScreen() );
1354
1355 SCH_RULE_AREA::UpdateRuleAreasInScreens( all_screens, aSchView );
1356
1357 // Recalculate all connectivity
1358 ConnectionGraph()->Recalculate( list, true, aChangedItemHandler, aProgressReporter );
1359 }
1360 else
1361 {
1362 struct CHANGED_ITEM
1363 {
1364 SCH_ITEM* item;
1365 SCH_ITEM* linked_item;
1366 SCH_SCREEN* screen;
1367 };
1368
1369 // Final change sets
1370 std::set<SCH_ITEM*> changed_items;
1371 std::set<VECTOR2I> pts;
1372 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
1373
1374 // Working change sets
1375 std::unordered_set<SCH_SCREEN*> changed_screens;
1376 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
1377 std::vector<CHANGED_ITEM> changed_connectable_items;
1378
1379 // Lambda to add an item to the connectivity update sets
1380 auto addItemToChangeSet = [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
1381 {
1382 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
1383
1384 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
1385 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1386 changed_items.insert( itemData.item );
1387
1388 for( SCH_SHEET_PATH& path : paths )
1389 item_paths.insert( std::make_pair( path, itemData.item ) );
1390
1391 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
1392 return;
1393
1394 tmp_pts = itemData.linked_item->GetConnectionPoints();
1395 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1396 changed_items.insert( itemData.linked_item );
1397
1398 // We have to directly add the pins here because the link may not exist on the schematic
1399 // anymore and so won't be picked up by GetScreen()->Items().Overlapping() below.
1400 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( itemData.linked_item ) )
1401 {
1402 std::vector<SCH_PIN*> pins = symbol->GetPins();
1403 changed_items.insert( pins.begin(), pins.end() );
1404 }
1405
1406 for( SCH_SHEET_PATH& path : paths )
1407 item_paths.insert( std::make_pair( path, itemData.linked_item ) );
1408 };
1409
1410 // Get all changed connectable items and determine all changed screens
1411 for( unsigned ii = 0; ii < aLastChangeList->GetCount(); ++ii )
1412 {
1413 switch( aLastChangeList->GetPickedItemStatus( ii ) )
1414 {
1415 // Only care about changed, new, and deleted items, the other
1416 // cases are not connectivity-related
1417 case UNDO_REDO::CHANGED:
1418 case UNDO_REDO::NEWITEM:
1419 case UNDO_REDO::DELETED:
1420 break;
1421
1422 default:
1423 continue;
1424 }
1425
1426 SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( aLastChangeList->GetPickedItem( ii ) );
1427
1428 if( item )
1429 {
1430 SCH_SCREEN* screen = static_cast<SCH_SCREEN*>( aLastChangeList->GetScreenForItem( ii ) );
1431 changed_screens.insert( screen );
1432
1433 if( item->Type() == SCH_RULE_AREA_T )
1434 {
1435 SCH_RULE_AREA* ruleArea = static_cast<SCH_RULE_AREA*>( item );
1436 changed_rule_areas.insert( { ruleArea, screen } );
1437 }
1438 else if( item->IsConnectable() )
1439 {
1440 SCH_ITEM* linked_item = dynamic_cast<SCH_ITEM*>( aLastChangeList->GetPickedItemLink( ii ) );
1441 changed_connectable_items.push_back( { item, linked_item, screen } );
1442 }
1443 }
1444 }
1445
1446 // Update rule areas in changed screens to propagate any directive connectivity changes
1447 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
1448 SCH_RULE_AREA::UpdateRuleAreasInScreens( changed_screens, aSchView );
1449
1450 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
1451 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
1452 {
1453 changed_rule_areas.insert( updatedRuleArea );
1454 } );
1455
1456 // If a SCH_RULE_AREA was changed, we need to add all past and present contained items to
1457 // update their connectivity
1458 std::map<KIID, EDA_ITEM*> itemMap;
1459 list.FillItemMap( itemMap );
1460
1461 auto addPastAndPresentContainedItems =
1462 [&]( SCH_RULE_AREA* changedRuleArea, SCH_SCREEN* screen )
1463 {
1464 for( const KIID& pastItem : changedRuleArea->GetPastContainedItems() )
1465 {
1466 if( itemMap.contains( pastItem ) )
1467 addItemToChangeSet( { static_cast<SCH_ITEM*>( itemMap[pastItem] ), nullptr, screen } );
1468 }
1469
1470 for( SCH_ITEM* containedItem : changedRuleArea->GetContainedItems() )
1471 addItemToChangeSet( { containedItem, nullptr, screen } );
1472 };
1473
1474 for( const auto& [changedRuleArea, screen] : changed_rule_areas )
1475 addPastAndPresentContainedItems( changedRuleArea, screen );
1476
1477 // Add all changed items, and associated items, to the change set
1478 for( CHANGED_ITEM& changed_item_data : changed_connectable_items )
1479 {
1480 addItemToChangeSet( changed_item_data );
1481
1482 // If a SCH_DIRECTIVE_LABEL was changed which is attached to a SCH_RULE_AREA, we need
1483 // to add the contained items to the change set to force update of their connectivity
1484 if( changed_item_data.item->Type() == SCH_DIRECTIVE_LABEL_T )
1485 {
1486 const std::vector<VECTOR2I> labelConnectionPoints =
1487 changed_item_data.item->GetConnectionPoints();
1488
1489 auto candidateRuleAreas =
1490 changed_item_data.screen->Items().Overlapping( SCH_RULE_AREA_T,
1491 changed_item_data.item->GetBoundingBox() );
1492
1493 for( SCH_ITEM* candidateRuleArea : candidateRuleAreas )
1494 {
1495 SCH_RULE_AREA* ruleArea = static_cast<SCH_RULE_AREA*>( candidateRuleArea );
1496 std::vector<SHAPE*> borderShapes = ruleArea->MakeEffectiveShapes( true );
1497
1498 if( ruleArea->GetPolyShape().CollideEdge( labelConnectionPoints[0], nullptr, 5 ) )
1499 addPastAndPresentContainedItems( ruleArea, changed_item_data.screen );
1500 }
1501 }
1502 }
1503
1504 for( const VECTOR2I& pt: pts )
1505 {
1506 for( SCH_ITEM* item : GetCurrentScreen()->Items().Overlapping( pt ) )
1507 {
1508 // Leave this check in place. Overlapping items are not necessarily connectable.
1509 if( !item->IsConnectable() )
1510 continue;
1511
1512 if( item->Type() == SCH_LINE_T )
1513 {
1514 if( item->HitTest( pt ) )
1515 changed_items.insert( item );
1516 }
1517 else if( item->Type() == SCH_SYMBOL_T && item->IsConnected( pt ) )
1518 {
1519 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
1520 std::vector<SCH_PIN*> pins = symbol->GetPins();
1521
1522 changed_items.insert( pins.begin(), pins.end() );
1523 }
1524 else if( item->Type() == SCH_SHEET_T )
1525 {
1526 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
1527
1528 wxCHECK2( sheet, continue );
1529
1530 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->GetPins();
1531 changed_items.insert( sheetPins.begin(), sheetPins.end() );
1532 }
1533 else
1534 {
1535 if( item->IsConnected( pt ) )
1536 changed_items.insert( item );
1537 }
1538 }
1539 }
1540
1541 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
1542 ConnectionGraph()->ExtractAffectedItems( changed_items );
1543
1544 all_items.insert( item_paths.begin(), item_paths.end() );
1545
1546 CONNECTION_GRAPH new_graph( this );
1547
1548 new_graph.SetLastCodes( ConnectionGraph() );
1549
1550 std::shared_ptr<NET_SETTINGS> netSettings = m_project->GetProjectFile().NetSettings();
1551
1552 std::set<wxString> affectedNets;
1553
1554 for( auto&[ path, item ] : all_items )
1555 {
1556 wxCHECK2( item, continue );
1557 item->SetConnectivityDirty();
1558 SCH_CONNECTION* conn = item->Connection();
1559
1560 if( conn )
1561 affectedNets.insert( conn->Name() );
1562 }
1563
1564 // Reset resolved netclass cache for this connection
1565 for( const wxString& netName : affectedNets )
1566 netSettings->ClearCacheForNet( netName );
1567
1568 new_graph.Recalculate( list, false, aChangedItemHandler, aProgressReporter );
1569 ConnectionGraph()->Merge( new_graph );
1570 }
1571
1572 if( !localCommit.Empty() )
1573 localCommit.Push( _( "Schematic Cleanup" ) );
1574}
const char * name
Definition: DXF_plotter.cpp:62
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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:73
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:85
bool Empty() const
Definition: commit.h:152
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition: commit.h:97
Calculate the connectivity of a schematic and generates netlists.
const NET_MAP & GetNetMap() const
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > ExtractAffectedItems(const std::set< SCH_ITEM * > &aItems)
For a set of items, this will remove the connected items and their associated data including subgraph...
void SetLastCodes(const CONNECTION_GRAPH *aOther)
void Merge(CONNECTION_GRAPH &aGraph)
Combine the input graph contents into the current graph.
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:98
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:148
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
bool IsSelected() const
Definition: eda_item.h:127
EDA_ITEM * GetParent() const
Definition: eda_item.h:112
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:145
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:337
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition: sch_rtree.h:246
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:241
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
Container for ERC settings.
Definition: erc_settings.h:132
std::map< wxString, wxString > m_ErcExclusionComments
Definition: erc_settings.h:211
std::set< wxString > m_ErcExclusions
Definition: erc_settings.h:210
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:37
wxAny Get(PROPERTY_BASE *aProperty) const
Definition: inspectable.h:121
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
virtual bool IsStroke() const
Definition: font.h:138
Class OUTLINE_FONT implements outline font drawing.
Definition: outline_font.h:53
Definition: kiid.h:49
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:93
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:107
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
Definition: marker_base.h:94
wxString GetComment() const
Definition: marker_base.h:100
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
A holder to handle information on schematic or board items.
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
unsigned GetCount() const
BASE_SCREEN * GetScreenForItem(unsigned int aIdx) const
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
A small class to help profiling.
Definition: profile.h:49
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:88
double msecs(bool aSinceLast=false)
Definition: profile.h:149
A progress reporter interface for use in multi-threaded environments.
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:68
ERC_SETTINGS * m_ErcSettings
Eeschema params.
Definition: project_file.h:148
SCHEMATIC_SETTINGS * m_SchematicSettings
Definition: project_file.h:151
std::shared_ptr< NET_SETTINGS > & NetSettings()
Definition: project_file.h:99
Container for project specific data.
Definition: project.h:65
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:161
virtual bool TextVarResolver(wxString *aToken) const
Definition: project.cpp:76
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:204
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:98
virtual bool IsNullProject() const
Check if this project is a null project (i.e.
Definition: project.cpp:167
const wxString & Name() const
Definition: property.h:218
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
void UnregisterListeners(TYPE_ID aType)
Definition: property_mgr.h:259
void RegisterListener(TYPE_ID aType, PROPERTY_LISTENER aListenerFunc)
Registers a listener for the given type.
Definition: property_mgr.h:254
virtual void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr)=0
Add an item to the screen (and view) aScreen is the screen the item is located on,...
virtual void IntersheetRefUpdate(SCH_GLOBALLABEL *aItem)
virtual void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)=0
virtual SCH_SELECTION_TOOL * GetSelectionTool()
virtual void OnSchItemsRemoved(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
Definition: schematic.h:65
virtual void OnSchItemsChanged(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
Definition: schematic.h:66
virtual void OnSchSheetChanged(SCHEMATIC &aSch)
Definition: schematic.h:70
virtual void OnSchItemsAdded(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
Definition: schematic.h:64
These are loaded from Eeschema settings but then overwritten by the project settings.
std::shared_ptr< REFDES_TRACKER > m_refDesTracker
A list of previously used schematic reference designators.
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
Definition: schematic.cpp:144
std::set< const SCH_SCREEN * > GetSchematicsSharedByMultipleProjects() const
Return a list of schematic files in the current project that contain instance data for multiple proje...
Definition: schematic.cpp:1003
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
Definition: schematic.cpp:682
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:835
CONNECTION_GRAPH * m_connectionGraph
Hold and calculate connectivity information of this schematic.
Definition: schematic.h:482
void BreakSegment(SCH_COMMIT *aCommit, SCH_LINE *aSegment, const VECTOR2I &aPoint, SCH_LINE **aNewSegment, SCH_SCREEN *aScreen)
Break a single segment into two at the specified point.
Definition: schematic.cpp:1056
SCH_SHEET_LIST m_hierarchy
Cache of the entire schematic hierarchy sorted by sheet page number.
Definition: schematic.h:504
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
Definition: schematic.cpp:910
void RecomputeIntersheetRefs()
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
Definition: schematic.cpp:735
void CacheExistingAnnotation()
Store all existing annotations in the REFDES_TRACKER.
Definition: schematic.cpp:200
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
Definition: schematic.h:108
void RemoveListener(SCHEMATIC_LISTENER *aListener)
Remove the specified listener.
Definition: schematic.cpp:866
bool BreakSegmentsOnJunctions(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen)
Test all junctions and bus entries in the schematic for intersections with wires and buses and breaks...
Definition: schematic.cpp:1091
bool IsComplexHierarchy() const
Test if the schematic is a complex hierarchy.
Definition: schematic.cpp:1038
void OnSchSheetChanged()
Notify the schematic and its listeners that the current sheet has been changed.
Definition: schematic.cpp:853
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:350
SCH_SHEET_PATH * m_currentSheet
The sheet path of the sheet currently being edited or displayed.
Definition: schematic.h:479
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:787
void CleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
Definition: schematic.cpp:1117
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:841
virtual ~SCHEMATIC()
Definition: schematic.cpp:133
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:452
std::vector< SCH_MARKER * > ResolveERCExclusions()
Definition: schematic.cpp:370
void EmbedFonts() override
Embed fonts in the schematic.
Definition: schematic.cpp:984
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:356
SCH_SCREEN * GetCurrentScreen() const
Definition: schematic.h:181
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:625
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Definition: schematic.h:134
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: schematic.cpp:884
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:258
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition: schematic.h:219
void FixupJunctionsAfterImport()
Add junctions to this schematic where required.
Definition: schematic.cpp:807
std::set< KIFONT::OUTLINE_FONT * > GetFonts() const override
Get a set of fonts used in the schematic.
Definition: schematic.cpp:951
bool Contains(const SCH_REFERENCE &aRef) const
Check if the schematic contains the specified reference.
Definition: schematic.cpp:219
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:555
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
Definition: schematic.cpp:238
void SetProject(PROJECT *aPrj)
Definition: schematic.cpp:170
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:859
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
Definition: schematic.cpp:544
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: schematic.cpp:927
PROJECT * m_project
Definition: schematic.h:467
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:183
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
Definition: schematic.cpp:252
SCHEMATIC(PROJECT *aPrj)
Definition: schematic.cpp:56
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
Definition: schematic.cpp:297
std::set< wxString > GetNetClassAssignmentCandidates()
Return the set of netname candidates for netclass assignment.
Definition: schematic.cpp:467
void InvokeListeners(Func &&aFunc, Args &&... args)
Definition: schematic.h:461
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:156
static bool m_IsSchematicExists
True if a SCHEMATIC exists, false if not.
Definition: schematic.h:449
void RemoveAllListeners()
Remove all listeners.
Definition: schematic.cpp:878
void GetContextualTextVars(wxArrayString *aVars) const
Definition: schematic.cpp:272
SCH_SHEET & Root() const
Definition: schematic.h:140
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
Definition: schematic.cpp:528
void RunOnNestedEmbeddedFiles(const std::function< void(EMBEDDED_FILES *)> &aFunction) override
Provide access to nested embedded files, such as symbols in schematics and footprints in boards.
Definition: schematic.cpp:939
SCHEMATIC_HOLDER * m_schematicHolder
What currently "Holds" the schematic, i.e.
Definition: schematic.h:514
wxString GetUniqueFilenameForCurrentSheet()
Get the unique file name for the current sheet.
Definition: schematic.cpp:690
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
Definition: schematic.cpp:706
bool BreakSegments(SCH_COMMIT *aCommit, const VECTOR2I &aPoint, SCH_SCREEN *aScreen)
Check every wire and bus for a intersection at aPoint and break into two segments at aPoint if an int...
Definition: schematic.cpp:1076
std::vector< SCHEMATIC_LISTENER * > m_listeners
Currently installed listeners.
Definition: schematic.h:509
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:171
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:486
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, TOOL_MANAGER *aToolManager, PROGRESS_REPORTER *aProgressReporter=nullptr, KIGFX::SCH_VIEW *aSchView=nullptr, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PICKED_ITEMS_LIST *aLastChangeList=nullptr)
Generate the connection data for the entire schematic hierarchy.
Definition: schematic.cpp:1308
std::map< wxString, double > m_operatingPoints
Simulation operating points for text variable substitution.
Definition: schematic.h:499
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:363
void RefreshHierarchy()
Definition: schematic.cpp:266
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:847
SCH_SHEET * m_rootSheet
The top-level sheet in this schematic hierarchy (or potentially the only one)
Definition: schematic.h:470
VECTOR2I GetPosition() const override
VECTOR2I GetEnd() const
Class for a wire to bus entry.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Definition: sch_commit.cpp:489
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString Name(bool aIgnoreSheet=false) const
bool IsBus() const
FIELD_T GetId() const
Definition: sch_field.h:116
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:168
virtual bool IsConnectable() const
Definition: sch_item.h:498
int GetUnit() const
Definition: sch_item.h:239
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:313
VECTOR2I GetPosition() const override
Definition: sch_junction.h:107
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Definition: sch_label.cpp:891
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:42
SCH_LINE * NonGroupAware_BreakAt(const VECTOR2I &aPoint)
This version should only be used when importing files.
Definition: sch_line.cpp:558
bool IsParallel(const SCH_LINE *aLine) const
Definition: sch_line.cpp:412
VECTOR2I GetEndPoint() const
Definition: sch_line.h:144
VECTOR2I GetStartPoint() const
Definition: sch_line.h:139
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
Definition: sch_line.cpp:425
bool IsNull() const
Definition: sch_line.h:137
SCH_LINE * BreakAt(SCH_COMMIT *aCommit, const VECTOR2I &aPoint)
Break this segment into two at the specified point.
Definition: sch_line.cpp:546
bool IsStrokeEquivalent(const SCH_LINE *aLine)
Definition: sch_line.h:196
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
Definition: sch_line.h:91
static SCH_MARKER * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
Definition: sch_marker.cpp:145
wxString SerializeToString() const
Definition: sch_marker.cpp:90
bool IsLegacyMarker() const
Determine if this marker is legacy (i.e.
Definition: sch_marker.h:121
VECTOR2I GetPosition() const override
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
size_t GetCount() const
A helper to define a symbol's reference designator in a schematic.
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const override
Make a set of SHAPE objects representing the EDA_SHAPE.
const std::unordered_set< SCH_ITEM * > & GetContainedItems() const
Return a set of all items contained within the rule area.
static std::vector< std::pair< SCH_RULE_AREA *, SCH_SCREEN * > > UpdateRuleAreasInScreens(std::unordered_set< SCH_SCREEN * > &screens, KIGFX::SCH_VIEW *view)
Update all rule area connectvity / caches in the given sheet paths.
const std::unordered_set< KIID > & GetPastContainedItems() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:758
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:160
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition: sch_screen.h:186
std::vector< SCH_LINE * > GetBusesAndWires(const VECTOR2I &aPosition, bool aIgnoreEndpoints=false) const
Return buses and wires passing through aPosition.
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicate that a junction dot is necessary at the given location.
Definition: sch_screen.cpp:482
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition: sch_screen.h:117
const wxString & GetFileName() const
Definition: sch_screen.h:152
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:163
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:323
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 * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Fetch a SCH_ITEM by ID.
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Fill an item cache for temporary use when many items need to be fetched.
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 HasPath(const KIID_PATH &aPath) const
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:47
wxString GetName() const
Definition: sch_sheet.h:113
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
Definition: sch_sheet.cpp:828
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:116
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:187
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:220
Schematic symbol object.
Definition: sch_symbol.h:75
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition: sch_symbol.h:134
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Definition: sch_symbol.cpp:600
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
const LIB_ID & GetLibId() const override
Definition: sch_symbol.h:164
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:558
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
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, int aFlags=0) const
static void GetContextualTextVars(wxArrayString *aVars)
Definition: title_block.cpp:75
Master controller class:
Definition: tool_manager.h:62
#define _HKI(x)
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
#define IS_CHANGED
Item was edited, and modified.
#define IS_NEW
New item, just created.
#define IS_BROKEN
Is a segment just broken by BreakSegment.
#define STRUCT_DELETED
flag indication structures to be erased
void ignore_unused(const T &)
Definition: ignore.h:24
@ LAYER_WIRE
Definition: layer_ids.h:442
@ LAYER_BUS
Definition: layer_ids.h:443
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
Definition: kicad_algo.h:84
#define TYPE_HASH(x)
Definition: property.h:72
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
@ AUTOPLACE_AUTO
Definition: sch_item.h:71
SCH_CLEANUP_FLAGS
Definition: schematic.h:74
@ LOCAL_CLEANUP
Definition: schematic.h:76
@ GLOBAL_CLEANUP
Definition: schematic.h:77
A simple container for schematic symbol instance information.
@ SCH_LINE_T
Definition: typeinfo.h:164
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:161
@ SCH_SYMBOL_T
Definition: typeinfo.h:173
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:172
@ SCH_SHEET_T
Definition: typeinfo.h:176
@ SCH_MARKER_T
Definition: typeinfo.h:159
@ SCH_RULE_AREA_T
Definition: typeinfo.h:171
@ SCHEMATIC_T
Definition: typeinfo.h:205
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:162
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:169
@ SCH_JUNCTION_T
Definition: typeinfo.h:160