KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew.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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[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, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <pgm_base.h>
27#include <eda_pattern_match.h>
30#include <confirm.h>
31#include <kiface_base.h>
32#include <kiface_ids.h>
33#include <kiway_holder.h>
34#include <pcb_edit_frame.h>
35#include <eda_dde.h>
36#include <macros.h>
37#include <wx/snglinst.h>
38#include <gestfich.h>
39#include <paths.h>
40#include <pcbnew_settings.h>
41#include <footprint.h>
51#include <footprint_info_impl.h>
52#include <footprint.h>
53#include <nlohmann/json.hpp>
57#include <panel_edit_options.h>
68#include <project_pcb.h>
69#include <string_utils.h>
70#include <thread_pool.h>
71#include <trace_helpers.h>
72#include <widgets/kistatusbar.h>
73
74#include <wx/tokenzr.h>
75
76#include "invoke_pcb_dialog.h"
78#include "pcbnew_jobs_handler.h"
79
83#include <toolbars_pcb_editor.h>
84
85#include <wx/crt.h>
86
87#if defined( KICAD_IPC_API )
89#include <api/api_handler_pcb.h>
90#include <api/api_server.h>
91#include <api/api_utils.h>
94#include <board.h>
95#include <board_loader.h>
97#include <lib_id.h>
98#include <project_pcb.h>
99#endif
100
101
114static wxString filterFootprints( const wxString& aFilterJson )
115{
116 using json = nlohmann::json;
117
118 try
119 {
120 json input = json::parse( aFilterJson.ToStdString() );
121
122 int pinCount = input.value( "pin_count", 0 );
123 bool zeroFilters = input.value( "zero_filters", true );
124 int maxResults = input.value( "max_results", 400 );
125
126 std::vector<std::unique_ptr<EDA_PATTERN_MATCH>> filterMatchers;
127
128 if( input.contains( "filters" ) && input["filters"].is_array() )
129 {
130 for( const auto& f : input["filters"] )
131 {
132 if( f.is_string() )
133 {
134 wxString pattern = wxString::FromUTF8( f.get<std::string>() );
135 auto matcher = std::make_unique<EDA_PATTERN_MATCH_WILDCARD_ANCHORED>();
136 matcher->SetPattern( pattern.Lower() );
137 filterMatchers.push_back( std::move( matcher ) );
138 }
139 }
140 }
141
142 bool hasFilters = ( pinCount > 0 || !filterMatchers.empty() );
143
144 if( zeroFilters && !hasFilters )
145 return wxS( "[]" );
146
147 PROJECT* project = nullptr;
148
149 if( wxTheApp )
150 {
151 wxWindow* focus = wxWindow::FindFocus();
152 wxWindow* top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
153
154 if( top )
155 {
156 if( KIWAY_HOLDER* holder = dynamic_cast<KIWAY_HOLDER*>( top ) )
157 project = &holder->Prj();
158 }
159 }
160
161 if( !project )
163
165
166 if( !adapter )
167 return wxS( "[]" );
168
169 adapter->AsyncLoad();
170 adapter->BlockUntilLoaded();
171
172 // Iterate through preloaded footprints directly instead of re-reading from disk
173 json output = json::array();
174 int count = 0;
175
176 for( const wxString& nickname : adapter->GetLibraryNames() )
177 {
178 std::vector<FOOTPRINT*> footprints = adapter->GetFootprints( nickname, true );
179
180 for( FOOTPRINT* fp : footprints )
181 {
182 if( !fp )
183 continue;
184
185 // Pin count filter
186 if( pinCount > 0 )
187 {
188 int fpPadCount = fp->GetUniquePadCount( DO_NOT_INCLUDE_NPTH );
189
190 if( fpPadCount != pinCount )
191 continue;
192 }
193
194 // Footprint filter patterns with case-insensitive matching
195 if( !filterMatchers.empty() )
196 {
197 bool matches = false;
198
199 for( const auto& matcher : filterMatchers )
200 {
201 wxString name;
202
203 // If filter contains ':', include library nickname in match string
204 if( matcher->GetPattern().Contains( wxS( ":" ) ) )
205 name = fp->GetFPID().GetLibNickname().wx_str().Lower() + wxS( ":" );
206
207 name += fp->GetFPID().GetLibItemName().wx_str().Lower();
208
209 if( matcher->Find( name ) )
210 {
211 matches = true;
212 break;
213 }
214 }
215
216 if( !matches )
217 continue;
218 }
219
220 wxString libId = fp->GetFPID().Format();
221 output.push_back( libId.ToStdString() );
222
223 if( ++count >= maxResults )
224 break;
225 }
226
227 if( count >= maxResults )
228 break;
229 }
230
231 return wxString::FromUTF8( output.dump() );
232 }
233 catch( const std::exception& )
234 {
235 return wxS( "[]" );
236 }
237}
238
239
240namespace PCB {
241
242static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
243{
244 // Of course all are virtual overloads, implementations of the KIFACE.
245
246 IFACE( const char* aName, KIWAY::FACE_T aType ) :
247 KIFACE_BASE( aName, aType ),
249 {}
250
251 bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway ) override;
252
253 void Reset() override;
254
255 void OnKifaceEnd() override;
256
257 wxWindow* CreateKiWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) override
258 {
259 switch( aClassId )
260 {
261 case FRAME_PCB_EDITOR:
262 {
263 auto frame = new PCB_EDIT_FRAME( aKiway, aParent );
264
265 if( Kiface().IsSingle() )
266 {
267 // only run this under single_top, not under a project manager.
268 frame->CreateServer( KICAD_PCB_PORT_SERVICE_NUMBER );
269 }
270
271 return frame;
272 }
273
275 return new FOOTPRINT_EDIT_FRAME( aKiway, aParent );
276
278 return new FOOTPRINT_VIEWER_FRAME( aKiway, aParent );
279
281 return new FOOTPRINT_CHOOSER_FRAME( aKiway, aParent );
282
284 return new FOOTPRINT_WIZARD_FRAME( aKiway, aParent, FRAME_T( aClassId ) );
285
287 return FOOTPRINT_PREVIEW_PANEL::New( aKiway, aParent, this );
288
290 {
291 DIALOG_CONFIGURE_PATHS dlg( aParent );
292
293 // The dialog's constructor probably failed to set its Kiway because the
294 // dynamic_cast fails when aParent was allocated by a separate compilation
295 // module. So set it directly.
296 dlg.SetKiway( &dlg, aKiway );
297
298 // Use QuasiModal so that HTML help window will work
299 if( dlg.ShowQuasiModal() == wxID_OK )
301
302 // Dialog has completed; nothing to return.
303 return nullptr;
304 }
305
307 InvokePcbLibTableEditor( aKiway, aParent );
308 // Dialog has completed; nothing to return.
309 return nullptr;
310
312 return new PANEL_DISPLAY_OPTIONS( aParent, GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" ) );
313
314 case PANEL_FP_GRIDS:
315 {
316 FOOTPRINT_EDITOR_SETTINGS* cfg = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" );
317 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_FOOTPRINT_EDITOR, false );
318
319 if( !frame )
320 frame = aKiway->Player( FRAME_FOOTPRINT_VIEWER, false );
321
322 if( !frame )
323 frame = aKiway->Player( FRAME_PCB_EDITOR, false );
324
325 if( frame )
326 SetUserUnits( frame->GetUserUnits() );
327
328 return new PANEL_GRID_SETTINGS( aParent, this, frame, cfg, FRAME_FOOTPRINT_EDITOR );
329 }
330
332 return new PANEL_PCBNEW_DISPLAY_ORIGIN( aParent, GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" ),
334
336 {
337 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_FOOTPRINT_EDITOR, false );
338
339 if( !frame )
340 frame = aKiway->Player( FRAME_FOOTPRINT_VIEWER, false );
341
342 if( !frame )
343 frame = aKiway->Player( FRAME_PCB_EDITOR, false );
345 if( frame )
346 SetUserUnits( frame->GetUserUnits() );
348 return new PANEL_EDIT_OPTIONS( aParent, this, frame, true );
352 {
353 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_FOOTPRINT_EDITOR, false );
354
355 if( !frame )
356 frame = aKiway->Player( FRAME_FOOTPRINT_VIEWER, false );
357
358 if( !frame )
359 frame = aKiway->Player( FRAME_PCB_EDITOR, false );
360
361 if( frame )
362 SetUserUnits( frame->GetUserUnits() );
363
364 return new PANEL_FP_EDITOR_FIELD_DEFAULTS( aParent );
365 }
366
368 {
369 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_FOOTPRINT_EDITOR, false );
370
371 if( !frame )
372 frame = aKiway->Player( FRAME_FOOTPRINT_VIEWER, false );
373
374 if( !frame )
375 frame = aKiway->Player( FRAME_PCB_EDITOR, false );
376
377 if( frame )
378 SetUserUnits( frame->GetUserUnits() );
379
380 return new PANEL_FP_EDITOR_GRAPHICS_DEFAULTS( aParent, this );
381 }
382
384 return new class PANEL_FP_USER_LAYER_NAMES( aParent );
385
387 {
388 APP_SETTINGS_BASE* cfg = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" );
389 TOOLBAR_SETTINGS* tb = GetToolbarSettings<FOOTPRINT_EDIT_TOOLBAR_SETTINGS>( "fpedit-toolbars" );
390
391 std::vector<TOOL_ACTION*> actions;
392 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
393
394 for( TOOL_ACTION* action : ACTION_MANAGER::GetActionList() )
395 actions.push_back( action );
396
397 for( ACTION_TOOLBAR_CONTROL* control : ACTION_TOOLBAR::GetCustomControlList( FRAME_FOOTPRINT_EDITOR ) )
398 controls.push_back( control );
399
400 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb, FRAME_FOOTPRINT_EDITOR, actions, controls );
401 }
402
403 case PANEL_FP_COLORS:
404 return new PANEL_FP_EDITOR_COLOR_SETTINGS( aParent );
405
407 return new PANEL_DISPLAY_OPTIONS( aParent, GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ) );
408
409 case PANEL_PCB_GRIDS:
410 {
411 PCBNEW_SETTINGS* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" );
412 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_PCB_EDITOR, false );
413
414 if( !frame )
415 frame = aKiway->Player( FRAME_FOOTPRINT_EDITOR, false );
416
417 if( !frame )
418 frame = aKiway->Player( FRAME_FOOTPRINT_VIEWER, false );
419
420 if( frame )
421 SetUserUnits( frame->GetUserUnits() );
422
423 return new PANEL_GRID_SETTINGS( aParent, this, frame, cfg, FRAME_PCB_EDITOR );
424 }
425
427 return new PANEL_PCBNEW_DISPLAY_ORIGIN( aParent, GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ),
429
431 {
432 EDA_BASE_FRAME* frame = aKiway->Player( FRAME_PCB_EDITOR, false );
433
434 if( !frame )
435 frame = aKiway->Player( FRAME_FOOTPRINT_EDITOR, false );
436
437 if( !frame )
438 frame = aKiway->Player( FRAME_FOOTPRINT_VIEWER, false );
439
440 if( frame )
441 SetUserUnits( frame->GetUserUnits() );
442
443 return new PANEL_EDIT_OPTIONS( aParent, this, frame, false );
444 }
445
446 case PANEL_PCB_COLORS:
447 {
448 BOARD* board = nullptr;
449 EDA_BASE_FRAME* boardProvider = aKiway->Player( FRAME_PCB_EDITOR, false );
450
451 if( boardProvider )
452 board = static_cast<PCB_EDIT_FRAME*>( boardProvider )->GetBoard();
453
454 return new PANEL_PCBNEW_COLOR_SETTINGS( aParent, board );
455 }
456
458 {
459 APP_SETTINGS_BASE* cfg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" );
460 TOOLBAR_SETTINGS* tb = GetToolbarSettings<PCB_EDIT_TOOLBAR_SETTINGS>( "pcbnew-toolbars" );
461
462 std::vector<TOOL_ACTION*> actions;
463 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
464
465 for( TOOL_ACTION* action : ACTION_MANAGER::GetActionList() )
466 actions.push_back( action );
467
468 for( ACTION_TOOLBAR_CONTROL* control : ACTION_TOOLBAR::GetCustomControlList( FRAME_PCB_EDITOR ) )
469 controls.push_back( control );
470
471 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb, FRAME_PCB_EDITOR, actions, controls );
472 }
473
475 return new PANEL_PCBNEW_ACTION_PLUGINS( aParent );
476
478 return new PANEL_3D_DISPLAY_OPTIONS( aParent );
479
480 case PANEL_3DV_OPENGL:
481 return new PANEL_3D_OPENGL_OPTIONS( aParent );
482
484 return new PANEL_3D_RAYTRACING_OPTIONS( aParent );
485
487 {
488 APP_SETTINGS_BASE* cfg = GetAppSettings<EDA_3D_VIEWER_SETTINGS>( "3d_viewer" );
489 TOOLBAR_SETTINGS* tb = GetToolbarSettings<EDA_3D_VIEWER_TOOLBAR_SETTINGS>( "3d_viewer-toolbars" );
490
491 std::vector<TOOL_ACTION*> actions;
492 std::vector<ACTION_TOOLBAR_CONTROL*> controls;
493
494 for( TOOL_ACTION* action : ACTION_MANAGER::GetActionList() )
495 actions.push_back( action );
496
497 for( ACTION_TOOLBAR_CONTROL* control : ACTION_TOOLBAR::GetCustomControlList( FRAME_PCB_DISPLAY3D ) )
498 controls.push_back( control );
499
500 return new PANEL_TOOLBAR_CUSTOMIZATION( aParent, cfg, tb, FRAME_PCB_DISPLAY3D, actions, controls );
501 }
502
503 default:
504 return nullptr;
505 }
506 }
507
518 void* IfaceOrAddress( int aDataId ) override
519 {
520 switch( aDataId )
521 {
523 {
524 // This is the mechanism by which FOOTPRINT_SELECT_WIDGET can get access to the adapter
525 // without directly linking to pcbnew or pcbcommon, going through PROJECT::FootprintLibAdapter
526 PROJECT* project = nullptr;
527
528 if( wxTheApp )
529 {
530 wxWindow* focus = wxWindow::FindFocus();
531 wxWindow* top = focus ? wxGetTopLevelParent( focus ) : wxTheApp->GetTopWindow();
532
533 if( top )
534 {
535 if( KIWAY_HOLDER* holder = dynamic_cast<KIWAY_HOLDER*>( top ) )
536 project = &holder->Prj();
537 }
538 }
539
540 if( !project )
542
544 }
545
547 {
548 // Return function pointer for filtering footprints
549 // Signature: wxString (*)(const wxString& aFilterJson)
550 return reinterpret_cast<void*>( &filterFootprints );
551 }
552
553 default:
554 return nullptr;
555 }
556 }
557
563 void SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcProjectName,
564 const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
565 const wxString& aSrcFilePath, wxString& aErrors ) override;
566
567 int HandleJob( JOB* aJob, REPORTER* aReporter, PROGRESS_REPORTER* aProgressReporter ) override;
568
569 bool HandleJobConfig( JOB* aJob, wxWindow* aParent ) override;
570
571#if defined( KICAD_IPC_API )
572 bool HandleApiOpenDocument( const wxString& aPath,
573 KICAD_API_SERVER* aServer,
574 wxString* aError ) override;
575
576 bool HandleApiCloseDocument( const wxString& aBoardFileName,
577 KICAD_API_SERVER* aServer,
578 wxString* aError ) override;
579
580 bool handleOpenPcb( const wxString& aPath, KICAD_API_SERVER* aServer, wxString* aError );
581
582 bool handleOpenFootprint( const wxString& aProjectPath, const wxString& aLibIdStr, KICAD_API_SERVER* aServer,
583 wxString* aError );
584#endif
585
586 void PreloadLibraries( KIWAY* aKiway ) override;
587 void ProjectChanged() override;
588 void CancelPreload( bool aBlock = true ) override;
589
590private:
591 std::unique_ptr<PCBNEW_JOBS_HANDLER> m_jobHandler;
592 std::shared_ptr<BACKGROUND_JOB> m_libraryPreloadBackgroundJob;
593 std::future<void> m_libraryPreloadReturn;
595 std::atomic_bool m_libraryPreloadAbort;
596
597#if defined( KICAD_IPC_API )
598 void closeCurrentDocument( KICAD_API_SERVER* aServer );
599
600 KIWAY* m_kiway = nullptr;
601 std::shared_ptr<HEADLESS_PCB_CONTEXT> m_openContext;
602 std::unique_ptr<API_HANDLER_PCB> m_openHandler;
603 std::shared_ptr<HEADLESS_FOOTPRINT_CONTEXT> m_openFpContext;
604 std::unique_ptr<API_HANDLER_FOOTPRINT> m_openFpHandler;
605#endif
606
607} kiface( "pcbnew", KIWAY::FACE_PCB );
608
609} // namespace
610
611
612using namespace PCB;
613
614
616
617
618// KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
619// KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
620KIFACE_API KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
621{
622 return &kiface;
623}
624
625
626bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits, KIWAY* aKiway )
627{
628 // This is process-level-initialization, not project-level-initialization of the DSO.
629 // Do nothing in here pertinent to a project!
631
632 SETTINGS_MANAGER& mgr = aProgram->GetSettingsManager();
633
636
637 // We intentionally register KifaceSettings after FOOTPRINT_EDITOR_SETTINGS and EDA_3D_VIEWER_SETTINGS
638 // In legacy configs, many settings were in a single editor config and the migration routine
639 // for the main editor file will try and call into the now separate settings stores
640 // to move the settings into them
642
643 // Register the footprint editor settings as well because they share a KiFACE and need to be
644 // loaded prior to use to avoid threading deadlocks
646
647 start_common( aCtlBits );
648
649#if defined( KICAD_IPC_API )
650 m_kiway = aKiway;
651#endif
652
653 m_jobHandler = std::make_unique<PCBNEW_JOBS_HANDLER>( aKiway );
654
656 {
657 m_jobHandler->SetReporter( &CLI_REPORTER::GetInstance() );
658 m_jobHandler->SetProgressReporter( &CLI_PROGRESS_REPORTER::GetInstance() );
659 }
660
661 return true;
662}
663
664
666{
667}
668
669
671{
672 end_common();
673}
674
675
676void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcProjectName,
677 const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
678 const wxString& aSrcFilePath, wxString& aErrors )
679{
680 wxFileName destFile( aSrcFilePath );
681 wxString destPath = destFile.GetPathWithSep();
682 wxUniChar pathSep = wxFileName::GetPathSeparator();
683 wxString ext = destFile.GetExt();
684
685 if( destPath.StartsWith( aProjectBasePath + pathSep ) )
686 destPath.Replace( aProjectBasePath, aNewProjectBasePath, false );
687
688 wxString srcProjectFootprintLib = pathSep + aSrcProjectName + wxT( ".pretty" ) + pathSep;
689 wxString newProjectFootprintLib = pathSep + aNewProjectName + wxT( ".pretty" ) + pathSep;
690
691 destPath.Replace( srcProjectFootprintLib, newProjectFootprintLib, true );
692
693 destFile.SetPath( destPath );
694
697 {
698 if( destFile.GetName() == aSrcProjectName )
699 destFile.SetName( aNewProjectName );
700
701 CopySexprFile( aSrcFilePath, destFile.GetFullPath(),
702 [&]( const std::string& token, wxString& value )
703 {
704 if( token == "sheetfile" )
705 {
706 for( const wxString extension : { wxT( ".sch" ), wxT( ".kicad_sch" ) } )
707 {
708 if( value == aSrcProjectName + extension )
709 {
710 value = aNewProjectName + extension;
711 return true;
712 }
713 else if( value == aProjectBasePath + "/" + aSrcProjectName + extension )
714 {
715 value = aNewProjectBasePath + "/" + aNewProjectName + extension;
716 return true;
717 }
718 else if( value.StartsWith( aProjectBasePath ) )
719 {
720 value.Replace( aProjectBasePath, aNewProjectBasePath, false );
721 return true;
722 }
723 }
724 }
725
726 return false;
727 },
728 aErrors );
729 }
730 else if( ext == FILEEXT::LegacyPcbFileExtension )
731 {
732 if( destFile.GetName() == aSrcProjectName )
733 destFile.SetName( aNewProjectName );
734
735 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
736 }
739 {
740 // Footprints are not project-specific. Keep their source names.
741 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
742 }
744 {
745 // TODO
746 }
747 else if( ext == wxT( "rpt" ) )
748 {
749 // DRC must be the "gold standard". Since we can't guarantee that there aren't
750 // any non-deterministic cases in the save-as algorithm, we don't want to certify
751 // the result with the source's DRC report. Therefore copy it under the old
752 // name.
753 KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
754 }
755 else if( destFile.GetName() == FILEEXT::FootprintLibraryTableFileName )
756 {
757 wxFileName libTableFn( aSrcFilePath );
758 LIBRARY_TABLE libTable( libTableFn, LIBRARY_TABLE_SCOPE::PROJECT );
759 libTable.SetPath( destFile.GetFullPath() );
760 libTable.SetType( LIBRARY_TABLE_TYPE::FOOTPRINT );
761
762 for( LIBRARY_TABLE_ROW& row : libTable.Rows() )
763 {
764 wxString uri = row.URI();
765
766 uri.Replace( wxT( "/" ) + aSrcProjectName + wxT( ".pretty" ),
767 wxT( "/" ) + aNewProjectName + wxT( ".pretty" ) );
768
769 row.SetURI( uri );
770 }
771
772 libTable.Save().map_error(
773 [&]( const LIBRARY_ERROR& aError )
774 {
775 wxString msg;
776
777 if( !aErrors.empty() )
778 aErrors += wxT( "\n" );
779
780 msg.Printf( _( "Cannot copy file '%s'." ), destFile.GetFullPath() );
781 aErrors += msg;
782 } );
783 }
784 else
785 {
786 wxFAIL_MSG( wxT( "Unexpected filetype for Pcbnew::SaveFileAs()" ) );
787 }
788}
789
790
791int IFACE::HandleJob( JOB* aJob, REPORTER* aReporter, PROGRESS_REPORTER* aProgressReporter )
792{
793 return m_jobHandler->RunJob( aJob, aReporter, aProgressReporter );
794}
795
796
797bool IFACE::HandleJobConfig( JOB* aJob, wxWindow* aParent )
798{
799 return m_jobHandler->HandleJobConfig( aJob, aParent );
800}
801
802
803#if defined( KICAD_IPC_API )
804void IFACE::closeCurrentDocument( KICAD_API_SERVER* aServer )
805{
806 if( m_openHandler )
807 {
808 if( aServer )
809 aServer->DeregisterHandler( m_openHandler.get() );
810
811 m_openHandler.reset();
812 }
813
814 m_openContext.reset();
815
816 // The jobs handler caches the last-loaded board. Clear it so the next job
817 // uses the board from the newly opened document rather than a stale copy.
818 m_jobHandler->ClearCachedBoard();
819
820 if( m_openFpHandler )
821 {
822 if( aServer )
823 aServer->DeregisterHandler( m_openFpHandler.get() );
824
825 m_openFpHandler.reset();
826 }
827
828 m_openFpContext.reset();
829}
830
831
832bool IFACE::HandleApiOpenDocument( const wxString& aPath, KICAD_API_SERVER* aServer, wxString* aError )
833{
834 wxCHECK( aServer, false );
835
836 if( aPath.IsEmpty() )
837 {
838 if( aError )
839 *aError = wxS( "No path specified to open" );
840
841 return false;
842 }
843
844 return handleOpenPcb( aPath, aServer, aError );
845}
846
847
848bool IFACE::handleOpenFootprint( const wxString& aProjectPath, const wxString& aLibIdStr, KICAD_API_SERVER* aServer,
849 wxString* aError )
850{
851 LIB_ID fpid;
852
853 if( fpid.Parse( aLibIdStr ) >= 0 )
854 {
855 if( aError )
856 *aError = wxString::Format( wxS( "Invalid footprint LIB_ID: %s" ), aLibIdStr );
857
858 return false;
859 }
860
861 wxFileName projectPath( aProjectPath );
862 projectPath.MakeAbsolute();
863
864 SETTINGS_MANAGER& settingsManager = Pgm().GetSettingsManager();
865
866 if( !settingsManager.LoadProject( projectPath.GetFullPath(), true ) )
867 {
868 wxLogTrace( traceApi, "Warning: no project file found for %s", aProjectPath );
869 }
870
871 PROJECT* project = settingsManager.GetProject( projectPath.GetFullPath() );
872
873 if( !project )
874 {
875 if( aError )
876 *aError = wxString::Format( wxS( "Error loading project for %s" ), aProjectPath );
877
878 return false;
879 }
880
881 std::shared_ptr<HEADLESS_FOOTPRINT_CONTEXT> newContext;
882
883 try
884 {
885 FOOTPRINT_LIBRARY_ADAPTER* adapter = PROJECT_PCB::FootprintLibAdapter( project );
886 adapter->AsyncLoad();
887 adapter->BlockUntilLoaded();
888 std::unique_ptr<FOOTPRINT> footprint( adapter->LoadFootprintWithOptionalNickname( fpid, true ) );
889
890 if( !footprint )
891 {
892 if( aError )
893 *aError = wxString::Format( wxS( "Footprint not found: %s" ), aLibIdStr );
894
895 return false;
896 }
897
898 newContext = std::make_shared<HEADLESS_FOOTPRINT_CONTEXT>(
899 std::move( footprint ), fpid, project, GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" ), m_kiway );
900 }
901 catch( ... )
902 {
903 if( aError )
904 *aError = wxString::Format( wxS( "Failed to load footprint: %s" ), aLibIdStr );
905
906 return false;
907 }
908
909 closeCurrentDocument( aServer );
910 m_openFpContext = std::move( newContext );
911
912 m_openFpHandler = std::make_unique<API_HANDLER_FOOTPRINT>( m_openFpContext, nullptr );
913 aServer->RegisterHandler( m_openFpHandler.get() );
914
915 return true;
916}
917
918
919bool IFACE::handleOpenPcb( const wxString& aPath, KICAD_API_SERVER* aServer, wxString* aError )
920{
921 wxFileName projectPath( aPath );
922
923 if( projectPath.GetExt() == FILEEXT::KiCadPcbFileExtension )
924 projectPath.SetExt( FILEEXT::ProjectFileExtension );
925 else if( projectPath.GetExt() != FILEEXT::ProjectFileExtension )
926 projectPath.SetExt( FILEEXT::ProjectFileExtension );
927
928 projectPath.MakeAbsolute();
929
930 // Close any existing document before loading a new project. LoadProject with
931 // aSetActive=true destroys the old PROJECT, which would leave the old board and
932 // context holding dangling m_project pointers.
933 closeCurrentDocument( aServer );
934
935 SETTINGS_MANAGER& settingsManager = Pgm().GetSettingsManager();
936
937 if( !settingsManager.LoadProject( projectPath.GetFullPath(), true ) )
938 {
939 wxLogTrace( traceApi, "Warning: no project file found for %s", aPath );
940 }
941
942 PROJECT* project = settingsManager.GetProject( projectPath.GetFullPath() );
943
944 if( !project )
945 {
946 if( aError )
947 *aError = wxString::Format( wxS( "Error loading project for %s" ), aPath );
948
949 return false;
950 }
951
952 wxFileName boardPath( projectPath );
953 boardPath.SetExt( FILEEXT::KiCadPcbFileExtension );
954
955 if( !boardPath.FileExists() )
956 {
957 if( aError )
958 *aError = wxString::Format( wxS( "File not found: %s" ), aPath );
959
960 return false;
961 }
962
963 PCB_IO_MGR::PCB_FILE_T pluginType =
965
966 if( pluginType == PCB_IO_MGR::FILE_TYPE_NONE )
967 {
968 if( aError )
969 *aError = wxString::Format( wxS( "%s is not a recognized file type" ), aPath );
970
971 return false;
972 }
973
974 std::shared_ptr<HEADLESS_PCB_CONTEXT> newContext;
975
976 try
977 {
978 std::unique_ptr<BOARD> loadedBoard = BOARD_LOADER::Load( boardPath.GetFullPath(), pluginType, project );
979
980 if( !loadedBoard )
981 {
982 if( aError )
983 *aError = wxS( "Failed to load board" );
984
985 return false;
986 }
987
988 newContext = std::make_shared<HEADLESS_PCB_CONTEXT>( std::move( loadedBoard ), project,
989 GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" ), m_kiway );
990 }
991 catch( ... )
992 {
993 if( aError )
994 *aError = wxS( "Failed to load board" );
995
996 return false;
997 }
998
999 m_openContext = std::move( newContext );
1000
1001 m_openHandler = std::make_unique<API_HANDLER_PCB>( m_openContext, nullptr );
1002 aServer->RegisterHandler( m_openHandler.get() );
1003
1004 return true;
1005}
1006
1007
1008bool IFACE::HandleApiCloseDocument( const wxString& aFileName, KICAD_API_SERVER* aServer, wxString* aError )
1009{
1010 wxCHECK( aServer, false );
1011
1012 if( !m_openContext && !m_openFpContext )
1013 {
1014 if( aError )
1015 *aError = wxS( "No document is currently open" );
1016
1017 return false;
1018 }
1019
1020 if( !aFileName.IsEmpty() && m_openContext )
1021 {
1022 wxFileName currentBoard( m_openContext->GetCurrentFileName() );
1023
1024 if( currentBoard.GetFullName() != aFileName )
1025 {
1026 if( aError )
1027 *aError = wxS( "Requested document does not match the open document" );
1028
1029 return false;
1030 }
1031 }
1032
1033 closeCurrentDocument( aServer );
1034 return true;
1035}
1036#endif
1037
1038
1040{
1041 constexpr static int interval = 150;
1042 constexpr static int timeLimit = 120000;
1043
1044 wxCHECK( aKiway, /* void */ );
1045
1046 // Use compare_exchange to atomically check and set the flag to prevent race conditions
1047 // when PreloadLibraries is called multiple times concurrently (e.g., from project manager
1048 // and pcb editor both scheduling via CallAfter)
1049 bool expected = false;
1050
1051 if( !m_libraryPreloadInProgress.compare_exchange_strong( expected, true ) )
1052 return;
1053
1055
1057 Pgm().GetBackgroundJobMonitor().Create( _( "Loading Footprint Libraries" ) );
1058
1059 auto preload =
1060 [this, aKiway]() -> void
1061 {
1062 std::shared_ptr<BACKGROUND_JOB_REPORTER> reporter =
1064
1066
1067 int elapsed = 0;
1068 bool aborted = false;
1069
1070 reporter->Report( _( "Loading Footprint Libraries" ) );
1071 adapter->AsyncLoad();
1072
1073 while( true )
1074 {
1075 if( m_libraryPreloadAbort.load() )
1076 {
1077 aborted = true;
1078 break;
1079 }
1080
1081 std::this_thread::sleep_for( std::chrono::milliseconds( interval ) );
1082
1083 if( std::optional<float> loadStatus = adapter->AsyncLoadProgress() )
1084 {
1085 float progress = *loadStatus;
1086 reporter->SetCurrentProgress( progress );
1087
1088 if( progress >= 1 )
1089 break;
1090 }
1091 else
1092 {
1093 reporter->SetCurrentProgress( 1 );
1094 break;
1095 }
1096
1097 elapsed += interval;
1098
1099 if( elapsed > timeLimit )
1100 break;
1101 }
1102
1103 adapter->BlockUntilLoaded();
1104
1105 // Check again after blocking - abort may have been requested while we were waiting
1106 if( m_libraryPreloadAbort.load() )
1107 aborted = true;
1108
1109 // If aborted, skip operations that use the adapter since the project may have changed
1110 // and the adapter's project reference could be stale. This prevents use-after-free
1111 // crashes when switching projects during library preload.
1112 if( !aborted )
1113 {
1114 // Collect and report library load errors from adapter
1115 wxString errors = adapter->GetLibraryLoadErrors();
1116
1117 wxLogTrace( traceLibraries,
1118 "pcbnew PreloadLibraries: adapter errors.IsEmpty()=%d, length=%zu",
1119 errors.IsEmpty(), errors.length() );
1120
1121 if( !errors.IsEmpty() )
1122 {
1123 std::vector<LOAD_MESSAGE> messages =
1125
1126 wxLogTrace( traceLibraries, " -> adapter: collected %zu messages",
1127 messages.size() );
1128
1129 if( !messages.empty() )
1130 Pgm().AddLibraryLoadMessages( messages );
1131 }
1132 else
1133 {
1134 wxLogTrace( traceLibraries, " -> no errors from footprint adapter" );
1135 }
1136 }
1137 else
1138 {
1139 wxLogTrace( traceLibraries, "pcbnew PreloadLibraries: aborted, skipping footprint processing" );
1140 }
1141
1142 m_libraryPreloadAbort.store( false );
1145 m_libraryPreloadInProgress.store( false );
1146
1147 // Only send reload notifications if we weren't aborted
1148 if( !aborted )
1149 {
1150 std::string payload = "";
1151 aKiway->ExpressMail( FRAME_PCB_EDITOR, MAIL_RELOAD_LIB, payload, nullptr, true );
1152 aKiway->ExpressMail( FRAME_FOOTPRINT_EDITOR, MAIL_RELOAD_LIB, payload, nullptr, true );
1153 aKiway->ExpressMail( FRAME_CVPCB, MAIL_RELOAD_LIB, payload, nullptr, true );
1154 }
1155 };
1156
1157 std::future<void> preloadFuture = std::async( std::launch::async, preload );
1158 m_libraryPreloadReturn = std::move( preloadFuture );
1159}
1160
1161
1163{
1164 if( m_libraryPreloadInProgress.load() )
1165 m_libraryPreloadAbort.store( true );
1166}
1167
1168
1169void IFACE::CancelPreload( bool aBlock )
1170{
1171 if( m_libraryPreloadInProgress.load() )
1172 {
1173 m_libraryPreloadAbort.store( true );
1174
1175 if( aBlock )
1177 }
1178}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
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.
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 std::unique_ptr< BOARD > Load(const wxString &aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, PROJECT *aProject, const OPTIONS &aOptions)
static CLI_PROGRESS_REPORTER & GetInstance()
static CLI_REPORTER & GetInstance()
Definition reporter.cpp:161
The base frame for deriving all KiCad main window classes.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
std::vector< FOOTPRINT * > GetFootprints(const wxString &aNickname, bool aBestEfforts=false)
Retrieves a list of footprints contained in a given loaded library.
FOOTPRINT * LoadFootprintWithOptionalNickname(const LIB_ID &aFootprintId, bool aKeepUUID)
Load a footprint having aFootprintId with possibly an empty nickname.
static FOOTPRINT_PREVIEW_PANEL * New(KIWAY *aKiway, wxWindow *aParent, UNITS_PROVIDER *aUnitsProvider)
Component library viewer main window.
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:39
KIFACE_BASE(const char *aKifaceName, KIWAY::FACE_T aId)
Definition kiface_base.h:67
void InitSettings(APP_SETTINGS_BASE *aSettings)
Definition kiface_base.h:97
void end_common()
Common things to do for a top program module, during OnKifaceEnd();.
APP_SETTINGS_BASE * KifaceSettings() const
Definition kiface_base.h:95
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?
A mix in class which holds the location of a wxWindow's KIWAY.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:315
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:402
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:500
FACE_T
Known KIFACE implementations.
Definition kiway.h:321
@ FACE_PCB
pcbnew DSO
Definition kiway.h:323
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:594
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:205
std::optional< float > AsyncLoadProgress() const
Returns async load progress between 0.0 and 1.0, or nullopt if load is not in progress.
wxString GetLibraryLoadErrors() const
Returns all library load errors as newline-separated strings for display.
std::vector< wxString > GetLibraryNames() const
Returns a list of library nicknames that are available (skips any that failed to load)
void AsyncLoad()
Loads all available libraries for this adapter type in the background.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:52
The main frame for Pcbnew.
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition pcb_io_mgr.h:56
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
Container for data for KiCad programs.
Definition pgm_base.h:108
virtual BACKGROUND_JOBS_MONITOR & GetBackgroundJobMonitor() const
Definition pgm_base.h:136
void ClearLibraryLoadMessages()
Clear library load messages from all registered status bars.
void AddLibraryLoadMessages(const std::vector< LOAD_MESSAGE > &aMessages)
Add library load messages to all registered status bars.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:130
A progress reporter interface for use in multi-threaded environments.
static FOOTPRINT_LIBRARY_ADAPTER * FootprintLibAdapter(PROJECT *aProject)
Container for project specific data.
Definition project.h:66
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:75
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.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
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)
DDE server & client.
#define KICAD_PCB_PORT_SERVICE_NUMBER
Pcbnew listens on this port for commands from Eeschema.
Definition eda_dde.h:40
Abstract pattern-matching tool and implementations.
EDA_UNITS
Definition eda_units.h:48
std::unique_ptr< EESCHEMA_JOBS_HANDLER > m_jobHandler
Definition eeschema.cpp:264
@ DO_NOT_INCLUDE_NPTH
Definition footprint.h:74
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:33
@ PANEL_PCB_GRIDS
Definition frame_type.h:98
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ PANEL_3DV_TOOLBARS
Definition frame_type.h:108
@ FRAME_FOOTPRINT_VIEWER
Definition frame_type.h:45
@ PANEL_3DV_OPENGL
Definition frame_type.h:106
@ PANEL_FP_DEFAULT_GRAPHICS_VALUES
Definition frame_type.h:93
@ PANEL_PCB_TOOLBARS
Definition frame_type.h:101
@ PANEL_PCB_ORIGINS_AXES
Definition frame_type.h:103
@ FRAME_FOOTPRINT_WIZARD
Definition frame_type.h:46
@ PANEL_PCB_EDIT_OPTIONS
Definition frame_type.h:99
@ PANEL_FP_DISPLAY_OPTIONS
Definition frame_type.h:87
@ PANEL_PCB_COLORS
Definition frame_type.h:100
@ PANEL_FP_USER_LAYER_NAMES
Definition frame_type.h:94
@ PANEL_3DV_RAYTRACING
Definition frame_type.h:107
@ DIALOG_PCB_LIBRARY_TABLE
Definition frame_type.h:126
@ FRAME_FOOTPRINT_PREVIEW
Definition frame_type.h:48
@ FRAME_FOOTPRINT_CHOOSER
Definition frame_type.h:44
@ PANEL_FP_GRIDS
Definition frame_type.h:88
@ PANEL_FP_ORIGINS_AXES
Definition frame_type.h:95
@ PANEL_PCB_DISPLAY_OPTS
Definition frame_type.h:97
@ DIALOG_CONFIGUREPATHS
Definition frame_type.h:123
@ PANEL_FP_COLORS
Definition frame_type.h:90
@ PANEL_FP_DEFAULT_FIELDS
Definition frame_type.h:92
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
@ FRAME_PCB_DISPLAY3D
Definition frame_type.h:47
@ PANEL_FP_EDIT_OPTIONS
Definition frame_type.h:89
@ PANEL_FP_TOOLBARS
Definition frame_type.h:91
@ PANEL_PCB_ACTION_PLUGINS
Definition frame_type.h:102
@ PANEL_3DV_DISPLAY_OPTIONS
Definition frame_type.h:105
@ FRAME_CVPCB
Definition frame_type.h:52
nlohmann::json json
Definition gerbview.cpp:53
void CopySexprFile(const wxString &aSrcPath, const wxString &aDestPath, std::function< bool(const std::string &token, wxString &value)> aCallback, wxString &aErrors)
Definition gestfich.cpp:338
void KiCopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Definition gestfich.cpp:311
static const std::string ProjectFileExtension
static const std::string LegacyPcbFileExtension
static const std::string FootprintLibraryTableFileName
static const std::string BackupFileSuffix
static const std::string LegacyFootprintLibPathExtension
static const std::string FootprintAssignmentFileExtension
static const std::string KiCadFootprintFileExtension
static const std::string KiCadPcbFileExtension
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:29
#define KIFACE_API
@ KIFACE_FOOTPRINT_LIBRARY_ADAPTER
Definition kiface_ids.h:34
@ KIFACE_FILTER_FOOTPRINTS
Function pointer type: wxString (*)(const wxString& aFilterJson) Input JSON: {"pin_count": N,...
Definition kiface_ids.h:39
#define KFCTL_CLI
Running as CLI app.
Definition kiway.h:165
#define KIFACE_GETTER
Definition kiway.h:113
#define KICTL_KICAD_ONLY
chosen file is from KiCad according to user
This file contains miscellaneous commonly used macros and functions.
@ MAIL_RELOAD_LIB
Definition mail_type.h:58
PCB::IFACE KIFACE_BASE, UNITS_PROVIDER kiface("pcbnew", KIWAY::FACE_PCB)
void InvokePcbLibTableEditor(KIWAY *aKiway, wxWindow *aCaller)
Function InvokePcbLibTableEditor shows the modal DIALOG_FP_LIB_TABLE for purposes of editing the glob...
static wxString filterFootprints(const wxString &aFilterJson)
Filter footprints based on criteria passed as JSON.
Definition pcbnew.cpp:114
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Definition pcbnew.cpp:615
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
@ RPT_SEVERITY_ERROR
T * GetToolbarSettings(const wxString &aFilename)
T * GetAppSettings(const char *aFilename)
std::vector< LOAD_MESSAGE > ExtractLibraryLoadErrors(const wxString &aErrorString, int aSeverity)
Parse library load error messages, extracting user-facing information while stripping internal code l...
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
Implement a participant in the KIWAY alchemy.
Definition kiway.h:156
virtual bool HandleApiCloseDocument(const wxString &aBoardFileName, KICAD_API_SERVER *aServer, wxString *aError)
Definition kiway.h:269
virtual bool HandleApiOpenDocument(const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError)
Definition kiway.h:259
std::atomic_bool m_libraryPreloadInProgress
Definition pcbnew.cpp:594
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
Definition pcbnew.cpp:626
void PreloadLibraries(KIWAY *aKiway) override
Definition pcbnew.cpp:1039
void ProjectChanged() override
Definition pcbnew.cpp:1162
void SaveFileAs(const wxString &aProjectBasePath, const wxString &aSrcProjectName, 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 pcbnew.cpp:676
void CancelPreload(bool aBlock=true) override
Definition pcbnew.cpp:1169
std::shared_ptr< BACKGROUND_JOB > m_libraryPreloadBackgroundJob
Definition pcbnew.cpp:592
void * IfaceOrAddress(int aDataId) override
Return a pointer to the requested object.
Definition pcbnew.cpp:518
void Reset() override
Reloads global state.
Definition pcbnew.cpp:665
wxWindow * CreateKiWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Create a wxWindow for the current project.
Definition pcbnew.cpp:257
IFACE(const char *aName, KIWAY::FACE_T aType)
Definition pcbnew.cpp:246
std::atomic_bool m_libraryPreloadAbort
Definition pcbnew.cpp:595
int HandleJob(JOB *aJob, REPORTER *aReporter, PROGRESS_REPORTER *aProgressReporter) override
Definition pcbnew.cpp:791
std::unique_ptr< PCBNEW_JOBS_HANDLER > m_jobHandler
Definition pcbnew.cpp:591
bool HandleJobConfig(JOB *aJob, wxWindow *aParent) override
Definition pcbnew.cpp:797
void OnKifaceEnd() override
Called just once just before the DSO is to be unloaded.
Definition pcbnew.cpp:670
std::future< void > m_libraryPreloadReturn
Definition pcbnew.cpp:593
IbisParser parser & reporter
KIBIS top(path, &reporter)
VECTOR3I expected(15, 30, 45)
static const long long MM
nlohmann::json output
#define ENVVARS_CHANGED
wxLogTrace helper definitions.
Definition of file extensions used in Kicad.