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 (C) 2014-2023 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 <core/ignore.h>
28#include <macros.h>
29#include <kiway.h>
30#include <kiway_player.h>
31#include <kiway_express.h>
32#include <pgm_base.h>
33#include <config.h>
34#include <core/arraydim.h>
35#include <id.h>
36#include <kiplatform/app.h>
39#include <tool/action_manager.h>
40#include <logging.h>
41
42#include <wx/dynlib.h>
43#include <wx/stdpaths.h>
44#include <wx/debug.h>
45#include <wx/utils.h>
46#include <confirm.h>
47
48#ifdef KICAD_USE_SENTRY
49#include <sentry.h>
50#endif
51
52KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT];
53int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
54
55
56
57KIWAY::KIWAY( int aCtlBits, wxFrame* aTop ):
58 m_ctl( aCtlBits ), m_top( nullptr ), m_blockingDialog( wxID_NONE )
59{
60 SetTop( aTop ); // hook player_destroy_handler() into aTop.
61
62 // Set the array of all known frame window IDs to empty = wxID_NONE,
63 // once they are be created, they are added with FRAME_T as index to this array.
64 // Note: A non empty entry does not mean the frame still exists.
65 // It means only the frame was created at least once. It can be destroyed after.
66 // These entries are not cleared automatically on window closing. The purpose is just
67 // to allow a call to wxWindow::FindWindowById() using a FRAME_T frame type
68 for( int n = 0; n < KIWAY_PLAYER_COUNT; n++ )
69 m_playerFrameId[n] = wxID_NONE;
70}
71
72
73#if 0
74// Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are
75// propagated upwards to parent windows if not handled below. Therefore the
76// m_top window should receive all wxWindowDestroyEvents originating from
77// KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops
78// on that event stream looking for KIWAY_PLAYERs being closed.
79
80void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event )
81{
82 // Currently : do nothing
83 event.Skip(); // skip to who, the wxApp? I'm the top window.
84}
85#endif
86
87
88void KIWAY::SetTop( wxFrame* aTop )
89{
90#if 0
91 if( m_top )
92 {
93 m_top->Disconnect( wxEVT_DESTROY,
94 wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ),
95 nullptr, this );
96 }
97
98 if( aTop )
99 {
100 aTop->Connect( wxEVT_DESTROY,
101 wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ),
102 nullptr, this );
103 }
104#endif
105
106 m_top = aTop;
107}
108
109
110const wxString KIWAY::dso_search_path( FACE_T aFaceId )
111{
112 const char* name;
113
114 switch( aFaceId )
115 {
116 case FACE_SCH: name = KIFACE_PREFIX "eeschema"; break;
117 case FACE_PCB: name = KIFACE_PREFIX "pcbnew"; break;
118 case FACE_CVPCB: name = KIFACE_PREFIX "cvpcb"; break;
119 case FACE_GERBVIEW: name = KIFACE_PREFIX "gerbview"; break;
120 case FACE_PL_EDITOR: name = KIFACE_PREFIX "pl_editor"; break;
121 case FACE_PCB_CALCULATOR: name = KIFACE_PREFIX "pcb_calculator"; break;
122 case FACE_BMP2CMP: name = KIFACE_PREFIX "bitmap2component"; break;
123 case FACE_PYTHON: name = KIFACE_PREFIX "kipython"; break;
124
125 default:
126 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
127 return wxEmptyString;
128 }
129
130#ifndef __WXMAC__
131 wxString path;
132
134 {
135 // The 2 *.cpp program launchers: single_top.cpp and kicad.cpp expect
136 // the *.kiface's to reside in same directory as their binaries do.
137 path = wxStandardPaths::Get().GetExecutablePath();
138 }
139
140 wxFileName fn = path;
141#else
142 // we have the dso's in main OSX bundle kicad.app/Contents/PlugIns
143 wxFileName fn = Pgm().GetExecutablePath();
144 fn.AppendDir( wxT( "Contents" ) );
145 fn.AppendDir( wxT( "PlugIns" ) );
146#endif
147
148 fn.SetName( name );
149
150 // To speed up development, it's sometimes nice to run kicad from inside
151 // the build path. In that case, each program will be in a subdirectory.
152 // To find the DSOs, we need to go up one directory and then enter a subdirectory.
153
154 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
155 {
156#ifdef __WXMAC__
157 // On Mac, all of the kifaces are placed in the kicad.app bundle, even though the individual
158 // standalone binaries are placed in separate bundles before the make install step runs.
159 // So, we have to jump up to the kicad directory, then the PlugIns section of the kicad
160 // bundle.
161 fn = wxStandardPaths::Get().GetExecutablePath();
162
163 fn.RemoveLastDir();
164 fn.RemoveLastDir();
165 fn.RemoveLastDir();
166 fn.RemoveLastDir();
167 fn.AppendDir( wxT( "kicad" ) );
168 fn.AppendDir( wxT( "kicad.app" ) );
169 fn.AppendDir( wxT( "Contents" ) );
170 fn.AppendDir( wxT( "PlugIns" ) );
171 fn.SetName( name );
172#else
173 const char* dirName;
174
175 // The subdirectories usually have the same name as the kiface
176 switch( aFaceId )
177 {
178 case FACE_PL_EDITOR: dirName = "pagelayout_editor"; break;
179 case FACE_PYTHON: dirName = "scripting"; break;
180 default: dirName = name + 1; break;
181 }
182
183 fn.RemoveLastDir();
184 fn.AppendDir( dirName );
185#endif
186 }
187
188 // Here a "suffix" == an extension with a preceding '.',
189 // so skip the preceding '.' to get an extension
190 fn.SetExt( &KIFACE_SUFFIX[1] );
191
192 return fn.GetFullPath();
193}
194
195
197{
198 return Pgm().GetSettingsManager().Prj();
199}
200
201
202KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
203{
204 // Since this will be called from python, cannot assume that code will
205 // not pass a bad aFaceId.
206 if( (unsigned) aFaceId >= arrayDim( m_kiface ) )
207 {
208 // @todo : throw an exception here for python's benefit, at least that
209 // way it gets some explanatory text.
210
211 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
212 return nullptr;
213 }
214
215 // return the previously loaded KIFACE, if it was.
216 if( m_kiface[aFaceId] )
217 return m_kiface[aFaceId];
218
219 // DSO with KIFACE has not been loaded yet, does caller want to load it?
220 if( doLoad )
221 {
222 wxString dname = dso_search_path( aFaceId );
223
224 // Insert DLL search path for kicad_3dsg from build dir
225 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
226 {
227 wxFileName myPath = wxStandardPaths::Get().GetExecutablePath();
228
229 if( !myPath.GetPath().EndsWith( wxT( "pcbnew" ) ) )
230 {
231 myPath.RemoveLastDir();
232 myPath.AppendDir( wxT( "pcbnew" ) );
234 }
235 }
236
237 wxString msg;
238
239#ifdef KICAD_WIN32_VERIFY_CODESIGN
240 bool codeSignOk = KIPLATFORM::ENV::VerifyFileSignature( dname );
241 if( !codeSignOk )
242 {
243 msg.Printf( _( "Failed to verify kiface library '%s' signature." ), dname );
244 THROW_IO_ERROR( msg );
245 }
246#endif
247
248 wxDynamicLibrary dso;
249
250 void* addr = nullptr;
251
252 // For some reason wxDynamicLibrary::Load() crashes in some languages
253 // (chinese for instance) when loading the dynamic library.
254 // The crash happens for Eeschema.
255 // So switch to "C" locale during loading (LC_COLLATE is enough).
256 int lc_new_type = LC_COLLATE;
257 std::string user_locale = setlocale( lc_new_type, nullptr );
258 setlocale( lc_new_type, "C" );
259
260 bool success = dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL );
261
262 setlocale( lc_new_type, user_locale.c_str() );
263
264#ifdef KICAD_USE_SENTRY
265 if( Pgm().IsSentryOptedIn() )
266 {
267 msg = wxString::Format( "Loading kiface %d", aFaceId );
268 sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
269 sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.kiface" ) );
270 sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
271 sentry_add_breadcrumb( crumb );
272 }
273#endif
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 exception resides in
321 Pgm().HandleException( std::current_exception() );
322 }
323
324 if( startSuccess )
325 {
326 return m_kiface[aFaceId] = kiface;
327 }
328 else
329 {
330 // Usually means cancelled initial global library setup
331 // But it could have been an exception/failure
332 // Let the module go out of scope to unload
333 dso.Attach( dsoHandle );
334
335 return nullptr;
336 }
337 }
338 }
339
340 return nullptr;
341}
342
343
345{
346 switch( aFrameType )
347 {
348 case FRAME_SCH:
350 case FRAME_SCH_VIEWER:
352 case FRAME_SIMULATOR:
353 return FACE_SCH;
354
355 case FRAME_PCB_EDITOR:
361 return FACE_PCB;
362
363 case FRAME_CVPCB:
365 return FACE_CVPCB;
366
367 case FRAME_PYTHON:
368 return FACE_PYTHON;
369
370 case FRAME_GERBER:
371 return FACE_GERBVIEW;
372
373 case FRAME_PL_EDITOR:
374 return FACE_PL_EDITOR;
375
376 case FRAME_CALC:
377 return FACE_PCB_CALCULATOR;
378
379 case FRAME_BM2CMP:
380 return FACE_BMP2CMP;
381
382 default:
383 return FACE_T( -1 );
384 }
385}
386
387
389{
390 wxWindowID storedId = m_playerFrameId[aFrameType];
391
392 if( storedId == wxID_NONE )
393 return nullptr;
394
395 wxWindow* frame = wxWindow::FindWindowById( storedId );
396
397 // Since wxWindow::FindWindow*() is not cheap (especially if the window does not exist),
398 // clear invalid entries to save CPU on repeated calls that do not lead to frame creation
399 if( !frame )
400 m_playerFrameId[aFrameType].compare_exchange_strong( storedId, wxID_NONE );
401
402 return static_cast<KIWAY_PLAYER*>( frame );
403}
404
405
406KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow* aParent )
407{
408 // Since this will be called from python, cannot assume that code will
409 // not pass a bad aFrameType.
410 if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
411 {
412 // @todo : throw an exception here for python's benefit, at least that
413 // way it gets some explanatory text.
414
415 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
416 return nullptr;
417 }
418
419 // return the previously opened window
420 KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
421
422 if( frame )
423 return frame;
424
425 if( doCreate )
426 {
427 try
428 {
429#ifdef KICAD_USE_SENTRY
430 if( Pgm().IsSentryOptedIn() )
431 {
432 wxString msg = wxString::Format( "Creating window type %d", aFrameType );
433 sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
434 sentry_value_set_by_key( crumb, "category",
435 sentry_value_new_string( "kiway.player" ) );
436 sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
437 sentry_add_breadcrumb( crumb );
438 }
439#endif
440
441 FACE_T face_type = KifaceType( aFrameType );
442 KIFACE* kiface = KiFACE( face_type );
443
444 if( !kiface )
445 return nullptr;
446
448 aParent, // Parent window of frame in modal mode,
449 // NULL in non modal mode
450 aFrameType,
451 this,
452 m_ctl // questionable need, these same flags
453 // were passed to KIFACE::OnKifaceStart()
454 );
455
456 m_playerFrameId[aFrameType].store( frame->GetId() );
457 return frame;
458 }
459 catch( ... )
460 {
461 Pgm().HandleException( std::current_exception() );
462 wxLogError( _( "Error loading editor." ) );
463 }
464 }
465
466 return nullptr;
467}
468
469
470bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
471{
472 // Since this will be called from python, cannot assume that code will
473 // not pass a bad aFrameType.
474 if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
475 {
476 // @todo : throw an exception here for python's benefit, at least that
477 // way it gets some explanatory text.
478
479 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
480 return false;
481 }
482
483 KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
484
485 if( frame == nullptr ) // Already closed
486 return true;
487
488#ifdef KICAD_USE_SENTRY
489 if( Pgm().IsSentryOptedIn() )
490 {
491 wxString msg = wxString::Format( "Closing window type %d", aFrameType );
492 sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
493 sentry_value_set_by_key( crumb, "category",
494 sentry_value_new_string( "kiway.playerclose" ) );
495 sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
496 sentry_add_breadcrumb( crumb );
497 }
498#endif
499
500 if( frame->NonUserClose( doForce ) )
501 {
502 m_playerFrameId[aFrameType] = wxID_NONE;
503 return true;
504 }
505
506 return false;
507}
508
509
510bool KIWAY::PlayersClose( bool doForce )
511{
512 bool ret = true;
513
514 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
515 ret = ret && PlayerClose( FRAME_T( i ), doForce );
516
517 return ret;
518}
519
520
522{
523 m_playerFrameId[aFrameType] = wxID_NONE;
524}
525
526
527void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
528 wxWindow* aSource )
529{
530 KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource );
531
532 ProcessEvent( mail );
533}
534
535
536void KIWAY::GetActions( std::vector<TOOL_ACTION*>& aActions ) const
537{
539 aActions.push_back( action );
540}
541
542
543void KIWAY::SetLanguage( int aLanguage )
544{
545 wxString errMsg;
546 bool ret = false;
547
548 {
549 // Only allow the traces to be logged by wx. We use our own system to log when the
550 // OS doesn't support the language, so we want to hide the wx error.
551 WX_LOG_TRACE_ONLY logtraceOnly;
552 Pgm().SetLanguageIdentifier( aLanguage );
553 ret = Pgm().SetLanguage( errMsg );
554 }
555
556 if( !ret )
557 {
558 wxString lang;
559
560 for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
561 {
562 if( aLanguage == LanguagesList[ii].m_KI_Lang_Identifier )
563 {
564 if( LanguagesList[ii].m_DoNotTranslate )
565 lang = LanguagesList[ii].m_Lang_Label;
566 else
567 lang = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
568
569 break;
570 }
571 }
572
573 DisplayErrorMessage( nullptr,
574 wxString::Format( _( "Unable to switch language to %s" ), lang ),
575 errMsg );
576 return;
577 }
578
579#if 1
580 // This is a risky hack that goes away if we allow the language to be
581 // set only from the top most frame if !Kiface.IsSingle()
582
583 // Only for the C++ project manager, and not for the python one and not for
584 // single_top do we look for the EDA_BASE_FRAME as the top level window.
585 // For single_top this is not needed because that window is registered in
586 // the array below.
588 {
589 // A dynamic_cast could be better, but creates link issues
590 // (some basic_frame functions not found) on some platforms,
591 // so a static_cast is used.
592 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
593
594 if ( top )
595 {
596 top->ShowChangedLanguage();
597 wxCommandEvent e( EDA_LANG_CHANGED );
598 top->GetEventHandler()->ProcessEvent( e );
599 }
600 }
601#endif
602
603 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
604 {
605 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
606
607 if( frame )
608 {
609 frame->ShowChangedLanguage();
610 wxCommandEvent e( EDA_LANG_CHANGED );
611 frame->GetEventHandler()->ProcessEvent( e );
612 }
613 }
614}
615
616
617void KIWAY::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
618{
620 {
621 // A dynamic_cast could be better, but creates link issues
622 // (some basic_frame functions not found) on some platforms,
623 // so a static_cast is used.
624 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
625
626 if( top )
627 top->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
628 }
629
630 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
631 {
632 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
633
634 if( frame )
635 frame->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
636 }
637}
638
639
641{
642#ifdef KICAD_USE_SENTRY
643 sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", "Changing project" );
644 sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.projectchanged" ) );
645 sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
646 sentry_add_breadcrumb( crumb );
647#endif
648
650 {
651 // A dynamic_cast could be better, but creates link issues
652 // (some basic_frame functions not found) on some platforms,
653 // so a static_cast is used.
654 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
655
656 if( top )
657 top->ProjectChanged();
658 }
659
660 for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
661 {
662 KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
663
664 if( frame )
665 frame->ProjectChanged();
666 }
667}
668
670{
671 return wxWindow::FindWindowById( m_blockingDialog );
672}
673
674void KIWAY::SetBlockingDialog( wxWindow* aWin )
675{
676 if( !aWin )
677 m_blockingDialog = wxID_NONE;
678 else
679 m_blockingDialog = aWin->GetId();
680}
681
682
683bool KIWAY::ProcessEvent( wxEvent& aEvent )
684{
685 KIWAY_EXPRESS* mail = dynamic_cast<KIWAY_EXPRESS*>( &aEvent );
686
687 if( mail )
688 {
689 FRAME_T dest = mail->Dest();
690
691 // see if recipient is alive
692 KIWAY_PLAYER* alive = Player( dest, false );
693
694 if( alive )
695 {
696#if 1
697 return alive->ProcessEvent( aEvent );
698#else
699 alive->KiwayMailIn( *mail );
700 return true;
701#endif
702 }
703 }
704
705 return false;
706}
707
708
710{
711 KIFACE* kiface = KiFACE( aFace );
712
713 return kiface->HandleJob( job );
714}
715
716
717bool KIWAY::ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow )
718{
719 KIFACE* kiface = KiFACE( aFace );
720
721 return kiface->HandleJobConfig( aJob, aWindow );
722}
723
724
726{
728 {
729 // A dynamic_cast could be better, but creates link issues
730 // (some basic_frame functions not found) on some platforms,
731 // so a static_cast is used.
732 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
733
734 if( top )
735 top->Close( false );
736 }
737}
738
739
741{
742 for( KIFACE* i : m_kiface )
743 {
744 if( i )
745 i->OnKifaceEnd();
746 }
747}
const char * name
Definition: DXF_plotter.cpp:57
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
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 ShowChangedLanguage() override
Redraw the menus and what not in current language.
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
An simple container class that lets us dispatch output jobs to kifaces.
Definition: job.h:79
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:40
FRAME_T Dest()
Return the destination player id of the message.
Definition: kiway_express.h:45
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
virtual void KiwayMailIn(KIWAY_EXPRESS &aEvent)
Receive KIWAY_EXPRESS messages from other players.
void OnKiCadExit()
Definition: kiway.cpp:725
virtual void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition: kiway.cpp:617
bool ProcessJobConfigDialog(KIWAY::FACE_T aFace, JOB *aJob, wxWindow *aWindow)
Definition: kiway.cpp:717
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
const wxString dso_search_path(FACE_T aFaceId)
Get the [path &] name of the DSO holding the requested FACE_T.
Definition: kiway.cpp:110
void SetBlockingDialog(wxWindow *aWin)
Definition: kiway.cpp:674
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:470
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:344
wxWindowID m_blockingDialog
Definition: kiway.h:472
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition: kiway.cpp:669
static KIFACE * m_kiface[KIWAY_FACE_COUNT]
Definition: kiway.h:465
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob)
Definition: kiway.cpp:709
wxFrame * m_top
Definition: kiway.h:470
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition: kiway.cpp:543
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:202
FACE_T
Known KIFACE implementations.
Definition: kiway.h:290
@ FACE_SCH
eeschema DSO
Definition: kiway.h:291
@ FACE_PL_EDITOR
Definition: kiway.h:295
@ FACE_PYTHON
Definition: kiway.h:298
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:292
@ FACE_CVPCB
Definition: kiway.h:293
@ FACE_GERBVIEW
Definition: kiway.h:294
@ FACE_BMP2CMP
Definition: kiway.h:297
@ FACE_PCB_CALCULATOR
Definition: kiway.h:296
static int m_kiface_version[KIWAY_FACE_COUNT]
Definition: kiway.h:466
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition: kiway.cpp:388
bool ProcessEvent(wxEvent &aEvent) override
Definition: kiway.cpp:683
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:510
std::atomic< wxWindowID > m_playerFrameId[KIWAY_PLAYER_COUNT]
Definition: kiway.h:480
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:527
void OnKiwayEnd()
Definition: kiway.cpp:740
KIWAY(int aCtlBits, wxFrame *aTop=nullptr)
Definition: kiway.cpp:57
void PlayerDidClose(FRAME_T aFrameType)
Notifies a Kiway that a player has been closed.
Definition: kiway.cpp:521
virtual void GetActions(std::vector< TOOL_ACTION * > &aActions) const
Append all registered actions to the given list.
Definition: kiway.cpp:536
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:88
virtual void ProjectChanged()
Calls ProjectChanged() on all KIWAY_PLAYERs.
Definition: kiway.cpp:640
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:196
int m_ctl
Definition: kiway.h:468
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:827
void HandleException(std::exception_ptr aPtr)
A exception handler to be used at the top level if exceptions bubble up that for.
Definition: pgm_base.cpp:939
virtual const wxString & GetExecutablePath() const
Definition: pgm_base.cpp:1039
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
virtual bool SetLanguage(wxString &aErrMsg, bool first_time=false)
Set the dictionary file name for internationalization.
Definition: pgm_base.cpp:685
Container for project specific data.
Definition: project.h:64
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
Represent a single user action.
Definition: tool_action.h:269
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:195
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)
Definition: ki_exception.h:39
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition: kiway.h:159
KIFACE * KIFACE_GETTER_FUNC(int *aKIFACEversion, int aKIWAYversion, PGM_BASE *aProgram)
Point to the one and only KIFACE export.
Definition: kiway.h:503
#define KIFACE_INSTANCE_NAME_AND_VERSION
Definition: kiway.h:114
#define KIFACE_VERSION
The KIWAY and KIFACE classes are used to communicate between various process modules,...
Definition: kiway.h:109
#define KFCTL_STANDALONE
Running as a standalone Top.
Definition: kiway.h:158
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 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.
Definition: pgm_base.cpp:1060
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition: pgm_base.cpp:95
see class PGM_BASE
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway) override
Typically start_common() is called from here.
wxWindow * CreateKiWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Create a wxWindow for the current project.
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:151
virtual bool HandleJobConfig(JOB *aJob, wxWindow *aParent)
Definition: kiway.h:249
virtual int HandleJob(JOB *aJob)
Definition: kiway.h:244
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.h:73
wxString m_Lang_Label
Labels used in menus.
Definition: pgm_base.h:76
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)