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