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
);
210 wxImplDC
* wxNativePrintFactory::CreatePrinterImplDC( wxPrinterDC
*owner
, const wxPrintData
& data
)
212 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
213 return new wxWindowsPrinterDCImpl( owner
, data
);
214 #elif defined(__WXMAC__)
215 return new wxMacPrinterDCImpl( owner
, data
);
217 return new wxPostScriptImplDC( owner
, data
);
223 wxDC
* wxNativePrintFactory::CreatePrinterDC( const wxPrintData
& data
)
225 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
226 return new wxPrinterDC(data
);
227 #elif defined(__WXMAC__)
228 return new wxPrinterDC(data
);
230 return new wxPostScriptDC(data
);
236 bool wxNativePrintFactory::HasOwnPrintToFile()
238 // Only relevant for PostScript and here the
239 // setup dialog provides no "print to file"
240 // option. In the GNOME setup dialog, the
241 // setup dialog has its own print to file.
245 bool wxNativePrintFactory::HasPrinterLine()
247 // Only relevant for PostScript for now
251 wxString
wxNativePrintFactory::CreatePrinterLine()
253 // Only relevant for PostScript for now
255 // We should query "lpstat -d" here
256 return _("Generic PostScript");
259 bool wxNativePrintFactory::HasStatusLine()
261 // Only relevant for PostScript for now
265 wxString
wxNativePrintFactory::CreateStatusLine()
267 // Only relevant for PostScript for now
269 // We should query "lpstat -r" or "lpstat -p" here
273 wxPrintNativeDataBase
*wxNativePrintFactory::CreatePrintNativeData()
275 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
276 return new wxWindowsPrintNativeData
;
277 #elif defined(__WXMAC__)
278 return new wxMacCarbonPrintData
;
280 return new wxPostScriptPrintNativeData
;
284 //----------------------------------------------------------------------------
285 // wxPrintNativeDataBase
286 //----------------------------------------------------------------------------
288 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase
, wxObject
)
290 wxPrintNativeDataBase::wxPrintNativeDataBase()
295 //----------------------------------------------------------------------------
296 // wxPrintFactoryModule
297 //----------------------------------------------------------------------------
299 class wxPrintFactoryModule
: public wxModule
302 wxPrintFactoryModule() {}
303 bool OnInit() { return true; }
304 void OnExit() { wxPrintFactory::SetPrintFactory( NULL
); }
307 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule
)
310 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule
, wxModule
)
312 //----------------------------------------------------------------------------
314 //----------------------------------------------------------------------------
316 IMPLEMENT_CLASS(wxPrinterBase
, wxObject
)
318 wxPrinterBase::wxPrinterBase(wxPrintDialogData
*data
)
320 m_currentPrintout
= (wxPrintout
*) NULL
;
321 sm_abortWindow
= (wxWindow
*) NULL
;
324 m_printDialogData
= (*data
);
325 sm_lastError
= wxPRINTER_NO_ERROR
;
328 wxWindow
*wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
329 bool wxPrinterBase::sm_abortIt
= false;
330 wxPrinterError
wxPrinterBase::sm_lastError
= wxPRINTER_NO_ERROR
;
332 wxPrinterBase::~wxPrinterBase()
336 wxWindow
*wxPrinterBase::CreateAbortWindow(wxWindow
*parent
, wxPrintout
* printout
)
338 wxPrintAbortDialog
*dialog
= new wxPrintAbortDialog(parent
, _("Printing ") , wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
);
340 wxBoxSizer
*button_sizer
= new wxBoxSizer( wxVERTICAL
);
341 button_sizer
->Add( new wxStaticText(dialog
, wxID_ANY
, _("Please wait while printing\n") + printout
->GetTitle() ), 0, wxALL
, 10 );
342 button_sizer
->Add( new wxButton( dialog
, wxID_CANCEL
, wxT("Cancel") ), 0, wxALL
| wxALIGN_CENTER
, 10 );
344 dialog
->SetAutoLayout( true );
345 dialog
->SetSizer( button_sizer
);
347 button_sizer
->Fit(dialog
);
348 button_sizer
->SetSizeHints (dialog
) ;
353 void wxPrinterBase::ReportError(wxWindow
*parent
, wxPrintout
*WXUNUSED(printout
), const wxString
& message
)
355 wxMessageBox(message
, _("Printing Error"), wxOK
, parent
);
358 wxPrintDialogData
& wxPrinterBase::GetPrintDialogData() const
360 return (wxPrintDialogData
&) m_printDialogData
;
363 //----------------------------------------------------------------------------
365 //----------------------------------------------------------------------------
367 IMPLEMENT_CLASS(wxPrinter
, wxPrinterBase
)
369 wxPrinter::wxPrinter(wxPrintDialogData
*data
)
371 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrinter( data
);
374 wxPrinter::~wxPrinter()
379 wxWindow
*wxPrinter::CreateAbortWindow(wxWindow
*parent
, wxPrintout
*printout
)
381 return m_pimpl
->CreateAbortWindow( parent
, printout
);
384 void wxPrinter::ReportError(wxWindow
*parent
, wxPrintout
*printout
, const wxString
& message
)
386 m_pimpl
->ReportError( parent
, printout
, message
);
389 bool wxPrinter::Setup(wxWindow
*parent
)
391 return m_pimpl
->Setup( parent
);
394 bool wxPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
396 return m_pimpl
->Print( parent
, printout
, prompt
);
399 wxDC
* wxPrinter::PrintDialog(wxWindow
*parent
)
401 return m_pimpl
->PrintDialog( parent
);
404 wxPrintDialogData
& wxPrinter::GetPrintDialogData() const
406 return m_pimpl
->GetPrintDialogData();
409 // ---------------------------------------------------------------------------
410 // wxPrintDialogBase: the dialog for printing.
411 // ---------------------------------------------------------------------------
413 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase
, wxDialog
)
415 wxPrintDialogBase::wxPrintDialogBase(wxWindow
*parent
,
417 const wxString
&title
,
421 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Print")) : title
,
426 // ---------------------------------------------------------------------------
427 // wxPrintDialog: the dialog for printing
428 // ---------------------------------------------------------------------------
430 IMPLEMENT_CLASS(wxPrintDialog
, wxObject
)
432 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintDialogData
* data
)
434 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
437 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintData
* data
)
439 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
442 wxPrintDialog::~wxPrintDialog()
447 int wxPrintDialog::ShowModal()
449 return m_pimpl
->ShowModal();
452 wxPrintDialogData
& wxPrintDialog::GetPrintDialogData()
454 return m_pimpl
->GetPrintDialogData();
457 wxPrintData
& wxPrintDialog::GetPrintData()
459 return m_pimpl
->GetPrintData();
462 wxDC
*wxPrintDialog::GetPrintDC()
464 return m_pimpl
->GetPrintDC();
467 // ---------------------------------------------------------------------------
468 // wxPageSetupDialogBase: the page setup dialog
469 // ---------------------------------------------------------------------------
471 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase
, wxDialog
)
473 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow
*parent
,
475 const wxString
&title
,
479 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Page setup")) : title
,
484 // ---------------------------------------------------------------------------
485 // wxPageSetupDialog: the page setup dialog
486 // ---------------------------------------------------------------------------
488 IMPLEMENT_CLASS(wxPageSetupDialog
, wxObject
)
490 wxPageSetupDialog::wxPageSetupDialog(wxWindow
*parent
, wxPageSetupDialogData
*data
)
492 m_pimpl
= wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent
, data
);
495 wxPageSetupDialog::~wxPageSetupDialog()
500 int wxPageSetupDialog::ShowModal()
502 return m_pimpl
->ShowModal();
505 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupDialogData()
507 return m_pimpl
->GetPageSetupDialogData();
511 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupData()
513 return m_pimpl
->GetPageSetupDialogData();
516 //----------------------------------------------------------------------------
517 // wxPrintAbortDialog
518 //----------------------------------------------------------------------------
520 BEGIN_EVENT_TABLE(wxPrintAbortDialog
, wxDialog
)
521 EVT_BUTTON(wxID_CANCEL
, wxPrintAbortDialog::OnCancel
)
524 void wxPrintAbortDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
))
526 wxPrinterBase::sm_abortIt
= true;
527 wxPrinterBase::sm_abortWindow
->Show(false);
528 wxPrinterBase::sm_abortWindow
->Close(true);
529 wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
532 //----------------------------------------------------------------------------
534 //----------------------------------------------------------------------------
536 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
)
538 wxPrintout::wxPrintout(const wxString
& title
)
540 m_printoutTitle
= title
;
541 m_printoutDC
= (wxDC
*) NULL
;
544 m_pageWidthPixels
= 0;
545 m_pageHeightPixels
= 0;
553 wxPrintout::~wxPrintout()
557 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
))
559 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
);
562 void wxPrintout::OnEndDocument()
567 void wxPrintout::OnBeginPrinting()
571 void wxPrintout::OnEndPrinting()
575 bool wxPrintout::HasPage(int page
)
580 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
)
588 void wxPrintout::FitThisSizeToPaper(const wxSize
& imageSize
)
590 // Set the DC scale and origin so that the given image size fits within the
591 // entire page and the origin is at the top left corner of the page. Note
592 // that with most printers, portions of the page will be non-printable. Use
593 // this if you're managing your own page margins.
594 if (!m_printoutDC
) return;
595 wxRect paperRect
= GetPaperRectPixels();
597 GetPageSizePixels(&pw
, &ph
);
599 m_printoutDC
->GetSize(&w
, &h
);
600 float scaleX
= ((float(paperRect
.width
) * w
) / (float(pw
) * imageSize
.x
));
601 float scaleY
= ((float(paperRect
.height
) * h
) / (float(ph
) * imageSize
.y
));
602 float actualScale
= wxMin(scaleX
, scaleY
);
603 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
604 m_printoutDC
->SetDeviceOrigin(0, 0);
605 wxRect logicalPaperRect
= GetLogicalPaperRect();
606 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
609 void wxPrintout::FitThisSizeToPage(const wxSize
& imageSize
)
611 // Set the DC scale and origin so that the given image size fits within the
612 // printable area of the page and the origin is at the top left corner of
613 // the printable area.
614 if (!m_printoutDC
) return;
616 m_printoutDC
->GetSize(&w
, &h
);
617 float scaleX
= float(w
) / imageSize
.x
;
618 float scaleY
= float(h
) / imageSize
.y
;
619 float actualScale
= wxMin(scaleX
, scaleY
);
620 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
621 m_printoutDC
->SetDeviceOrigin(0, 0);
624 void wxPrintout::FitThisSizeToPageMargins(const wxSize
& imageSize
, const wxPageSetupDialogData
& pageSetupData
)
626 // Set the DC scale and origin so that the given image size fits within the
627 // page margins defined in the given wxPageSetupDialogData object and the
628 // origin is at the top left corner of the page margins.
629 if (!m_printoutDC
) return;
630 wxRect paperRect
= GetPaperRectPixels();
632 GetPageSizePixels(&pw
, &ph
);
633 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
634 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
636 GetPageSizeMM(&mw
, &mh
);
637 float mmToDeviceX
= float(pw
) / mw
;
638 float mmToDeviceY
= float(ph
) / mh
;
639 wxRect
pageMarginsRect(paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
640 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
641 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
642 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
644 m_printoutDC
->GetSize(&w
, &h
);
645 float scaleX
= (float(pageMarginsRect
.width
) * w
) / (float(pw
) * imageSize
.x
);
646 float scaleY
= (float(pageMarginsRect
.height
) * h
) / (float(ph
) * imageSize
.y
);
647 float actualScale
= wxMin(scaleX
, scaleY
);
648 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
649 m_printoutDC
->SetDeviceOrigin(0, 0);
650 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
651 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
654 void wxPrintout::MapScreenSizeToPaper()
656 // Set the DC scale so that an image on the screen is the same size on the
657 // paper and the origin is at the top left of the paper. Note that with most
658 // printers, portions of the page will be cut off. Use this if you're
659 // managing your own page margins.
660 if (!m_printoutDC
) return;
661 MapScreenSizeToPage();
662 wxRect logicalPaperRect
= GetLogicalPaperRect();
663 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
666 void wxPrintout::MapScreenSizeToPage()
668 // Set the DC scale and origin so that an image on the screen is the same
669 // size on the paper and the origin is at the top left of the printable area.
670 if (!m_printoutDC
) return;
671 int ppiScreenX
, ppiScreenY
;
672 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
673 int ppiPrinterX
, ppiPrinterY
;
674 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
676 m_printoutDC
->GetSize(&w
, &h
);
677 int pageSizePixelsX
, pageSizePixelsY
;
678 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
679 float userScaleX
= (float(ppiPrinterX
) * w
) / (float(ppiScreenX
) * pageSizePixelsX
);
680 float userScaleY
= (float(ppiPrinterY
) * h
) / (float(ppiScreenY
) * pageSizePixelsY
);
681 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
682 m_printoutDC
->SetDeviceOrigin(0, 0);
685 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData
& pageSetupData
)
687 // Set the DC scale so that an image on the screen is the same size on the
688 // paper and the origin is at the top left of the page margins defined by
689 // the given wxPageSetupDialogData object.
690 if (!m_printoutDC
) return;
691 MapScreenSizeToPage();
692 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
693 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
696 void wxPrintout::MapScreenSizeToDevice()
698 // Set the DC scale so that a screen pixel is the same size as a device
699 // pixel and the origin is at the top left of the printable area.
700 if (!m_printoutDC
) return;
702 m_printoutDC
->GetSize(&w
, &h
);
703 int pageSizePixelsX
, pageSizePixelsY
;
704 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
705 float userScaleX
= float(w
) / pageSizePixelsX
;
706 float userScaleY
= float(h
) / pageSizePixelsY
;
707 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
708 m_printoutDC
->SetDeviceOrigin(0, 0);
711 wxRect
wxPrintout::GetLogicalPaperRect() const
713 // Return the rectangle in logical units that corresponds to the paper
715 wxRect paperRect
= GetPaperRectPixels();
717 GetPageSizePixels(&pw
, &ph
);
719 m_printoutDC
->GetSize(&w
, &h
);
720 if (w
== pw
&& h
== ph
) {
721 // this DC matches the printed page, so no scaling
722 return wxRect(m_printoutDC
->DeviceToLogicalX(paperRect
.x
),
723 m_printoutDC
->DeviceToLogicalY(paperRect
.y
),
724 m_printoutDC
->DeviceToLogicalXRel(paperRect
.width
),
725 m_printoutDC
->DeviceToLogicalYRel(paperRect
.height
));
727 // This DC doesn't match the printed page, so we have to scale.
728 float scaleX
= float(w
) / pw
;
729 float scaleY
= float(h
) / ph
;
730 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(paperRect
.x
* scaleX
)),
731 m_printoutDC
->DeviceToLogicalY(wxRound(paperRect
.y
* scaleY
)),
732 m_printoutDC
->DeviceToLogicalXRel(wxRound(paperRect
.width
* scaleX
)),
733 m_printoutDC
->DeviceToLogicalYRel(wxRound(paperRect
.height
* scaleY
)));
736 wxRect
wxPrintout::GetLogicalPageRect() const
738 // Return the rectangle in logical units that corresponds to the printable
741 m_printoutDC
->GetSize(&w
, &h
);
742 return wxRect(m_printoutDC
->DeviceToLogicalX(0),
743 m_printoutDC
->DeviceToLogicalY(0),
744 m_printoutDC
->DeviceToLogicalXRel(w
),
745 m_printoutDC
->DeviceToLogicalYRel(h
));
748 wxRect
wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData
& pageSetupData
) const
750 // Return the rectangle in logical units that corresponds to the region
751 // within the page margins as specified by the given wxPageSetupDialogData
754 // We get the paper size in device units and the margins in mm,
755 // so we need to calculate the conversion with this trick
757 GetPageSizePixels(&pw
, &ph
);
759 GetPageSizeMM(&mw
, &mh
);
760 float mmToDeviceX
= float(pw
) / mw
;
761 float mmToDeviceY
= float(ph
) / mh
;
763 // paper size in device units
764 wxRect paperRect
= GetPaperRectPixels();
767 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
768 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
770 // calculate margins in device units
771 wxRect
pageMarginsRect(
772 paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
773 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
774 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
775 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
778 m_printoutDC
->GetSize(&w
, &h
);
779 if (w
== pw
&& h
== ph
)
781 // this DC matches the printed page, so no scaling
783 m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),
784 m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),
785 m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),
786 m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
));
789 // This DC doesn't match the printed page, so we have to scale.
790 float scaleX
= float(w
) / pw
;
791 float scaleY
= float(h
) / ph
;
792 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(pageMarginsRect
.x
* scaleX
)),
793 m_printoutDC
->DeviceToLogicalY(wxRound(pageMarginsRect
.y
* scaleY
)),
794 m_printoutDC
->DeviceToLogicalXRel(wxRound(pageMarginsRect
.width
* scaleX
)),
795 m_printoutDC
->DeviceToLogicalYRel(wxRound(pageMarginsRect
.height
* scaleY
)));
798 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
)
800 // Set the device origin by specifying a point in logical coordinates.
801 m_printoutDC
->SetDeviceOrigin(
802 m_printoutDC
->LogicalToDeviceX(x
),
803 m_printoutDC
->LogicalToDeviceY(y
) );
806 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
)
808 // Offset the device origin by a specified distance in device coordinates.
809 wxPoint dev_org
= m_printoutDC
->GetDeviceOrigin();
810 m_printoutDC
->SetDeviceOrigin(
811 dev_org
.x
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),
812 dev_org
.y
+ m_printoutDC
->LogicalToDeviceYRel(yoff
) );
816 //----------------------------------------------------------------------------
818 //----------------------------------------------------------------------------
820 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
822 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
823 EVT_PAINT(wxPreviewCanvas::OnPaint
)
824 EVT_CHAR(wxPreviewCanvas::OnChar
)
825 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
827 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
831 // VZ: the current code doesn't refresh properly without
832 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
833 // really horrible flicker when resizing the preview frame, but without
834 // this style it simply doesn't work correctly at all...
835 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
836 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
837 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
839 m_printPreview
= preview
;
841 // The app workspace colour is always white, but we should have
842 // a contrast with the page.
843 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
844 #elif defined(__WXGTK__)
845 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
847 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
849 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
851 SetScrollbars(10, 10, 100, 100);
854 wxPreviewCanvas::~wxPreviewCanvas()
858 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
865 if (!GetUpdateRegion().IsEmpty())
866 dc.SetClippingRegion( GetUpdateRegion() );
872 m_printPreview
->PaintPage(this, dc
);
876 // Responds to colour changes, and passes event on to children.
877 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
880 // The app workspace colour is always white, but we should have
881 // a contrast with the page.
882 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
883 #elif defined(__WXGTK__)
884 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
886 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
888 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
891 // Propagate the event to the non-top-level children
892 wxWindow::OnSysColourChanged(event
);
895 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
897 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
898 switch (event
.GetKeyCode())
901 controlBar
->OnGoto();
904 controlBar
->OnPrint();
908 if (!event
.ControlDown())
914 switch(event
.GetKeyCode())
917 controlBar
->OnNext(); break;
919 controlBar
->OnPrevious(); break;
921 controlBar
->OnFirst(); break;
923 controlBar
->OnLast(); break;
931 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
933 wxPreviewControlBar
*
934 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
938 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
940 int currentZoom
= controlBar
->GetZoomControl();
943 if ( currentZoom
< 100 )
945 else if ( currentZoom
<= 120 )
950 if ( event
.GetWheelRotation() > 0 )
953 int newZoom
= currentZoom
+ delta
;
958 if ( newZoom
!= currentZoom
)
960 controlBar
->SetZoomControl(newZoom
);
961 m_printPreview
->SetZoom(newZoom
);
971 #endif // wxUSE_MOUSEWHEEL
973 //----------------------------------------------------------------------------
974 // wxPreviewControlBar
975 //----------------------------------------------------------------------------
977 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
979 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
980 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
981 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
982 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
983 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
984 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
985 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
986 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
987 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
988 EVT_PAINT(wxPreviewControlBar::OnPaint
)
991 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
992 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
993 long style
, const wxString
& name
):
994 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
996 m_printPreview
= preview
;
997 m_closeButton
= (wxButton
*) NULL
;
998 m_nextPageButton
= (wxButton
*) NULL
;
999 m_previousPageButton
= (wxButton
*) NULL
;
1000 m_printButton
= (wxButton
*) NULL
;
1001 m_zoomControl
= (wxChoice
*) NULL
;
1002 m_buttonFlags
= buttons
;
1005 wxPreviewControlBar::~wxPreviewControlBar()
1009 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1015 dc
.SetPen(*wxBLACK_PEN
);
1016 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
1017 dc
.DrawLine( 0, h
-1, w
, h
-1 );
1020 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
1022 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1026 void wxPreviewControlBar::OnPrint(void)
1028 wxPrintPreviewBase
*preview
= GetPrintPreview();
1029 preview
->Print(true);
1032 void wxPreviewControlBar::OnNext(void)
1034 wxPrintPreviewBase
*preview
= GetPrintPreview();
1037 int currentPage
= preview
->GetCurrentPage();
1038 if ((preview
->GetMaxPage() > 0) &&
1039 (currentPage
< preview
->GetMaxPage()) &&
1040 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1042 preview
->SetCurrentPage(currentPage
+ 1);
1047 void wxPreviewControlBar::OnPrevious(void)
1049 wxPrintPreviewBase
*preview
= GetPrintPreview();
1052 int currentPage
= preview
->GetCurrentPage();
1053 if ((preview
->GetMinPage() > 0) &&
1054 (currentPage
> preview
->GetMinPage()) &&
1055 preview
->GetPrintout()->HasPage(currentPage
- 1))
1057 preview
->SetCurrentPage(currentPage
- 1);
1062 void wxPreviewControlBar::OnFirst(void)
1064 wxPrintPreviewBase
*preview
= GetPrintPreview();
1067 int currentPage
= preview
->GetMinPage();
1068 if (preview
->GetPrintout()->HasPage(currentPage
))
1070 preview
->SetCurrentPage(currentPage
);
1075 void wxPreviewControlBar::OnLast(void)
1077 wxPrintPreviewBase
*preview
= GetPrintPreview();
1080 int currentPage
= preview
->GetMaxPage();
1081 if (preview
->GetPrintout()->HasPage(currentPage
))
1083 preview
->SetCurrentPage(currentPage
);
1088 void wxPreviewControlBar::OnGoto(void)
1090 wxPrintPreviewBase
*preview
= GetPrintPreview();
1095 if (preview
->GetMinPage() > 0)
1100 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1101 preview
->GetMinPage(), preview
->GetMaxPage());
1102 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1105 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1107 if ( strPage
.ToLong( ¤tPage
) )
1108 if (preview
->GetPrintout()->HasPage(currentPage
))
1110 preview
->SetCurrentPage(currentPage
);
1116 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1118 int zoom
= GetZoomControl();
1119 if (GetPrintPreview())
1120 GetPrintPreview()->SetZoom(zoom
);
1123 void wxPreviewControlBar::CreateButtons()
1125 SetSize(0, 0, 400, 40);
1127 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1129 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1130 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1132 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1134 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1135 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1138 // Exact-fit buttons are too tiny on wxUniversal
1140 wxSize navButtonSize
;
1141 #ifdef __WXUNIVERSAL__
1143 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1145 navButtonStyle
= wxBU_EXACTFIT
;
1146 navButtonSize
= wxDefaultSize
;
1149 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1151 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1152 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1155 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1157 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1158 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1161 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1163 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1164 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1167 if (m_buttonFlags
& wxPREVIEW_LAST
)
1169 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1170 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1173 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1175 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1176 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1179 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1181 wxString choices
[] =
1183 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1184 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1185 wxT("120%"), wxT("150%"), wxT("200%")
1187 int n
= WXSIZEOF(choices
);
1189 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1190 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1191 SetZoomControl(m_printPreview
->GetZoom());
1198 void wxPreviewControlBar::SetZoomControl(int zoom
)
1202 int n
, count
= m_zoomControl
->GetCount();
1204 for (n
=0; n
<count
; n
++)
1206 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1207 (val
>= long(zoom
)))
1209 m_zoomControl
->SetSelection(n
);
1214 m_zoomControl
->SetSelection(count
-1);
1218 int wxPreviewControlBar::GetZoomControl()
1220 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1223 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1235 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1237 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1238 EVT_CHAR_HOOK(wxPreviewFrame::OnChar
)
1239 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1242 void wxPreviewFrame::OnChar(wxKeyEvent
&event
)
1244 if ( event
.GetKeyCode() == WXK_ESCAPE
)
1254 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1255 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1256 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1258 m_printPreview
= preview
;
1259 m_controlBar
= NULL
;
1260 m_previewCanvas
= NULL
;
1261 m_windowDisabler
= NULL
;
1263 // Give the application icon
1265 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1267 SetIcon(topFrame
->GetIcon());
1271 wxPreviewFrame::~wxPreviewFrame()
1275 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1277 if (m_windowDisabler
)
1278 delete m_windowDisabler
;
1280 // Need to delete the printout and the print preview
1281 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1285 m_printPreview
->SetPrintout(NULL
);
1286 m_printPreview
->SetCanvas(NULL
);
1287 m_printPreview
->SetFrame(NULL
);
1289 delete m_printPreview
;
1294 void wxPreviewFrame::Initialize()
1302 m_printPreview
->SetCanvas(m_previewCanvas
);
1303 m_printPreview
->SetFrame(this);
1305 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1307 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1308 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1310 SetAutoLayout( true );
1313 m_windowDisabler
= new wxWindowDisabler(this);
1317 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1318 m_previewCanvas
->SetFocus();
1319 m_controlBar
->SetFocus();
1322 void wxPreviewFrame::CreateCanvas()
1324 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1327 void wxPreviewFrame::CreateControlBar()
1329 long buttons
= wxPREVIEW_DEFAULT
;
1330 if (m_printPreview
->GetPrintoutForPrinting())
1331 buttons
|= wxPREVIEW_PRINT
;
1333 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1334 m_controlBar
->CreateButtons();
1341 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1343 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1344 wxPrintout
*printoutForPrinting
,
1348 m_printDialogData
= (*data
);
1350 Init(printout
, printoutForPrinting
);
1353 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1354 wxPrintout
*printoutForPrinting
,
1355 wxPrintDialogData
*data
)
1358 m_printDialogData
= (*data
);
1360 Init(printout
, printoutForPrinting
);
1363 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1364 wxPrintout
*printoutForPrinting
)
1367 m_previewPrintout
= printout
;
1368 if (m_previewPrintout
)
1369 m_previewPrintout
->SetIsPreview(true);
1371 m_printPrintout
= printoutForPrinting
;
1373 m_previewCanvas
= NULL
;
1374 m_previewFrame
= NULL
;
1375 m_previewBitmap
= NULL
;
1382 m_printingPrepared
= false;
1387 wxPrintPreviewBase::~wxPrintPreviewBase()
1389 if (m_previewPrintout
)
1390 delete m_previewPrintout
;
1391 if (m_previewBitmap
)
1392 delete m_previewBitmap
;
1393 if (m_printPrintout
)
1394 delete m_printPrintout
;
1397 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1399 if (m_currentPage
== pageNum
)
1402 m_currentPage
= pageNum
;
1403 if (m_previewBitmap
)
1405 delete m_previewBitmap
;
1406 m_previewBitmap
= NULL
;
1409 if (m_previewCanvas
)
1411 AdjustScrollbars(m_previewCanvas
);
1413 if (!RenderPage(pageNum
))
1415 m_previewCanvas
->Refresh();
1416 m_previewCanvas
->SetFocus();
1421 int wxPrintPreviewBase::GetCurrentPage() const
1422 { return m_currentPage
; }
1423 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1424 { m_previewPrintout
= printout
; }
1425 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1426 { return m_previewPrintout
; }
1427 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1428 { return m_printPrintout
; }
1429 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1430 { m_previewFrame
= frame
; }
1431 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1432 { m_previewCanvas
= canvas
; }
1433 wxFrame
*wxPrintPreviewBase::GetFrame() const
1434 { return m_previewFrame
; }
1435 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1436 { return m_previewCanvas
; }
1438 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1440 // Calculate the rectangles for the printable area of the page and the
1441 // entire paper as they appear on the canvas on-screen.
1442 int canvasWidth
, canvasHeight
;
1443 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1445 float zoomScale
= float(m_currentZoom
) / 100;
1446 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1447 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1449 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1450 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1451 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1452 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1453 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1454 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1455 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1457 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1458 if (paperRect
.x
< m_leftMargin
)
1459 paperRect
.x
= m_leftMargin
;
1460 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1461 if (paperRect
.y
< m_topMargin
)
1462 paperRect
.y
= m_topMargin
;
1464 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1465 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1466 pageRect
.width
= wxCoord(screenPrintableWidth
);
1467 pageRect
.height
= wxCoord(screenPrintableHeight
);
1471 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1473 DrawBlankPage(canvas
, dc
);
1475 if (!m_previewBitmap
)
1476 if (!RenderPage(m_currentPage
))
1478 if (!m_previewBitmap
)
1483 wxRect pageRect
, paperRect
;
1484 CalcRects(canvas
, pageRect
, paperRect
);
1486 temp_dc
.SelectObject(*m_previewBitmap
);
1488 dc
.Blit(pageRect
.x
, pageRect
.y
,
1489 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1491 temp_dc
.SelectObject(wxNullBitmap
);
1495 // Adjusts the scrollbars for the current scale
1496 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1501 wxRect pageRect
, paperRect
;
1502 CalcRects(canvas
, pageRect
, paperRect
);
1503 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1504 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1505 int scrollUnitsX
= totalWidth
/ 10;
1506 int scrollUnitsY
= totalHeight
/ 10;
1507 wxSize virtualSize
= canvas
->GetVirtualSize();
1508 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1509 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1512 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1516 if (!m_previewCanvas
)
1518 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1522 wxRect pageRect
, paperRect
;
1523 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1525 if (!m_previewBitmap
)
1527 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1529 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1531 if (m_previewBitmap
) {
1532 delete m_previewBitmap
;
1533 m_previewBitmap
= NULL
;
1535 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1540 wxMemoryDC memoryDC
;
1541 memoryDC
.SelectObject(*m_previewBitmap
);
1545 m_previewPrintout
->SetDC(&memoryDC
);
1546 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1548 // Need to delay OnPreparePrinting until here, so we have enough information.
1549 if (!m_printingPrepared
)
1551 m_previewPrintout
->OnPreparePrinting();
1553 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1554 m_printingPrepared
= true;
1557 m_previewPrintout
->OnBeginPrinting();
1559 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1561 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1563 memoryDC
.SelectObject(wxNullBitmap
);
1565 delete m_previewBitmap
;
1566 m_previewBitmap
= NULL
;
1570 m_previewPrintout
->OnPrintPage(pageNum
);
1571 m_previewPrintout
->OnEndDocument();
1572 m_previewPrintout
->OnEndPrinting();
1574 m_previewPrintout
->SetDC(NULL
);
1576 memoryDC
.SelectObject(wxNullBitmap
);
1581 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1583 status
= wxString::Format(_("Page %d"), pageNum
);
1586 m_previewFrame
->SetStatusText(status
);
1592 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1594 wxRect pageRect
, paperRect
;
1596 CalcRects(canvas
, pageRect
, paperRect
);
1598 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1599 wxCoord shadowOffset
= 4;
1601 dc
.SetPen(*wxBLACK_PEN
);
1602 dc
.SetBrush(*wxBLACK_BRUSH
);
1603 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1604 paperRect
.width
, shadowOffset
);
1606 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1607 shadowOffset
, paperRect
.height
);
1609 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1610 dc
.SetPen(*wxBLACK_PEN
);
1611 dc
.SetBrush(*wxWHITE_BRUSH
);
1612 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1613 paperRect
.width
+ 3, paperRect
.height
+ 2);
1618 void wxPrintPreviewBase::SetZoom(int percent
)
1620 if (m_currentZoom
== percent
)
1623 m_currentZoom
= percent
;
1624 if (m_previewBitmap
)
1626 delete m_previewBitmap
;
1627 m_previewBitmap
= NULL
;
1630 if (m_previewCanvas
)
1632 AdjustScrollbars(m_previewCanvas
);
1633 RenderPage(m_currentPage
);
1634 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1635 m_previewCanvas
->ClearBackground();
1636 m_previewCanvas
->Refresh();
1637 m_previewCanvas
->SetFocus();
1641 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1643 return m_printDialogData
;
1646 int wxPrintPreviewBase::GetZoom() const
1647 { return m_currentZoom
; }
1648 int wxPrintPreviewBase::GetMaxPage() const
1649 { return m_maxPage
; }
1650 int wxPrintPreviewBase::GetMinPage() const
1651 { return m_minPage
; }
1652 bool wxPrintPreviewBase::IsOk() const
1654 void wxPrintPreviewBase::SetOk(bool ok
)
1657 //----------------------------------------------------------------------------
1659 //----------------------------------------------------------------------------
1661 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1663 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1664 wxPrintout
*printoutForPrinting
,
1665 wxPrintDialogData
*data
) :
1666 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1668 m_pimpl
= wxPrintFactory::GetFactory()->
1669 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1672 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1673 wxPrintout
*printoutForPrinting
,
1674 wxPrintData
*data
) :
1675 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1677 m_pimpl
= wxPrintFactory::GetFactory()->
1678 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1681 wxPrintPreview::~wxPrintPreview()
1685 // don't delete twice
1686 m_printPrintout
= NULL
;
1687 m_previewPrintout
= NULL
;
1688 m_previewBitmap
= NULL
;
1691 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1693 return m_pimpl
->SetCurrentPage( pageNum
);
1696 int wxPrintPreview::GetCurrentPage() const
1698 return m_pimpl
->GetCurrentPage();
1701 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1703 m_pimpl
->SetPrintout( printout
);
1706 wxPrintout
*wxPrintPreview::GetPrintout() const
1708 return m_pimpl
->GetPrintout();
1711 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1713 return m_pimpl
->GetPrintoutForPrinting();
1716 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1718 m_pimpl
->SetFrame( frame
);
1721 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1723 m_pimpl
->SetCanvas( canvas
);
1726 wxFrame
*wxPrintPreview::GetFrame() const
1728 return m_pimpl
->GetFrame();
1731 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1733 return m_pimpl
->GetCanvas();
1736 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1738 return m_pimpl
->PaintPage( canvas
, dc
);
1741 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1743 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1746 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1748 m_pimpl
->AdjustScrollbars( canvas
);
1751 bool wxPrintPreview::RenderPage(int pageNum
)
1753 return m_pimpl
->RenderPage( pageNum
);
1756 void wxPrintPreview::SetZoom(int percent
)
1758 m_pimpl
->SetZoom( percent
);
1761 int wxPrintPreview::GetZoom() const
1763 return m_pimpl
->GetZoom();
1766 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1768 return m_pimpl
->GetPrintDialogData();
1771 int wxPrintPreview::GetMaxPage() const
1773 return m_pimpl
->GetMaxPage();
1776 int wxPrintPreview::GetMinPage() const
1778 return m_pimpl
->GetMinPage();
1781 bool wxPrintPreview::IsOk() const
1783 return m_pimpl
->Ok();
1786 void wxPrintPreview::SetOk(bool ok
)
1788 m_pimpl
->SetOk( ok
);
1791 bool wxPrintPreview::Print(bool interactive
)
1793 return m_pimpl
->Print( interactive
);
1796 void wxPrintPreview::DetermineScaling()
1798 m_pimpl
->DetermineScaling();
1801 #endif // wxUSE_PRINTING_ARCHITECTURE