From 4d955fda7ea6225a20f27aa452c306fa0bdbd469 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Sun, 4 May 2014 14:57:44 -0500 Subject: [PATCH] wx 2.8 now builds, but the quasi-modal support seems broken on 2.8. Wanted others to be able to build at least. --- common/basicframe.cpp | 2 + common/dialog_shim.cpp | 87 +++++++++++++++++++++++++++++++++++++---- common/kiway_player.cpp | 2 +- include/dialog_shim.h | 16 +++++++- include/kiway_player.h | 12 +++++- 5 files changed, 108 insertions(+), 11 deletions(-) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 2fb7d4c604..dbcf15d9f9 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -153,6 +153,8 @@ bool EDA_BASE_FRAME::ProcessEvent( wxEvent& aEvent ) bool EDA_BASE_FRAME::Enable( bool enable ) { + // so we can do logging of this state change: + #if defined(DEBUG) const char* type_id = typeid( *this ).name(); printf( "wxFrame %s: %s\n", type_id, enable ? "enabled" : "disabled" ); diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index 8c1d94e794..548a91cdb4 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -130,6 +130,8 @@ bool DIALOG_SHIM::Show( bool show ) bool DIALOG_SHIM::Enable( bool enable ) { + // so we can do logging of this state change: + #if defined(DEBUG) const char* type_id = typeid( *this ).name(); printf( "wxDialog %s: %s\n", type_id, enable ? "enabled" : "disabled" ); @@ -139,6 +141,73 @@ bool DIALOG_SHIM::Enable( bool enable ) } +#if !wxCHECK_VERSION( 2, 9, 4 ) +wxWindow* DIALOG_SHIM::CheckIfCanBeUsedAsParent( wxWindow* parent ) const +{ + if ( !parent ) + return NULL; + + extern WXDLLIMPEXP_DATA_BASE(wxList) wxPendingDelete; + + if ( wxPendingDelete.Member(parent) || parent->IsBeingDeleted() ) + { + // this window is being deleted and we shouldn't create any children + // under it + return NULL; + } + + if ( parent->GetExtraStyle() & wxWS_EX_TRANSIENT ) + { + // this window is not being deleted yet but it's going to disappear + // soon so still don't parent this window under it + return NULL; + } + + if ( !parent->IsShownOnScreen() ) + { + // using hidden parent won't work correctly neither + return NULL; + } + + // FIXME-VC6: this compiler requires an explicit const cast or it fails + // with error C2446 + if ( const_cast(parent) == this ) + { + // not sure if this can really happen but it doesn't hurt to guard + // against this clearly invalid situation + return NULL; + } + + return parent; +} + + +wxWindow* DIALOG_SHIM::GetParentForModalDialog(wxWindow *parent, long style) const +{ + // creating a parent-less modal dialog will result (under e.g. wxGTK2) + // in an unfocused dialog, so try to find a valid parent for it unless we + // were explicitly asked not to + if ( style & wxDIALOG_NO_PARENT ) + return NULL; + + // first try the given parent + if ( parent ) + parent = CheckIfCanBeUsedAsParent(wxGetTopLevelParent(parent)); + + // then the currently active window + if ( !parent ) + parent = CheckIfCanBeUsedAsParent( + wxGetTopLevelParent(wxGetActiveWindow())); + + // and finally the application main window + if ( !parent ) + parent = CheckIfCanBeUsedAsParent(wxTheApp->GetTopWindow()); + + return parent; +} +#endif + + int DIALOG_SHIM::ShowQuasiModal() { // toggle a window's "enable" status to disabled, then enabled on exit. @@ -147,7 +216,14 @@ int DIALOG_SHIM::ShowQuasiModal() { wxWindow* m_win; ENABLE_DISABLE( wxWindow* aWindow ) : m_win( aWindow ) { if( m_win ) m_win->Disable(); } - ~ENABLE_DISABLE() { if( m_win ) m_win->Enable(); } + ~ENABLE_DISABLE() + { + if( m_win ) + { + m_win->Enable(); + m_win->SetFocus(); // let's focus back on the parent window + } + } }; // This is an exception safe way to zero a pointer before returning. @@ -168,7 +244,7 @@ int DIALOG_SHIM::ShowQuasiModal() if( win ) win->ReleaseMouse(); - wxWindow* parent = GetParentForModalDialog(); + wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() ); ENABLE_DISABLE toggle( parent ); @@ -176,16 +252,13 @@ int DIALOG_SHIM::ShowQuasiModal() m_qmodal_showing = true; - wxGUIEventLoop event_loop; + WX_EVENT_LOOP event_loop; wxEventLoopActivator event_loop_stacker( &event_loop ); m_qmodal_loop = &event_loop; event_loop.Run(); - if( toggle.m_win ) // let's focus back on the parent window - toggle.m_win->SetFocus(); - return GetReturnCode(); } @@ -233,7 +306,7 @@ static bool findWindowRecursively( const wxWindowList& children, const wxWindow* } -static bool findWindowReursively( const wxWindow* topmost, const wxWindow* wanted ) +static bool findWindowRecursively( const wxWindow* topmost, const wxWindow* wanted ) { // wanted may be NULL and that is ok. diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index d171744227..bd993efa0b 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -100,7 +100,7 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult ) Show( true ); - wxGUIEventLoop event_loop; + WX_EVENT_LOOP event_loop; wxEventLoopActivator event_loop_stacker( &event_loop ); m_modal_loop = &event_loop; diff --git a/include/dialog_shim.h b/include/dialog_shim.h index ae906dc97b..3e2ab62cee 100644 --- a/include/dialog_shim.h +++ b/include/dialog_shim.h @@ -35,6 +35,14 @@ #define DLGSHIM_USE_SETFOCUS 0 #endif +#if wxCHECK_VERSION( 2, 9, 4 ) + #define WX_EVENT_LOOP wxGUIEventLoop +#else + #define WX_EVENT_LOOP wxEventLoop +#endif + +class WX_EVENT_LOOP; + /** * Class DIALOG_SHIM @@ -69,10 +77,16 @@ public: bool Enable( bool enable ); // override wxDialog::Enable virtual protected: + +#if !wxCHECK_VERSION( 2, 9, 4 ) + wxWindow* CheckIfCanBeUsedAsParent( wxWindow* parent ) const; + wxWindow* GetParentForModalDialog( wxWindow *parent, long style ) const; +#endif + std::string m_hash_key; // alternate for class_map when classname re-used. // variables for quasi-modal behavior support, only used by a few derivatives. - wxGUIEventLoop* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed + WX_EVENT_LOOP* m_qmodal_loop; // points to nested event_loop, NULL means not qmodal and dismissed bool m_qmodal_showing; diff --git a/include/kiway_player.h b/include/kiway_player.h index ff20714bbc..e62981ab54 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -87,7 +87,15 @@ private: class KIWAY_EXPRESS; -class wxGUIEventLoop; + +#if wxCHECK_VERSION( 2, 9, 4 ) + #define WX_EVENT_LOOP wxGUIEventLoop +#else + #define WX_EVENT_LOOP wxEventLoop +#endif + +class WX_EVENT_LOOP; + /** * Class KIWAY_PLAYER @@ -219,7 +227,7 @@ protected: // variables for modal behavior support, only used by a few derivatives. bool m_modal; // true if frame is intended to be modal, not modeless - wxGUIEventLoop* m_modal_loop; // points to nested event_loop, NULL means not modal and dismissed + WX_EVENT_LOOP* m_modal_loop; // points to nested event_loop, NULL means not modal and dismissed wxString m_modal_string; bool m_modal_ret_val; // true if a selection was made