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 case FACE_PYTHON: name = KIFACE_PREFIX "kipython"; break;
128
129 default:
130 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
131 return wxEmptyString;
132 }
133
134#ifndef __WXMAC__
135 wxString path;
136
138 {
139 // The 2 *.cpp program launchers: single_top.cpp and kicad.cpp expect
140 // the *.kiface's to reside in same directory as their binaries do.
141 wxString appDir;
142
143 // When running inside an AppImage, the bundled ld-linux is invoked as a wrapper
144 // which causes /proc/self/exe to resolve to the dynamic linker rather than the
145 // actual binary. Use APPDIR to construct the correct executable path.
146 if( wxGetEnv( wxT( "APPDIR" ), &appDir ) )
147 path = appDir + wxT( "/usr/bin/kicad" );
148 else
149 path = wxStandardPaths::Get().GetExecutablePath();
150 }
151
152 wxFileName fn = path;
153#else
154 // we have the dso's in main OSX bundle kicad.app/Contents/PlugIns
155 wxFileName fn = Pgm().GetExecutablePath();
156 fn.AppendDir( wxT( "Contents" ) );
157 fn.AppendDir( wxT( "PlugIns" ) );
158#endif
159
160 fn.SetName( name );
161
162 // To speed up development, it's sometimes nice to run kicad from inside
163 // the build path. In that case, each program will be in a subdirectory.
164 // To find the DSOs, we need to go up one directory and then enter a subdirectory.
165 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
166 {
167#ifdef __WXMAC__
168 // On Mac, all of the kifaces are placed in the kicad.app bundle, even though the individual
169 // standalone binaries are placed in separate bundles before the make install step runs.
170 // So, we have to jump up to the kicad directory, then the PlugIns section of the kicad
171 // bundle.
172 fn = wxStandardPaths::Get().GetExecutablePath();
173
174 fn.RemoveLastDir();
175 fn.RemoveLastDir();
176 fn.RemoveLastDir();
177 fn.RemoveLastDir();
178 fn.AppendDir( wxT( "kicad" ) );
179 fn.AppendDir( wxT( "kicad.app" ) );
180 fn.AppendDir( wxT( "Contents" ) );
181 fn.AppendDir( wxT( "PlugIns" ) );
182 fn.SetName( name );
183#else
184 const char* dirName;
185
186 // The subdirectories usually have the same name as the kiface
187 switch( aFaceId )
188 {
189 case FACE_PL_EDITOR: dirName = "pagelayout_editor"; break;
190 case FACE_PYTHON: dirName = "scripting"; break;
191 default: dirName = name + 1; break;
192 }
193
194 fn.RemoveLastDir();
195 fn.AppendDir( dirName );
196#endif
197 }
198
199 // Here a "suffix" == an extension with a preceding '.',
200 // so skip the preceding '.' to get an extension
201 fn.SetExt( &KIFACE_SUFFIX[1] );
202
203 return fn.GetFullPath();
204}
205
206
208{
209 return Pgm().GetSettingsManager().Prj();
210}
211
212
213KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
214{
215 // Since this will be called from python, cannot assume that code will
216 // not pass a bad aFaceId.
217 if( (unsigned) aFaceId >= m_kiface.size() )
218 {
219 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
220 return nullptr;
221 }
222
223 // return the previously loaded KIFACE, if it was.
224 if( m_kiface[aFaceId] )
225 return m_kiface[aFaceId];
226
227 // DSO with KIFACE has not been loaded yet, does caller want to load it?
228 if( doLoad )
229 {
230 wxString dname = dso_search_path( aFaceId );
231
232 // Insert DLL search path for kicad_3dsg from build dir
233 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
234 {
235 wxFileName myPath = wxStandardPaths::Get().GetExecutablePath();
236
237 if( !myPath.GetPath().EndsWith( wxT( "pcbnew" ) ) )
238 {
239 myPath.RemoveLastDir();
240 myPath.AppendDir( wxT( "pcbnew" ) );
242 }
243 }
244
245 wxString msg;
246
247#ifdef KICAD_WIN32_VERIFY_CODESIGN
248 bool codeSignOk = KIPLATFORM::ENV::VerifyFileSignature( dname );
249 if( !codeSignOk )
250 {
251 msg.Printf( _( "Failed to verify kiface library '%s' signature." ), dname );
252 THROW_IO_ERROR( msg );
253 }
254#endif
255
256 wxDynamicLibrary dso;
257
258 void* addr = nullptr;
259
260 // For some reason wxDynamicLibrary::Load() crashes in some languages
261 // (chinese for instance) when loading the dynamic library.
262 // The crash happens for Eeschema.
263 // So switch to "C" locale during loading (LC_COLLATE is enough).
264 int lc_new_type = LC_COLLATE;
265 std::string user_locale = setlocale( lc_new_type, nullptr );
266 setlocale( lc_new_type, "C" );
267
268 bool success = dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL );
269
270 setlocale( lc_new_type, user_locale.c_str() );
271
272 msg = wxString::Format( "Loading kiface %d", aFaceId );
273 APP_MONITOR::AddNavigationBreadcrumb( msg, "kiway.kiface" );
274
275 if( !success )
276 {
277 // Failure: error reporting UI was done via wxLogSysError().
278 // No further reporting required here. Apparently this is not true on all
279 // platforms and/or wxWidgets builds and KiCad will crash. Throwing the exception
280 // here and catching it in the KiCad launcher resolves the crash issue. See bug
281 // report https://bugs.launchpad.net/kicad/+bug/1577786.
282
283 msg.Printf( _( "Failed to load kiface library '%s'." ), dname );
284 THROW_IO_ERROR( msg );
285 }
286 else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == nullptr )
287 {
288 // Failure: error reporting UI was done via wxLogSysError().
289 // No further reporting required here. Assume the same thing applies here as
290 // above with the Load() call. This has not been tested.
291 msg.Printf( _( "Could not read instance name and version from kiface library '%s'." ),
292 dname );
293 THROW_IO_ERROR( msg );
294 }
295 else
296 {
297 KIFACE_GETTER_FUNC* ki_getter = (KIFACE_GETTER_FUNC*) addr;
298
299 KIFACE* kiface = ki_getter( &m_kiface_version[aFaceId], KIFACE_VERSION, &Pgm() );
300
301 // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
302 wxASSERT_MSG( kiface,
303 wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
304
305 wxDllType dsoHandle = dso.Detach();
306
307 bool startSuccess = false;
308
309 // Give the DSO a single chance to do its "process level" initialization.
310 // "Process level" specifically means stay away from any projects in there.
311
312 try
313 {
314 startSuccess = kiface->OnKifaceStart( &Pgm(), m_ctl, this );
315 }
316 catch (...)
317 {
318 // OnKiFaceStart may generate an exception
319 // Before we continue and ultimately unload our module to retry we need
320 // to process the exception before we delete the free the memory space the
321 // exception resides in
322 Pgm().HandleException( std::current_exception() );
323 }
324
325 if( startSuccess )
326 {
327 return m_kiface[aFaceId] = kiface;
328 }
329 else
330 {
331 // Usually means canceled initial global library setup
332 // But it could have been an exception/failure
333 // Let the module go out of scope to unload
334 dso.Attach( dsoHandle );
335
336 return nullptr;
337 }
338 }
339 }
340
341 return nullptr;
342}
343
344
346{
347 switch( aFrameType )
348 {
349 case FRAME_SCH:
351 case FRAME_SCH_VIEWER:
353 case FRAME_SIMULATOR:
354 return FACE_SCH;
355
356 case FRAME_PCB_EDITOR:
362 return FACE_PCB;
363
364 case FRAME_CVPCB:
366 return FACE_CVPCB;
367
368 case FRAME_PYTHON:
369 return FACE_PYTHON;
370
371 case FRAME_GERBER:
372 return FACE_GERBVIEW;
373
374 case FRAME_PL_EDITOR:
375 return FACE_PL_EDITOR;
376
377 case FRAME_CALC:
378 return FACE_PCB_CALCULATOR;
379
380 case FRAME_BM2CMP:
381 return FACE_BMP2CMP;
382
383 default:
384 return FACE_T( -1 );
385 }
386}
387
388
390{
391 wxWindowID storedId = m_playerFrameId[aFrameType];
392
393 if( storedId == wxID_NONE )
394 return nullptr;
395
396 wxWindow* frame = wxWindow::FindWindowById( storedId );
397
398 // Since wxWindow::FindWindow*() is not cheap (especially if the window does not exist),
399 // clear invalid entries to save CPU on repeated calls that do not lead to frame creation
400 if( !frame )
401 m_playerFrameId[aFrameType].compare_exchange_strong( storedId, wxID_NONE );
402
403 return static_cast<KIWAY_PLAYER*>( frame );
404}
405
406
407KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow* aParent )
408{
409 // Since this will be called from python, cannot assume that code will
410 // not pass a bad aFrameType.
411 if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
412 {
413 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
414 return nullptr;
415 }
416
417 // return the previously opened window
418 KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
419
420 if( frame )
421 return frame;
422
423 if( doCreate )
424 {
425 try
426 {
427 wxString msg = wxString::Format( "Creating window type %d", aFrameType );
428 APP_MONITOR::AddNavigationBreadcrumb( msg, "kiway.player" );
429
430 FACE_T face_type = KifaceType( aFrameType );
431 KIFACE* kiface = KiFACE( face_type );
432
433 if( !kiface )
434 return nullptr;
435
436 frame = (KIWAY_PLAYER*) kiface->CreateKiWindow(
437 aParent, // Parent window of frame in modal mode,
438 // NULL in non modal mode
439 aFrameType,
440 this,
441 m_ctl // questionable need, these same flags
442 // were passed to KIFACE::OnKifaceStart()
443 );
444 if( frame )
445 m_playerFrameId[aFrameType].store( frame->GetId() );
446
447 return frame;
448 }
449 catch( ... )
450 {
451 Pgm().HandleException( std::current_exception() );
452 wxLogError( _( "Error loading editor." ) );
453 }
454 }
455
456 return nullptr;
457}
458
459
460bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
461{
462 // Since this will be called from python, cannot assume that code will
463 // not pass a bad aFrameType.
464 if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
465 {
466 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
467 return false;
468 }
469
470 KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
471
472 if( frame == nullptr ) // Already closed
473 return true;
474
475 wxString msg = wxString::Format( "Closing window type %d", aFrameType );
476 APP_MONITOR::AddNavigationBreadcrumb( msg, "kiway.playerclose" );
477
478 if( frame->NonUserClose( doForce ) )
479 {
480 m_playerFrameId[aFrameType] = wxID_NONE;
481 return true;
482 }
483
484 return false;
485}
486
487
488bool KIWAY::PlayersClose( bool doForce )
489{
490 bool ret = true;
491
492 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
493 ret = ret && PlayerClose( FRAME_T( i ), doForce );
494
495 return ret;
496}
497
498
500{
501 m_playerFrameId[aFrameType] = wxID_NONE;
502}
503
504
505void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
506 wxWindow* aSource, bool aFromOtherThread )
507{
508 std::unique_ptr<KIWAY_MAIL_EVENT> mail =
509 std::make_unique<KIWAY_MAIL_EVENT>( aDestination, aCommand, aPayload, aSource );
510
511 if( aFromOtherThread )
512 QueueEvent( mail.release() );
513 else
514 ProcessEvent( *mail );
515}
516
517
518void KIWAY::GetActions( std::vector<TOOL_ACTION*>& aActions ) const
519{
521 aActions.push_back( action );
522}
523
524
525void KIWAY::SetLanguage( int aLanguage )
526{
527 wxString errMsg;
528 bool ret = false;
529
530 {
531 // Only allow the traces to be logged by wx. We use our own system to log when the
532 // OS doesn't support the language, so we want to hide the wx error.
533 WX_LOG_TRACE_ONLY logtraceOnly;
534 Pgm().SetLanguageIdentifier( aLanguage );
535 ret = Pgm().SetLanguage( errMsg );
536 }
537
538 if( !ret )
539 {
540 wxString lang;
541
542 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
543 {
544 if( aLanguage == LanguagesList[ii].m_KI_Lang_Identifier )
545 {
546 if( LanguagesList[ii].m_DoNotTranslate )
547 lang = LanguagesList[ii].m_Lang_Label;
548 else
549 lang = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
550
551 break;
552 }
553 }
554
555 DisplayErrorMessage( nullptr,
556 wxString::Format( _( "Unable to switch language to %s" ), lang ),
557 errMsg );
558 return;
559 }
560
561#if 1
562 // This is a risky hack that goes away if we allow the language to be
563 // set only from the top most frame if !Kiface.IsSingle()
564
565 // Only for the C++ project manager, and not for the python one and not for
566 // single_top do we look for the EDA_BASE_FRAME as the top level window.
567 // For single_top this is not needed because that window is registered in
568 // the array below.
570 {
571 // A dynamic_cast could be better, but creates link issues
572 // (some basic_frame functions not found) on some platforms,
573 // so a static_cast is used.
574 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
575
576 if ( top )
577 {
578 top->ShowChangedLanguage();
579 wxCommandEvent e( EDA_LANG_CHANGED );
580 top->GetEventHandler()->ProcessEvent( e );
581 }
582 }
583#endif
584
585 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
586 {
587 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
588
589 if( frame )
590 {
591 frame->ShowChangedLanguage();
592 wxCommandEvent e( EDA_LANG_CHANGED );
593 frame->GetEventHandler()->ProcessEvent( e );
594 }
595 }
596}
597
598
600{
602 {
603 // A dynamic_cast could be better, but creates link issues
604 // (some basic_frame functions not found) on some platforms,
605 // so a static_cast is used.
606 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
607
608 if( top )
609 top->CommonSettingsChanged( aFlags );
610 }
611
612 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
613 {
614 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
615
616 if( frame )
617 frame->CommonSettingsChanged( aFlags );
618 }
619}
620
621
623{
625 {
626 // A dynamic_cast could be better, but creates link issues
627 // (some basic_frame functions not found) on some platforms,
628 // so a static_cast is used.
629 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
630
631 if( top )
632 top->ClearFileHistory();
633 }
634
635 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
636 {
637 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
638
639 if( frame )
640 frame->ClearFileHistory();
641 }
642}
643
644
646{
647 // Skip project change notifications during application shutdown to avoid
648 // clearing savers and re-registering them unnecessarily
649 if( PgmOrNull() && Pgm().m_Quitting )
650 return;
651
652 APP_MONITOR::AddNavigationBreadcrumb( "Changing project", "kiway.projectchanged" );
653
655
657 {
658 // A dynamic_cast could be better, but creates link issues
659 // (some basic_frame functions not found) on some platforms,
660 // so a static_cast is used.
661 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
662
663 if( top )
664 top->ProjectChanged();
665 }
666
667 // Cancel an in-progress load of libraries; handled through the schematic and PCB ifaces
668 if ( KIFACE* schface = KiFACE( KIWAY::FACE_SCH ) )
669 schface->ProjectChanged();
670
671 if ( KIFACE* pcbface = KiFACE( KIWAY::FACE_PCB ) )
672 pcbface->ProjectChanged();
673
674 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
675 {
676 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
677
678 if( frame )
679 frame->ProjectChanged();
680 }
681}
682
683
685{
686 return wxWindow::FindWindowById( m_blockingDialog );
687}
688
689
690void KIWAY::SetBlockingDialog( wxWindow* aWin )
691{
692 if( !aWin )
693 m_blockingDialog = wxID_NONE;
694 else
695 m_blockingDialog = aWin->GetId();
696}
697
698
699bool KIWAY::ProcessEvent( wxEvent& aEvent )
700{
701 KIWAY_MAIL_EVENT* mail = dynamic_cast<KIWAY_MAIL_EVENT*>( &aEvent );
702
703 if( mail )
704 {
705 FRAME_T dest = mail->Dest();
706
707 // see if recipient is alive
708 KIWAY_PLAYER* alive = Player( dest, false );
709
710 if( alive )
711 {
712#if 1
713 return alive->ProcessEvent( aEvent );
714#else
715 alive->KiwayMailIn( *mail );
716 return true;
717#endif
718 }
719 }
720
721 return false;
722}
723
724
725void KIWAY::QueueEvent( wxEvent* aEvent )
726{
727 KIWAY_MAIL_EVENT* mail = dynamic_cast<KIWAY_MAIL_EVENT*>( aEvent );
728
729 if( mail )
730 {
731 FRAME_T dest = mail->Dest();
732
733 // see if recipient is alive
734 KIWAY_PLAYER* alive = Player( dest, false );
735
736 if( alive )
737 {
738 alive->GetEventHandler()->QueueEvent( aEvent );
739 }
740 }
741}
742
743
744int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job, REPORTER* aReporter, PROGRESS_REPORTER* aProgressReporter )
745{
746 KIFACE* kiface = KiFACE( aFace );
747
748 return kiface->HandleJob( job, aReporter, aProgressReporter );
749}
750
751
752bool KIWAY::ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow )
753{
754 KIFACE* kiface = KiFACE( aFace );
755
756 return kiface->HandleJobConfig( aJob, aWindow );
757}
758
759
761{
763 {
764 // A dynamic_cast could be better, but creates link issues
765 // (some basic_frame functions not found) on some platforms,
766 // so a static_cast is used.
767 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
768
769 if( top )
770 top->Close( false );
771 }
772}
773
774
776{
777 for( KIFACE* i : m_kiface )
778 {
779 if( i )
780 i->OnKifaceEnd();
781 }
782}
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:760
bool ProcessJobConfigDialog(KIWAY::FACE_T aFace, JOB *aJob, wxWindow *aWindow)
Definition kiway.cpp:752
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:407
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:744
void SetBlockingDialog(wxWindow *aWin)
Definition kiway.cpp:690
LOCAL_HISTORY * m_local_history
Definition kiway.h:507
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:460
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:345
wxWindowID m_blockingDialog
Definition kiway.h:497
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:505
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition kiway.cpp:684
static std::array< KIFACE *, KIWAY_FACE_COUNT > m_kiface
Definition kiway.h:490
void ClearFileHistory()
Clear the wxWidgets file history on each open frame.
Definition kiway.cpp:622
wxFrame * m_top
Definition kiway.h:495
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition kiway.cpp:525
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition kiway.cpp:213
FACE_T
Known KIFACE implementations.
Definition kiway.h:301
@ FACE_SCH
eeschema DSO
Definition kiway.h:302
@ FACE_PL_EDITOR
Definition kiway.h:306
@ FACE_PYTHON
Definition kiway.h:309
@ FACE_PCB
pcbnew DSO
Definition kiway.h:303
@ FACE_CVPCB
Definition kiway.h:304
@ FACE_GERBVIEW
Definition kiway.h:305
@ FACE_BMP2CMP
Definition kiway.h:308
@ FACE_PCB_CALCULATOR
Definition kiway.h:307
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition kiway.cpp:389
bool ProcessEvent(wxEvent &aEvent) override
Definition kiway.cpp:699
static std::array< int, KIWAY_FACE_COUNT > m_kiface_version
Definition kiway.h:491
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:488
std::atomic< wxWindowID > m_playerFrameId[KIWAY_PLAYER_COUNT]
Definition kiway.h:505
void OnKiwayEnd()
Definition kiway.cpp:775
KIWAY(int aCtlBits, wxFrame *aTop=nullptr)
Definition kiway.cpp:54
LOCAL_HISTORY & LocalHistory()
Return the LOCAL_HISTORY associated with this KIWAY.
Definition kiway.h:407
virtual void CommonSettingsChanged(int aFlags=0)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition kiway.cpp:599
~KIWAY()
Definition kiway.cpp:71
void QueueEvent(wxEvent *aEvent) override
Definition kiway.cpp:725
void PlayerDidClose(FRAME_T aFrameType)
Notifies a Kiway that a player has been closed.
Definition kiway.cpp:499
virtual void GetActions(std::vector< TOOL_ACTION * > &aActions) const
Append all registered actions to the given list.
Definition kiway.cpp:518
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:645
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition kiway.cpp:207
int m_ctl
Definition kiway.h:493
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:131
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:65
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_PYTHON
Definition frame_type.h:55
@ 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:530
#define KIFACE_INSTANCE_NAME_AND_VERSION
Definition kiway.h:115
#define KIFACE_VERSION
The KIWAY and KIFACE classes are used to communicate between various process modules,...
Definition kiway.h:110
#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:100
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:95
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)