KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema.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) 2004 Jean-Pierre Charras, [email protected]
5 * Copyright (C) 2008 Wayne Stambaugh <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <algorithm>
23
24#include <api/api_handler_sch.h>
27#include <api/api_server.h>
28#include <api/api_utils.h>
33#include <pgm_base.h>
34#include <kiface_base.h>
37#include <confirm.h>
38#include <gestfich.h>
40#include "eeschema_helpers.h"
42#include <reporter.h>
43#include "git/kigit_sch_merge.h"
46#include <eeschema_settings.h>
47#include <sch_edit_frame.h>
49#include <symbol_edit_frame.h>
50#include <symbol_viewer_frame.h>
57#include <kiway.h>
58#include <project_sch.h>
59#include <richio.h>
62#include <sexpr/sexpr.h>
63#include <sexpr/sexpr_parser.h>
64#include <string_utils.h>
65#include <trace_helpers.h>
66#include <thread_pool.h>
67#include <kiface_ids.h>
68#include <widgets/kistatusbar.h>
70#include <wx/ffile.h>
71#include <wx/tokenzr.h>
73
74#include <schematic.h>
75#include <connection_graph.h>
86#include <sim/simulator_frame.h>
87
89#include <toolbars_sch_editor.h>
91
92#include <sch_io/sch_io.h>
93#include <sch_io/sch_io_mgr.h>
94
95#include <wx/crt.h>
96
97// The main sheet of the project
99
100
101namespace SCH {
102
103// Non-job kiface exports for diff/merge (returned by IfaceOrAddress). Defined
104// after the kiface instance so they can route into its jobs handler.
105static int eeschemaMergeExport( int aKind, const wxString& aAncestor, const wxString& aOurs,
106 const wxString& aTheirs, const wxString& aOutput, bool aInteractive,
107 bool aSingleFile, REPORTER* aReporter );
108static int eeschemaOpenDiffDialogExport( int aKind, const wxString& aFileA, const wxString& aFileB,
109 const wxString& aLabelA, const wxString& aLabelB,
110 wxWindow* aParent, REPORTER* aReporter );
111
112
113
114// TODO: This should move out of this file
115static std::unique_ptr<SCHEMATIC> readSchematicFromFile( const std::string& aFilename )
116{
117 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
118 std::unique_ptr<SCHEMATIC> schematic = std::make_unique<SCHEMATIC>( nullptr );
119
121
122 wxFileName pro( aFilename );
123 pro.SetExt( FILEEXT::ProjectFileExtension );
124 pro.MakeAbsolute();
125 wxString projectPath = pro.GetFullPath();
126
127 PROJECT* project = manager.GetProject( projectPath );
128
129 if( !project )
130 {
131 manager.LoadProject( projectPath, true );
132 project = manager.GetProject( projectPath );
133 }
134
135 schematic->Reset();
136 schematic->SetProject( project );
137 SCH_SHEET* rootSheet = pi->LoadSchematicFile( aFilename, schematic.get() );
138
139 if( !rootSheet )
140 return nullptr;
141
142 std::vector<SCH_SHEET*> topLevelSheets = schematic->GetTopLevelSheets();
143 bool rootIsTopLevel = std::find( topLevelSheets.begin(), topLevelSheets.end(), rootSheet )
144 != topLevelSheets.end();
145 bool rootIsVirtualRoot = rootSheet == &schematic->Root() || rootSheet->IsVirtualRootSheet();
146
147 if( !rootIsTopLevel && !rootIsVirtualRoot )
148 schematic->SetTopLevelSheets( { rootSheet } );
149
150 SCH_SCREENS screens( schematic->Root() );
151
152 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
153 screen->UpdateLocalLibSymbolLinks();
154
155 SCH_SHEET_LIST sheets = schematic->Hierarchy();
156
157 // Restore all of the loaded symbol instances from the root sheet screen.
158 sheets.UpdateSymbolInstanceData( schematic->RootScreen()->GetSymbolInstances() );
159
160 if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20230221 )
161 {
162 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
163 screen->FixLegacyPowerSymbolMismatches();
164 }
165
166 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
167 screen->MigrateSimModels();
168
169 // NOTE: This is required for multi-unit symbols to be correct
170 for( SCH_SHEET_PATH& sheet : sheets )
171 sheet.UpdateAllScreenReferences();
172
173 // TODO: this must handle SchematicCleanup somehow. The original version didn't because
174 // it knew that QA test cases were saved in a clean state.
175
176 // TODO: does this need to handle PruneOrphanedSymbolInstances() and
177 // PruneOrphanedSheetInstances()?
178
179 schematic->ConnectionGraph()->Recalculate( sheets, true );
180
181 return schematic;
182}
183
184
185// TODO: This should move out of this file
186bool generateSchematicNetlist( const wxString& aFilename, std::string& aNetlist, KIWAY* aKiway )
187{
188 std::unique_ptr<SCHEMATIC> schematic = readSchematicFromFile( aFilename.ToStdString() );
189
190 if( !schematic )
191 return false;
192
193 NETLIST_EXPORTER_KICAD exporter( schematic.get(), aKiway );
194 STRING_FORMATTER formatter;
195
196 exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
197 aNetlist = formatter.GetString();
198
199 return true;
200}
201
202
203static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
204{
205 // Of course all are virtual overloads, implementations of the KIFACE.
206
207 IFACE( const char* aName, KIWAY::FACE_T aType ) :
208 KIFACE_BASE( aName, aType ),
211 {}
212
213 bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway ) override;
214
215 void Reset() override;
216
217 void OnKifaceEnd() override;
218
219 wxWindow* CreateKiWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) override
220 {
221 switch( aClassId )
222 {
223 case FRAME_SCH:
224 {
225 SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent );
226
228
229 if( Kiface().IsSingle() )
230 {
231 // only run this under single_top, not under a project manager.
234 }
235
236 return frame;
237 }
238
240 return new SYMBOL_EDIT_FRAME( aKiway, aParent );
241
242 case FRAME_SIMULATOR:
243 {
244 try
245 {
246 SIMULATOR_FRAME* frame = new SIMULATOR_FRAME( aKiway, aParent );
247 return frame;
248 }
249 catch( const SIMULATOR_INIT_ERR& )
250 {
251 // catch the init err exception as we don't want it to bubble up
252 // its going to be some ngspice install issue but we don't want to log that
253 return nullptr;
254 }
255 }
256
257 case FRAME_SCH_VIEWER:
258 return new SYMBOL_VIEWER_FRAME( aKiway, aParent );
259
261 {
262 bool cancelled = false;
263 SYMBOL_CHOOSER_FRAME* chooser = new SYMBOL_CHOOSER_FRAME( aKiway, aParent, cancelled );
264
265 if( cancelled )
266 {
267 chooser->Destroy();
268 return nullptr;
269 }
270
271 return chooser;
273
275 InvokeSchEditSymbolLibTable( aKiway, aParent );
276 // Dialog has completed; nothing to return.
277 return nullptr;
281 // Dialog has completed; nothing to return.
282 return nullptr;
283
285 return new PANEL_SYM_DISPLAY_OPTIONS( aParent, GetAppSettings<SYMBOL_EDITOR_SETTINGS>( "symbol_editor" ) );
291
292 if( !frame )
293 frame = aKiway->Player( FRAME_SCH_VIEWER, false );
294
295 if( !frame )
296 frame = aKiway->Player( FRAME_SCH, false );
298 if( frame )
301 return new PANEL_GRID_SETTINGS( aParent, this, frame, cfg, FRAME_SCH_SYMBOL_EDITOR );
302 }
303
305 return CreateSnappingPanel( aParent, GetAppSettings<SYMBOL_EDITOR_SETTINGS>( "symbol_editor" ),
307
309 {
310 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_SCH_SYMBOL_EDITOR, false );
311
312 if( !frame )
313 frame = aKiway->Player( FRAME_SCH_VIEWER, false );
314
315 if( !frame )
316 frame = aKiway->Player( FRAME_SCH, false );
317
318 if( frame )
319 SetUserUnits( frame->GetUserUnits() );
320
321 return new PANEL_SYM_EDITING_OPTIONS( aParent, this, frame );
322 }
323
325 {
326 APP_SETTINGS_BASE* cfg = GetAppSettings<SYMBOL_EDITOR_SETTINGS>( "symbol_editor" );
327 TOOLBAR_SETTINGS* tb = GetToolbarSettings<SYMBOL_EDIT_TOOLBAR_SETTINGS>( "symbol_editor-toolbars" );
328
329 std::vector<TOOL_ACTION*> actions;
330 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
331
332 for( TOOL_ACTION* action : ACTION_MANAGER::GetActionList() )
333 actions.push_back( action );
334
335 for( ACTION_TOOLBAR_CONTROL* control : ACTION_TOOLBAR::GetCustomControlList( FRAME_SCH_SYMBOL_EDITOR ) )
336 controls.push_back( control );
337
338 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb, FRAME_SCH_SYMBOL_EDITOR, actions, controls );
339 }
340
341 case PANEL_SYM_COLORS:
342 return new PANEL_SYM_COLOR_SETTINGS( aParent );
343
345 return new PANEL_EESCHEMA_DISPLAY_OPTIONS( aParent, GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" ) );
346
347 case PANEL_SCH_GRIDS:
348 {
349 EESCHEMA_SETTINGS* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
350 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_SCH, false );
351
352 if( !frame )
353 frame = aKiway->Player( FRAME_SCH_SYMBOL_EDITOR, false );
354
355 if( !frame )
356 frame = aKiway->Player( FRAME_SCH_VIEWER, false );
357
358 if( frame )
359 SetUserUnits( frame->GetUserUnits() );
360
361 return new PANEL_GRID_SETTINGS( aParent, this, frame, cfg, FRAME_SCH );
362 }
363
367
369 {
370 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_SCH, false );
371
372 if( !frame )
373 frame = aKiway->Player( FRAME_SCH_SYMBOL_EDITOR, false );
374
375 if( !frame )
376 frame = aKiway->Player( FRAME_SCH_VIEWER, false );
377
378 if( frame )
379 SetUserUnits( frame->GetUserUnits() );
380
381 return new PANEL_EESCHEMA_EDITING_OPTIONS( aParent, this, frame );
382 }
383
385 {
386 APP_SETTINGS_BASE* cfg = GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
387 TOOLBAR_SETTINGS* tb = GetToolbarSettings<SCH_EDIT_TOOLBAR_SETTINGS>( "eeschema-toolbars" );
388
389 std::vector<TOOL_ACTION*> actions;
390 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
391
392 for( TOOL_ACTION* action : ACTION_MANAGER::GetActionList() )
393 actions.push_back( action );
394
395 for( ACTION_TOOLBAR_CONTROL* control : ACTION_TOOLBAR::GetCustomControlList( FRAME_SCH ) )
396 controls.push_back( control );
397
398 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb, FRAME_SCH, actions, controls );
399 }
400
401 case PANEL_SCH_COLORS:
402 return new PANEL_EESCHEMA_COLOR_SETTINGS( aParent );
403
405 return new PANEL_TEMPLATE_FIELDNAMES( aParent, nullptr );
406
408 {
409 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_SCH, false );
410
411 if( !frame )
412 frame = aKiway->Player( FRAME_SCH_SYMBOL_EDITOR, false );
413
414 if( !frame )
415 frame = aKiway->Player( FRAME_SCH_VIEWER, false );
416
417 return new class PANEL_SCH_DATA_SOURCES( aParent, frame );
418 }
419
421 return new PANEL_SIMULATOR_PREFERENCES( aParent );
422
423 default:
424 return nullptr;
425 }
426 }
427
438 void* IfaceOrAddress( int aDataId ) override
439 {
440 switch( aDataId )
441 {
443 return (void*) generateSchematicNetlist;
444
446 return reinterpret_cast<void*>( &eeschemaMergeExport );
447
449 return reinterpret_cast<void*>( &eeschemaOpenDiffDialogExport );
450 }
451
452 return nullptr;
453 }
454
457
463 void SaveFileAs( const wxString& aProjectBasePath, const wxString& aProjectName,
464 const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
465 const wxString& aSrcFilePath, wxString& aErrors ) override;
466
467
468 int HandleJob( JOB* aJob, REPORTER* aReporter, PROGRESS_REPORTER* aProgressReporter ) override;
469
470 bool HandleJobConfig( JOB* aJob, wxWindow* aParent ) override;
471
472 bool HandleApiOpenDocument( const DOCUMENT_SPEC& aSpec,
473 KICAD_API_SERVER* aServer,
474 wxString* aError ) override;
475
476 bool handleCreateSchematic( const wxString& aPath, KICAD_API_SERVER* aServer, wxString* aError );
477 bool handleOpenSymbol( const wxString& aProjectPath, const wxString& aLibIdStr, KICAD_API_SERVER* aServer,
478 wxString* aError );
479 bool HandleApiCloseDocument( const DOCUMENT_SPEC& aSpec,
480 KICAD_API_SERVER* aServer,
481 wxString* aError ) override;
482
483 void PreloadLibraries( KIWAY* aKiway ) override;
484 void CancelPreload( bool aBlock = true ) override;
485 void ProjectChanged() override;
486 void RegisterLibraryHandlers( KICAD_API_SERVER* aServer ) override;
487 bool LoadAllLibraries() override;
488
489
490private:
491 std::unique_ptr<EESCHEMA_JOBS_HANDLER> m_jobHandler;
492 std::shared_ptr<BACKGROUND_JOB> m_libraryPreloadBackgroundJob;
493 std::future<void> m_libraryPreloadReturn;
495 std::atomic_bool m_libraryPreloadAbort;
496
497 void closeSchematic( KICAD_API_SERVER* aServer );
498 void closeSymbol( KICAD_API_SERVER* aServer );
499
500 KIWAY* m_kiway = nullptr;
502 std::shared_ptr<HEADLESS_SCH_CONTEXT> m_openContext;
503 std::shared_ptr<HEADLESS_SYMBOL_EDITOR_CONTEXT> m_openSymbolContext;
504 std::unique_ptr<API_HANDLER_SYMBOL> m_openSymbolHandler;
505 std::unique_ptr<API_HANDLER_SCH> m_openHandler;
506 std::unique_ptr<API_HANDLER_SCH_LIBRARIES> m_apiHandlerSchLibs;
507
508} kiface( "eeschema", KIWAY::FACE_SCH );
509
510
511int eeschemaMergeExport( int aKind, const wxString& aAncestor, const wxString& aOurs,
512 const wxString& aTheirs, const wxString& aOutput, bool aInteractive,
513 bool aSingleFile, REPORTER* aReporter )
514{
515 return kiface.JobHandler()->RunMerge( static_cast<KICAD_DIFF::DOC_KIND>( aKind ), aAncestor,
516 aOurs, aTheirs, aOutput, aInteractive, aSingleFile,
517 aReporter );
518}
519
520
521int eeschemaOpenDiffDialogExport( int aKind, const wxString& aFileA, const wxString& aFileB,
522 const wxString& aLabelA, const wxString& aLabelB,
523 wxWindow* aParent, REPORTER* aReporter )
524{
525 return kiface.JobHandler()->OpenDiffDialog( static_cast<KICAD_DIFF::DOC_KIND>( aKind ), aFileA,
526 aFileB, aLabelA, aLabelB, aParent, aReporter );
527}
528
529} // namespace
530
531using namespace SCH;
532
533
535
536
537// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
538// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
539KIFACE_API KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
540{
541 return &kiface;
542}
543
544
545bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway )
546{
547 // This is process-level-initialization, not project-level-initialization of the DSO.
548 // Do nothing in here pertinent to a project!
550
551 // Register the symbol editor settings as well because they share a KiFACE and need to be
552 // loaded prior to use to avoid threading deadlocks
554 aProgram->GetSettingsManager().RegisterSettings( symSettings ); // manager takes ownership
555
556 // We intentionally register KifaceSettings after SYMBOL_EDITOR_SETTINGS
557 // In legacy configs, many settings were in a single editor config nd the migration routine
558 // for the main editor file will try and call into the now separate settings stores
559 // to move the settings into them
561
562 start_common( aCtlBits );
563
564 m_kiway = aKiway;
565
566 m_jobHandler = std::make_unique<EESCHEMA_JOBS_HANDLER>( aKiway );
567
569 {
570 m_jobHandler->SetReporter( &CLI_REPORTER::GetInstance() );
571 m_jobHandler->SetProgressReporter( &CLI_PROGRESS_REPORTER::GetInstance() );
572 }
573
574 if( Pgm().ApiServerOrNull() )
575 {
576 m_apiHandlerSchLibs = std::make_unique<API_HANDLER_SCH_LIBRARIES>();
578 }
579
580 // Register the schematic and symbol-library merge drivers with libgit2 so
581 // `.gitattributes` entries `merge=kicad-sch` and `merge=kicad-sym-lib`
582 // route through KiCad-aware merge logic.
585
586 return true;
587}
588
589
591{
592 if( m_jobHandler )
593 m_jobHandler->ClearCachedSchematic();
594
595 closeSchematic( nullptr );
596 closeSymbol( nullptr );
597}
598
599
601{
602 constexpr static int interval = 150;
603 constexpr static int timeLimit = 120000;
604
605 wxCHECK( aKiway, /* void */ );
606
607 // Use compare_exchange to atomically check and set the flag to prevent race conditions
608 // when PreloadLibraries is called multiple times concurrently (e.g., from project manager
609 // and schematic editor both scheduling via CallAfter)
610 bool expected = false;
611
612 if( !m_libraryPreloadInProgress.compare_exchange_strong( expected, true ) )
613 return;
614
616
618 Pgm().GetBackgroundJobMonitor().Create( _( "Loading Symbol Libraries" ) );
619
620 auto preload =
621 [this, aKiway]() -> void
622 {
623 std::shared_ptr<BACKGROUND_JOB_REPORTER> reporter =
625
627
628 int elapsed = 0;
629 bool aborted = false;
630
631 reporter->Report( _( "Loading Symbol Libraries" ) );
632 adapter->AsyncLoad();
633
634 while( true )
635 {
636 if( m_libraryPreloadAbort.load() )
637 {
638 m_libraryPreloadAbort.store( false );
639 aborted = true;
640 break;
641 }
642
643 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
644
645 if( std::optional<float> loadStatus = adapter->AsyncLoadProgress() )
646 {
647 float progress = *loadStatus;
648 reporter->SetCurrentProgress( progress );
649
650 if( progress >= 1 )
651 break;
652 }
653 else
654 {
655 reporter->SetCurrentProgress( 1 );
656 break;
657 }
658
659 elapsed += interval;
660
661 if( elapsed > timeLimit )
662 break;
663 }
664
665 // AbortAsyncLoad() sets the adapter's worker abort flag and then blocks,
666 // so workers exit at their next checkpoint. BlockUntilLoaded() alone just
667 // waits for each future to complete naturally, which can hang indefinitely
668 // if a worker is stuck on a stalled network or filesystem operation.
669 if( aborted )
670 adapter->AbortAsyncLoad();
671 else
672 adapter->BlockUntilLoaded();
673
674 // If aborted, skip operations that use the adapter since the project may have changed
675 // and the adapter's project reference could be stale. This prevents use-after-free
676 // crashes when switching projects during library preload.
677 if( !aborted )
678 {
679 // Collect library load errors for async reporting
681 }
682 else
683 {
684 wxLogTrace( traceLibraries, "eeschema PreloadLibraries: aborted, skipping symbol processing" );
685 }
686
689 m_libraryPreloadInProgress.store( false );
690
691 // Only send reload notifications if we weren't aborted
692 if( !aborted )
693 {
694 std::string payload = "";
695 aKiway->ExpressMail( FRAME_SCH, MAIL_RELOAD_LIB, payload, nullptr, true );
696 aKiway->ExpressMail( FRAME_SCH_SYMBOL_EDITOR, MAIL_RELOAD_LIB, payload, nullptr, true );
697 aKiway->ExpressMail( FRAME_SCH_VIEWER, MAIL_RELOAD_LIB, payload, nullptr, true );
698 }
699 };
700
701 std::future<void> preloadFuture = std::async( std::launch::async, preload );
702 m_libraryPreloadReturn = std::move( preloadFuture );
703}
704
705
706void IFACE::CancelPreload( bool aBlock )
707{
708 if( m_libraryPreloadInProgress.load() )
709 {
710 m_libraryPreloadAbort.store( true );
711
712 if( aBlock )
714 }
715}
716
717
719{
720 if( m_libraryPreloadInProgress.load() )
721 m_libraryPreloadAbort.store( true );
722}
723
724
726{
728 {
729 if( Pgm().ApiServerOrNull() )
731
732 m_apiHandlerSchLibs.reset();
733 }
734
735 // Release the CLI-cached schematic while the static ERC_ITEM tables it serializes against are
736 // still alive; deferring to static teardown crashes reading dangling severity keys
737 if( m_jobHandler )
738 m_jobHandler->ClearCachedSchematic();
739
740 end_common();
741}
742
743
744void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProjectName,
745 const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
746 const wxString& aSrcFilePath, wxString& aErrors )
747{
748 wxFileName destFile( aSrcFilePath );
749 wxString destPath = destFile.GetPathWithSep();
750 wxUniChar pathSep = wxFileName::GetPathSeparator();
751 wxString ext = destFile.GetExt();
752
753 if( destPath.StartsWith( aProjectBasePath + pathSep ) )
754 destPath.Replace( aProjectBasePath, aNewProjectBasePath, false );
755
756 destFile.SetPath( destPath );
757
762 {
763 if( destFile.GetName() == aProjectName )
764 {
765 destFile.SetName( aNewProjectName );
766 }
767 else if( destFile.GetName() == aNewProjectName )
768 {
769 wxString msg;
770
771 if( !aErrors.empty() )
772 aErrors += wxS( "\n" );
773
774 msg.Printf( _( "Cannot copy file '%s' as it will be overwritten by the new root "
775 "sheet file." ), destFile.GetFullPath() );
776 aErrors += msg;
777 return;
778 }
779
780 CopySexprFile( aSrcFilePath, destFile.GetFullPath(),
781 [&]( const std::string& token, wxString& value ) -> bool
782 {
783 if( token == "project" && value == aProjectName )
784 {
785 value = aNewProjectName;
786 return true;
787 }
788
789 return false;
790 },
791 aErrors );
792 }
794 {
795 // Symbols are not project-specific. Keep their source names.
796 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
797 }
801 {
802 if( destFile.GetName() == aProjectName + wxS( "-cache" ) )
803 destFile.SetName( aNewProjectName + wxS( "-cache" ) );
804
805 if( destFile.GetName() == aProjectName + wxS( "-rescue" ) )
806 destFile.SetName( aNewProjectName + wxS( "-rescue" ) );
807
808 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
809 }
810 else if( ext == FILEEXT::NetlistFileExtension )
811 {
812 if( destFile.GetName() == aProjectName )
813 destFile.SetName( aNewProjectName );
814
815 CopySexprFile( aSrcFilePath, destFile.GetFullPath(),
816 [&]( const std::string& token, wxString& value ) -> bool
817 {
818 if( token == "source" )
819 {
820 for( const wxString& extension : { wxString( wxT( ".sch" ) ), wxString( wxT( ".kicad_sch" ) ) } )
821 {
822 if( value == aProjectName + extension )
823 {
824 value = aNewProjectName + extension;
825 return true;
826 }
827 else if( value == aProjectBasePath + "/" + aProjectName + extension )
828 {
829 value = aNewProjectBasePath + "/" + aNewProjectName + extension;
830 return true;
831 }
832 else if( value.StartsWith( aProjectBasePath ) )
833 {
834 value.Replace( aProjectBasePath, aNewProjectBasePath, false );
835 return true;
836 }
837 }
838 }
839
840 return false;
841 },
842 aErrors );
843 }
844 else if( destFile.GetName() == FILEEXT::SymbolLibraryTableFileName )
845 {
846 wxFileName libTableFn( aSrcFilePath );
847 LIBRARY_TABLE libTable( libTableFn, LIBRARY_TABLE_SCOPE::PROJECT );
848 libTable.SetPath( destFile.GetFullPath() );
849 libTable.SetType( LIBRARY_TABLE_TYPE::SYMBOL );
850
851 for( LIBRARY_TABLE_ROW& row : libTable.Rows() )
852 {
853 wxString uri = row.URI();
854
855 uri.Replace( wxS( "/" ) + aProjectName + wxS( "-cache.lib" ),
856 wxS( "/" ) + aNewProjectName + wxS( "-cache.lib" ) );
857 uri.Replace( wxS( "/" ) + aProjectName + wxS( "-rescue.lib" ),
858 wxS( "/" ) + aNewProjectName + wxS( "-rescue.lib" ) );
859 uri.Replace( wxS( "/" ) + aProjectName + wxS( ".lib" ),
860 wxS( "/" ) + aNewProjectName + wxS( ".lib" ) );
861
862 row.SetURI( uri );
863 }
864
865 libTable.Save().map_error(
866 [&]( const LIBRARY_ERROR& aError )
867 {
868 wxString msg;
869
870 if( !aErrors.empty() )
871 aErrors += wxT( "\n" );
872
873 msg.Printf( _( "Cannot copy file '%s'." ), destFile.GetFullPath() );
874 aErrors += msg;
875 } );
876 }
877 else
878 {
879 wxFAIL_MSG( wxS( "Unexpected filetype for Eeschema::SaveFileAs()" ) );
880 }
881}
882
883
884int IFACE::HandleJob( JOB* aJob, REPORTER* aReporter, PROGRESS_REPORTER* aProgressReporter )
885{
886 return m_jobHandler->RunJob( aJob, aReporter, aProgressReporter );
887}
888
889
890bool IFACE::HandleJobConfig( JOB* aJob, wxWindow* aParent )
891{
892 return m_jobHandler->HandleJobConfig( aJob, aParent );
893}
894
895
896// TODO(JE) some of the below methods can probably be factored out and shared between sch/pcb
898{
899 if( m_openHandler )
900 {
901 if( aServer )
902 aServer->DeregisterHandler( m_openHandler.get() );
903
904 m_openHandler.reset();
905 }
906
907 m_openContext.reset();
908
909 delete m_openSchematic;
910 m_openSchematic = nullptr;
911
912 // The jobs handler caches the last-loaded schematic. Clear it so the next job
913 // uses the schematic from the newly opened document rather than a stale copy.
914 if( m_jobHandler )
915 m_jobHandler->ClearCachedSchematic();
916}
917
918
920{
922 {
923 if( aServer )
924 aServer->DeregisterHandler( m_openSymbolHandler.get() );
925
926 m_openSymbolHandler.reset();
927 }
928
929 m_openSymbolContext.reset();
930}
931
932
934 KICAD_API_SERVER* aServer, wxString* aError )
935{
936 wxCHECK( aServer, false );
937
938 if( aSpec.kind == DOCUMENT_SPEC::KIND::CREATE_KIND )
939 return handleCreateSchematic( aSpec.path, aServer, aError );
940
941 if( aSpec.kind == DOCUMENT_SPEC::KIND::LIBID_KIND )
942 return handleOpenSymbol( aSpec.path, aSpec.libId.GetUniStringLibId(), aServer, aError );
943
944 if( aSpec.path.IsEmpty() )
945 {
946 if( aError )
947 *aError = wxS( "No path specified to open" );
948
949 return false;
950 }
951
952 wxFileName projectPath( aSpec.path );
953
954 if( projectPath.GetExt() == FILEEXT::KiCadSchematicFileExtension )
955 projectPath.SetExt( FILEEXT::ProjectFileExtension );
956 else if( projectPath.GetExt() != FILEEXT::ProjectFileExtension )
957 projectPath.SetExt( FILEEXT::ProjectFileExtension );
958
959 projectPath.MakeAbsolute();
960
961 // We currently only support one document per type (and each needs to come from
962 // the same project). This will need evolution once we support MDI and multi-project.
963 closeSchematic( aServer );
964
965 SETTINGS_MANAGER& settingsManager = Pgm().GetSettingsManager();
966
967 // Reuse an already-loaded project if one exists for this path.
968 PROJECT* project = settingsManager.GetProject( projectPath.GetFullPath() );
969
970 if( !project )
971 {
972 if( !settingsManager.LoadProject( projectPath.GetFullPath(), true ) )
973 wxLogTrace( traceApi, "Warning: no project file found for %s", aSpec.path );
974
975 project = settingsManager.GetProject( projectPath.GetFullPath() );
976 }
977
978 if( !project )
979 {
980 if( aError )
981 *aError = wxString::Format( wxS( "Error loading project for %s" ), aSpec.path );
982
983 return false;
984 }
985
986 wxFileName schPath( projectPath );
987 schPath.SetExt( FILEEXT::KiCadSchematicFileExtension );
988
989 if( !schPath.FileExists() )
990 {
991 if( aError )
992 *aError = wxString::Format( wxS( "File not found: %s" ), schPath.GetFullPath() );
993
994 return false;
995 }
996
997 SCHEMATIC* schematic = nullptr;
998
999 try
1000 {
1001 schematic = EESCHEMA_HELPERS::LoadSchematic( schPath.GetFullPath(), false, false, project );
1002
1003 if( !schematic )
1004 {
1005 if( aError )
1006 *aError = wxS( "Failed to load schematic" );
1007
1008 return false;
1009 }
1010 }
1011 catch( ... )
1012 {
1013 if( aError )
1014 *aError = wxS( "Failed to load schematic" );
1015
1016 return false;
1017 }
1018
1020
1021 m_openContext = std::make_shared<HEADLESS_SCH_CONTEXT>( &m_openSchematic, project, m_kiway );
1022
1023 if( !m_apiHandlerSchLibs )
1024 {
1025 m_apiHandlerSchLibs = std::make_unique<API_HANDLER_SCH_LIBRARIES>();
1026 aServer->RegisterHandler( m_apiHandlerSchLibs.get() );
1027 }
1028
1029 m_openHandler = std::make_unique<API_HANDLER_SCH>( m_openContext );
1030 aServer->RegisterHandler( m_openHandler.get() );
1031
1032 return true;
1033}
1034
1035
1036bool IFACE::handleCreateSchematic( const wxString& aPath, KICAD_API_SERVER* aServer, wxString* aError )
1037{
1038 wxFileName schPath( aPath );
1039 schPath.MakeAbsolute();
1040
1041 wxFileName projectPath( schPath );
1042 projectPath.SetExt( FILEEXT::ProjectFileExtension );
1043
1044 if( m_openSchematic && m_openSchematic->HasHierarchy() )
1045 {
1046 if( m_openSchematic->Hierarchy().IsModified() )
1047 {
1048 if( aError )
1049 *aError = wxS( "The current schematic has unsaved changes; save or revert it first" );
1050
1051 return false;
1052 }
1053 }
1054
1055 closeSchematic( aServer );
1056
1057 SETTINGS_MANAGER& settingsManager = Pgm().GetSettingsManager();
1058
1059 PROJECT* project = settingsManager.GetProject( projectPath.GetFullPath() );
1060
1061 if( !project )
1062 {
1063 // Create the project settings in memory (LoadProject falls back to defaults when the
1064 // file does not exist on disk) without writing any files.
1065 settingsManager.LoadProject( projectPath.GetFullPath(), true );
1066 project = settingsManager.GetProject( projectPath.GetFullPath() );
1067 }
1068
1069 if( !project )
1070 {
1071 if( aError )
1072 *aError = wxString::Format( wxS( "Error creating project for %s" ), aPath );
1073
1074 return false;
1075 }
1076
1077 std::unique_ptr<SCHEMATIC> schematic = std::make_unique<SCHEMATIC>( project );
1078 schematic->CreateDefaultScreens();
1079
1080 SCH_SCREENS screens( schematic->Root() );
1081 schematic->RootScreen()->SetFileName( schPath.GetFullPath() );
1082
1083 m_openSchematic = schematic.release();
1084
1085 m_openContext = std::make_shared<HEADLESS_SCH_CONTEXT>( &m_openSchematic, project, m_kiway );
1086
1087 if( !m_apiHandlerSchLibs )
1088 {
1089 m_apiHandlerSchLibs = std::make_unique<API_HANDLER_SCH_LIBRARIES>();
1090 aServer->RegisterHandler( m_apiHandlerSchLibs.get() );
1091 }
1092
1093 m_openHandler = std::make_unique<API_HANDLER_SCH>( m_openContext );
1094 aServer->RegisterHandler( m_openHandler.get() );
1095
1096 return true;
1097}
1098
1099
1100bool IFACE::handleOpenSymbol( const wxString& aProjectPath, const wxString& aLibIdStr, KICAD_API_SERVER* aServer,
1101 wxString* aError )
1102{
1103 LIB_ID libId;
1104
1105 if( libId.Parse( aLibIdStr ) >= 0 )
1106 {
1107 if( aError )
1108 *aError = wxString::Format( wxS( "Invalid symbol LIB_ID: %s" ), aLibIdStr );
1109
1110 return false;
1111 }
1112
1113 wxFileName projectPath( aProjectPath );
1114 projectPath.MakeAbsolute();
1115
1116 SETTINGS_MANAGER& settingsManager = Pgm().GetSettingsManager();
1117
1118 if( !settingsManager.LoadProject( projectPath.GetFullPath(), true ) )
1119 {
1120 wxLogTrace( traceApi, "Warning: no project file found for %s", aProjectPath );
1121 }
1122
1123 PROJECT* project = settingsManager.GetProject( projectPath.GetFullPath() );
1124
1125 if( !project )
1126 {
1127 if( aError )
1128 *aError = wxString::Format( wxS( "Error loading project for %s" ), aProjectPath );
1129
1130 return false;
1131 }
1132
1134 adapter->AsyncLoad();
1135 adapter->BlockUntilLoaded();
1136
1137 std::unique_ptr<LIB_SYMBOL> symbol;
1138
1139 try
1140 {
1141 LIB_SYMBOL* loaded = adapter->LoadSymbol( libId );
1142
1143 if( !loaded )
1144 {
1145 if( aError )
1146 *aError = wxString::Format( wxS( "Symbol not found: %s" ), aLibIdStr );
1147
1148 return false;
1149 }
1150
1151 symbol = std::make_unique<LIB_SYMBOL>( *loaded );
1152 }
1153 catch( const IO_ERROR& err )
1154 {
1155 if( aError )
1156 *aError = wxString::Format( wxS( "Failed to load symbol: %s" ), err.What() );
1157
1158 return false;
1159 }
1160 catch( ... )
1161 {
1162 if( aError )
1163 *aError = wxS( "Failed to load symbol" );
1164
1165 return false;
1166 }
1167
1168 closeSymbol( aServer );
1169
1170 if( !m_apiHandlerSchLibs )
1171 {
1172 m_apiHandlerSchLibs = std::make_unique<API_HANDLER_SCH_LIBRARIES>();
1173 aServer->RegisterHandler( m_apiHandlerSchLibs.get() );
1174 }
1175
1176 m_openSymbolContext = std::make_shared<HEADLESS_SYMBOL_EDITOR_CONTEXT>(
1177 std::move( symbol ), libId, project, GetAppSettings<SYMBOL_EDITOR_SETTINGS>( "symbol_editor" ), m_kiway );
1178
1179 m_openSymbolHandler = std::make_unique<API_HANDLER_SYMBOL>( m_openSymbolContext, nullptr );
1180 aServer->RegisterHandler( m_openSymbolHandler.get() );
1181
1182 return true;
1183}
1184
1185
1186bool IFACE::HandleApiCloseDocument( const DOCUMENT_SPEC& aSpec, KICAD_API_SERVER* aServer, wxString* aError )
1187{
1188 wxCHECK( aServer, false );
1189
1190 if( aSpec.kind == DOCUMENT_SPEC::KIND::LIBID_KIND )
1191 {
1192 if( !m_openSymbolContext )
1193 {
1194 if( aError )
1195 *aError = wxS( "No symbol is currently open" );
1196
1197 return false;
1198 }
1199
1200 if( aSpec.libId.IsValid() && m_openSymbolContext->GetLoadedLibId() != aSpec.libId )
1201 {
1202 if( aError )
1203 *aError = wxS( "Requested document does not match the open document" );
1204
1205 return false;
1206 }
1207
1208 closeSymbol( aServer );
1209 return true;
1210 }
1211
1212 if( !m_openContext )
1213 {
1214 if( aError )
1215 *aError = wxS( "No schematic is currently open" );
1216
1217 return false;
1218 }
1219
1220 if( !aSpec.path.IsEmpty() )
1221 {
1222 wxFileName currentSch( m_openContext->GetCurrentFileName() );
1223
1224 if( currentSch.GetFullName() != wxFileName( aSpec.path ).GetFullName() )
1225 {
1226 if( aError )
1227 *aError = wxS( "Requested document does not match the open document" );
1228
1229 return false;
1230 }
1231 }
1232
1233 closeSchematic( aServer );
1234 return true;
1235}
1236
1237
1239{
1240 wxCHECK_RET( aServer, "no API server provided" );
1241
1242 if( !m_apiHandlerSchLibs )
1243 {
1244 m_apiHandlerSchLibs = std::make_unique<API_HANDLER_SCH_LIBRARIES>();
1245 aServer->RegisterHandler( m_apiHandlerSchLibs.get() );
1246 }
1247}
1248
1249
1251{
1253
1254 if( !adapter )
1255 return false;
1256
1257 adapter->AsyncLoad();
1258 return true;
1259}
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static std::list< TOOL_ACTION * > & GetActionList()
Return list of TOOL_ACTIONs.
static std::list< ACTION_TOOLBAR_CONTROL * > GetCustomControlList(FRAME_T aContext)
Get the list of custom controls that could be used on a particular frame type.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
std::shared_ptr< BACKGROUND_JOB > Create(const wxString &aName)
Creates a background job with the given name.
void Remove(std::shared_ptr< BACKGROUND_JOB > job)
Removes the given background job from any lists and frees it.
static CLI_PROGRESS_REPORTER & GetInstance()
static CLI_REPORTER & GetInstance()
Definition reporter.cpp:261
static bool IsOnStandardSocketPath()
static void AnnounceToPrimary(FRAME_T aFrameType)
The base frame for deriving all KiCad main window classes.
static void SetSchEditFrame(SCH_EDIT_FRAME *aSchEditFrame)
static SCHEMATIC * LoadSchematic(const wxString &aFileName, bool aSetActive, bool aForceDefaultProject, PROJECT *aProject=nullptr, bool aCalculateConnectivity=true, REPORTER *aRootReporter=nullptr)
Handle Eeschema job dispatches.
SNAP_INFERENCE_SETTINGS m_SnapInference
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
An simple container class that lets us dispatch output jobs to kifaces.
Definition job.h:184
void RegisterHandler(API_HANDLER *aHandler)
Adds a new request handler to the server.
void DeregisterHandler(API_HANDLER *aHandler)
A KIFACE implementation.
Definition kiface_base.h:35
KIFACE_BASE(const char *aKifaceName, KIWAY::FACE_T aId)
Definition kiface_base.h:64
void InitSettings(APP_SETTINGS_BASE *aSettings)
Definition kiface_base.h:94
void end_common()
Common things to do for a top program module, during OnKifaceEnd();.
APP_SETTINGS_BASE * KifaceSettings() const
Definition kiface_base.h:92
bool start_common(int aCtlBits)
Common things to do for a top program module, during OnKifaceStart().
int m_start_flags
flags provided in OnKifaceStart()
bool IsSingle() const
Is this KIFACE running under single_top?
static int Apply(const git_merge_driver_source *aSrc, const char **aPathOut, unsigned int *aModeOut, git_buf *aMergedOut)
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:348
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:388
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:486
FACE_T
Known KIFACE implementations.
Definition kiway.h:354
@ FACE_SCH
eeschema DSO
Definition kiway.h:355
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:201
std::optional< float > AsyncLoadProgress() const
Returns the fraction of the libraries queued by AsyncLoad() that have been processed,...
std::vector< KI_ERROR > GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
void AbortAsyncLoad()
Aborts any async load in progress; blocks until fully done aborting.
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:168
wxString GetUniStringLibId() const
Definition lib_id.h:144
Define a library symbol object.
Definition lib_symbol.h:114
Generate the KiCad netlist format supported by Pcbnew.
void Format(OUTPUTFORMATTER *aOutputFormatter, int aCtl)
Output this s-expression netlist into aOutputFormatter.
Container for data for KiCad programs.
Definition pgm_base.h:101
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:129
void AddLibraryLoadMessages(const std::vector< KI_ERROR > &aMessages)
Add library load messages to all registered status bars.
void ClearLibraryLoadMessages()
Clear library load messages from all registered status bars.
KICAD_API_SERVER & GetApiServer()
Definition pgm_base.h:141
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:123
A progress reporter interface for use in multi-threaded environments.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
Container for project specific data.
Definition project.h:63
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
Holds all the data relating to one schematic.
Definition schematic.h:149
Schematic editor (Eeschema) main window.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition sch_screen.h:818
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void UpdateSymbolInstanceData(const std::vector< SCH_SYMBOL_INSTANCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
bool IsVirtualRootSheet() const
T * RegisterSettings(T *aSettings, bool aLoadNow=true)
Take ownership of the pointer passed in.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT * GetProject(const wxString &aFullPath) const
Retrieve a loaded project by name.
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:430
const std::string & GetString()
Definition richio.h:453
Symbol library viewer main window.
SNAP_INFERENCE_SETTINGS m_SnapInference
An interface to the global shared library manager that is schematic-specific and linked to one projec...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
Symbol library viewer main window.
UNITS_PROVIDER(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits)
EDA_UNITS GetUserUnits() const
void SetUserUnits(EDA_UNITS aUnits)
This file is part of the common library.
#define _(s)
EDA_UNITS
Definition eda_units.h:44
SCH_SHEET * g_RootSheet
Definition eeschema.cpp:98
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Definition eeschema.cpp:534
@ PANEL_SYM_EDIT_GRIDS
Definition frame_type.h:74
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
@ PANEL_SCH_FIELD_NAME_TEMPLATES
Definition frame_type.h:86
@ PANEL_SCH_TOOLBARS
Definition frame_type.h:85
@ PANEL_SYM_SNAPPING
Definition frame_type.h:75
@ FRAME_SCH_VIEWER
Definition frame_type.h:32
@ PANEL_SCH_DISP_OPTIONS
Definition frame_type.h:80
@ PANEL_SCH_SIMULATOR
Definition frame_type.h:87
@ FRAME_SCH
Definition frame_type.h:30
@ PANEL_SYM_TOOLBARS
Definition frame_type.h:78
@ FRAME_SIMULATOR
Definition frame_type.h:34
@ PANEL_SYM_EDIT_OPTIONS
Definition frame_type.h:76
@ PANEL_SCH_EDIT_OPTIONS
Definition frame_type.h:83
@ PANEL_SYM_DISP_OPTIONS
Definition frame_type.h:73
@ DIALOG_SCH_LIBRARY_TABLE
Definition frame_type.h:132
@ PANEL_SCH_DATA_SOURCES
Definition frame_type.h:88
@ PANEL_SYM_COLORS
Definition frame_type.h:77
@ PANEL_SCH_SNAPPING
Definition frame_type.h:82
@ PANEL_SCH_GRIDS
Definition frame_type.h:81
@ PANEL_SCH_COLORS
Definition frame_type.h:84
@ DIALOG_DESIGN_BLOCK_LIBRARY_TABLE
Definition frame_type.h:131
@ FRAME_SYMBOL_CHOOSER
Definition frame_type.h:33
void CopySexprFile(const wxString &aSrcPath, const wxString &aDestPath, std::function< bool(const std::string &token, wxString &value)> aCallback, wxString &aErrors)
Definition gestfich.cpp:375
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition gestfich.cpp:348
static const std::string LegacySchematicFileExtension
static const std::string NetlistFileExtension
static const std::string SymbolLibraryTableFileName
static const std::string ProjectFileExtension
static const std::string SchematicSymbolFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string LegacySymbolLibFileExtension
static const std::string KiCadSymbolLibFileExtension
static const std::string BackupFileSuffix
static const std::string LegacySymbolDocumentFileExtension
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
const wxChar *const traceApi
Flag to enable debug output related to the IPC API and its plugin system.
Definition api_utils.cpp:33
#define KIFACE_API
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition io_mgr.h:33
@ KIFACE_MERGE_DOCUMENT
int (*)( int aKind, const wxString& aAncestor, const wxString& aOurs, const wxString& aTheirs,...
Definition kiface_ids.h:55
@ KIFACE_NETLIST_SCHEMATIC
Definition kiface_ids.h:48
@ KIFACE_OPEN_DIFF_DIALOG
int (*)( int aKind, const wxString& aFileA, const wxString& aFileB, const wxString& aLabelA,...
Definition kiface_ids.h:62
#define KFCTL_CLI
Running as CLI app.
Definition kiway.h:176
#define KIFACE_GETTER
Definition kiway.h:110
@ MAIL_RELOAD_LIB
Definition mail_type.h:54
DOC_KIND
Document type a diff/merge entry point should route to, derived from a file path's extension.
bool RegisterMergeDriver(const char *aName, MERGE_APPLY_FN aApply)
Register a KiCad merge driver with libgit2.
static int eeschemaMergeExport(int aKind, const wxString &aAncestor, const wxString &aOurs, const wxString &aTheirs, const wxString &aOutput, bool aInteractive, bool aSingleFile, REPORTER *aReporter)
Definition eeschema.cpp:511
bool generateSchematicNetlist(const wxString &aFilename, std::string &aNetlist, KIWAY *aKiway)
Definition eeschema.cpp:186
static std::unique_ptr< SCHEMATIC > readSchematicFromFile(const std::string &aFilename)
Definition eeschema.cpp:115
SCH::IFACE KIFACE_BASE, UNITS_PROVIDER kiface("eeschema", KIWAY::FACE_SCH)
static int eeschemaOpenDiffDialogExport(int aKind, const wxString &aFileA, const wxString &aFileB, const wxString &aLabelA, const wxString &aLabelB, wxWindow *aParent, REPORTER *aReporter)
Definition eeschema.cpp:521
#define GNL_ALL
@ GNL_OPT_KICAD
void InvokeEditDesignBlockLibTable(KIWAY *aKiway, wxWindow *aParent)
PANEL_SNAPPING * CreateSnappingPanel(wxWindow *aParent, SETTINGS_T *aCfg, FRAME_T aFrameType, SNAP_INFERENCE_SETTINGS SETTINGS_T::*aInference=nullptr, MAGNETIC_SETTINGS SETTINGS_T::*aMagnetics=nullptr)
Build the snapping page for an editor.
void InvokeSchEditSymbolLibTable(KIWAY *aKiway, wxWindow *aParent)
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
wxString path
File path (KIND::FILE_KIND) or project path (KIND::LIBID_KIND).
Definition kiway.h:164
LIB_ID libId
Library identifier; valid when kind == KIND::LIBID_KIND.
Definition kiway.h:165
Implement a participant in the KIWAY alchemy.
Definition kiway.h:153
std::future< void > m_libraryPreloadReturn
Definition eeschema.cpp:493
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
Definition eeschema.cpp:545
std::shared_ptr< BACKGROUND_JOB > m_libraryPreloadBackgroundJob
Definition eeschema.cpp:492
std::unique_ptr< API_HANDLER_SCH > m_openHandler
Definition eeschema.cpp:505
void PreloadLibraries(KIWAY *aKiway) override
Definition eeschema.cpp:600
void closeSymbol(KICAD_API_SERVER *aServer)
Definition eeschema.cpp:919
void SaveFileAs(const wxString &aProjectBasePath, const wxString &aProjectName, const wxString &aNewProjectBasePath, const wxString &aNewProjectName, const wxString &aSrcFilePath, wxString &aErrors) override
Saving a file under a different name is delegated to the various KIFACEs because the project doesn't ...
Definition eeschema.cpp:744
void ProjectChanged() override
Definition eeschema.cpp:718
std::unique_ptr< API_HANDLER_SYMBOL > m_openSymbolHandler
Definition eeschema.cpp:504
void CancelPreload(bool aBlock=true) override
Definition eeschema.cpp:706
wxWindow * CreateKiWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Create a wxWindow for the current project.
Definition eeschema.cpp:219
EESCHEMA_JOBS_HANDLER * JobHandler() const
Accessor for the non-job diff/merge exports (eeschemaMergeExport etc.).
Definition eeschema.cpp:456
std::atomic_bool m_libraryPreloadAbort
Definition eeschema.cpp:495
KIWAY * m_kiway
Definition eeschema.cpp:500
IFACE(const char *aName, KIWAY::FACE_T aType)
Definition eeschema.cpp:207
void RegisterLibraryHandlers(KICAD_API_SERVER *aServer) override
Register this face's library API handlers on the given server.
void Reset() override
Reloads global state.
Definition eeschema.cpp:590
void * IfaceOrAddress(int aDataId) override
Return a pointer to the requested object.
Definition eeschema.cpp:438
int HandleJob(JOB *aJob, REPORTER *aReporter, PROGRESS_REPORTER *aProgressReporter) override
Definition eeschema.cpp:884
std::unique_ptr< EESCHEMA_JOBS_HANDLER > m_jobHandler
Definition eeschema.cpp:491
std::unique_ptr< API_HANDLER_SCH_LIBRARIES > m_apiHandlerSchLibs
Definition eeschema.cpp:506
bool LoadAllLibraries() override
Starts a background load of all libraries of the type owned by this face.
std::atomic_bool m_libraryPreloadInProgress
Definition eeschema.cpp:494
bool HandleApiCloseDocument(const DOCUMENT_SPEC &aSpec, KICAD_API_SERVER *aServer, wxString *aError) override
Close the document identified by aSpec.
bool HandleApiOpenDocument(const DOCUMENT_SPEC &aSpec, KICAD_API_SERVER *aServer, wxString *aError) override
Definition eeschema.cpp:933
void closeSchematic(KICAD_API_SERVER *aServer)
Definition eeschema.cpp:897
std::shared_ptr< HEADLESS_SYMBOL_EDITOR_CONTEXT > m_openSymbolContext
Definition eeschema.cpp:503
bool handleOpenSymbol(const wxString &aProjectPath, const wxString &aLibIdStr, KICAD_API_SERVER *aServer, wxString *aError)
bool HandleJobConfig(JOB *aJob, wxWindow *aParent) override
Definition eeschema.cpp:890
std::shared_ptr< HEADLESS_SCH_CONTEXT > m_openContext
Definition eeschema.cpp:502
bool handleCreateSchematic(const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError)
SCHEMATIC * m_openSchematic
Definition eeschema.cpp:501
void OnKifaceEnd() override
Called just once just before the DSO is to be unloaded.
Definition eeschema.cpp:725
IbisParser parser & reporter
VECTOR3I expected(15, 30, 45)
static const long long MM
wxLogTrace helper definitions.
Definition of file extensions used in Kicad.