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 new wxMacCarbonPrintData
;
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
= (wxWindow
*) NULL
;
518 //----------------------------------------------------------------------------
520 //----------------------------------------------------------------------------
522 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
)
524 wxPrintout::wxPrintout(const wxString
& title
)
526 m_printoutTitle
= title
;
527 m_printoutDC
= (wxDC
*) NULL
;
530 m_pageWidthPixels
= 0;
531 m_pageHeightPixels
= 0;
539 wxPrintout::~wxPrintout()
543 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
))
545 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
);
548 void wxPrintout::OnEndDocument()
553 void wxPrintout::OnBeginPrinting()
557 void wxPrintout::OnEndPrinting()
561 bool wxPrintout::HasPage(int page
)
566 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
)
574 void wxPrintout::FitThisSizeToPaper(const wxSize
& imageSize
)
576 // Set the DC scale and origin so that the given image size fits within the
577 // entire page and the origin is at the top left corner of the page. Note
578 // that with most printers, portions of the page will be non-printable. Use
579 // this if you're managing your own page margins.
580 if (!m_printoutDC
) return;
581 wxRect paperRect
= GetPaperRectPixels();
583 GetPageSizePixels(&pw
, &ph
);
585 m_printoutDC
->GetSize(&w
, &h
);
586 float scaleX
= ((float(paperRect
.width
) * w
) / (float(pw
) * imageSize
.x
));
587 float scaleY
= ((float(paperRect
.height
) * h
) / (float(ph
) * imageSize
.y
));
588 float actualScale
= wxMin(scaleX
, scaleY
);
589 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
590 m_printoutDC
->SetDeviceOrigin(0, 0);
591 wxRect logicalPaperRect
= GetLogicalPaperRect();
592 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
595 void wxPrintout::FitThisSizeToPage(const wxSize
& imageSize
)
597 // Set the DC scale and origin so that the given image size fits within the
598 // printable area of the page and the origin is at the top left corner of
599 // the printable area.
600 if (!m_printoutDC
) return;
602 m_printoutDC
->GetSize(&w
, &h
);
603 float scaleX
= float(w
) / imageSize
.x
;
604 float scaleY
= float(h
) / imageSize
.y
;
605 float actualScale
= wxMin(scaleX
, scaleY
);
606 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
607 m_printoutDC
->SetDeviceOrigin(0, 0);
610 void wxPrintout::FitThisSizeToPageMargins(const wxSize
& imageSize
, const wxPageSetupDialogData
& pageSetupData
)
612 // Set the DC scale and origin so that the given image size fits within the
613 // page margins defined in the given wxPageSetupDialogData object and the
614 // origin is at the top left corner of the page margins.
615 if (!m_printoutDC
) return;
616 wxRect paperRect
= GetPaperRectPixels();
618 GetPageSizePixels(&pw
, &ph
);
619 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
620 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
622 GetPageSizeMM(&mw
, &mh
);
623 float mmToDeviceX
= float(pw
) / mw
;
624 float mmToDeviceY
= float(ph
) / mh
;
625 wxRect
pageMarginsRect(paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
626 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
627 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
628 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
630 m_printoutDC
->GetSize(&w
, &h
);
631 float scaleX
= (float(pageMarginsRect
.width
) * w
) / (float(pw
) * imageSize
.x
);
632 float scaleY
= (float(pageMarginsRect
.height
) * h
) / (float(ph
) * imageSize
.y
);
633 float actualScale
= wxMin(scaleX
, scaleY
);
634 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
635 m_printoutDC
->SetDeviceOrigin(0, 0);
636 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
637 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
640 void wxPrintout::MapScreenSizeToPaper()
642 // Set the DC scale so that an image on the screen is the same size on the
643 // paper and the origin is at the top left of the paper. Note that with most
644 // printers, portions of the page will be cut off. Use this if you're
645 // managing your own page margins.
646 if (!m_printoutDC
) return;
647 MapScreenSizeToPage();
648 wxRect logicalPaperRect
= GetLogicalPaperRect();
649 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
652 void wxPrintout::MapScreenSizeToPage()
654 // Set the DC scale and origin so that an image on the screen is the same
655 // size on the paper and the origin is at the top left of the printable area.
656 if (!m_printoutDC
) return;
657 int ppiScreenX
, ppiScreenY
;
658 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
659 int ppiPrinterX
, ppiPrinterY
;
660 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
662 m_printoutDC
->GetSize(&w
, &h
);
663 int pageSizePixelsX
, pageSizePixelsY
;
664 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
665 float userScaleX
= (float(ppiPrinterX
) * w
) / (float(ppiScreenX
) * pageSizePixelsX
);
666 float userScaleY
= (float(ppiPrinterY
) * h
) / (float(ppiScreenY
) * pageSizePixelsY
);
667 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
668 m_printoutDC
->SetDeviceOrigin(0, 0);
671 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData
& pageSetupData
)
673 // Set the DC scale so that an image on the screen is the same size on the
674 // paper and the origin is at the top left of the page margins defined by
675 // the given wxPageSetupDialogData object.
676 if (!m_printoutDC
) return;
677 MapScreenSizeToPage();
678 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
679 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
682 void wxPrintout::MapScreenSizeToDevice()
684 // Set the DC scale so that a screen pixel is the same size as a device
685 // pixel and the origin is at the top left of the printable area.
686 if (!m_printoutDC
) return;
688 m_printoutDC
->GetSize(&w
, &h
);
689 int pageSizePixelsX
, pageSizePixelsY
;
690 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
691 float userScaleX
= float(w
) / pageSizePixelsX
;
692 float userScaleY
= float(h
) / pageSizePixelsY
;
693 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
694 m_printoutDC
->SetDeviceOrigin(0, 0);
697 wxRect
wxPrintout::GetLogicalPaperRect() const
699 // Return the rectangle in logical units that corresponds to the paper
701 wxRect paperRect
= GetPaperRectPixels();
703 GetPageSizePixels(&pw
, &ph
);
705 m_printoutDC
->GetSize(&w
, &h
);
706 if (w
== pw
&& h
== ph
) {
707 // this DC matches the printed page, so no scaling
708 return wxRect(m_printoutDC
->DeviceToLogicalX(paperRect
.x
),
709 m_printoutDC
->DeviceToLogicalY(paperRect
.y
),
710 m_printoutDC
->DeviceToLogicalXRel(paperRect
.width
),
711 m_printoutDC
->DeviceToLogicalYRel(paperRect
.height
));
713 // This DC doesn't match the printed page, so we have to scale.
714 float scaleX
= float(w
) / pw
;
715 float scaleY
= float(h
) / ph
;
716 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(paperRect
.x
* scaleX
)),
717 m_printoutDC
->DeviceToLogicalY(wxRound(paperRect
.y
* scaleY
)),
718 m_printoutDC
->DeviceToLogicalXRel(wxRound(paperRect
.width
* scaleX
)),
719 m_printoutDC
->DeviceToLogicalYRel(wxRound(paperRect
.height
* scaleY
)));
722 wxRect
wxPrintout::GetLogicalPageRect() const
724 // Return the rectangle in logical units that corresponds to the printable
727 m_printoutDC
->GetSize(&w
, &h
);
728 return wxRect(m_printoutDC
->DeviceToLogicalX(0),
729 m_printoutDC
->DeviceToLogicalY(0),
730 m_printoutDC
->DeviceToLogicalXRel(w
),
731 m_printoutDC
->DeviceToLogicalYRel(h
));
734 wxRect
wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData
& pageSetupData
) const
736 // Return the rectangle in logical units that corresponds to the region
737 // within the page margins as specified by the given wxPageSetupDialogData
740 // We get the paper size in device units and the margins in mm,
741 // so we need to calculate the conversion with this trick
743 GetPageSizePixels(&pw
, &ph
);
745 GetPageSizeMM(&mw
, &mh
);
746 float mmToDeviceX
= float(pw
) / mw
;
747 float mmToDeviceY
= float(ph
) / mh
;
749 // paper size in device units
750 wxRect paperRect
= GetPaperRectPixels();
753 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
754 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
756 // calculate margins in device units
757 wxRect
pageMarginsRect(
758 paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
759 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
760 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
761 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
764 m_printoutDC
->GetSize(&w
, &h
);
765 if (w
== pw
&& h
== ph
)
767 // this DC matches the printed page, so no scaling
769 m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),
770 m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),
771 m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),
772 m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
));
775 // This DC doesn't match the printed page, so we have to scale.
776 float scaleX
= float(w
) / pw
;
777 float scaleY
= float(h
) / ph
;
778 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(pageMarginsRect
.x
* scaleX
)),
779 m_printoutDC
->DeviceToLogicalY(wxRound(pageMarginsRect
.y
* scaleY
)),
780 m_printoutDC
->DeviceToLogicalXRel(wxRound(pageMarginsRect
.width
* scaleX
)),
781 m_printoutDC
->DeviceToLogicalYRel(wxRound(pageMarginsRect
.height
* scaleY
)));
784 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
)
786 // Set the device origin by specifying a point in logical coordinates.
787 m_printoutDC
->SetDeviceOrigin(
788 m_printoutDC
->LogicalToDeviceX(x
),
789 m_printoutDC
->LogicalToDeviceY(y
) );
792 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
)
794 // Offset the device origin by a specified distance in device coordinates.
795 wxPoint dev_org
= m_printoutDC
->GetDeviceOrigin();
796 m_printoutDC
->SetDeviceOrigin(
797 dev_org
.x
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),
798 dev_org
.y
+ m_printoutDC
->LogicalToDeviceYRel(yoff
) );
802 //----------------------------------------------------------------------------
804 //----------------------------------------------------------------------------
806 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
808 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
809 EVT_PAINT(wxPreviewCanvas::OnPaint
)
810 EVT_CHAR(wxPreviewCanvas::OnChar
)
811 EVT_IDLE(wxPreviewCanvas::OnIdle
)
812 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
814 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
818 // VZ: the current code doesn't refresh properly without
819 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
820 // really horrible flicker when resizing the preview frame, but without
821 // this style it simply doesn't work correctly at all...
822 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
823 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
824 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
826 m_printPreview
= preview
;
828 // The app workspace colour is always white, but we should have
829 // a contrast with the page.
830 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
831 #elif defined(__WXGTK__)
832 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
834 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
836 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
838 SetScrollbars(10, 10, 100, 100);
841 wxPreviewCanvas::~wxPreviewCanvas()
845 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
852 if (!GetUpdateRegion().IsEmpty())
853 dc.SetClippingRegion( GetUpdateRegion() );
859 m_printPreview
->PaintPage(this, dc
);
863 void wxPreviewCanvas::OnIdle(wxIdleEvent
& event
)
867 // prevent UpdatePageRendering() from being called recursively:
868 static bool s_inIdle
= false;
873 if ( m_printPreview
)
875 if ( m_printPreview
->UpdatePageRendering() )
882 // Responds to colour changes, and passes event on to children.
883 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
886 // The app workspace colour is always white, but we should have
887 // a contrast with the page.
888 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
889 #elif defined(__WXGTK__)
890 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
892 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
894 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
897 // Propagate the event to the non-top-level children
898 wxWindow::OnSysColourChanged(event
);
901 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
903 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
904 switch (event
.GetKeyCode())
907 controlBar
->OnGoto();
910 controlBar
->OnPrint();
914 if (!event
.ControlDown())
920 switch(event
.GetKeyCode())
923 controlBar
->OnNext(); break;
925 controlBar
->OnPrevious(); break;
927 controlBar
->OnFirst(); break;
929 controlBar
->OnLast(); break;
937 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
939 wxPreviewControlBar
*
940 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
944 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
946 int currentZoom
= controlBar
->GetZoomControl();
949 if ( currentZoom
< 100 )
951 else if ( currentZoom
<= 120 )
956 if ( event
.GetWheelRotation() > 0 )
959 int newZoom
= currentZoom
+ delta
;
964 if ( newZoom
!= currentZoom
)
966 controlBar
->SetZoomControl(newZoom
);
967 m_printPreview
->SetZoom(newZoom
);
977 #endif // wxUSE_MOUSEWHEEL
979 //----------------------------------------------------------------------------
980 // wxPreviewControlBar
981 //----------------------------------------------------------------------------
983 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
985 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
986 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
987 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
988 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
989 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
990 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
991 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
992 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
993 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
994 EVT_PAINT(wxPreviewControlBar::OnPaint
)
997 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
998 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
999 long style
, const wxString
& name
):
1000 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
1002 m_printPreview
= preview
;
1003 m_closeButton
= (wxButton
*) NULL
;
1004 m_nextPageButton
= (wxButton
*) NULL
;
1005 m_previousPageButton
= (wxButton
*) NULL
;
1006 m_printButton
= (wxButton
*) NULL
;
1007 m_zoomControl
= (wxChoice
*) NULL
;
1008 m_buttonFlags
= buttons
;
1011 wxPreviewControlBar::~wxPreviewControlBar()
1015 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1021 dc
.SetPen(*wxBLACK_PEN
);
1022 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1023 dc
.DrawLine( 0, h
-1, w
, h
-1 );
1026 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
1028 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1032 void wxPreviewControlBar::OnPrint(void)
1034 wxPrintPreviewBase
*preview
= GetPrintPreview();
1035 preview
->Print(true);
1038 void wxPreviewControlBar::OnNext(void)
1040 wxPrintPreviewBase
*preview
= GetPrintPreview();
1043 int currentPage
= preview
->GetCurrentPage();
1044 if ((preview
->GetMaxPage() > 0) &&
1045 (currentPage
< preview
->GetMaxPage()) &&
1046 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1048 preview
->SetCurrentPage(currentPage
+ 1);
1053 void wxPreviewControlBar::OnPrevious(void)
1055 wxPrintPreviewBase
*preview
= GetPrintPreview();
1058 int currentPage
= preview
->GetCurrentPage();
1059 if ((preview
->GetMinPage() > 0) &&
1060 (currentPage
> preview
->GetMinPage()) &&
1061 preview
->GetPrintout()->HasPage(currentPage
- 1))
1063 preview
->SetCurrentPage(currentPage
- 1);
1068 void wxPreviewControlBar::OnFirst(void)
1070 wxPrintPreviewBase
*preview
= GetPrintPreview();
1073 int currentPage
= preview
->GetMinPage();
1074 if (preview
->GetPrintout()->HasPage(currentPage
))
1076 preview
->SetCurrentPage(currentPage
);
1081 void wxPreviewControlBar::OnLast(void)
1083 wxPrintPreviewBase
*preview
= GetPrintPreview();
1086 int currentPage
= preview
->GetMaxPage();
1087 if (preview
->GetPrintout()->HasPage(currentPage
))
1089 preview
->SetCurrentPage(currentPage
);
1094 void wxPreviewControlBar::OnGoto(void)
1096 wxPrintPreviewBase
*preview
= GetPrintPreview();
1101 if (preview
->GetMinPage() > 0)
1106 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1107 preview
->GetMinPage(), preview
->GetMaxPage());
1108 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1111 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1113 if ( strPage
.ToLong( ¤tPage
) )
1114 if (preview
->GetPrintout()->HasPage(currentPage
))
1116 preview
->SetCurrentPage(currentPage
);
1122 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1124 int zoom
= GetZoomControl();
1125 if (GetPrintPreview())
1126 GetPrintPreview()->SetZoom(zoom
);
1129 void wxPreviewControlBar::CreateButtons()
1131 SetSize(0, 0, 400, 40);
1133 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1135 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1136 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1138 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1140 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1141 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1144 // Exact-fit buttons are too tiny on wxUniversal
1146 wxSize navButtonSize
;
1147 #ifdef __WXUNIVERSAL__
1149 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1151 navButtonStyle
= wxBU_EXACTFIT
;
1152 navButtonSize
= wxDefaultSize
;
1155 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1157 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1158 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1161 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1163 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1164 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1167 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1169 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1170 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1173 if (m_buttonFlags
& wxPREVIEW_LAST
)
1175 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1176 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1179 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1181 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1182 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1185 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1187 wxString choices
[] =
1189 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1190 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1191 wxT("120%"), wxT("150%"), wxT("200%")
1193 int n
= WXSIZEOF(choices
);
1195 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1196 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1197 SetZoomControl(m_printPreview
->GetZoom());
1204 void wxPreviewControlBar::SetZoomControl(int zoom
)
1208 int n
, count
= m_zoomControl
->GetCount();
1210 for (n
=0; n
<count
; n
++)
1212 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1213 (val
>= long(zoom
)))
1215 m_zoomControl
->SetSelection(n
);
1220 m_zoomControl
->SetSelection(count
-1);
1224 int wxPreviewControlBar::GetZoomControl()
1226 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1229 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1241 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1243 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1244 EVT_CHAR_HOOK(wxPreviewFrame::OnChar
)
1245 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1248 void wxPreviewFrame::OnChar(wxKeyEvent
&event
)
1250 if ( event
.GetKeyCode() == WXK_ESCAPE
)
1260 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1261 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1262 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1264 m_printPreview
= preview
;
1265 m_controlBar
= NULL
;
1266 m_previewCanvas
= NULL
;
1267 m_windowDisabler
= NULL
;
1269 // Give the application icon
1271 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1273 SetIcon(topFrame
->GetIcon());
1277 wxPreviewFrame::~wxPreviewFrame()
1281 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1283 if (m_windowDisabler
)
1284 delete m_windowDisabler
;
1286 // Need to delete the printout and the print preview
1287 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1291 m_printPreview
->SetPrintout(NULL
);
1292 m_printPreview
->SetCanvas(NULL
);
1293 m_printPreview
->SetFrame(NULL
);
1296 m_previewCanvas
->SetPreview(NULL
);
1297 wxDELETE(m_printPreview
);
1302 void wxPreviewFrame::Initialize()
1310 m_printPreview
->SetCanvas(m_previewCanvas
);
1311 m_printPreview
->SetFrame(this);
1313 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1315 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1316 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1318 SetAutoLayout( true );
1321 m_windowDisabler
= new wxWindowDisabler(this);
1325 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1326 m_previewCanvas
->SetFocus();
1327 m_controlBar
->SetFocus();
1330 void wxPreviewFrame::CreateCanvas()
1332 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1335 void wxPreviewFrame::CreateControlBar()
1337 long buttons
= wxPREVIEW_DEFAULT
;
1338 if (m_printPreview
->GetPrintoutForPrinting())
1339 buttons
|= wxPREVIEW_PRINT
;
1341 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1342 m_controlBar
->CreateButtons();
1349 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1351 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1352 wxPrintout
*printoutForPrinting
,
1356 m_printDialogData
= (*data
);
1358 Init(printout
, printoutForPrinting
);
1361 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1362 wxPrintout
*printoutForPrinting
,
1363 wxPrintDialogData
*data
)
1366 m_printDialogData
= (*data
);
1368 Init(printout
, printoutForPrinting
);
1371 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1372 wxPrintout
*printoutForPrinting
)
1375 m_previewPrintout
= printout
;
1376 if (m_previewPrintout
)
1377 m_previewPrintout
->SetIsPreview(true);
1379 m_printPrintout
= printoutForPrinting
;
1381 m_previewCanvas
= NULL
;
1382 m_previewFrame
= NULL
;
1383 m_previewBitmap
= NULL
;
1384 m_previewFailed
= false;
1391 m_printingPrepared
= false;
1396 wxPrintPreviewBase::~wxPrintPreviewBase()
1398 if (m_previewPrintout
)
1399 delete m_previewPrintout
;
1400 if (m_previewBitmap
)
1401 delete m_previewBitmap
;
1402 if (m_printPrintout
)
1403 delete m_printPrintout
;
1406 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1408 if (m_currentPage
== pageNum
)
1411 m_currentPage
= pageNum
;
1413 InvalidatePreviewBitmap();
1415 if (m_previewCanvas
)
1417 AdjustScrollbars(m_previewCanvas
);
1419 m_previewCanvas
->Refresh();
1420 m_previewCanvas
->SetFocus();
1425 int wxPrintPreviewBase::GetCurrentPage() const
1426 { return m_currentPage
; }
1427 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1428 { m_previewPrintout
= printout
; }
1429 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1430 { return m_previewPrintout
; }
1431 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1432 { return m_printPrintout
; }
1433 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1434 { m_previewFrame
= frame
; }
1435 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1436 { m_previewCanvas
= canvas
; }
1437 wxFrame
*wxPrintPreviewBase::GetFrame() const
1438 { return m_previewFrame
; }
1439 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1440 { return m_previewCanvas
; }
1442 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1444 // Calculate the rectangles for the printable area of the page and the
1445 // entire paper as they appear on the canvas on-screen.
1446 int canvasWidth
, canvasHeight
;
1447 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1449 float zoomScale
= float(m_currentZoom
) / 100;
1450 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1451 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1453 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1454 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1455 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1456 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1457 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1458 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1459 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1461 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1462 if (paperRect
.x
< m_leftMargin
)
1463 paperRect
.x
= m_leftMargin
;
1464 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1465 if (paperRect
.y
< m_topMargin
)
1466 paperRect
.y
= m_topMargin
;
1468 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1469 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1470 pageRect
.width
= wxCoord(screenPrintableWidth
);
1471 pageRect
.height
= wxCoord(screenPrintableHeight
);
1475 void wxPrintPreviewBase::InvalidatePreviewBitmap()
1477 wxDELETE(m_previewBitmap
);
1478 // if there was a problem with rendering the preview, try again now
1479 // that it changed in some way (less memory may be needed, for example):
1480 m_previewFailed
= false;
1483 bool wxPrintPreviewBase::UpdatePageRendering()
1485 if ( m_previewBitmap
)
1488 if ( m_previewFailed
)
1491 if ( !RenderPage(m_currentPage
) )
1493 m_previewFailed
= true; // don't waste time failing again
1500 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1502 DrawBlankPage(canvas
, dc
);
1504 if (!m_previewBitmap
)
1509 wxRect pageRect
, paperRect
;
1510 CalcRects(canvas
, pageRect
, paperRect
);
1512 temp_dc
.SelectObject(*m_previewBitmap
);
1514 dc
.Blit(pageRect
.x
, pageRect
.y
,
1515 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1517 temp_dc
.SelectObject(wxNullBitmap
);
1521 // Adjusts the scrollbars for the current scale
1522 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1527 wxRect pageRect
, paperRect
;
1528 CalcRects(canvas
, pageRect
, paperRect
);
1529 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1530 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1531 int scrollUnitsX
= totalWidth
/ 10;
1532 int scrollUnitsY
= totalHeight
/ 10;
1533 wxSize virtualSize
= canvas
->GetVirtualSize();
1534 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1535 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1538 bool wxPrintPreviewBase::RenderPageIntoDC(wxDC
& dc
, int pageNum
)
1540 m_previewPrintout
->SetDC(&dc
);
1541 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1543 // Need to delay OnPreparePrinting() until here, so we have enough
1545 if (!m_printingPrepared
)
1547 m_previewPrintout
->OnPreparePrinting();
1549 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1550 m_printingPrepared
= true;
1553 m_previewPrintout
->OnBeginPrinting();
1555 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1557 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1561 m_previewPrintout
->OnPrintPage(pageNum
);
1562 m_previewPrintout
->OnEndDocument();
1563 m_previewPrintout
->OnEndPrinting();
1565 m_previewPrintout
->SetDC(NULL
);
1570 bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap
& bmp
, int pageNum
)
1572 wxMemoryDC memoryDC
;
1573 memoryDC
.SelectObject(bmp
);
1576 return RenderPageIntoDC(memoryDC
, pageNum
);
1579 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1583 if (!m_previewCanvas
)
1585 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1589 wxRect pageRect
, paperRect
;
1590 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1592 if (!m_previewBitmap
)
1594 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1596 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1598 InvalidatePreviewBitmap();
1599 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1604 if ( !RenderPageIntoBitmap(*m_previewBitmap
, pageNum
) )
1606 InvalidatePreviewBitmap();
1607 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1614 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1616 status
= wxString::Format(_("Page %d"), pageNum
);
1619 m_previewFrame
->SetStatusText(status
);
1625 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1627 wxRect pageRect
, paperRect
;
1629 CalcRects(canvas
, pageRect
, paperRect
);
1631 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1632 wxCoord shadowOffset
= 4;
1634 dc
.SetPen(*wxBLACK_PEN
);
1635 dc
.SetBrush(*wxBLACK_BRUSH
);
1636 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1637 paperRect
.width
, shadowOffset
);
1639 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1640 shadowOffset
, paperRect
.height
);
1642 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1643 dc
.SetPen(*wxBLACK_PEN
);
1644 dc
.SetBrush(*wxWHITE_BRUSH
);
1645 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1646 paperRect
.width
+ 3, paperRect
.height
+ 2);
1651 void wxPrintPreviewBase::SetZoom(int percent
)
1653 if (m_currentZoom
== percent
)
1656 m_currentZoom
= percent
;
1658 InvalidatePreviewBitmap();
1660 if (m_previewCanvas
)
1662 AdjustScrollbars(m_previewCanvas
);
1663 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1664 m_previewCanvas
->ClearBackground();
1665 m_previewCanvas
->Refresh();
1666 m_previewCanvas
->SetFocus();
1670 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1672 return m_printDialogData
;
1675 int wxPrintPreviewBase::GetZoom() const
1676 { return m_currentZoom
; }
1677 int wxPrintPreviewBase::GetMaxPage() const
1678 { return m_maxPage
; }
1679 int wxPrintPreviewBase::GetMinPage() const
1680 { return m_minPage
; }
1681 bool wxPrintPreviewBase::IsOk() const
1683 void wxPrintPreviewBase::SetOk(bool ok
)
1686 //----------------------------------------------------------------------------
1688 //----------------------------------------------------------------------------
1690 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1692 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1693 wxPrintout
*printoutForPrinting
,
1694 wxPrintDialogData
*data
) :
1695 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1697 m_pimpl
= wxPrintFactory::GetFactory()->
1698 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1701 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1702 wxPrintout
*printoutForPrinting
,
1703 wxPrintData
*data
) :
1704 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1706 m_pimpl
= wxPrintFactory::GetFactory()->
1707 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1710 wxPrintPreview::~wxPrintPreview()
1714 // don't delete twice
1715 m_printPrintout
= NULL
;
1716 m_previewPrintout
= NULL
;
1717 m_previewBitmap
= NULL
;
1720 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1722 return m_pimpl
->SetCurrentPage( pageNum
);
1725 int wxPrintPreview::GetCurrentPage() const
1727 return m_pimpl
->GetCurrentPage();
1730 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1732 m_pimpl
->SetPrintout( printout
);
1735 wxPrintout
*wxPrintPreview::GetPrintout() const
1737 return m_pimpl
->GetPrintout();
1740 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1742 return m_pimpl
->GetPrintoutForPrinting();
1745 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1747 m_pimpl
->SetFrame( frame
);
1750 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1752 m_pimpl
->SetCanvas( canvas
);
1755 wxFrame
*wxPrintPreview::GetFrame() const
1757 return m_pimpl
->GetFrame();
1760 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1762 return m_pimpl
->GetCanvas();
1765 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1767 return m_pimpl
->PaintPage( canvas
, dc
);
1770 bool wxPrintPreview::UpdatePageRendering()
1772 return m_pimpl
->UpdatePageRendering();
1775 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1777 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1780 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1782 m_pimpl
->AdjustScrollbars( canvas
);
1785 bool wxPrintPreview::RenderPage(int pageNum
)
1787 return m_pimpl
->RenderPage( pageNum
);
1790 void wxPrintPreview::SetZoom(int percent
)
1792 m_pimpl
->SetZoom( percent
);
1795 int wxPrintPreview::GetZoom() const
1797 return m_pimpl
->GetZoom();
1800 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1802 return m_pimpl
->GetPrintDialogData();
1805 int wxPrintPreview::GetMaxPage() const
1807 return m_pimpl
->GetMaxPage();
1810 int wxPrintPreview::GetMinPage() const
1812 return m_pimpl
->GetMinPage();
1815 bool wxPrintPreview::IsOk() const
1817 return m_pimpl
->Ok();
1820 void wxPrintPreview::SetOk(bool ok
)
1822 m_pimpl
->SetOk( ok
);
1825 bool wxPrintPreview::Print(bool interactive
)
1827 return m_pimpl
->Print( interactive
);
1830 void wxPrintPreview::DetermineScaling()
1832 m_pimpl
->DetermineScaling();
1835 #endif // wxUSE_PRINTING_ARCHITECTURE