KiCad PCB EDA Suite
kiway_player.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-2017 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 
26 #include <pgm_base.h>
27 #include <kiway_player.h>
28 #include <kiway_express.h>
29 #include <kiway.h>
30 #include <id.h>
31 #include <macros.h>
32 #include <typeinfo>
33 #include <wx/utils.h>
34 #include <wx/evtloop.h>
35 
36 
37 BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME )
38  EVT_KIWAY_EXPRESS( KIWAY_PLAYER::kiway_express )
41  KIWAY_PLAYER::OnChangeIconsOptions )
42 END_EVENT_TABLE()
43 
44 
45 KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
46  const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
47  long aStyle, const wxString& aWdoName ) :
48  EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ),
49  KIWAY_HOLDER( aKiway ),
50  m_modal( false ),
51  m_modal_loop( 0 ), m_modal_resultant_parent( 0 )
52 {
53  // DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );)
54  m_modal_ret_val = 0;
55 }
56 
57 
58 KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle,
59  const wxPoint& aPos, const wxSize& aSize, long aStyle,
60  const wxString& aWdoName ) :
61  EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ),
62  KIWAY_HOLDER( 0 ),
63  m_modal( false ),
64  m_modal_loop( 0 ),
65  m_modal_resultant_parent( 0 ),
66  m_modal_ret_val( false )
67 {
68  // DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );)
69 }
70 
71 
73 
74 
76 {
77  // override this in derived classes.
78 }
79 
80 
81 bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow )
82 {
83  wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) );
84 
85  /*
86  This function has a nice interface but a necessarily unsightly implementation.
87  Now the implementation is encapsulated, localizing future changes.
88 
89  It works in tandem with DismissModal(). But only ShowModal() is in the
90  vtable and therefore cross-module capable.
91  */
92 
93  // This is an exception safe way to zero a pointer before returning.
94  // Yes, even though DismissModal() clears this first normally, this is
95  // here in case there's an exception before the dialog is dismissed.
96  struct NULLER
97  {
98  void*& m_what;
99  NULLER( void*& aPtr ) : m_what( aPtr ) {}
100  ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction
101  } clear_this( (void*&) m_modal_loop );
102 
103 
104  m_modal_resultant_parent = aResultantFocusWindow;
105 
106  Show( true );
107  Raise(); // Needed on some Window managers to always display the frame
108 
109  SetFocus();
110 
111  {
112  // We have to disable all frames but the the modal one.
113  // wxWindowDisabler does that, but it also disables all top level windows
114  // We do not want to disable top level windows which are child of the modal one,
115  // if they are enabled.
116  // An example is an aui toolbar which was moved
117  // or a dialog or an other frame or miniframe opened by the modal one.
118  wxWindowList wlist = GetChildren();
119  std::vector<wxWindow*> enabledTopLevelWindows;
120 
121  for( unsigned ii = 0; ii < wlist.size(); ii++ )
122  if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
123  enabledTopLevelWindows.push_back( wlist[ii] );
124 
125  // exception safe way to disable all top level windows except the modal one,
126  // re-enables only those that were disabled on exit
127  wxWindowDisabler toggle( this );
128 
129  for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
130  enabledTopLevelWindows[ii]->Enable( true );
131 
132  WX_EVENT_LOOP event_loop;
133  m_modal_loop = &event_loop;
134  event_loop.Run();
135 
136  } // End of scope for some variables.
137  // End nesting before setting focus below.
138 
139  if( aResult )
140  *aResult = m_modal_string;
141 
142  DBG(printf( "~%s: aResult:'%s' ret:%d\n",
143  __func__, TO_UTF8( m_modal_string ), m_modal_ret_val );)
144 
145  if( aResultantFocusWindow )
146  {
147  aResultantFocusWindow->Raise();
148 
149  // have the final say, after wxWindowDisabler reenables my parent and
150  // the events settle down, set the focus
151  wxSafeYield();
152  aResultantFocusWindow->SetFocus();
153  }
154 
155  return m_modal_ret_val;
156 }
157 
159 {
160  return EDA_BASE_FRAME::Destroy();
161 }
162 
164 {
165  bool ret = !m_modal_loop;
166 
167  DBG(printf( "%s: ret:%d\n", __func__, ret );)
168 
169  return ret;
170 }
171 
172 
173 void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult )
174 {
175  m_modal_ret_val = aRetVal;
176  m_modal_string = aResult;
177 
178  if( m_modal_loop )
179  {
180  m_modal_loop->Exit();
181  m_modal_loop = 0; // this marks it as dismissed.
182  }
183 
184  Show( false );
185 }
186 
187 
189 {
190  // logging support
191 #if defined(DEBUG)
192  const char* class_name = typeid( this ).name();
193 
194  printf( "%s: received cmd:%d pay:'%s'\n", class_name,
195  aEvent.Command(), aEvent.GetPayload().c_str() );
196 #endif
197 
198  KiwayMailIn( aEvent ); // call the virtual, override in derived.
199 }
200 
201 
202 void KIWAY_PLAYER::language_change( wxCommandEvent& event )
203 {
204  int id = event.GetId();
205 
206  // tell all the KIWAY_PLAYERs about the language change.
207  Kiway().SetLanguage( id );
208 }
209 
210 
211 void KIWAY_PLAYER::OnChangeIconsOptions( wxCommandEvent& event )
212 {
215 }
Class KIWAY_HOLDER is a mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_player.h:48
bool m_modal_ret_val
Definition: kiway_player.h:293
Class KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a porti...
Definition: kiway_player.h:111
Class KIWAY_EXPRESS carries a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:39
#define WX_EVENT_LOOP
Definition: kiway_player.h:91
wxWindow * m_modal_resultant_parent
Definition: kiway_player.h:291
ID_LANGUAGE_CHOICE_END
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
wxString m_modal_string
Definition: kiway_player.h:292
bool IsDismissed()
Function IsDismissed returns false only if both the frame is acting in modal mode and it has not been...
KIWAY_PLAYER(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aWdoName=wxFrameNameStr)
FRAME_T
Enum FRAME_T is the set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:34
virtual void OnChangeIconsOptions(wxCommandEvent &event)
Function OnChangeIconsOptions Selects the current icons options in menus (or toolbars) in Kicad (the ...
Definition: basicframe.cpp:681
VTBL_ENTRY void SetLanguage(int aLanguage)
Function SetLanguage changes the language and then calls ShowChangedLanguage() on all KIWAY_PLAYERs...
Definition: kiway.cpp:396
VTBL_ENTRY void ShowChangedIcons()
Function ShowChangedIcons Calls ShowChangedIcons() on all KIWAY_PLAYERs.
Definition: kiway.cpp:432
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
void language_change(wxCommandEvent &event)
Function language_change is an event handler called on a language menu selection. ...
#define EVT_KIWAY_EXPRESS(func)
Definition: kiway_express.h:97
KICAD_MANAGER_FRAME::language_change ID_KICAD_SELECT_ICON_OPTIONS_END
bool Enable(bool enable) override
Definition: basicframe.cpp:211
Class KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within...
Definition: kiway.h:257
virtual void KiwayMailIn(KIWAY_EXPRESS &aEvent)
Function KiwayMailIn receives KIWAY_EXPRESS messages from other players.
void kiway_express(KIWAY_EXPRESS &aEvent)
event handler, routes to derivative specific virtual KiwayMailIn()
bool IsModal()
Definition: kiway_player.h:259
const std::string & GetPayload()
Function Payload returns the payload, which can be any text but it typicall self identifying s-expres...
Definition: kiway_express.h:62
void OnChangeIconsOptions(wxCommandEvent &event) override
Function OnChangeIconsOptions is an event handler called on a icons options in menus or toolbars menu...
see class PGM_BASE
void DismissModal(bool aRetVal, const wxString &aResult=wxEmptyString)
Class EDA_BASE_FRAME is the base frame for deriving all KiCad main window classes.
Definition: wxstruct.h:117
WX_EVENT_LOOP * m_modal_loop
Definition: kiway_player.h:290
const char * name
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
#define DBG(x)
Definition: fctsys.h:33
MAIL_T Command()
Function Command returns the MAIL_T associated with this mail.
Definition: kiway_express.h:52
EVT_MENU_RANGE(ID_KICAD_SELECT_ICONS_OPTIONS, ID_KICAD_SELECT_ICON_OPTIONS_END, KIWAY_PLAYER::OnChangeIconsOptions) KIWAY_PLAYER
VTBL_ENTRY bool ShowModal(wxString *aResult=NULL, wxWindow *aResultantFocusWindow=NULL)
Function ShowModal puts up this wxFrame as if it were a modal dialog, with all other instantiated wxF...