KiCad PCB EDA Suite
Loading...
Searching...
No Matches
kiway.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) 2014 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <cstring>
26
27#include <app_monitor.h>
28#include <core/ignore.h>
29#include <macros.h>
30#include <kiway.h>
31#include <kiway_player.h>
32#include <kiway_mail.h>
33#include <pgm_base.h>
34#include <config.h>
35#include <id.h>
36#include <kiplatform/app.h>
39#include <tool/action_manager.h>
40#include <logging.h>
41#include <local_history.h>
42
43#include <wx/dynlib.h>
44#include <wx/stdpaths.h>
45#include <wx/debug.h>
46#include <wx/utils.h>
47#include <confirm.h>
48
49std::array<KIFACE*, KIWAY::FACE_T::KIWAY_FACE_COUNT> KIWAY::m_kiface;
50std::array<int, KIWAY::FACE_T::KIWAY_FACE_COUNT> KIWAY::m_kiface_version;
51
52
53
54KIWAY::KIWAY( int aCtlBits, wxFrame* aTop ):
55 m_ctl( aCtlBits ), m_top( nullptr ), m_blockingDialog( wxID_NONE ), m_local_history( nullptr )
56{
58 SetTop( aTop ); // hook player_destroy_handler() into aTop.
59
60 // Set the array of all known frame window IDs to empty = wxID_NONE,
61 // once they are be created, they are added with FRAME_T as index to this array.
62 // Note: A non empty entry does not mean the frame still exists.
63 // It means only the frame was created at least once. It can be destroyed after.
64 // These entries are not cleared automatically on window closing. The purpose is just
65 // to allow a call to wxWindow::FindWindowById() using a FRAME_T frame type
66 for( int n = 0; n < KIWAY_PLAYER_COUNT; n++ )
67 m_playerFrameId[n] = wxID_NONE;
68}
69
70
72{
73 delete m_local_history;
74}
75
76
77#if 0
78// Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are
79// propagated upwards to parent windows if not handled below. Therefore the
80// m_top window should receive all wxWindowDestroyEvents originating from
81// KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops
82// on that event stream looking for KIWAY_PLAYERs being closed.
83
84void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event )
85{
86 // Currently : do nothing
87 event.Skip(); // skip to who, the wxApp? I'm the top window.
88}
89#endif
90
91
92void KIWAY::SetTop( wxFrame* aTop )
93{
94#if 0
95 if( m_top )
96 {
97 m_top->Disconnect( wxEVT_DESTROY,
98 wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ),
99 nullptr, this );
100 }
101
102 if( aTop )
103 {
104 aTop->Connect( wxEVT_DESTROY,
105 wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ),
106 nullptr, this );
107 }
108#endif
109
110 m_top = aTop;
111}
112
113
114const wxString KIWAY::dso_search_path( FACE_T aFaceId )
115{
116 const char* name;
117
118 switch( aFaceId )
119 {
120 case FACE_SCH: name = KIFACE_PREFIX "eeschema"; break;
121 case FACE_PCB: name = KIFACE_PREFIX "pcbnew"; break;
122 case FACE_CVPCB: name = KIFACE_PREFIX "cvpcb"; break;
123 case FACE_GERBVIEW: name = KIFACE_PREFIX "gerbview"; break;
124 case FACE_PL_EDITOR: name = KIFACE_PREFIX "pl_editor"; break;
125 case FACE_PCB_CALCULATOR: name = KIFACE_PREFIX "pcb_calculator"; break;
126 case FACE_BMP2CMP: name = KIFACE_PREFIX "bitmap2component"; break;
127
128 default:
129 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
130 return wxEmptyString;
131 }
132
133#ifndef __WXMAC__
134 wxString path;
135
137 {
138 // The 2 *.cpp program launchers: single_top.cpp and kicad.cpp expect
139 // the *.kiface's to reside in same directory as their binaries do.
140 wxString appDir;
141
142 // When running inside an AppImage, the bundled ld-linux is invoked as a wrapper
143 // which causes /proc/self/exe to resolve to the dynamic linker rather than the
144 // actual binary. Use APPDIR to construct the correct executable path.
145 if( wxGetEnv( wxT( "APPDIR" ), &appDir ) )
146 path = appDir + wxT( "/usr/bin/kicad" );
147 else
148 path = wxStandardPaths::Get().GetExecutablePath();
149 }
150
151 wxFileName fn = path;
152#else
153 // we have the dso's in main OSX bundle kicad.app/Contents/PlugIns
154 wxFileName fn = Pgm().GetExecutablePath();
155 fn.AppendDir( wxT( "Contents" ) );
156 fn.AppendDir( wxT( "PlugIns" ) );
157#endif
158
159 fn.SetName( name );
160
161 // To speed up development, it's sometimes nice to run kicad from inside
162 // the build path. In that case, each program will be in a subdirectory.
163 // To find the DSOs, we need to go up one directory and then enter a subdirectory.
164 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
165 {
166#ifdef __WXMAC__
167 // On Mac, all of the kifaces are placed in the kicad.app bundle, even though the individual
168 // standalone binaries are placed in separate bundles before the make install step runs.
169 // So, we have to jump up to the kicad directory, then the PlugIns section of the kicad
170 // bundle.
171 fn = wxStandardPaths::Get().GetExecutablePath();
172
173 fn.RemoveLastDir();
174 fn.RemoveLastDir();
175 fn.RemoveLastDir();
176 fn.RemoveLastDir();
177 fn.AppendDir( wxT( "kicad" ) );
178 fn.AppendDir( wxT( "kicad.app" ) );
179 fn.AppendDir( wxT( "Contents" ) );
180 fn.AppendDir( wxT( "PlugIns" ) );
181 fn.SetName( name );
182#else
183 const char* dirName;
184
185 // The subdirectories usually have the same name as the kiface
186 switch( aFaceId )
187 {
188 case FACE_PL_EDITOR: dirName = "pagelayout_editor"; break;
189 default: dirName = name + 1; break;
190 }
191
192 fn.RemoveLastDir();
193 fn.AppendDir( dirName );
194#endif
195 }
196
197 // Here a "suffix" == an extension with a preceding '.',
198 // so skip the preceding '.' to get an extension
199 fn.SetExt( &KIFACE_SUFFIX[1] );
200
201 return fn.GetFullPath();
202}
203
204
206{
207 return Pgm().GetSettingsManager().Prj();
208}
209
210
211KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
212{
213 // Since this will be called from python, cannot assume that code will
214 // not pass a bad aFaceId.
215 if( (unsigned) aFaceId >= m_kiface.size() )
216 {
217 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
218 return nullptr;
219 }
220
221 // return the previously loaded KIFACE, if it was.
222 if( m_kiface[aFaceId] )
223 return m_kiface[aFaceId];
224
225 // DSO with KIFACE has not been loaded yet, does caller want to load it?
226 if( doLoad )
227 {
228 wxString dname = dso_search_path( aFaceId );
229
230 // Insert DLL search path for kicad_3dsg from build dir
231 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
232 {
233 wxFileName myPath = wxStandardPaths::Get().GetExecutablePath();
234
235 if( !myPath.GetPath().EndsWith( wxT( "pcbnew" ) ) )
236 {
237 myPath.RemoveLastDir();
238 myPath.AppendDir( wxT( "pcbnew" ) );
240 }
241 }
242
243 wxString msg;
244
245#ifdef KICAD_WIN32_VERIFY_CODESIGN
246 bool codeSignOk = KIPLATFORM::ENV::VerifyFileSignature( dname );
247 if( !codeSignOk )
248 {
249 msg.Printf( _( "Failed to verify kiface library '%s' signature." ), dname );
250 THROW_IO_ERROR( msg );
251 }
252#endif
253
254 wxDynamicLibrary dso;
255
256 void* addr = nullptr;
257
258 // For some reason wxDynamicLibrary::Load() crashes in some languages
259 // (chinese for instance) when loading the dynamic library.
260 // The crash happens for Eeschema.
261 // So switch to "C" locale during loading (LC_COLLATE is enough).
262 int lc_new_type = LC_COLLATE;
263 std::string user_locale = setlocale( lc_new_type, nullptr );
264 setlocale( lc_new_type, "C" );
265
266 bool success = dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL );
267
268 setlocale( lc_new_type, user_locale.c_str() );
269
270 msg = wxString::Format( "Loading kiface %d", aFaceId );
271 APP_MONITOR::AddNavigationBreadcrumb( msg, "kiway.kiface" );
272
273 if( !success )
274 {
275 // Failure: error reporting UI was done via wxLogSysError().
276 // No further reporting required here. Apparently this is not true on all
277 // platforms and/or wxWidgets builds and KiCad will crash. Throwing the exception
278 // here and catching it in the KiCad launcher resolves the crash issue. See bug
279 // report https://bugs.launchpad.net/kicad/+bug/1577786.
280
281 msg.Printf( _( "Failed to load kiface library '%s'." ), dname );
282 THROW_IO_ERROR( msg );
283 }
284 else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == nullptr )
285 {
286 // Failure: error reporting UI was done via wxLogSysError().
287 // No further reporting required here. Assume the same thing applies here as
288 // above with the Load() call. This has not been tested.
289 msg.Printf( _( "Could not read instance name and version from kiface library '%s'." ),
290 dname );
291 THROW_IO_ERROR( msg );
292 }
293 else
294 {
295 KIFACE_GETTER_FUNC* ki_getter = (KIFACE_GETTER_FUNC*) addr;
296
297 KIFACE* kiface = ki_getter( &m_kiface_version[aFaceId], KIFACE_VERSION, &Pgm() );
298
299 // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
300 wxASSERT_MSG( kiface,
301 wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
302
303 wxDllType dsoHandle = dso.Detach();
304
305 bool startSuccess = false;
306
307 // Give the DSO a single chance to do its "process level" initialization.
308 // "Process level" specifically means stay away from any projects in there.
309
310 try
311 {
312 startSuccess = kiface->OnKifaceStart( &Pgm(), m_ctl, this );
313 }
314 catch (...)
315 {
316 // OnKiFaceStart may generate an exception
317 // Before we continue and ultimately unload our module to retry we need
318 // to process the exception before we delete the free the memory space the
319 // exception resides in
320 Pgm().HandleException( std::current_exception() );
321 }
322
323 if( startSuccess )
324 {
325 return m_kiface[aFaceId] = kiface;
326 }
327 else
328 {
329 // Usually means canceled initial global library setup
330 // But it could have been an exception/failure
331 // Let the module go out of scope to unload
332 dso.Attach( dsoHandle );
333
334 return nullptr;
335 }
336 }
337 }
338
339 return nullptr;
340}
341
342
344{
345 switch( aFrameType )
346 {
347 case FRAME_SCH:
349 case FRAME_SCH_VIEWER:
351 case FRAME_SIMULATOR:
352 return FACE_SCH;
353
354 case FRAME_PCB_EDITOR:
360 return FACE_PCB;
361
362 case FRAME_CVPCB:
364 return FACE_CVPCB;
365
366 case FRAME_GERBER:
367 return FACE_GERBVIEW;
368
369 case FRAME_PL_EDITOR:
370 return FACE_PL_EDITOR;
371
372 case FRAME_CALC:
373 return FACE_PCB_CALCULATOR;
374
375 case FRAME_BM2CMP:
376 return FACE_BMP2CMP;
377
378 default:
379 return FACE_T( -1 );
380 }
381}
382
383
385{
386 wxWindowID storedId = m_playerFrameId[aFrameType];
387
388 if( storedId == wxID_NONE )
389 return nullptr;
390
391 wxWindow* frame = wxWindow::FindWindowById( storedId );
392
393 // Since wxWindow::FindWindow*() is not cheap (especially if the window does not exist),
394 // clear invalid entries to save CPU on repeated calls that do not lead to frame creation
395 if( !frame )
396 m_playerFrameId[aFrameType].compare_exchange_strong( storedId, wxID_NONE );
397
398 return static_cast<KIWAY_PLAYER*>( frame );
399}
400
401
402KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow* aParent )
403{
404 // Since this will be called from python, cannot assume that code will
405 // not pass a bad aFrameType.
406 if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
407 {
408 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
409 return nullptr;
410 }
411
412 // return the previously opened window
413 KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
414
415 if( frame )
416 return frame;
417
418 if( doCreate )
419 {
420 try
421 {
422 wxString msg = wxString::Format( "Creating window type %d", aFrameType );
423 APP_MONITOR::AddNavigationBreadcrumb( msg, "kiway.player" );
424
425 FACE_T face_type = KifaceType( aFrameType );
426 KIFACE* kiface = KiFACE( face_type );
427
428 if( !kiface )
429 return nullptr;
430
431 frame = (KIWAY_PLAYER*) kiface->CreateKiWindow(
432 aParent, // Parent window of frame in modal mode,
433 // NULL in non modal mode
434 aFrameType,
435 this,
436 m_ctl // questionable need, these same flags
437 // were passed to KIFACE::OnKifaceStart()
438 );
439 if( frame )
440 m_playerFrameId[aFrameType].store( frame->GetId() );
441
442 return frame;
443 }
444 catch( ... )
445 {
446 Pgm().HandleException( std::current_exception() );
447 wxLogError( _( "Error loading editor." ) );
448 }
449 }
450
451 return nullptr;
452}
453
454
455bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
456{
457 // Since this will be called from python, cannot assume that code will
458 // not pass a bad aFrameType.
459 if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
460 {
461 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
462 return false;
463 }
464
465 KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
466
467 if( frame == nullptr ) // Already closed
468 return true;
469
470 wxString msg = wxString::Format( "Closing window type %d", aFrameType );
471 APP_MONITOR::AddNavigationBreadcrumb( msg, "kiway.playerclose" );
472
473 if( frame->NonUserClose( doForce ) )
474 {
475 m_playerFrameId[aFrameType] = wxID_NONE;
476 return true;
477 }
478
479 return false;
480}
481
482
483bool KIWAY::PlayersClose( bool doForce )
484{
485 bool ret = true;
486
487 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
488 ret = ret && PlayerClose( FRAME_T( i ), doForce );
489
490 return ret;
491}
492
493
495{
496 m_playerFrameId[aFrameType] = wxID_NONE;
497}
498
499
500void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
501 wxWindow* aSource, bool aFromOtherThread )
502{
503 std::unique_ptr<KIWAY_MAIL_EVENT> mail =
504 std::make_unique<KIWAY_MAIL_EVENT>( aDestination, aCommand, aPayload, aSource );
505
506 if( aFromOtherThread )
507 QueueEvent( mail.release() );
508 else
509 ProcessEvent( *mail );
510}
511
512
513void KIWAY::GetActions( std::vector<TOOL_ACTION*>& aActions ) const
514{
516 aActions.push_back( action );
517}
518
519
520void KIWAY::SetLanguage( int aLanguage )
521{
522 wxString errMsg;
523 bool ret = false;
524
525 {
526 // Only allow the traces to be logged by wx. We use our own system to log when the
527 // OS doesn't support the language, so we want to hide the wx error.
528 WX_LOG_TRACE_ONLY logtraceOnly;
529 Pgm().SetLanguageIdentifier( aLanguage );
530 ret = Pgm().SetLanguage( errMsg );
531 }
532
533 if( !ret )
534 {
535 wxString lang;
536
537 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
538 {
539 if( aLanguage == LanguagesList[ii].m_KI_Lang_Identifier )
540 {
541 if( LanguagesList[ii].m_DoNotTranslate )
542 lang = LanguagesList[ii].m_Lang_Label;
543 else
544 lang = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
545
546 break;
547 }
548 }
549
550 DisplayErrorMessage( nullptr,
551 wxString::Format( _( "Unable to switch language to %s" ), lang ),
552 errMsg );
553 return;
554 }
555
556#if 1
557 // This is a risky hack that goes away if we allow the language to be
558 // set only from the top most frame if !Kiface.IsSingle()
559
560 // Only for the C++ project manager, and not for the python one and not for
561 // single_top do we look for the EDA_BASE_FRAME as the top level window.
562 // For single_top this is not needed because that window is registered in
563 // the array below.
565 {
566 // A dynamic_cast could be better, but creates link issues
567 // (some basic_frame functions not found) on some platforms,
568 // so a static_cast is used.
569 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
570
571 if ( top )
572 {
573 top->ShowChangedLanguage();
574 wxCommandEvent e( EDA_LANG_CHANGED );
575 top->GetEventHandler()->ProcessEvent( e );
576 }
577 }
578#endif
579
580 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
581 {
582 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
583
584 if( frame )
585 {
586 frame->ShowChangedLanguage();
587 wxCommandEvent e( EDA_LANG_CHANGED );
588 frame->GetEventHandler()->ProcessEvent( e );
589 }
590 }
591}
592
593
595{
597 {
598 // A dynamic_cast could be better, but creates link issues
599 // (some basic_frame functions not found) on some platforms,
600 // so a static_cast is used.
601 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
602
603 if( top )
604 top->CommonSettingsChanged( aFlags );
605 }
606
607 if( aFlags & ENVVARS_CHANGED )
608 {
609 if( KIFACE* sch = KiFACE( FACE_SCH, false ) )
610 sch->PreloadLibraries( this );
611
612 if( KIFACE* pcb = KiFACE( FACE_PCB, false ) )
613 pcb->PreloadLibraries( this );
614 }
615
616 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
617 {
618 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
619
620 if( frame )
621 frame->CommonSettingsChanged( aFlags );
622 }
623}
624
625
627{
629 {
630 // A dynamic_cast could be better, but creates link issues
631 // (some basic_frame functions not found) on some platforms,
632 // so a static_cast is used.
633 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
634
635 if( top )
636 top->ClearFileHistory();
637 }
638
639 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
640 {
641 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
642
643 if( frame )
644 frame->ClearFileHistory();
645 }
646}
647
648
650{
651 // Skip project change notifications during application shutdown to avoid
652 // clearing savers and re-registering them unnecessarily
653 if( PgmOrNull() && Pgm().m_Quitting )
654 return;
655
656 APP_MONITOR::AddNavigationBreadcrumb( "Changing project", "kiway.projectchanged" );
657
659
661 {
662 // A dynamic_cast could be better, but creates link issues
663 // (some basic_frame functions not found) on some platforms,
664 // so a static_cast is used.
665 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
666
667 if( top )
668 top->ProjectChanged();
669 }
670
671 // Cancel an in-progress load of libraries; handled through the schematic and PCB ifaces
672 if ( KIFACE* schface = KiFACE( KIWAY::FACE_SCH ) )
673 schface->ProjectChanged();
674
675 if ( KIFACE* pcbface = KiFACE( KIWAY::FACE_PCB ) )
676 pcbface->ProjectChanged();
677
678 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
679 {
680 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
681
682 if( frame )
683 frame->ProjectChanged();
684 }
685}
686
687
689{
690 return wxWindow::FindWindowById( m_blockingDialog );
691}
692
693
694void KIWAY::SetBlockingDialog( wxWindow* aWin )
695{
696 if( !aWin )
697 m_blockingDialog = wxID_NONE;
698 else
699 m_blockingDialog = aWin->GetId();
700}
701
702
703bool KIWAY::ProcessEvent( wxEvent& aEvent )
704{
705 KIWAY_MAIL_EVENT* mail = dynamic_cast<KIWAY_MAIL_EVENT*>( &aEvent );
706
707 if( mail )
708 {
709 FRAME_T dest = mail->Dest();
710
711 // see if recipient is alive
712 KIWAY_PLAYER* alive = Player( dest, false );
713
714 if( alive )
715 {
716#if 1
717 return alive->ProcessEvent( aEvent );
718#else
719 alive->KiwayMailIn( *mail );
720 return true;
721#endif
722 }
723 }
724
725 return false;
726}
727
728
729void KIWAY::QueueEvent( wxEvent* aEvent )
730{
731 KIWAY_MAIL_EVENT* mail = dynamic_cast<KIWAY_MAIL_EVENT*>( aEvent );
732
733 if( mail )
734 {
735 FRAME_T dest = mail->Dest();
736
737 // see if recipient is alive
738 KIWAY_PLAYER* alive = Player( dest, false );
739
740 if( alive )
741 {
742 alive->GetEventHandler()->QueueEvent( aEvent );
743 }
744 }
745}
746
747
748int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job, REPORTER* aReporter, PROGRESS_REPORTER* aProgressReporter )
749{
750 KIFACE* kiface = KiFACE( aFace );
751
752 return kiface->HandleJob( job, aReporter, aProgressReporter );
753}
754
755
756bool KIWAY::ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow )
757{
758 KIFACE* kiface = KiFACE( aFace );
759
760 return kiface->HandleJobConfig( aJob, aWindow );
761}
762
763
764bool KIWAY::ProcessApiOpenDocument( KIWAY::FACE_T aFace, const wxString& aPath, KICAD_API_SERVER* aServer,
765 wxString* aError )
766{
767 KIFACE* kiface = KiFACE( aFace );
768
769 if( !kiface )
770 {
771 if( aError )
772 *aError = wxS( "Failed to load requested face" );
773
774 return false;
775 }
776
777 return kiface->HandleApiOpenDocument( aPath, aServer, aError );
778}
779
780
781bool KIWAY::ProcessApiCloseDocument( KIWAY::FACE_T aFace, const wxString& aPath, KICAD_API_SERVER* aServer,
782 wxString* aError )
783{
784 KIFACE* kiface = KiFACE( aFace );
785
786 if( !kiface )
787 {
788 if( aError )
789 *aError = wxS( "Failed to load requested face" );
790
791 return false;
792 }
793
794 return kiface->HandleApiCloseDocument( aPath, aServer, aError );
795}
796
797
799{
801 {
802 // A dynamic_cast could be better, but creates link issues
803 // (some basic_frame functions not found) on some platforms,
804 // so a static_cast is used.
805 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
806
807 if( top )
808 top->Close( false );
809 }
810}
811
812
814{
815 for( KIFACE* i : m_kiface )
816 {
817 if( i )
818 i->OnKifaceEnd();
819 }
820}
const char * name
static std::list< TOOL_ACTION * > & GetActionList()
Return list of TOOL_ACTIONs.
The base frame for deriving all KiCad main window classes.
bool NonUserClose(bool aForce)
virtual void ProjectChanged()
Notification event that the project has changed.
void CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
virtual void ClearFileHistory()
Remove all files from the file history.
An simple container class that lets us dispatch output jobs to kifaces.
Definition job.h:184
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:38
FRAME_T Dest()
Return the destination player id of the message.
Definition kiway_mail.h:43
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual void KiwayMailIn(KIWAY_MAIL_EVENT &aEvent)
Receive #KIWAY_ROUTED_EVENT messages from other players.
void OnKiCadExit()
Definition kiway.cpp:798
bool ProcessJobConfigDialog(KIWAY::FACE_T aFace, JOB *aJob, wxWindow *aWindow)
Definition kiway.cpp:756
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
const wxString dso_search_path(FACE_T aFaceId)
Get the [path &] name of the DSO holding the requested FACE_T.
Definition kiway.cpp:114
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob, REPORTER *aReporter=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Definition kiway.cpp:748
void SetBlockingDialog(wxWindow *aWin)
Definition kiway.cpp:694
LOCAL_HISTORY * m_local_history
Definition kiway.h:534
virtual bool PlayerClose(FRAME_T aFrameType, bool doForce)
Call the KIWAY_PLAYER::Close( bool force ) function on the window and if not vetoed,...
Definition kiway.cpp:455
static FACE_T KifaceType(FRAME_T aFrameType)
A simple mapping function which returns the FACE_T which is known to implement aFrameType.
Definition kiway.cpp:343
wxWindowID m_blockingDialog
Definition kiway.h:524
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
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition kiway.cpp:688
static std::array< KIFACE *, KIWAY_FACE_COUNT > m_kiface
Definition kiway.h:517
void ClearFileHistory()
Clear the wxWidgets file history on each open frame.
Definition kiway.cpp:626
bool ProcessApiCloseDocument(KIWAY::FACE_T aFace, const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError=nullptr)
Definition kiway.cpp:781
wxFrame * m_top
Definition kiway.h:522
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition kiway.cpp:520
bool ProcessApiOpenDocument(KIWAY::FACE_T aFace, const wxString &aPath, KICAD_API_SERVER *aServer, wxString *aError=nullptr)
Definition kiway.cpp:764
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition kiway.cpp:211
FACE_T
Known KIFACE implementations.
Definition kiway.h:321
@ FACE_SCH
eeschema DSO
Definition kiway.h:322
@ FACE_PL_EDITOR
Definition kiway.h:326
@ FACE_PCB
pcbnew DSO
Definition kiway.h:323
@ FACE_CVPCB
Definition kiway.h:324
@ FACE_GERBVIEW
Definition kiway.h:325
@ FACE_BMP2CMP
Definition kiway.h:328
@ FACE_PCB_CALCULATOR
Definition kiway.h:327
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition kiway.cpp:384
bool ProcessEvent(wxEvent &aEvent) override
Definition kiway.cpp:703
static std::array< int, KIWAY_FACE_COUNT > m_kiface_version
Definition kiway.h:518
virtual bool PlayersClose(bool doForce)
Call the KIWAY_PLAYER::Close( bool force ) function on all the windows and if none are vetoed,...
Definition kiway.cpp:483
std::atomic< wxWindowID > m_playerFrameId[KIWAY_PLAYER_COUNT]
Definition kiway.h:532
void OnKiwayEnd()
Definition kiway.cpp:813
KIWAY(int aCtlBits, wxFrame *aTop=nullptr)
Definition kiway.cpp:54
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:426
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:594
~KIWAY()
Definition kiway.cpp:71
void QueueEvent(wxEvent *aEvent) override
Definition kiway.cpp:729
void PlayerDidClose(FRAME_T aFrameType)
Notifies a Kiway that a player has been closed.
Definition kiway.cpp:494
virtual void GetActions(std::vector< TOOL_ACTION * > &aActions) const
Append all registered actions to the given list.
Definition kiway.cpp:513
void SetTop(wxFrame *aTop)
Tell this KIWAY about the top most frame in the program and optionally allows it to play the role of ...
Definition kiway.cpp:92
virtual void ProjectChanged()
Calls ProjectChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:649
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:205
int m_ctl
Definition kiway.h:520
Simple local history manager built on libgit2.
void ClearAllSavers()
Clear all registered savers.
void HandleException(std::exception_ptr aPtr, bool aUnhandled=false)
A exception handler to be used at the top level if exceptions bubble up that for.
Definition pgm_base.cpp:802
virtual void SetLanguageIdentifier(int menu_id)
Set in .m_language_id member the wxWidgets language identifier ID from the KiCad menu id (internal me...
Definition pgm_base.cpp:689
virtual const wxString & GetExecutablePath() const
Definition pgm_base.cpp:867
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:130
virtual bool SetLanguage(wxString &aErrMsg, bool first_time=false)
Set the dictionary file name for internationalization.
Definition pgm_base.cpp:547
A progress reporter interface for use in multi-threaded environments.
Container for project specific data.
Definition project.h:66
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
Represent a single user action.
A logger class that filters out all log messages that are not generated by wxLogTrace and ignores the...
Definition logging.h:32
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
This file is part of the common library.
#define _(s)
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:33
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_CALC
Definition frame_type.h:63
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:35
@ FRAME_CVPCB_DISPLAY
Definition frame_type.h:53
@ FRAME_FOOTPRINT_VIEWER
Definition frame_type.h:45
@ FRAME_BM2CMP
Definition frame_type.h:61
@ FRAME_FOOTPRINT_WIZARD
Definition frame_type.h:46
@ FRAME_SCH_VIEWER
Definition frame_type.h:36
@ FRAME_SCH
Definition frame_type.h:34
@ FRAME_SIMULATOR
Definition frame_type.h:38
@ KIWAY_PLAYER_COUNT
Definition frame_type.h:65
@ FRAME_FOOTPRINT_CHOOSER
Definition frame_type.h:44
@ FRAME_PL_EDITOR
Definition frame_type.h:59
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
@ FRAME_GERBER
Definition frame_type.h:57
@ FRAME_PCB_DISPLAY3D
Definition frame_type.h:47
@ FRAME_CVPCB
Definition frame_type.h:52
@ FRAME_SYMBOL_CHOOSER
Definition frame_type.h:37
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition kiway.h:164
KIFACE * KIFACE_GETTER_FUNC(int *aKIFACEversion, int aKIWAYversion, PGM_BASE *aProgram)
Point to the one and only KIFACE export.
Definition kiway.h:553
#define KIFACE_INSTANCE_NAME_AND_VERSION
Definition kiway.h:117
#define KIFACE_VERSION
Definition kiway.h:112
#define KFCTL_STANDALONE
Running as a standalone Top.
Definition kiway.h:163
This file contains miscellaneous commonly used macros and functions.
MAIL_T
The set of mail types sendable via KIWAY::ExpressMail() and supplied as the aCommand parameter to tha...
Definition mail_type.h:38
void AddNavigationBreadcrumb(const wxString &aMsg, const wxString &aCategory)
Add a navigation breadcrumb.
void AddDynamicLibrarySearchPath(const wxString &aPath)
Inserts a search path for loading dynamic libraries.
Definition unix/app.cpp:112
bool VerifyFileSignature(const wxString &aPath)
Validates the code signing signature of a given file This is most likely only ever going to be applic...
PGM_BASE & Pgm()
The global program "get" accessor.
PGM_BASE * PgmOrNull()
Return a reference that can be nullptr when running a shared lib from a script, not from a kicad app.
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition pgm_base.cpp:94
see class PGM_BASE
Implement a participant in the KIWAY alchemy.
Definition kiway.h:156
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)
std::string path
KIBIS top(path, &reporter)
#define ENVVARS_CHANGED