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