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 )
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, aKiway ),
47  m_modal( false ),
48  m_modal_loop( 0 ),
49  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, nullptr ),
59  m_modal( false ),
60  m_modal_loop( 0 ),
61  m_modal_resultant_parent( 0 ),
62  m_modal_ret_val( false )
63 {
64 }
65 
66 
68 
69 
71 {
72  // override this in derived classes.
73 }
74 
75 
76 bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow )
77 {
78  wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) );
79 
80  /*
81  This function has a nice interface but a necessarily unsightly implementation.
82  Now the implementation is encapsulated, localizing future changes.
83 
84  It works in tandem with DismissModal(). But only ShowModal() is in the
85  vtable and therefore cross-module capable.
86  */
87 
88  // This is an exception safe way to zero a pointer before returning.
89  // Yes, even though DismissModal() clears this first normally, this is
90  // here in case there's an exception before the dialog is dismissed.
91  struct NULLER
92  {
93  void*& m_what;
94  NULLER( void*& aPtr ) : m_what( aPtr ) {}
95  ~NULLER() { m_what = 0; } // indeed, set it to NULL on destruction
96  } clear_this( (void*&) m_modal_loop );
97 
98 
99  m_modal_resultant_parent = aResultantFocusWindow;
100 
101  Show( true );
102  Raise(); // Needed on some Window managers to always display the frame
103 
104  SetFocus();
105 
106  {
107  // We have to disable all frames but the the modal one.
108  // wxWindowDisabler does that, but it also disables all top level windows
109  // We do not want to disable top level windows which are child of the modal one,
110  // if they are enabled.
111  // An example is an aui toolbar which was moved
112  // or a dialog or another frame or miniframe opened by the modal one.
113  wxWindowList wlist = GetChildren();
114  std::vector<wxWindow*> enabledTopLevelWindows;
115 
116  for( unsigned ii = 0; ii < wlist.size(); ii++ )
117  if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
118  enabledTopLevelWindows.push_back( wlist[ii] );
119 
120  // exception safe way to disable all top level windows except the modal one,
121  // re-enables only those that were disabled on exit
122  wxWindowDisabler toggle( this );
123 
124  for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
125  enabledTopLevelWindows[ii]->Enable( true );
126 
127  WX_EVENT_LOOP event_loop;
128  m_modal_loop = &event_loop;
129  event_loop.Run();
130 
131  } // End of scope for some variables.
132  // End nesting before setting focus below.
133 
134  if( aResult )
135  *aResult = m_modal_string;
136 
137  if( aResultantFocusWindow )
138  {
139  aResultantFocusWindow->Raise();
140 
141  // have the final say, after wxWindowDisabler reenables my parent and
142  // the events settle down, set the focus
143  wxSafeYield();
144  aResultantFocusWindow->SetFocus();
145  }
146 
147  return m_modal_ret_val;
148 }
149 
151 {
152  return EDA_BASE_FRAME::Destroy();
153 }
154 
156 {
157  return !m_modal_loop;
158 }
159 
160 
161 void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult )
162 {
163  m_modal_ret_val = aRetVal;
164  m_modal_string = aResult;
165 
166  if( m_modal_loop )
167  {
168  m_modal_loop->Exit();
169  m_modal_loop = 0; // this marks it as dismissed.
170  }
171 
172  Show( false );
173 }
174 
175 
177 {
178  // logging support
179  KiwayMailIn( aEvent ); // call the virtual, override in derived.
180 }
181 
182 
183 void KIWAY_PLAYER::language_change( wxCommandEvent& event )
184 {
185  int id = event.GetId();
186 
187  // tell all the KIWAY_PLAYERs about the language change.
188  Kiway().SetLanguage( id );
189 }
190 
191 
bool m_modal_ret_val
Definition: kiway_player.h:207
KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of ...
Definition: kiway_player.h:61
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:43
wxWindow * m_modal_resultant_parent
Definition: kiway_player.h:205
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_holder.h:56
wxString m_modal_string
Definition: kiway_player.h:206
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
VTBL_ENTRY void SetLanguage(int aLanguage)
Function SetLanguage changes the language and then calls ShowChangedLanguage() on all KIWAY_PLAYERs.
Definition: kiway.cpp:445
This file contains miscellaneous commonly used macros and functions.
EVT_MENU_RANGE(ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILEMAX, GERBVIEW_FRAME::OnDrlFileHistory) EVT_MENU_RANGE(ID_GERBVIEW_ZIP_FILE1
void language_change(wxCommandEvent &event)
Function language_change is an event handler called on a language menu selection.
#define EVT_KIWAY_EXPRESS(func)
Event table definition for the KIWAY_EXPRESS event class.
Definition: kiway_express.h:95
KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the s...
Definition: kiway.h:273
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() const override
Return true if the frame is shown in our modal mode and false if the frame is shown as an usual frame...
Definition: kiway_player.h:178
see class PGM_BASE
void DismissModal(bool aRetVal, const wxString &aResult=wxEmptyString)
The base frame for deriving all KiCad main window classes.
WX_EVENT_LOOP * m_modal_loop
Definition: kiway_player.h:204
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
virtual 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...