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__)
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
)
865 if ( m_printPreview
)
867 if ( m_printPreview
->UpdatePageRendering() )
873 // Responds to colour changes, and passes event on to children.
874 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
877 // The app workspace colour is always white, but we should have
878 // a contrast with the page.
879 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
880 #elif defined(__WXGTK__)
881 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
883 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
885 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
888 // Propagate the event to the non-top-level children
889 wxWindow::OnSysColourChanged(event
);
892 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
894 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
895 switch (event
.GetKeyCode())
898 controlBar
->OnGoto();
901 controlBar
->OnPrint();
905 if (!event
.ControlDown())
911 switch(event
.GetKeyCode())
914 controlBar
->OnNext(); break;
916 controlBar
->OnPrevious(); break;
918 controlBar
->OnFirst(); break;
920 controlBar
->OnLast(); break;
928 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
930 wxPreviewControlBar
*
931 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
935 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
937 int currentZoom
= controlBar
->GetZoomControl();
940 if ( currentZoom
< 100 )
942 else if ( currentZoom
<= 120 )
947 if ( event
.GetWheelRotation() > 0 )
950 int newZoom
= currentZoom
+ delta
;
955 if ( newZoom
!= currentZoom
)
957 controlBar
->SetZoomControl(newZoom
);
958 m_printPreview
->SetZoom(newZoom
);
968 #endif // wxUSE_MOUSEWHEEL
970 //----------------------------------------------------------------------------
971 // wxPreviewControlBar
972 //----------------------------------------------------------------------------
974 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
976 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
977 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
978 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
979 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
980 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
981 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
982 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
983 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
984 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
985 EVT_PAINT(wxPreviewControlBar::OnPaint
)
988 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
989 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
990 long style
, const wxString
& name
):
991 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
993 m_printPreview
= preview
;
994 m_closeButton
= (wxButton
*) NULL
;
995 m_nextPageButton
= (wxButton
*) NULL
;
996 m_previousPageButton
= (wxButton
*) NULL
;
997 m_printButton
= (wxButton
*) NULL
;
998 m_zoomControl
= (wxChoice
*) NULL
;
999 m_buttonFlags
= buttons
;
1002 wxPreviewControlBar::~wxPreviewControlBar()
1006 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1012 dc
.SetPen(*wxBLACK_PEN
);
1013 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1014 dc
.DrawLine( 0, h
-1, w
, h
-1 );
1017 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
1019 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1023 void wxPreviewControlBar::OnPrint(void)
1025 wxPrintPreviewBase
*preview
= GetPrintPreview();
1026 preview
->Print(true);
1029 void wxPreviewControlBar::OnNext(void)
1031 wxPrintPreviewBase
*preview
= GetPrintPreview();
1034 int currentPage
= preview
->GetCurrentPage();
1035 if ((preview
->GetMaxPage() > 0) &&
1036 (currentPage
< preview
->GetMaxPage()) &&
1037 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1039 preview
->SetCurrentPage(currentPage
+ 1);
1044 void wxPreviewControlBar::OnPrevious(void)
1046 wxPrintPreviewBase
*preview
= GetPrintPreview();
1049 int currentPage
= preview
->GetCurrentPage();
1050 if ((preview
->GetMinPage() > 0) &&
1051 (currentPage
> preview
->GetMinPage()) &&
1052 preview
->GetPrintout()->HasPage(currentPage
- 1))
1054 preview
->SetCurrentPage(currentPage
- 1);
1059 void wxPreviewControlBar::OnFirst(void)
1061 wxPrintPreviewBase
*preview
= GetPrintPreview();
1064 int currentPage
= preview
->GetMinPage();
1065 if (preview
->GetPrintout()->HasPage(currentPage
))
1067 preview
->SetCurrentPage(currentPage
);
1072 void wxPreviewControlBar::OnLast(void)
1074 wxPrintPreviewBase
*preview
= GetPrintPreview();
1077 int currentPage
= preview
->GetMaxPage();
1078 if (preview
->GetPrintout()->HasPage(currentPage
))
1080 preview
->SetCurrentPage(currentPage
);
1085 void wxPreviewControlBar::OnGoto(void)
1087 wxPrintPreviewBase
*preview
= GetPrintPreview();
1092 if (preview
->GetMinPage() > 0)
1097 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1098 preview
->GetMinPage(), preview
->GetMaxPage());
1099 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1102 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1104 if ( strPage
.ToLong( ¤tPage
) )
1105 if (preview
->GetPrintout()->HasPage(currentPage
))
1107 preview
->SetCurrentPage(currentPage
);
1113 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1115 int zoom
= GetZoomControl();
1116 if (GetPrintPreview())
1117 GetPrintPreview()->SetZoom(zoom
);
1120 void wxPreviewControlBar::CreateButtons()
1122 SetSize(0, 0, 400, 40);
1124 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1126 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1127 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1129 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1131 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1132 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1135 // Exact-fit buttons are too tiny on wxUniversal
1137 wxSize navButtonSize
;
1138 #ifdef __WXUNIVERSAL__
1140 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1142 navButtonStyle
= wxBU_EXACTFIT
;
1143 navButtonSize
= wxDefaultSize
;
1146 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1148 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1149 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1152 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1154 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1155 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1158 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1160 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1161 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1164 if (m_buttonFlags
& wxPREVIEW_LAST
)
1166 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1167 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1170 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1172 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1173 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1176 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1178 wxString choices
[] =
1180 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1181 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1182 wxT("120%"), wxT("150%"), wxT("200%")
1184 int n
= WXSIZEOF(choices
);
1186 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1187 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1188 SetZoomControl(m_printPreview
->GetZoom());
1195 void wxPreviewControlBar::SetZoomControl(int zoom
)
1199 int n
, count
= m_zoomControl
->GetCount();
1201 for (n
=0; n
<count
; n
++)
1203 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1204 (val
>= long(zoom
)))
1206 m_zoomControl
->SetSelection(n
);
1211 m_zoomControl
->SetSelection(count
-1);
1215 int wxPreviewControlBar::GetZoomControl()
1217 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1220 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1232 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1234 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1235 EVT_CHAR_HOOK(wxPreviewFrame::OnChar
)
1236 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1239 void wxPreviewFrame::OnChar(wxKeyEvent
&event
)
1241 if ( event
.GetKeyCode() == WXK_ESCAPE
)
1251 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1252 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1253 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1255 m_printPreview
= preview
;
1256 m_controlBar
= NULL
;
1257 m_previewCanvas
= NULL
;
1258 m_windowDisabler
= NULL
;
1260 // Give the application icon
1262 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1264 SetIcon(topFrame
->GetIcon());
1268 wxPreviewFrame::~wxPreviewFrame()
1272 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1274 if (m_windowDisabler
)
1275 delete m_windowDisabler
;
1277 // Need to delete the printout and the print preview
1278 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1282 m_printPreview
->SetPrintout(NULL
);
1283 m_printPreview
->SetCanvas(NULL
);
1284 m_printPreview
->SetFrame(NULL
);
1287 m_previewCanvas
->SetPreview(NULL
);
1288 wxDELETE(m_printPreview
);
1293 void wxPreviewFrame::Initialize()
1301 m_printPreview
->SetCanvas(m_previewCanvas
);
1302 m_printPreview
->SetFrame(this);
1304 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1306 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1307 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1309 SetAutoLayout( true );
1312 m_windowDisabler
= new wxWindowDisabler(this);
1316 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1317 m_previewCanvas
->SetFocus();
1318 m_controlBar
->SetFocus();
1321 void wxPreviewFrame::CreateCanvas()
1323 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1326 void wxPreviewFrame::CreateControlBar()
1328 long buttons
= wxPREVIEW_DEFAULT
;
1329 if (m_printPreview
->GetPrintoutForPrinting())
1330 buttons
|= wxPREVIEW_PRINT
;
1332 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1333 m_controlBar
->CreateButtons();
1340 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1342 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1343 wxPrintout
*printoutForPrinting
,
1347 m_printDialogData
= (*data
);
1349 Init(printout
, printoutForPrinting
);
1352 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1353 wxPrintout
*printoutForPrinting
,
1354 wxPrintDialogData
*data
)
1357 m_printDialogData
= (*data
);
1359 Init(printout
, printoutForPrinting
);
1362 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1363 wxPrintout
*printoutForPrinting
)
1366 m_previewPrintout
= printout
;
1367 if (m_previewPrintout
)
1368 m_previewPrintout
->SetIsPreview(true);
1370 m_printPrintout
= printoutForPrinting
;
1372 m_previewCanvas
= NULL
;
1373 m_previewFrame
= NULL
;
1374 m_previewBitmap
= NULL
;
1381 m_printingPrepared
= false;
1386 wxPrintPreviewBase::~wxPrintPreviewBase()
1388 if (m_previewPrintout
)
1389 delete m_previewPrintout
;
1390 if (m_previewBitmap
)
1391 delete m_previewBitmap
;
1392 if (m_printPrintout
)
1393 delete m_printPrintout
;
1396 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1398 if (m_currentPage
== pageNum
)
1401 m_currentPage
= pageNum
;
1402 if (m_previewBitmap
)
1404 delete m_previewBitmap
;
1405 m_previewBitmap
= NULL
;
1408 if (m_previewCanvas
)
1410 AdjustScrollbars(m_previewCanvas
);
1412 m_previewCanvas
->Refresh();
1413 m_previewCanvas
->SetFocus();
1418 int wxPrintPreviewBase::GetCurrentPage() const
1419 { return m_currentPage
; }
1420 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1421 { m_previewPrintout
= printout
; }
1422 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1423 { return m_previewPrintout
; }
1424 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1425 { return m_printPrintout
; }
1426 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1427 { m_previewFrame
= frame
; }
1428 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1429 { m_previewCanvas
= canvas
; }
1430 wxFrame
*wxPrintPreviewBase::GetFrame() const
1431 { return m_previewFrame
; }
1432 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1433 { return m_previewCanvas
; }
1435 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1437 // Calculate the rectangles for the printable area of the page and the
1438 // entire paper as they appear on the canvas on-screen.
1439 int canvasWidth
, canvasHeight
;
1440 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1442 float zoomScale
= float(m_currentZoom
) / 100;
1443 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1444 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1446 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1447 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1448 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1449 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1450 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1451 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1452 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1454 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1455 if (paperRect
.x
< m_leftMargin
)
1456 paperRect
.x
= m_leftMargin
;
1457 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1458 if (paperRect
.y
< m_topMargin
)
1459 paperRect
.y
= m_topMargin
;
1461 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1462 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1463 pageRect
.width
= wxCoord(screenPrintableWidth
);
1464 pageRect
.height
= wxCoord(screenPrintableHeight
);
1468 bool wxPrintPreviewBase::UpdatePageRendering()
1470 if ( m_previewBitmap
)
1473 if ( !RenderPage(m_currentPage
) )
1479 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1481 DrawBlankPage(canvas
, dc
);
1483 if (!m_previewBitmap
)
1488 wxRect pageRect
, paperRect
;
1489 CalcRects(canvas
, pageRect
, paperRect
);
1491 temp_dc
.SelectObject(*m_previewBitmap
);
1493 dc
.Blit(pageRect
.x
, pageRect
.y
,
1494 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1496 temp_dc
.SelectObject(wxNullBitmap
);
1500 // Adjusts the scrollbars for the current scale
1501 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1506 wxRect pageRect
, paperRect
;
1507 CalcRects(canvas
, pageRect
, paperRect
);
1508 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1509 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1510 int scrollUnitsX
= totalWidth
/ 10;
1511 int scrollUnitsY
= totalHeight
/ 10;
1512 wxSize virtualSize
= canvas
->GetVirtualSize();
1513 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1514 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1517 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1521 if (!m_previewCanvas
)
1523 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1527 wxRect pageRect
, paperRect
;
1528 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1530 if (!m_previewBitmap
)
1532 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1534 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1536 if (m_previewBitmap
) {
1537 delete m_previewBitmap
;
1538 m_previewBitmap
= NULL
;
1540 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1545 wxMemoryDC memoryDC
;
1546 memoryDC
.SelectObject(*m_previewBitmap
);
1550 m_previewPrintout
->SetDC(&memoryDC
);
1551 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1553 // Need to delay OnPreparePrinting until here, so we have enough information.
1554 if (!m_printingPrepared
)
1556 m_previewPrintout
->OnPreparePrinting();
1558 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1559 m_printingPrepared
= true;
1562 m_previewPrintout
->OnBeginPrinting();
1564 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1566 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1568 memoryDC
.SelectObject(wxNullBitmap
);
1570 delete m_previewBitmap
;
1571 m_previewBitmap
= NULL
;
1575 m_previewPrintout
->OnPrintPage(pageNum
);
1576 m_previewPrintout
->OnEndDocument();
1577 m_previewPrintout
->OnEndPrinting();
1579 m_previewPrintout
->SetDC(NULL
);
1581 memoryDC
.SelectObject(wxNullBitmap
);
1586 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1588 status
= wxString::Format(_("Page %d"), pageNum
);
1591 m_previewFrame
->SetStatusText(status
);
1597 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1599 wxRect pageRect
, paperRect
;
1601 CalcRects(canvas
, pageRect
, paperRect
);
1603 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1604 wxCoord shadowOffset
= 4;
1606 dc
.SetPen(*wxBLACK_PEN
);
1607 dc
.SetBrush(*wxBLACK_BRUSH
);
1608 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1609 paperRect
.width
, shadowOffset
);
1611 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1612 shadowOffset
, paperRect
.height
);
1614 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1615 dc
.SetPen(*wxBLACK_PEN
);
1616 dc
.SetBrush(*wxWHITE_BRUSH
);
1617 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1618 paperRect
.width
+ 3, paperRect
.height
+ 2);
1623 void wxPrintPreviewBase::SetZoom(int percent
)
1625 if (m_currentZoom
== percent
)
1628 m_currentZoom
= percent
;
1629 if (m_previewBitmap
)
1631 delete m_previewBitmap
;
1632 m_previewBitmap
= NULL
;
1635 if (m_previewCanvas
)
1637 AdjustScrollbars(m_previewCanvas
);
1638 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1639 m_previewCanvas
->ClearBackground();
1640 m_previewCanvas
->Refresh();
1641 m_previewCanvas
->SetFocus();
1645 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1647 return m_printDialogData
;
1650 int wxPrintPreviewBase::GetZoom() const
1651 { return m_currentZoom
; }
1652 int wxPrintPreviewBase::GetMaxPage() const
1653 { return m_maxPage
; }
1654 int wxPrintPreviewBase::GetMinPage() const
1655 { return m_minPage
; }
1656 bool wxPrintPreviewBase::IsOk() const
1658 void wxPrintPreviewBase::SetOk(bool ok
)
1661 //----------------------------------------------------------------------------
1663 //----------------------------------------------------------------------------
1665 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1667 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1668 wxPrintout
*printoutForPrinting
,
1669 wxPrintDialogData
*data
) :
1670 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1672 m_pimpl
= wxPrintFactory::GetFactory()->
1673 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1676 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1677 wxPrintout
*printoutForPrinting
,
1678 wxPrintData
*data
) :
1679 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1681 m_pimpl
= wxPrintFactory::GetFactory()->
1682 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1685 wxPrintPreview::~wxPrintPreview()
1689 // don't delete twice
1690 m_printPrintout
= NULL
;
1691 m_previewPrintout
= NULL
;
1692 m_previewBitmap
= NULL
;
1695 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1697 return m_pimpl
->SetCurrentPage( pageNum
);
1700 int wxPrintPreview::GetCurrentPage() const
1702 return m_pimpl
->GetCurrentPage();
1705 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1707 m_pimpl
->SetPrintout( printout
);
1710 wxPrintout
*wxPrintPreview::GetPrintout() const
1712 return m_pimpl
->GetPrintout();
1715 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1717 return m_pimpl
->GetPrintoutForPrinting();
1720 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1722 m_pimpl
->SetFrame( frame
);
1725 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1727 m_pimpl
->SetCanvas( canvas
);
1730 wxFrame
*wxPrintPreview::GetFrame() const
1732 return m_pimpl
->GetFrame();
1735 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1737 return m_pimpl
->GetCanvas();
1740 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1742 return m_pimpl
->PaintPage( canvas
, dc
);
1745 bool wxPrintPreview::UpdatePageRendering()
1747 return m_pimpl
->UpdatePageRendering();
1750 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1752 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1755 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1757 m_pimpl
->AdjustScrollbars( canvas
);
1760 bool wxPrintPreview::RenderPage(int pageNum
)
1762 return m_pimpl
->RenderPage( pageNum
);
1765 void wxPrintPreview::SetZoom(int percent
)
1767 m_pimpl
->SetZoom( percent
);
1770 int wxPrintPreview::GetZoom() const
1772 return m_pimpl
->GetZoom();
1775 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1777 return m_pimpl
->GetPrintDialogData();
1780 int wxPrintPreview::GetMaxPage() const
1782 return m_pimpl
->GetMaxPage();
1785 int wxPrintPreview::GetMinPage() const
1787 return m_pimpl
->GetMinPage();
1790 bool wxPrintPreview::IsOk() const
1792 return m_pimpl
->Ok();
1795 void wxPrintPreview::SetOk(bool ok
)
1797 m_pimpl
->SetOk( ok
);
1800 bool wxPrintPreview::Print(bool interactive
)
1802 return m_pimpl
->Print( interactive
);
1805 void wxPrintPreview::DetermineScaling()
1807 m_pimpl
->DetermineScaling();
1810 #endif // wxUSE_PRINTING_ARCHITECTURE