+
+void wxPreviewFrame::InitializeWithModality(wxPreviewFrameModalityKind kind)
+{
+#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_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;
+ }
+
+ if ( m_modalityKind != wxPreviewFrame_NonModal )
+ {
+ // Behave like modal dialogs, don't show in taskbar. This implies
+ // removing the minimize box, because minimizing windows without
+ // taskbar entry is confusing.
+ SetWindowStyle((GetWindowStyle() & ~wxMINIMIZE_BOX) | wxFRAME_NO_TASKBAR);
+ }
+
+ 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);
+ 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->SetPreview(static_cast<wxPrintPreview *>(this));
+
+ m_printPrintout = printoutForPrinting;
+
+ m_previewCanvas = NULL;
+ m_previewFrame = NULL;
+ m_previewBitmap = NULL;
+ m_previewFailed = false;
+ m_currentPage = 1;
+ m_currentZoom = 70;
+ m_topMargin =
+ m_leftMargin = 2*wxSizerFlags::GetDefaultBorder();
+ 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 and a wxDC.
+ if (!m_printingPrepared)
+ {
+ m_printingPrepared = true;
+
+ m_previewPrintout->OnPreparePrinting();
+ int selFrom, selTo;
+ m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
+
+ // Update the wxPreviewControlBar page range display.
+ if ( m_previewFrame )
+ {
+ wxPreviewControlBar * const
+ controlBar = ((wxPreviewFrame*)m_previewFrame)->GetControlBar();
+ if ( controlBar )
+ controlBar->SetPageInfo(m_minPage, m_maxPage);
+ }
+ }
+
+ 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(wxT("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->IsOk())
+ {
+ 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;
+}
+
+void wxPrintPreviewBase::SetZoom(int percent)
+{
+ if (m_currentZoom == percent)
+ return;
+
+ m_currentZoom = percent;
+
+ InvalidatePreviewBitmap();
+
+ if (m_previewCanvas)
+ {
+ AdjustScrollbars(m_previewCanvas);
+ ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
+ m_previewCanvas->ClearBackground();
+ m_previewCanvas->Refresh();
+ m_previewCanvas->SetFocus();
+ }
+}
+
+wxPrintDialogData& wxPrintPreviewBase::GetPrintDialogData()
+{
+ return m_printDialogData;
+}
+
+int wxPrintPreviewBase::GetZoom() const
+{ return m_currentZoom; }
+int wxPrintPreviewBase::GetMaxPage() const
+{ return m_maxPage; }
+int wxPrintPreviewBase::GetMinPage() const
+{ return m_minPage; }
+bool wxPrintPreviewBase::IsOk() const
+{ return m_isOk; }
+void wxPrintPreviewBase::SetOk(bool ok)
+{ m_isOk = ok; }
+
+//----------------------------------------------------------------------------
+// wxPrintPreview
+//----------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxPrintPreview, wxPrintPreviewBase)
+
+wxPrintPreview::wxPrintPreview(wxPrintout *printout,
+ wxPrintout *printoutForPrinting,
+ wxPrintDialogData *data) :
+ wxPrintPreviewBase( printout, printoutForPrinting, data )
+{
+ m_pimpl = wxPrintFactory::GetFactory()->
+ CreatePrintPreview( printout, printoutForPrinting, data );
+}
+
+wxPrintPreview::wxPrintPreview(wxPrintout *printout,
+ wxPrintout *printoutForPrinting,
+ wxPrintData *data ) :
+ wxPrintPreviewBase( printout, printoutForPrinting, data )
+{
+ m_pimpl = wxPrintFactory::GetFactory()->
+ CreatePrintPreview( printout, printoutForPrinting, data );
+}
+
+wxPrintPreview::~wxPrintPreview()
+{
+ delete m_pimpl;
+
+ // don't delete twice
+ m_printPrintout = NULL;
+ m_previewPrintout = NULL;
+ m_previewBitmap = NULL;
+}
+
+bool wxPrintPreview::SetCurrentPage(int pageNum)
+{
+ return m_pimpl->SetCurrentPage( pageNum );
+}
+
+int wxPrintPreview::GetCurrentPage() const
+{
+ return m_pimpl->GetCurrentPage();
+}
+
+void wxPrintPreview::SetPrintout(wxPrintout *printout)
+{
+ m_pimpl->SetPrintout( printout );
+}
+
+wxPrintout *wxPrintPreview::GetPrintout() const
+{
+ return m_pimpl->GetPrintout();
+}
+
+wxPrintout *wxPrintPreview::GetPrintoutForPrinting() const
+{
+ return m_pimpl->GetPrintoutForPrinting();
+}
+
+void wxPrintPreview::SetFrame(wxFrame *frame)
+{
+ m_pimpl->SetFrame( frame );
+}
+
+void wxPrintPreview::SetCanvas(wxPreviewCanvas *canvas)
+{
+ m_pimpl->SetCanvas( canvas );
+}
+
+wxFrame *wxPrintPreview::GetFrame() const
+{
+ return m_pimpl->GetFrame();
+}
+
+wxPreviewCanvas *wxPrintPreview::GetCanvas() const
+{
+ return m_pimpl->GetCanvas();
+}
+
+bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
+{
+ return m_pimpl->PaintPage( canvas, dc );
+}
+
+bool wxPrintPreview::UpdatePageRendering()
+{
+ return m_pimpl->UpdatePageRendering();
+}
+
+bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
+{
+ return m_pimpl->DrawBlankPage( canvas, dc );
+}
+
+void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas *canvas)
+{
+ m_pimpl->AdjustScrollbars( canvas );
+}
+
+bool wxPrintPreview::RenderPage(int pageNum)
+{
+ return m_pimpl->RenderPage( pageNum );
+}
+
+void wxPrintPreview::SetZoom(int percent)
+{
+ m_pimpl->SetZoom( percent );
+}
+
+int wxPrintPreview::GetZoom() const
+{
+ return m_pimpl->GetZoom();
+}
+
+wxPrintDialogData& wxPrintPreview::GetPrintDialogData()
+{
+ return m_pimpl->GetPrintDialogData();
+}
+
+int wxPrintPreview::GetMaxPage() const
+{
+ return m_pimpl->GetMaxPage();
+}
+
+int wxPrintPreview::GetMinPage() const
+{
+ return m_pimpl->GetMinPage();
+}
+
+bool wxPrintPreview::IsOk() const
+{
+ return m_pimpl->IsOk();
+}
+
+void wxPrintPreview::SetOk(bool ok)
+{
+ m_pimpl->SetOk( ok );
+}
+
+bool wxPrintPreview::Print(bool interactive)
+{
+ return m_pimpl->Print( interactive );
+}
+
+void wxPrintPreview::DetermineScaling()
+{
+ m_pimpl->DetermineScaling();
+}
+
+#endif // wxUSE_PRINTING_ARCHITECTURE