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. - This function should be called by the application prior to showing the frame. + 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. + + @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();