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