KiCad PCB EDA Suite
KIWAY Class Reference

A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad process. More...

#include <kiway.h>

Inheritance diagram for KIWAY:

Public Types

enum  FACE_T {
  FACE_SCH, FACE_PCB, FACE_CVPCB, FACE_GERBVIEW,
  FACE_PL_EDITOR, FACE_PCB_CALCULATOR, FACE_BMP2CMP, KIWAY_FACE_COUNT
}
 Known KIFACE implementations. More...
 

Public Member Functions

 ~KIWAY () throw ()
 
virtual KIFACEKiFACE (FACE_T aFaceId, bool doLoad=true)
 Return the KIFACE* given a FACE_T. More...
 
virtual KIWAY_PLAYERPlayer (FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
 Return the KIWAY_PLAYER* given a FRAME_T. More...
 
virtual bool PlayerClose (FRAME_T aFrameType, bool doForce)
 Call the KIWAY_PLAYER::Close( bool force ) function on the window and if not vetoed, returns true, else false. More...
 
virtual bool PlayersClose (bool doForce)
 Call the KIWAY_PLAYER::Close( bool force ) function on all the windows and if none are vetoed, returns true, else false. More...
 
virtual void ExpressMail (FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
 Send aPayload to aDestination from aSource. More...
 
virtual PROJECTPrj () const
 Return the PROJECT associated with this KIWAY. More...
 
virtual void SetLanguage (int aLanguage)
 Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs. More...
 
virtual void CommonSettingsChanged (bool aEnvVarsChanged, bool aTextVarsChanged)
 Call CommonSettingsChanged() on all KIWAY_PLAYERs. More...
 
virtual void ProjectChanged ()
 Calls ProjectChanged() on all KIWAY_PLAYERs. More...
 
 KIWAY (PGM_BASE *aProgram, int aCtlBits, wxFrame *aTop=nullptr)
 
void SetTop (wxFrame *aTop)
 Tell this KIWAY about the top most frame in the program and optionally allows it to play the role of one of the KIWAY_PLAYERs if launched from single_top.cpp. More...
 
void OnKiCadExit ()
 
void OnKiwayEnd ()
 
bool ProcessEvent (wxEvent &aEvent) override
 

Static Public Member Functions

static FACE_T KifaceType (FRAME_T aFrameType)
 A simple mapping function which returns the FACE_T which is known to implement aFrameType. More...
 

Private Member Functions

const wxString dso_search_path (FACE_T aFaceId)
 Get the [path &] name of the DSO holding the requested FACE_T. More...
 
bool set_kiface (FACE_T aFaceType, KIFACE *aKiface)
 
KIWAY_PLAYERGetPlayerFrame (FRAME_T aFrameType)
 

Private Attributes

PGM_BASEm_program
 
int m_ctl
 
wxFrame * m_top
 
wxArrayString m_playerFrameName
 

Static Private Attributes

static KIFACEm_kiface [KIWAY_FACE_COUNT]
 
static int m_kiface_version [KIWAY_FACE_COUNT]
 

Friends

struct PGM_SINGLE_TOP
 

Detailed Description

A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad process.

It makes it possible to call between DSOs without having to link them together, and without having to link to the top process module which houses the KIWAY(s). More importantly it makes it possible to send custom wxEvents between DSOs and from the top process module down into the DSOs. The latter capability is thought useful for driving the lower DSOs from a python test rig or for demo (automation) purposes.

Most all calls are via virtual functions, which means C++ vtables are used to hold function pointers and eliminate the need to link to specific object code libraries, speeding development and encouraging clearly defined interface design. Unlike Microsoft COM, which is a multi-vendor design supporting DLL's built at various points in time, the KIWAY alchemy is single project, with all components being built at the same time. So one should expect solid compatibility between all KiCad components, as long at they are compiled at the same time.

There is one KIWAY in the launching portion of the process for each open KiCad project. Each project has its own KIWAY. Available to each KIWAY is an actual PROJECT data structure. If you have a KIWAY, you can get to the PROJECT using KIWAY::Prj().

In summary, a KIWAY facilitates communicating between DSOs, where the topic of the communication is project specific. Here a "project" means a BOARD and a SCHEMATIC and a NETLIST, (anything relating to production of a single BOARD and added to class PROJECT.)

Definition at line 260 of file kiway.h.

Member Enumeration Documentation

◆ FACE_T

Known KIFACE implementations.

Enumerator
FACE_SCH 

eeschema DSO

FACE_PCB 

pcbnew DSO

FACE_CVPCB 
FACE_GERBVIEW 
FACE_PL_EDITOR 
FACE_PCB_CALCULATOR 
FACE_BMP2CMP 
KIWAY_FACE_COUNT 

Definition at line 266 of file kiway.h.

Constructor & Destructor Documentation

◆ ~KIWAY()

KIWAY::~KIWAY ( )
throw (
)
inline

Definition at line 279 of file kiway.h.

279 {}

◆ KIWAY()

KIWAY::KIWAY ( PGM_BASE aProgram,
int  aCtlBits,
wxFrame *  aTop = nullptr 
)

Definition at line 49 of file kiway.cpp.

49  :
50  m_program( aProgram ), m_ctl( aCtlBits ), m_top( 0 )
51 {
52  SetTop( aTop ); // hook player_destroy_handler() into aTop.
53 
54 
55  // Prepare the room to store the frame names, once they will be created
56  // with FRAME_T type as index in this table.
57  // (note this is a list of frame names, but a non empty entry
58  // does not mean the frame still exists. It means only the frame was created
59  // at least once. It can be destroyed after. These entries are not cleared.
60  // the purpose is just to allow a call to wxWindow::FindWindowByName(), from
61  // a FRAME_T frame type
62  m_playerFrameName.Add( wxEmptyString, KIWAY_PLAYER_COUNT );
63 }
PGM_BASE * m_program
Definition: kiway.h:422
int m_ctl
Definition: kiway.h:423
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:81
wxArrayString m_playerFrameName
Definition: kiway.h:433
wxFrame * m_top
Definition: kiway.h:425
int PGM_BASE * aProgram
Definition: cvpcb.cpp:97

References KIWAY_PLAYER_COUNT, m_playerFrameName, and SetTop().

Member Function Documentation

◆ CommonSettingsChanged()

void KIWAY::CommonSettingsChanged ( bool  aEnvVarsChanged,
bool  aTextVarsChanged 
)
virtual

Call CommonSettingsChanged() on all KIWAY_PLAYERs.

Use after changing suite-wide options such as panning, autosave interval, etc.

Definition at line 527 of file kiway.cpp.

528 {
530  {
531  // A dynamic_cast could be better, but creates link issues
532  // (some basic_frame functions not found) on some platforms,
533  // so a static_cast is used.
534  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
535 
536  if( top )
537  top->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
538  }
539 
540  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
541  {
542  KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
543 
544  if( frame )
545  frame->CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
546  }
547 }
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition: kiway.h:156
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition: kiway.cpp:348
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
int m_ctl
Definition: kiway.h:423
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
The base frame for deriving all KiCad main window classes.
wxFrame * m_top
Definition: kiway.h:425

References EDA_BASE_FRAME::CommonSettingsChanged(), GetPlayerFrame(), KFCTL_CPP_PROJECT_SUITE, KIWAY_PLAYER_COUNT, m_ctl, and m_top.

Referenced by COMMON_CONTROL::ConfigurePaths(), PCB::IFACE::CreateWindow(), EDA_BASE_FRAME::OnPreferences(), PCB_EDIT_FRAME::ShowBoardSetupDialog(), and SCH_EDIT_FRAME::ShowSchematicSetupDialog().

◆ dso_search_path()

const wxString KIWAY::dso_search_path ( FACE_T  aFaceId)
private

Get the [path &] name of the DSO holding the requested FACE_T.

Definition at line 99 of file kiway.cpp.

100 {
101  const char* name;
102 
103  switch( aFaceId )
104  {
105  case FACE_SCH: name = KIFACE_PREFIX "eeschema"; break;
106  case FACE_PCB: name = KIFACE_PREFIX "pcbnew"; break;
107  case FACE_CVPCB: name = KIFACE_PREFIX "cvpcb"; break;
108  case FACE_GERBVIEW: name = KIFACE_PREFIX "gerbview"; break;
109  case FACE_PL_EDITOR: name = KIFACE_PREFIX "pl_editor"; break;
110  case FACE_PCB_CALCULATOR: name = KIFACE_PREFIX "pcb_calculator"; break;
111  case FACE_BMP2CMP: name = KIFACE_PREFIX "bitmap2component"; break;
112 
113  default:
114  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
115  return wxEmptyString;
116  }
117 
118 #ifndef __WXMAC__
119  wxString path;
120 
122  {
123  // The 2 *.cpp program launchers: single_top.cpp and kicad.cpp expect
124  // the *.kiface's to reside in same directory as their binaries do.
125  // Not so for python launcher, identified by KFCTL_PY_PROJECT_SUITE
126  path = wxStandardPaths::Get().GetExecutablePath();
127  }
128 
129  wxFileName fn = path;
130 #else
131  // we have the dso's in main OSX bundle kicad.app/Contents/PlugIns
132  wxFileName fn = Pgm().GetExecutablePath();
133  fn.AppendDir( wxT( "Contents" ) );
134  fn.AppendDir( wxT( "PlugIns" ) );
135 #endif
136 
137  fn.SetName( name );
138 
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 
165  // Here a "suffix" == an extension with a preceding '.',
166  // so skip the preceding '.' to get an extension
167  fn.SetExt( &KIFACE_SUFFIX[1] );
168 
169  return fn.GetFullPath();
170 }
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition: kiway.h:156
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
int m_ctl
Definition: kiway.h:423
pcbnew DSO
Definition: kiway.h:269
eeschema DSO
Definition: kiway.h:268
const char * name
Definition: DXF_plotter.cpp:59
#define KFCTL_STANDALONE
Running as a standalone Top.
Definition: kiway.h:155

References FACE_BMP2CMP, FACE_CVPCB, FACE_GERBVIEW, FACE_PCB, FACE_PCB_CALCULATOR, FACE_PL_EDITOR, FACE_SCH, KFCTL_CPP_PROJECT_SUITE, KFCTL_STANDALONE, m_ctl, name, path, and Pgm().

Referenced by KiFACE().

◆ ExpressMail()

void KIWAY::ExpressMail ( FRAME_T  aDestination,
MAIL_T  aCommand,
std::string &  aPayload,
wxWindow *  aSource = nullptr 
)
virtual

◆ GetPlayerFrame()

KIWAY_PLAYER * KIWAY::GetPlayerFrame ( FRAME_T  aFrameType)
private
Returns
the reference of the KIWAY_PLAYER having the type aFrameType if exists, or NULL if this KIWAY_PLAYER was not yet created, or was closed

Definition at line 348 of file kiway.cpp.

349 {
350  if( m_playerFrameName[aFrameType].IsEmpty() )
351  return NULL;
352 
353  return static_cast<KIWAY_PLAYER*>( wxWindow::FindWindowByName( m_playerFrameName[aFrameType] ) );
354 }
#define NULL
wxArrayString m_playerFrameName
Definition: kiway.h:433

References m_playerFrameName, and NULL.

Referenced by CommonSettingsChanged(), Player(), PlayerClose(), ProjectChanged(), and SetLanguage().

◆ KiFACE()

KIFACE * KIWAY::KiFACE ( FACE_T  aFaceId,
bool  doLoad = true 
)
virtual

Return the KIFACE* given a FACE_T.

If it is not already loaded, the KIFACE is loaded and initialized with a call to KIFACE::OnKifaceStart().

Definition at line 179 of file kiway.cpp.

180 {
181  // Since this will be called from python, cannot assume that code will
182  // not pass a bad aFaceId.
183  if( (unsigned) aFaceId >= arrayDim( m_kiface ) )
184  {
185  // @todo : throw an exception here for python's benefit, at least that
186  // way it gets some explanatory text.
187 
188  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
189  return NULL;
190  }
191 
192  // return the previously loaded KIFACE, if it was.
193  if( m_kiface[aFaceId] )
194  return m_kiface[aFaceId];
195 
196  wxString msg;
197 
198  // DSO with KIFACE has not been loaded yet, does caller want to load it?
199  if( doLoad )
200  {
201  wxString dname = dso_search_path( aFaceId );
202 
203  // Insert DLL search path for kicad_3dsg from build dir
204  if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
205  {
206  wxFileName myPath = wxStandardPaths::Get().GetExecutablePath();
207 
208  if( !myPath.GetPath().EndsWith( wxT( "pcbnew" ) ) )
209  {
210  myPath.RemoveLastDir();
211  myPath.AppendDir( wxT( "pcbnew" ) );
213  }
214  }
215 
216  wxDynamicLibrary dso;
217 
218  void* addr = NULL;
219 
220  // For some reason wxDynamicLibrary::Load() crashes in some languages
221  // (chinese for instance) when loading the dynamic library.
222  // The crash happens for Eeschema.
223  // So switch to "C" locale during loading (LC_COLLATE is enough).
224  int lc_new_type = LC_COLLATE;
225  std::string user_locale = setlocale( lc_new_type, nullptr );
226  setlocale( lc_new_type, "C" );
227 
228  bool success = dso.Load( dname, wxDL_VERBATIM | wxDL_NOW | wxDL_GLOBAL );
229 
230  setlocale( lc_new_type, user_locale.c_str() );
231 
232  if( !success )
233  {
234  // Failure: error reporting UI was done via wxLogSysError().
235  // No further reporting required here. Apparently this is not true on all
236  // platforms and/or wxWidgets builds and KiCad will crash. Throwing the exception
237  // here and catching it in the KiCad launcher resolves the crash issue. See bug
238  // report https://bugs.launchpad.net/kicad/+bug/1577786.
239 
240  msg.Printf( _( "Failed to load kiface library \"%s\"." ),
241  dname );
242  THROW_IO_ERROR( msg );
243  }
244  else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL )
245  {
246  // Failure: error reporting UI was done via wxLogSysError().
247  // No further reporting required here. Assume the same thing applies here as
248  // above with the Load() call. This has not been tested.
249  msg.Printf( _( "Could not read instance name and version symbol from kiface "
250  "library \"%s\"." ),
251  dname );
252  THROW_IO_ERROR( msg );
253  }
254  else
255  {
256  KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr;
257 
258  KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, m_program );
259 
260  // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
261  wxASSERT_MSG( kiface,
262  wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
263 
264  // Give the DSO a single chance to do its "process level" initialization.
265  // "Process level" specifically means stay away from any projects in there.
266  if( kiface->OnKifaceStart( m_program, m_ctl ) )
267  {
268  // Tell dso's wxDynamicLibrary destructor not to Unload() the program image.
269  (void) dso.Detach();
270 
271  return m_kiface[aFaceId] = kiface;
272  }
273  }
274 
275  // In any of the failure cases above, dso.Unload() should be called here
276  // by dso destructor.
277  // However:
278 
279  // There is a file installation bug. We only look for KIFACE_I's which we know
280  // to exist, and we did not find one. If we do not find one, this is an
281  // installation bug.
282 
283  msg = wxString::Format( _(
284  "Fatal Installation Bug. File:\n"
285  "\"%s\"\ncould not be loaded\n" ), dname );
286 
287  if( ! wxFileExists( dname ) )
288  msg << _( "It is missing.\n" );
289  else
290  msg << _( "Perhaps a shared library (.dll or .so) file is missing.\n" );
291 
292  msg << _( "From command line: argv[0]:\n'" );
293  msg << wxStandardPaths::Get().GetExecutablePath() << wxT( "'\n" );
294 
295  // This is a fatal error, one from which we cannot recover, nor do we want
296  // to protect against in client code which would require numerous noisy
297  // tests in numerous places. So we inform the user that the installation
298  // is bad. This exception will likely not get caught until way up in the
299  // wxApp derivative, at which point the process will exit gracefully.
300  THROW_IO_ERROR( msg );
301  }
302 
303  return NULL;
304 }
BITMAP2CMP_SETTINGS kiface
#define KIFACE_VERSION
The KIWAY and KIFACE classes are used to communicate between various process modules,...
Definition: kiway.h:108
PGM_BASE * m_program
Definition: kiway.h:422
void AddDynamicLibrarySearchPath(const wxString &aPath)
Inserts a search path for loading dynamic libraries.
Definition: gtk/app.cpp:86
#define KIFACE_INSTANCE_NAME_AND_VERSION
Definition: kiway.h:113
#define NULL
KIFACE * KIFACE_GETTER_FUNC(int *aKIFACEversion, int aKIWAYversion, PGM_BASE *aProgram)
Point to the one and only KIFACE export.
Definition: kiway.h:456
int m_ctl
Definition: kiway.h:423
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
const wxString dso_search_path(FACE_T aFaceId)
Get the [path &] name of the DSO holding the requested FACE_T.
Definition: kiway.cpp:99
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
#define _(s)
Definition: 3d_actions.cpp:33
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:147
static int m_kiface_version[KIWAY_FACE_COUNT]
Definition: kiway.h:420
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
static KIFACE * m_kiface[KIWAY_FACE_COUNT]
Definition: kiway.h:419

References _, KIPLATFORM::APP::AddDynamicLibrarySearchPath(), arrayDim(), dso_search_path(), Format(), kiface, KIFACE_INSTANCE_NAME_AND_VERSION, KIFACE_VERSION, m_ctl, m_kiface, m_kiface_version, m_program, NULL, and THROW_IO_ERROR.

Referenced by COMMON_CONTROL::ConfigurePaths(), FOOTPRINT_PREVIEW_PANEL_BASE::Create(), get_instance_from_id(), SAVE_AS_TRAVERSER::OnFile(), PROJECT::PcbFootprintLibs(), Player(), and COMMON_CONTROL::ShowLibraryTable().

◆ KifaceType()

KIWAY::FACE_T KIWAY::KifaceType ( FRAME_T  aFrameType)
static

A simple mapping function which returns the FACE_T which is known to implement aFrameType.

Returns
a valid value KIWAY::FACE_T or FACE_T(-1) if given a bad aFrameType.

Definition at line 307 of file kiway.cpp.

308 {
309  switch( aFrameType )
310  {
311  case FRAME_SCH:
313  case FRAME_SCH_VIEWER:
315  case FRAME_SIMULATOR:
316  return FACE_SCH;
317 
318  case FRAME_PCB_EDITOR:
323  case FRAME_PCB_DISPLAY3D:
324  return FACE_PCB;
325 
326  case FRAME_CVPCB:
327  case FRAME_CVPCB_DISPLAY:
328  return FACE_CVPCB;
329 
330  case FRAME_GERBER:
331  return FACE_GERBVIEW;
332 
333  case FRAME_PL_EDITOR:
334  return FACE_PL_EDITOR;
335 
336  case FRAME_CALC:
337  return FACE_PCB_CALCULATOR;
338 
339  case FRAME_BM2CMP:
340  return FACE_BMP2CMP;
341 
342  default:
343  return FACE_T( -1 );
344  }
345 }
pcbnew DSO
Definition: kiway.h:269
FACE_T
Known KIFACE implementations.
Definition: kiway.h:266
eeschema DSO
Definition: kiway.h:268

References FACE_BMP2CMP, FACE_CVPCB, FACE_GERBVIEW, FACE_PCB, FACE_PCB_CALCULATOR, FACE_PL_EDITOR, FACE_SCH, FRAME_BM2CMP, FRAME_CALC, FRAME_CVPCB, FRAME_CVPCB_DISPLAY, FRAME_FOOTPRINT_EDITOR, FRAME_FOOTPRINT_VIEWER, FRAME_FOOTPRINT_VIEWER_MODAL, FRAME_FOOTPRINT_WIZARD, FRAME_GERBER, FRAME_PCB_DISPLAY3D, FRAME_PCB_EDITOR, FRAME_PL_EDITOR, FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR, FRAME_SCH_VIEWER, FRAME_SCH_VIEWER_MODAL, and FRAME_SIMULATOR.

Referenced by PGM_SINGLE_TOP::OnPgmInit(), and Player().

◆ OnKiCadExit()

void KIWAY::OnKiCadExit ( )

Definition at line 599 of file kiway.cpp.

600 {
602  {
603  // A dynamic_cast could be better, but creates link issues
604  // (some basic_frame functions not found) on some platforms,
605  // so a static_cast is used.
606  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
607 
608  if( top )
609  top->Close( false );
610  }
611 }
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition: kiway.h:156
int m_ctl
Definition: kiway.h:423
The base frame for deriving all KiCad main window classes.
wxFrame * m_top
Definition: kiway.h:425

References KFCTL_CPP_PROJECT_SUITE, m_ctl, and m_top.

Referenced by PL_EDITOR_FRAME::OnExit(), SCH_EDIT_FRAME::OnExit(), FOOTPRINT_EDIT_FRAME::OnExitKiCad(), FOOTPRINT_VIEWER_FRAME::OnExitKiCad(), SYMBOL_EDIT_FRAME::OnExitKiCad(), and PCB_EDIT_FRAME::OnQuit().

◆ OnKiwayEnd()

void KIWAY::OnKiwayEnd ( )

Definition at line 614 of file kiway.cpp.

615 {
616  for( KIFACE* i : m_kiface )
617  {
618  if( i )
619  i->OnKifaceEnd();
620  }
621 }
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:147
static KIFACE * m_kiface[KIWAY_FACE_COUNT]
Definition: kiway.h:419

References m_kiface.

Referenced by CreateWindow(), PGM_KICAD::OnPgmExit(), PGM_SINGLE_TOP::OnPgmExit(), PGM_TEST_FRAME::OnPgmExit(), and PGM_MOCK_EESCHEMA_FRAME::OnPgmExit().

◆ Player()

KIWAY_PLAYER * KIWAY::Player ( FRAME_T  aFrameType,
bool  doCreate = true,
wxTopLevelWindow *  aParent = nullptr 
)
virtual

Return the KIWAY_PLAYER* given a FRAME_T.

If it is not already created, the required KIFACE is found and loaded and initialized if necessary, then the KIWAY_PLAYER window is created but not shown. Caller must Show() it. If it is already created, then the existing KIWAY_PLAYER* pointer is returned.

Parameters
aFrameTypeis from enum FRAME_T.
doCreatewhen true asks that the player be created if it is not already created, false means do not create and maybe return NULL.
aParentis a parent for modal KIWAY_PLAYER frames, otherwise NULL used only when doCreate = true and by KIWAY_PLAYER frames created in modal form
Returns
a valid opened KIWAY_PLAYER or NULL if there is something wrong or doCreate was false and the player has yet to be created.
Exceptions
IO_ERRORif the *.kiface file could not be found, filled with text saying what.

Definition at line 357 of file kiway.cpp.

358 {
359  // Since this will be called from python, cannot assume that code will
360  // not pass a bad aFrameType.
361  if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
362  {
363  // @todo : throw an exception here for python's benefit, at least that
364  // way it gets some explanatory text.
365 
366  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
367  return nullptr;
368  }
369 
370  // return the previously opened window
371  KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
372 
373  if( frame )
374  return frame;
375 
376  if( doCreate )
377  {
378  try
379  {
380  FACE_T face_type = KifaceType( aFrameType );
381  KIFACE* kiface = KiFACE( face_type );
382 
383  frame = (KIWAY_PLAYER*) kiface->CreateWindow(
384  aParent, // Parent window of frame in modal mode,
385  // NULL in non modal mode
386  aFrameType,
387  this,
388  m_ctl // questionable need, these same flags
389  // were passed to KIFACE::OnKifaceStart()
390  );
391 
392  m_playerFrameName[aFrameType] = frame->GetName();
393  return frame;
394  }
395  catch( const IO_ERROR& ioe )
396  {
397  DisplayErrorMessage( nullptr, _( "Error loading editor" ), ioe.What() );
398  }
399  catch( const std::exception& e)
400  {
401  DisplayErrorMessage( nullptr, _( "Error loading editor" ), e.what() );
402  }
403  catch( ... )
404  {
405  DisplayErrorMessage( nullptr, _( "Error loading editor" ) );
406  }
407  }
408 
409  return nullptr;
410 }
BITMAP2CMP_SETTINGS kiface
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
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:307
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:348
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
int m_ctl
Definition: kiway.h:423
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:179
FACE_T
Known KIFACE implementations.
Definition: kiway.h:266
#define _(s)
Definition: 3d_actions.cpp:33
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:147
wxArrayString m_playerFrameName
Definition: kiway.h:433
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75

References _, DisplayErrorMessage(), GetPlayerFrame(), kiface, KiFACE(), KifaceType(), KIWAY_PLAYER_COUNT, m_ctl, m_playerFrameName, and IO_ERROR::What().

Referenced by FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB(), PCB_BASE_EDIT_FRAME::AddLibrary(), SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic(), SYMBOL_EDIT_FRAME::canCloseWindow(), SCH_EDIT_FRAME::canCloseWindow(), FOOTPRINT_EDITOR_CONTROL::CreateFootprint(), FIELDS_GRID_TRICKS::doPopupSelection(), FIELDS_EDITOR_GRID_TRICKS::doPopupSelection(), BOARD_EDITOR_CONTROL::EditFpInFpEditor(), SCH_EDITOR_CONTROL::EditWithSymbolEditor(), BACK_ANNOTATE::FetchNetlistFromPCB(), KICAD_MANAGER_FRAME::ImportNonKiCadProject(), InvokePcbLibTableEditor(), InvokeSchEditSymbolLibTable(), DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser(), DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser(), FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard(), TEXT_BUTTON_SYMBOL_CHOOSER::OnButtonClick(), TEXT_BUTTON_FP_CHOOSER::OnButtonClick(), SCH_EDIT_FRAME::OnOpenCvpcb(), SCH_EDIT_FRAME::OnOpenPcbnew(), PGM_SINGLE_TOP::OnPgmInit(), EDA_BASE_FRAME::OnPreferences(), DIALOG_SYMBOL_REMAP::OnRemapSymbols(), DIALOG_EDIT_ONE_FIELD::OnTextValueSelectButtonClick(), FOOTPRINT_EDIT_FRAME::OnUpdateLoadFootprintFromBoard(), SCH_EDIT_FRAME::OnUpdatePCB(), FOOTPRINT_EDIT_FRAME::OnUpdateSaveFootprintToBoard(), SCH_BASE_FRAME::PickSymbolFromLibBrowser(), ProcessEvent(), SCH_EDIT_TOOL::Properties(), SCH_EDITOR_CONTROL::rescueProject(), PCB_EDIT_FRAME::RunEeschema(), EE_INSPECTION_TOOL::RunSimulation(), SYMBOL_EDIT_FRAME::Save(), FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard(), PCB_BASE_FRAME::SelectFootprintFromLibBrowser(), PCB_EDIT_FRAME::ShowFootprintPropertiesDialog(), CVPCB_CONTROL::ShowFootprintViewer(), COMMON_CONTROL::ShowPlayer(), KICAD_MANAGER_CONTROL::ShowPlayer(), SIM_PLOT_FRAME::SIM_PLOT_FRAME(), PCB_EDIT_FRAME::TestStandalone(), BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB(), and DIALOG_EXCHANGE_FOOTPRINTS::ViewAndSelectFootprint().

◆ PlayerClose()

bool KIWAY::PlayerClose ( FRAME_T  aFrameType,
bool  doForce 
)
virtual

Call the KIWAY_PLAYER::Close( bool force ) function on the window and if not vetoed, returns true, else false.

If window actually closes, then this KIWAY marks it as not opened internally.

Returns
true if the window is closed and not vetoed, else false.

Definition at line 413 of file kiway.cpp.

414 {
415  // Since this will be called from python, cannot assume that code will
416  // not pass a bad aFrameType.
417  if( (unsigned) aFrameType >= KIWAY_PLAYER_COUNT )
418  {
419  // @todo : throw an exception here for python's benefit, at least that
420  // way it gets some explanatory text.
421 
422  wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
423  return false;
424  }
425 
426  KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
427 
428  if( frame == NULL ) // Already closed
429  return true;
430 
431  if( frame->NonUserClose( doForce ) )
432  return true;
433 
434  return false;
435 }
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition: kiway.cpp:348
#define NULL
bool NonUserClose(bool aForce)

References GetPlayerFrame(), KIWAY_PLAYER_COUNT, EDA_BASE_FRAME::NonUserClose(), and NULL.

Referenced by PlayersClose().

◆ PlayersClose()

bool KIWAY::PlayersClose ( bool  doForce)
virtual

Call the KIWAY_PLAYER::Close( bool force ) function on all the windows and if none are vetoed, returns true, else false.

If any window actually closes, then* this KIWAY marks it as not opened internally.

Returns
true indicates that all windows closed because none were vetoed, false means at least one cast a veto. Any that cast a veto are still open.

Definition at line 438 of file kiway.cpp.

439 {
440  bool ret = true;
441 
442  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
443  {
444  ret = ret && PlayerClose( FRAME_T( i ), doForce );
445  }
446 
447  return ret;
448 }
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
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:413

References KIWAY_PLAYER_COUNT, and PlayerClose().

◆ Prj()

PROJECT & KIWAY::Prj ( ) const
virtual

Return the PROJECT associated with this KIWAY.

This is here as an accessor, so that there is freedom to put the actual PROJECT storage in a place decided by the implementation, and not known to the caller.

Definition at line 173 of file kiway.cpp.

174 {
175  return Pgm().GetSettingsManager().Prj();
176 }
virtual PROJECT & Prj() const
Return the PROJECT associated with this KIWAY.
Definition: kiway.cpp:173
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106

References Pgm(), and Prj().

Referenced by PCB::IFACE::CreateWindow(), SYMBOL_PREVIEW_WIDGET::DisplaySymbol(), FOOTPRINT_LIST::GetInstance(), InvokePcbLibTableEditor(), InvokeSchEditSymbolLibTable(), LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER(), KIWAY_HOLDER::Prj(), Prj(), Prj(), and LIB_TREE_MODEL_ADAPTER::SavePinnedItems().

◆ ProcessEvent()

bool KIWAY::ProcessEvent ( wxEvent &  aEvent)
override

Definition at line 573 of file kiway.cpp.

574 {
575  KIWAY_EXPRESS* mail = dynamic_cast<KIWAY_EXPRESS*>( &aEvent );
576 
577  if( mail )
578  {
579  FRAME_T dest = mail->Dest();
580 
581  // see if recipient is alive
582  KIWAY_PLAYER* alive = Player( dest, false );
583 
584  if( alive )
585  {
586 #if 1
587  return alive->ProcessEvent( aEvent );
588 #else
589  alive->KiwayMailIn( *mail );
590  return true;
591 #endif
592  }
593  }
594 
595  return false;
596 }
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
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:357
virtual void KiwayMailIn(KIWAY_EXPRESS &aEvent)
Receive KIWAY_EXPRESS messages from other players.
FRAME_T Dest()
Return the destination player id of the message.
Definition: kiway_express.h:44
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.

References KIWAY_EXPRESS::Dest(), KIWAY_PLAYER::KiwayMailIn(), Player(), and EDA_BASE_FRAME::ProcessEvent().

Referenced by ExpressMail().

◆ ProjectChanged()

void KIWAY::ProjectChanged ( )
virtual

Calls ProjectChanged() on all KIWAY_PLAYERs.

Used after changing the project to ensure all players are updated correctly.

Definition at line 550 of file kiway.cpp.

551 {
553  {
554  // A dynamic_cast could be better, but creates link issues
555  // (some basic_frame functions not found) on some platforms,
556  // so a static_cast is used.
557  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
558 
559  if( top )
560  top->ProjectChanged();
561  }
562 
563  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
564  {
565  KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
566 
567  if( frame )
568  frame->ProjectChanged();
569  }
570 }
#define KFCTL_CPP_PROJECT_SUITE
Running under C++ project mgr, possibly with others.
Definition: kiway.h:156
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
KIWAY_PLAYER * GetPlayerFrame(FRAME_T aFrameType)
Definition: kiway.cpp:348
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
int m_ctl
Definition: kiway.h:423
The base frame for deriving all KiCad main window classes.
virtual void ProjectChanged()
Notification event that the project has changed.
wxFrame * m_top
Definition: kiway.h:425

References GetPlayerFrame(), KFCTL_CPP_PROJECT_SUITE, KIWAY_PLAYER_COUNT, m_ctl, m_top, and EDA_BASE_FRAME::ProjectChanged().

Referenced by SETTINGS_MANAGER::LoadProject(), and SETTINGS_MANAGER::UnloadProject().

◆ set_kiface()

bool KIWAY::set_kiface ( FACE_T  aFaceType,
KIFACE aKiface 
)
inlineprivate

Definition at line 402 of file kiway.h.

403  {
404  if( (unsigned) aFaceType < (unsigned) KIWAY_FACE_COUNT )
405  {
406  m_kiface[aFaceType] = aKiface;
407  return true;
408  }
409 
410  return false;
411  }
static KIFACE * m_kiface[KIWAY_FACE_COUNT]
Definition: kiway.h:419

References KIWAY_FACE_COUNT, and m_kiface.

Referenced by PGM_SINGLE_TOP::OnPgmInit().

◆ SetLanguage()

void KIWAY::SetLanguage ( int  aLanguage)
virtual

Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.

Definition at line 459 of file kiway.cpp.

460 {
461  wxString errMsg;
462  bool ret = false;
463 
464  {
465  // Only allow the traces to be logged by wx. We use our own system to log when the
466  // OS doesn't support the language, so we want to hide the wx error.
467  WX_LOG_TRACE_ONLY logtraceOnly;
468  Pgm().SetLanguageIdentifier( aLanguage );
469  ret = Pgm().SetLanguage( errMsg );
470  }
471 
472  if( !ret )
473  {
474  wxString lang;
475 
476  for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
477  {
478  if( aLanguage == LanguagesList[ii].m_KI_Lang_Identifier )
479  {
480  if( LanguagesList[ii].m_DoNotTranslate )
481  lang = LanguagesList[ii].m_Lang_Label;
482  else
483  lang = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
484 
485  break;
486  }
487  }
488 
489  DisplayErrorMessage( nullptr,
490  wxString::Format( _( "Unable to switch language to %s" ), lang ),
491  errMsg );
492  return;
493  }
494 
495 #if 1
496  // This is a risky hack that goes away if we allow the language to be
497  // set only from the top most frame if !Kiface.IsSingle()
498 
499  // Only for the C++ project manager, and not for the python one and not for
500  // single_top do we look for the EDA_BASE_FRAME as the top level window.
501  // For single_top this is not needed because that window is registered in
502  // the array below.
504  {
505  // A dynamic_cast could be better, but creates link issues
506  // (some basic_frame functions not found) on some platforms,
507  // so a static_cast is used.
508  EDA_BASE_FRAME* top = static_cast<EDA_BASE_FRAME*>( m_top );
509 
510  if( top )
511  top->ShowChangedLanguage();
512  }
513 #endif
514 
515  for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
516  {
517  KIWAY_PLAYER* frame = GetPlayerFrame( ( FRAME_T )i );
518 
519  if( frame )
520  {
521  frame->ShowChangedLanguage();
522  }
523  }
524 }
#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
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
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:348
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.h:62
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition: kiway.cpp:459
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
int m_ctl
Definition: kiway.h:423
wxString m_Lang_Label
Labels used in menus.
Definition: pgm_base.h:65
A logger class that filters out all log messages that are not generated by wxLogTrace and ignores the...
Definition: logging.h:31
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
#define _(s)
Definition: 3d_actions.cpp:33
The base frame for deriving all KiCad main window classes.
wxFrame * m_top
Definition: kiway.h:425
virtual void ShowChangedLanguage()
Redraw the menus and what not in current language.

References _, DisplayErrorMessage(), Format(), GetPlayerFrame(), KFCTL_CPP_PROJECT_SUITE, KIWAY_PLAYER_COUNT, LanguagesList, m_ctl, LANGUAGE_DESCR::m_KI_Lang_Identifier, LANGUAGE_DESCR::m_Lang_Label, m_top, Pgm(), SetLanguage(), and EDA_BASE_FRAME::ShowChangedLanguage().

Referenced by KICAD_MANAGER_FRAME::language_change(), KIWAY_PLAYER::language_change(), and SetLanguage().

◆ SetTop()

void KIWAY::SetTop ( wxFrame *  aTop)

Tell this KIWAY about the top most frame in the program and optionally allows it to play the role of one of the KIWAY_PLAYERs if launched from single_top.cpp.

Parameters
aTopis the top most wxFrame in the entire program.

Definition at line 81 of file kiway.cpp.

82 {
83 #if 0
84  if( m_top )
85  {
86  m_top->Disconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this );
87  }
88 
89  if( aTop )
90  {
91  aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::player_destroy_handler ), NULL, this );
92  }
93 #endif
94 
95  m_top = aTop;
96 }
#define NULL
wxFrame * m_top
Definition: kiway.h:425

References m_top, and NULL.

Referenced by KIWAY(), PGM_KICAD::OnPgmInit(), and PGM_SINGLE_TOP::OnPgmInit().

Friends And Related Function Documentation

◆ PGM_SINGLE_TOP

friend struct PGM_SINGLE_TOP
friend

Definition at line 262 of file kiway.h.

Member Data Documentation

◆ m_ctl

int KIWAY::m_ctl
private

◆ m_kiface

KIFACE * KIWAY::m_kiface
staticprivate

Definition at line 419 of file kiway.h.

Referenced by KiFACE(), OnKiwayEnd(), and set_kiface().

◆ m_kiface_version

int KIWAY::m_kiface_version
staticprivate

Definition at line 420 of file kiway.h.

Referenced by KiFACE().

◆ m_playerFrameName

wxArrayString KIWAY::m_playerFrameName
private

Definition at line 433 of file kiway.h.

Referenced by GetPlayerFrame(), KIWAY(), and Player().

◆ m_program

PGM_BASE* KIWAY::m_program
private

Definition at line 422 of file kiway.h.

Referenced by KiFACE().

◆ m_top

wxFrame* KIWAY::m_top
private

Definition at line 425 of file kiway.h.

Referenced by CommonSettingsChanged(), OnKiCadExit(), ProjectChanged(), SetLanguage(), and SetTop().


The documentation for this class was generated from the following files: