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
This commit is contained in:
Vadim Zeitlin
2011-04-26 22:57:27 +00:00
parent c25f8d007d
commit 6aacfc7320
7 changed files with 132 additions and 21 deletions

View File

@@ -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:

View File

@@ -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);

View File

@@ -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.
*/

View File

@@ -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<wxPreviewFrameModalityKind>(
wxPreviewFrame_AppModal +
(event.GetId() - WXPRINT_FRAME_MODAL_APP));
}
// ----------------------------------------------------------------------------
// MyCanvas

View File

@@ -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
};

View File

@@ -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<wxEventLoopBase> tmpLoop(CreateMainLoop());
return tmpLoop->Yield(onlyIfNeeded);
}
void wxAppConsoleBase::WakeUpIdle()

View File

@@ -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();