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 <[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
26#include <kiway_player.h>
27#include <kiway_express.h>
28#include <kiway.h>
29#include <id.h>
30#include <macros.h>
31#include <typeinfo>
32#include <wx/utils.h>
33#include <wx/evtloop.h>
34#include <wx/socket.h>
35
36
37BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME )
40END_EVENT_TABLE()
41
42
43KIWAY_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& aFrameName,
46 const EDA_IU_SCALE& aIuScale ) :
47 EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName, aKiway,
48 aIuScale ),
49 m_modal( false ),
50 m_modal_loop( nullptr ),
51 m_modal_resultant_parent( nullptr ),
52 m_modal_ret_val( false ),
53 m_socketServer( nullptr )
54{
55}
56
57
58KIWAY_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, nullptr,
62 unityScale ),
63 m_modal( false ),
64 m_modal_loop( nullptr ),
65 m_modal_resultant_parent( nullptr ),
66 m_modal_ret_val( false ),
67 m_socketServer( nullptr )
68{
69}
70
71
73
74 // socket server must be destructed before we complete
75 // destructing the frame or else we could crash
76 // as the socket server holds a reference to this frame
77 if( m_socketServer )
78 {
79 // ensure any event handling stops
80 m_socketServer->Notify( false );
81
82 delete m_socketServer;
83 }
84}
85
86
88{
89 // override this in derived classes.
90}
91
92
93bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow )
94{
95 wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) );
96
97 /*
98 This function has a nice interface but a necessarily unsightly implementation.
99 Now the implementation is encapsulated, localizing future changes.
100
101 It works in tandem with DismissModal(). But only ShowModal() is in the
102 vtable and therefore cross-module capable.
103 */
104
105 // This is an exception safe way to zero a pointer before returning.
106 // Yes, even though DismissModal() clears this first normally, this is
107 // here in case there's an exception before the dialog is dismissed.
108 struct NULLER
109 {
110 void*& m_what;
111 NULLER( void*& aPtr ) : m_what( aPtr ) {}
112 ~NULLER() { m_what = nullptr; } // indeed, set it to NULL on destruction
113 } clear_this( (void*&) m_modal_loop );
114
115
116 m_modal_resultant_parent = aResultantFocusWindow;
117
118 Show( true );
119 Raise(); // Needed on some Window managers to always display the frame
120
121 SetFocus();
122
123 {
124 // We have to disable all frames but the modal one.
125 // wxWindowDisabler does that, but it also disables all top level windows
126 // We do not want to disable top level windows which are child of the modal one,
127 // if they are enabled.
128 // An example is an aui toolbar which was moved
129 // or a dialog or another frame or miniframe opened by the modal one.
130 wxWindowList wlist = GetChildren();
131 std::vector<wxWindow*> enabledTopLevelWindows;
132
133 for( unsigned ii = 0; ii < wlist.size(); ii++ )
134 {
135 if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
136 enabledTopLevelWindows.push_back( wlist[ii] );
137 }
138
139 // exception safe way to disable all top level windows except the modal one,
140 // re-enables only those that were disabled on exit
141 wxWindowDisabler toggle( this );
142
143 for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
144 enabledTopLevelWindows[ii]->Enable( true );
145
146 WX_EVENT_LOOP event_loop;
147 m_modal_loop = &event_loop;
148 event_loop.Run();
149
150 } // End of scope for some variables.
151 // End nesting before setting focus below.
152
153 if( aResult )
154 *aResult = m_modal_string;
155
156 if( aResultantFocusWindow )
157 {
158 aResultantFocusWindow->Raise();
159
160 // have the final say, after wxWindowDisabler reenables my parent and
161 // the events settle down, set the focus
162 wxSafeYield();
163 aResultantFocusWindow->SetFocus();
164 }
165
166 return m_modal_ret_val;
167}
168
169
171{
172 return EDA_BASE_FRAME::Destroy();
173}
174
175
177{
178 return !m_modal_loop;
179}
180
181
182void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult )
183{
184 m_modal_ret_val = aRetVal;
185 m_modal_string = aResult;
186
187 if( m_modal_loop )
188 {
189 m_modal_loop->Exit();
190 m_modal_loop = nullptr; // this marks it as dismissed.
191 }
192
193 Show( false );
194}
195
196
198{
199 // logging support
200 KiwayMailIn( aEvent ); // call the virtual, override in derived.
201}
202
203
204void KIWAY_PLAYER::language_change( wxCommandEvent& event )
205{
206 int id = event.GetId();
207
208 // tell all the KIWAY_PLAYERs about the language change.
209 Kiway().SetLanguage( id );
210}
211
212
213
214// LocalWords: ShowModal DismissModal vtable wxWindowDisabler aui
215// LocalWords: miniframe reenables KIWAY PLAYERs
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:112
The base frame for deriving all KiCad main window classes.
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition: kiway_express.h:39
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:66
virtual bool ShowModal(wxString *aResult=nullptr, wxWindow *aResultantFocusWindow=nullptr)
Show this wxFrame as if it were a modal dialog, with all other instantiated wxFrames disabled until t...
bool IsDismissed()
wxString m_modal_string
Definition: kiway_player.h:201
virtual void KiwayMailIn(KIWAY_EXPRESS &aEvent)
Receive KIWAY_EXPRESS messages from other players.
WX_EVENT_LOOP * m_modal_loop
< Points to nested event_loop. NULL means not modal and dismissed.
Definition: kiway_player.h:199
void language_change(wxCommandEvent &event)
An event handler called on a language menu selection.
bool m_modal_ret_val
Definition: kiway_player.h:202
void kiway_express(KIWAY_EXPRESS &aEvent)
event handler, routes to derivative specific virtual KiwayMailIn()
wxWindow * m_modal_resultant_parent
Definition: kiway_player.h:200
KIWAY_PLAYER(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, const EDA_IU_SCALE &aIuScale)
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
void DismissModal(bool aRetVal, const wxString &aResult=wxEmptyString)
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:159
wxSocketServer * m_socketServer
Definition: kiway_player.h:204
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:273
virtual void SetLanguage(int aLanguage)
Change the language and then calls ShowChangedLanguage() on all #KIWAY_PLAYERs.
Definition: kiway.cpp:504
EVT_MENU_RANGE(ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILEMAX, GERBVIEW_FRAME::OnDrlFileHistory) EVT_MENU_RANGE(ID_GERBVIEW_ZIP_FILE1
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:33
@ ID_LANGUAGE_CHOICE
Definition: id.h:105
@ ID_LANGUAGE_CHOICE_END
Definition: id.h:141
#define EVT_KIWAY_EXPRESS(func)
Event table definition for the KIWAY_EXPRESS event class.
Definition: kiway_express.h:90
#define WX_EVENT_LOOP
Definition: kiway_player.h:41
This file contains miscellaneous commonly used macros and functions.