You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							191 lines
						
					
					
						
							5.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							191 lines
						
					
					
						
							5.8 KiB
						
					
					
				
								/*
							 | 
						|
								 * This program source code file is part of KiCad, a free EDA CAD application.
							 | 
						|
								 *
							 | 
						|
								 * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
							 | 
						|
								 * Copyright (C) 2014-2017 KiCad Developers, see AUTHORS.txt for contributors.
							 | 
						|
								 *
							 | 
						|
								 * This program is free software; you can redistribute it and/or
							 | 
						|
								 * modify it under the terms of the GNU General Public License
							 | 
						|
								 * as published by the Free Software Foundation; either version 2
							 | 
						|
								 * of the License, or (at your option) any later version.
							 | 
						|
								 *
							 | 
						|
								 * This program is distributed in the hope that it will be useful,
							 | 
						|
								 * but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						|
								 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						|
								 * GNU General Public License for more details.
							 | 
						|
								 *
							 | 
						|
								 * You should have received a copy of the GNU General Public License
							 | 
						|
								 * along with this program; if not, you may find one here:
							 | 
						|
								 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
							 | 
						|
								 * or you may search the http://www.gnu.org website for the version 2 license,
							 | 
						|
								 * or you may write to the Free Software Foundation, Inc.,
							 | 
						|
								 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#include <pgm_base.h>
							 | 
						|
								#include <kiway_player.h>
							 | 
						|
								#include <kiway_express.h>
							 | 
						|
								#include <kiway.h>
							 | 
						|
								#include <id.h>
							 | 
						|
								#include <macros.h>
							 | 
						|
								#include <typeinfo>
							 | 
						|
								#include <wx/utils.h>
							 | 
						|
								#include <wx/evtloop.h>
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME )
							 | 
						|
								    EVT_KIWAY_EXPRESS( KIWAY_PLAYER::kiway_express )
							 | 
						|
								    EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KIWAY_PLAYER::language_change )
							 | 
						|
								END_EVENT_TABLE()
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
							 | 
						|
								        const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
							 | 
						|
								        long aStyle, const wxString& aWdoName ) :
							 | 
						|
								    EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName, aKiway ),
							 | 
						|
								    m_modal( false ),
							 | 
						|
								    m_modal_loop( 0 ),
							 | 
						|
								    m_modal_resultant_parent( 0 )
							 | 
						|
								{
							 | 
						|
								    m_modal_ret_val = 0;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle,
							 | 
						|
								        const wxPoint& aPos, const wxSize& aSize, long aStyle,
							 | 
						|
								        const wxString& aWdoName ) :
							 | 
						|
								    EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName, nullptr ),
							 | 
						|
								    m_modal( false ),
							 | 
						|
								    m_modal_loop( 0 ),
							 | 
						|
								    m_modal_resultant_parent( 0 ),
							 | 
						|
								    m_modal_ret_val( false )
							 | 
						|
								{
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								KIWAY_PLAYER::~KIWAY_PLAYER() throw() {}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent )
							 | 
						|
								{
							 | 
						|
								    // override this in derived classes.
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow )
							 | 
						|
								{
							 | 
						|
								    wxASSERT_MSG( IsModal(), wxT( "ShowModal() shouldn't be called on non-modal frame" ) );
							 | 
						|
								
							 | 
						|
								    /*
							 | 
						|
								        This function has a nice interface but a necessarily unsightly implementation.
							 | 
						|
								        Now the implementation is encapsulated, localizing future changes.
							 | 
						|
								
							 | 
						|
								        It works in tandem with DismissModal().  But only ShowModal() is in the
							 | 
						|
								        vtable and therefore cross-module capable.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								    // This is an exception safe way to zero a pointer before returning.
							 | 
						|
								    // Yes, even though DismissModal() clears this first normally, this is
							 | 
						|
								    // here in case there's an exception before the dialog is dismissed.
							 | 
						|
								    struct NULLER
							 | 
						|
								    {
							 | 
						|
								        void*&  m_what;
							 | 
						|
								        NULLER( void*& aPtr ) : m_what( aPtr ) {}
							 | 
						|
								        ~NULLER() { m_what = 0; }   // indeed, set it to NULL on destruction
							 | 
						|
								    } clear_this( (void*&) m_modal_loop );
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								    m_modal_resultant_parent = aResultantFocusWindow;
							 | 
						|
								
							 | 
						|
								    Show( true );
							 | 
						|
								    Raise();    // Needed on some Window managers to always display the frame
							 | 
						|
								
							 | 
						|
								    SetFocus();
							 | 
						|
								
							 | 
						|
								    {
							 | 
						|
								        // We have to disable all frames but the the modal one.
							 | 
						|
								        // wxWindowDisabler does that, but it also disables all top level windows
							 | 
						|
								        // We do not want to disable top level windows which are child of the modal one,
							 | 
						|
								        // if they are enabled.
							 | 
						|
								        // An example is an aui toolbar which was moved
							 | 
						|
								        // or a dialog or another frame or miniframe opened by the modal one.
							 | 
						|
								        wxWindowList wlist = GetChildren();
							 | 
						|
								        std::vector<wxWindow*> enabledTopLevelWindows;
							 | 
						|
								
							 | 
						|
								        for( unsigned ii = 0; ii < wlist.size(); ii++ )
							 | 
						|
								            if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
							 | 
						|
								                enabledTopLevelWindows.push_back( wlist[ii] );
							 | 
						|
								
							 | 
						|
								        // exception safe way to disable all top level windows except the modal one,
							 | 
						|
								        // re-enables only those that were disabled on exit
							 | 
						|
								        wxWindowDisabler toggle( this );
							 | 
						|
								
							 | 
						|
								        for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
							 | 
						|
								            enabledTopLevelWindows[ii]->Enable( true );
							 | 
						|
								
							 | 
						|
								        WX_EVENT_LOOP event_loop;
							 | 
						|
								        m_modal_loop = &event_loop;
							 | 
						|
								        event_loop.Run();
							 | 
						|
								
							 | 
						|
								    }   // End of scope for some variables.
							 | 
						|
								        // End nesting before setting focus below.
							 | 
						|
								
							 | 
						|
								    if( aResult )
							 | 
						|
								        *aResult = m_modal_string;
							 | 
						|
								
							 | 
						|
								    if( aResultantFocusWindow )
							 | 
						|
								    {
							 | 
						|
								        aResultantFocusWindow->Raise();
							 | 
						|
								
							 | 
						|
								        // have the final say, after wxWindowDisabler reenables my parent and
							 | 
						|
								        // the events settle down, set the focus
							 | 
						|
								        wxSafeYield();
							 | 
						|
								        aResultantFocusWindow->SetFocus();
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return m_modal_ret_val;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								bool KIWAY_PLAYER::Destroy()
							 | 
						|
								{
							 | 
						|
								    return EDA_BASE_FRAME::Destroy();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								bool KIWAY_PLAYER::IsDismissed()
							 | 
						|
								{
							 | 
						|
								    return !m_modal_loop;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void KIWAY_PLAYER::DismissModal( bool aRetVal, const wxString& aResult )
							 | 
						|
								{
							 | 
						|
								    m_modal_ret_val = aRetVal;
							 | 
						|
								    m_modal_string  = aResult;
							 | 
						|
								
							 | 
						|
								    if( m_modal_loop )
							 | 
						|
								    {
							 | 
						|
								        m_modal_loop->Exit();
							 | 
						|
								        m_modal_loop = 0;      // this marks it as dismissed.
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    Show( false );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void KIWAY_PLAYER::kiway_express( KIWAY_EXPRESS& aEvent )
							 | 
						|
								{
							 | 
						|
								    // logging support
							 | 
						|
								    KiwayMailIn( aEvent );     // call the virtual, override in derived.
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void KIWAY_PLAYER::language_change( wxCommandEvent& event )
							 | 
						|
								{
							 | 
						|
								    int id = event.GetId();
							 | 
						|
								
							 | 
						|
								    // tell all the KIWAY_PLAYERs about the language change.
							 | 
						|
								    Kiway().SetLanguage( id );
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 |