From 65afac3fbc6115b899045d767af823fc3abd7322 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Apr 2006 00:38:49 +0000 Subject: [PATCH] added wxTLW::ShouldPreventAppExit() which can be overridden to allow closing the application even if some windows are still opened; use it for wxHtmlHelpFrame git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38607 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/tlw.tex | 11 +++++++++ include/wx/html/helpfrm.h | 4 ++++ include/wx/toplevel.h | 10 ++++++-- src/common/toplvcmn.cpp | 48 +++++++++++++++++++++++++++++++-------- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/docs/latex/wx/tlw.tex b/docs/latex/wx/tlw.tex index 91e4a75f3a..dfdf848b7a 100644 --- a/docs/latex/wx/tlw.tex +++ b/docs/latex/wx/tlw.tex @@ -263,6 +263,17 @@ Sets the window title. \helpref{wxTopLevelWindow::GetTitle}{wxtoplevelwindowgettitle} +\membersection{wxTopLevelWindow::ShouldPreventAppExit}\label{wxtoplevelwindowshouldpreventappexit} + +\constfunc{virtual bool}{ShouldPreventAppExit}{\void} + +This virtual function is not meant to be called directly but can be overridden +to return \false (it returns \true by default) to allow the application to +close even if this, presumably not very important, window is still opened. +By default, the application stays alive as long as there are any open top level +windows. + + \membersection{wxTopLevelWindow::ShowFullScreen}\label{wxtoplevelwindowshowfullscreen} \func{bool}{ShowFullScreen}{\param{bool}{ show}, \param{long}{ style = wxFULLSCREEN\_ALL}} diff --git a/include/wx/html/helpfrm.h b/include/wx/html/helpfrm.h index afe7ae849f..fa3c26e609 100644 --- a/include/wx/html/helpfrm.h +++ b/include/wx/html/helpfrm.h @@ -106,6 +106,10 @@ public: virtual void AddToolbarButtons(wxToolBar* WXUNUSED(toolBar), int WXUNUSED(style)) {}; protected: + // we don't want to prevent the app from closing just because a help window + // remains opened + virtual bool ShouldPreventAppExit() const { return false; } + void Init(wxHtmlHelpData* data = NULL); void OnCloseWindow(wxCloseEvent& event); diff --git a/include/wx/toplevel.h b/include/wx/toplevel.h index ecb99fd9cb..dbfa07ef6b 100644 --- a/include/wx/toplevel.h +++ b/include/wx/toplevel.h @@ -229,8 +229,14 @@ protected: virtual bool IsOneOfBars(const wxWindow *WXUNUSED(win)) const { return false; } - // check if we should exit the program after deleting this top level - // window (this is used in common dtor and wxMSW code) + // this function may be overridden to return false to allow closing the + // application even when this top level window is still open + // + // notice that the window is still closed prior to the application exit and + // so it can still veto it even if it returns false from here + virtual bool ShouldPreventAppExit() const { return true; } + + // check if we should exit the program after deleting this window bool IsLastBeforeExit() const; // send the iconize event, return true if processed diff --git a/src/common/toplvcmn.cpp b/src/common/toplvcmn.cpp index d99000e5e2..8441f436eb 100644 --- a/src/common/toplvcmn.cpp +++ b/src/common/toplvcmn.cpp @@ -62,13 +62,11 @@ wxTopLevelWindowBase::~wxTopLevelWindowBase() if ( wxTheApp && wxTheApp->GetTopWindow() == this ) wxTheApp->SetTopWindow(NULL); - bool shouldExit = IsLastBeforeExit(); - wxTopLevelWindows.DeleteObject(this); - if ( shouldExit ) + if ( IsLastBeforeExit() ) { - // then do it + // no other (important) windows left, quit the app wxTheApp->ExitMainLoop(); } } @@ -96,11 +94,43 @@ bool wxTopLevelWindowBase::Destroy() bool wxTopLevelWindowBase::IsLastBeforeExit() const { - // we exit the application if there are no more top level windows left - // normally but wxApp can prevent this from happening - return wxTopLevelWindows.GetCount() == 1 && - wxTopLevelWindows.GetFirst()->GetData() == (wxWindow *)this && - wxTheApp && wxTheApp->GetExitOnFrameDelete(); + // first of all, automatically exiting the app on last window close can be + // completely disabled at wxTheApp level + if ( !wxTheApp || !wxTheApp->GetExitOnFrameDelete() ) + return false; + + wxWindowList::const_iterator i; + const wxWindowList::const_iterator end = wxTopLevelWindows.end(); + + // then decide whether we should exit at all + for ( i = wxTopLevelWindows.begin(); i != end; ++i ) + { + wxTopLevelWindow * const win = wx_static_cast(wxTopLevelWindow *, *i); + if ( win->ShouldPreventAppExit() ) + { + // there remains at least one important TLW, don't exit + return false; + } + } + + // if yes, close all the other windows: this could still fail + for ( i = wxTopLevelWindows.begin(); i != end; ++i ) + { + // don't close twice the windows which are already marked for deletion + wxTopLevelWindow * const win = wx_static_cast(wxTopLevelWindow *, *i); + if ( !wxPendingDelete.Member(win) && !win->Close() ) + { + // one of the windows refused to close, don't exit + // + // NB: of course, by now some other windows could have been already + // closed but there is really nothing we can do about it as we + // have no way just to ask the window if it can close without + // forcing it to do it + return false; + } + } + + return true; } // ---------------------------------------------------------------------------- -- 2.45.2