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 <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 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
154 {
155#ifdef __WXMAC__
156 // On Mac, all of the kifaces are placed in the kicad.app bundle, even though the individual
157 // standalone binaries are placed in separate bundles before the make install step runs.
158 // So, we have to jump up to the kicad directory, then the PlugIns section of the kicad
159 // bundle.
160 fn = wxStandardPaths::Get().GetExecutablePath();
161
162 fn.RemoveLastDir();
163 fn.RemoveLastDir();
164 fn.RemoveLastDir();
165 fn.RemoveLastDir();
166 fn.AppendDir( wxT( "kicad" ) );
167 fn.AppendDir( wxT( "kicad.app" ) );
168 fn.AppendDir( wxT( "Contents" ) );
169 fn.AppendDir( wxT( "PlugIns" ) );
170 fn.SetName( name );
171#else
172 const char* dirName;
173
174 // The subdirectories usually have the same name as the kiface
175 switch( aFaceId )
176 {
177 case FACE_PL_EDITOR: dirName = "pagelayout_editor"; break;
178 case FACE_PYTHON: dirName = "scripting"; break;
179 default: dirName = name + 1; break;
180 }
181
182 fn.RemoveLastDir();
183 fn.AppendDir( dirName );
184#endif
185 }
186
187 // Here a "suffix" == an extension with a preceding '.',
188 // so skip the preceding '.' to get an extension
189 fn.SetExt( &KIFACE_SUFFIX[1] );
190
191 return fn.GetFullPath();
192}
193
194
196{
197 return Pgm().GetSettingsManager().Prj();
198}
199
200
201KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
202{
203 // Since this will be called from python, cannot assume that code will
204 // not pass a bad aFaceId.
205 if( (unsigned) aFaceId >= arrayDim( m_kiface ) )
206 {
207 // @todo : throw an exception here for python's benefit, at least that
208 // way it gets some explanatory text.
209
210 wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
211 return nullptr;
212 }
213
214 // return the previously loaded KIFACE, if it was.
215 if( m_kiface[aFaceId] )
216 return m_kiface[aFaceId];
217
218 // DSO with KIFACE has not been loaded yet, does caller want to load it?
219 if( doLoad )
220 {
221 wxString dname = dso_search_path( aFaceId );
222
223 // Insert DLL search path for kicad_3dsg from build dir
224 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
225 {
226 wxFileName myPath = wxStandardPaths::Get().GetExecutablePath();
227
228 if( !myPath.GetPath().EndsWith( wxT( "pcbnew" ) ) )
229 {
230 myPath.RemoveLastDir();
231 myPath.AppendDir( wxT( "pcbnew" ) );
233 }
234 }
235
236 wxString msg;
237
238#ifdef KICAD_WIN32_VERIFY_CODESIGN
239 bool codeSignOk = KIPLATFORM::ENV::VerifyFileSignature( dname );
240 if( !codeSignOk )
241 {
242 msg.Printf( _( "Failed to verify kiface library '%s' signature." ), dname );
243 THROW_IO_ERROR( msg );
244 }
245#endif
246
247 wxDynamicLibrary dso;
248
249 void* addr = nullptr;
250
251 // For some reason wxDynamicLibrary::Load() crashes in some languages
252 // (chinese for instance) when loading the dynamic library.
253 // The crash happens for Eeschema.
254 // So switch to "C" locale during loading (LC_COLLATE is enough).
255 int lc_new_type = LC_COLLATE;
256 std::string user_locale = setlocale( lc_new_type, nullptr );
257 setlocale( lc_new_type, "C" );
258
259 bool success = dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL );
260
261 setlocale( lc_new_type, user_locale.c_str() );
262
263#ifdef KICAD_USE_SENTRY
264 if( Pgm().IsSentryOptedIn() )
265 {
266 msg = wxString::Format( "Loading kiface %d", aFaceId );
267 sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
268 sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.kiface" ) );
269 sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
270 sentry_add_breadcrumb( crumb );
271 }
272#endif
273
274 if( !success )
275 {
276 // Failure: error reporting UI was done via wxLogSysError().
277 // No further reporting required here. Apparently this is not true on all
278 // platforms and/or wxWidgets builds and KiCad will crash. Throwing the exception
279 // here and catching it in the KiCad launcher resolves the crash issue. See bug
280 // report https://bugs.launchpad.net/kicad/+bug/1577786.
281
282 msg.Printf( _( "Failed to load kiface library '%s'." ), dname );
283 THROW_IO_ERROR( msg );
284 }
285 else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == nullptr )
286 {
287 // Failure: error reporting UI was done via wxLogSysError().
288 // No further reporting required here. Assume the same thing applies here as
289 // above with the Load() call. This has not been tested.
290 msg.Printf( _( "Could not read instance name and version from kiface library '%s'." ),
291 dname );
292 THROW_IO_ERROR( msg );
293 }
294 else
295 {
296 KIFACE_GETTER_FUNC* ki_getter = (KIFACE_GETTER_FUNC*) addr;
297
298 KIFACE* kiface = ki_getter( &m_kiface_version[aFaceId], KIFACE_VERSION, &Pgm() );
299
300 // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
301 wxASSERT_MSG( kiface,
302 wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
303
304 wxDllType dsoHandle = dso.Detach();
305
306 bool startSuccess = false;
307
308 // Give the DSO a single chance to do its "process level" initialization.
309 // "Process level" specifically means stay away from any projects in there.
310
311 try
312 {
313 startSuccess = kiface->OnKifaceStart( &Pgm(), m_ctl, this );
314 }
315 catch (...)
316 {
317 // OnKiFaceStart may generate an exception
318 // Before we continue and ultimately unload our module to retry we need
319 // to process the exception before we delete the free the memory space the
320 // 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 canceled 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
669
671{
672 return wxWindow::FindWindowById( m_blockingDialog );
673}
674
675
676void KIWAY::SetBlockingDialog( wxWindow* aWin )
677{
678 if( !aWin )
679 m_blockingDialog = wxID_NONE;
680 else
681 m_blockingDialog = aWin->GetId();
682}
683
684
685bool KIWAY::ProcessEvent( wxEvent& aEvent )
686{
687 KIWAY_EXPRESS* mail = dynamic_cast<KIWAY_EXPRESS*>( &aEvent );
688
689 if( mail )
690 {
691 FRAME_T dest = mail->Dest();
692
693 // see if recipient is alive
694 KIWAY_PLAYER* alive = Player( dest, false );
695
696 if( alive )
697 {
698#if 1
699 return alive->ProcessEvent( aEvent );
700#else
701 alive->KiwayMailIn( *mail );
702 return true;
703#endif
704 }
705 }
706
707 return false;
708}
709
710
711int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job, REPORTER* aReporter )
712{
713 KIFACE* kiface = KiFACE( aFace );
714
715 return kiface->HandleJob( job, aReporter );
716}
717
718
719bool KIWAY::ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow )
720{
721 KIFACE* kiface = KiFACE( aFace );
722
723 return kiface->HandleJobConfig( aJob, aWindow );
724}
725
726
728{
730 {
731 // A dynamic_cast could be better, but creates link issues
732 // (some basic_frame functions not found) on some platforms,
733 // so a static_cast is used.
734 EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
735
736 if( top )
737 top->Close( false );
738 }
739}
740
741
743{
744 for( KIFACE* i : m_kiface )
745 {
746 if( i )
747 i->OnKifaceEnd();
748 }
749}
const char * name
Definition: DXF_plotter.cpp:59
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:182
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:727
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:719
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:676
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:473
wxWindow * GetBlockingDialog()
Gets the window pointer to the blocking dialog (to send it signals)
Definition: kiway.cpp:670
static KIFACE * m_kiface[KIWAY_FACE_COUNT]
Definition: kiway.h:466
wxFrame * m_top
Definition: kiway.h:471
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:201
FACE_T
Known KIFACE implementations.
Definition: kiway.h:291
@ FACE_SCH
eeschema DSO
Definition: kiway.h:292
@ FACE_PL_EDITOR
Definition: kiway.h:296
@ FACE_PYTHON
Definition: kiway.h:299
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:293
@ FACE_CVPCB
Definition: kiway.h:294
@ FACE_GERBVIEW
Definition: kiway.h:295
@ FACE_BMP2CMP
Definition: kiway.h:298
@ FACE_PCB_CALCULATOR
Definition: kiway.h:297
static int m_kiface_version[KIWAY_FACE_COUNT]
Definition: kiway.h:467
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition: kiway.cpp:388
bool ProcessEvent(wxEvent &aEvent) override
Definition: kiway.cpp:685
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
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob, REPORTER *aReporter=nullptr)
Definition: kiway.cpp:711
std::atomic< wxWindowID > m_playerFrameId[KIWAY_PLAYER_COUNT]
Definition: kiway.h:481
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:742
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:195
int m_ctl
Definition: kiway.h:469
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:837
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:950
virtual const wxString & GetExecutablePath() const
Definition: pgm_base.cpp:1050
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:125
virtual bool SetLanguage(wxString &aErrMsg, bool first_time=false)
Set the dictionary file name for internationalization.
Definition: pgm_base.cpp:695
Container for project specific data.
Definition: project.h:64
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:72
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
Common command IDs shared by more than one of the KiCad applications.
#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:160
KIFACE * KIFACE_GETTER_FUNC(int *aKIFACEversion, int aKIWAYversion, PGM_BASE *aProgram)
Point to the one and only KIFACE export.
Definition: kiway.h:504
#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:159
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:1073
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:152
virtual bool HandleJobConfig(JOB *aJob, wxWindow *aParent)
Definition: kiway.h:250
virtual int HandleJob(JOB *aJob, REPORTER *aReporter)
Definition: kiway.h:245
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.h:74
wxString m_Lang_Label
Labels used in menus.
Definition: pgm_base.h:77
IFACE KIFACE_BASE kiface("pcb_test_frame", KIWAY::FACE_PCB)