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
736 wxRect paperRect
= GetPaperRectPixels();
738 GetPageSizePixels(&pw
, &ph
);
739 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
740 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
742 GetPageSizeMM(&mw
, &mh
);
743 float mmToDeviceX
= float(pw
) / mw
;
744 float mmToDeviceY
= float(ph
) / mh
;
745 wxRect
pageMarginsRect(paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
746 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
747 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
748 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
750 m_printoutDC
->GetSize(&w
, &h
);
751 if (w
== pw
&& h
== ph
) {
752 // this DC matches the printed page, so no scaling
753 return wxRect(m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),
754 m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),
755 m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),
756 m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
));
758 // This DC doesn't match the printed page, so we have to scale.
759 float scaleX
= float(w
) / pw
;
760 float scaleY
= float(h
) / ph
;
761 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(pageMarginsRect
.x
* scaleX
)),
762 m_printoutDC
->DeviceToLogicalY(wxRound(pageMarginsRect
.y
* scaleY
)),
763 m_printoutDC
->DeviceToLogicalXRel(wxRound(pageMarginsRect
.width
* scaleX
)),
764 m_printoutDC
->DeviceToLogicalYRel(wxRound(pageMarginsRect
.height
* scaleY
)));
767 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
)
769 // Set the device origin by specifying a point in logical coordinates.
770 m_printoutDC
->SetDeviceOrigin(m_printoutDC
->LogicalToDeviceX(x
),
771 m_printoutDC
->LogicalToDeviceY(y
));
774 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
)
776 // Offset the device origin by a specified distance in device coordinates.
777 wxCoord x
= m_printoutDC
->LogicalToDeviceX(0);
778 wxCoord y
= m_printoutDC
->LogicalToDeviceY(0);
779 m_printoutDC
->SetDeviceOrigin(x
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),
780 y
+ m_printoutDC
->LogicalToDeviceYRel(yoff
));
784 //----------------------------------------------------------------------------
786 //----------------------------------------------------------------------------
788 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
790 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
791 EVT_PAINT(wxPreviewCanvas::OnPaint
)
792 EVT_CHAR(wxPreviewCanvas::OnChar
)
793 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
795 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
799 // VZ: the current code doesn't refresh properly without
800 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
801 // really horrible flicker when resizing the preview frame, but without
802 // this style it simply doesn't work correctly at all...
803 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
804 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
805 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
807 m_printPreview
= preview
;
809 // The app workspace colour is always white, but we should have
810 // a contrast with the page.
811 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
812 #elif defined(__WXGTK__)
813 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
815 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
817 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
819 SetScrollbars(10, 10, 100, 100);
822 wxPreviewCanvas::~wxPreviewCanvas()
826 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
833 if (!GetUpdateRegion().IsEmpty())
834 dc.SetClippingRegion( GetUpdateRegion() );
840 m_printPreview
->PaintPage(this, dc
);
844 // Responds to colour changes, and passes event on to children.
845 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
848 // The app workspace colour is always white, but we should have
849 // a contrast with the page.
850 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
851 #elif defined(__WXGTK__)
852 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
854 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
856 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
859 // Propagate the event to the non-top-level children
860 wxWindow::OnSysColourChanged(event
);
863 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
865 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
866 if (event
.GetKeyCode() == WXK_ESCAPE
)
868 ((wxPreviewFrame
*) GetParent())->Close(true);
871 else if (event
.GetKeyCode() == WXK_TAB
)
873 controlBar
->OnGoto();
876 else if (event
.GetKeyCode() == WXK_RETURN
)
878 controlBar
->OnPrint();
882 if (!event
.ControlDown())
888 switch(event
.GetKeyCode())
891 controlBar
->OnNext(); break;
893 controlBar
->OnPrevious(); break;
895 controlBar
->OnFirst(); break;
897 controlBar
->OnLast(); break;
905 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
907 wxPreviewControlBar
*
908 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
912 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
914 int currentZoom
= controlBar
->GetZoomControl();
917 if ( currentZoom
< 100 )
919 else if ( currentZoom
<= 120 )
924 if ( event
.GetWheelRotation() > 0 )
927 int newZoom
= currentZoom
+ delta
;
932 if ( newZoom
!= currentZoom
)
934 controlBar
->SetZoomControl(newZoom
);
935 m_printPreview
->SetZoom(newZoom
);
945 #endif // wxUSE_MOUSEWHEEL
947 //----------------------------------------------------------------------------
948 // wxPreviewControlBar
949 //----------------------------------------------------------------------------
951 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
953 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
954 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
955 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
956 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
957 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
958 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
959 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
960 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
961 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
962 EVT_PAINT(wxPreviewControlBar::OnPaint
)
965 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
966 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
967 long style
, const wxString
& name
):
968 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
970 m_printPreview
= preview
;
971 m_closeButton
= (wxButton
*) NULL
;
972 m_nextPageButton
= (wxButton
*) NULL
;
973 m_previousPageButton
= (wxButton
*) NULL
;
974 m_printButton
= (wxButton
*) NULL
;
975 m_zoomControl
= (wxChoice
*) NULL
;
976 m_buttonFlags
= buttons
;
979 wxPreviewControlBar::~wxPreviewControlBar()
983 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
989 dc
.SetPen(*wxBLACK_PEN
);
990 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
991 dc
.DrawLine( 0, h
-1, w
, h
-1 );
994 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
996 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
1000 void wxPreviewControlBar::OnPrint(void)
1002 wxPrintPreviewBase
*preview
= GetPrintPreview();
1003 preview
->Print(true);
1006 void wxPreviewControlBar::OnNext(void)
1008 wxPrintPreviewBase
*preview
= GetPrintPreview();
1011 int currentPage
= preview
->GetCurrentPage();
1012 if ((preview
->GetMaxPage() > 0) &&
1013 (currentPage
< preview
->GetMaxPage()) &&
1014 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1016 preview
->SetCurrentPage(currentPage
+ 1);
1021 void wxPreviewControlBar::OnPrevious(void)
1023 wxPrintPreviewBase
*preview
= GetPrintPreview();
1026 int currentPage
= preview
->GetCurrentPage();
1027 if ((preview
->GetMinPage() > 0) &&
1028 (currentPage
> preview
->GetMinPage()) &&
1029 preview
->GetPrintout()->HasPage(currentPage
- 1))
1031 preview
->SetCurrentPage(currentPage
- 1);
1036 void wxPreviewControlBar::OnFirst(void)
1038 wxPrintPreviewBase
*preview
= GetPrintPreview();
1041 int currentPage
= preview
->GetMinPage();
1042 if (preview
->GetPrintout()->HasPage(currentPage
))
1044 preview
->SetCurrentPage(currentPage
);
1049 void wxPreviewControlBar::OnLast(void)
1051 wxPrintPreviewBase
*preview
= GetPrintPreview();
1054 int currentPage
= preview
->GetMaxPage();
1055 if (preview
->GetPrintout()->HasPage(currentPage
))
1057 preview
->SetCurrentPage(currentPage
);
1062 void wxPreviewControlBar::OnGoto(void)
1064 wxPrintPreviewBase
*preview
= GetPrintPreview();
1069 if (preview
->GetMinPage() > 0)
1074 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1075 preview
->GetMinPage(), preview
->GetMaxPage());
1076 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1079 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1081 if ( strPage
.ToLong( ¤tPage
) )
1082 if (preview
->GetPrintout()->HasPage(currentPage
))
1084 preview
->SetCurrentPage(currentPage
);
1090 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1092 int zoom
= GetZoomControl();
1093 if (GetPrintPreview())
1094 GetPrintPreview()->SetZoom(zoom
);
1097 void wxPreviewControlBar::CreateButtons()
1099 SetSize(0, 0, 400, 40);
1101 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1103 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1104 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1106 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1108 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1109 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1112 // Exact-fit buttons are too tiny on wxUniversal
1114 wxSize navButtonSize
;
1115 #ifdef __WXUNIVERSAL__
1117 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1119 navButtonStyle
= wxBU_EXACTFIT
;
1120 navButtonSize
= wxDefaultSize
;
1123 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1125 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1126 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1129 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1131 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1132 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1135 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1137 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1138 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1141 if (m_buttonFlags
& wxPREVIEW_LAST
)
1143 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1144 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1147 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1149 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1150 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1153 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1155 wxString choices
[] =
1157 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1158 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1159 wxT("120%"), wxT("150%"), wxT("200%")
1161 int n
= WXSIZEOF(choices
);
1163 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1164 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1165 SetZoomControl(m_printPreview
->GetZoom());
1172 void wxPreviewControlBar::SetZoomControl(int zoom
)
1176 int n
, count
= m_zoomControl
->GetCount();
1178 for (n
=0; n
<count
; n
++)
1180 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1181 (val
>= long(zoom
)))
1183 m_zoomControl
->SetSelection(n
);
1188 m_zoomControl
->SetSelection(count
-1);
1192 int wxPreviewControlBar::GetZoomControl()
1194 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1197 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1209 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1211 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1212 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1215 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1216 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1217 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1219 m_printPreview
= preview
;
1220 m_controlBar
= NULL
;
1221 m_previewCanvas
= NULL
;
1222 m_windowDisabler
= NULL
;
1224 // Give the application icon
1226 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1228 SetIcon(topFrame
->GetIcon());
1232 wxPreviewFrame::~wxPreviewFrame()
1236 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1238 if (m_windowDisabler
)
1239 delete m_windowDisabler
;
1241 // Need to delete the printout and the print preview
1242 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1246 m_printPreview
->SetPrintout(NULL
);
1247 m_printPreview
->SetCanvas(NULL
);
1248 m_printPreview
->SetFrame(NULL
);
1250 delete m_printPreview
;
1255 void wxPreviewFrame::Initialize()
1263 m_printPreview
->SetCanvas(m_previewCanvas
);
1264 m_printPreview
->SetFrame(this);
1266 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1268 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1269 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1271 SetAutoLayout( true );
1274 m_windowDisabler
= new wxWindowDisabler(this);
1278 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1279 m_previewCanvas
->SetFocus();
1280 m_controlBar
->SetFocus();
1283 void wxPreviewFrame::CreateCanvas()
1285 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1288 void wxPreviewFrame::CreateControlBar()
1290 long buttons
= wxPREVIEW_DEFAULT
;
1291 if (m_printPreview
->GetPrintoutForPrinting())
1292 buttons
|= wxPREVIEW_PRINT
;
1294 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1295 m_controlBar
->CreateButtons();
1302 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1304 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1305 wxPrintout
*printoutForPrinting
,
1309 m_printDialogData
= (*data
);
1311 Init(printout
, printoutForPrinting
);
1314 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1315 wxPrintout
*printoutForPrinting
,
1316 wxPrintDialogData
*data
)
1319 m_printDialogData
= (*data
);
1321 Init(printout
, printoutForPrinting
);
1324 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1325 wxPrintout
*printoutForPrinting
)
1328 m_previewPrintout
= printout
;
1329 if (m_previewPrintout
)
1330 m_previewPrintout
->SetIsPreview(true);
1332 m_printPrintout
= printoutForPrinting
;
1334 m_previewCanvas
= NULL
;
1335 m_previewFrame
= NULL
;
1336 m_previewBitmap
= NULL
;
1343 m_printingPrepared
= false;
1348 wxPrintPreviewBase::~wxPrintPreviewBase()
1350 if (m_previewPrintout
)
1351 delete m_previewPrintout
;
1352 if (m_previewBitmap
)
1353 delete m_previewBitmap
;
1354 if (m_printPrintout
)
1355 delete m_printPrintout
;
1358 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1360 if (m_currentPage
== pageNum
)
1363 m_currentPage
= pageNum
;
1364 if (m_previewBitmap
)
1366 delete m_previewBitmap
;
1367 m_previewBitmap
= NULL
;
1370 if (m_previewCanvas
)
1372 AdjustScrollbars(m_previewCanvas
);
1374 if (!RenderPage(pageNum
))
1376 m_previewCanvas
->Refresh();
1377 m_previewCanvas
->SetFocus();
1382 int wxPrintPreviewBase::GetCurrentPage() const
1383 { return m_currentPage
; }
1384 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1385 { m_previewPrintout
= printout
; }
1386 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1387 { return m_previewPrintout
; }
1388 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1389 { return m_printPrintout
; }
1390 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1391 { m_previewFrame
= frame
; }
1392 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1393 { m_previewCanvas
= canvas
; }
1394 wxFrame
*wxPrintPreviewBase::GetFrame() const
1395 { return m_previewFrame
; }
1396 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1397 { return m_previewCanvas
; }
1399 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1401 // Calculate the rectangles for the printable area of the page and the
1402 // entire paper as they appear on the canvas on-screen.
1403 int canvasWidth
, canvasHeight
;
1404 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1406 float zoomScale
= float(m_currentZoom
) / 100;
1407 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1408 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1410 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1411 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1412 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1413 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1414 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1415 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1416 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1418 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1419 if (paperRect
.x
< m_leftMargin
)
1420 paperRect
.x
= m_leftMargin
;
1421 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1422 if (paperRect
.y
< m_topMargin
)
1423 paperRect
.y
= m_topMargin
;
1425 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1426 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1427 pageRect
.width
= wxCoord(screenPrintableWidth
);
1428 pageRect
.height
= wxCoord(screenPrintableHeight
);
1432 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1434 DrawBlankPage(canvas
, dc
);
1436 if (!m_previewBitmap
)
1437 if (!RenderPage(m_currentPage
))
1439 if (!m_previewBitmap
)
1444 wxRect pageRect
, paperRect
;
1445 CalcRects(canvas
, pageRect
, paperRect
);
1447 temp_dc
.SelectObject(*m_previewBitmap
);
1449 dc
.Blit(pageRect
.x
, pageRect
.y
,
1450 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1452 temp_dc
.SelectObject(wxNullBitmap
);
1456 // Adjusts the scrollbars for the current scale
1457 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1462 wxRect pageRect
, paperRect
;
1463 CalcRects(canvas
, pageRect
, paperRect
);
1464 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1465 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1466 int scrollUnitsX
= totalWidth
/ 10;
1467 int scrollUnitsY
= totalHeight
/ 10;
1468 wxSize virtualSize
= canvas
->GetVirtualSize();
1469 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1470 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1473 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1477 if (!m_previewCanvas
)
1479 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1483 wxRect pageRect
, paperRect
;
1484 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1486 if (!m_previewBitmap
)
1488 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1490 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1492 if (m_previewBitmap
) {
1493 delete m_previewBitmap
;
1494 m_previewBitmap
= NULL
;
1496 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1501 wxMemoryDC memoryDC
;
1502 memoryDC
.SelectObject(*m_previewBitmap
);
1506 m_previewPrintout
->SetDC(&memoryDC
);
1507 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1509 // Need to delay OnPreparePrinting until here, so we have enough information.
1510 if (!m_printingPrepared
)
1512 m_previewPrintout
->OnPreparePrinting();
1514 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1515 m_printingPrepared
= true;
1518 m_previewPrintout
->OnBeginPrinting();
1520 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1522 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1524 memoryDC
.SelectObject(wxNullBitmap
);
1526 delete m_previewBitmap
;
1527 m_previewBitmap
= NULL
;
1531 m_previewPrintout
->OnPrintPage(pageNum
);
1532 m_previewPrintout
->OnEndDocument();
1533 m_previewPrintout
->OnEndPrinting();
1535 m_previewPrintout
->SetDC(NULL
);
1537 memoryDC
.SelectObject(wxNullBitmap
);
1542 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1544 status
= wxString::Format(_("Page %d"), pageNum
);
1547 m_previewFrame
->SetStatusText(status
);
1553 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1555 wxRect pageRect
, paperRect
;
1557 CalcRects(canvas
, pageRect
, paperRect
);
1559 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1560 wxCoord shadowOffset
= 4;
1562 dc
.SetPen(*wxBLACK_PEN
);
1563 dc
.SetBrush(*wxBLACK_BRUSH
);
1564 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1565 paperRect
.width
, shadowOffset
);
1567 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1568 shadowOffset
, paperRect
.height
);
1570 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1571 dc
.SetPen(*wxBLACK_PEN
);
1572 dc
.SetBrush(*wxWHITE_BRUSH
);
1573 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1574 paperRect
.width
+ 3, paperRect
.height
+ 2);
1579 void wxPrintPreviewBase::SetZoom(int percent
)
1581 if (m_currentZoom
== percent
)
1584 m_currentZoom
= percent
;
1585 if (m_previewBitmap
)
1587 delete m_previewBitmap
;
1588 m_previewBitmap
= NULL
;
1591 if (m_previewCanvas
)
1593 AdjustScrollbars(m_previewCanvas
);
1594 RenderPage(m_currentPage
);
1595 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1596 m_previewCanvas
->ClearBackground();
1597 m_previewCanvas
->Refresh();
1598 m_previewCanvas
->SetFocus();
1602 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1604 return m_printDialogData
;
1607 int wxPrintPreviewBase::GetZoom() const
1608 { return m_currentZoom
; }
1609 int wxPrintPreviewBase::GetMaxPage() const
1610 { return m_maxPage
; }
1611 int wxPrintPreviewBase::GetMinPage() const
1612 { return m_minPage
; }
1613 bool wxPrintPreviewBase::IsOk() const
1615 void wxPrintPreviewBase::SetOk(bool ok
)
1618 //----------------------------------------------------------------------------
1620 //----------------------------------------------------------------------------
1622 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1624 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1625 wxPrintout
*printoutForPrinting
,
1626 wxPrintDialogData
*data
) :
1627 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1629 m_pimpl
= wxPrintFactory::GetFactory()->
1630 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1633 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1634 wxPrintout
*printoutForPrinting
,
1635 wxPrintData
*data
) :
1636 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1638 m_pimpl
= wxPrintFactory::GetFactory()->
1639 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1642 wxPrintPreview::~wxPrintPreview()
1646 // don't delete twice
1647 m_printPrintout
= NULL
;
1648 m_previewPrintout
= NULL
;
1649 m_previewBitmap
= NULL
;
1652 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1654 return m_pimpl
->SetCurrentPage( pageNum
);
1657 int wxPrintPreview::GetCurrentPage() const
1659 return m_pimpl
->GetCurrentPage();
1662 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1664 m_pimpl
->SetPrintout( printout
);
1667 wxPrintout
*wxPrintPreview::GetPrintout() const
1669 return m_pimpl
->GetPrintout();
1672 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1674 return m_pimpl
->GetPrintoutForPrinting();
1677 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1679 m_pimpl
->SetFrame( frame
);
1682 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1684 m_pimpl
->SetCanvas( canvas
);
1687 wxFrame
*wxPrintPreview::GetFrame() const
1689 return m_pimpl
->GetFrame();
1692 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1694 return m_pimpl
->GetCanvas();
1697 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1699 return m_pimpl
->PaintPage( canvas
, dc
);
1702 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1704 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1707 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1709 m_pimpl
->AdjustScrollbars( canvas
);
1712 bool wxPrintPreview::RenderPage(int pageNum
)
1714 return m_pimpl
->RenderPage( pageNum
);
1717 void wxPrintPreview::SetZoom(int percent
)
1719 m_pimpl
->SetZoom( percent
);
1722 int wxPrintPreview::GetZoom() const
1724 return m_pimpl
->GetZoom();
1727 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1729 return m_pimpl
->GetPrintDialogData();
1732 int wxPrintPreview::GetMaxPage() const
1734 return m_pimpl
->GetMaxPage();
1737 int wxPrintPreview::GetMinPage() const
1739 return m_pimpl
->GetMinPage();
1742 bool wxPrintPreview::IsOk() const
1744 return m_pimpl
->Ok();
1747 void wxPrintPreview::SetOk(bool ok
)
1749 m_pimpl
->SetOk( ok
);
1752 bool wxPrintPreview::Print(bool interactive
)
1754 return m_pimpl
->Print( interactive
);
1757 void wxPrintPreview::DetermineScaling()
1759 m_pimpl
->DetermineScaling();
1762 #endif // wxUSE_PRINTING_ARCHITECTURE