From 020a0ae4771f79c3526f0790814449df9a422535 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 29 Aug 2014 19:49:49 +0200 Subject: [PATCH] All: Fix crash on close Kicad, when a quasi modal dialog is open, and Kicad is closed from the Kicad project manager. --- common/basicframe.cpp | 34 ++++++++++++++++++++++++++++++++++ eeschema/schframe.cpp | 2 +- include/wxstruct.h | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 382c9c9164..f97a71cb5b 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -107,6 +108,39 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event ) { + DIALOG_SHIM* dlg = NULL; + wxWindowList list = GetChildren(); + + // Quasi modal dialogs create issues (crashes) when closing Kicad. + // I am guessing they are delete too late, when deleting main frames. + // AFAIK, only these DIALOG_SHIM dialogs create such issues. + // The policy is do not allow closing Kicad if a Quasi modal dialog is open. + // (Anyway, closing without prompting the user is certainly bad, + // because an edit is in preogress) + // Therefore, iterate through the child list to find at least + // a DIALOG_SHIM opened in quasi modal mode + for( wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter ) + { + if( (dlg = dynamic_cast (*iter) ) != NULL ) + { + if( dlg->IsQuasiModal() ) + break; + else + dlg = NULL; + } + } + + if( dlg ) + { + // Happens when a quasi modal dialog is currently open. + // For example: if the Kicad manager try to close Kicad. + wxMessageBox( _( + "The program cannot be closed\n" + "A quasi-modal dialog window is currently open, please close it first." ) ); + event.Veto(); + return; + } + wxConfigBase* cfg = config(); if( cfg ) diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index cc4d5b463a..e95c27ac32 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -617,7 +617,7 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) } } - // Close the find dialog and perserve it's setting if it is displayed. + // Close the find dialog and preserve it's setting if it is displayed. if( m_dlgFindReplace ) { m_findDialogPosition = m_dlgFindReplace->GetPosition(); diff --git a/include/wxstruct.h b/include/wxstruct.h index 416ddb625f..b0478a1a1e 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -107,7 +107,7 @@ class EDA_BASE_FRAME : public wxFrame * SaveSettings(). SaveSettings() is called for all derived wxFrames in this * base class overload. (Calling it from a destructor is deprecated since the * wxFrame's position is not available in the destructor on linux.) In other words, - * you should not need to call call SaveSettings() anywhere, except in this + * you should not need to call SaveSettings() anywhere, except in this * one function found only in this class. */ void windowClosing( wxCloseEvent& event );