+//----------------------------------------------------------------------------
+// wxPreviewControlBar
+//----------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
+
+BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
+ EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
+ EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrintButton)
+ EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
+ EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
+ EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
+ EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
+ EVT_BUTTON(wxID_PREVIEW_GOTO, wxPreviewControlBar::OnGotoButton)
+ EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoom)
+ EVT_PAINT(wxPreviewControlBar::OnPaint)
+END_EVENT_TABLE()
+
+wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
+ wxWindow *parent, const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name):
+wxPanel(parent, wxID_ANY, pos, size, style, name)
+{
+ m_printPreview = preview;
+ m_closeButton = (wxButton *) NULL;
+ m_nextPageButton = (wxButton *) NULL;
+ m_previousPageButton = (wxButton *) NULL;
+ m_printButton = (wxButton *) NULL;
+ m_zoomControl = (wxChoice *) NULL;
+ m_buttonFlags = buttons;
+}
+
+wxPreviewControlBar::~wxPreviewControlBar()
+{
+}
+
+void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+ wxPaintDC dc(this);
+
+ int w, h;
+ GetSize(&w, &h);
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxTRANSPARENT_BRUSH);
+ dc.DrawLine( 0, h-1, w, h-1 );
+}
+
+void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
+{
+ wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
+ frame->Close(true);
+}
+
+void wxPreviewControlBar::OnPrint(void)
+{
+ wxPrintPreviewBase *preview = GetPrintPreview();
+ preview->Print(true);
+}
+
+void wxPreviewControlBar::OnNext(void)
+{
+ wxPrintPreviewBase *preview = GetPrintPreview();
+ if (preview)
+ {
+ int currentPage = preview->GetCurrentPage();
+ if ((preview->GetMaxPage() > 0) &&
+ (currentPage < preview->GetMaxPage()) &&
+ preview->GetPrintout()->HasPage(currentPage + 1))
+ {
+ preview->SetCurrentPage(currentPage + 1);
+ }
+ }
+}
+
+void wxPreviewControlBar::OnPrevious(void)
+{
+ wxPrintPreviewBase *preview = GetPrintPreview();
+ if (preview)
+ {
+ int currentPage = preview->GetCurrentPage();
+ if ((preview->GetMinPage() > 0) &&
+ (currentPage > preview->GetMinPage()) &&
+ preview->GetPrintout()->HasPage(currentPage - 1))
+ {
+ preview->SetCurrentPage(currentPage - 1);
+ }
+ }
+}
+
+void wxPreviewControlBar::OnFirst(void)
+{
+ wxPrintPreviewBase *preview = GetPrintPreview();
+ if (preview)
+ {
+ int currentPage = preview->GetMinPage();
+ if (preview->GetPrintout()->HasPage(currentPage))
+ {
+ preview->SetCurrentPage(currentPage);
+ }
+ }
+}
+
+void wxPreviewControlBar::OnLast(void)
+{
+ wxPrintPreviewBase *preview = GetPrintPreview();
+ if (preview)
+ {
+ int currentPage = preview->GetMaxPage();
+ if (preview->GetPrintout()->HasPage(currentPage))
+ {
+ preview->SetCurrentPage(currentPage);
+ }
+ }
+}
+
+void wxPreviewControlBar::OnGoto(void)
+{
+ wxPrintPreviewBase *preview = GetPrintPreview();
+ if (preview)
+ {
+ long currentPage;
+
+ if (preview->GetMinPage() > 0)
+ {
+ wxString strPrompt;
+ wxString strPage;
+
+ strPrompt.Printf( _("Enter a page number between %d and %d:"),
+ preview->GetMinPage(), preview->GetMaxPage());
+ strPage.Printf( wxT("%d"), preview->GetCurrentPage() );
+
+ strPage =
+ wxGetTextFromUser( strPrompt, _("Goto Page"), strPage, GetParent());
+
+ if ( strPage.ToLong( ¤tPage ) )
+ if (preview->GetPrintout()->HasPage(currentPage))
+ {
+ preview->SetCurrentPage(currentPage);
+ }
+ }
+ }
+}
+
+void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
+{
+ int zoom = GetZoomControl();
+ if (GetPrintPreview())
+ GetPrintPreview()->SetZoom(zoom);
+}
+
+void wxPreviewControlBar::CreateButtons()
+{
+ SetSize(0, 0, 400, 40);
+
+ wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_closeButton = new wxButton( this, wxID_PREVIEW_CLOSE, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ item0->Add( m_closeButton, 0, wxALIGN_CENTRE|wxALL, 5 );
+
+ if (m_buttonFlags & wxPREVIEW_PRINT)
+ {
+ m_printButton = new wxButton( this, wxID_PREVIEW_PRINT, _("&Print..."), wxDefaultPosition, wxDefaultSize, 0 );
+ item0->Add( m_printButton, 0, wxALIGN_CENTRE|wxALL, 5 );
+ }
+
+ // Exact-fit buttons are too tiny on wxUniversal
+ int navButtonStyle;
+ wxSize navButtonSize;
+#ifdef __WXUNIVERSAL__
+ navButtonStyle = 0;
+ navButtonSize = wxSize(40, m_closeButton->GetSize().y);
+#else
+ navButtonStyle = wxBU_EXACTFIT;
+ navButtonSize = wxDefaultSize;
+#endif
+
+ if (m_buttonFlags & wxPREVIEW_FIRST)
+ {
+ m_firstPageButton = new wxButton( this, wxID_PREVIEW_FIRST, _("|<<"), wxDefaultPosition, navButtonSize, navButtonStyle );
+ item0->Add( m_firstPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
+ }
+
+ if (m_buttonFlags & wxPREVIEW_PREVIOUS)
+ {
+ m_previousPageButton = new wxButton( this, wxID_PREVIEW_PREVIOUS, _("<<"), wxDefaultPosition, navButtonSize, navButtonStyle );
+ item0->Add( m_previousPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
+ }
+
+ if (m_buttonFlags & wxPREVIEW_NEXT)
+ {
+ m_nextPageButton = new wxButton( this, wxID_PREVIEW_NEXT, _(">>"), wxDefaultPosition, navButtonSize, navButtonStyle );
+ item0->Add( m_nextPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
+ }
+
+ if (m_buttonFlags & wxPREVIEW_LAST)
+ {
+ m_lastPageButton = new wxButton( this, wxID_PREVIEW_LAST, _(">>|"), wxDefaultPosition, navButtonSize, navButtonStyle );
+ item0->Add( m_lastPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
+ }
+
+ if (m_buttonFlags & wxPREVIEW_GOTO)
+ {
+ m_gotoPageButton = new wxButton( this, wxID_PREVIEW_GOTO, _("&Goto..."), wxDefaultPosition, wxDefaultSize, 0 );
+ item0->Add( m_gotoPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
+ }
+
+ if (m_buttonFlags & wxPREVIEW_ZOOM)
+ {
+ wxString choices[] =
+ {
+ wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
+ wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
+ wxT("120%"), wxT("150%"), wxT("200%")
+ };
+ int n = WXSIZEOF(choices);
+
+ m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,wxDefaultCoord), n, choices, 0 );
+ item0->Add( m_zoomControl, 0, wxALIGN_CENTRE|wxALL, 5 );
+ SetZoomControl(m_printPreview->GetZoom());
+ }
+
+ SetSizer(item0);
+ item0->Fit(this);
+}
+
+void wxPreviewControlBar::SetZoomControl(int zoom)
+{
+ if (m_zoomControl)
+ {
+ int n, count = m_zoomControl->GetCount();
+ long val;
+ for (n=0; n<count; n++)
+ {
+ if (m_zoomControl->GetString(n).BeforeFirst(wxT('%')).ToLong(&val) &&
+ (val >= long(zoom)))
+ {
+ m_zoomControl->SetSelection(n);
+ return;
+ }
+ }
+
+ m_zoomControl->SetSelection(count-1);
+ }
+}
+
+int wxPreviewControlBar::GetZoomControl()
+{
+ if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxEmptyString))
+ {
+ long val;
+ if (m_zoomControl->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val))
+ return int(val);
+ }
+
+ return 0;
+}
+
+
+/*
+* Preview frame
+*/
+
+IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
+
+BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
+ EVT_CHAR_HOOK(wxPreviewFrame::OnChar)
+ EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
+END_EVENT_TABLE()
+
+void wxPreviewFrame::OnChar(wxKeyEvent &event)
+{
+ if ( event.GetKeyCode() == WXK_ESCAPE )
+ {
+ Close(true);
+ }
+ else
+ {
+ event.Skip();
+ }
+}
+
+wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name):
+wxFrame(parent, wxID_ANY, title, pos, size, style, name)
+{
+ m_printPreview = preview;
+ m_controlBar = NULL;
+ m_previewCanvas = NULL;
+ m_windowDisabler = NULL;
+
+ // Give the application icon
+#ifdef __WXMSW__
+ wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
+ if (topFrame)
+ SetIcon(topFrame->GetIcon());
+#endif
+}
+
+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)
+ {
+ delete printout;
+ m_printPreview->SetPrintout(NULL);
+ m_printPreview->SetCanvas(NULL);
+ m_printPreview->SetFrame(NULL);
+ }
+
+ m_previewCanvas->SetPreview(NULL);
+ wxDELETE(m_printPreview);
+
+ Destroy();
+}
+
+void wxPreviewFrame::Initialize()
+{
+#if wxUSE_STATUSBAR
+ CreateStatusBar();
+#endif
+ CreateCanvas();
+ CreateControlBar();
+
+ m_printPreview->SetCanvas(m_previewCanvas);
+ m_printPreview->SetFrame(this);
+
+ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
+
+ item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
+ item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
+
+ SetAutoLayout( true );
+ SetSizer( item0 );
+
+ m_windowDisabler = new wxWindowDisabler(this);
+
+ Layout();
+
+ m_printPreview->AdjustScrollbars(m_previewCanvas);
+ m_previewCanvas->SetFocus();
+ m_controlBar->SetFocus();
+}
+
+void wxPreviewFrame::CreateCanvas()
+{
+ m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
+}
+
+void wxPreviewFrame::CreateControlBar()
+{
+ long buttons = wxPREVIEW_DEFAULT;
+ if (m_printPreview->GetPrintoutForPrinting())
+ buttons |= wxPREVIEW_PRINT;
+
+ m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0,0), wxSize(400, 40));
+ m_controlBar->CreateButtons();
+}
+
+/*
+* Print preview
+*/
+
+IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
+
+wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
+ wxPrintout *printoutForPrinting,
+ wxPrintData *data)
+{
+ if (data)
+ m_printDialogData = (*data);
+
+ Init(printout, printoutForPrinting);
+}
+
+wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
+ wxPrintout *printoutForPrinting,
+ wxPrintDialogData *data)
+{
+ if (data)
+ m_printDialogData = (*data);
+
+ Init(printout, printoutForPrinting);
+}
+
+void wxPrintPreviewBase::Init(wxPrintout *printout,
+ wxPrintout *printoutForPrinting)
+{
+ m_isOk = true;
+ m_previewPrintout = printout;
+ if (m_previewPrintout)
+ m_previewPrintout->SetIsPreview(true);
+
+ m_printPrintout = printoutForPrinting;
+
+ m_previewCanvas = NULL;
+ m_previewFrame = NULL;
+ m_previewBitmap = NULL;
+ m_previewFailed = false;
+ m_currentPage = 1;
+ m_currentZoom = 70;
+ m_topMargin = 40;
+ m_leftMargin = 40;
+ m_pageWidth = 0;
+ m_pageHeight = 0;
+ m_printingPrepared = false;
+ m_minPage = 1;
+ m_maxPage = 1;
+}
+
+wxPrintPreviewBase::~wxPrintPreviewBase()
+{
+ if (m_previewPrintout)
+ delete m_previewPrintout;
+ if (m_previewBitmap)
+ delete m_previewBitmap;
+ if (m_printPrintout)
+ delete m_printPrintout;
+}
+
+bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
+{
+ if (m_currentPage == pageNum)
+ return true;
+
+ m_currentPage = pageNum;
+
+ InvalidatePreviewBitmap();
+
+ if (m_previewCanvas)
+ {
+ AdjustScrollbars(m_previewCanvas);
+
+ m_previewCanvas->Refresh();
+ m_previewCanvas->SetFocus();
+ }
+ return true;
+}
+
+int wxPrintPreviewBase::GetCurrentPage() const
+ { return m_currentPage; }
+void wxPrintPreviewBase::SetPrintout(wxPrintout *printout)
+ { m_previewPrintout = printout; }
+wxPrintout *wxPrintPreviewBase::GetPrintout() const
+ { return m_previewPrintout; }
+wxPrintout *wxPrintPreviewBase::GetPrintoutForPrinting() const
+ { return m_printPrintout; }
+void wxPrintPreviewBase::SetFrame(wxFrame *frame)
+ { m_previewFrame = frame; }
+void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas *canvas)
+ { m_previewCanvas = canvas; }
+wxFrame *wxPrintPreviewBase::GetFrame() const
+ { return m_previewFrame; }
+wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
+ { return m_previewCanvas; }
+
+void wxPrintPreviewBase::CalcRects(wxPreviewCanvas *canvas, wxRect& pageRect, wxRect& paperRect)
+{
+ // Calculate the rectangles for the printable area of the page and the
+ // entire paper as they appear on the canvas on-screen.
+ int canvasWidth, canvasHeight;
+ canvas->GetSize(&canvasWidth, &canvasHeight);
+
+ float zoomScale = float(m_currentZoom) / 100;
+ float screenPrintableWidth = zoomScale * m_pageWidth * m_previewScaleX;
+ float screenPrintableHeight = zoomScale * m_pageHeight * m_previewScaleY;
+
+ wxRect devicePaperRect = m_previewPrintout->GetPaperRectPixels();
+ wxCoord devicePrintableWidth, devicePrintableHeight;
+ m_previewPrintout->GetPageSizePixels(&devicePrintableWidth, &devicePrintableHeight);
+ float scaleX = screenPrintableWidth / devicePrintableWidth;
+ float scaleY = screenPrintableHeight / devicePrintableHeight;
+ paperRect.width = wxCoord(scaleX * devicePaperRect.width);
+ paperRect.height = wxCoord(scaleY * devicePaperRect.height);
+
+ paperRect.x = wxCoord((canvasWidth - paperRect.width)/ 2.0);
+ if (paperRect.x < m_leftMargin)
+ paperRect.x = m_leftMargin;
+ paperRect.y = wxCoord((canvasHeight - paperRect.height)/ 2.0);
+ if (paperRect.y < m_topMargin)
+ paperRect.y = m_topMargin;
+
+ pageRect.x = paperRect.x - wxCoord(scaleX * devicePaperRect.x);
+ pageRect.y = paperRect.y - wxCoord(scaleY * devicePaperRect.y);
+ pageRect.width = wxCoord(screenPrintableWidth);
+ pageRect.height = wxCoord(screenPrintableHeight);
+}
+
+
+void wxPrintPreviewBase::InvalidatePreviewBitmap()
+{
+ wxDELETE(m_previewBitmap);
+ // if there was a problem with rendering the preview, try again now
+ // that it changed in some way (less memory may be needed, for example):
+ m_previewFailed = false;
+}
+
+bool wxPrintPreviewBase::UpdatePageRendering()
+{
+ if ( m_previewBitmap )
+ return false;
+
+ if ( m_previewFailed )
+ return false;
+
+ if ( !RenderPage(m_currentPage) )
+ {
+ m_previewFailed = true; // don't waste time failing again
+ return false;
+ }
+
+ return true;
+}
+
+bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
+{
+ DrawBlankPage(canvas, dc);
+
+ if (!m_previewBitmap)
+ return false;
+ if (!canvas)
+ return false;
+
+ wxRect pageRect, paperRect;
+ CalcRects(canvas, pageRect, paperRect);
+ wxMemoryDC temp_dc;
+ temp_dc.SelectObject(*m_previewBitmap);
+
+ dc.Blit(pageRect.x, pageRect.y,
+ m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
+
+ temp_dc.SelectObject(wxNullBitmap);
+ return true;
+}
+
+// Adjusts the scrollbars for the current scale
+void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
+{
+ if (!canvas)
+ return ;
+
+ wxRect pageRect, paperRect;
+ CalcRects(canvas, pageRect, paperRect);
+ int totalWidth = paperRect.width + 2 * m_leftMargin;
+ int totalHeight = paperRect.height + 2 * m_topMargin;
+ int scrollUnitsX = totalWidth / 10;
+ int scrollUnitsY = totalHeight / 10;
+ wxSize virtualSize = canvas->GetVirtualSize();
+ if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
+ canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
+}
+
+bool wxPrintPreviewBase::RenderPageIntoDC(wxDC& dc, int pageNum)
+{
+ m_previewPrintout->SetDC(&dc);
+ m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
+
+ // Need to delay OnPreparePrinting() until here, so we have enough
+ // information.
+ if (!m_printingPrepared)
+ {
+ m_previewPrintout->OnPreparePrinting();
+ int selFrom, selTo;
+ m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
+ m_printingPrepared = true;
+ }
+
+ m_previewPrintout->OnBeginPrinting();
+
+ if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
+ {
+ wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
+ return false;
+ }
+
+ m_previewPrintout->OnPrintPage(pageNum);
+ m_previewPrintout->OnEndDocument();
+ m_previewPrintout->OnEndPrinting();
+
+ m_previewPrintout->SetDC(NULL);
+
+ return true;
+}
+
+bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum)
+{
+ wxMemoryDC memoryDC;
+ memoryDC.SelectObject(bmp);
+ memoryDC.Clear();
+
+ return RenderPageIntoDC(memoryDC, pageNum);
+}
+
+bool wxPrintPreviewBase::RenderPage(int pageNum)
+{
+ wxBusyCursor busy;
+
+ if (!m_previewCanvas)
+ {
+ wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
+ return false;
+ }
+
+ wxRect pageRect, paperRect;
+ CalcRects(m_previewCanvas, pageRect, paperRect);
+
+ if (!m_previewBitmap)
+ {
+ m_previewBitmap = new wxBitmap(pageRect.width, pageRect.height);
+
+ if (!m_previewBitmap || !m_previewBitmap->Ok())
+ {
+ InvalidatePreviewBitmap();
+ wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
+ return false;
+ }
+ }
+
+ if ( !RenderPageIntoBitmap(*m_previewBitmap, pageNum) )
+ {
+ InvalidatePreviewBitmap();
+ wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
+ return false;
+ }
+
+#if wxUSE_STATUSBAR
+ wxString status;
+ if (m_maxPage != 0)
+ status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
+ else
+ status = wxString::Format(_("Page %d"), pageNum);
+
+ if (m_previewFrame)
+ m_previewFrame->SetStatusText(status);
+#endif
+
+ return true;
+}
+
+bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
+{
+ wxRect pageRect, paperRect;
+
+ CalcRects(canvas, pageRect, paperRect);
+
+ // Draw shadow, allowing for 1-pixel border AROUND the actual paper
+ wxCoord shadowOffset = 4;
+
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxBLACK_BRUSH);
+ dc.DrawRectangle(paperRect.x + shadowOffset, paperRect.y + paperRect.height + 1,
+ paperRect.width, shadowOffset);
+
+ dc.DrawRectangle(paperRect.x + paperRect.width, paperRect.y + shadowOffset,
+ shadowOffset, paperRect.height);
+
+ // Draw blank page allowing for 1-pixel border AROUND the actual paper
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxWHITE_BRUSH);
+ dc.DrawRectangle(paperRect.x - 2, paperRect.y - 1,
+ paperRect.width + 3, paperRect.height + 2);
+
+ return true;
+}