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