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"
30 #include "wx/msgdlg.h"
31 #include "wx/layout.h"
32 #include "wx/choice.h"
33 #include "wx/button.h"
34 #include "wx/settings.h"
35 #include "wx/dcmemory.h"
36 #include "wx/stattext.h"
38 #include "wx/textdlg.h"
40 #include "wx/module.h"
43 #include "wx/prntbase.h"
44 #include "wx/printdlg.h"
46 #include "wx/dcprint.h"
51 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
52 #include "wx/msw/printdlg.h"
53 #elif defined(__WXMAC__)
54 #include "wx/mac/printdlg.h"
55 #include "wx/mac/private/print.h"
57 #include "wx/generic/prntdlgg.h"
67 //----------------------------------------------------------------------------
69 //----------------------------------------------------------------------------
71 wxPrintFactory
*wxPrintFactory::m_factory
= NULL
;
73 void wxPrintFactory::SetPrintFactory( wxPrintFactory
*factory
)
75 if (wxPrintFactory::m_factory
)
76 delete wxPrintFactory::m_factory
;
78 wxPrintFactory::m_factory
= factory
;
81 wxPrintFactory
*wxPrintFactory::GetFactory()
83 if (!wxPrintFactory::m_factory
)
84 wxPrintFactory::m_factory
= new wxNativePrintFactory
;
86 return wxPrintFactory::m_factory
;
89 //----------------------------------------------------------------------------
90 // wxNativePrintFactory
91 //----------------------------------------------------------------------------
93 wxPrinterBase
*wxNativePrintFactory::CreatePrinter( wxPrintDialogData
*data
)
95 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
96 return new wxWindowsPrinter( data
);
97 #elif defined(__WXMAC__)
98 return new wxMacPrinter( data
);
99 #elif defined(__WXPM__)
100 return new wxOS2Printer( data
);
102 return new wxPostScriptPrinter( data
);
106 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
107 wxPrintout
*printout
, wxPrintDialogData
*data
)
109 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
110 return new wxWindowsPrintPreview( preview
, printout
, data
);
111 #elif defined(__WXMAC__)
112 return new wxMacPrintPreview( preview
, printout
, data
);
113 #elif defined(__WXPM__)
114 return new wxOS2PrintPreview( preview
, printout
, data
);
116 return new wxPostScriptPrintPreview( preview
, printout
, data
);
120 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
121 wxPrintout
*printout
, wxPrintData
*data
)
123 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
124 return new wxWindowsPrintPreview( preview
, printout
, data
);
125 #elif defined(__WXMAC__)
126 return new wxMacPrintPreview( preview
, printout
, data
);
127 #elif defined(__WXPM__)
128 return new wxOS2PrintPreview( preview
, printout
, data
);
130 return new wxPostScriptPrintPreview( preview
, printout
, data
);
134 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
135 wxPrintDialogData
*data
)
137 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
138 return new wxWindowsPrintDialog( parent
, data
);
139 #elif defined(__WXMAC__)
140 return new wxMacPrintDialog( parent
, data
);
142 return new wxGenericPrintDialog( parent
, data
);
146 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
149 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
150 return new wxWindowsPrintDialog( parent
, data
);
151 #elif defined(__WXMAC__)
152 return new wxMacPrintDialog( parent
, data
);
154 return new wxGenericPrintDialog( parent
, data
);
158 wxPageSetupDialogBase
*wxNativePrintFactory::CreatePageSetupDialog( wxWindow
*parent
,
159 wxPageSetupDialogData
*data
)
161 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
162 return new wxWindowsPageSetupDialog( parent
, data
);
163 #elif defined(__WXMAC__)
164 return new wxMacPageSetupDialog( parent
, data
);
166 return new wxGenericPageSetupDialog( parent
, data
);
170 bool wxNativePrintFactory::HasPrintSetupDialog()
172 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
174 #elif defined(__WXMAC__)
177 // Only here do we need to provide the print setup
178 // dialog ourselves, the other platforms either have
179 // none, don't make it accessible or let you configure
180 // the printer from the wxPrintDialog anyway.
186 wxDialog
*wxNativePrintFactory::CreatePrintSetupDialog( wxWindow
*parent
,
189 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
193 #elif defined(__WXMAC__)
198 // Only here do we need to provide the print setup
199 // dialog ourselves, the other platforms either have
200 // none, don't make it accessible or let you configure
201 // the printer from the wxPrintDialog anyway.
202 return new wxGenericPrintSetupDialog( parent
, data
);
206 wxDC
* wxNativePrintFactory::CreatePrinterDC( const wxPrintData
& data
)
208 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
209 return new wxPrinterDC(data
);
210 #elif defined(__WXMAC__)
211 return new wxPrinterDC(data
);
213 return new wxPostScriptDC(data
);
217 bool wxNativePrintFactory::HasOwnPrintToFile()
219 // Only relevant for PostScript and here the
220 // setup dialog provides no "print to file"
221 // option. In the GNOME setup dialog, the
222 // setup dialog has its own print to file.
226 bool wxNativePrintFactory::HasPrinterLine()
228 // Only relevant for PostScript for now
232 wxString
wxNativePrintFactory::CreatePrinterLine()
234 // Only relevant for PostScript for now
236 // We should query "lpstat -d" here
237 return _("Generic PostScript");
240 bool wxNativePrintFactory::HasStatusLine()
242 // Only relevant for PostScript for now
246 wxString
wxNativePrintFactory::CreateStatusLine()
248 // Only relevant for PostScript for now
250 // We should query "lpstat -r" or "lpstat -p" here
254 wxPrintNativeDataBase
*wxNativePrintFactory::CreatePrintNativeData()
256 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
257 return new wxWindowsPrintNativeData
;
258 #elif defined(__WXMAC__)
259 return new wxMacCarbonPrintData
;
261 return new wxPostScriptPrintNativeData
;
265 //----------------------------------------------------------------------------
266 // wxPrintNativeDataBase
267 //----------------------------------------------------------------------------
269 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase
, wxObject
)
271 wxPrintNativeDataBase::wxPrintNativeDataBase()
276 //----------------------------------------------------------------------------
277 // wxPrintFactoryModule
278 //----------------------------------------------------------------------------
280 class wxPrintFactoryModule
: public wxModule
283 wxPrintFactoryModule() {}
284 bool OnInit() { return true; }
285 void OnExit() { wxPrintFactory::SetPrintFactory( NULL
); }
288 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule
)
291 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule
, wxModule
)
293 //----------------------------------------------------------------------------
295 //----------------------------------------------------------------------------
297 IMPLEMENT_CLASS(wxPrinterBase
, wxObject
)
299 wxPrinterBase::wxPrinterBase(wxPrintDialogData
*data
)
301 m_currentPrintout
= (wxPrintout
*) NULL
;
302 sm_abortWindow
= (wxWindow
*) NULL
;
305 m_printDialogData
= (*data
);
306 sm_lastError
= wxPRINTER_NO_ERROR
;
309 wxWindow
*wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
310 bool wxPrinterBase::sm_abortIt
= false;
311 wxPrinterError
wxPrinterBase::sm_lastError
= wxPRINTER_NO_ERROR
;
313 wxPrinterBase::~wxPrinterBase()
317 wxWindow
*wxPrinterBase::CreateAbortWindow(wxWindow
*parent
, wxPrintout
* printout
)
319 wxPrintAbortDialog
*dialog
= new wxPrintAbortDialog(parent
, _("Printing ") , wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
);
321 wxBoxSizer
*button_sizer
= new wxBoxSizer( wxVERTICAL
);
322 button_sizer
->Add( new wxStaticText(dialog
, wxID_ANY
, _("Please wait while printing\n") + printout
->GetTitle() ), 0, wxALL
, 10 );
323 button_sizer
->Add( new wxButton( dialog
, wxID_CANCEL
, wxT("Cancel") ), 0, wxALL
| wxALIGN_CENTER
, 10 );
325 dialog
->SetAutoLayout( true );
326 dialog
->SetSizer( button_sizer
);
328 button_sizer
->Fit(dialog
);
329 button_sizer
->SetSizeHints (dialog
) ;
334 void wxPrinterBase::ReportError(wxWindow
*parent
, wxPrintout
*WXUNUSED(printout
), const wxString
& message
)
336 wxMessageBox(message
, _("Printing Error"), wxOK
, parent
);
339 wxPrintDialogData
& wxPrinterBase::GetPrintDialogData() const
341 return (wxPrintDialogData
&) m_printDialogData
;
344 //----------------------------------------------------------------------------
346 //----------------------------------------------------------------------------
348 IMPLEMENT_CLASS(wxPrinter
, wxPrinterBase
)
350 wxPrinter::wxPrinter(wxPrintDialogData
*data
)
352 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrinter( data
);
355 wxPrinter::~wxPrinter()
360 wxWindow
*wxPrinter::CreateAbortWindow(wxWindow
*parent
, wxPrintout
*printout
)
362 return m_pimpl
->CreateAbortWindow( parent
, printout
);
365 void wxPrinter::ReportError(wxWindow
*parent
, wxPrintout
*printout
, const wxString
& message
)
367 m_pimpl
->ReportError( parent
, printout
, message
);
370 bool wxPrinter::Setup(wxWindow
*parent
)
372 return m_pimpl
->Setup( parent
);
375 bool wxPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
377 return m_pimpl
->Print( parent
, printout
, prompt
);
380 wxDC
* wxPrinter::PrintDialog(wxWindow
*parent
)
382 return m_pimpl
->PrintDialog( parent
);
385 wxPrintDialogData
& wxPrinter::GetPrintDialogData() const
387 return m_pimpl
->GetPrintDialogData();
390 // ---------------------------------------------------------------------------
391 // wxPrintDialogBase: the dialog for printing.
392 // ---------------------------------------------------------------------------
394 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase
, wxDialog
)
396 wxPrintDialogBase::wxPrintDialogBase(wxWindow
*parent
,
398 const wxString
&title
,
402 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Print")) : title
,
407 // ---------------------------------------------------------------------------
408 // wxPrintDialog: the dialog for printing
409 // ---------------------------------------------------------------------------
411 IMPLEMENT_CLASS(wxPrintDialog
, wxObject
)
413 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintDialogData
* data
)
415 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
418 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintData
* data
)
420 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
423 wxPrintDialog::~wxPrintDialog()
428 int wxPrintDialog::ShowModal()
430 return m_pimpl
->ShowModal();
433 wxPrintDialogData
& wxPrintDialog::GetPrintDialogData()
435 return m_pimpl
->GetPrintDialogData();
438 wxPrintData
& wxPrintDialog::GetPrintData()
440 return m_pimpl
->GetPrintData();
443 wxDC
*wxPrintDialog::GetPrintDC()
445 return m_pimpl
->GetPrintDC();
448 // ---------------------------------------------------------------------------
449 // wxPageSetupDialogBase: the page setup dialog
450 // ---------------------------------------------------------------------------
452 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase
, wxDialog
)
454 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow
*parent
,
456 const wxString
&title
,
460 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Page setup")) : title
,
465 // ---------------------------------------------------------------------------
466 // wxPageSetupDialog: the page setup dialog
467 // ---------------------------------------------------------------------------
469 IMPLEMENT_CLASS(wxPageSetupDialog
, wxObject
)
471 wxPageSetupDialog::wxPageSetupDialog(wxWindow
*parent
, wxPageSetupDialogData
*data
)
473 m_pimpl
= wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent
, data
);
476 wxPageSetupDialog::~wxPageSetupDialog()
481 int wxPageSetupDialog::ShowModal()
483 return m_pimpl
->ShowModal();
486 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupDialogData()
488 return m_pimpl
->GetPageSetupDialogData();
492 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupData()
494 return m_pimpl
->GetPageSetupDialogData();
497 //----------------------------------------------------------------------------
498 // wxPrintAbortDialog
499 //----------------------------------------------------------------------------
501 BEGIN_EVENT_TABLE(wxPrintAbortDialog
, wxDialog
)
502 EVT_BUTTON(wxID_CANCEL
, wxPrintAbortDialog::OnCancel
)
505 void wxPrintAbortDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
))
507 wxPrinterBase::sm_abortIt
= true;
508 wxPrinterBase::sm_abortWindow
->Show(false);
509 wxPrinterBase::sm_abortWindow
->Close(true);
510 wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
513 //----------------------------------------------------------------------------
515 //----------------------------------------------------------------------------
517 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
)
519 wxPrintout::wxPrintout(const wxString
& title
)
521 m_printoutTitle
= title
;
522 m_printoutDC
= (wxDC
*) NULL
;
525 m_pageWidthPixels
= 0;
526 m_pageHeightPixels
= 0;
534 wxPrintout::~wxPrintout()
538 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
))
540 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
);
543 void wxPrintout::OnEndDocument()
548 void wxPrintout::OnBeginPrinting()
552 void wxPrintout::OnEndPrinting()
556 bool wxPrintout::HasPage(int page
)
561 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
)
569 void wxPrintout::FitThisSizeToPaper(const wxSize
& imageSize
)
571 // Set the DC scale and origin so that the given image size fits within the
572 // entire page and the origin is at the top left corner of the page. Note
573 // that with most printers, portions of the page will be non-printable. Use
574 // this if you're managing your own page margins.
575 if (!m_printoutDC
) return;
576 wxRect paperRect
= GetPaperRectPixels();
578 GetPageSizePixels(&pw
, &ph
);
580 m_printoutDC
->GetSize(&w
, &h
);
581 float scaleX
= ((float(paperRect
.width
) * w
) / (float(pw
) * imageSize
.x
));
582 float scaleY
= ((float(paperRect
.height
) * h
) / (float(ph
) * imageSize
.y
));
583 float actualScale
= wxMin(scaleX
, scaleY
);
584 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
585 m_printoutDC
->SetDeviceOrigin(0, 0);
586 wxRect logicalPaperRect
= GetLogicalPaperRect();
587 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
590 void wxPrintout::FitThisSizeToPage(const wxSize
& imageSize
)
592 // Set the DC scale and origin so that the given image size fits within the
593 // printable area of the page and the origin is at the top left corner of
594 // the printable area.
595 if (!m_printoutDC
) return;
597 m_printoutDC
->GetSize(&w
, &h
);
598 float scaleX
= float(w
) / imageSize
.x
;
599 float scaleY
= float(h
) / imageSize
.y
;
600 float actualScale
= wxMin(scaleX
, scaleY
);
601 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
602 m_printoutDC
->SetDeviceOrigin(0, 0);
605 void wxPrintout::FitThisSizeToPageMargins(const wxSize
& imageSize
, const wxPageSetupDialogData
& pageSetupData
)
607 // Set the DC scale and origin so that the given image size fits within the
608 // page margins defined in the given wxPageSetupDialogData object and the
609 // origin is at the top left corner of the page margins.
610 if (!m_printoutDC
) return;
611 wxRect paperRect
= GetPaperRectPixels();
613 GetPageSizePixels(&pw
, &ph
);
614 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
615 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
617 GetPageSizeMM(&mw
, &mh
);
618 float mmToDeviceX
= float(pw
) / mw
;
619 float mmToDeviceY
= float(ph
) / mh
;
620 wxRect
pageMarginsRect(paperRect
.x
+ wxCoordRound(mmToDeviceX
* topLeft
.x
),
621 paperRect
.y
+ wxCoordRound(mmToDeviceY
* topLeft
.y
),
622 paperRect
.width
- wxCoordRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
623 paperRect
.height
- wxCoordRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
625 m_printoutDC
->GetSize(&w
, &h
);
626 float scaleX
= (float(pageMarginsRect
.width
) * w
) / (float(pw
) * imageSize
.x
);
627 float scaleY
= (float(pageMarginsRect
.height
) * h
) / (float(ph
) * imageSize
.y
);
628 float actualScale
= wxMin(scaleX
, scaleY
);
629 m_printoutDC
->SetUserScale(actualScale
, actualScale
);
630 m_printoutDC
->SetDeviceOrigin(0, 0);
631 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
632 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
635 void wxPrintout::MapScreenSizeToPaper()
637 // Set the DC scale so that an image on the screen is the same size on the
638 // paper and the origin is at the top left of the paper. Note that with most
639 // printers, portions of the page will be cut off. Use this if you're
640 // managing your own page margins.
641 if (!m_printoutDC
) return;
642 MapScreenSizeToPage();
643 wxRect logicalPaperRect
= GetLogicalPaperRect();
644 SetLogicalOrigin(logicalPaperRect
.x
, logicalPaperRect
.y
);
647 void wxPrintout::MapScreenSizeToPage()
649 // Set the DC scale and origin so that an image on the screen is the same
650 // size on the paper and the origin is at the top left of the printable area.
651 if (!m_printoutDC
) return;
652 int ppiScreenX
, ppiScreenY
;
653 GetPPIScreen(&ppiScreenX
, &ppiScreenY
);
654 int ppiPrinterX
, ppiPrinterY
;
655 GetPPIPrinter(&ppiPrinterX
, &ppiPrinterY
);
657 m_printoutDC
->GetSize(&w
, &h
);
658 int pageSizePixelsX
, pageSizePixelsY
;
659 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
660 float userScaleX
= (float(ppiPrinterX
) * w
) / (float(ppiScreenX
) * pageSizePixelsX
);
661 float userScaleY
= (float(ppiPrinterY
) * h
) / (float(ppiScreenY
) * pageSizePixelsY
);
662 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
663 m_printoutDC
->SetDeviceOrigin(0, 0);
666 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData
& pageSetupData
)
668 // Set the DC scale so that an image on the screen is the same size on the
669 // paper and the origin is at the top left of the page margins defined by
670 // the given wxPageSetupDialogData object.
671 if (!m_printoutDC
) return;
672 MapScreenSizeToPage();
673 wxRect logicalPageMarginsRect
= GetLogicalPageMarginsRect(pageSetupData
);
674 SetLogicalOrigin(logicalPageMarginsRect
.x
, logicalPageMarginsRect
.y
);
677 void wxPrintout::MapScreenSizeToDevice()
679 // Set the DC scale so that a screen pixel is the same size as a device
680 // pixel and the origin is at the top left of the printable area.
681 if (!m_printoutDC
) return;
683 m_printoutDC
->GetSize(&w
, &h
);
684 int pageSizePixelsX
, pageSizePixelsY
;
685 GetPageSizePixels(&pageSizePixelsX
, &pageSizePixelsY
);
686 float userScaleX
= float(w
) / pageSizePixelsX
;
687 float userScaleY
= float(h
) / pageSizePixelsY
;
688 m_printoutDC
->SetUserScale(userScaleX
, userScaleY
);
689 m_printoutDC
->SetDeviceOrigin(0, 0);
692 wxRect
wxPrintout::GetLogicalPaperRect() const
694 // Return the rectangle in logical units that corresponds to the paper
696 wxRect paperRect
= GetPaperRectPixels();
698 GetPageSizePixels(&pw
, &ph
);
700 m_printoutDC
->GetSize(&w
, &h
);
701 if (w
== pw
&& h
== ph
) {
702 // this DC matches the printed page, so no scaling
703 return wxRect(m_printoutDC
->DeviceToLogicalX(paperRect
.x
),
704 m_printoutDC
->DeviceToLogicalY(paperRect
.y
),
705 m_printoutDC
->DeviceToLogicalXRel(paperRect
.width
),
706 m_printoutDC
->DeviceToLogicalYRel(paperRect
.height
));
708 // This DC doesn't match the printed page, so we have to scale.
709 float scaleX
= float(w
) / pw
;
710 float scaleY
= float(h
) / ph
;
711 return wxRect(m_printoutDC
->DeviceToLogicalX(wxCoordRound(paperRect
.x
* scaleX
)),
712 m_printoutDC
->DeviceToLogicalY(wxCoordRound(paperRect
.y
* scaleY
)),
713 m_printoutDC
->DeviceToLogicalXRel(wxCoordRound(paperRect
.width
* scaleX
)),
714 m_printoutDC
->DeviceToLogicalYRel(wxCoordRound(paperRect
.height
* scaleY
)));
717 wxRect
wxPrintout::GetLogicalPageRect() const
719 // Return the rectangle in logical units that corresponds to the printable
722 m_printoutDC
->GetSize(&w
, &h
);
723 return wxRect(m_printoutDC
->DeviceToLogicalX(0),
724 m_printoutDC
->DeviceToLogicalY(0),
725 m_printoutDC
->DeviceToLogicalXRel(w
),
726 m_printoutDC
->DeviceToLogicalYRel(h
));
729 wxRect
wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData
& pageSetupData
) const
731 // Return the rectangle in logical units that corresponds to the region
732 // within the page margins as specified by the given wxPageSetupDialogData
734 wxRect paperRect
= GetPaperRectPixels();
736 GetPageSizePixels(&pw
, &ph
);
737 wxPoint topLeft
= pageSetupData
.GetMarginTopLeft();
738 wxPoint bottomRight
= pageSetupData
.GetMarginBottomRight();
740 GetPageSizeMM(&mw
, &mh
);
741 float mmToDeviceX
= float(pw
) / mw
;
742 float mmToDeviceY
= float(ph
) / mh
;
743 wxRect
pageMarginsRect(paperRect
.x
+ wxCoordRound(mmToDeviceX
* topLeft
.x
),
744 paperRect
.y
+ wxCoordRound(mmToDeviceY
* topLeft
.y
),
745 paperRect
.width
- wxCoordRound(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
746 paperRect
.height
- wxCoordRound(mmToDeviceY
* (topLeft
.y
+ bottomRight
.y
)));
748 m_printoutDC
->GetSize(&w
, &h
);
749 if (w
== pw
&& h
== ph
) {
750 // this DC matches the printed page, so no scaling
751 return wxRect(m_printoutDC
->DeviceToLogicalX(pageMarginsRect
.x
),
752 m_printoutDC
->DeviceToLogicalY(pageMarginsRect
.y
),
753 m_printoutDC
->DeviceToLogicalXRel(pageMarginsRect
.width
),
754 m_printoutDC
->DeviceToLogicalYRel(pageMarginsRect
.height
));
756 // This DC doesn't match the printed page, so we have to scale.
757 float scaleX
= float(w
) / pw
;
758 float scaleY
= float(h
) / ph
;
759 return wxRect(m_printoutDC
->DeviceToLogicalX(wxCoordRound(pageMarginsRect
.x
* scaleX
)),
760 m_printoutDC
->DeviceToLogicalY(wxCoordRound(pageMarginsRect
.y
* scaleY
)),
761 m_printoutDC
->DeviceToLogicalXRel(wxCoordRound(pageMarginsRect
.width
* scaleX
)),
762 m_printoutDC
->DeviceToLogicalYRel(wxCoordRound(pageMarginsRect
.height
* scaleY
)));
765 void wxPrintout::SetLogicalOrigin(wxCoord x
, wxCoord y
)
767 // Set the device origin by specifying a point in logical coordinates.
768 m_printoutDC
->SetDeviceOrigin(m_printoutDC
->LogicalToDeviceX(x
),
769 m_printoutDC
->LogicalToDeviceY(y
));
772 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff
, wxCoord yoff
)
774 // Offset the device origin by a specified distance in device coordinates.
775 wxCoord x
= m_printoutDC
->LogicalToDeviceX(0);
776 wxCoord y
= m_printoutDC
->LogicalToDeviceY(0);
777 m_printoutDC
->SetDeviceOrigin(x
+ m_printoutDC
->LogicalToDeviceXRel(xoff
),
778 y
+ m_printoutDC
->LogicalToDeviceYRel(yoff
));
782 //----------------------------------------------------------------------------
784 //----------------------------------------------------------------------------
786 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
788 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
789 EVT_PAINT(wxPreviewCanvas::OnPaint
)
790 EVT_CHAR(wxPreviewCanvas::OnChar
)
791 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
793 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
797 // VZ: the current code doesn't refresh properly without
798 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
799 // really horrible flicker when resizing the preview frame, but without
800 // this style it simply doesn't work correctly at all...
801 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
802 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
803 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
805 m_printPreview
= preview
;
807 // The app workspace colour is always white, but we should have
808 // a contrast with the page.
809 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
810 #elif defined(__WXGTK__)
811 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
813 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
815 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
817 SetScrollbars(10, 10, 100, 100);
820 wxPreviewCanvas::~wxPreviewCanvas()
824 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
831 if (!GetUpdateRegion().IsEmpty())
832 dc.SetClippingRegion( GetUpdateRegion() );
838 m_printPreview
->PaintPage(this, dc
);
842 // Responds to colour changes, and passes event on to children.
843 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
846 // The app workspace colour is always white, but we should have
847 // a contrast with the page.
848 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
849 #elif defined(__WXGTK__)
850 wxSystemColour colourIndex
= wxSYS_COLOUR_BTNFACE
;
852 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
854 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
857 // Propagate the event to the non-top-level children
858 wxWindow::OnSysColourChanged(event
);
861 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
863 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
864 if (event
.GetKeyCode() == WXK_ESCAPE
)
866 ((wxPreviewFrame
*) GetParent())->Close(true);
869 else if (event
.GetKeyCode() == WXK_TAB
)
871 controlBar
->OnGoto();
874 else if (event
.GetKeyCode() == WXK_RETURN
)
876 controlBar
->OnPrint();
880 if (!event
.ControlDown())
886 switch(event
.GetKeyCode())
889 controlBar
->OnNext(); break;
891 controlBar
->OnPrevious(); break;
893 controlBar
->OnFirst(); break;
895 controlBar
->OnLast(); break;
903 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
905 wxPreviewControlBar
*
906 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
910 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
912 int currentZoom
= controlBar
->GetZoomControl();
915 if ( currentZoom
< 100 )
917 else if ( currentZoom
<= 120 )
922 if ( event
.GetWheelRotation() > 0 )
925 int newZoom
= currentZoom
+ delta
;
930 if ( newZoom
!= currentZoom
)
932 controlBar
->SetZoomControl(newZoom
);
933 m_printPreview
->SetZoom(newZoom
);
943 #endif // wxUSE_MOUSEWHEEL
945 //----------------------------------------------------------------------------
946 // wxPreviewControlBar
947 //----------------------------------------------------------------------------
949 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
951 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
952 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
953 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
954 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
955 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
956 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
957 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
958 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
959 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
960 EVT_PAINT(wxPreviewControlBar::OnPaint
)
963 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
964 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
965 long style
, const wxString
& name
):
966 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
968 m_printPreview
= preview
;
969 m_closeButton
= (wxButton
*) NULL
;
970 m_nextPageButton
= (wxButton
*) NULL
;
971 m_previousPageButton
= (wxButton
*) NULL
;
972 m_printButton
= (wxButton
*) NULL
;
973 m_zoomControl
= (wxChoice
*) NULL
;
974 m_buttonFlags
= buttons
;
977 wxPreviewControlBar::~wxPreviewControlBar()
981 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
987 dc
.SetPen(*wxBLACK_PEN
);
988 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
989 dc
.DrawLine( 0, h
-1, w
, h
-1 );
992 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
994 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
998 void wxPreviewControlBar::OnPrint(void)
1000 wxPrintPreviewBase
*preview
= GetPrintPreview();
1001 preview
->Print(true);
1004 void wxPreviewControlBar::OnNext(void)
1006 wxPrintPreviewBase
*preview
= GetPrintPreview();
1009 int currentPage
= preview
->GetCurrentPage();
1010 if ((preview
->GetMaxPage() > 0) &&
1011 (currentPage
< preview
->GetMaxPage()) &&
1012 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1014 preview
->SetCurrentPage(currentPage
+ 1);
1019 void wxPreviewControlBar::OnPrevious(void)
1021 wxPrintPreviewBase
*preview
= GetPrintPreview();
1024 int currentPage
= preview
->GetCurrentPage();
1025 if ((preview
->GetMinPage() > 0) &&
1026 (currentPage
> preview
->GetMinPage()) &&
1027 preview
->GetPrintout()->HasPage(currentPage
- 1))
1029 preview
->SetCurrentPage(currentPage
- 1);
1034 void wxPreviewControlBar::OnFirst(void)
1036 wxPrintPreviewBase
*preview
= GetPrintPreview();
1039 int currentPage
= preview
->GetMinPage();
1040 if (preview
->GetPrintout()->HasPage(currentPage
))
1042 preview
->SetCurrentPage(currentPage
);
1047 void wxPreviewControlBar::OnLast(void)
1049 wxPrintPreviewBase
*preview
= GetPrintPreview();
1052 int currentPage
= preview
->GetMaxPage();
1053 if (preview
->GetPrintout()->HasPage(currentPage
))
1055 preview
->SetCurrentPage(currentPage
);
1060 void wxPreviewControlBar::OnGoto(void)
1062 wxPrintPreviewBase
*preview
= GetPrintPreview();
1067 if (preview
->GetMinPage() > 0)
1072 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1073 preview
->GetMinPage(), preview
->GetMaxPage());
1074 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1077 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1079 if ( strPage
.ToLong( ¤tPage
) )
1080 if (preview
->GetPrintout()->HasPage(currentPage
))
1082 preview
->SetCurrentPage(currentPage
);
1088 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1090 int zoom
= GetZoomControl();
1091 if (GetPrintPreview())
1092 GetPrintPreview()->SetZoom(zoom
);
1095 void wxPreviewControlBar::CreateButtons()
1097 SetSize(0, 0, 400, 40);
1099 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1101 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1102 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1104 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1106 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1107 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1110 // Exact-fit buttons are too tiny on wxUniversal
1112 wxSize navButtonSize
;
1113 #ifdef __WXUNIVERSAL__
1115 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1117 navButtonStyle
= wxBU_EXACTFIT
;
1118 navButtonSize
= wxDefaultSize
;
1121 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1123 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1124 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1127 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1129 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1130 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1133 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1135 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1136 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1139 if (m_buttonFlags
& wxPREVIEW_LAST
)
1141 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1142 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1145 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1147 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1148 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1151 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1153 wxString choices
[] =
1155 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1156 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1157 wxT("120%"), wxT("150%"), wxT("200%")
1159 int n
= WXSIZEOF(choices
);
1161 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1162 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1163 SetZoomControl(m_printPreview
->GetZoom());
1170 void wxPreviewControlBar::SetZoomControl(int zoom
)
1174 int n
, count
= m_zoomControl
->GetCount();
1176 for (n
=0; n
<count
; n
++)
1178 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1179 (val
>= long(zoom
)))
1181 m_zoomControl
->SetSelection(n
);
1186 m_zoomControl
->SetSelection(count
-1);
1190 int wxPreviewControlBar::GetZoomControl()
1192 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1195 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1207 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1209 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1210 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
1213 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1214 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1215 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1217 m_printPreview
= preview
;
1218 m_controlBar
= NULL
;
1219 m_previewCanvas
= NULL
;
1220 m_windowDisabler
= NULL
;
1222 // Give the application icon
1224 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1226 SetIcon(topFrame
->GetIcon());
1230 wxPreviewFrame::~wxPreviewFrame()
1234 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1236 if (m_windowDisabler
)
1237 delete m_windowDisabler
;
1239 // Need to delete the printout and the print preview
1240 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1244 m_printPreview
->SetPrintout(NULL
);
1245 m_printPreview
->SetCanvas(NULL
);
1246 m_printPreview
->SetFrame(NULL
);
1248 delete m_printPreview
;
1253 void wxPreviewFrame::Initialize()
1261 m_printPreview
->SetCanvas(m_previewCanvas
);
1262 m_printPreview
->SetFrame(this);
1264 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1266 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1267 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1269 SetAutoLayout( true );
1272 m_windowDisabler
= new wxWindowDisabler(this);
1276 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1277 m_previewCanvas
->SetFocus();
1278 m_controlBar
->SetFocus();
1281 void wxPreviewFrame::CreateCanvas()
1283 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1286 void wxPreviewFrame::CreateControlBar()
1288 long buttons
= wxPREVIEW_DEFAULT
;
1289 if (m_printPreview
->GetPrintoutForPrinting())
1290 buttons
|= wxPREVIEW_PRINT
;
1292 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1293 m_controlBar
->CreateButtons();
1300 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1302 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1303 wxPrintout
*printoutForPrinting
,
1307 m_printDialogData
= (*data
);
1309 Init(printout
, printoutForPrinting
);
1312 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1313 wxPrintout
*printoutForPrinting
,
1314 wxPrintDialogData
*data
)
1317 m_printDialogData
= (*data
);
1319 Init(printout
, printoutForPrinting
);
1322 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1323 wxPrintout
*printoutForPrinting
)
1326 m_previewPrintout
= printout
;
1327 if (m_previewPrintout
)
1328 m_previewPrintout
->SetIsPreview(true);
1330 m_printPrintout
= printoutForPrinting
;
1332 m_previewCanvas
= NULL
;
1333 m_previewFrame
= NULL
;
1334 m_previewBitmap
= NULL
;
1341 m_printingPrepared
= false;
1346 wxPrintPreviewBase::~wxPrintPreviewBase()
1348 if (m_previewPrintout
)
1349 delete m_previewPrintout
;
1350 if (m_previewBitmap
)
1351 delete m_previewBitmap
;
1352 if (m_printPrintout
)
1353 delete m_printPrintout
;
1356 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1358 if (m_currentPage
== pageNum
)
1361 m_currentPage
= pageNum
;
1362 if (m_previewBitmap
)
1364 delete m_previewBitmap
;
1365 m_previewBitmap
= NULL
;
1368 if (m_previewCanvas
)
1370 AdjustScrollbars(m_previewCanvas
);
1372 if (!RenderPage(pageNum
))
1374 m_previewCanvas
->Refresh();
1375 m_previewCanvas
->SetFocus();
1380 int wxPrintPreviewBase::GetCurrentPage() const
1381 { return m_currentPage
; }
1382 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1383 { m_previewPrintout
= printout
; }
1384 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1385 { return m_previewPrintout
; }
1386 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1387 { return m_printPrintout
; }
1388 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1389 { m_previewFrame
= frame
; }
1390 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1391 { m_previewCanvas
= canvas
; }
1392 wxFrame
*wxPrintPreviewBase::GetFrame() const
1393 { return m_previewFrame
; }
1394 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1395 { return m_previewCanvas
; }
1397 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1399 // Calculate the rectangles for the printable area of the page and the
1400 // entire paper as they appear on the canvas on-screen.
1401 int canvasWidth
, canvasHeight
;
1402 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1404 float zoomScale
= float(m_currentZoom
) / 100;
1405 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1406 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1408 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1409 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1410 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1411 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1412 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1413 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1414 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1416 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1417 if (paperRect
.x
< m_leftMargin
)
1418 paperRect
.x
= m_leftMargin
;
1419 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1420 if (paperRect
.y
< m_topMargin
)
1421 paperRect
.y
= m_topMargin
;
1423 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1424 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1425 pageRect
.width
= wxCoord(screenPrintableWidth
);
1426 pageRect
.height
= wxCoord(screenPrintableHeight
);
1430 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1432 DrawBlankPage(canvas
, dc
);
1434 if (!m_previewBitmap
)
1435 if (!RenderPage(m_currentPage
))
1437 if (!m_previewBitmap
)
1442 wxRect pageRect
, paperRect
;
1443 CalcRects(canvas
, pageRect
, paperRect
);
1445 temp_dc
.SelectObject(*m_previewBitmap
);
1447 dc
.Blit(pageRect
.x
, pageRect
.y
,
1448 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1450 temp_dc
.SelectObject(wxNullBitmap
);
1454 // Adjusts the scrollbars for the current scale
1455 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1460 wxRect pageRect
, paperRect
;
1461 CalcRects(canvas
, pageRect
, paperRect
);
1462 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1463 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1464 int scrollUnitsX
= totalWidth
/ 10;
1465 int scrollUnitsY
= totalHeight
/ 10;
1466 wxSize virtualSize
= canvas
->GetVirtualSize();
1467 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1468 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1471 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1475 if (!m_previewCanvas
)
1477 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1481 wxRect pageRect
, paperRect
;
1482 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1484 if (!m_previewBitmap
)
1486 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1488 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1490 if (m_previewBitmap
) {
1491 delete m_previewBitmap
;
1492 m_previewBitmap
= NULL
;
1494 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1499 wxMemoryDC memoryDC
;
1500 memoryDC
.SelectObject(*m_previewBitmap
);
1504 m_previewPrintout
->SetDC(&memoryDC
);
1505 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1507 // Need to delay OnPreparePrinting until here, so we have enough information.
1508 if (!m_printingPrepared
)
1510 m_previewPrintout
->OnPreparePrinting();
1512 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1513 m_printingPrepared
= true;
1516 m_previewPrintout
->OnBeginPrinting();
1518 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1520 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1522 memoryDC
.SelectObject(wxNullBitmap
);
1524 delete m_previewBitmap
;
1525 m_previewBitmap
= NULL
;
1529 m_previewPrintout
->OnPrintPage(pageNum
);
1530 m_previewPrintout
->OnEndDocument();
1531 m_previewPrintout
->OnEndPrinting();
1533 m_previewPrintout
->SetDC(NULL
);
1535 memoryDC
.SelectObject(wxNullBitmap
);
1540 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1542 status
= wxString::Format(_("Page %d"), pageNum
);
1545 m_previewFrame
->SetStatusText(status
);
1551 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1553 wxRect pageRect
, paperRect
;
1555 CalcRects(canvas
, pageRect
, paperRect
);
1557 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1558 wxCoord shadowOffset
= 4;
1560 dc
.SetPen(*wxBLACK_PEN
);
1561 dc
.SetBrush(*wxBLACK_BRUSH
);
1562 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1563 paperRect
.width
, shadowOffset
);
1565 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1566 shadowOffset
, paperRect
.height
);
1568 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1569 dc
.SetPen(*wxBLACK_PEN
);
1570 dc
.SetBrush(*wxWHITE_BRUSH
);
1571 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1572 paperRect
.width
+ 3, paperRect
.height
+ 2);
1577 void wxPrintPreviewBase::SetZoom(int percent
)
1579 if (m_currentZoom
== percent
)
1582 m_currentZoom
= percent
;
1583 if (m_previewBitmap
)
1585 delete m_previewBitmap
;
1586 m_previewBitmap
= NULL
;
1589 if (m_previewCanvas
)
1591 AdjustScrollbars(m_previewCanvas
);
1592 RenderPage(m_currentPage
);
1593 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1594 m_previewCanvas
->ClearBackground();
1595 m_previewCanvas
->Refresh();
1596 m_previewCanvas
->SetFocus();
1600 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1602 return m_printDialogData
;
1605 int wxPrintPreviewBase::GetZoom() const
1606 { return m_currentZoom
; }
1607 int wxPrintPreviewBase::GetMaxPage() const
1608 { return m_maxPage
; }
1609 int wxPrintPreviewBase::GetMinPage() const
1610 { return m_minPage
; }
1611 bool wxPrintPreviewBase::IsOk() const
1613 void wxPrintPreviewBase::SetOk(bool ok
)
1616 //----------------------------------------------------------------------------
1618 //----------------------------------------------------------------------------
1620 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1622 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1623 wxPrintout
*printoutForPrinting
,
1624 wxPrintDialogData
*data
) :
1625 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1627 m_pimpl
= wxPrintFactory::GetFactory()->
1628 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1631 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1632 wxPrintout
*printoutForPrinting
,
1633 wxPrintData
*data
) :
1634 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1636 m_pimpl
= wxPrintFactory::GetFactory()->
1637 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1640 wxPrintPreview::~wxPrintPreview()
1644 // don't delete twice
1645 m_printPrintout
= NULL
;
1646 m_previewPrintout
= NULL
;
1647 m_previewBitmap
= NULL
;
1650 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1652 return m_pimpl
->SetCurrentPage( pageNum
);
1655 int wxPrintPreview::GetCurrentPage() const
1657 return m_pimpl
->GetCurrentPage();
1660 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1662 m_pimpl
->SetPrintout( printout
);
1665 wxPrintout
*wxPrintPreview::GetPrintout() const
1667 return m_pimpl
->GetPrintout();
1670 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1672 return m_pimpl
->GetPrintoutForPrinting();
1675 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1677 m_pimpl
->SetFrame( frame
);
1680 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1682 m_pimpl
->SetCanvas( canvas
);
1685 wxFrame
*wxPrintPreview::GetFrame() const
1687 return m_pimpl
->GetFrame();
1690 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1692 return m_pimpl
->GetCanvas();
1695 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1697 return m_pimpl
->PaintPage( canvas
, dc
);
1700 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1702 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1705 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1707 m_pimpl
->AdjustScrollbars( canvas
);
1710 bool wxPrintPreview::RenderPage(int pageNum
)
1712 return m_pimpl
->RenderPage( pageNum
);
1715 void wxPrintPreview::SetZoom(int percent
)
1717 m_pimpl
->SetZoom( percent
);
1720 int wxPrintPreview::GetZoom() const
1722 return m_pimpl
->GetZoom();
1725 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1727 return m_pimpl
->GetPrintDialogData();
1730 int wxPrintPreview::GetMaxPage() const
1732 return m_pimpl
->GetMaxPage();
1735 int wxPrintPreview::GetMinPage() const
1737 return m_pimpl
->GetMinPage();
1740 bool wxPrintPreview::IsOk() const
1742 return m_pimpl
->Ok();
1745 void wxPrintPreview::SetOk(bool ok
)
1747 m_pimpl
->SetOk( ok
);
1750 bool wxPrintPreview::Print(bool interactive
)
1752 return m_pimpl
->Print( interactive
);
1755 void wxPrintPreview::DetermineScaling()
1757 m_pimpl
->DetermineScaling();
1760 #endif // wxUSE_PRINTING_ARCHITECTURE