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 switch (event
.GetKeyCode())
884 controlBar
->OnGoto();
887 controlBar
->OnPrint();
891 if (!event
.ControlDown())
897 switch(event
.GetKeyCode())
900 controlBar
->OnNext(); break;
902 controlBar
->OnPrevious(); break;
904 controlBar
->OnFirst(); break;
906 controlBar
->OnLast(); break;
914 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
916 wxPreviewControlBar
*
917 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
921 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
923 int currentZoom
= controlBar
->GetZoomControl();
926 if ( currentZoom
< 100 )
928 else if ( currentZoom
<= 120 )
933 if ( event
.GetWheelRotation() > 0 )
936 int newZoom
= currentZoom
+ delta
;
941 if ( newZoom
!= currentZoom
)
943 controlBar
->SetZoomControl(newZoom
);
944 m_printPreview
->SetZoom(newZoom
);
954 #endif // wxUSE_MOUSEWHEEL
956 //----------------------------------------------------------------------------
957 // wxPreviewControlBar
958 //----------------------------------------------------------------------------
960 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
962 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
963 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
964 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
965 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
966 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
967 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
968 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
969 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
970 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
971 EVT_PAINT(wxPreviewControlBar::OnPaint
)
974 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
975 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
976 long style
, const wxString
& name
):
977 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
979 m_printPreview
= preview
;
980 m_closeButton
= (wxButton
*) NULL
;
981 m_nextPageButton
= (wxButton
*) NULL
;
982 m_previousPageButton
= (wxButton
*) NULL
;
983 m_printButton
= (wxButton
*) NULL
;
984 m_zoomControl
= (wxChoice
*) NULL
;
985 m_buttonFlags
= buttons
;
988 wxPreviewControlBar::~wxPreviewControlBar()
992 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
998 dc
.SetPen(*wxBLACK_PEN
);
999 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1000 dc
.DrawLine( 0, h
-1, w
, h
-1 );
1003 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
1005 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1009 void wxPreviewControlBar::OnPrint(void)
1011 wxPrintPreviewBase
*preview
= GetPrintPreview();
1012 preview
->Print(true);
1015 void wxPreviewControlBar::OnNext(void)
1017 wxPrintPreviewBase
*preview
= GetPrintPreview();
1020 int currentPage
= preview
->GetCurrentPage();
1021 if ((preview
->GetMaxPage() > 0) &&
1022 (currentPage
< preview
->GetMaxPage()) &&
1023 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1025 preview
->SetCurrentPage(currentPage
+ 1);
1030 void wxPreviewControlBar::OnPrevious(void)
1032 wxPrintPreviewBase
*preview
= GetPrintPreview();
1035 int currentPage
= preview
->GetCurrentPage();
1036 if ((preview
->GetMinPage() > 0) &&
1037 (currentPage
> preview
->GetMinPage()) &&
1038 preview
->GetPrintout()->HasPage(currentPage
- 1))
1040 preview
->SetCurrentPage(currentPage
- 1);
1045 void wxPreviewControlBar::OnFirst(void)
1047 wxPrintPreviewBase
*preview
= GetPrintPreview();
1050 int currentPage
= preview
->GetMinPage();
1051 if (preview
->GetPrintout()->HasPage(currentPage
))
1053 preview
->SetCurrentPage(currentPage
);
1058 void wxPreviewControlBar::OnLast(void)
1060 wxPrintPreviewBase
*preview
= GetPrintPreview();
1063 int currentPage
= preview
->GetMaxPage();
1064 if (preview
->GetPrintout()->HasPage(currentPage
))
1066 preview
->SetCurrentPage(currentPage
);
1071 void wxPreviewControlBar::OnGoto(void)
1073 wxPrintPreviewBase
*preview
= GetPrintPreview();
1078 if (preview
->GetMinPage() > 0)
1083 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1084 preview
->GetMinPage(), preview
->GetMaxPage());
1085 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1088 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1090 if ( strPage
.ToLong( ¤tPage
) )
1091 if (preview
->GetPrintout()->HasPage(currentPage
))
1093 preview
->SetCurrentPage(currentPage
);
1099 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1101 int zoom
= GetZoomControl();
1102 if (GetPrintPreview())
1103 GetPrintPreview()->SetZoom(zoom
);
1106 void wxPreviewControlBar::CreateButtons()
1108 SetSize(0, 0, 400, 40);
1110 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1112 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1113 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1115 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1117 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1118 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1121 // Exact-fit buttons are too tiny on wxUniversal
1123 wxSize navButtonSize
;
1124 #ifdef __WXUNIVERSAL__
1126 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1128 navButtonStyle
= wxBU_EXACTFIT
;
1129 navButtonSize
= wxDefaultSize
;
1132 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1134 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1135 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1138 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1140 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1141 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1144 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1146 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1147 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1150 if (m_buttonFlags
& wxPREVIEW_LAST
)
1152 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1153 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1156 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1158 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1159 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1162 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1164 wxString choices
[] =
1166 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1167 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1168 wxT("120%"), wxT("150%"), wxT("200%")
1170 int n
= WXSIZEOF(choices
);
1172 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1173 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1174 SetZoomControl(m_printPreview
->GetZoom());
1181 void wxPreviewControlBar::SetZoomControl(int zoom
)
1185 int n
, count
= m_zoomControl
->GetCount();
1187 for (n
=0; n
<count
; n
++)
1189 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1190 (val
>= long(zoom
)))
1192 m_zoomControl
->SetSelection(n
);
1197 m_zoomControl
->SetSelection(count
-1);
1201 int wxPreviewControlBar::GetZoomControl()
1203 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1206 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1218 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1220 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1221 EVT_CHAR_HOOK(wxPreviewFrame::OnChar
)
1222 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1225 void wxPreviewFrame::OnChar(wxKeyEvent
&event
)
1227 if ( event
.GetKeyCode() == WXK_ESCAPE
)
1237 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1238 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1239 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1241 m_printPreview
= preview
;
1242 m_controlBar
= NULL
;
1243 m_previewCanvas
= NULL
;
1244 m_windowDisabler
= NULL
;
1246 // Give the application icon
1248 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1250 SetIcon(topFrame
->GetIcon());
1254 wxPreviewFrame::~wxPreviewFrame()
1258 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1260 if (m_windowDisabler
)
1261 delete m_windowDisabler
;
1263 // Need to delete the printout and the print preview
1264 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1268 m_printPreview
->SetPrintout(NULL
);
1269 m_printPreview
->SetCanvas(NULL
);
1270 m_printPreview
->SetFrame(NULL
);
1272 delete m_printPreview
;
1277 void wxPreviewFrame::Initialize()
1285 m_printPreview
->SetCanvas(m_previewCanvas
);
1286 m_printPreview
->SetFrame(this);
1288 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1290 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1291 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1293 SetAutoLayout( true );
1296 m_windowDisabler
= new wxWindowDisabler(this);
1300 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1301 m_previewCanvas
->SetFocus();
1302 m_controlBar
->SetFocus();
1305 void wxPreviewFrame::CreateCanvas()
1307 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1310 void wxPreviewFrame::CreateControlBar()
1312 long buttons
= wxPREVIEW_DEFAULT
;
1313 if (m_printPreview
->GetPrintoutForPrinting())
1314 buttons
|= wxPREVIEW_PRINT
;
1316 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1317 m_controlBar
->CreateButtons();
1324 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1326 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1327 wxPrintout
*printoutForPrinting
,
1331 m_printDialogData
= (*data
);
1333 Init(printout
, printoutForPrinting
);
1336 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1337 wxPrintout
*printoutForPrinting
,
1338 wxPrintDialogData
*data
)
1341 m_printDialogData
= (*data
);
1343 Init(printout
, printoutForPrinting
);
1346 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1347 wxPrintout
*printoutForPrinting
)
1350 m_previewPrintout
= printout
;
1351 if (m_previewPrintout
)
1352 m_previewPrintout
->SetIsPreview(true);
1354 m_printPrintout
= printoutForPrinting
;
1356 m_previewCanvas
= NULL
;
1357 m_previewFrame
= NULL
;
1358 m_previewBitmap
= NULL
;
1365 m_printingPrepared
= false;
1370 wxPrintPreviewBase::~wxPrintPreviewBase()
1372 if (m_previewPrintout
)
1373 delete m_previewPrintout
;
1374 if (m_previewBitmap
)
1375 delete m_previewBitmap
;
1376 if (m_printPrintout
)
1377 delete m_printPrintout
;
1380 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1382 if (m_currentPage
== pageNum
)
1385 m_currentPage
= pageNum
;
1386 if (m_previewBitmap
)
1388 delete m_previewBitmap
;
1389 m_previewBitmap
= NULL
;
1392 if (m_previewCanvas
)
1394 AdjustScrollbars(m_previewCanvas
);
1396 if (!RenderPage(pageNum
))
1398 m_previewCanvas
->Refresh();
1399 m_previewCanvas
->SetFocus();
1404 int wxPrintPreviewBase::GetCurrentPage() const
1405 { return m_currentPage
; }
1406 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1407 { m_previewPrintout
= printout
; }
1408 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1409 { return m_previewPrintout
; }
1410 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1411 { return m_printPrintout
; }
1412 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1413 { m_previewFrame
= frame
; }
1414 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1415 { m_previewCanvas
= canvas
; }
1416 wxFrame
*wxPrintPreviewBase::GetFrame() const
1417 { return m_previewFrame
; }
1418 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1419 { return m_previewCanvas
; }
1421 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1423 // Calculate the rectangles for the printable area of the page and the
1424 // entire paper as they appear on the canvas on-screen.
1425 int canvasWidth
, canvasHeight
;
1426 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1428 float zoomScale
= float(m_currentZoom
) / 100;
1429 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1430 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1432 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1433 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1434 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1435 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1436 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1437 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1438 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1440 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1441 if (paperRect
.x
< m_leftMargin
)
1442 paperRect
.x
= m_leftMargin
;
1443 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1444 if (paperRect
.y
< m_topMargin
)
1445 paperRect
.y
= m_topMargin
;
1447 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1448 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1449 pageRect
.width
= wxCoord(screenPrintableWidth
);
1450 pageRect
.height
= wxCoord(screenPrintableHeight
);
1454 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1456 DrawBlankPage(canvas
, dc
);
1458 if (!m_previewBitmap
)
1459 if (!RenderPage(m_currentPage
))
1461 if (!m_previewBitmap
)
1466 wxRect pageRect
, paperRect
;
1467 CalcRects(canvas
, pageRect
, paperRect
);
1469 temp_dc
.SelectObject(*m_previewBitmap
);
1471 dc
.Blit(pageRect
.x
, pageRect
.y
,
1472 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1474 temp_dc
.SelectObject(wxNullBitmap
);
1478 // Adjusts the scrollbars for the current scale
1479 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1484 wxRect pageRect
, paperRect
;
1485 CalcRects(canvas
, pageRect
, paperRect
);
1486 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1487 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1488 int scrollUnitsX
= totalWidth
/ 10;
1489 int scrollUnitsY
= totalHeight
/ 10;
1490 wxSize virtualSize
= canvas
->GetVirtualSize();
1491 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1492 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1495 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1499 if (!m_previewCanvas
)
1501 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1505 wxRect pageRect
, paperRect
;
1506 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1508 if (!m_previewBitmap
)
1510 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1512 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1514 if (m_previewBitmap
) {
1515 delete m_previewBitmap
;
1516 m_previewBitmap
= NULL
;
1518 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1523 wxMemoryDC memoryDC
;
1524 memoryDC
.SelectObject(*m_previewBitmap
);
1528 m_previewPrintout
->SetDC(&memoryDC
);
1529 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1531 // Need to delay OnPreparePrinting until here, so we have enough information.
1532 if (!m_printingPrepared
)
1534 m_previewPrintout
->OnPreparePrinting();
1536 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1537 m_printingPrepared
= true;
1540 m_previewPrintout
->OnBeginPrinting();
1542 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1544 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1546 memoryDC
.SelectObject(wxNullBitmap
);
1548 delete m_previewBitmap
;
1549 m_previewBitmap
= NULL
;
1553 m_previewPrintout
->OnPrintPage(pageNum
);
1554 m_previewPrintout
->OnEndDocument();
1555 m_previewPrintout
->OnEndPrinting();
1557 m_previewPrintout
->SetDC(NULL
);
1559 memoryDC
.SelectObject(wxNullBitmap
);
1564 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1566 status
= wxString::Format(_("Page %d"), pageNum
);
1569 m_previewFrame
->SetStatusText(status
);
1575 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1577 wxRect pageRect
, paperRect
;
1579 CalcRects(canvas
, pageRect
, paperRect
);
1581 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1582 wxCoord shadowOffset
= 4;
1584 dc
.SetPen(*wxBLACK_PEN
);
1585 dc
.SetBrush(*wxBLACK_BRUSH
);
1586 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1587 paperRect
.width
, shadowOffset
);
1589 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1590 shadowOffset
, paperRect
.height
);
1592 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1593 dc
.SetPen(*wxBLACK_PEN
);
1594 dc
.SetBrush(*wxWHITE_BRUSH
);
1595 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1596 paperRect
.width
+ 3, paperRect
.height
+ 2);
1601 void wxPrintPreviewBase::SetZoom(int percent
)
1603 if (m_currentZoom
== percent
)
1606 m_currentZoom
= percent
;
1607 if (m_previewBitmap
)
1609 delete m_previewBitmap
;
1610 m_previewBitmap
= NULL
;
1613 if (m_previewCanvas
)
1615 AdjustScrollbars(m_previewCanvas
);
1616 RenderPage(m_currentPage
);
1617 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1618 m_previewCanvas
->ClearBackground();
1619 m_previewCanvas
->Refresh();
1620 m_previewCanvas
->SetFocus();
1624 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1626 return m_printDialogData
;
1629 int wxPrintPreviewBase::GetZoom() const
1630 { return m_currentZoom
; }
1631 int wxPrintPreviewBase::GetMaxPage() const
1632 { return m_maxPage
; }
1633 int wxPrintPreviewBase::GetMinPage() const
1634 { return m_minPage
; }
1635 bool wxPrintPreviewBase::IsOk() const
1637 void wxPrintPreviewBase::SetOk(bool ok
)
1640 //----------------------------------------------------------------------------
1642 //----------------------------------------------------------------------------
1644 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1646 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1647 wxPrintout
*printoutForPrinting
,
1648 wxPrintDialogData
*data
) :
1649 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1651 m_pimpl
= wxPrintFactory::GetFactory()->
1652 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1655 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1656 wxPrintout
*printoutForPrinting
,
1657 wxPrintData
*data
) :
1658 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1660 m_pimpl
= wxPrintFactory::GetFactory()->
1661 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1664 wxPrintPreview::~wxPrintPreview()
1668 // don't delete twice
1669 m_printPrintout
= NULL
;
1670 m_previewPrintout
= NULL
;
1671 m_previewBitmap
= NULL
;
1674 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1676 return m_pimpl
->SetCurrentPage( pageNum
);
1679 int wxPrintPreview::GetCurrentPage() const
1681 return m_pimpl
->GetCurrentPage();
1684 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1686 m_pimpl
->SetPrintout( printout
);
1689 wxPrintout
*wxPrintPreview::GetPrintout() const
1691 return m_pimpl
->GetPrintout();
1694 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1696 return m_pimpl
->GetPrintoutForPrinting();
1699 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1701 m_pimpl
->SetFrame( frame
);
1704 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1706 m_pimpl
->SetCanvas( canvas
);
1709 wxFrame
*wxPrintPreview::GetFrame() const
1711 return m_pimpl
->GetFrame();
1714 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1716 return m_pimpl
->GetCanvas();
1719 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1721 return m_pimpl
->PaintPage( canvas
, dc
);
1724 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1726 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1729 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1731 m_pimpl
->AdjustScrollbars( canvas
);
1734 bool wxPrintPreview::RenderPage(int pageNum
)
1736 return m_pimpl
->RenderPage( pageNum
);
1739 void wxPrintPreview::SetZoom(int percent
)
1741 m_pimpl
->SetZoom( percent
);
1744 int wxPrintPreview::GetZoom() const
1746 return m_pimpl
->GetZoom();
1749 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1751 return m_pimpl
->GetPrintDialogData();
1754 int wxPrintPreview::GetMaxPage() const
1756 return m_pimpl
->GetMaxPage();
1759 int wxPrintPreview::GetMinPage() const
1761 return m_pimpl
->GetMinPage();
1764 bool wxPrintPreview::IsOk() const
1766 return m_pimpl
->Ok();
1769 void wxPrintPreview::SetOk(bool ok
)
1771 m_pimpl
->SetOk( ok
);
1774 bool wxPrintPreview::Print(bool interactive
)
1776 return m_pimpl
->Print( interactive
);
1779 void wxPrintPreview::DetermineScaling()
1781 m_pimpl
->DetermineScaling();
1784 #endif // wxUSE_PRINTING_ARCHITECTURE