KiCad PCB EDA Suite
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 <dick@softplc.com>
5  * Copyright (C) 2014-2020 KiCad Developers, see CHANGELOG.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 <macros.h>
28 #include <kiway.h>
29 #include <kiway_player.h>
30 #include <kiway_express.h>
31 #include <pgm_base.h>
32 #include <config.h>
33 #include <core/arraydim.h>
34 #include <id.h>
36 #include <logging.h>
37 
38 #include <wx/stdpaths.h>
39 #include <wx/debug.h>
40 #include <wx/utils.h>
41 #include <confirm.h>
42 
43 KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT];
44 int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
45 
46 
47 
48 KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ):
49  m_program( aProgram ), m_ctl( aCtlBits ), m_top( 0 )
50 {
51  SetTop( aTop ); // hook player_destroy_handler() into aTop.
52 
53 
54  // Prepare the room to store the frame names, once they will be created
55  // with FRAME_T type as index in this table.
56  // (note this is a list of frame names, but a non empty entry
57  // does not mean the frame still exists. It means only the frame was created
58  // at least once. It can be destroyed after. These entries are not cleared.
59  // the purpose is just to allow a call to wxWindow::FindWindowByName(), from
60  // a FRAME_T frame type
61  m_playerFrameName.Add( wxEmptyString, KIWAY_PLAYER_COUNT );
62 }
63 
64 
65 #if 0
66 // Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are
67 // propagated upwards to parent windows if not handled below. Therefore the
68 // m_top window should receive all wxWindowDestroyEvents originating from
69 // KIWAY_PLAYERs. It does anyways, but now player_destroy_handler eavesdrops
70 // on that event stream looking for KIWAY_PLAYERs being closed.
71 
72 void KIWAY::player_destroy_handler( wxWindowDestroyEvent& event )
73 {
74  // Currently : do nothing
75  event.Skip(); // skip to who, the wxApp? I'm the top window.
76 }
77 #endif
78 
79 
80 void KIWAY::SetTop( wxFrame* aTop )
81 {
82 #if 0
83  if( m_top )
84  {
85  m_top->Disconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this );
86  }
87 
88  if( aTop )
89  {
90  aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this );
91  }
92 #endif
93 
94  m_top = aTop;
95 }
96 
97 
98 const wxString KIWAY::dso_search_path( FACE_T aFaceId )
99 {
100  const char* name;
101 
102  switch( aFaceId )
103  {
104  case FACE_SCH: name = KIFACE_PREFIX "eeschema"; break;
105  case FACE_PCB: name = KIFACE_PREFIX "pcbnew"; break;
106  case FACE_CVPCB: name = KIFACE_PREFIX "cvpcb"; break;
107  case FACE_GERBVIEW: name = KIFACE_PREFIX "gerbview"; break;
108  case FACE_PL_EDITOR: name = KIFACE_PREFIX "pl_editor"; break;
109  case FACE_PCB_CALCULATOR: name = KIFACE_PREFIX "pcb_calculator"; break;
110  case FACE_BMP2CMP: name = KIFACE_PREFIX "bitmap2component"; break;
111 
112  default:
113  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
114  return wxEmptyString;
115  }
116 
117 #ifndef __WXMAC__
118  wxString path;
119 
121  {
122  // The 2 *.cpp program launchers: single_top.cpp and kicad.cpp expect
123  // the *.kiface's to reside in same directory as their binaries do.
124  // Not so for python launcher, identified by KFCTL_PY_PROJECT_SUITE
125  path = wxStandardPaths::Get().GetExecutablePath();
126  }
127 
128  wxFileName fn = path;
129 #else
130  // we have the dso's in main OSX bundle kicad.app/Contents/PlugIns
131  wxFileName fn = Pgm().GetExecutablePath();
132  fn.AppendDir( wxT( "Contents" ) );
133  fn.AppendDir( wxT( "PlugIns" ) );
134 #endif
135 
136  fn.SetName( name );
137 
138 #ifdef DEBUG
139  // To speed up development, it's sometimes nice to run kicad from inside
140  // the build path. In that case, each program will be in a subdirectory.
141  // To find the DSOs, we need to go up one directory and then enter a subdirectory.
142 
143  if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
144  {
145 #ifdef __WXMAC__
146  fn = wxStandardPaths::Get().GetExecutablePath();
147  fn.RemoveLastDir();
148  fn.AppendDir( wxT( "PlugIns" ) );
149  fn.SetName( name );
150 #else
151  const char* dirName;
152 
153  // The subdirectories usually have the same name as the kiface
154  switch( aFaceId )
155  {
156  case FACE_PL_EDITOR: dirName = "pagelayout_editor"; break;
157  default: dirName = name + 1; break;
158  }
159 
160  fn.RemoveLastDir();
161  fn.AppendDir( dirName );
162 #endif
163  }
164 #endif
165 
166  // Here a "suffix" == an extension with a preceding '.',
167  // so skip the preceding '.' to get an extension
168  fn.SetExt( &KIFACE_SUFFIX[1] );
169 
170  return fn.GetFullPath();
171 }
172 
173 
175 {
176  return Pgm().GetSettingsManager().Prj();
177 }
178 
179 
180 KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
181 {
182  // Since this will be called from python, cannot assume that code will
183  // not pass a bad aFaceId.
184  if( (unsigned) aFaceId >= arrayDim( m_kiface ) )
185  {
186  // @todo : throw an exception here for python's benefit, at least that
187  // way it gets some explanatory text.
188 
189  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
190  return NULL;
191  }
192 
193  // return the previously loaded KIFACE, if it was.
194  if( m_kiface[aFaceId] )
195  return m_kiface[aFaceId];
196 
197  wxString msg;
198 
199  // DSO with KIFACE has not been loaded yet, does caller want to load it?
200  if( doLoad )
201  {
202  wxString dname = dso_search_path( aFaceId );
203 
204  wxDynamicLibrary dso;
205 
206  void* addr = NULL;
207 
208  // For some reason wxDynamicLibrary::Load() crashes in some languages
209  // (chinese for instance) when loading the dynamic library.
210  // The crash happens for Eeschema.
211  // So switch to "C" locale during loading (LC_COLLATE is enough).
212  int lc_new_type = LC_COLLATE;
213  std::string user_locale = setlocale( lc_new_type, nullptr );
214  setlocale( lc_new_type, "C" );
215 
216  bool success = dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL );
217 
218  setlocale( lc_new_type, user_locale.c_str() );
219 
220  if( !success )
221  {
222  // Failure: error reporting UI was done via wxLogSysError().
223  // No further reporting required here. Apparently this is not true on all
224  // platforms and/or wxWidgets builds and KiCad will crash. Throwing the exception
225  // here and catching it in the KiCad launcher resolves the crash issue. See bug
226  // report https://bugs.launchpad.net/kicad/+bug/1577786.
227 
228  msg.Printf( _( "Failed to load kiface library \"%s\"." ),
229  dname );
230  THROW_IO_ERROR( msg );
231  }
232  else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL )
233  {
234  // Failure: error reporting UI was done via wxLogSysError().
235  // No further reporting required here. Assume the same thing applies here as
236  // above with the Load() call. This has not been tested.
237  msg.Printf( _( "Could not read instance name and version symbol from kiface "
238  "library \"%s\"." ),
239  dname );
240  THROW_IO_ERROR( msg );
241  }
242  else
243  {
244  KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr;
245 
246  KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, m_program );
247 
248  // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
249  wxASSERT_MSG( kiface,
250  wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
251 
252  // Give the DSO a single chance to do its "process level" initialization.
253  // "Process level" specifically means stay away from any projects in there.
254  if( kiface->OnKifaceStart( m_program, m_ctl ) )
255  {
256  // Tell dso's wxDynamicLibrary destructor not to Unload() the program image.
257  (void) dso.Detach();
258 
259  return m_kiface[aFaceId] = kiface;
260  }
261  }
262 
263  // In any of the failure cases above, dso.Unload() should be called here
264  // by dso destructor.
265  // However:
266 
267  // There is a file installation bug. We only look for KIFACE_I's which we know
268  // to exist, and we did not find one. If we do not find one, this is an
269  // installation bug.
270 
271  msg = wxString::Format( _(
272  "Fatal Installation Bug. File:\n"
273  "\"%s\"\ncould not be loaded\n" ), dname );
274 
275  if( ! wxFileExists( dname ) )
276  msg << _( "It is missing.\n" );
277  else
278  msg << _( "Perhaps a shared library (.dll or .so) file is missing.\n" );
279 
280  msg << _( "From command line: argv[0]:\n'" );
281  msg << wxStandardPaths::Get().GetExecutablePath() << wxT( "'\n" );
282 
283  // This is a fatal error, one from which we cannot recover, nor do we want
284  // to protect against in client code which would require numerous noisy
285  // tests in numerous places. So we inform the user that the installation
286  // is bad. This exception will likely not get caught until way up in the
287  // wxApp derivative, at which point the process will exit gracefully.
288  THROW_IO_ERROR( msg );
289  }
290 
291  return NULL;
292 }
293 
294 
296 {
297  switch( aFrameType )
298  {
299  case FRAME_SCH:
301  case FRAME_SCH_VIEWER:
303  case FRAME_SIMULATOR:
304  return FACE_SCH;
305 
306  case FRAME_PCB_EDITOR:
311  case FRAME_PCB_DISPLAY3D:
312  return FACE_PCB;
313 
314  case FRAME_CVPCB:
315  case FRAME_CVPCB_DISPLAY:
316  return FACE_CVPCB;
317 
318  case FRAME_GERBER:
319  return FACE_GERBVIEW;
320 
321  case FRAME_PL_EDITOR:
322  return FACE_PL_EDITOR;
323 
324  case FRAME_CALC:
325  return FACE_PCB_CALCULATOR;
326 
327  case FRAME_BM2CMP:
328  return FACE_BMP2CMP;
329 
330  default:
331  return FACE_T( -1 );
332  }
333 }
334 
335 
337 {
338  if( m_playerFrameName[aFrameType].IsEmpty() )
339  return NULL;
340 
341  return static_cast<KIWAY_PLAYER*>( wxWindow::FindWindowByName( m_playerFrameName[aFrameType] ) );
342 }
343 
344 
345 KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow* aParent )
346 {
347  // Since this will be called from python, cannot assume that code will
348  // not pass a bad aFrameType.
349  if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
350  {
351  // @todo : throw an exception here for python's benefit, at least that
352  // way it gets some explanatory text.
353 
354  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
355  return nullptr;
356  }
357 
358  // return the previously opened window
359  KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
360 
361  if( frame )
362  return frame;
363 
364  if( doCreate )
365  {
366  try
367  {
368  FACE_T face_type = KifaceType( aFrameType );
369  KIFACE* kiface = KiFACE( face_type );
370 
371  frame = (KIWAY_PLAYER*) kiface->CreateWindow(
372  aParent, // Parent window of frame in modal mode,
373  // NULL in non modal mode
374  aFrameType,
375  this,
376  m_ctl // questionable need, these same flags
377  // were passed to KIFACE::OnKifaceStart()
378  );
379 
380  m_playerFrameName[aFrameType] = frame->GetName();
381  return frame;
382  }
383  catch( const IO_ERROR& ioe )
384  {
385  DisplayErrorMessage( nullptr, _( "Error loading editor" ), ioe.What() );
386  }
387  catch( const std::exception& e)
388  {
389  DisplayErrorMessage( nullptr, _( "Error loading editor" ), e.what() );
390  }
391  catch( ... )
392  {
393  DisplayErrorMessage( nullptr, _( "Error loading editor" ) );
394  }
395  }
396 
397  return nullptr;
398 }
399 
400 
401 bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
402 {
403  // Since this will be called from python, cannot assume that code will
404  // not pass a bad aFrameType.
405  if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
406  {
407  // @todo : throw an exception here for python's benefit, at least that
408  // way it gets some explanatory text.
409 
410  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
411  return false;
412  }
413 
414  KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
415 
416  if( frame == NULL ) // Already closed
417  return true;
418 
419  if( frame->NonUserClose( doForce ) )
420  return true;
421 
422  return false;
423 }
424 
425 
426 bool KIWAY::PlayersClose( bool doForce )
427 {
428  bool ret = true;
429 
430  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
431  {
432  ret = ret && PlayerClose( FRAME_T( i ), doForce );
433  }
434 
435  return ret;
436 }
437 
438 
439 void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload, wxWindow* aSource )
440 {
441  KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource );
442 
443  ProcessEvent( mail );
444 }
445 
446 
447 void KIWAY::SetLanguage( int aLanguage )
448 {
449  wxString errMsg;
450  bool ret = false;
451 
452  {
453  // Only allow the traces to be logged by wx. We use our own system to log when the
454  // OS doesn't support the language, so we want to hide the wx error.
455  WX_LOG_TRACE_ONLY logtraceOnly;
456  Pgm().SetLanguageIdentifier( aLanguage );
457  ret = Pgm().SetLanguage( errMsg );
458  }
459 
460  if( !ret )
461  {
462  wxString lang;
463 
464  for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
465  {
466  if( aLanguage == LanguagesList[ii].m_KI_Lang_Identifier )
467  {
468  if( LanguagesList[ii].m_DoNotTranslate )
469  lang = LanguagesList[ii].m_Lang_Label;
470  else
471  lang = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
472 
473  break;
474  }
475  }
476 
477  DisplayErrorMessage( nullptr,
478  wxString::Format( _( "Unable to switch language to %s" ), lang ),
479  errMsg );
480  return;
481  }
482 
483 #if 1
484  // This is a risky hack that goes away if we allow the language to be
485  // set only from the top most frame if !Kiface.IsSingle()
486 
487  // Only for the C++ project manager, and not for the python one and not for
488  // single_top do we look for the EDA_BASE_FRAME as the top level window.
489  // For single_top this is not needed because that window is registered in
490  // the array below.
492  {
493  // A dynamic_cast could be better, but creates link issues
494  // (some basic_frame functions not found) on some platforms,
495  // so a static_cast is used.
496  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
497 
498  if( top )
499  top->ShowChangedLanguage();
500  }
501 #endif
502 
503  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
504  {
505  KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
506 
507  if( frame )
508  {
509  frame->ShowChangedLanguage();
510  }
511  }
512 }
513 
514 
515 void KIWAY::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
516 {
518  {
519  // A dynamic_cast could be better, but creates link issues
520  // (some basic_frame functions not found) on some platforms,
521  // so a static_cast is used.
522  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
523 
524  if( top )
525  top->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
526  }
527 
528  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
529  {
530  KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
531 
532  if( frame )
533  frame->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
534  }
535 }
536 
537 
539 {
541  {
542  // A dynamic_cast could be better, but creates link issues
543  // (some basic_frame functions not found) on some platforms,
544  // so a static_cast is used.
545  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
546 
547  if( top )
548  top->ProjectChanged();
549  }
550 
551  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
552  {
553  KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
554 
555  if( frame )
556  frame->ProjectChanged();
557  }
558 }
559 
560 
561 bool KIWAY::ProcessEvent( wxEvent& aEvent )
562 {
563  KIWAY_EXPRESS* mail = dynamic_cast<KIWAY_EXPRESS*>( &aEvent );
564 
565  if( mail )
566  {
567  FRAME_T dest = mail->Dest();
568 
569  // see if recipient is alive
570  KIWAY_PLAYER* alive = Player( dest, false );
571 
572  if( alive )
573  {
574 #if 1
575  return alive->ProcessEvent( aEvent );
576 #else
577  alive->KiwayMailIn( *mail );
578  return true;
579 #endif
580  }
581  }
582 
583  return false;
584 }
585 
586 
588 {
590  {
591  // A dynamic_cast could be better, but creates link issues
592  // (some basic_frame functions not found) on some platforms,
593  // so a static_cast is used.
594  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
595 
596  if( top )
597  top->Close( false );
598  }
599 }
600 
601 
603 {
604  for( KIFACE* i : m_kiface )
605  {
606  if( i )
607  i->OnKifaceEnd();
608  }
609 }
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition: kiway.h:156
LANGUAGE_DESCR LanguagesList[]
An array containing all the languages that KiCad supports.
Definition: pgm_base.cpp:76
BITMAP2CMP_SETTINGS kiface
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:426
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:38
void OnKiCadExit()
Definition: kiway.cpp:587
Container for project specific data.
Definition: project.h:62
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:295
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:266
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition: kiway.cpp:336
This file is part of the common library.
Container for data for KiCad programs.
Definition: pgm_base.h:131
#define KIFACE_VERSION
The KIWAY and KIFACE classes are used to communicate between various process modules,...
Definition: kiway.h:108
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:174
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.h:63
PGM_BASE * m_program
Definition: kiway.h:422
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:345
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:439
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition: kiway.cpp:447
void OnKiwayEnd()
Definition: kiway.cpp:602
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
#define KIFACE_INSTANCE_NAME_AND_VERSION
Definition: kiway.h:113
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:37
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
bool NonUserClose(bool aForce)
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:401
bool ProcessEvent(wxEvent &aEvent) override
Definition: kiway.cpp:561
KIFACE * KIFACE_GETTER_FUNC(int *aKIFACEversion, int aKIWAYversion, PGM_BASE *aProgram)
Point to the one and only KIFACE export.
Definition: kiway.h:456
virtual void ProjectChanged()
Calls ProjectChanged() on all KIWAY_PLAYERs.
Definition: kiway.cpp:538
int m_ctl
Definition: kiway.h:423
virtual void KiwayMailIn(KIWAY_EXPRESS &aEvent)
Receive KIWAY_EXPRESS messages from other players.
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
pcbnew DSO
Definition: kiway.h:269
const wxString dso_search_path(FACE_T aFaceId)
Get the [path &] name of the DSO holding the requested FACE_T.
Definition: kiway.cpp:98
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:180
wxString m_Lang_Label
Labels used in menus.
Definition: pgm_base.h:66
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:80
A logger class that filters out all log messages that are not generated by wxLogTrace and ignores the...
Definition: logging.h:31
FACE_T
Known KIFACE implementations.
Definition: kiway.h:266
eeschema DSO
Definition: kiway.h:268
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
FRAME_T Dest()
Return the destination player id of the message.
Definition: kiway_express.h:44
see class PGM_BASE
const char * name
Definition: DXF_plotter.cpp:59
#define _(s)
Definition: 3d_actions.cpp:33
The base frame for deriving all KiCad main window classes.
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:147
KIWAY(PGM_BASE *aProgram, int aCtlBits, wxFrame *aTop=nullptr)
Definition: kiway.cpp:48
static int m_kiface_version[KIWAY_FACE_COUNT]
Definition: kiway.h:420
virtual void ProjectChanged()
Notification event that the project has changed.
virtual void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged)
Call CommonSettingsChanged() on all KIWAY_PLAYERs.
Definition: kiway.cpp:515
wxArrayString m_playerFrameName
Definition: kiway.h:433
wxFrame * m_top
Definition: kiway.h:425
virtual void ShowChangedLanguage()
Redraw the menus and what not in current language.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
int PGM_BASE * aProgram
Definition: cvpcb.cpp:97
static KIFACE * m_kiface[KIWAY_FACE_COUNT]
Definition: kiway.h:419
#define KFCTL_STANDALONE
Running as a standalone Top.
Definition: kiway.h:155