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/stattext.h"
39 #include "wx/textdlg.h"
41 #include "wx/module.h"
44 #include "wx/prntbase.h"
45 #include "wx/printdlg.h"
47 #include "wx/dcprint.h"
52 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
53 #include "wx/msw/printdlg.h"
54 #elif defined(__WXMAC__)
55 #include "wx/mac/printdlg.h"
56 #include "wx/mac/private/print.h"
58 #include "wx/generic/prntdlgg.h"
68 //----------------------------------------------------------------------------
70 //----------------------------------------------------------------------------
72 wxPrintFactory
*wxPrintFactory::m_factory
= NULL
;
74 void wxPrintFactory::SetPrintFactory( wxPrintFactory
*factory
)
76 if (wxPrintFactory::m_factory
)
77 delete wxPrintFactory::m_factory
;
79 wxPrintFactory::m_factory
= factory
;
82 wxPrintFactory
*wxPrintFactory::GetFactory()
84 if (!wxPrintFactory::m_factory
)
85 wxPrintFactory::m_factory
= new wxNativePrintFactory
;
87 return wxPrintFactory::m_factory
;
90 //----------------------------------------------------------------------------
91 // wxNativePrintFactory
92 //----------------------------------------------------------------------------
94 wxPrinterBase
*wxNativePrintFactory::CreatePrinter( wxPrintDialogData
*data
)
96 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
97 return new wxWindowsPrinter( data
);
98 #elif defined(__WXMAC__)
99 return new wxMacPrinter( data
);
100 #elif defined(__WXPM__)
101 return new wxOS2Printer( data
);
103 return new wxPostScriptPrinter( data
);
107 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
108 wxPrintout
*printout
, wxPrintDialogData
*data
)
110 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
111 return new wxWindowsPrintPreview( preview
, printout
, data
);
112 #elif defined(__WXMAC__)
113 return new wxMacPrintPreview( preview
, printout
, data
);
114 #elif defined(__WXPM__)
115 return new wxOS2PrintPreview( preview
, printout
, data
);
117 return new wxPostScriptPrintPreview( preview
, printout
, data
);
121 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
122 wxPrintout
*printout
, wxPrintData
*data
)
124 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
125 return new wxWindowsPrintPreview( preview
, printout
, data
);
126 #elif defined(__WXMAC__)
127 return new wxMacPrintPreview( preview
, printout
, data
);
128 #elif defined(__WXPM__)
129 return new wxOS2PrintPreview( preview
, printout
, data
);
131 return new wxPostScriptPrintPreview( preview
, printout
, data
);
135 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
136 wxPrintDialogData
*data
)
138 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
139 return new wxWindowsPrintDialog( parent
, data
);
140 #elif defined(__WXMAC__)
141 return new wxMacPrintDialog( parent
, data
);
143 return new wxGenericPrintDialog( parent
, data
);
147 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
150 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
151 return new wxWindowsPrintDialog( parent
, data
);
152 #elif defined(__WXMAC__)
153 return new wxMacPrintDialog( parent
, data
);
155 return new wxGenericPrintDialog( parent
, data
);
159 wxPageSetupDialogBase
*wxNativePrintFactory::CreatePageSetupDialog( wxWindow
*parent
,
160 wxPageSetupDialogData
*data
)
162 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
163 return new wxWindowsPageSetupDialog( parent
, data
);
164 #elif defined(__WXMAC__)
165 return new wxMacPageSetupDialog( parent
, data
);
167 return new wxGenericPageSetupDialog( parent
, data
);
171 bool wxNativePrintFactory::HasPrintSetupDialog()
173 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
175 #elif defined(__WXMAC__)
178 // Only here do we need to provide the print setup
179 // dialog ourselves, the other platforms either have
180 // none, don't make it accessible or let you configure
181 // the printer from the wxPrintDialog anyway.
187 wxDialog
*wxNativePrintFactory::CreatePrintSetupDialog( wxWindow
*parent
,
190 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
194 #elif defined(__WXMAC__)
199 // Only here do we need to provide the print setup
200 // dialog ourselves, the other platforms either have
201 // none, don't make it accessible or let you configure
202 // the printer from the wxPrintDialog anyway.
203 return new wxGenericPrintSetupDialog( parent
, data
);
207 wxDC
* wxNativePrintFactory::CreatePrinterDC( const wxPrintData
& data
)
209 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
210 return new wxPrinterDC(data
);
211 #elif defined(__WXMAC__)
212 return new wxPrinterDC(data
);
214 return new wxPostScriptDC(data
);
218 bool wxNativePrintFactory::HasOwnPrintToFile()
220 // Only relevant for PostScript and here the
221 // setup dialog provides no "print to file"
222 // option. In the GNOME setup dialog, the
223 // setup dialog has its own print to file.
227 bool wxNativePrintFactory::HasPrinterLine()
229 // Only relevant for PostScript for now
233 wxString
wxNativePrintFactory::CreatePrinterLine()
235 // Only relevant for PostScript for now
237 // We should query "lpstat -d" here
238 return _("Generic PostScript");
241 bool wxNativePrintFactory::HasStatusLine()
243 // Only relevant for PostScript for now
247 wxString
wxNativePrintFactory::CreateStatusLine()
249 // Only relevant for PostScript for now
251 // We should query "lpstat -r" or "lpstat -p" here
255 wxPrintNativeDataBase
*wxNativePrintFactory::CreatePrintNativeData()
257 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
258 return new wxWindowsPrintNativeData
;
259 #elif defined(__WXMAC__)
260 return new wxMacCarbonPrintData
;
262 return new wxPostScriptPrintNativeData
;
266 //----------------------------------------------------------------------------
267 // wxPrintNativeDataBase
268 //----------------------------------------------------------------------------
270 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase
, wxObject
)
272 wxPrintNativeDataBase::wxPrintNativeDataBase()
277 //----------------------------------------------------------------------------
278 // wxPrintFactoryModule
279 //----------------------------------------------------------------------------
281 class wxPrintFactoryModule
: public wxModule
284 wxPrintFactoryModule() {}
285 bool OnInit() { return true; }
286 void OnExit() { wxPrintFactory::SetPrintFactory( NULL
); }
289 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule
)
292 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule
, wxModule
)
294 //----------------------------------------------------------------------------
296 //----------------------------------------------------------------------------
298 IMPLEMENT_CLASS(wxPrinterBase
, wxObject
)
300 wxPrinterBase::wxPrinterBase(wxPrintDialogData
*data
)
302 m_currentPrintout
= (wxPrintout
*) NULL
;
303 sm_abortWindow
= (wxWindow
*) NULL
;
306 m_printDialogData
= (*data
);
307 sm_lastError
= wxPRINTER_NO_ERROR
;
310 wxWindow
*wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
311 bool wxPrinterBase::sm_abortIt
= false;
312 wxPrinterError
wxPrinterBase::sm_lastError
= wxPRINTER_NO_ERROR
;
314 wxPrinterBase::~wxPrinterBase()
318 wxWindow
*wxPrinterBase::CreateAbortWindow(wxWindow
*parent
, wxPrintout
* printout
)
320 wxPrintAbortDialog
*dialog
= new wxPrintAbortDialog(parent
, _("Printing ") , wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
);
322 wxBoxSizer
*button_sizer
= new wxBoxSizer( wxVERTICAL
);
323 button_sizer
->Add( new wxStaticText(dialog
, wxID_ANY
, _("Please wait while printing\n") + printout
->GetTitle() ), 0, wxALL
, 10 );
324 button_sizer
->Add( new wxButton( dialog
, wxID_CANCEL
, wxT("Cancel") ), 0, wxALL
| wxALIGN_CENTER
, 10 );
326 dialog
->SetAutoLayout( true );
327 dialog
->SetSizer( button_sizer
);
329 button_sizer
->Fit(dialog
);
330 button_sizer
->SetSizeHints (dialog
) ;
335 void wxPrinterBase::ReportError(wxWindow
*parent
, wxPrintout
*WXUNUSED(printout
), const wxString
& message
)
337 wxMessageBox(message
, _("Printing Error"), wxOK
, parent
);
340 wxPrintDialogData
& wxPrinterBase::GetPrintDialogData() const
342 return (wxPrintDialogData
&) m_printDialogData
;
345 //----------------------------------------------------------------------------
347 //----------------------------------------------------------------------------
349 IMPLEMENT_CLASS(wxPrinter
, wxPrinterBase
)
351 wxPrinter::wxPrinter(wxPrintDialogData
*data
)
353 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrinter( data
);
356 wxPrinter::~wxPrinter()
361 wxWindow
*wxPrinter::CreateAbortWindow(wxWindow
*parent
, wxPrintout
*printout
)
363 return m_pimpl
->CreateAbortWindow( parent
, printout
);
366 void wxPrinter::ReportError(wxWindow
*parent
, wxPrintout
*printout
, const wxString
& message
)
368 m_pimpl
->ReportError( parent
, printout
, message
);
371 bool wxPrinter::Setup(wxWindow
*parent
)
373 return m_pimpl
->Setup( parent
);
376 bool wxPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
378 return m_pimpl
->Print( parent
, printout
, prompt
);
381 wxDC
* wxPrinter::PrintDialog(wxWindow
*parent
)
383 return m_pimpl
->PrintDialog( parent
);
386 wxPrintDialogData
& wxPrinter::GetPrintDialogData() const
388 return m_pimpl
->GetPrintDialogData();
391 // ---------------------------------------------------------------------------
392 // wxPrintDialogBase: the dialog for printing.
393 // ---------------------------------------------------------------------------
395 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase
, wxDialog
)
397 wxPrintDialogBase::wxPrintDialogBase(wxWindow
*parent
,
399 const wxString
&title
,
403 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Print")) : title
,
408 // ---------------------------------------------------------------------------
409 // wxPrintDialog: the dialog for printing
410 // ---------------------------------------------------------------------------
412 IMPLEMENT_CLASS(wxPrintDialog
, wxObject
)
414 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintDialogData
* data
)
416 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
419 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintData
* data
)
421 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
424 wxPrintDialog::~wxPrintDialog()
429 int wxPrintDialog::ShowModal()
431 return m_pimpl
->ShowModal();
434 wxPrintDialogData
& wxPrintDialog::GetPrintDialogData()
436 return m_pimpl
->GetPrintDialogData();
439 wxPrintData
& wxPrintDialog::GetPrintData()
441 return m_pimpl
->GetPrintData();
444 wxDC
*wxPrintDialog::GetPrintDC()
446 return m_pimpl
->GetPrintDC();
449 // ---------------------------------------------------------------------------
450 // wxPageSetupDialogBase: the page setup dialog
451 // ---------------------------------------------------------------------------
453 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase
, wxDialog
)
455 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow
*parent
,
457 const wxString
&title
,
461 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Page setup")) : title
,
466 // ---------------------------------------------------------------------------
467 // wxPageSetupDialog: the page setup dialog
468 // ---------------------------------------------------------------------------
470 IMPLEMENT_CLASS(wxPageSetupDialog
, wxObject
)
472 wxPageSetupDialog::wxPageSetupDialog(wxWindow
*parent
, wxPageSetupDialogData
*data
)
474 m_pimpl
= wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent
, data
);
477 wxPageSetupDialog::~wxPageSetupDialog()
482 int wxPageSetupDialog::ShowModal()
484 return m_pimpl
->ShowModal();
487 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupDialogData()
489 return m_pimpl
->GetPageSetupDialogData();
493 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupData()
495 return m_pimpl
->GetPageSetupDialogData();
498 //----------------------------------------------------------------------------
499 // wxPrintAbortDialog
500 //----------------------------------------------------------------------------
502 BEGIN_EVENT_TABLE(wxPrintAbortDialog
, wxDialog
)
503 EVT_BUTTON(wxID_CANCEL
, wxPrintAbortDialog::OnCancel
)
506 void wxPrintAbortDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
))
508 wxPrinterBase::sm_abortIt
= true;
509 wxPrinterBase::sm_abortWindow
->Show(false);
510 wxPrinterBase::sm_abortWindow
->Close(true);
511 wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
514 //----------------------------------------------------------------------------
516 //----------------------------------------------------------------------------
518 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
)
520 wxPrintout::wxPrintout(const wxString
& title
)
522 m_printoutTitle
= title
;
523 m_printoutDC
= (wxDC
*) NULL
;
526 m_pageWidthPixels
= 0;
527 m_pageHeightPixels
= 0;
535 wxPrintout::~wxPrintout()
539 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
))
541 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
);
544 void wxPrintout::OnEndDocument()
549 void wxPrintout::OnBeginPrinting()
553 void wxPrintout::OnEndPrinting()
557 bool wxPrintout::HasPage(int page
)
562 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
)
570 void wxPrintout::FitThisSizeToPaper(const wxSize
& imageSize
)
572 // Set the DC scale and origin so that the given image size fits within the
573 // entire page and the origin is at the top left corner of the page. Note
574 // that with most printers, portions of the page will be non-printable. Use
575 // this if you're managing your own page margins.
576 if (!m_printoutDC
) return;
577 wxRect paperRect
= GetPaperRectPixels();
579 GetPageSizePixels(&pw
, &ph
);
581 m_printoutDC
->GetSize(&w
, &h
);
582 float scaleX
= ((float(paperRect
.width
) * w
) / (float(pw
) * imageSize
.x
));
583 float scaleY
= ((float(paperRect
.height
) * h
) / (float(ph
) * imageSize
.y
));
584 float actualScale
= wxMin(scaleX
, scaleY
);
585 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
586 m_printoutDC
->SetDeviceOrigin(0, 0);
587 wxRect logicalPaperRect
= GetLogicalPaperRect();
588 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
591 void wxPrintout::FitThisSizeToPage(const wxSize
& imageSize
)
593 // Set the DC scale and origin so that the given image size fits within the
594 // printable area of the page and the origin is at the top left corner of
595 // the printable area.
596 if (!m_printoutDC
) return;
598 m_printoutDC
->GetSize(&w
, &h
);
599 float scaleX
= float(w
) / imageSize
.x
;
600 float scaleY
= float(h
) / imageSize
.y
;
601 float actualScale
= wxMin(scaleX
, scaleY
);
602 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
603 m_printoutDC
->SetDeviceOrigin(0, 0);
606 void wxPrintout::FitThisSizeToPageMargins(const wxSize
& imageSize
, const wxPageSetupDialogData
& pageSetupData
)
608 // Set the DC scale and origin so that the given image size fits within the
609 // page margins defined in the given wxPageSetupDialogData object and the
610 // origin is at the top left corner of the page margins.
611 if (!m_printoutDC
) return;
612 wxRect paperRect
= GetPaperRectPixels();
614 GetPageSizePixels(&pw
, &ph
);
615 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
616 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
618 GetPageSizeMM(&mw
, &mh
);
619 float mmToDeviceX
= float(pw
) / mw
;
620 float mmToDeviceY
= float(ph
) / mh
;
621 wxRect
pageMarginsRect(paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
622 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
623 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
624 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
626 m_printoutDC
->GetSize(&w
, &h
);
627 float scaleX
= (float(pageMarginsRect
.width
) * w
) / (float(pw
) * imageSize
.x
);
628 float scaleY
= (float(pageMarginsRect
.height
) * h
) / (float(ph
) * imageSize
.y
);
629 float actualScale
= wxMin(scaleX
, scaleY
);
630 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
631 m_printoutDC
->SetDeviceOrigin(0, 0);
632 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
633 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
636 void wxPrintout::MapScreenSizeToPaper()
638 // Set the DC scale so that an image on the screen is the same size on the
639 // paper and the origin is at the top left of the paper. Note that with most
640 // printers, portions of the page will be cut off. Use this if you're
641 // managing your own page margins.
642 if (!m_printoutDC
) return;
643 MapScreenSizeToPage();
644 wxRect logicalPaperRect
= GetLogicalPaperRect();
645 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
648 void wxPrintout::MapScreenSizeToPage()
650 // Set the DC scale and origin so that an image on the screen is the same
651 // size on the paper and the origin is at the top left of the printable area.
652 if (!m_printoutDC
) return;
653 int ppiScreenX
, ppiScreenY
;
654 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
655 int ppiPrinterX
, ppiPrinterY
;
656 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
658 m_printoutDC
->GetSize(&w
, &h
);
659 int pageSizePixelsX
, pageSizePixelsY
;
660 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
661 float userScaleX
= (float(ppiPrinterX
) * w
) / (float(ppiScreenX
) * pageSizePixelsX
);
662 float userScaleY
= (float(ppiPrinterY
) * h
) / (float(ppiScreenY
) * pageSizePixelsY
);
663 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
664 m_printoutDC
->SetDeviceOrigin(0, 0);
667 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData
& pageSetupData
)
669 // Set the DC scale so that an image on the screen is the same size on the
670 // paper and the origin is at the top left of the page margins defined by
671 // the given wxPageSetupDialogData object.
672 if (!m_printoutDC
) return;
673 MapScreenSizeToPage();
674 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
675 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
678 void wxPrintout::MapScreenSizeToDevice()
680 // Set the DC scale so that a screen pixel is the same size as a device
681 // pixel and the origin is at the top left of the printable area.
682 if (!m_printoutDC
) return;
684 m_printoutDC
->GetSize(&w
, &h
);
685 int pageSizePixelsX
, pageSizePixelsY
;
686 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
687 float userScaleX
= float(w
) / pageSizePixelsX
;
688 float userScaleY
= float(h
) / pageSizePixelsY
;
689 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
690 m_printoutDC
->SetDeviceOrigin(0, 0);
693 wxRect
wxPrintout::GetLogicalPaperRect() const
695 // Return the rectangle in logical units that corresponds to the paper
697 wxRect paperRect
= GetPaperRectPixels();
699 GetPageSizePixels(&pw
, &ph
);
701 m_printoutDC
->GetSize(&w
, &h
);
702 if (w
== pw
&& h
== ph
) {
703 // this DC matches the printed page, so no scaling
704 return wxRect(m_printoutDC
->DeviceToLogicalX(paperRect
.x
),
705 m_printoutDC
->DeviceToLogicalY(paperRect
.y
),
706 m_printoutDC
->DeviceToLogicalXRel(paperRect
.width
),
707 m_printoutDC
->DeviceToLogicalYRel(paperRect
.height
));
709 // This DC doesn't match the printed page, so we have to scale.
710 float scaleX
= float(w
) / pw
;
711 float scaleY
= float(h
) / ph
;
712 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(paperRect
.x
* scaleX
)),
713 m_printoutDC
->DeviceToLogicalY(wxRound(paperRect
.y
* scaleY
)),
714 m_printoutDC
->DeviceToLogicalXRel(wxRound(paperRect
.width
* scaleX
)),
715 m_printoutDC
->DeviceToLogicalYRel(wxRound(paperRect
.height
* scaleY
)));
718 wxRect
wxPrintout::GetLogicalPageRect() const
720 // Return the rectangle in logical units that corresponds to the printable
723 m_printoutDC
->GetSize(&w
, &h
);
724 return wxRect(m_printoutDC
->DeviceToLogicalX(0),
725 m_printoutDC
->DeviceToLogicalY(0),
726 m_printoutDC
->DeviceToLogicalXRel(w
),
727 m_printoutDC
->DeviceToLogicalYRel(h
));
730 wxRect
wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData
& pageSetupData
) const
732 // Return the rectangle in logical units that corresponds to the region
733 // within the page margins as specified by the given wxPageSetupDialogData
735 wxRect paperRect
= GetPaperRectPixels();
737 GetPageSizePixels(&pw
, &ph
);
738 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
739 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
741 GetPageSizeMM(&mw
, &mh
);
742 float mmToDeviceX
= float(pw
) / mw
;
743 float mmToDeviceY
= float(ph
) / mh
;
744 wxRect
pageMarginsRect(paperRect
.x
+ wxRound(mmToDeviceX
* topLeft
.x
),
745 paperRect
.y
+ wxRound(mmToDeviceY
* topLeft
.y
),
746 paperRect
.width
- wxRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
747 paperRect
.height
- wxRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
749 m_printoutDC
->GetSize(&w
, &h
);
750 if (w
== pw
&& h
== ph
) {
751 // this DC matches the printed page, so no scaling
752 return wxRect(m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),
753 m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),
754 m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),
755 m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
));
757 // This DC doesn't match the printed page, so we have to scale.
758 float scaleX
= float(w
) / pw
;
759 float scaleY
= float(h
) / ph
;
760 return wxRect(m_printoutDC
->DeviceToLogicalX(wxRound(pageMarginsRect
.x
* scaleX
)),
761 m_printoutDC
->DeviceToLogicalY(wxRound(pageMarginsRect
.y
* scaleY
)),
762 m_printoutDC
->DeviceToLogicalXRel(wxRound(pageMarginsRect
.width
* scaleX
)),
763 m_printoutDC
->DeviceToLogicalYRel(wxRound(pageMarginsRect
.height
* scaleY
)));
766 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
)
768 // Set the device origin by specifying a point in logical coordinates.
769 m_printoutDC
->SetDeviceOrigin(m_printoutDC
->LogicalToDeviceX(x
),
770 m_printoutDC
->LogicalToDeviceY(y
));
773 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
)
775 // Offset the device origin by a specified distance in device coordinates.
776 wxCoord x
= m_printoutDC
->LogicalToDeviceX(0);
777 wxCoord y
= m_printoutDC
->LogicalToDeviceY(0);
778 m_printoutDC
->SetDeviceOrigin(x
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),
779 y
+ m_printoutDC
->LogicalToDeviceYRel(yoff
));
783 //----------------------------------------------------------------------------
785 //----------------------------------------------------------------------------
787 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
789 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
790 EVT_PAINT(wxPreviewCanvas::OnPaint
)
791 EVT_CHAR(wxPreviewCanvas::OnChar
)
792 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
794 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
798 // VZ: the current code doesn't refresh properly without
799 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
800 // really horrible flicker when resizing the preview frame, but without
801 // this style it simply doesn't work correctly at all...
802 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
803 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
804 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
806 m_printPreview
= preview
;
808 // The app workspace colour is always white, but we should have
809 // a contrast with the page.
810 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
811 #elif defined(__WXGTK__)
812 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
814 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
816 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
818 SetScrollbars(10, 10, 100, 100);
821 wxPreviewCanvas::~wxPreviewCanvas()
825 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
832 if (!GetUpdateRegion().IsEmpty())
833 dc.SetClippingRegion( GetUpdateRegion() );
839 m_printPreview
->PaintPage(this, dc
);
843 // Responds to colour changes, and passes event on to children.
844 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
847 // The app workspace colour is always white, but we should have
848 // a contrast with the page.
849 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
850 #elif defined(__WXGTK__)
851 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
853 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
855 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
858 // Propagate the event to the non-top-level children
859 wxWindow::OnSysColourChanged(event
);
862 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
864 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
865 if (event
.GetKeyCode() == WXK_ESCAPE
)
867 ((wxPreviewFrame
*) GetParent())->Close(true);
870 else if (event
.GetKeyCode() == WXK_TAB
)
872 controlBar
->OnGoto();
875 else if (event
.GetKeyCode() == WXK_RETURN
)
877 controlBar
->OnPrint();
881 if (!event
.ControlDown())
887 switch(event
.GetKeyCode())
890 controlBar
->OnNext(); break;
892 controlBar
->OnPrevious(); break;
894 controlBar
->OnFirst(); break;
896 controlBar
->OnLast(); break;
904 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
906 wxPreviewControlBar
*
907 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
911 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
913 int currentZoom
= controlBar
->GetZoomControl();
916 if ( currentZoom
< 100 )
918 else if ( currentZoom
<= 120 )
923 if ( event
.GetWheelRotation() > 0 )
926 int newZoom
= currentZoom
+ delta
;
931 if ( newZoom
!= currentZoom
)
933 controlBar
->SetZoomControl(newZoom
);
934 m_printPreview
->SetZoom(newZoom
);
944 #endif // wxUSE_MOUSEWHEEL
946 //----------------------------------------------------------------------------
947 // wxPreviewControlBar
948 //----------------------------------------------------------------------------
950 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
952 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
953 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
954 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
955 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
956 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
957 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
958 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
959 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
960 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
961 EVT_PAINT(wxPreviewControlBar::OnPaint
)
964 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
965 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
966 long style
, const wxString
& name
):
967 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
969 m_printPreview
= preview
;
970 m_closeButton
= (wxButton
*) NULL
;
971 m_nextPageButton
= (wxButton
*) NULL
;
972 m_previousPageButton
= (wxButton
*) NULL
;
973 m_printButton
= (wxButton
*) NULL
;
974 m_zoomControl
= (wxChoice
*) NULL
;
975 m_buttonFlags
= buttons
;
978 wxPreviewControlBar::~wxPreviewControlBar()
982 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
988 dc
.SetPen(*wxBLACK_PEN
);
989 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
990 dc
.DrawLine( 0, h
-1, w
, h
-1 );
993 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
995 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
999 void wxPreviewControlBar::OnPrint(void)
1001 wxPrintPreviewBase
*preview
= GetPrintPreview();
1002 preview
->Print(true);
1005 void wxPreviewControlBar::OnNext(void)
1007 wxPrintPreviewBase
*preview
= GetPrintPreview();
1010 int currentPage
= preview
->GetCurrentPage();
1011 if ((preview
->GetMaxPage() > 0) &&
1012 (currentPage
< preview
->GetMaxPage()) &&
1013 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1015 preview
->SetCurrentPage(currentPage
+ 1);
1020 void wxPreviewControlBar::OnPrevious(void)
1022 wxPrintPreviewBase
*preview
= GetPrintPreview();
1025 int currentPage
= preview
->GetCurrentPage();
1026 if ((preview
->GetMinPage() > 0) &&
1027 (currentPage
> preview
->GetMinPage()) &&
1028 preview
->GetPrintout()->HasPage(currentPage
- 1))
1030 preview
->SetCurrentPage(currentPage
- 1);
1035 void wxPreviewControlBar::OnFirst(void)
1037 wxPrintPreviewBase
*preview
= GetPrintPreview();
1040 int currentPage
= preview
->GetMinPage();
1041 if (preview
->GetPrintout()->HasPage(currentPage
))
1043 preview
->SetCurrentPage(currentPage
);
1048 void wxPreviewControlBar::OnLast(void)
1050 wxPrintPreviewBase
*preview
= GetPrintPreview();
1053 int currentPage
= preview
->GetMaxPage();
1054 if (preview
->GetPrintout()->HasPage(currentPage
))
1056 preview
->SetCurrentPage(currentPage
);
1061 void wxPreviewControlBar::OnGoto(void)
1063 wxPrintPreviewBase
*preview
= GetPrintPreview();
1068 if (preview
->GetMinPage() > 0)
1073 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1074 preview
->GetMinPage(), preview
->GetMaxPage());
1075 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1078 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1080 if ( strPage
.ToLong( ¤tPage
) )
1081 if (preview
->GetPrintout()->HasPage(currentPage
))
1083 preview
->SetCurrentPage(currentPage
);
1089 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1091 int zoom
= GetZoomControl();
1092 if (GetPrintPreview())
1093 GetPrintPreview()->SetZoom(zoom
);
1096 void wxPreviewControlBar::CreateButtons()
1098 SetSize(0, 0, 400, 40);
1100 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1102 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1103 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1105 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1107 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1108 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1111 // Exact-fit buttons are too tiny on wxUniversal
1113 wxSize navButtonSize
;
1114 #ifdef __WXUNIVERSAL__
1116 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1118 navButtonStyle
= wxBU_EXACTFIT
;
1119 navButtonSize
= wxDefaultSize
;
1122 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1124 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1125 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1128 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1130 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1131 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1134 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1136 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1137 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1140 if (m_buttonFlags
& wxPREVIEW_LAST
)
1142 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1143 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1146 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1148 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1149 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1152 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1154 wxString choices
[] =
1156 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1157 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1158 wxT("120%"), wxT("150%"), wxT("200%")
1160 int n
= WXSIZEOF(choices
);
1162 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1163 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1164 SetZoomControl(m_printPreview
->GetZoom());
1171 void wxPreviewControlBar::SetZoomControl(int zoom
)
1175 int n
, count
= m_zoomControl
->GetCount();
1177 for (n
=0; n
<count
; n
++)
1179 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1180 (val
>= long(zoom
)))
1182 m_zoomControl
->SetSelection(n
);
1187 m_zoomControl
->SetSelection(count
-1);
1191 int wxPreviewControlBar::GetZoomControl()
1193 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1196 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1208 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1210 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1211 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1214 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1215 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1216 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1218 m_printPreview
= preview
;
1219 m_controlBar
= NULL
;
1220 m_previewCanvas
= NULL
;
1221 m_windowDisabler
= NULL
;
1223 // Give the application icon
1225 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1227 SetIcon(topFrame
->GetIcon());
1231 wxPreviewFrame::~wxPreviewFrame()
1235 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1237 if (m_windowDisabler
)
1238 delete m_windowDisabler
;
1240 // Need to delete the printout and the print preview
1241 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1245 m_printPreview
->SetPrintout(NULL
);
1246 m_printPreview
->SetCanvas(NULL
);
1247 m_printPreview
->SetFrame(NULL
);
1249 delete m_printPreview
;
1254 void wxPreviewFrame::Initialize()
1262 m_printPreview
->SetCanvas(m_previewCanvas
);
1263 m_printPreview
->SetFrame(this);
1265 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1267 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1268 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1270 SetAutoLayout( true );
1273 m_windowDisabler
= new wxWindowDisabler(this);
1277 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1278 m_previewCanvas
->SetFocus();
1279 m_controlBar
->SetFocus();
1282 void wxPreviewFrame::CreateCanvas()
1284 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1287 void wxPreviewFrame::CreateControlBar()
1289 long buttons
= wxPREVIEW_DEFAULT
;
1290 if (m_printPreview
->GetPrintoutForPrinting())
1291 buttons
|= wxPREVIEW_PRINT
;
1293 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1294 m_controlBar
->CreateButtons();
1301 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1303 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1304 wxPrintout
*printoutForPrinting
,
1308 m_printDialogData
= (*data
);
1310 Init(printout
, printoutForPrinting
);
1313 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1314 wxPrintout
*printoutForPrinting
,
1315 wxPrintDialogData
*data
)
1318 m_printDialogData
= (*data
);
1320 Init(printout
, printoutForPrinting
);
1323 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1324 wxPrintout
*printoutForPrinting
)
1327 m_previewPrintout
= printout
;
1328 if (m_previewPrintout
)
1329 m_previewPrintout
->SetIsPreview(true);
1331 m_printPrintout
= printoutForPrinting
;
1333 m_previewCanvas
= NULL
;
1334 m_previewFrame
= NULL
;
1335 m_previewBitmap
= NULL
;
1342 m_printingPrepared
= false;
1347 wxPrintPreviewBase::~wxPrintPreviewBase()
1349 if (m_previewPrintout
)
1350 delete m_previewPrintout
;
1351 if (m_previewBitmap
)
1352 delete m_previewBitmap
;
1353 if (m_printPrintout
)
1354 delete m_printPrintout
;
1357 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1359 if (m_currentPage
== pageNum
)
1362 m_currentPage
= pageNum
;
1363 if (m_previewBitmap
)
1365 delete m_previewBitmap
;
1366 m_previewBitmap
= NULL
;
1369 if (m_previewCanvas
)
1371 AdjustScrollbars(m_previewCanvas
);
1373 if (!RenderPage(pageNum
))
1375 m_previewCanvas
->Refresh();
1376 m_previewCanvas
->SetFocus();
1381 int wxPrintPreviewBase::GetCurrentPage() const
1382 { return m_currentPage
; }
1383 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1384 { m_previewPrintout
= printout
; }
1385 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1386 { return m_previewPrintout
; }
1387 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1388 { return m_printPrintout
; }
1389 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1390 { m_previewFrame
= frame
; }
1391 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1392 { m_previewCanvas
= canvas
; }
1393 wxFrame
*wxPrintPreviewBase::GetFrame() const
1394 { return m_previewFrame
; }
1395 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1396 { return m_previewCanvas
; }
1398 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1400 // Calculate the rectangles for the printable area of the page and the
1401 // entire paper as they appear on the canvas on-screen.
1402 int canvasWidth
, canvasHeight
;
1403 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1405 float zoomScale
= float(m_currentZoom
) / 100;
1406 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1407 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1409 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1410 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1411 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1412 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1413 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1414 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1415 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1417 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1418 if (paperRect
.x
< m_leftMargin
)
1419 paperRect
.x
= m_leftMargin
;
1420 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1421 if (paperRect
.y
< m_topMargin
)
1422 paperRect
.y
= m_topMargin
;
1424 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1425 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1426 pageRect
.width
= wxCoord(screenPrintableWidth
);
1427 pageRect
.height
= wxCoord(screenPrintableHeight
);
1431 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1433 DrawBlankPage(canvas
, dc
);
1435 if (!m_previewBitmap
)
1436 if (!RenderPage(m_currentPage
))
1438 if (!m_previewBitmap
)
1443 wxRect pageRect
, paperRect
;
1444 CalcRects(canvas
, pageRect
, paperRect
);
1446 temp_dc
.SelectObject(*m_previewBitmap
);
1448 dc
.Blit(pageRect
.x
, pageRect
.y
,
1449 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1451 temp_dc
.SelectObject(wxNullBitmap
);
1455 // Adjusts the scrollbars for the current scale
1456 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1461 wxRect pageRect
, paperRect
;
1462 CalcRects(canvas
, pageRect
, paperRect
);
1463 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1464 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1465 int scrollUnitsX
= totalWidth
/ 10;
1466 int scrollUnitsY
= totalHeight
/ 10;
1467 wxSize virtualSize
= canvas
->GetVirtualSize();
1468 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1469 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1472 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1476 if (!m_previewCanvas
)
1478 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1482 wxRect pageRect
, paperRect
;
1483 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1485 if (!m_previewBitmap
)
1487 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1489 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1491 if (m_previewBitmap
) {
1492 delete m_previewBitmap
;
1493 m_previewBitmap
= NULL
;
1495 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1500 wxMemoryDC memoryDC
;
1501 memoryDC
.SelectObject(*m_previewBitmap
);
1505 m_previewPrintout
->SetDC(&memoryDC
);
1506 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1508 // Need to delay OnPreparePrinting until here, so we have enough information.
1509 if (!m_printingPrepared
)
1511 m_previewPrintout
->OnPreparePrinting();
1513 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1514 m_printingPrepared
= true;
1517 m_previewPrintout
->OnBeginPrinting();
1519 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1521 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1523 memoryDC
.SelectObject(wxNullBitmap
);
1525 delete m_previewBitmap
;
1526 m_previewBitmap
= NULL
;
1530 m_previewPrintout
->OnPrintPage(pageNum
);
1531 m_previewPrintout
->OnEndDocument();
1532 m_previewPrintout
->OnEndPrinting();
1534 m_previewPrintout
->SetDC(NULL
);
1536 memoryDC
.SelectObject(wxNullBitmap
);
1541 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1543 status
= wxString::Format(_("Page %d"), pageNum
);
1546 m_previewFrame
->SetStatusText(status
);
1552 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1554 wxRect pageRect
, paperRect
;
1556 CalcRects(canvas
, pageRect
, paperRect
);
1558 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1559 wxCoord shadowOffset
= 4;
1561 dc
.SetPen(*wxBLACK_PEN
);
1562 dc
.SetBrush(*wxBLACK_BRUSH
);
1563 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1564 paperRect
.width
, shadowOffset
);
1566 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1567 shadowOffset
, paperRect
.height
);
1569 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1570 dc
.SetPen(*wxBLACK_PEN
);
1571 dc
.SetBrush(*wxWHITE_BRUSH
);
1572 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1573 paperRect
.width
+ 3, paperRect
.height
+ 2);
1578 void wxPrintPreviewBase::SetZoom(int percent
)
1580 if (m_currentZoom
== percent
)
1583 m_currentZoom
= percent
;
1584 if (m_previewBitmap
)
1586 delete m_previewBitmap
;
1587 m_previewBitmap
= NULL
;
1590 if (m_previewCanvas
)
1592 AdjustScrollbars(m_previewCanvas
);
1593 RenderPage(m_currentPage
);
1594 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1595 m_previewCanvas
->ClearBackground();
1596 m_previewCanvas
->Refresh();
1597 m_previewCanvas
->SetFocus();
1601 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1603 return m_printDialogData
;
1606 int wxPrintPreviewBase::GetZoom() const
1607 { return m_currentZoom
; }
1608 int wxPrintPreviewBase::GetMaxPage() const
1609 { return m_maxPage
; }
1610 int wxPrintPreviewBase::GetMinPage() const
1611 { return m_minPage
; }
1612 bool wxPrintPreviewBase::IsOk() const
1614 void wxPrintPreviewBase::SetOk(bool ok
)
1617 //----------------------------------------------------------------------------
1619 //----------------------------------------------------------------------------
1621 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1623 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1624 wxPrintout
*printoutForPrinting
,
1625 wxPrintDialogData
*data
) :
1626 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1628 m_pimpl
= wxPrintFactory::GetFactory()->
1629 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1632 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1633 wxPrintout
*printoutForPrinting
,
1634 wxPrintData
*data
) :
1635 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1637 m_pimpl
= wxPrintFactory::GetFactory()->
1638 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1641 wxPrintPreview::~wxPrintPreview()
1645 // don't delete twice
1646 m_printPrintout
= NULL
;
1647 m_previewPrintout
= NULL
;
1648 m_previewBitmap
= NULL
;
1651 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1653 return m_pimpl
->SetCurrentPage( pageNum
);
1656 int wxPrintPreview::GetCurrentPage() const
1658 return m_pimpl
->GetCurrentPage();
1661 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1663 m_pimpl
->SetPrintout( printout
);
1666 wxPrintout
*wxPrintPreview::GetPrintout() const
1668 return m_pimpl
->GetPrintout();
1671 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1673 return m_pimpl
->GetPrintoutForPrinting();
1676 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1678 m_pimpl
->SetFrame( frame
);
1681 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1683 m_pimpl
->SetCanvas( canvas
);
1686 wxFrame
*wxPrintPreview::GetFrame() const
1688 return m_pimpl
->GetFrame();
1691 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1693 return m_pimpl
->GetCanvas();
1696 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1698 return m_pimpl
->PaintPage( canvas
, dc
);
1701 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1703 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1706 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1708 m_pimpl
->AdjustScrollbars( canvas
);
1711 bool wxPrintPreview::RenderPage(int pageNum
)
1713 return m_pimpl
->RenderPage( pageNum
);
1716 void wxPrintPreview::SetZoom(int percent
)
1718 m_pimpl
->SetZoom( percent
);
1721 int wxPrintPreview::GetZoom() const
1723 return m_pimpl
->GetZoom();
1726 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1728 return m_pimpl
->GetPrintDialogData();
1731 int wxPrintPreview::GetMaxPage() const
1733 return m_pimpl
->GetMaxPage();
1736 int wxPrintPreview::GetMinPage() const
1738 return m_pimpl
->GetMinPage();
1741 bool wxPrintPreview::IsOk() const
1743 return m_pimpl
->Ok();
1746 void wxPrintPreview::SetOk(bool ok
)
1748 m_pimpl
->SetOk( ok
);
1751 bool wxPrintPreview::Print(bool interactive
)
1753 return m_pimpl
->Print( interactive
);
1756 void wxPrintPreview::DetermineScaling()
1758 m_pimpl
->DetermineScaling();
1761 #endif // wxUSE_PRINTING_ARCHITECTURE