home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / prntbase.cpp < prev    next >
C/C++ Source or Header  |  2002-12-22  |  24KB  |  897 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        prntbase.cpp
  3. // Purpose:     Printing framework base class implementation
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     04/01/98
  7. // RCS-ID:      $Id: prntbase.cpp,v 1.46.2.3 2002/12/19 23:43:33 VS Exp $
  8. // Copyright:   (c) Julian Smart and Markus Holzem
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "prntbase.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #include "wx/defs.h"
  24.  
  25. #if wxUSE_PRINTING_ARCHITECTURE
  26.  
  27. #ifndef WX_PRECOMP
  28. #include "wx/utils.h"
  29. #include "wx/dc.h"
  30. #include "wx/app.h"
  31. #include "wx/msgdlg.h"
  32. #include "wx/layout.h"
  33. #include "wx/choice.h"
  34. #include "wx/button.h"
  35. #include "wx/settings.h"
  36. #include "wx/dcmemory.h"
  37. #include "wx/stattext.h"
  38. #include "wx/intl.h"
  39. #include "wx/textdlg.h"
  40. #include "wx/sizer.h"
  41. #endif // !WX_PRECOMP
  42.  
  43. #include "wx/prntbase.h"
  44. #include "wx/dcprint.h"
  45. #include "wx/printdlg.h"
  46. #include "wx/module.h"
  47.  
  48. #include <stdlib.h>
  49. #include <string.h>
  50.  
  51. #ifdef __WXMSW__
  52.     #include "wx/msw/private.h"
  53.     #include <commdlg.h>
  54.  
  55.     #ifndef __WIN32__
  56.         #include <print.h>
  57.     #endif
  58. #endif // __WXMSW__
  59.  
  60. IMPLEMENT_CLASS(wxPrinterBase, wxObject)
  61. IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
  62. IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
  63. IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
  64. IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
  65. IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
  66.  
  67. BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
  68.     EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
  69. END_EVENT_TABLE()
  70.  
  71. BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
  72.     EVT_PAINT(wxPreviewCanvas::OnPaint)
  73.     EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
  74. END_EVENT_TABLE()
  75.  
  76. /*
  77. * Printer
  78. */
  79.  
  80. wxPrinterBase::wxPrinterBase(wxPrintDialogData *data)
  81. {
  82.     m_currentPrintout = (wxPrintout *) NULL;
  83.     sm_abortWindow = (wxWindow *) NULL;
  84.     sm_abortIt = FALSE;
  85.     if (data)
  86.         m_printDialogData = (*data);
  87.     sm_lastError = wxPRINTER_NO_ERROR;
  88. }
  89.  
  90. wxWindow *wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
  91. bool wxPrinterBase::sm_abortIt = FALSE;
  92. wxPrinterError wxPrinterBase::sm_lastError = wxPRINTER_NO_ERROR;
  93.  
  94. wxPrinterBase::~wxPrinterBase()
  95. {
  96. }
  97.  
  98. void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
  99. {
  100.     wxPrinterBase::sm_abortIt = TRUE;
  101.     wxPrinterBase::sm_abortWindow->Show(FALSE);
  102.     wxPrinterBase::sm_abortWindow->Close(TRUE);
  103.     wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
  104. }
  105.  
  106. wxWindow *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout * printout)
  107. {
  108.     wxPrintAbortDialog *dialog = new wxPrintAbortDialog(parent, _("Printing ") , wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
  109.  
  110.     wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
  111.     button_sizer->Add( new wxStaticText(dialog, -1, _("Please wait while printing\n") + printout->GetTitle() ), 0, wxALL, 10 );
  112.     button_sizer->Add( new wxButton( dialog, wxID_CANCEL, wxT("Cancel") ), 0, wxALL | wxALIGN_CENTER, 10 );
  113.  
  114.     dialog->SetAutoLayout( TRUE );
  115.     dialog->SetSizer( button_sizer );
  116.  
  117.     button_sizer->Fit(dialog);
  118.     button_sizer->SetSizeHints (dialog) ;
  119.  
  120.     return dialog;
  121. }
  122.  
  123. void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), const wxString& message)
  124. {
  125.     wxMessageBox(message, _("Printing Error"), wxOK, parent);
  126. }
  127.  
  128. /*
  129. * Printout class
  130. */
  131.  
  132. wxPrintout::wxPrintout(const wxString& title)
  133. {
  134.     m_printoutTitle = title ;
  135.     m_printoutDC = (wxDC *) NULL;
  136.     m_pageWidthMM = 0;
  137.     m_pageHeightMM = 0;
  138.     m_pageWidthPixels = 0;
  139.     m_pageHeightPixels = 0;
  140.     m_PPIScreenX = 0;
  141.     m_PPIScreenY = 0;
  142.     m_PPIPrinterX = 0;
  143.     m_PPIPrinterY = 0;
  144.     m_isPreview = FALSE;
  145. }
  146.  
  147. wxPrintout::~wxPrintout()
  148. {
  149. }
  150.  
  151. bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
  152. {
  153.     return GetDC()->StartDoc(_("Printing ") + m_printoutTitle);
  154. }
  155.  
  156. void wxPrintout::OnEndDocument()
  157. {
  158.     GetDC()->EndDoc();
  159. }
  160.  
  161. void wxPrintout::OnBeginPrinting()
  162. {
  163. }
  164.  
  165. void wxPrintout::OnEndPrinting()
  166. {
  167. }
  168.  
  169. bool wxPrintout::HasPage(int page)
  170. {
  171.     return (page == 1);
  172. }
  173.  
  174. void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
  175. {
  176.     *minPage = 1;
  177.     *maxPage = 32000;
  178.     *fromPage = 1;
  179.     *toPage = 1;
  180. }
  181.  
  182. /*
  183. * Preview canvas
  184. */
  185.  
  186. wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
  187.                                  const wxPoint& pos, const wxSize& size, long style, const wxString& name):
  188. wxScrolledWindow(parent, -1, pos, size, style, name)
  189. {
  190.     m_printPreview = preview;
  191.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
  192.  
  193.     SetScrollbars(15, 18, 100, 100);
  194. }
  195.  
  196. wxPreviewCanvas::~wxPreviewCanvas()
  197. {
  198. }
  199.  
  200. void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
  201. {
  202.     wxPaintDC dc(this);
  203.     PrepareDC( dc );
  204.  
  205. /*
  206. #ifdef __WXGTK__
  207.     if (!GetUpdateRegion().IsEmpty())
  208.         dc.SetClippingRegion( GetUpdateRegion() );
  209. #endif
  210. */
  211.  
  212.     if (m_printPreview)
  213.     {
  214.         m_printPreview->PaintPage(this, dc);
  215.     }
  216. }
  217.  
  218. // Responds to colour changes, and passes event on to children.
  219. void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
  220. {
  221.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
  222.     Refresh();
  223.  
  224.     // Propagate the event to the non-top-level children
  225.     wxWindow::OnSysColourChanged(event);
  226. }
  227.  
  228. /*
  229. * Preview control bar
  230. */
  231.  
  232. BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
  233.     EVT_BUTTON(wxID_PREVIEW_CLOSE,    wxPreviewControlBar::OnWindowClose)
  234.     EVT_BUTTON(wxID_PREVIEW_PRINT,    wxPreviewControlBar::OnPrint)
  235.     EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
  236.     EVT_BUTTON(wxID_PREVIEW_NEXT,     wxPreviewControlBar::OnNextButton)
  237.     EVT_BUTTON(wxID_PREVIEW_FIRST,    wxPreviewControlBar::OnFirstButton)
  238.     EVT_BUTTON(wxID_PREVIEW_LAST,     wxPreviewControlBar::OnLastButton)
  239.     EVT_BUTTON(wxID_PREVIEW_GOTO,     wxPreviewControlBar::OnGotoButton)
  240.     EVT_CHAR(wxPreviewControlBar::OnChar)
  241.     EVT_CHOICE(wxID_PREVIEW_ZOOM,     wxPreviewControlBar::OnZoom)
  242.     EVT_PAINT(wxPreviewControlBar::OnPaint)
  243. END_EVENT_TABLE()
  244.  
  245. wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
  246.                                          wxWindow *parent, const wxPoint& pos, const wxSize& size,
  247.                                          long style, const wxString& name):
  248. wxPanel(parent, -1, pos, size, style, name)
  249. {
  250.     m_printPreview = preview;
  251.     m_closeButton = (wxButton *) NULL;
  252.     m_nextPageButton = (wxButton *) NULL;
  253.     m_previousPageButton = (wxButton *) NULL;
  254.     m_printButton = (wxButton *) NULL;
  255.     m_zoomControl = (wxChoice *) NULL;
  256.     m_buttonFlags = buttons;
  257. }
  258.  
  259. wxPreviewControlBar::~wxPreviewControlBar()
  260. {
  261. }
  262.  
  263. void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
  264. {
  265.     wxPaintDC dc(this);
  266.  
  267.     int w, h;
  268.     GetSize(&w, &h);
  269.     dc.SetPen(*wxBLACK_PEN);
  270.     dc.SetBrush(*wxTRANSPARENT_BRUSH);
  271.     dc.DrawLine( 0, h-1, w, h-1 );
  272. }
  273.  
  274. void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
  275. {
  276.     wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
  277.     frame->Close(TRUE);
  278. }
  279.  
  280. void wxPreviewControlBar::OnPrint(wxCommandEvent& WXUNUSED(event))
  281. {
  282.     wxPrintPreviewBase *preview = GetPrintPreview();
  283.     preview->Print(TRUE);
  284. }
  285.  
  286. void wxPreviewControlBar::OnChar(wxKeyEvent &event)
  287. {
  288.    switch(event.KeyCode())
  289.    {
  290.    case WXK_NEXT:
  291.       OnNext(); break;
  292.    case WXK_PRIOR:
  293.       OnPrevious(); break;
  294.    case WXK_HOME:
  295.       OnFirst(); break;
  296.    case WXK_END:
  297.       OnLast(); break;
  298.    case WXK_TAB:
  299.       OnGoto(); break;
  300.    default:
  301.       event.Skip();
  302.    }
  303. }
  304.  
  305. void wxPreviewControlBar::OnNext(void)
  306. {
  307.     wxPrintPreviewBase *preview = GetPrintPreview();
  308.     if (preview)
  309.     {
  310.         int currentPage = preview->GetCurrentPage();
  311.         if ((preview->GetMaxPage() > 0) &&
  312.             (currentPage < preview->GetMaxPage()) &&
  313.             preview->GetPrintout()->HasPage(currentPage + 1))
  314.         {
  315.             preview->SetCurrentPage(currentPage + 1);
  316.         }
  317.     }
  318. }
  319.  
  320. void wxPreviewControlBar::OnPrevious(void)
  321. {
  322.     wxPrintPreviewBase *preview = GetPrintPreview();
  323.     if (preview)
  324.     {
  325.         int currentPage = preview->GetCurrentPage();
  326.         if ((preview->GetMinPage() > 0) &&
  327.             (currentPage > preview->GetMinPage()) &&
  328.             preview->GetPrintout()->HasPage(currentPage - 1))
  329.         {
  330.             preview->SetCurrentPage(currentPage - 1);
  331.         }
  332.     }
  333. }
  334.  
  335. void wxPreviewControlBar::OnFirst(void)
  336. {
  337.     wxPrintPreviewBase *preview = GetPrintPreview();
  338.     if (preview)
  339.     {
  340.         int currentPage = preview->GetMinPage();
  341.         if (preview->GetPrintout()->HasPage(currentPage))
  342.         {
  343.             preview->SetCurrentPage(currentPage);
  344.         }
  345.     }
  346. }
  347.  
  348. void wxPreviewControlBar::OnLast(void)
  349. {
  350.     wxPrintPreviewBase *preview = GetPrintPreview();
  351.     if (preview)
  352.     {
  353.         int currentPage = preview->GetMaxPage();
  354.         if (preview->GetPrintout()->HasPage(currentPage))
  355.         {
  356.             preview->SetCurrentPage(currentPage);
  357.         }
  358.     }
  359. }
  360.  
  361. void wxPreviewControlBar::OnGoto(void)
  362. {
  363.     wxPrintPreviewBase *preview = GetPrintPreview();
  364.     if (preview)
  365.     {
  366.         long currentPage;
  367.  
  368.         if (preview->GetMinPage() > 0)
  369.         {
  370.             wxString strPrompt;
  371.             wxString strPage;
  372.  
  373.             strPrompt.Printf( wxT("%d...%d"),
  374.                 preview->GetMinPage(), preview->GetMaxPage());
  375.             strPage.Printf( wxT("%d"), preview->GetCurrentPage() );
  376.  
  377.             strPage =
  378.                 wxGetTextFromUser( strPrompt, _("Goto Page"), strPage);
  379.  
  380.             if ( strPage.ToLong( ¤tPage ) )
  381.                 if (preview->GetPrintout()->HasPage(currentPage))
  382.                 {
  383.                     preview->SetCurrentPage(currentPage);
  384.                 }
  385.         }
  386.     }
  387. }
  388.  
  389. void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
  390. {
  391.     int zoom = GetZoomControl();
  392.     if (GetPrintPreview())
  393.         GetPrintPreview()->SetZoom(zoom);
  394. }
  395.  
  396. void wxPreviewControlBar::CreateButtons()
  397. {
  398.     SetSize(0, 0, 400, 40);
  399.  
  400.     /*
  401.     #ifdef __WXMSW__
  402.     int fontSize = 9;
  403.     #else
  404.     int fontSize = 10;
  405.     #endif
  406.  
  407.       wxFont buttonFont(fontSize, wxSWISS, wxNORMAL, wxBOLD);
  408.       SetFont(buttonFont);
  409.     */
  410.  
  411.     int buttonWidth = 60;
  412.     int buttonNavigation = 30;
  413. #ifdef __WXGTK__
  414.     int buttonHeight = -1;
  415. #else
  416.     int buttonHeight = 24;
  417. #endif
  418.  
  419.     int x = 5;
  420.     int y = 5;
  421.  
  422. #ifdef __WXMOTIF__
  423.     int gap = 15;
  424. #else
  425.     int gap = 5;
  426. #endif
  427.  
  428.     m_closeButton = new wxButton(this, wxID_PREVIEW_CLOSE, _("Close"),
  429.         wxPoint(x, y), wxSize(buttonWidth, buttonHeight));
  430.  
  431.     x += gap + buttonWidth;
  432.  
  433.     if (m_buttonFlags & wxPREVIEW_PRINT)
  434.     {
  435.         m_printButton =  new wxButton(this, wxID_PREVIEW_PRINT, _("Print..."), wxPoint(x, y),
  436.             wxSize(buttonWidth, buttonHeight));
  437.         x += gap + buttonWidth;
  438.     }
  439.  
  440.     if (m_buttonFlags & wxPREVIEW_FIRST)
  441.     {
  442.         m_firstPageButton = new wxButton(this, wxID_PREVIEW_FIRST, wxT("|<<"), wxPoint(x, y),
  443.             wxSize(buttonNavigation, buttonHeight));
  444.         x += gap + buttonNavigation;
  445.     }
  446.  
  447.     if (m_buttonFlags & wxPREVIEW_PREVIOUS)
  448.     {
  449.         m_previousPageButton = new wxButton(this, wxID_PREVIEW_PREVIOUS, wxT("<<"), wxPoint(x, y),
  450.             wxSize(buttonNavigation, buttonHeight));
  451.         x += gap + buttonNavigation;
  452.     }
  453.  
  454.     if (m_buttonFlags & wxPREVIEW_NEXT)
  455.     {
  456.         m_nextPageButton = new wxButton(this, wxID_PREVIEW_NEXT, wxT(">>"),
  457.             wxPoint(x, y), wxSize(buttonNavigation, buttonHeight));
  458.         x += gap + buttonNavigation;
  459.     }
  460.  
  461.     if (m_buttonFlags & wxPREVIEW_LAST)
  462.     {
  463.         m_lastPageButton = new wxButton(this, wxID_PREVIEW_LAST, wxT(">>|"), wxPoint(x, y),
  464.             wxSize(buttonNavigation, buttonHeight));
  465.         x += gap + buttonNavigation;
  466.     }
  467.  
  468.     if (m_buttonFlags & wxPREVIEW_GOTO)
  469.     {
  470.         m_gotoPageButton = new wxButton(this, wxID_PREVIEW_GOTO, wxT("Goto..."), wxPoint(x, y),
  471.             wxSize(buttonWidth, buttonHeight));
  472.         x += gap + buttonWidth;
  473.     }
  474.  
  475.     if (m_buttonFlags & wxPREVIEW_ZOOM)
  476.     {
  477.         static const wxChar *choices[] =
  478.         {
  479.             wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
  480.             wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
  481.             wxT("120%"), wxT("150%"), wxT("200%")
  482.         };
  483.  
  484.         int n = WXSIZEOF(choices);
  485.  
  486.         wxString* strings = new wxString[n];
  487.         int i;
  488.         for (i = 0; i < n; i++ )
  489.            strings[i] = choices[i];
  490.  
  491.         m_zoomControl = new wxChoice(this, wxID_PREVIEW_ZOOM,
  492.                                      wxPoint(x, y),
  493.                                      wxSize(100, -1),
  494.                                      n,
  495.                                      strings
  496.                                     );
  497.         delete[] strings;
  498.  
  499.         SetZoomControl(m_printPreview->GetZoom());
  500.     }
  501.  
  502.     //  m_closeButton->SetDefault();
  503. }
  504.  
  505. void wxPreviewControlBar::SetZoomControl(int zoom)
  506. {
  507.     wxChar buf[20];
  508.     wxSprintf( buf, wxT("%d%%"), zoom );
  509.  
  510.     if (m_zoomControl)
  511.         m_zoomControl->SetStringSelection(buf);
  512. }
  513.  
  514. int wxPreviewControlBar::GetZoomControl()
  515. {
  516.     wxChar buf[20];
  517.     if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxT("")))
  518.     {
  519.         wxStrcpy(buf, m_zoomControl->GetStringSelection());
  520.         buf[wxStrlen(buf) - 1] = 0;
  521.         return (int)wxAtoi(buf);
  522.     }
  523.     else return 0;
  524. }
  525.  
  526.  
  527. /*
  528. * Preview frame
  529. */
  530.  
  531. BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
  532.     EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
  533. END_EVENT_TABLE()
  534.  
  535. wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxFrame *parent, const wxString& title,
  536.                                const wxPoint& pos, const wxSize& size, long style, const wxString& name):
  537. wxFrame(parent, -1, title, pos, size, style, name)
  538. {
  539.     m_printPreview = preview;
  540.     m_controlBar = NULL;
  541.     m_previewCanvas = NULL;
  542. }
  543.  
  544. wxPreviewFrame::~wxPreviewFrame()
  545. {
  546. }
  547.  
  548. void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
  549. {
  550.     MakeModal(FALSE);
  551.  
  552.     // Need to delete the printout and the print preview
  553.     wxPrintout *printout = m_printPreview->GetPrintout();
  554.     if (printout)
  555.     {
  556.         delete printout;
  557.         m_printPreview->SetPrintout(NULL);
  558.         m_printPreview->SetCanvas(NULL);
  559.         m_printPreview->SetFrame(NULL);
  560.     }
  561.     delete m_printPreview;
  562.  
  563.     Destroy();
  564. }
  565.  
  566. void wxPreviewFrame::Initialize()
  567. {
  568.     CreateStatusBar();
  569.  
  570.     CreateCanvas();
  571.     CreateControlBar();
  572.  
  573.     m_printPreview->SetCanvas(m_previewCanvas);
  574.     m_printPreview->SetFrame(this);
  575.  
  576.     // Set layout constraints here
  577.  
  578.     // Control bar constraints
  579.     wxLayoutConstraints *c1 = new wxLayoutConstraints;
  580.     //  int w, h;
  581.     //  m_controlBar->GetSize(&w, &h);
  582.     int h;
  583. #if (defined(__WXMSW__) || defined(__WXGTK__))
  584.     h = 40;
  585. #else
  586.     h = 60;
  587. #endif
  588.  
  589.     c1->left.SameAs       (this, wxLeft);
  590.     c1->top.SameAs        (this, wxTop);
  591.     c1->right.SameAs      (this, wxRight);
  592.     c1->height.Absolute   (h);
  593.  
  594.     m_controlBar->SetConstraints(c1);
  595.  
  596.     // Canvas constraints
  597.     wxLayoutConstraints *c2 = new wxLayoutConstraints;
  598.  
  599.     c2->left.SameAs       (this, wxLeft);
  600.     c2->top.Below         (m_controlBar);
  601.     c2->right.SameAs      (this, wxRight);
  602.     c2->bottom.SameAs     (this, wxBottom);
  603.  
  604.     m_previewCanvas->SetConstraints(c2);
  605.  
  606.     SetAutoLayout(TRUE);
  607.  
  608.     MakeModal(TRUE);
  609.  
  610.     Layout();
  611. }
  612.  
  613. void wxPreviewFrame::CreateCanvas()
  614. {
  615.     m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
  616. }
  617.  
  618. void wxPreviewFrame::CreateControlBar()
  619. {
  620.     long buttons = wxPREVIEW_DEFAULT;
  621.     if (m_printPreview->GetPrintoutForPrinting())
  622.         buttons |= wxPREVIEW_PRINT;
  623.  
  624.     m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0, 0), wxSize(400, 40));
  625.     m_controlBar->CreateButtons();
  626. }
  627.  
  628. /*
  629. * Print preview
  630. */
  631.  
  632. wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
  633.                                        wxPrintout *printoutForPrinting,
  634.                                        wxPrintData *data)
  635. {
  636.     if (data)
  637.         m_printDialogData = (*data);
  638.  
  639.     Init(printout, printoutForPrinting);
  640. }
  641.  
  642. wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
  643.                                        wxPrintout *printoutForPrinting,
  644.                                        wxPrintDialogData *data)
  645. {
  646.     if (data)
  647.         m_printDialogData = (*data);
  648.  
  649.     Init(printout, printoutForPrinting);
  650. }
  651.  
  652. void wxPrintPreviewBase::Init(wxPrintout *printout,
  653.                               wxPrintout *printoutForPrinting)
  654. {
  655.     m_isOk = TRUE;
  656.     m_previewPrintout = printout;
  657.     if (m_previewPrintout)
  658.         m_previewPrintout->SetIsPreview(TRUE);
  659.  
  660.     m_printPrintout = printoutForPrinting;
  661.  
  662.     m_previewCanvas = NULL;
  663.     m_previewFrame = NULL;
  664.     m_previewBitmap = NULL;
  665.     m_currentPage = 1;
  666.     m_currentZoom = 70;
  667.     m_topMargin = 40;
  668.     m_leftMargin = 40;
  669.     m_pageWidth = 0;
  670.     m_pageHeight = 0;
  671.     m_printingPrepared = FALSE;
  672.  
  673.     // Too soon! Moved to RenderPage.
  674.     // printout->OnPreparePrinting();
  675.  
  676.     // Get some parameters from the printout, if defined
  677.     int selFrom, selTo;
  678.     printout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
  679. }
  680.  
  681. wxPrintPreviewBase::~wxPrintPreviewBase()
  682. {
  683.     if (m_previewPrintout)
  684.         delete m_previewPrintout;
  685.     if (m_previewBitmap)
  686.         delete m_previewBitmap;
  687.     if (m_printPrintout)
  688.         delete m_printPrintout;
  689. }
  690.  
  691. bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
  692. {
  693.     if (m_currentPage == pageNum)
  694.         return TRUE;
  695.  
  696.     m_currentPage = pageNum;
  697.     if (m_previewBitmap)
  698.     {
  699.         delete m_previewBitmap;
  700.         m_previewBitmap = NULL;
  701.     }
  702.  
  703.     if (m_previewCanvas)
  704.     {
  705.         if (!RenderPage(pageNum))
  706.             return FALSE;
  707.         m_previewCanvas->Refresh();
  708.     }
  709.     return TRUE;
  710. }
  711.  
  712. bool wxPrintPreviewBase::PaintPage(wxWindow *canvas, wxDC& dc)
  713. {
  714.     DrawBlankPage(canvas, dc);
  715.  
  716.     if (!m_previewBitmap)
  717.         if (!RenderPage(m_currentPage))
  718.             return FALSE;
  719.  
  720.     if (!m_previewBitmap)
  721.         return FALSE;
  722.  
  723.     if (!canvas)
  724.         return FALSE;
  725.  
  726.     int canvasWidth, canvasHeight;
  727.     canvas->GetSize(&canvasWidth, &canvasHeight);
  728.  
  729.     double zoomScale = ((float)m_currentZoom/(float)100);
  730.     double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
  731.     //  float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
  732.  
  733.     int x = (int) ((canvasWidth - actualWidth)/2.0);
  734.     if (x < m_leftMargin)
  735.         x = m_leftMargin;
  736.     int y = m_topMargin;
  737.  
  738.     wxMemoryDC temp_dc;
  739.     temp_dc.SelectObject(*m_previewBitmap);
  740.  
  741.     dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
  742.  
  743.     temp_dc.SelectObject(wxNullBitmap);
  744.  
  745.     return TRUE;
  746. }
  747.  
  748. bool wxPrintPreviewBase::RenderPage(int pageNum)
  749. {
  750.     wxBusyCursor busy;
  751.  
  752.     int canvasWidth, canvasHeight;
  753.  
  754.     if (!m_previewCanvas)
  755.     {
  756.         wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
  757.  
  758.         return FALSE;
  759.     }
  760.     m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
  761.  
  762.     double zoomScale = (m_currentZoom/100.0);
  763.     int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
  764.     int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
  765.  
  766.     int x = (int)((canvasWidth - actualWidth)/2.0);
  767.     if (x < m_leftMargin)
  768.         x = m_leftMargin;
  769.     //  int y = m_topMargin;
  770.  
  771.  
  772.     if (!m_previewBitmap)
  773.     {
  774.         m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
  775.         if (!m_previewBitmap || !m_previewBitmap->Ok())
  776.         {
  777.             if (m_previewBitmap) {
  778.                 delete m_previewBitmap;
  779.                 m_previewBitmap = NULL;
  780.             }
  781.             wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
  782.             return FALSE;
  783.         }
  784.     }
  785.  
  786.     wxMemoryDC memoryDC;
  787.     memoryDC.SelectObject(*m_previewBitmap);
  788.  
  789.     memoryDC.Clear();
  790.  
  791.     m_previewPrintout->SetDC(&memoryDC);
  792.     m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
  793.  
  794.     // Need to delay OnPreparePrinting until here, so we have enough information.
  795.     if (!m_printingPrepared)
  796.     {
  797.         m_previewPrintout->OnPreparePrinting();
  798.         m_printingPrepared = TRUE;
  799.     }
  800.  
  801.     m_previewPrintout->OnBeginPrinting();
  802.  
  803.     if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
  804.     {
  805.         wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
  806.  
  807.         memoryDC.SelectObject(wxNullBitmap);
  808.  
  809.         delete m_previewBitmap;
  810.         m_previewBitmap = NULL;
  811.         return FALSE;
  812.     }
  813.  
  814.     m_previewPrintout->OnPrintPage(pageNum);
  815.     m_previewPrintout->OnEndDocument();
  816.     m_previewPrintout->OnEndPrinting();
  817.  
  818.     m_previewPrintout->SetDC(NULL);
  819.  
  820.     memoryDC.SelectObject(wxNullBitmap);
  821.  
  822.     wxChar buf[200];
  823.     if (m_maxPage != 0)
  824.         wxSprintf(buf, _("Page %d of %d"), pageNum, m_maxPage);
  825.     else
  826.         wxSprintf(buf, _("Page %d"), pageNum);
  827.  
  828.     if (m_previewFrame)
  829.         m_previewFrame->SetStatusText(buf);
  830.  
  831.     return TRUE;
  832. }
  833.  
  834.  
  835. bool wxPrintPreviewBase::DrawBlankPage(wxWindow *canvas, wxDC& dc)
  836. {
  837.     int canvasWidth, canvasHeight;
  838.     canvas->GetSize(&canvasWidth, &canvasHeight);
  839.  
  840.     float zoomScale = (float)((float)m_currentZoom/(float)100);
  841.     float actualWidth = zoomScale*m_pageWidth*m_previewScale;
  842.     float actualHeight = zoomScale*m_pageHeight*m_previewScale;
  843.  
  844.     float x = (float)((canvasWidth - actualWidth)/2.0);
  845.     if (x < m_leftMargin)
  846.         x = (float)m_leftMargin;
  847.     float y = (float)m_topMargin;
  848.  
  849.     // Draw shadow, allowing for 1-pixel border AROUND the actual page
  850.     int shadowOffset = 4;
  851.     dc.SetPen(*wxBLACK_PEN);
  852.     dc.SetBrush(*wxBLACK_BRUSH);
  853.     /*
  854.     dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
  855.     */
  856.     dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
  857.     dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
  858.  
  859.     // Draw blank page allowing for 1-pixel border AROUND the actual page
  860.     dc.SetPen(*wxBLACK_PEN);
  861.     dc.SetBrush(*wxWHITE_BRUSH);
  862.  
  863.     /*
  864.     wxRegion update_region = canvas->GetUpdateRegion();
  865.     wxRect r = update_region.GetBox();
  866.  
  867.       printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
  868.     */
  869.  
  870.     dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
  871.  
  872.     return TRUE;
  873. }
  874.  
  875. void wxPrintPreviewBase::SetZoom(int percent)
  876. {
  877.     if (m_currentZoom == percent)
  878.         return;
  879.  
  880.     m_currentZoom = percent;
  881.     if (m_previewBitmap)
  882.     {
  883.         delete m_previewBitmap;
  884.         m_previewBitmap = NULL;
  885.     }
  886.  
  887.     if (m_previewCanvas)
  888.     {
  889.         RenderPage(m_currentPage);
  890.         ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
  891.         m_previewCanvas->Clear();
  892.         m_previewCanvas->Refresh();
  893.     }
  894. }
  895.  
  896. #endif // wxUSE_PRINTING_ARCHITECTURE
  897.