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 #elif defined(__WXMAC__)
56 #include "wx/mac/printdlg.h"
57 #include "wx/mac/private/print.h"
59 #include "wx/generic/prntdlgg.h"
69 //----------------------------------------------------------------------------
71 //----------------------------------------------------------------------------
73 wxPrintFactory
*wxPrintFactory::m_factory
= NULL
;
75 void wxPrintFactory::SetPrintFactory( wxPrintFactory
*factory
)
77 if (wxPrintFactory::m_factory
)
78 delete wxPrintFactory::m_factory
;
80 wxPrintFactory::m_factory
= factory
;
83 wxPrintFactory
*wxPrintFactory::GetFactory()
85 if (!wxPrintFactory::m_factory
)
86 wxPrintFactory::m_factory
= new wxNativePrintFactory
;
88 return wxPrintFactory::m_factory
;
91 //----------------------------------------------------------------------------
92 // wxNativePrintFactory
93 //----------------------------------------------------------------------------
95 wxPrinterBase
*wxNativePrintFactory::CreatePrinter( wxPrintDialogData
*data
)
97 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
98 return new wxWindowsPrinter( data
);
99 #elif defined(__WXMAC__)
100 return new wxMacPrinter( data
);
101 #elif defined(__WXPM__)
102 return new wxOS2Printer( data
);
104 return new wxPostScriptPrinter( data
);
108 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
109 wxPrintout
*printout
, wxPrintDialogData
*data
)
111 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
112 return new wxWindowsPrintPreview( preview
, printout
, data
);
113 #elif defined(__WXMAC__)
114 return new wxMacPrintPreview( preview
, printout
, data
);
115 #elif defined(__WXPM__)
116 return new wxOS2PrintPreview( preview
, printout
, data
);
118 return new wxPostScriptPrintPreview( preview
, printout
, data
);
122 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
123 wxPrintout
*printout
, wxPrintData
*data
)
125 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
126 return new wxWindowsPrintPreview( preview
, printout
, data
);
127 #elif defined(__WXMAC__)
128 return new wxMacPrintPreview( preview
, printout
, data
);
129 #elif defined(__WXPM__)
130 return new wxOS2PrintPreview( preview
, printout
, data
);
132 return new wxPostScriptPrintPreview( preview
, printout
, data
);
136 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
137 wxPrintDialogData
*data
)
139 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
140 return new wxWindowsPrintDialog( parent
, data
);
141 #elif defined(__WXMAC__)
142 return new wxMacPrintDialog( parent
, data
);
144 return new wxGenericPrintDialog( parent
, data
);
148 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
151 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
152 return new wxWindowsPrintDialog( parent
, data
);
153 #elif defined(__WXMAC__)
154 return new wxMacPrintDialog( parent
, data
);
156 return new wxGenericPrintDialog( parent
, data
);
160 wxPageSetupDialogBase
*wxNativePrintFactory::CreatePageSetupDialog( wxWindow
*parent
,
161 wxPageSetupDialogData
*data
)
163 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
164 return new wxWindowsPageSetupDialog( parent
, data
);
165 #elif defined(__WXMAC__)
166 return new wxMacPageSetupDialog( parent
, data
);
168 return new wxGenericPageSetupDialog( parent
, data
);
172 bool wxNativePrintFactory::HasPrintSetupDialog()
174 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
176 #elif defined(__WXMAC__)
179 // Only here do we need to provide the print setup
180 // dialog ourselves, the other platforms either have
181 // none, don't make it accessible or let you configure
182 // the printer from the wxPrintDialog anyway.
188 wxDialog
*wxNativePrintFactory::CreatePrintSetupDialog( wxWindow
*parent
,
191 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
195 #elif defined(__WXMAC__)
200 // Only here do we need to provide the print setup
201 // dialog ourselves, the other platforms either have
202 // none, don't make it accessible or let you configure
203 // the printer from the wxPrintDialog anyway.
204 return new wxGenericPrintSetupDialog( parent
, data
);
208 wxDC
* wxNativePrintFactory::CreatePrinterDC( const wxPrintData
& data
)
210 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
211 return new wxPrinterDC(data
);
212 #elif defined(__WXMAC__)
213 return new wxPrinterDC(data
);
215 return new wxPostScriptDC(data
);
219 bool wxNativePrintFactory::HasOwnPrintToFile()
221 // Only relevant for PostScript and here the
222 // setup dialog provides no "print to file"
223 // option. In the GNOME setup dialog, the
224 // setup dialog has its own print to file.
228 bool wxNativePrintFactory::HasPrinterLine()
230 // Only relevant for PostScript for now
234 wxString
wxNativePrintFactory::CreatePrinterLine()
236 // Only relevant for PostScript for now
238 // We should query "lpstat -d" here
239 return _("Generic PostScript");
242 bool wxNativePrintFactory::HasStatusLine()
244 // Only relevant for PostScript for now
248 wxString
wxNativePrintFactory::CreateStatusLine()
250 // Only relevant for PostScript for now
252 // We should query "lpstat -r" or "lpstat -p" here
256 wxPrintNativeDataBase
*wxNativePrintFactory::CreatePrintNativeData()
258 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
259 return new wxWindowsPrintNativeData
;
260 #elif defined(__WXMAC__)
261 return new wxMacCarbonPrintData
;
263 return new wxPostScriptPrintNativeData
;
267 //----------------------------------------------------------------------------
268 // wxPrintNativeDataBase
269 //----------------------------------------------------------------------------
271 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase
, wxObject
)
273 wxPrintNativeDataBase::wxPrintNativeDataBase()
278 //----------------------------------------------------------------------------
279 // wxPrintFactoryModule
280 //----------------------------------------------------------------------------
282 class wxPrintFactoryModule
: public wxModule
285 wxPrintFactoryModule() {}
286 bool OnInit() { return true; }
287 void OnExit() { wxPrintFactory::SetPrintFactory( NULL
); }
290 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule
)
293 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule
, wxModule
)
295 //----------------------------------------------------------------------------
297 //----------------------------------------------------------------------------
299 IMPLEMENT_CLASS(wxPrinterBase
, wxObject
)
301 wxPrinterBase::wxPrinterBase(wxPrintDialogData
*data
)
303 m_currentPrintout
= (wxPrintout
*) NULL
;
304 sm_abortWindow
= (wxWindow
*) NULL
;
307 m_printDialogData
= (*data
);
308 sm_lastError
= wxPRINTER_NO_ERROR
;
311 wxWindow
*wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
312 bool wxPrinterBase::sm_abortIt
= false;
313 wxPrinterError
wxPrinterBase::sm_lastError
= wxPRINTER_NO_ERROR
;
315 wxPrinterBase::~wxPrinterBase()
319 wxWindow
*wxPrinterBase::CreateAbortWindow(wxWindow
*parent
, wxPrintout
* printout
)
321 wxPrintAbortDialog
*dialog
= new wxPrintAbortDialog(parent
, _("Printing ") , wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
);
323 wxBoxSizer
*button_sizer
= new wxBoxSizer( wxVERTICAL
);
324 button_sizer
->Add( new wxStaticText(dialog
, wxID_ANY
, _("Please wait while printing\n") + printout
->GetTitle() ), 0, wxALL
, 10 );
325 button_sizer
->Add( new wxButton( dialog
, wxID_CANCEL
, wxT("Cancel") ), 0, wxALL
| wxALIGN_CENTER
, 10 );
327 dialog
->SetAutoLayout( true );
328 dialog
->SetSizer( button_sizer
);
330 button_sizer
->Fit(dialog
);
331 button_sizer
->SetSizeHints (dialog
) ;
336 void wxPrinterBase::ReportError(wxWindow
*parent
, wxPrintout
*WXUNUSED(printout
), const wxString
& message
)
338 wxMessageBox(message
, _("Printing Error"), wxOK
, parent
);
341 wxPrintDialogData
& wxPrinterBase::GetPrintDialogData() const
343 return (wxPrintDialogData
&) m_printDialogData
;
346 //----------------------------------------------------------------------------
348 //----------------------------------------------------------------------------
350 IMPLEMENT_CLASS(wxPrinter
, wxPrinterBase
)
352 wxPrinter::wxPrinter(wxPrintDialogData
*data
)
354 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrinter( data
);
357 wxPrinter::~wxPrinter()
362 wxWindow
*wxPrinter::CreateAbortWindow(wxWindow
*parent
, wxPrintout
*printout
)
364 return m_pimpl
->CreateAbortWindow( parent
, printout
);
367 void wxPrinter::ReportError(wxWindow
*parent
, wxPrintout
*printout
, const wxString
& message
)
369 m_pimpl
->ReportError( parent
, printout
, message
);
372 bool wxPrinter::Setup(wxWindow
*parent
)
374 return m_pimpl
->Setup( parent
);
377 bool wxPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
379 return m_pimpl
->Print( parent
, printout
, prompt
);
382 wxDC
* wxPrinter::PrintDialog(wxWindow
*parent
)
384 return m_pimpl
->PrintDialog( parent
);
387 wxPrintDialogData
& wxPrinter::GetPrintDialogData() const
389 return m_pimpl
->GetPrintDialogData();
392 // ---------------------------------------------------------------------------
393 // wxPrintDialogBase: the dialog for printing.
394 // ---------------------------------------------------------------------------
396 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase
, wxDialog
)
398 wxPrintDialogBase::wxPrintDialogBase(wxWindow
*parent
,
400 const wxString
&title
,
404 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Print")) : title
,
409 // ---------------------------------------------------------------------------
410 // wxPrintDialog: the dialog for printing
411 // ---------------------------------------------------------------------------
413 IMPLEMENT_CLASS(wxPrintDialog
, wxObject
)
415 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintDialogData
* data
)
417 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
420 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintData
* data
)
422 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
425 wxPrintDialog::~wxPrintDialog()
430 int wxPrintDialog::ShowModal()
432 return m_pimpl
->ShowModal();
435 wxPrintDialogData
& wxPrintDialog::GetPrintDialogData()
437 return m_pimpl
->GetPrintDialogData();
440 wxPrintData
& wxPrintDialog::GetPrintData()
442 return m_pimpl
->GetPrintData();
445 wxDC
*wxPrintDialog::GetPrintDC()
447 return m_pimpl
->GetPrintDC();
450 // ---------------------------------------------------------------------------
451 // wxPageSetupDialogBase: the page setup dialog
452 // ---------------------------------------------------------------------------
454 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase
, wxDialog
)
456 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow
*parent
,
458 const wxString
&title
,
462 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Page setup")) : title
,
467 // ---------------------------------------------------------------------------
468 // wxPageSetupDialog: the page setup dialog
469 // ---------------------------------------------------------------------------
471 IMPLEMENT_CLASS(wxPageSetupDialog
, wxObject
)
473 wxPageSetupDialog::wxPageSetupDialog(wxWindow
*parent
, wxPageSetupDialogData
*data
)
475 m_pimpl
= wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent
, data
);
478 wxPageSetupDialog::~wxPageSetupDialog()
483 int wxPageSetupDialog::ShowModal()
485 return m_pimpl
->ShowModal();
488 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupDialogData()
490 return m_pimpl
->GetPageSetupDialogData();
494 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupData()
496 return m_pimpl
->GetPageSetupDialogData();
499 //----------------------------------------------------------------------------
500 // wxPrintAbortDialog
501 //----------------------------------------------------------------------------
503 BEGIN_EVENT_TABLE(wxPrintAbortDialog
, wxDialog
)
504 EVT_BUTTON(wxID_CANCEL
, wxPrintAbortDialog::OnCancel
)
507 void wxPrintAbortDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
))
509 wxPrinterBase::sm_abortIt
= true;
510 wxPrinterBase::sm_abortWindow
->Show(false);
511 wxPrinterBase::sm_abortWindow
->Close(true);
512 wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
515 //----------------------------------------------------------------------------
517 //----------------------------------------------------------------------------
519 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
)
521 wxPrintout::wxPrintout(const wxString
& title
)
523 m_printoutTitle
= title
;
524 m_printoutDC
= (wxDC
*) NULL
;
527 m_pageWidthPixels
= 0;
528 m_pageHeightPixels
= 0;
536 wxPrintout::~wxPrintout()
540 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
))
542 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
);
545 void wxPrintout::OnEndDocument()
550 void wxPrintout::OnBeginPrinting()
554 void wxPrintout::OnEndPrinting()
558 bool wxPrintout::HasPage(int page
)
563 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
)
571 void wxPrintout::FitThisSizeToPaper(const wxSize
& imageSize
)
573 // Set the DC scale and origin so that the given image size fits within the
574 // entire page and the origin is at the top left corner of the page. Note
575 // that with most printers, portions of the page will be non-printable. Use
576 // this if you're managing your own page margins.
577 if (!m_printoutDC
) return;
578 wxRect paperRect
= GetPaperRectPixels();
580 GetPageSizePixels(&pw
, &ph
);
582 m_printoutDC
->GetSize(&w
, &h
);
583 float scaleX
= ((float(paperRect
.width
) * w
) / (float(pw
) * imageSize
.x
));
584 float scaleY
= ((float(paperRect
.height
) * h
) / (float(ph
) * imageSize
.y
));
585 float actualScale
= wxMin(scaleX
, scaleY
);
586 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
587 m_printoutDC
->SetDeviceOrigin(0, 0);
588 wxRect logicalPaperRect
= GetLogicalPaperRect();
589 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
592 void wxPrintout::FitThisSizeToPage(const wxSize
& imageSize
)
594 // Set the DC scale and origin so that the given image size fits within the
595 // printable area of the page and the origin is at the top left corner of
596 // the printable area.
597 if (!m_printoutDC
) return;
599 m_printoutDC
->GetSize(&w
, &h
);
600 float scaleX
= float(w
) / imageSize
.x
;
601 float scaleY
= float(h
) / imageSize
.y
;
602 float actualScale
= wxMin(scaleX
, scaleY
);
603 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
604 m_printoutDC
->SetDeviceOrigin(0, 0);
607 void wxPrintout::FitThisSizeToPageMargins(const wxSize
& imageSize
, const wxPageSetupDialogData
& pageSetupData
)
609 // Set the DC scale and origin so that the given image size fits within the
610 // page margins defined in the given wxPageSetupDialogData object and the
611 // origin is at the top left corner of the page margins.
612 if (!m_printoutDC
) return;
613 wxRect paperRect
= GetPaperRectPixels();
615 GetPageSizePixels(&pw
, &ph
);
616 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
617 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
619 GetPageSizeMM(&mw
, &mh
);
620 float mmToDeviceX
= float(pw
) / mw
;
621 float mmToDeviceY
= float(ph
) / mh
;
622 wxRect
pageMarginsRect(paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
623 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
624 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
625 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
627 m_printoutDC
->GetSize(&w
, &h
);
628 float scaleX
= (float(pageMarginsRect
.width
) * w
) / (float(pw
) * imageSize
.x
);
629 float scaleY
= (float(pageMarginsRect
.height
) * h
) / (float(ph
) * imageSize
.y
);
630 float actualScale
= wxMin(scaleX
, scaleY
);
631 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
632 m_printoutDC
->SetDeviceOrigin(0, 0);
633 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
634 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
637 void wxPrintout::MapScreenSizeToPaper()
639 // Set the DC scale so that an image on the screen is the same size on the
640 // paper and the origin is at the top left of the paper. Note that with most
641 // printers, portions of the page will be cut off. Use this if you're
642 // managing your own page margins.
643 if (!m_printoutDC
) return;
644 MapScreenSizeToPage();
645 wxRect logicalPaperRect
= GetLogicalPaperRect();
646 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
649 void wxPrintout::MapScreenSizeToPage()
651 // Set the DC scale and origin so that an image on the screen is the same
652 // size on the paper and the origin is at the top left of the printable area.
653 if (!m_printoutDC
) return;
654 int ppiScreenX
, ppiScreenY
;
655 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
656 int ppiPrinterX
, ppiPrinterY
;
657 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
659 m_printoutDC
->GetSize(&w
, &h
);
660 int pageSizePixelsX
, pageSizePixelsY
;
661 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
662 float userScaleX
= (float(ppiPrinterX
) * w
) / (float(ppiScreenX
) * pageSizePixelsX
);
663 float userScaleY
= (float(ppiPrinterY
) * h
) / (float(ppiScreenY
) * pageSizePixelsY
);
664 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
665 m_printoutDC
->SetDeviceOrigin(0, 0);
668 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData
& pageSetupData
)
670 // Set the DC scale so that an image on the screen is the same size on the
671 // paper and the origin is at the top left of the page margins defined by
672 // the given wxPageSetupDialogData object.
673 if (!m_printoutDC
) return;
674 MapScreenSizeToPage();
675 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
676 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
679 void wxPrintout::MapScreenSizeToDevice()
681 // Set the DC scale so that a screen pixel is the same size as a device
682 // pixel and the origin is at the top left of the printable area.
683 if (!m_printoutDC
) return;
685 m_printoutDC
->GetSize(&w
, &h
);
686 int pageSizePixelsX
, pageSizePixelsY
;
687 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
688 float userScaleX
= float(w
) / pageSizePixelsX
;
689 float userScaleY
= float(h
) / pageSizePixelsY
;
690 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
691 m_printoutDC
->SetDeviceOrigin(0, 0);
694 wxRect
wxPrintout::GetLogicalPaperRect() const
696 // Return the rectangle in logical units that corresponds to the paper
698 wxRect paperRect
= GetPaperRectPixels();
700 GetPageSizePixels(&pw
, &ph
);
702 m_printoutDC
->GetSize(&w
, &h
);
703 if (w
== pw
&& h
== ph
) {
704 // this DC matches the printed page, so no scaling
705 return wxRect(m_printoutDC
->DeviceToLogicalX(paperRect
.x
),
706 m_printoutDC
->DeviceToLogicalY(paperRect
.y
),
707 m_printoutDC
->DeviceToLogicalXRel(paperRect
.width
),
708 m_printoutDC
->DeviceToLogicalYRel(paperRect
.height
));
710 // This DC doesn't match the printed page, so we have to scale.
711 float scaleX
= float(w
) / pw
;
712 float scaleY
= float(h
) / ph
;
713 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(paperRect
.x
* scaleX
)),
714 m_printoutDC
->DeviceToLogicalY(wxRound(paperRect
.y
* scaleY
)),
715 m_printoutDC
->DeviceToLogicalXRel(wxRound(paperRect
.width
* scaleX
)),
716 m_printoutDC
->DeviceToLogicalYRel(wxRound(paperRect
.height
* scaleY
)));
719 wxRect
wxPrintout::GetLogicalPageRect() const
721 // Return the rectangle in logical units that corresponds to the printable
724 m_printoutDC
->GetSize(&w
, &h
);
725 return wxRect(m_printoutDC
->DeviceToLogicalX(0),
726 m_printoutDC
->DeviceToLogicalY(0),
727 m_printoutDC
->DeviceToLogicalXRel(w
),
728 m_printoutDC
->DeviceToLogicalYRel(h
));
731 wxRect
wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData
& pageSetupData
) const
733 // Return the rectangle in logical units that corresponds to the region
734 // within the page margins as specified by the given wxPageSetupDialogData
737 // We get the paper size in device units and the margins in mm,
738 // so we need to calculate the conversion with this trick
740 GetPageSizePixels(&pw
, &ph
);
742 GetPageSizeMM(&mw
, &mh
);
743 float mmToDeviceX
= float(pw
) / mw
;
744 float mmToDeviceY
= float(ph
) / mh
;
746 // paper size in device units
747 wxRect paperRect
= GetPaperRectPixels();
750 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
751 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
753 // calculate margins in device units
754 wxRect
pageMarginsRect(
755 paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
756 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
757 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
758 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
761 m_printoutDC
->GetSize(&w
, &h
);
762 if (w
== pw
&& h
== ph
)
764 // this DC matches the printed page, so no scaling
766 m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),
767 m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),
768 m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),
769 m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
));
772 // This DC doesn't match the printed page, so we have to scale.
773 float scaleX
= float(w
) / pw
;
774 float scaleY
= float(h
) / ph
;
775 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(pageMarginsRect
.x
* scaleX
)),
776 m_printoutDC
->DeviceToLogicalY(wxRound(pageMarginsRect
.y
* scaleY
)),
777 m_printoutDC
->DeviceToLogicalXRel(wxRound(pageMarginsRect
.width
* scaleX
)),
778 m_printoutDC
->DeviceToLogicalYRel(wxRound(pageMarginsRect
.height
* scaleY
)));
781 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
)
783 // Set the device origin by specifying a point in logical coordinates.
784 m_printoutDC
->SetDeviceOrigin(
785 m_printoutDC
->LogicalToDeviceX(x
),
786 m_printoutDC
->LogicalToDeviceY(y
) );
789 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
)
791 // Offset the device origin by a specified distance in device coordinates.
792 wxPoint dev_org
= m_printoutDC
->GetDeviceOrigin();
793 m_printoutDC
->SetDeviceOrigin(
794 dev_org
.x
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),
795 dev_org
.y
+ m_printoutDC
->LogicalToDeviceYRel(yoff
) );
799 //----------------------------------------------------------------------------
801 //----------------------------------------------------------------------------
803 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
805 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
806 EVT_PAINT(wxPreviewCanvas::OnPaint
)
807 EVT_CHAR(wxPreviewCanvas::OnChar
)
808 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
810 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
814 // VZ: the current code doesn't refresh properly without
815 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
816 // really horrible flicker when resizing the preview frame, but without
817 // this style it simply doesn't work correctly at all...
818 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
819 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
820 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
822 m_printPreview
= preview
;
824 // The app workspace colour is always white, but we should have
825 // a contrast with the page.
826 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
827 #elif defined(__WXGTK__)
828 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
830 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
832 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
834 SetScrollbars(10, 10, 100, 100);
837 wxPreviewCanvas::~wxPreviewCanvas()
841 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
848 if (!GetUpdateRegion().IsEmpty())
849 dc.SetClippingRegion( GetUpdateRegion() );
855 m_printPreview
->PaintPage(this, dc
);
859 // Responds to colour changes, and passes event on to children.
860 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
863 // The app workspace colour is always white, but we should have
864 // a contrast with the page.
865 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
866 #elif defined(__WXGTK__)
867 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
869 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
871 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
874 // Propagate the event to the non-top-level children
875 wxWindow::OnSysColourChanged(event
);
878 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
880 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
881 if (event
.GetKeyCode() == WXK_ESCAPE
)
883 ((wxPreviewFrame
*) GetParent())->Close(true);
886 else if (event
.GetKeyCode() == WXK_TAB
)
888 controlBar
->OnGoto();
891 else if (event
.GetKeyCode() == WXK_RETURN
)
893 controlBar
->OnPrint();
897 if (!event
.ControlDown())
903 switch(event
.GetKeyCode())
906 controlBar
->OnNext(); break;
908 controlBar
->OnPrevious(); break;
910 controlBar
->OnFirst(); break;
912 controlBar
->OnLast(); break;
920 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
922 wxPreviewControlBar
*
923 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
927 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
929 int currentZoom
= controlBar
->GetZoomControl();
932 if ( currentZoom
< 100 )
934 else if ( currentZoom
<= 120 )
939 if ( event
.GetWheelRotation() > 0 )
942 int newZoom
= currentZoom
+ delta
;
947 if ( newZoom
!= currentZoom
)
949 controlBar
->SetZoomControl(newZoom
);
950 m_printPreview
->SetZoom(newZoom
);
960 #endif // wxUSE_MOUSEWHEEL
962 //----------------------------------------------------------------------------
963 // wxPreviewControlBar
964 //----------------------------------------------------------------------------
966 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
968 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
969 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
970 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
971 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
972 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
973 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
974 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
975 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
976 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
977 EVT_PAINT(wxPreviewControlBar::OnPaint
)
980 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
981 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
982 long style
, const wxString
& name
):
983 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
985 m_printPreview
= preview
;
986 m_closeButton
= (wxButton
*) NULL
;
987 m_nextPageButton
= (wxButton
*) NULL
;
988 m_previousPageButton
= (wxButton
*) NULL
;
989 m_printButton
= (wxButton
*) NULL
;
990 m_zoomControl
= (wxChoice
*) NULL
;
991 m_buttonFlags
= buttons
;
994 wxPreviewControlBar::~wxPreviewControlBar()
998 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1004 dc
.SetPen(*wxBLACK_PEN
);
1005 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1006 dc
.DrawLine( 0, h
-1, w
, h
-1 );
1009 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
1011 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1015 void wxPreviewControlBar::OnPrint(void)
1017 wxPrintPreviewBase
*preview
= GetPrintPreview();
1018 preview
->Print(true);
1021 void wxPreviewControlBar::OnNext(void)
1023 wxPrintPreviewBase
*preview
= GetPrintPreview();
1026 int currentPage
= preview
->GetCurrentPage();
1027 if ((preview
->GetMaxPage() > 0) &&
1028 (currentPage
< preview
->GetMaxPage()) &&
1029 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1031 preview
->SetCurrentPage(currentPage
+ 1);
1036 void wxPreviewControlBar::OnPrevious(void)
1038 wxPrintPreviewBase
*preview
= GetPrintPreview();
1041 int currentPage
= preview
->GetCurrentPage();
1042 if ((preview
->GetMinPage() > 0) &&
1043 (currentPage
> preview
->GetMinPage()) &&
1044 preview
->GetPrintout()->HasPage(currentPage
- 1))
1046 preview
->SetCurrentPage(currentPage
- 1);
1051 void wxPreviewControlBar::OnFirst(void)
1053 wxPrintPreviewBase
*preview
= GetPrintPreview();
1056 int currentPage
= preview
->GetMinPage();
1057 if (preview
->GetPrintout()->HasPage(currentPage
))
1059 preview
->SetCurrentPage(currentPage
);
1064 void wxPreviewControlBar::OnLast(void)
1066 wxPrintPreviewBase
*preview
= GetPrintPreview();
1069 int currentPage
= preview
->GetMaxPage();
1070 if (preview
->GetPrintout()->HasPage(currentPage
))
1072 preview
->SetCurrentPage(currentPage
);
1077 void wxPreviewControlBar::OnGoto(void)
1079 wxPrintPreviewBase
*preview
= GetPrintPreview();
1084 if (preview
->GetMinPage() > 0)
1089 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1090 preview
->GetMinPage(), preview
->GetMaxPage());
1091 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1094 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1096 if ( strPage
.ToLong( ¤tPage
) )
1097 if (preview
->GetPrintout()->HasPage(currentPage
))
1099 preview
->SetCurrentPage(currentPage
);
1105 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1107 int zoom
= GetZoomControl();
1108 if (GetPrintPreview())
1109 GetPrintPreview()->SetZoom(zoom
);
1112 void wxPreviewControlBar::CreateButtons()
1114 SetSize(0, 0, 400, 40);
1116 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1118 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1119 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1121 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1123 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1124 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1127 // Exact-fit buttons are too tiny on wxUniversal
1129 wxSize navButtonSize
;
1130 #ifdef __WXUNIVERSAL__
1132 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1134 navButtonStyle
= wxBU_EXACTFIT
;
1135 navButtonSize
= wxDefaultSize
;
1138 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1140 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1141 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1144 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1146 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1147 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1150 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1152 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1153 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1156 if (m_buttonFlags
& wxPREVIEW_LAST
)
1158 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1159 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1162 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1164 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1165 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1168 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1170 wxString choices
[] =
1172 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1173 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1174 wxT("120%"), wxT("150%"), wxT("200%")
1176 int n
= WXSIZEOF(choices
);
1178 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1179 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1180 SetZoomControl(m_printPreview
->GetZoom());
1187 void wxPreviewControlBar::SetZoomControl(int zoom
)
1191 int n
, count
= m_zoomControl
->GetCount();
1193 for (n
=0; n
<count
; n
++)
1195 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1196 (val
>= long(zoom
)))
1198 m_zoomControl
->SetSelection(n
);
1203 m_zoomControl
->SetSelection(count
-1);
1207 int wxPreviewControlBar::GetZoomControl()
1209 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1212 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1224 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1226 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1227 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1230 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1231 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1232 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1234 m_printPreview
= preview
;
1235 m_controlBar
= NULL
;
1236 m_previewCanvas
= NULL
;
1237 m_windowDisabler
= NULL
;
1239 // Give the application icon
1241 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1243 SetIcon(topFrame
->GetIcon());
1247 wxPreviewFrame::~wxPreviewFrame()
1251 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1253 if (m_windowDisabler
)
1254 delete m_windowDisabler
;
1256 // Need to delete the printout and the print preview
1257 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1261 m_printPreview
->SetPrintout(NULL
);
1262 m_printPreview
->SetCanvas(NULL
);
1263 m_printPreview
->SetFrame(NULL
);
1265 delete m_printPreview
;
1270 void wxPreviewFrame::Initialize()
1278 m_printPreview
->SetCanvas(m_previewCanvas
);
1279 m_printPreview
->SetFrame(this);
1281 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1283 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1284 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1286 SetAutoLayout( true );
1289 m_windowDisabler
= new wxWindowDisabler(this);
1293 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1294 m_previewCanvas
->SetFocus();
1295 m_controlBar
->SetFocus();
1298 void wxPreviewFrame::CreateCanvas()
1300 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1303 void wxPreviewFrame::CreateControlBar()
1305 long buttons
= wxPREVIEW_DEFAULT
;
1306 if (m_printPreview
->GetPrintoutForPrinting())
1307 buttons
|= wxPREVIEW_PRINT
;
1309 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1310 m_controlBar
->CreateButtons();
1317 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1319 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1320 wxPrintout
*printoutForPrinting
,
1324 m_printDialogData
= (*data
);
1326 Init(printout
, printoutForPrinting
);
1329 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1330 wxPrintout
*printoutForPrinting
,
1331 wxPrintDialogData
*data
)
1334 m_printDialogData
= (*data
);
1336 Init(printout
, printoutForPrinting
);
1339 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1340 wxPrintout
*printoutForPrinting
)
1343 m_previewPrintout
= printout
;
1344 if (m_previewPrintout
)
1345 m_previewPrintout
->SetIsPreview(true);
1347 m_printPrintout
= printoutForPrinting
;
1349 m_previewCanvas
= NULL
;
1350 m_previewFrame
= NULL
;
1351 m_previewBitmap
= NULL
;
1358 m_printingPrepared
= false;
1363 wxPrintPreviewBase::~wxPrintPreviewBase()
1365 if (m_previewPrintout
)
1366 delete m_previewPrintout
;
1367 if (m_previewBitmap
)
1368 delete m_previewBitmap
;
1369 if (m_printPrintout
)
1370 delete m_printPrintout
;
1373 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1375 if (m_currentPage
== pageNum
)
1378 m_currentPage
= pageNum
;
1379 if (m_previewBitmap
)
1381 delete m_previewBitmap
;
1382 m_previewBitmap
= NULL
;
1385 if (m_previewCanvas
)
1387 AdjustScrollbars(m_previewCanvas
);
1389 if (!RenderPage(pageNum
))
1391 m_previewCanvas
->Refresh();
1392 m_previewCanvas
->SetFocus();
1397 int wxPrintPreviewBase::GetCurrentPage() const
1398 { return m_currentPage
; }
1399 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1400 { m_previewPrintout
= printout
; }
1401 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1402 { return m_previewPrintout
; }
1403 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1404 { return m_printPrintout
; }
1405 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1406 { m_previewFrame
= frame
; }
1407 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1408 { m_previewCanvas
= canvas
; }
1409 wxFrame
*wxPrintPreviewBase::GetFrame() const
1410 { return m_previewFrame
; }
1411 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1412 { return m_previewCanvas
; }
1414 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1416 // Calculate the rectangles for the printable area of the page and the
1417 // entire paper as they appear on the canvas on-screen.
1418 int canvasWidth
, canvasHeight
;
1419 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1421 float zoomScale
= float(m_currentZoom
) / 100;
1422 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1423 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1425 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1426 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1427 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1428 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1429 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1430 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1431 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1433 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1434 if (paperRect
.x
< m_leftMargin
)
1435 paperRect
.x
= m_leftMargin
;
1436 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1437 if (paperRect
.y
< m_topMargin
)
1438 paperRect
.y
= m_topMargin
;
1440 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1441 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1442 pageRect
.width
= wxCoord(screenPrintableWidth
);
1443 pageRect
.height
= wxCoord(screenPrintableHeight
);
1447 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1449 DrawBlankPage(canvas
, dc
);
1451 if (!m_previewBitmap
)
1452 if (!RenderPage(m_currentPage
))
1454 if (!m_previewBitmap
)
1459 wxRect pageRect
, paperRect
;
1460 CalcRects(canvas
, pageRect
, paperRect
);
1462 temp_dc
.SelectObject(*m_previewBitmap
);
1464 dc
.Blit(pageRect
.x
, pageRect
.y
,
1465 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1467 temp_dc
.SelectObject(wxNullBitmap
);
1471 // Adjusts the scrollbars for the current scale
1472 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1477 wxRect pageRect
, paperRect
;
1478 CalcRects(canvas
, pageRect
, paperRect
);
1479 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1480 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1481 int scrollUnitsX
= totalWidth
/ 10;
1482 int scrollUnitsY
= totalHeight
/ 10;
1483 wxSize virtualSize
= canvas
->GetVirtualSize();
1484 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1485 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1488 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1492 if (!m_previewCanvas
)
1494 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1498 wxRect pageRect
, paperRect
;
1499 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1501 if (!m_previewBitmap
)
1503 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1505 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1507 if (m_previewBitmap
) {
1508 delete m_previewBitmap
;
1509 m_previewBitmap
= NULL
;
1511 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1516 wxMemoryDC memoryDC
;
1517 memoryDC
.SelectObject(*m_previewBitmap
);
1521 m_previewPrintout
->SetDC(&memoryDC
);
1522 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1524 // Need to delay OnPreparePrinting until here, so we have enough information.
1525 if (!m_printingPrepared
)
1527 m_previewPrintout
->OnPreparePrinting();
1529 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1530 m_printingPrepared
= true;
1533 m_previewPrintout
->OnBeginPrinting();
1535 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1537 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1539 memoryDC
.SelectObject(wxNullBitmap
);
1541 delete m_previewBitmap
;
1542 m_previewBitmap
= NULL
;
1546 m_previewPrintout
->OnPrintPage(pageNum
);
1547 m_previewPrintout
->OnEndDocument();
1548 m_previewPrintout
->OnEndPrinting();
1550 m_previewPrintout
->SetDC(NULL
);
1552 memoryDC
.SelectObject(wxNullBitmap
);
1557 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1559 status
= wxString::Format(_("Page %d"), pageNum
);
1562 m_previewFrame
->SetStatusText(status
);
1568 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1570 wxRect pageRect
, paperRect
;
1572 CalcRects(canvas
, pageRect
, paperRect
);
1574 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1575 wxCoord shadowOffset
= 4;
1577 dc
.SetPen(*wxBLACK_PEN
);
1578 dc
.SetBrush(*wxBLACK_BRUSH
);
1579 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1580 paperRect
.width
, shadowOffset
);
1582 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1583 shadowOffset
, paperRect
.height
);
1585 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1586 dc
.SetPen(*wxBLACK_PEN
);
1587 dc
.SetBrush(*wxWHITE_BRUSH
);
1588 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1589 paperRect
.width
+ 3, paperRect
.height
+ 2);
1594 void wxPrintPreviewBase::SetZoom(int percent
)
1596 if (m_currentZoom
== percent
)
1599 m_currentZoom
= percent
;
1600 if (m_previewBitmap
)
1602 delete m_previewBitmap
;
1603 m_previewBitmap
= NULL
;
1606 if (m_previewCanvas
)
1608 AdjustScrollbars(m_previewCanvas
);
1609 RenderPage(m_currentPage
);
1610 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1611 m_previewCanvas
->ClearBackground();
1612 m_previewCanvas
->Refresh();
1613 m_previewCanvas
->SetFocus();
1617 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1619 return m_printDialogData
;
1622 int wxPrintPreviewBase::GetZoom() const
1623 { return m_currentZoom
; }
1624 int wxPrintPreviewBase::GetMaxPage() const
1625 { return m_maxPage
; }
1626 int wxPrintPreviewBase::GetMinPage() const
1627 { return m_minPage
; }
1628 bool wxPrintPreviewBase::IsOk() const
1630 void wxPrintPreviewBase::SetOk(bool ok
)
1633 //----------------------------------------------------------------------------
1635 //----------------------------------------------------------------------------
1637 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1639 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1640 wxPrintout
*printoutForPrinting
,
1641 wxPrintDialogData
*data
) :
1642 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1644 m_pimpl
= wxPrintFactory::GetFactory()->
1645 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1648 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1649 wxPrintout
*printoutForPrinting
,
1650 wxPrintData
*data
) :
1651 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1653 m_pimpl
= wxPrintFactory::GetFactory()->
1654 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1657 wxPrintPreview::~wxPrintPreview()
1661 // don't delete twice
1662 m_printPrintout
= NULL
;
1663 m_previewPrintout
= NULL
;
1664 m_previewBitmap
= NULL
;
1667 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1669 return m_pimpl
->SetCurrentPage( pageNum
);
1672 int wxPrintPreview::GetCurrentPage() const
1674 return m_pimpl
->GetCurrentPage();
1677 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1679 m_pimpl
->SetPrintout( printout
);
1682 wxPrintout
*wxPrintPreview::GetPrintout() const
1684 return m_pimpl
->GetPrintout();
1687 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1689 return m_pimpl
->GetPrintoutForPrinting();
1692 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1694 m_pimpl
->SetFrame( frame
);
1697 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1699 m_pimpl
->SetCanvas( canvas
);
1702 wxFrame
*wxPrintPreview::GetFrame() const
1704 return m_pimpl
->GetFrame();
1707 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1709 return m_pimpl
->GetCanvas();
1712 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1714 return m_pimpl
->PaintPage( canvas
, dc
);
1717 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1719 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1722 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1724 m_pimpl
->AdjustScrollbars( canvas
);
1727 bool wxPrintPreview::RenderPage(int pageNum
)
1729 return m_pimpl
->RenderPage( pageNum
);
1732 void wxPrintPreview::SetZoom(int percent
)
1734 m_pimpl
->SetZoom( percent
);
1737 int wxPrintPreview::GetZoom() const
1739 return m_pimpl
->GetZoom();
1742 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1744 return m_pimpl
->GetPrintDialogData();
1747 int wxPrintPreview::GetMaxPage() const
1749 return m_pimpl
->GetMaxPage();
1752 int wxPrintPreview::GetMinPage() const
1754 return m_pimpl
->GetMinPage();
1757 bool wxPrintPreview::IsOk() const
1759 return m_pimpl
->Ok();
1762 void wxPrintPreview::SetOk(bool ok
)
1764 m_pimpl
->SetOk( ok
);
1767 bool wxPrintPreview::Print(bool interactive
)
1769 return m_pimpl
->Print( interactive
);
1772 void wxPrintPreview::DetermineScaling()
1774 m_pimpl
->DetermineScaling();
1777 #endif // wxUSE_PRINTING_ARCHITECTURE