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