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