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/mac/printdlg.h"
58 #include "wx/mac/private/print.h"
59 #include "wx/mac/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__)
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_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
813 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
817 // VZ: the current code doesn't refresh properly without
818 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
819 // really horrible flicker when resizing the preview frame, but without
820 // this style it simply doesn't work correctly at all...
821 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
822 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
823 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
825 m_printPreview
= preview
;
827 // The app workspace colour is always white, but we should have
828 // a contrast with the page.
829 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
830 #elif defined(__WXGTK__)
831 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
833 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
835 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
837 SetScrollbars(10, 10, 100, 100);
840 wxPreviewCanvas::~wxPreviewCanvas()
844 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
851 if (!GetUpdateRegion().IsEmpty())
852 dc.SetClippingRegion( GetUpdateRegion() );
858 m_printPreview
->PaintPage(this, dc
);
862 // Responds to colour changes, and passes event on to children.
863 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
866 // The app workspace colour is always white, but we should have
867 // a contrast with the page.
868 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
869 #elif defined(__WXGTK__)
870 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
872 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
874 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
877 // Propagate the event to the non-top-level children
878 wxWindow::OnSysColourChanged(event
);
881 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
883 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
884 switch (event
.GetKeyCode())
887 controlBar
->OnGoto();
890 controlBar
->OnPrint();
894 if (!event
.ControlDown())
900 switch(event
.GetKeyCode())
903 controlBar
->OnNext(); break;
905 controlBar
->OnPrevious(); break;
907 controlBar
->OnFirst(); break;
909 controlBar
->OnLast(); break;
917 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
919 wxPreviewControlBar
*
920 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
924 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
926 int currentZoom
= controlBar
->GetZoomControl();
929 if ( currentZoom
< 100 )
931 else if ( currentZoom
<= 120 )
936 if ( event
.GetWheelRotation() > 0 )
939 int newZoom
= currentZoom
+ delta
;
944 if ( newZoom
!= currentZoom
)
946 controlBar
->SetZoomControl(newZoom
);
947 m_printPreview
->SetZoom(newZoom
);
957 #endif // wxUSE_MOUSEWHEEL
959 //----------------------------------------------------------------------------
960 // wxPreviewControlBar
961 //----------------------------------------------------------------------------
963 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
965 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
966 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
967 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
968 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
969 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
970 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
971 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
972 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
973 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
974 EVT_PAINT(wxPreviewControlBar::OnPaint
)
977 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
978 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
979 long style
, const wxString
& name
):
980 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
982 m_printPreview
= preview
;
983 m_closeButton
= (wxButton
*) NULL
;
984 m_nextPageButton
= (wxButton
*) NULL
;
985 m_previousPageButton
= (wxButton
*) NULL
;
986 m_printButton
= (wxButton
*) NULL
;
987 m_zoomControl
= (wxChoice
*) NULL
;
988 m_buttonFlags
= buttons
;
991 wxPreviewControlBar::~wxPreviewControlBar()
995 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1001 dc
.SetPen(*wxBLACK_PEN
);
1002 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1003 dc
.DrawLine( 0, h
-1, w
, h
-1 );
1006 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
1008 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1012 void wxPreviewControlBar::OnPrint(void)
1014 wxPrintPreviewBase
*preview
= GetPrintPreview();
1015 preview
->Print(true);
1018 void wxPreviewControlBar::OnNext(void)
1020 wxPrintPreviewBase
*preview
= GetPrintPreview();
1023 int currentPage
= preview
->GetCurrentPage();
1024 if ((preview
->GetMaxPage() > 0) &&
1025 (currentPage
< preview
->GetMaxPage()) &&
1026 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1028 preview
->SetCurrentPage(currentPage
+ 1);
1033 void wxPreviewControlBar::OnPrevious(void)
1035 wxPrintPreviewBase
*preview
= GetPrintPreview();
1038 int currentPage
= preview
->GetCurrentPage();
1039 if ((preview
->GetMinPage() > 0) &&
1040 (currentPage
> preview
->GetMinPage()) &&
1041 preview
->GetPrintout()->HasPage(currentPage
- 1))
1043 preview
->SetCurrentPage(currentPage
- 1);
1048 void wxPreviewControlBar::OnFirst(void)
1050 wxPrintPreviewBase
*preview
= GetPrintPreview();
1053 int currentPage
= preview
->GetMinPage();
1054 if (preview
->GetPrintout()->HasPage(currentPage
))
1056 preview
->SetCurrentPage(currentPage
);
1061 void wxPreviewControlBar::OnLast(void)
1063 wxPrintPreviewBase
*preview
= GetPrintPreview();
1066 int currentPage
= preview
->GetMaxPage();
1067 if (preview
->GetPrintout()->HasPage(currentPage
))
1069 preview
->SetCurrentPage(currentPage
);
1074 void wxPreviewControlBar::OnGoto(void)
1076 wxPrintPreviewBase
*preview
= GetPrintPreview();
1081 if (preview
->GetMinPage() > 0)
1086 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1087 preview
->GetMinPage(), preview
->GetMaxPage());
1088 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1091 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1093 if ( strPage
.ToLong( ¤tPage
) )
1094 if (preview
->GetPrintout()->HasPage(currentPage
))
1096 preview
->SetCurrentPage(currentPage
);
1102 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1104 int zoom
= GetZoomControl();
1105 if (GetPrintPreview())
1106 GetPrintPreview()->SetZoom(zoom
);
1109 void wxPreviewControlBar::CreateButtons()
1111 SetSize(0, 0, 400, 40);
1113 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1115 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1116 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1118 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1120 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1121 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1124 // Exact-fit buttons are too tiny on wxUniversal
1126 wxSize navButtonSize
;
1127 #ifdef __WXUNIVERSAL__
1129 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1131 navButtonStyle
= wxBU_EXACTFIT
;
1132 navButtonSize
= wxDefaultSize
;
1135 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1137 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1138 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1141 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1143 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1144 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1147 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1149 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1150 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1153 if (m_buttonFlags
& wxPREVIEW_LAST
)
1155 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1156 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1159 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1161 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1162 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1165 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1167 wxString choices
[] =
1169 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1170 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1171 wxT("120%"), wxT("150%"), wxT("200%")
1173 int n
= WXSIZEOF(choices
);
1175 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1176 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1177 SetZoomControl(m_printPreview
->GetZoom());
1184 void wxPreviewControlBar::SetZoomControl(int zoom
)
1188 int n
, count
= m_zoomControl
->GetCount();
1190 for (n
=0; n
<count
; n
++)
1192 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1193 (val
>= long(zoom
)))
1195 m_zoomControl
->SetSelection(n
);
1200 m_zoomControl
->SetSelection(count
-1);
1204 int wxPreviewControlBar::GetZoomControl()
1206 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1209 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1221 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1223 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1224 EVT_CHAR_HOOK(wxPreviewFrame::OnChar
)
1225 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1228 void wxPreviewFrame::OnChar(wxKeyEvent
&event
)
1230 if ( event
.GetKeyCode() == WXK_ESCAPE
)
1240 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1241 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1242 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1244 m_printPreview
= preview
;
1245 m_controlBar
= NULL
;
1246 m_previewCanvas
= NULL
;
1247 m_windowDisabler
= NULL
;
1249 // Give the application icon
1251 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1253 SetIcon(topFrame
->GetIcon());
1257 wxPreviewFrame::~wxPreviewFrame()
1261 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1263 if (m_windowDisabler
)
1264 delete m_windowDisabler
;
1266 // Need to delete the printout and the print preview
1267 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1271 m_printPreview
->SetPrintout(NULL
);
1272 m_printPreview
->SetCanvas(NULL
);
1273 m_printPreview
->SetFrame(NULL
);
1275 delete m_printPreview
;
1280 void wxPreviewFrame::Initialize()
1288 m_printPreview
->SetCanvas(m_previewCanvas
);
1289 m_printPreview
->SetFrame(this);
1291 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1293 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1294 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1296 SetAutoLayout( true );
1299 m_windowDisabler
= new wxWindowDisabler(this);
1303 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1304 m_previewCanvas
->SetFocus();
1305 m_controlBar
->SetFocus();
1308 void wxPreviewFrame::CreateCanvas()
1310 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1313 void wxPreviewFrame::CreateControlBar()
1315 long buttons
= wxPREVIEW_DEFAULT
;
1316 if (m_printPreview
->GetPrintoutForPrinting())
1317 buttons
|= wxPREVIEW_PRINT
;
1319 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1320 m_controlBar
->CreateButtons();
1327 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1329 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1330 wxPrintout
*printoutForPrinting
,
1334 m_printDialogData
= (*data
);
1336 Init(printout
, printoutForPrinting
);
1339 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1340 wxPrintout
*printoutForPrinting
,
1341 wxPrintDialogData
*data
)
1344 m_printDialogData
= (*data
);
1346 Init(printout
, printoutForPrinting
);
1349 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1350 wxPrintout
*printoutForPrinting
)
1353 m_previewPrintout
= printout
;
1354 if (m_previewPrintout
)
1355 m_previewPrintout
->SetIsPreview(true);
1357 m_printPrintout
= printoutForPrinting
;
1359 m_previewCanvas
= NULL
;
1360 m_previewFrame
= NULL
;
1361 m_previewBitmap
= NULL
;
1368 m_printingPrepared
= false;
1373 wxPrintPreviewBase::~wxPrintPreviewBase()
1375 if (m_previewPrintout
)
1376 delete m_previewPrintout
;
1377 if (m_previewBitmap
)
1378 delete m_previewBitmap
;
1379 if (m_printPrintout
)
1380 delete m_printPrintout
;
1383 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1385 if (m_currentPage
== pageNum
)
1388 m_currentPage
= pageNum
;
1389 if (m_previewBitmap
)
1391 delete m_previewBitmap
;
1392 m_previewBitmap
= NULL
;
1395 if (m_previewCanvas
)
1397 AdjustScrollbars(m_previewCanvas
);
1399 if (!RenderPage(pageNum
))
1401 m_previewCanvas
->Refresh();
1402 m_previewCanvas
->SetFocus();
1407 int wxPrintPreviewBase::GetCurrentPage() const
1408 { return m_currentPage
; }
1409 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1410 { m_previewPrintout
= printout
; }
1411 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1412 { return m_previewPrintout
; }
1413 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1414 { return m_printPrintout
; }
1415 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1416 { m_previewFrame
= frame
; }
1417 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1418 { m_previewCanvas
= canvas
; }
1419 wxFrame
*wxPrintPreviewBase::GetFrame() const
1420 { return m_previewFrame
; }
1421 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1422 { return m_previewCanvas
; }
1424 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1426 // Calculate the rectangles for the printable area of the page and the
1427 // entire paper as they appear on the canvas on-screen.
1428 int canvasWidth
, canvasHeight
;
1429 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1431 float zoomScale
= float(m_currentZoom
) / 100;
1432 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1433 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1435 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1436 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1437 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1438 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1439 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1440 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1441 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1443 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1444 if (paperRect
.x
< m_leftMargin
)
1445 paperRect
.x
= m_leftMargin
;
1446 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1447 if (paperRect
.y
< m_topMargin
)
1448 paperRect
.y
= m_topMargin
;
1450 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1451 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1452 pageRect
.width
= wxCoord(screenPrintableWidth
);
1453 pageRect
.height
= wxCoord(screenPrintableHeight
);
1457 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1459 DrawBlankPage(canvas
, dc
);
1461 if (!m_previewBitmap
)
1462 if (!RenderPage(m_currentPage
))
1464 if (!m_previewBitmap
)
1469 wxRect pageRect
, paperRect
;
1470 CalcRects(canvas
, pageRect
, paperRect
);
1472 temp_dc
.SelectObject(*m_previewBitmap
);
1474 dc
.Blit(pageRect
.x
, pageRect
.y
,
1475 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1477 temp_dc
.SelectObject(wxNullBitmap
);
1481 // Adjusts the scrollbars for the current scale
1482 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1487 wxRect pageRect
, paperRect
;
1488 CalcRects(canvas
, pageRect
, paperRect
);
1489 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1490 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1491 int scrollUnitsX
= totalWidth
/ 10;
1492 int scrollUnitsY
= totalHeight
/ 10;
1493 wxSize virtualSize
= canvas
->GetVirtualSize();
1494 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1495 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1498 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1502 if (!m_previewCanvas
)
1504 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1508 wxRect pageRect
, paperRect
;
1509 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1511 if (!m_previewBitmap
)
1513 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1515 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1517 if (m_previewBitmap
) {
1518 delete m_previewBitmap
;
1519 m_previewBitmap
= NULL
;
1521 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1526 wxMemoryDC memoryDC
;
1527 memoryDC
.SelectObject(*m_previewBitmap
);
1531 m_previewPrintout
->SetDC(&memoryDC
);
1532 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1534 // Need to delay OnPreparePrinting until here, so we have enough information.
1535 if (!m_printingPrepared
)
1537 m_previewPrintout
->OnPreparePrinting();
1539 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1540 m_printingPrepared
= true;
1543 m_previewPrintout
->OnBeginPrinting();
1545 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1547 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1549 memoryDC
.SelectObject(wxNullBitmap
);
1551 delete m_previewBitmap
;
1552 m_previewBitmap
= NULL
;
1556 m_previewPrintout
->OnPrintPage(pageNum
);
1557 m_previewPrintout
->OnEndDocument();
1558 m_previewPrintout
->OnEndPrinting();
1560 m_previewPrintout
->SetDC(NULL
);
1562 memoryDC
.SelectObject(wxNullBitmap
);
1567 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1569 status
= wxString::Format(_("Page %d"), pageNum
);
1572 m_previewFrame
->SetStatusText(status
);
1578 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1580 wxRect pageRect
, paperRect
;
1582 CalcRects(canvas
, pageRect
, paperRect
);
1584 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1585 wxCoord shadowOffset
= 4;
1587 dc
.SetPen(*wxBLACK_PEN
);
1588 dc
.SetBrush(*wxBLACK_BRUSH
);
1589 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1590 paperRect
.width
, shadowOffset
);
1592 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1593 shadowOffset
, paperRect
.height
);
1595 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1596 dc
.SetPen(*wxBLACK_PEN
);
1597 dc
.SetBrush(*wxWHITE_BRUSH
);
1598 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1599 paperRect
.width
+ 3, paperRect
.height
+ 2);
1604 void wxPrintPreviewBase::SetZoom(int percent
)
1606 if (m_currentZoom
== percent
)
1609 m_currentZoom
= percent
;
1610 if (m_previewBitmap
)
1612 delete m_previewBitmap
;
1613 m_previewBitmap
= NULL
;
1616 if (m_previewCanvas
)
1618 AdjustScrollbars(m_previewCanvas
);
1619 RenderPage(m_currentPage
);
1620 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1621 m_previewCanvas
->ClearBackground();
1622 m_previewCanvas
->Refresh();
1623 m_previewCanvas
->SetFocus();
1627 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1629 return m_printDialogData
;
1632 int wxPrintPreviewBase::GetZoom() const
1633 { return m_currentZoom
; }
1634 int wxPrintPreviewBase::GetMaxPage() const
1635 { return m_maxPage
; }
1636 int wxPrintPreviewBase::GetMinPage() const
1637 { return m_minPage
; }
1638 bool wxPrintPreviewBase::IsOk() const
1640 void wxPrintPreviewBase::SetOk(bool ok
)
1643 //----------------------------------------------------------------------------
1645 //----------------------------------------------------------------------------
1647 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1649 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1650 wxPrintout
*printoutForPrinting
,
1651 wxPrintDialogData
*data
) :
1652 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1654 m_pimpl
= wxPrintFactory::GetFactory()->
1655 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1658 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1659 wxPrintout
*printoutForPrinting
,
1660 wxPrintData
*data
) :
1661 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1663 m_pimpl
= wxPrintFactory::GetFactory()->
1664 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1667 wxPrintPreview::~wxPrintPreview()
1671 // don't delete twice
1672 m_printPrintout
= NULL
;
1673 m_previewPrintout
= NULL
;
1674 m_previewBitmap
= NULL
;
1677 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1679 return m_pimpl
->SetCurrentPage( pageNum
);
1682 int wxPrintPreview::GetCurrentPage() const
1684 return m_pimpl
->GetCurrentPage();
1687 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1689 m_pimpl
->SetPrintout( printout
);
1692 wxPrintout
*wxPrintPreview::GetPrintout() const
1694 return m_pimpl
->GetPrintout();
1697 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1699 return m_pimpl
->GetPrintoutForPrinting();
1702 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1704 m_pimpl
->SetFrame( frame
);
1707 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1709 m_pimpl
->SetCanvas( canvas
);
1712 wxFrame
*wxPrintPreview::GetFrame() const
1714 return m_pimpl
->GetFrame();
1717 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1719 return m_pimpl
->GetCanvas();
1722 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1724 return m_pimpl
->PaintPage( canvas
, dc
);
1727 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1729 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1732 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1734 m_pimpl
->AdjustScrollbars( canvas
);
1737 bool wxPrintPreview::RenderPage(int pageNum
)
1739 return m_pimpl
->RenderPage( pageNum
);
1742 void wxPrintPreview::SetZoom(int percent
)
1744 m_pimpl
->SetZoom( percent
);
1747 int wxPrintPreview::GetZoom() const
1749 return m_pimpl
->GetZoom();
1752 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1754 return m_pimpl
->GetPrintDialogData();
1757 int wxPrintPreview::GetMaxPage() const
1759 return m_pimpl
->GetMaxPage();
1762 int wxPrintPreview::GetMinPage() const
1764 return m_pimpl
->GetMinPage();
1767 bool wxPrintPreview::IsOk() const
1769 return m_pimpl
->Ok();
1772 void wxPrintPreview::SetOk(bool ok
)
1774 m_pimpl
->SetOk( ok
);
1777 bool wxPrintPreview::Print(bool interactive
)
1779 return m_pimpl
->Print( interactive
);
1782 void wxPrintPreview::DetermineScaling()
1784 m_pimpl
->DetermineScaling();
1787 #endif // wxUSE_PRINTING_ARCHITECTURE