1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/prntbase.cpp 
   3 // Purpose:     Printing framework base class implementation 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  19 #if wxUSE_PRINTING_ARCHITECTURE 
  21 #include "wx/dcprint.h" 
  24     #if defined(__WXMSW__) 
  25         #include "wx/msw/wrapcdlg.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/dcclient.h" 
  38     #include "wx/stattext.h" 
  40     #include "wx/textdlg.h" 
  42     #include "wx/module.h" 
  45 #include "wx/prntbase.h" 
  46 #include "wx/printdlg.h" 
  48 #include "wx/dcprint.h" 
  53 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
  54 #include "wx/msw/printdlg.h" 
  55 #include "wx/msw/dcprint.h" 
  56 #elif defined(__WXMAC__) 
  57 #include "wx/osx/printdlg.h" 
  58 #include "wx/osx/private/print.h" 
  59 #include "wx/osx/dcprint.h" 
  60 #elif defined(__WXPM__) 
  61 #include "wx/os2/dcprint.h" 
  62 #include "wx/generic/prntdlgg.h" 
  64 #include "wx/generic/prntdlgg.h" 
  74 //---------------------------------------------------------------------------- 
  76 //---------------------------------------------------------------------------- 
  78 wxPrintFactory 
*wxPrintFactory::m_factory 
= NULL
; 
  80 void wxPrintFactory::SetPrintFactory( wxPrintFactory 
*factory 
) 
  82     if (wxPrintFactory::m_factory
) 
  83         delete wxPrintFactory::m_factory
; 
  85     wxPrintFactory::m_factory 
= factory
; 
  88 wxPrintFactory 
*wxPrintFactory::GetFactory() 
  90     if (!wxPrintFactory::m_factory
) 
  91         wxPrintFactory::m_factory 
= new wxNativePrintFactory
; 
  93     return wxPrintFactory::m_factory
; 
  96 //---------------------------------------------------------------------------- 
  97 // wxNativePrintFactory 
  98 //---------------------------------------------------------------------------- 
 100 wxPrinterBase 
*wxNativePrintFactory::CreatePrinter( wxPrintDialogData 
*data 
) 
 102 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 103     return new wxWindowsPrinter( data 
); 
 104 #elif defined(__WXMAC__) 
 105     return new wxMacPrinter( data 
); 
 106 #elif defined(__WXPM__) 
 107     return new wxOS2Printer( data 
); 
 109     return new wxPostScriptPrinter( data 
); 
 113 wxPrintPreviewBase 
*wxNativePrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 114     wxPrintout 
*printout
, wxPrintDialogData 
*data 
) 
 116 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 117     return new wxWindowsPrintPreview( preview
, printout
, data 
); 
 118 #elif defined(__WXMAC__) 
 119     return new wxMacPrintPreview( preview
, printout
, data 
); 
 120 #elif defined(__WXPM__) 
 121     return new wxOS2PrintPreview( preview
, printout
, data 
); 
 123     return new wxPostScriptPrintPreview( preview
, printout
, data 
); 
 127 wxPrintPreviewBase 
*wxNativePrintFactory::CreatePrintPreview( wxPrintout 
*preview
, 
 128     wxPrintout 
*printout
, wxPrintData 
*data 
) 
 130 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 131     return new wxWindowsPrintPreview( preview
, printout
, data 
); 
 132 #elif defined(__WXMAC__) 
 133     return new wxMacPrintPreview( preview
, printout
, data 
); 
 134 #elif defined(__WXPM__) 
 135     return new wxOS2PrintPreview( preview
, printout
, data 
); 
 137     return new wxPostScriptPrintPreview( preview
, printout
, data 
); 
 141 wxPrintDialogBase 
*wxNativePrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 142                                                   wxPrintDialogData 
*data 
) 
 144 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 145     return new wxWindowsPrintDialog( parent
, data 
); 
 146 #elif defined(__WXMAC__) 
 147     return new wxMacPrintDialog( parent
, data 
); 
 149     return new wxGenericPrintDialog( parent
, data 
); 
 153 wxPrintDialogBase 
*wxNativePrintFactory::CreatePrintDialog( wxWindow 
*parent
, 
 156 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 157     return new wxWindowsPrintDialog( parent
, data 
); 
 158 #elif defined(__WXMAC__) 
 159     return new wxMacPrintDialog( parent
, data 
); 
 161     return new wxGenericPrintDialog( parent
, data 
); 
 165 wxPageSetupDialogBase 
*wxNativePrintFactory::CreatePageSetupDialog( wxWindow 
*parent
, 
 166                                                   wxPageSetupDialogData 
*data 
) 
 168 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 169     return new wxWindowsPageSetupDialog( parent
, data 
); 
 170 #elif defined(__WXMAC__) 
 171     return new wxMacPageSetupDialog( parent
, data 
); 
 173     return new wxGenericPageSetupDialog( parent
, data 
); 
 177 bool wxNativePrintFactory::HasPrintSetupDialog() 
 179 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 181 #elif defined(__WXMAC__) 
 184     // Only here do we need to provide the print setup 
 185     // dialog ourselves, the other platforms either have 
 186     // none, don't make it accessible or let you configure 
 187     // the printer from the wxPrintDialog anyway. 
 193 wxDialog 
*wxNativePrintFactory::CreatePrintSetupDialog( wxWindow 
*parent
, 
 196 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 200 #elif defined(__WXMAC__) 
 205     // Only here do we need to provide the print setup 
 206     // dialog ourselves, the other platforms either have 
 207     // none, don't make it accessible or let you configure 
 208     // the printer from the wxPrintDialog anyway. 
 209     return new wxGenericPrintSetupDialog( parent
, data 
); 
 213 wxDCImpl
* wxNativePrintFactory::CreatePrinterDCImpl( wxPrinterDC 
*owner
, const wxPrintData
& data 
) 
 215 #if defined(__WXGTK__) || defined(__WXMOTIF__) || ( defined(__WXUNIVERSAL__) && !defined(__WXMAC__) ) 
 216     return new wxPostScriptDCImpl( owner
, data 
); 
 218     return new wxPrinterDCImpl( owner
, data 
); 
 222 bool wxNativePrintFactory::HasOwnPrintToFile() 
 224     // Only relevant for PostScript and here the 
 225     // setup dialog provides no "print to file" 
 226     // option. In the GNOME setup dialog, the 
 227     // setup dialog has its own print to file. 
 231 bool wxNativePrintFactory::HasPrinterLine() 
 233     // Only relevant for PostScript for now 
 237 wxString 
wxNativePrintFactory::CreatePrinterLine() 
 239     // Only relevant for PostScript for now 
 241     // We should query "lpstat -d" here 
 242     return _("Generic PostScript"); 
 245 bool wxNativePrintFactory::HasStatusLine() 
 247     // Only relevant for PostScript for now 
 251 wxString 
wxNativePrintFactory::CreateStatusLine() 
 253     // Only relevant for PostScript for now 
 255     // We should query "lpstat -r" or "lpstat -p" here 
 259 wxPrintNativeDataBase 
*wxNativePrintFactory::CreatePrintNativeData() 
 261 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) 
 262     return new wxWindowsPrintNativeData
; 
 263 #elif defined(__WXMAC__) 
 264     return wxOSXCreatePrintData(); 
 266     return new wxPostScriptPrintNativeData
; 
 270 //---------------------------------------------------------------------------- 
 271 // wxPrintNativeDataBase 
 272 //---------------------------------------------------------------------------- 
 274 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase
, wxObject
) 
 276 wxPrintNativeDataBase::wxPrintNativeDataBase() 
 281 //---------------------------------------------------------------------------- 
 282 // wxPrintFactoryModule 
 283 //---------------------------------------------------------------------------- 
 285 class wxPrintFactoryModule
: public wxModule
 
 288     wxPrintFactoryModule() {} 
 289     bool OnInit() { return true; } 
 290     void OnExit() { wxPrintFactory::SetPrintFactory( NULL 
); } 
 293     DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule
) 
 296 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule
, wxModule
) 
 298 //---------------------------------------------------------------------------- 
 300 //---------------------------------------------------------------------------- 
 302 IMPLEMENT_CLASS(wxPrinterBase
, wxObject
) 
 304 wxPrinterBase::wxPrinterBase(wxPrintDialogData 
*data
) 
 306     m_currentPrintout 
= (wxPrintout 
*) NULL
; 
 307     sm_abortWindow 
= (wxWindow 
*) NULL
; 
 310         m_printDialogData 
= (*data
); 
 311     sm_lastError 
= wxPRINTER_NO_ERROR
; 
 314 wxWindow 
*wxPrinterBase::sm_abortWindow 
= (wxWindow 
*) NULL
; 
 315 bool wxPrinterBase::sm_abortIt 
= false; 
 316 wxPrinterError 
wxPrinterBase::sm_lastError 
= wxPRINTER_NO_ERROR
; 
 318 wxPrinterBase::~wxPrinterBase() 
 322 wxWindow 
*wxPrinterBase::CreateAbortWindow(wxWindow 
*parent
, wxPrintout 
* printout
) 
 324     wxPrintAbortDialog 
*dialog 
= new wxPrintAbortDialog(parent
, _("Printing ") , wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
); 
 326     wxBoxSizer 
*button_sizer 
= new wxBoxSizer( wxVERTICAL 
); 
 327     button_sizer
->Add( new wxStaticText(dialog
, wxID_ANY
, _("Please wait while printing\n") + printout
->GetTitle() ), 0, wxALL
, 10 ); 
 328     button_sizer
->Add( new wxButton( dialog
, wxID_CANCEL
, wxT("Cancel") ), 0, wxALL 
| wxALIGN_CENTER
, 10 ); 
 330     dialog
->SetAutoLayout( true ); 
 331     dialog
->SetSizer( button_sizer 
); 
 333     button_sizer
->Fit(dialog
); 
 334     button_sizer
->SetSizeHints (dialog
) ; 
 339 void wxPrinterBase::ReportError(wxWindow 
*parent
, wxPrintout 
*WXUNUSED(printout
), const wxString
& message
) 
 341     wxMessageBox(message
, _("Printing Error"), wxOK
, parent
); 
 344 wxPrintDialogData
& wxPrinterBase::GetPrintDialogData() const 
 346     return (wxPrintDialogData
&) m_printDialogData
; 
 349 //---------------------------------------------------------------------------- 
 351 //---------------------------------------------------------------------------- 
 353 IMPLEMENT_CLASS(wxPrinter
, wxPrinterBase
) 
 355 wxPrinter::wxPrinter(wxPrintDialogData 
*data
) 
 357     m_pimpl 
= wxPrintFactory::GetFactory()->CreatePrinter( data 
); 
 360 wxPrinter::~wxPrinter() 
 365 wxWindow 
*wxPrinter::CreateAbortWindow(wxWindow 
*parent
, wxPrintout 
*printout
) 
 367     return m_pimpl
->CreateAbortWindow( parent
, printout 
); 
 370 void wxPrinter::ReportError(wxWindow 
*parent
, wxPrintout 
*printout
, const wxString
& message
) 
 372     m_pimpl
->ReportError( parent
, printout
, message 
); 
 375 bool wxPrinter::Setup(wxWindow 
*parent
) 
 377     return m_pimpl
->Setup( parent 
); 
 380 bool wxPrinter::Print(wxWindow 
*parent
, wxPrintout 
*printout
, bool prompt
) 
 382     return m_pimpl
->Print( parent
, printout
, prompt 
); 
 385 wxDC
* wxPrinter::PrintDialog(wxWindow 
*parent
) 
 387     return m_pimpl
->PrintDialog( parent 
); 
 390 wxPrintDialogData
& wxPrinter::GetPrintDialogData() const 
 392     return m_pimpl
->GetPrintDialogData(); 
 395 // --------------------------------------------------------------------------- 
 396 // wxPrintDialogBase: the dialog for printing. 
 397 // --------------------------------------------------------------------------- 
 399 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase
, wxDialog
) 
 401 wxPrintDialogBase::wxPrintDialogBase(wxWindow 
*parent
, 
 403                                      const wxString 
&title
, 
 407     : wxDialog( parent
, id
, title
.empty() ? wxString(_("Print")) : title
, 
 412 // --------------------------------------------------------------------------- 
 413 // wxPrintDialog: the dialog for printing 
 414 // --------------------------------------------------------------------------- 
 416 IMPLEMENT_CLASS(wxPrintDialog
, wxObject
) 
 418 wxPrintDialog::wxPrintDialog(wxWindow 
*parent
, wxPrintDialogData
* data
) 
 420     m_pimpl 
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data 
); 
 423 wxPrintDialog::wxPrintDialog(wxWindow 
*parent
, wxPrintData
* data
) 
 425     m_pimpl 
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data 
); 
 428 wxPrintDialog::~wxPrintDialog() 
 433 int wxPrintDialog::ShowModal() 
 435     return m_pimpl
->ShowModal(); 
 438 wxPrintDialogData
& wxPrintDialog::GetPrintDialogData() 
 440     return m_pimpl
->GetPrintDialogData(); 
 443 wxPrintData
& wxPrintDialog::GetPrintData() 
 445     return m_pimpl
->GetPrintData(); 
 448 wxDC 
*wxPrintDialog::GetPrintDC() 
 450     return m_pimpl
->GetPrintDC(); 
 453 // --------------------------------------------------------------------------- 
 454 // wxPageSetupDialogBase: the page setup dialog 
 455 // --------------------------------------------------------------------------- 
 457 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase
, wxDialog
) 
 459 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow 
*parent
, 
 461                                      const wxString 
&title
, 
 465     : wxDialog( parent
, id
, title
.empty() ? wxString(_("Page setup")) : title
, 
 470 // --------------------------------------------------------------------------- 
 471 // wxPageSetupDialog: the page setup dialog 
 472 // --------------------------------------------------------------------------- 
 474 IMPLEMENT_CLASS(wxPageSetupDialog
, wxObject
) 
 476 wxPageSetupDialog::wxPageSetupDialog(wxWindow 
*parent
, wxPageSetupDialogData 
*data 
) 
 478     m_pimpl 
= wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent
, data 
); 
 481 wxPageSetupDialog::~wxPageSetupDialog() 
 486 int wxPageSetupDialog::ShowModal() 
 488     return m_pimpl
->ShowModal(); 
 491 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupDialogData() 
 493     return m_pimpl
->GetPageSetupDialogData(); 
 497 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupData() 
 499     return m_pimpl
->GetPageSetupDialogData(); 
 502 //---------------------------------------------------------------------------- 
 503 // wxPrintAbortDialog 
 504 //---------------------------------------------------------------------------- 
 506 BEGIN_EVENT_TABLE(wxPrintAbortDialog
, wxDialog
) 
 507     EVT_BUTTON(wxID_CANCEL
, wxPrintAbortDialog::OnCancel
) 
 510 void wxPrintAbortDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
)) 
 512     wxPrinterBase::sm_abortIt 
= true; 
 513     wxPrinterBase::sm_abortWindow
->Show(false); 
 514     wxPrinterBase::sm_abortWindow
->Close(true); 
 515     wxPrinterBase::sm_abortWindow
->Destroy(); 
 516     wxPrinterBase::sm_abortWindow 
= (wxWindow 
*) NULL
; 
 519 //---------------------------------------------------------------------------- 
 521 //---------------------------------------------------------------------------- 
 523 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
) 
 525 wxPrintout::wxPrintout(const wxString
& title
) 
 527     m_printoutTitle 
= title 
; 
 528     m_printoutDC 
= (wxDC 
*) NULL
; 
 531     m_pageWidthPixels 
= 0; 
 532     m_pageHeightPixels 
= 0; 
 540 wxPrintout::~wxPrintout() 
 544 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
)) 
 546     return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
); 
 549 void wxPrintout::OnEndDocument() 
 554 void wxPrintout::OnBeginPrinting() 
 558 void wxPrintout::OnEndPrinting() 
 562 bool wxPrintout::HasPage(int page
) 
 567 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
) 
 575 void wxPrintout::FitThisSizeToPaper(const wxSize
& imageSize
) 
 577     // Set the DC scale and origin so that the given image size fits within the 
 578     // entire page and the origin is at the top left corner of the page. Note 
 579     // that with most printers, portions of the page will be non-printable. Use 
 580     // this if you're managing your own page margins. 
 581     if (!m_printoutDC
) return; 
 582     wxRect paperRect 
= GetPaperRectPixels(); 
 584     GetPageSizePixels(&pw
, &ph
); 
 586     m_printoutDC
->GetSize(&w
, &h
); 
 587     float scaleX 
= ((float(paperRect
.width
) * w
) / (float(pw
) * imageSize
.x
)); 
 588     float scaleY 
= ((float(paperRect
.height
) * h
) / (float(ph
) * imageSize
.y
)); 
 589     float actualScale 
= wxMin(scaleX
, scaleY
); 
 590     m_printoutDC
->SetUserScale(actualScale
, actualScale
);  
 591     m_printoutDC
->SetDeviceOrigin(0, 0); 
 592     wxRect logicalPaperRect 
= GetLogicalPaperRect(); 
 593     SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
); 
 596 void wxPrintout::FitThisSizeToPage(const wxSize
& imageSize
) 
 598     // Set the DC scale and origin so that the given image size fits within the 
 599     // printable area of the page and the origin is at the top left corner of 
 600     // the printable area. 
 601     if (!m_printoutDC
) return; 
 603     m_printoutDC
->GetSize(&w
, &h
); 
 604     float scaleX 
= float(w
) / imageSize
.x
; 
 605     float scaleY 
= float(h
) / imageSize
.y
; 
 606     float actualScale 
= wxMin(scaleX
, scaleY
); 
 607     m_printoutDC
->SetUserScale(actualScale
, actualScale
);  
 608     m_printoutDC
->SetDeviceOrigin(0, 0); 
 611 void wxPrintout::FitThisSizeToPageMargins(const wxSize
& imageSize
, const wxPageSetupDialogData
& pageSetupData
) 
 613     // Set the DC scale and origin so that the given image size fits within the 
 614     // page margins defined in the given wxPageSetupDialogData object and the 
 615     // origin is at the top left corner of the page margins. 
 616     if (!m_printoutDC
) return; 
 617     wxRect paperRect 
= GetPaperRectPixels(); 
 619     GetPageSizePixels(&pw
, &ph
); 
 620     wxPoint topLeft 
= pageSetupData
.GetMarginTopLeft(); 
 621     wxPoint bottomRight 
= pageSetupData
.GetMarginBottomRight(); 
 623     GetPageSizeMM(&mw
, &mh
); 
 624     float mmToDeviceX 
= float(pw
) / mw
; 
 625     float mmToDeviceY 
= float(ph
) / mh
; 
 626     wxRect 
pageMarginsRect(paperRect
.x 
+ wxRound(mmToDeviceX 
* topLeft
.x
), 
 627         paperRect
.y 
+ wxRound(mmToDeviceY 
* topLeft
.y
), 
 628         paperRect
.width 
- wxRound(mmToDeviceX 
* (topLeft
.x 
+ bottomRight
.x
)), 
 629         paperRect
.height 
- wxRound(mmToDeviceY 
* (topLeft
.y 
+ bottomRight
.y
))); 
 631     m_printoutDC
->GetSize(&w
, &h
); 
 632     float scaleX 
= (float(pageMarginsRect
.width
) * w
) / (float(pw
) * imageSize
.x
); 
 633     float scaleY 
= (float(pageMarginsRect
.height
) * h
) / (float(ph
) * imageSize
.y
); 
 634     float actualScale 
= wxMin(scaleX
, scaleY
); 
 635     m_printoutDC
->SetUserScale(actualScale
, actualScale
);  
 636     m_printoutDC
->SetDeviceOrigin(0, 0); 
 637     wxRect logicalPageMarginsRect 
= GetLogicalPageMarginsRect(pageSetupData
); 
 638     SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
); 
 641 void wxPrintout::MapScreenSizeToPaper() 
 643     // Set the DC scale so that an image on the screen is the same size on the 
 644     // paper and the origin is at the top left of the paper. Note that with most 
 645     // printers, portions of the page will be cut off. Use this if you're 
 646     // managing your own page margins. 
 647     if (!m_printoutDC
) return; 
 648     MapScreenSizeToPage(); 
 649     wxRect logicalPaperRect 
= GetLogicalPaperRect(); 
 650     SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
); 
 653 void wxPrintout::MapScreenSizeToPage() 
 655     // Set the DC scale and origin so that an image on the screen is the same 
 656     // size on the paper and the origin is at the top left of the printable area. 
 657     if (!m_printoutDC
) return; 
 658     int ppiScreenX
, ppiScreenY
;  
 659     GetPPIScreen(&ppiScreenX
, &ppiScreenY
);  
 660     int ppiPrinterX
, ppiPrinterY
;  
 661     GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);  
 663     m_printoutDC
->GetSize(&w
, &h
);  
 664     int pageSizePixelsX
, pageSizePixelsY
;  
 665     GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);  
 666     float userScaleX 
= (float(ppiPrinterX
) * w
) / (float(ppiScreenX
) * pageSizePixelsX
);  
 667     float userScaleY 
= (float(ppiPrinterY
) * h
) / (float(ppiScreenY
) * pageSizePixelsY
);  
 668     m_printoutDC
->SetUserScale(userScaleX
, userScaleY
); 
 669     m_printoutDC
->SetDeviceOrigin(0, 0); 
 672 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData
& pageSetupData
) 
 674     // Set the DC scale so that an image on the screen is the same size on the 
 675     // paper and the origin is at the top left of the page margins defined by 
 676     // the given wxPageSetupDialogData object. 
 677     if (!m_printoutDC
) return; 
 678     MapScreenSizeToPage(); 
 679     wxRect logicalPageMarginsRect 
= GetLogicalPageMarginsRect(pageSetupData
); 
 680     SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
); 
 683 void wxPrintout::MapScreenSizeToDevice() 
 685     // Set the DC scale so that a screen pixel is the same size as a device 
 686     // pixel and the origin is at the top left of the printable area. 
 687     if (!m_printoutDC
) return; 
 689     m_printoutDC
->GetSize(&w
, &h
);  
 690     int pageSizePixelsX
, pageSizePixelsY
;  
 691     GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);  
 692     float userScaleX 
= float(w
) / pageSizePixelsX
;  
 693     float userScaleY 
= float(h
) / pageSizePixelsY
;  
 694     m_printoutDC
->SetUserScale(userScaleX
, userScaleY
); 
 695     m_printoutDC
->SetDeviceOrigin(0, 0); 
 698 wxRect 
wxPrintout::GetLogicalPaperRect() const 
 700     // Return the rectangle in logical units that corresponds to the paper 
 702     wxRect paperRect 
= GetPaperRectPixels(); 
 704     GetPageSizePixels(&pw
, &ph
); 
 706     m_printoutDC
->GetSize(&w
, &h
); 
 707     if (w 
== pw 
&& h 
== ph
) { 
 708         // this DC matches the printed page, so no scaling 
 709         return wxRect(m_printoutDC
->DeviceToLogicalX(paperRect
.x
),  
 710             m_printoutDC
->DeviceToLogicalY(paperRect
.y
),  
 711             m_printoutDC
->DeviceToLogicalXRel(paperRect
.width
),  
 712             m_printoutDC
->DeviceToLogicalYRel(paperRect
.height
)); 
 714     // This DC doesn't match the printed page, so we have to scale. 
 715     float scaleX 
= float(w
) / pw
; 
 716     float scaleY 
= float(h
) / ph
; 
 717     return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(paperRect
.x 
* scaleX
)),  
 718         m_printoutDC
->DeviceToLogicalY(wxRound(paperRect
.y 
* scaleY
)),  
 719         m_printoutDC
->DeviceToLogicalXRel(wxRound(paperRect
.width 
* scaleX
)),  
 720         m_printoutDC
->DeviceToLogicalYRel(wxRound(paperRect
.height 
* scaleY
))); 
 723 wxRect 
wxPrintout::GetLogicalPageRect() const 
 725     // Return the rectangle in logical units that corresponds to the printable 
 728     m_printoutDC
->GetSize(&w
, &h
); 
 729     return wxRect(m_printoutDC
->DeviceToLogicalX(0),  
 730         m_printoutDC
->DeviceToLogicalY(0),  
 731         m_printoutDC
->DeviceToLogicalXRel(w
),  
 732         m_printoutDC
->DeviceToLogicalYRel(h
)); 
 735 wxRect 
wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData
& pageSetupData
) const 
 737     // Return the rectangle in logical units that corresponds to the region 
 738     // within the page margins as specified by the given wxPageSetupDialogData 
 741     // We get the paper size in device units and the margins in mm, 
 742     // so we need to calculate the conversion with this trick 
 744     GetPageSizePixels(&pw
, &ph
); 
 746     GetPageSizeMM(&mw
, &mh
); 
 747     float mmToDeviceX 
= float(pw
) / mw
; 
 748     float mmToDeviceY 
= float(ph
) / mh
; 
 750     // paper size in device units     
 751     wxRect paperRect 
= GetPaperRectPixels(); 
 754     wxPoint topLeft 
= pageSetupData
.GetMarginTopLeft(); 
 755     wxPoint bottomRight 
= pageSetupData
.GetMarginBottomRight(); 
 757     // calculate margins in device units 
 758     wxRect 
pageMarginsRect( 
 759         paperRect
.x      
+ wxRound(mmToDeviceX 
* topLeft
.x
), 
 760         paperRect
.y      
+ wxRound(mmToDeviceY 
* topLeft
.y
), 
 761         paperRect
.width  
- wxRound(mmToDeviceX 
* (topLeft
.x 
+ bottomRight
.x
)), 
 762         paperRect
.height 
- wxRound(mmToDeviceY 
* (topLeft
.y 
+ bottomRight
.y
))); 
 765     m_printoutDC
->GetSize(&w
, &h
); 
 766     if (w 
== pw 
&& h 
== ph
)  
 768         // this DC matches the printed page, so no scaling 
 770             m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),  
 771             m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),  
 772             m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),  
 773             m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
)); 
 776     // This DC doesn't match the printed page, so we have to scale. 
 777     float scaleX 
= float(w
) / pw
; 
 778     float scaleY 
= float(h
) / ph
; 
 779     return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(pageMarginsRect
.x 
* scaleX
)),  
 780         m_printoutDC
->DeviceToLogicalY(wxRound(pageMarginsRect
.y 
* scaleY
)),  
 781         m_printoutDC
->DeviceToLogicalXRel(wxRound(pageMarginsRect
.width 
* scaleX
)),  
 782         m_printoutDC
->DeviceToLogicalYRel(wxRound(pageMarginsRect
.height 
* scaleY
))); 
 785 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
) 
 787     // Set the device origin by specifying a point in logical coordinates. 
 788     m_printoutDC
->SetDeviceOrigin( 
 789         m_printoutDC
->LogicalToDeviceX(x
),  
 790         m_printoutDC
->LogicalToDeviceY(y
) ); 
 793 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
) 
 795     // Offset the device origin by a specified distance in device coordinates. 
 796     wxPoint dev_org 
= m_printoutDC
->GetDeviceOrigin(); 
 797     m_printoutDC
->SetDeviceOrigin( 
 798         dev_org
.x 
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),  
 799         dev_org
.y 
+ m_printoutDC
->LogicalToDeviceYRel(yoff
) ); 
 803 //---------------------------------------------------------------------------- 
 805 //---------------------------------------------------------------------------- 
 807 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
) 
 809 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
) 
 810     EVT_PAINT(wxPreviewCanvas::OnPaint
) 
 811     EVT_CHAR(wxPreviewCanvas::OnChar
) 
 812     EVT_IDLE(wxPreviewCanvas::OnIdle
) 
 813     EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
) 
 815     EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
) 
 819 // VZ: the current code doesn't refresh properly without 
 820 //     wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have 
 821 //     really horrible flicker when resizing the preview frame, but without 
 822 //     this style it simply doesn't work correctly at all... 
 823 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase 
*preview
, wxWindow 
*parent
, 
 824                                  const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
): 
 825 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style 
| wxFULL_REPAINT_ON_RESIZE
, name
) 
 827     m_printPreview 
= preview
; 
 829     // The app workspace colour is always white, but we should have 
 830     // a contrast with the page. 
 831     wxSystemColour colourIndex 
= wxSYS_COLOUR_3DDKSHADOW
; 
 832 #elif defined(__WXGTK__) 
 833     wxSystemColour colourIndex 
= wxSYS_COLOUR_BTNFACE
; 
 835     wxSystemColour colourIndex 
= wxSYS_COLOUR_APPWORKSPACE
; 
 837     SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
)); 
 839     SetScrollbars(10, 10, 100, 100); 
 842 wxPreviewCanvas::~wxPreviewCanvas() 
 846 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 853     if (!GetUpdateRegion().IsEmpty()) 
 854         dc.SetClippingRegion( GetUpdateRegion() ); 
 860         m_printPreview
->PaintPage(this, dc
); 
 864 void wxPreviewCanvas::OnIdle(wxIdleEvent
& event
) 
 868     // prevent UpdatePageRendering() from being called recursively: 
 869     static bool s_inIdle 
= false; 
 874     if ( m_printPreview 
) 
 876         if ( m_printPreview
->UpdatePageRendering() ) 
 883 // Responds to colour changes, and passes event on to children. 
 884 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 887     // The app workspace colour is always white, but we should have 
 888     // a contrast with the page. 
 889     wxSystemColour colourIndex 
= wxSYS_COLOUR_3DDKSHADOW
; 
 890 #elif defined(__WXGTK__) 
 891     wxSystemColour colourIndex 
= wxSYS_COLOUR_BTNFACE
; 
 893     wxSystemColour colourIndex 
= wxSYS_COLOUR_APPWORKSPACE
; 
 895     SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
)); 
 898     // Propagate the event to the non-top-level children 
 899     wxWindow::OnSysColourChanged(event
); 
 902 void wxPreviewCanvas::OnChar(wxKeyEvent 
&event
) 
 904     wxPreviewControlBar
* controlBar 
= ((wxPreviewFrame
*) GetParent())->GetControlBar(); 
 905     switch (event
.GetKeyCode()) 
 908             controlBar
->OnGoto(); 
 911             controlBar
->OnPrint(); 
 915     if (!event
.ControlDown()) 
 921     switch(event
.GetKeyCode()) 
 924             controlBar
->OnNext(); break; 
 926             controlBar
->OnPrevious(); break; 
 928             controlBar
->OnFirst(); break; 
 930             controlBar
->OnLast(); break; 
 938 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
) 
 940     wxPreviewControlBar 
* 
 941         controlBar 
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar(); 
 945         if ( event
.ControlDown() && event
.GetWheelRotation() != 0 ) 
 947             int currentZoom 
= controlBar
->GetZoomControl(); 
 950             if ( currentZoom 
< 100 ) 
 952             else if ( currentZoom 
<= 120 ) 
 957             if ( event
.GetWheelRotation() > 0 ) 
 960             int newZoom 
= currentZoom 
+ delta
; 
 965             if ( newZoom 
!= currentZoom 
) 
 967                 controlBar
->SetZoomControl(newZoom
); 
 968                 m_printPreview
->SetZoom(newZoom
); 
 978 #endif // wxUSE_MOUSEWHEEL 
 980 //---------------------------------------------------------------------------- 
 981 // wxPreviewControlBar 
 982 //---------------------------------------------------------------------------- 
 984 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
) 
 986 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
) 
 987     EVT_BUTTON(wxID_PREVIEW_CLOSE
,    wxPreviewControlBar::OnWindowClose
) 
 988     EVT_BUTTON(wxID_PREVIEW_PRINT
,    wxPreviewControlBar::OnPrintButton
) 
 989     EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
) 
 990     EVT_BUTTON(wxID_PREVIEW_NEXT
,     wxPreviewControlBar::OnNextButton
) 
 991     EVT_BUTTON(wxID_PREVIEW_FIRST
,    wxPreviewControlBar::OnFirstButton
) 
 992     EVT_BUTTON(wxID_PREVIEW_LAST
,     wxPreviewControlBar::OnLastButton
) 
 993     EVT_BUTTON(wxID_PREVIEW_GOTO
,     wxPreviewControlBar::OnGotoButton
) 
 994     EVT_CHOICE(wxID_PREVIEW_ZOOM
,     wxPreviewControlBar::OnZoom
) 
 995     EVT_PAINT(wxPreviewControlBar::OnPaint
) 
 998 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase 
*preview
, long buttons
, 
 999                                          wxWindow 
*parent
, const wxPoint
& pos
, const wxSize
& size
, 
1000                                          long style
, const wxString
& name
): 
1001 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
) 
1003     m_printPreview 
= preview
; 
1004     m_closeButton 
= (wxButton 
*) NULL
; 
1005     m_nextPageButton 
= (wxButton 
*) NULL
; 
1006     m_previousPageButton 
= (wxButton 
*) NULL
; 
1007     m_printButton 
= (wxButton 
*) NULL
; 
1008     m_zoomControl 
= (wxChoice 
*) NULL
; 
1009     m_buttonFlags 
= buttons
; 
1012 wxPreviewControlBar::~wxPreviewControlBar() 
1016 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
1022     dc
.SetPen(*wxBLACK_PEN
); 
1023     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
1024     dc
.DrawLine( 0, h
-1, w
, h
-1 ); 
1027 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
)) 
1029     wxPreviewFrame 
*frame 
= (wxPreviewFrame 
*)GetParent(); 
1033 void wxPreviewControlBar::OnPrint(void) 
1035     wxPrintPreviewBase 
*preview 
= GetPrintPreview(); 
1036     preview
->Print(true); 
1039 void wxPreviewControlBar::OnNext(void) 
1041     wxPrintPreviewBase 
*preview 
= GetPrintPreview(); 
1044         int currentPage 
= preview
->GetCurrentPage(); 
1045         if ((preview
->GetMaxPage() > 0) && 
1046             (currentPage 
< preview
->GetMaxPage()) && 
1047             preview
->GetPrintout()->HasPage(currentPage 
+ 1)) 
1049             preview
->SetCurrentPage(currentPage 
+ 1); 
1054 void wxPreviewControlBar::OnPrevious(void) 
1056     wxPrintPreviewBase 
*preview 
= GetPrintPreview(); 
1059         int currentPage 
= preview
->GetCurrentPage(); 
1060         if ((preview
->GetMinPage() > 0) && 
1061             (currentPage 
> preview
->GetMinPage()) && 
1062             preview
->GetPrintout()->HasPage(currentPage 
- 1)) 
1064             preview
->SetCurrentPage(currentPage 
- 1); 
1069 void wxPreviewControlBar::OnFirst(void) 
1071     wxPrintPreviewBase 
*preview 
= GetPrintPreview(); 
1074         int currentPage 
= preview
->GetMinPage(); 
1075         if (preview
->GetPrintout()->HasPage(currentPage
)) 
1077             preview
->SetCurrentPage(currentPage
); 
1082 void wxPreviewControlBar::OnLast(void) 
1084     wxPrintPreviewBase 
*preview 
= GetPrintPreview(); 
1087         int currentPage 
= preview
->GetMaxPage(); 
1088         if (preview
->GetPrintout()->HasPage(currentPage
)) 
1090             preview
->SetCurrentPage(currentPage
); 
1095 void wxPreviewControlBar::OnGoto(void) 
1097     wxPrintPreviewBase 
*preview 
= GetPrintPreview(); 
1102         if (preview
->GetMinPage() > 0) 
1107             strPrompt
.Printf( _("Enter a page number between %d and %d:"), 
1108                 preview
->GetMinPage(), preview
->GetMaxPage()); 
1109             strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() ); 
1112                 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent()); 
1114             if ( strPage
.ToLong( ¤tPage 
) ) 
1115                 if (preview
->GetPrintout()->HasPage(currentPage
)) 
1117                     preview
->SetCurrentPage(currentPage
); 
1123 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
)) 
1125     int zoom 
= GetZoomControl(); 
1126     if (GetPrintPreview()) 
1127         GetPrintPreview()->SetZoom(zoom
); 
1130 void wxPreviewControlBar::CreateButtons() 
1132     SetSize(0, 0, 400, 40); 
1134     wxBoxSizer 
*item0 
= new wxBoxSizer( wxHORIZONTAL 
); 
1136     m_closeButton 
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
1137     item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 ); 
1139     if (m_buttonFlags 
& wxPREVIEW_PRINT
) 
1141         m_printButton 
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 ); 
1142         item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 ); 
1145     // Exact-fit buttons are too tiny on wxUniversal 
1147     wxSize navButtonSize
; 
1148 #ifdef __WXUNIVERSAL__ 
1150     navButtonSize 
= wxSize(40, m_closeButton
->GetSize().y
); 
1152     navButtonStyle 
= wxBU_EXACTFIT
; 
1153     navButtonSize 
= wxDefaultSize
; 
1156     if (m_buttonFlags 
& wxPREVIEW_FIRST
) 
1158         m_firstPageButton 
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle 
); 
1159         item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 ); 
1162     if (m_buttonFlags 
& wxPREVIEW_PREVIOUS
) 
1164         m_previousPageButton 
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle 
); 
1165         item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 ); 
1168     if (m_buttonFlags 
& wxPREVIEW_NEXT
) 
1170         m_nextPageButton 
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle 
); 
1171         item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 ); 
1174     if (m_buttonFlags 
& wxPREVIEW_LAST
) 
1176         m_lastPageButton 
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle 
); 
1177         item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 ); 
1180     if (m_buttonFlags 
& wxPREVIEW_GOTO
) 
1182         m_gotoPageButton 
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 ); 
1183         item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 ); 
1186     if (m_buttonFlags 
& wxPREVIEW_ZOOM
) 
1188         wxString choices
[] = 
1190             wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"), 
1191                 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"), 
1192                 wxT("120%"), wxT("150%"), wxT("200%") 
1194         int n 
= WXSIZEOF(choices
); 
1196         m_zoomControl 
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 ); 
1197         item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 ); 
1198         SetZoomControl(m_printPreview
->GetZoom()); 
1205 void wxPreviewControlBar::SetZoomControl(int zoom
) 
1209         int n
, count 
= m_zoomControl
->GetCount(); 
1211         for (n
=0; n
<count
; n
++) 
1213             if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) && 
1214                 (val 
>= long(zoom
))) 
1216                 m_zoomControl
->SetSelection(n
); 
1221         m_zoomControl
->SetSelection(count
-1); 
1225 int wxPreviewControlBar::GetZoomControl() 
1227     if (m_zoomControl 
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
)) 
1230         if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
)) 
1242 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
) 
1244 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
) 
1245     EVT_CHAR_HOOK(wxPreviewFrame::OnChar
) 
1246     EVT_CLOSE(wxPreviewFrame::OnCloseWindow
) 
1249 void wxPreviewFrame::OnChar(wxKeyEvent 
&event
) 
1251     if ( event
.GetKeyCode() == WXK_ESCAPE 
) 
1261 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase 
*preview
, wxWindow 
*parent
, const wxString
& title
, 
1262                                const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
): 
1263 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
) 
1265     m_printPreview 
= preview
; 
1266     m_controlBar 
= NULL
; 
1267     m_previewCanvas 
= NULL
; 
1268     m_windowDisabler 
= NULL
; 
1270     // Give the application icon 
1272     wxFrame
* topFrame 
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
); 
1274         SetIcon(topFrame
->GetIcon()); 
1278 wxPreviewFrame::~wxPreviewFrame() 
1282 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
)) 
1284     if (m_windowDisabler
) 
1285         delete m_windowDisabler
; 
1287     // Need to delete the printout and the print preview 
1288     wxPrintout 
*printout 
= m_printPreview
->GetPrintout(); 
1292         m_printPreview
->SetPrintout(NULL
); 
1293         m_printPreview
->SetCanvas(NULL
); 
1294         m_printPreview
->SetFrame(NULL
); 
1297     m_previewCanvas
->SetPreview(NULL
); 
1298     wxDELETE(m_printPreview
); 
1303 void wxPreviewFrame::Initialize() 
1311     m_printPreview
->SetCanvas(m_previewCanvas
); 
1312     m_printPreview
->SetFrame(this); 
1314     wxBoxSizer 
*item0 
= new wxBoxSizer( wxVERTICAL 
); 
1316     item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 ); 
1317     item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 ); 
1319     SetAutoLayout( true ); 
1322     m_windowDisabler 
= new wxWindowDisabler(this); 
1326     m_printPreview
->AdjustScrollbars(m_previewCanvas
); 
1327     m_previewCanvas
->SetFocus(); 
1328     m_controlBar
->SetFocus(); 
1331 void wxPreviewFrame::CreateCanvas() 
1333     m_previewCanvas 
= new wxPreviewCanvas(m_printPreview
, this); 
1336 void wxPreviewFrame::CreateControlBar() 
1338     long buttons 
= wxPREVIEW_DEFAULT
; 
1339     if (m_printPreview
->GetPrintoutForPrinting()) 
1340         buttons 
|= wxPREVIEW_PRINT
; 
1342     m_controlBar 
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40)); 
1343     m_controlBar
->CreateButtons(); 
1350 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
) 
1352 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout 
*printout
, 
1353                                        wxPrintout 
*printoutForPrinting
, 
1357         m_printDialogData 
= (*data
); 
1359     Init(printout
, printoutForPrinting
); 
1362 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout 
*printout
, 
1363                                        wxPrintout 
*printoutForPrinting
, 
1364                                        wxPrintDialogData 
*data
) 
1367         m_printDialogData 
= (*data
); 
1369     Init(printout
, printoutForPrinting
); 
1372 void wxPrintPreviewBase::Init(wxPrintout 
*printout
, 
1373                               wxPrintout 
*printoutForPrinting
) 
1376     m_previewPrintout 
= printout
; 
1377     if (m_previewPrintout
) 
1378         m_previewPrintout
->SetIsPreview(true); 
1380     m_printPrintout 
= printoutForPrinting
; 
1382     m_previewCanvas 
= NULL
; 
1383     m_previewFrame 
= NULL
; 
1384     m_previewBitmap 
= NULL
; 
1385     m_previewFailed 
= false; 
1392     m_printingPrepared 
= false; 
1397 wxPrintPreviewBase::~wxPrintPreviewBase() 
1399     if (m_previewPrintout
) 
1400         delete m_previewPrintout
; 
1401     if (m_previewBitmap
) 
1402         delete m_previewBitmap
; 
1403     if (m_printPrintout
) 
1404         delete m_printPrintout
; 
1407 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
) 
1409     if (m_currentPage 
== pageNum
) 
1412     m_currentPage 
= pageNum
; 
1414     InvalidatePreviewBitmap(); 
1416     if (m_previewCanvas
) 
1418         AdjustScrollbars(m_previewCanvas
); 
1420         m_previewCanvas
->Refresh(); 
1421         m_previewCanvas
->SetFocus(); 
1426 int wxPrintPreviewBase::GetCurrentPage() const 
1427     { return m_currentPage
; } 
1428 void wxPrintPreviewBase::SetPrintout(wxPrintout 
*printout
) 
1429     { m_previewPrintout 
= printout
; } 
1430 wxPrintout 
*wxPrintPreviewBase::GetPrintout() const 
1431     { return m_previewPrintout
; } 
1432 wxPrintout 
*wxPrintPreviewBase::GetPrintoutForPrinting() const 
1433     { return m_printPrintout
; } 
1434 void wxPrintPreviewBase::SetFrame(wxFrame 
*frame
) 
1435     { m_previewFrame 
= frame
; } 
1436 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas 
*canvas
) 
1437     { m_previewCanvas 
= canvas
; } 
1438 wxFrame 
*wxPrintPreviewBase::GetFrame() const 
1439     { return m_previewFrame
; } 
1440 wxPreviewCanvas 
*wxPrintPreviewBase::GetCanvas() const 
1441     { return m_previewCanvas
; } 
1443 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas 
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
) 
1445     // Calculate the rectangles for the printable area of the page and the 
1446     // entire paper as they appear on the canvas on-screen. 
1447     int canvasWidth
, canvasHeight
; 
1448     canvas
->GetSize(&canvasWidth
, &canvasHeight
); 
1450     float zoomScale 
= float(m_currentZoom
) / 100; 
1451     float screenPrintableWidth 
= zoomScale 
* m_pageWidth 
* m_previewScaleX
; 
1452     float screenPrintableHeight 
= zoomScale 
* m_pageHeight 
* m_previewScaleY
; 
1454     wxRect devicePaperRect 
= m_previewPrintout
->GetPaperRectPixels(); 
1455     wxCoord devicePrintableWidth
, devicePrintableHeight
; 
1456     m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
); 
1457     float scaleX 
= screenPrintableWidth 
/ devicePrintableWidth
; 
1458     float scaleY 
= screenPrintableHeight 
/ devicePrintableHeight
; 
1459     paperRect
.width 
= wxCoord(scaleX 
* devicePaperRect
.width
); 
1460     paperRect
.height 
= wxCoord(scaleY 
* devicePaperRect
.height
); 
1462     paperRect
.x 
= wxCoord((canvasWidth 
- paperRect
.width
)/ 2.0); 
1463     if (paperRect
.x 
< m_leftMargin
) 
1464         paperRect
.x 
= m_leftMargin
; 
1465     paperRect
.y 
= wxCoord((canvasHeight 
- paperRect
.height
)/ 2.0); 
1466     if (paperRect
.y 
< m_topMargin
) 
1467         paperRect
.y 
= m_topMargin
; 
1469     pageRect
.x 
= paperRect
.x 
- wxCoord(scaleX 
* devicePaperRect
.x
); 
1470     pageRect
.y 
= paperRect
.y 
- wxCoord(scaleY 
* devicePaperRect
.y
); 
1471     pageRect
.width 
= wxCoord(screenPrintableWidth
); 
1472     pageRect
.height 
= wxCoord(screenPrintableHeight
); 
1476 void wxPrintPreviewBase::InvalidatePreviewBitmap() 
1478     wxDELETE(m_previewBitmap
); 
1479     // if there was a problem with rendering the preview, try again now 
1480     // that it changed in some way (less memory may be needed, for example): 
1481     m_previewFailed 
= false; 
1484 bool wxPrintPreviewBase::UpdatePageRendering() 
1486     if ( m_previewBitmap 
) 
1489     if ( m_previewFailed 
) 
1492     if ( !RenderPage(m_currentPage
) ) 
1494         m_previewFailed 
= true; // don't waste time failing again 
1501 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas 
*canvas
, wxDC
& dc
) 
1503     DrawBlankPage(canvas
, dc
); 
1505     if (!m_previewBitmap
) 
1510     wxRect pageRect
, paperRect
; 
1511     CalcRects(canvas
, pageRect
, paperRect
); 
1513     temp_dc
.SelectObject(*m_previewBitmap
); 
1515     dc
.Blit(pageRect
.x
, pageRect
.y
,  
1516         m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0); 
1518     temp_dc
.SelectObject(wxNullBitmap
); 
1522 // Adjusts the scrollbars for the current scale 
1523 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas 
*canvas
) 
1528     wxRect pageRect
, paperRect
; 
1529     CalcRects(canvas
, pageRect
, paperRect
); 
1530      int totalWidth 
= paperRect
.width 
+ 2 * m_leftMargin
; 
1531     int totalHeight 
= paperRect
.height 
+ 2 * m_topMargin
; 
1532     int scrollUnitsX 
= totalWidth 
/ 10; 
1533     int scrollUnitsY 
= totalHeight 
/ 10; 
1534     wxSize virtualSize 
= canvas
->GetVirtualSize(); 
1535     if (virtualSize
.GetWidth() != totalWidth 
|| virtualSize
.GetHeight() != totalHeight
) 
1536         canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true); 
1539 bool wxPrintPreviewBase::RenderPageIntoDC(wxDC
& dc
, int pageNum
) 
1541     m_previewPrintout
->SetDC(&dc
); 
1542     m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
); 
1544     // Need to delay OnPreparePrinting() until here, so we have enough 
1546     if (!m_printingPrepared
) 
1548         m_previewPrintout
->OnPreparePrinting(); 
1550         m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
); 
1551         m_printingPrepared 
= true; 
1554     m_previewPrintout
->OnBeginPrinting(); 
1556     if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage())) 
1558         wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
); 
1562     m_previewPrintout
->OnPrintPage(pageNum
); 
1563     m_previewPrintout
->OnEndDocument(); 
1564     m_previewPrintout
->OnEndPrinting(); 
1566     m_previewPrintout
->SetDC(NULL
); 
1571 bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap
& bmp
, int pageNum
) 
1573     wxMemoryDC memoryDC
; 
1574     memoryDC
.SelectObject(bmp
); 
1577     return RenderPageIntoDC(memoryDC
, pageNum
); 
1580 bool wxPrintPreviewBase::RenderPage(int pageNum
) 
1584     if (!m_previewCanvas
) 
1586         wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!")); 
1590     wxRect pageRect
, paperRect
; 
1591     CalcRects(m_previewCanvas
, pageRect
, paperRect
); 
1593     if (!m_previewBitmap
) 
1595         m_previewBitmap 
= new wxBitmap(pageRect
.width
, pageRect
.height
); 
1597         if (!m_previewBitmap 
|| !m_previewBitmap
->Ok()) 
1599             InvalidatePreviewBitmap(); 
1600             wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
); 
1605     if ( !RenderPageIntoBitmap(*m_previewBitmap
, pageNum
) ) 
1607         InvalidatePreviewBitmap(); 
1608         wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
); 
1615         status 
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
); 
1617         status 
= wxString::Format(_("Page %d"), pageNum
); 
1620         m_previewFrame
->SetStatusText(status
); 
1626 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas 
*canvas
, wxDC
& dc
) 
1628     wxRect pageRect
, paperRect
; 
1630     CalcRects(canvas
, pageRect
, paperRect
); 
1632     // Draw shadow, allowing for 1-pixel border AROUND the actual paper 
1633     wxCoord shadowOffset 
= 4; 
1635     dc
.SetPen(*wxBLACK_PEN
); 
1636     dc
.SetBrush(*wxBLACK_BRUSH
); 
1637     dc
.DrawRectangle(paperRect
.x 
+ shadowOffset
, paperRect
.y 
+ paperRect
.height 
+ 1, 
1638         paperRect
.width
, shadowOffset
); 
1640     dc
.DrawRectangle(paperRect
.x 
+ paperRect
.width
, paperRect
.y 
+ shadowOffset
, 
1641         shadowOffset
, paperRect
.height
); 
1643     // Draw blank page allowing for 1-pixel border AROUND the actual paper 
1644     dc
.SetPen(*wxBLACK_PEN
); 
1645     dc
.SetBrush(*wxWHITE_BRUSH
); 
1646     dc
.DrawRectangle(paperRect
.x 
- 2, paperRect
.y 
- 1,  
1647         paperRect
.width 
+ 3, paperRect
.height 
+ 2); 
1652 void wxPrintPreviewBase::SetZoom(int percent
) 
1654     if (m_currentZoom 
== percent
) 
1657     m_currentZoom 
= percent
; 
1659     InvalidatePreviewBitmap(); 
1661     if (m_previewCanvas
) 
1663         AdjustScrollbars(m_previewCanvas
); 
1664         ((wxScrolledWindow 
*) m_previewCanvas
)->Scroll(0, 0); 
1665         m_previewCanvas
->ClearBackground(); 
1666         m_previewCanvas
->Refresh(); 
1667         m_previewCanvas
->SetFocus(); 
1671 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData() 
1673     return m_printDialogData
; 
1676 int wxPrintPreviewBase::GetZoom() const 
1677 { return m_currentZoom
; } 
1678 int wxPrintPreviewBase::GetMaxPage() const 
1679 { return m_maxPage
; } 
1680 int wxPrintPreviewBase::GetMinPage() const 
1681 { return m_minPage
; } 
1682 bool wxPrintPreviewBase::IsOk() const 
1684 void wxPrintPreviewBase::SetOk(bool ok
) 
1687 //---------------------------------------------------------------------------- 
1689 //---------------------------------------------------------------------------- 
1691 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
) 
1693 wxPrintPreview::wxPrintPreview(wxPrintout 
*printout
, 
1694                    wxPrintout 
*printoutForPrinting
, 
1695                    wxPrintDialogData 
*data
) : 
1696     wxPrintPreviewBase( printout
, printoutForPrinting
, data 
) 
1698     m_pimpl 
= wxPrintFactory::GetFactory()-> 
1699         CreatePrintPreview( printout
, printoutForPrinting
, data 
); 
1702 wxPrintPreview::wxPrintPreview(wxPrintout 
*printout
, 
1703                    wxPrintout 
*printoutForPrinting
, 
1704                    wxPrintData 
*data 
) : 
1705     wxPrintPreviewBase( printout
, printoutForPrinting
, data 
) 
1707     m_pimpl 
= wxPrintFactory::GetFactory()-> 
1708         CreatePrintPreview( printout
, printoutForPrinting
, data 
); 
1711 wxPrintPreview::~wxPrintPreview() 
1715     // don't delete twice 
1716     m_printPrintout 
= NULL
; 
1717     m_previewPrintout 
= NULL
; 
1718     m_previewBitmap 
= NULL
; 
1721 bool wxPrintPreview::SetCurrentPage(int pageNum
) 
1723     return m_pimpl
->SetCurrentPage( pageNum 
); 
1726 int wxPrintPreview::GetCurrentPage() const 
1728     return m_pimpl
->GetCurrentPage(); 
1731 void wxPrintPreview::SetPrintout(wxPrintout 
*printout
) 
1733     m_pimpl
->SetPrintout( printout 
); 
1736 wxPrintout 
*wxPrintPreview::GetPrintout() const 
1738     return m_pimpl
->GetPrintout(); 
1741 wxPrintout 
*wxPrintPreview::GetPrintoutForPrinting() const 
1743     return m_pimpl
->GetPrintoutForPrinting(); 
1746 void wxPrintPreview::SetFrame(wxFrame 
*frame
) 
1748     m_pimpl
->SetFrame( frame 
); 
1751 void wxPrintPreview::SetCanvas(wxPreviewCanvas 
*canvas
) 
1753     m_pimpl
->SetCanvas( canvas 
); 
1756 wxFrame 
*wxPrintPreview::GetFrame() const 
1758     return m_pimpl
->GetFrame(); 
1761 wxPreviewCanvas 
*wxPrintPreview::GetCanvas() const 
1763     return m_pimpl
->GetCanvas(); 
1766 bool wxPrintPreview::PaintPage(wxPreviewCanvas 
*canvas
, wxDC
& dc
) 
1768     return m_pimpl
->PaintPage( canvas
, dc 
); 
1771 bool wxPrintPreview::UpdatePageRendering() 
1773     return m_pimpl
->UpdatePageRendering(); 
1776 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas 
*canvas
, wxDC
& dc
) 
1778     return m_pimpl
->DrawBlankPage( canvas
, dc 
); 
1781 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas 
*canvas
) 
1783     m_pimpl
->AdjustScrollbars( canvas 
); 
1786 bool wxPrintPreview::RenderPage(int pageNum
) 
1788     return m_pimpl
->RenderPage( pageNum 
); 
1791 void wxPrintPreview::SetZoom(int percent
) 
1793     m_pimpl
->SetZoom( percent 
); 
1796 int wxPrintPreview::GetZoom() const 
1798     return m_pimpl
->GetZoom(); 
1801 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData() 
1803     return m_pimpl
->GetPrintDialogData(); 
1806 int wxPrintPreview::GetMaxPage() const 
1808     return m_pimpl
->GetMaxPage(); 
1811 int wxPrintPreview::GetMinPage() const 
1813     return m_pimpl
->GetMinPage(); 
1816 bool wxPrintPreview::IsOk() const 
1818     return m_pimpl
->Ok(); 
1821 void wxPrintPreview::SetOk(bool ok
) 
1823     m_pimpl
->SetOk( ok 
); 
1826 bool wxPrintPreview::Print(bool interactive
) 
1828     return m_pimpl
->Print( interactive 
); 
1831 void wxPrintPreview::DetermineScaling() 
1833     m_pimpl
->DetermineScaling(); 
1836 #endif // wxUSE_PRINTING_ARCHITECTURE