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 )
40 END_EVENT_TABLE()
41 
42 
43 KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
44  const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
45  long aStyle, const wxString& aWdoName ) :
46  EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ),
47  KIWAY_HOLDER( aKiway ),
48  m_modal( false ),
49  m_modal_loop( 0 ), m_modal_resultant_parent( 0 )
50 {
51  m_modal_ret_val = 0;
52 }
53 
54 
55 KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle,
56  const wxPoint& aPos, const wxSize& aSize, long aStyle,
57  const wxString& aWdoName ) :
58  EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ),
59  KIWAY_HOLDER( 0 ),
60  m_modal( false ),
61  m_modal_loop( 0 ),
62  m_modal_resultant_parent( 0 ),
63  m_modal_ret_val( false )
64 {
65 }
66 
67 
69 
70 
72 {
73  // override this in derived classes.
74 }
75 
76 
77 bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow )
78 {
79  wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) );
80 
81  /*
82  This function has a nice interface but a necessarily unsightly implementation.
83  Now the implementation is encapsulated, localizing future changes.
84 
85  It works in tandem with DismissModal(). But only ShowModal() is in the
86  vtable and therefore cross-module capable.
87  */
88 
89  // This is an exception safe way to zero a pointer before returning.
90  // Yes, even though DismissModal() clears this first normally, this is
91  // here in case there's an exception before the dialog is dismissed.
92  struct NULLER
93  {
94  void*& m_what;
95  NULLER( void*& aPtr ) : m_what( aPtr ) {}
96  ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction
97  } clear_this( (void*&) m_modal_loop );
98 
99 
100  m_modal_resultant_parent = aResultantFocusWindow;
101 
102  Show( true );
103  Raise(); // Needed on some Window managers to always display the frame
104 
105  SetFocus();
106 
107  {
108  // We have to disable all frames but the the modal one.
109  // wxWindowDisabler does that, but it also disables all top level windows
110  // We do not want to disable top level windows which are child of the modal one,
111  // if they are enabled.
112  // An example is an aui toolbar which was moved
113  // or a dialog or another frame or miniframe opened by the modal one.
114  wxWindowList wlist = GetChildren();
115  std::vector<wxWindow*> enabledTopLevelWindows;
116 
117  for( unsigned ii = 0; ii < wlist.size(); ii++ )
118  if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
119  enabledTopLevelWindows.push_back( wlist[ii] );
120 
121  // exception safe way to disable all top level windows except the modal one,
122  // re-enables only those that were disabled on exit
123  wxWindowDisabler toggle( this );
124 
125  for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
126  enabledTopLevelWindows[ii]->Enable( true );
127 
128  WX_EVENT_LOOP event_loop;
129  m_modal_loop = &event_loop;
130  event_loop.Run();
131 
132  } // End of scope for some variables.
133  // End nesting before setting focus below.
134 
135  if( aResult )
136  *aResult = m_modal_string;
137 
138  if( aResultantFocusWindow )
139  {
140  aResultantFocusWindow->Raise();
141 
142  // have the final say, after wxWindowDisabler reenables my parent and
143  // the events settle down, set the focus
144  wxSafeYield();
145  aResultantFocusWindow->SetFocus();
146  }
147 
148  return m_modal_ret_val;
149 }
150 
152 {
153  return EDA_BASE_FRAME::Destroy();
154 }
155 
157 {
158  return !m_modal_loop;
159 }
160 
161 
162 void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult )
163 {
164  m_modal_ret_val = aRetVal;
165  m_modal_string = aResult;
166 
167  if( m_modal_loop )
168  {
169  m_modal_loop->Exit();
170  m_modal_loop = 0; // this marks it as dismissed.
171  }
172 
173  Show( false );
174 }
175 
176 
178 {
179  // logging support
180  KiwayMailIn( aEvent ); // call the virtual, override in derived.
181 }
182 
183 
184 void KIWAY_PLAYER::language_change( wxCommandEvent& event )
185 {
186  int id = event.GetId();
187 
188  // tell all the KIWAY_PLAYERs about the language change.
189  Kiway().SetLanguage( id );
190 }
191 
192 
Class KIWAY_HOLDER is a mix in class which holds the location of a wxWindow&#39;s KIWAY.
Definition: kiway_player.h:48
bool m_modal_ret_val
Definition: kiway_player.h:253
Class KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a porti...
Definition: kiway_player.h:120
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:100
wxWindow * m_modal_resultant_parent
Definition: kiway_player.h:251
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:252
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
EVT_MENU_RANGE(ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::language_change) EVT_UPDATE_UI_RANGE(ID_TO_SCH
VTBL_ENTRY void SetLanguage(int aLanguage)
Function SetLanguage changes the language and then calls ShowChangedLanguage() on all KIWAY_PLAYERs...
Definition: kiway.cpp:395
This file contains miscellaneous commonly used macros and functions.
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
Class KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within...
Definition: kiway.h:258
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:226
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.
WX_EVENT_LOOP * m_modal_loop
Definition: kiway_player.h:250
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
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...