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