From: Vadim Zeitlin Date: Tue, 26 Apr 2011 22:57:27 +0000 (+0000) Subject: Allow showing the print preview frame non modally. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/6aacfc7320dd6e5e145848b4f25630d675f8fb10 Allow showing the print preview frame non modally. Still show the print preview app modally by default, i.e. disabling all the other windows, but also allow disabling only the preview parent or nothing at all. Closes #13108. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67619 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 3e0b49cde7..32bd411257 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -503,6 +503,7 @@ All (GUI): - Add support for alpha channel in colours in wxSVGFileDC (snowleopard). - Allow customizing AUI tab colours in wxAuiTabArt (snowleopard). - Added wxAffineMatrix2D class (Catalin Raceanu). +- Allow showing preview frame non modally (John Roberts). GTK: diff --git a/include/wx/prntbase.h b/include/wx/prntbase.h index 1b0e68e67a..c6bdc8c00f 100644 --- a/include/wx/prntbase.h +++ b/include/wx/prntbase.h @@ -54,6 +54,19 @@ enum wxPrinterError wxPRINTER_ERROR }; +// Preview frame modality kind used with wxPreviewFrame::Initialize() +enum wxPreviewFrameModalityKind +{ + // Disable all the other top level windows while the preview is shown. + wxPreviewFrame_AppModal, + + // Disable only the parent window while the preview is shown. + wxPreviewFrame_WindowModal, + + // Don't disable any windows. + wxPreviewFrame_NonModal +}; + //---------------------------------------------------------------------------- // wxPrintFactory //---------------------------------------------------------------------------- @@ -386,7 +399,8 @@ public: virtual ~wxPreviewFrame(); void OnCloseWindow(wxCloseEvent& event); - virtual void Initialize(); + virtual void Initialize(wxPreviewFrameModalityKind kind + = wxPreviewFrame_AppModal); virtual void CreateCanvas(); virtual void CreateControlBar(); @@ -398,6 +412,9 @@ protected: wxPrintPreviewBase* m_printPreview; wxWindowDisabler* m_windowDisabler; + wxPreviewFrameModalityKind m_modalityKind; + + private: void OnChar(wxKeyEvent& event); diff --git a/interface/wx/print.h b/interface/wx/print.h index ad0ef0ea31..8eb1e3764b 100644 --- a/interface/wx/print.h +++ b/interface/wx/print.h @@ -117,7 +117,33 @@ public: void OnPaint(wxPaintEvent& event); }; +/** + Preview frame modality kind. + + The elements of this enum can be used with wxPreviewFrame::Initialize() to + indicate how should the preview frame be shown. + + @since 2.9.2 +*/ +enum wxPreviewFrameModalityKind +{ + /** + Disable all the other top level windows while the preview frame is shown. + + This is the default behaviour. + */ + wxPreviewFrame_AppModal, + /** + Disable only the parent window while the preview frame is shown. + */ + wxPreviewFrame_WindowModal, + + /** + Show the preview frame non-modally and don't disable any other windows. + */ + wxPreviewFrame_NonModal +}; /** @class wxPreviewFrame @@ -169,15 +195,24 @@ public: virtual void CreateControlBar(); /** - Creates the preview canvas and control bar, and calls wxWindow::MakeModal(@true) - to disable other top-level windows in the application. + Creates the preview canvas and control bar. + + By default also disables the other existing top level windows to + prepare for showing the preview frame modally. Since wxWidgets 2.9.2 + this can be changed by specifying either wxPreviewFrame_WindowModal -- + to disable just the parent window -- or wxPreviewFrame_NonModal -- to + not disable any windows at all -- as @a kind parameter. + + This function must be called by the application prior to showing the frame. - This function should be called by the application prior to showing the frame. + @param kind + The modality kind of preview frame. @since 2.9.2 */ - virtual void Initialize(); + virtual void Initialize(wxPreviewFrameModalityKind kind + = wxPreviewFrame_AppModal); /** - Enables the other frames in the application, and deletes the print preview + Enables any disabled frames in the application, and deletes the print preview object, implicitly deleting any printout objects associated with the print preview object. */ diff --git a/samples/printing/printing.cpp b/samples/printing/printing.cpp index 9ba62aa6cf..14f6545912 100644 --- a/samples/printing/printing.cpp +++ b/samples/printing/printing.cpp @@ -287,12 +287,17 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) #endif EVT_MENU(WXPRINT_ANGLEUP, MyFrame::OnAngleUp) EVT_MENU(WXPRINT_ANGLEDOWN, MyFrame::OnAngleDown) + + EVT_MENU_RANGE(WXPRINT_FRAME_MODAL_APP, + WXPRINT_FRAME_MODAL_NON, + MyFrame::OnPreviewFrameModalityKind) END_EVENT_TABLE() MyFrame::MyFrame(wxFrame *frame, const wxString&title, const wxPoint&pos, const wxSize&size) : wxFrame(frame, wxID_ANY, title, pos, size) { m_canvas = NULL; + m_previewModality = wxPreviewFrame_AppModal; #if wxUSE_STATUSBAR // Give us a status line @@ -313,6 +318,11 @@ MyFrame::MyFrame(wxFrame *frame, const wxString&title, const wxPoint&pos, const #endif file_menu->Append(wxID_PREVIEW, wxT("Print Pre&view"), wxT("Preview")); + wxMenu * const menuModalKind = new wxMenu; + menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_APP, "&App modal"); + menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_WIN, "&Window modal"); + menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_NON, "&Not modal"); + file_menu->AppendSubMenu(menuModalKind, "Preview frame &modal kind"); #if wxUSE_ACCEL // Accelerators wxAcceleratorEntry entries[1]; @@ -400,7 +410,7 @@ void MyFrame::OnPrintPreview(wxCommandEvent& WXUNUSED(event)) wxPreviewFrame *frame = new wxPreviewFrame(preview, this, wxT("Demo Print Preview"), wxPoint(100, 100), wxSize(600, 650)); frame->Centre(wxBOTH); - frame->Initialize(); + frame->Initialize(m_previewModality); frame->Show(); } @@ -480,6 +490,12 @@ void MyFrame::OnAngleDown(wxCommandEvent& WXUNUSED(event)) m_canvas->Refresh(); } +void MyFrame::OnPreviewFrameModalityKind(wxCommandEvent& event) +{ + m_previewModality = static_cast( + wxPreviewFrame_AppModal + + (event.GetId() - WXPRINT_FRAME_MODAL_APP)); +} // ---------------------------------------------------------------------------- // MyCanvas diff --git a/samples/printing/printing.h b/samples/printing/printing.h index 3c0a894940..a138d541b4 100644 --- a/samples/printing/printing.h +++ b/samples/printing/printing.h @@ -58,11 +58,14 @@ public: void OnPageMargins(wxCommandEvent& event); #endif + void OnPreviewFrameModalityKind(wxCommandEvent& event); + void OnExit(wxCommandEvent& event); void OnPrintAbout(wxCommandEvent& event); private: MyCanvas* m_canvas; + wxPreviewFrameModalityKind m_previewModality; DECLARE_EVENT_TABLE() }; @@ -113,9 +116,13 @@ enum WXPRINT_PREVIEW_PS, WXPRINT_ANGLEUP, - WXPRINT_ANGLEDOWN + WXPRINT_ANGLEDOWN, #ifdef __WXMAC__ - , WXPRINT_PAGE_MARGINS + WXPRINT_PAGE_MARGINS, #endif + + WXPRINT_FRAME_MODAL_APP, + WXPRINT_FRAME_MODAL_WIN, + WXPRINT_FRAME_MODAL_NON }; diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 34dbcf0089..194d0793ac 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -345,8 +345,11 @@ bool wxAppConsoleBase::Dispatch() bool wxAppConsoleBase::Yield(bool onlyIfNeeded) { wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); + if ( loop ) + return loop->Yield(onlyIfNeeded); - return loop && loop->Yield(onlyIfNeeded); + wxScopedPtr tmpLoop(CreateMainLoop()); + return tmpLoop->Yield(onlyIfNeeded); } void wxAppConsoleBase::WakeUpIdle() diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp index 0f4559e759..c9e587b700 100644 --- a/src/common/prntbase.cpp +++ b/src/common/prntbase.cpp @@ -1619,6 +1619,7 @@ wxFrame(parent, wxID_ANY, title, pos, size, style, name) m_controlBar = NULL; m_previewCanvas = NULL; m_windowDisabler = NULL; + m_modalityKind = wxPreviewFrame_NonModal; // Give the application icon #ifdef __WXMSW__ @@ -1630,14 +1631,6 @@ wxFrame(parent, wxID_ANY, title, pos, size, style, name) wxPreviewFrame::~wxPreviewFrame() { -} - -void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) -{ - if (m_windowDisabler) - delete m_windowDisabler; - - // Need to delete the printout and the print preview wxPrintout *printout = m_printPreview->GetPrintout(); if (printout) { @@ -1648,12 +1641,33 @@ void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) } m_previewCanvas->SetPreview(NULL); - wxDELETE(m_printPreview); + delete m_printPreview; +} + +void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) +{ + // Reenable any windows we disabled by undoing whatever we did in our + // Initialize(). + switch ( m_modalityKind ) + { + case wxPreviewFrame_AppModal: + delete m_windowDisabler; + m_windowDisabler = NULL; + break; + + case wxPreviewFrame_WindowModal: + if ( GetParent() ) + GetParent()->Enable(); + break; + + case wxPreviewFrame_NonModal: + break; + } Destroy(); } -void wxPreviewFrame::Initialize() +void wxPreviewFrame::Initialize(wxPreviewFrameModalityKind kind) { #if wxUSE_STATUSBAR CreateStatusBar(); @@ -1672,7 +1686,25 @@ void wxPreviewFrame::Initialize() SetAutoLayout( true ); SetSizer( item0 ); - m_windowDisabler = new wxWindowDisabler(this); + m_modalityKind = kind; + switch ( m_modalityKind ) + { + case wxPreviewFrame_AppModal: + // Disable everything. + m_windowDisabler = new wxWindowDisabler( this ); + break; + + case wxPreviewFrame_WindowModal: + // Disable our parent if we have one. + if ( GetParent() ) + GetParent()->Disable(); + break; + + case wxPreviewFrame_NonModal: + // Nothing to do, we don't need to disable any windows. + break; + } + Layout();