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
+ wxCoord(mmToDeviceX
* topLeft
.x
),
621 paperRect
.y
+ wxCoord(mmToDeviceY
* topLeft
.y
),
622 paperRect
.width
- wxCoord(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
623 paperRect
.height
- wxCoord(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(wxCoord(paperRect
.x
* scaleX
)),
712 m_printoutDC
->DeviceToLogicalY(wxCoord(paperRect
.y
* scaleY
)),
713 m_printoutDC
->DeviceToLogicalXRel(wxCoord(paperRect
.width
* scaleX
)),
714 m_printoutDC
->DeviceToLogicalYRel(wxCoord(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
+ wxCoord(mmToDeviceX
* topLeft
.x
),
744 paperRect
.y
+ wxCoord(mmToDeviceY
* topLeft
.y
),
745 paperRect
.width
- wxCoord(mmToDeviceX
* (topLeft
.x
+ bottomRight
.x
)),
746 paperRect
.height
- wxCoord(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(wxCoord(pageMarginsRect
.x
* scaleX
)),
760 m_printoutDC
->DeviceToLogicalY(wxCoord(pageMarginsRect
.y
* scaleY
)),
761 m_printoutDC
->DeviceToLogicalXRel(wxCoord(pageMarginsRect
.width
* scaleX
)),
762 m_printoutDC
->DeviceToLogicalYRel(wxCoord(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
;
811 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
813 SetBackgroundColour(wxSystemSettings
::GetColour(colourIndex
));
815 SetScrollbars(10, 10, 100, 100);
818 wxPreviewCanvas
::~wxPreviewCanvas()
822 void wxPreviewCanvas
::OnPaint(wxPaintEvent
& WXUNUSED(event
))
829 if (!GetUpdateRegion().IsEmpty())
830 dc.SetClippingRegion( GetUpdateRegion() );
836 m_printPreview
->PaintPage(this, dc
);
840 // Responds to colour changes, and passes event on to children.
841 void wxPreviewCanvas
::OnSysColourChanged(wxSysColourChangedEvent
& event
)
844 // The app workspace colour is always white, but we should have
845 // a contrast with the page.
846 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
848 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
850 SetBackgroundColour(wxSystemSettings
::GetColour(colourIndex
));
853 // Propagate the event to the non-top-level children
854 wxWindow
::OnSysColourChanged(event
);
857 void wxPreviewCanvas
::OnChar(wxKeyEvent
&event
)
859 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
860 if (event
.GetKeyCode() == WXK_ESCAPE
)
862 ((wxPreviewFrame
*) GetParent())->Close(true);
865 else if (event
.GetKeyCode() == WXK_TAB
)
867 controlBar
->OnGoto();
870 else if (event
.GetKeyCode() == WXK_RETURN
)
872 controlBar
->OnPrint();
876 if (!event
.ControlDown())
882 switch(event
.GetKeyCode())
885 controlBar
->OnNext(); break;
887 controlBar
->OnPrevious(); break;
889 controlBar
->OnFirst(); break;
891 controlBar
->OnLast(); break;
899 void wxPreviewCanvas
::OnMouseWheel(wxMouseEvent
& event
)
901 wxPreviewControlBar
*
902 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
906 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
908 int currentZoom
= controlBar
->GetZoomControl();
911 if ( currentZoom
< 100 )
913 else if ( currentZoom
<= 120 )
918 if ( event
.GetWheelRotation() > 0 )
921 int newZoom
= currentZoom
+ delta
;
926 if ( newZoom
!= currentZoom
)
928 controlBar
->SetZoomControl(newZoom
);
929 m_printPreview
->SetZoom(newZoom
);
939 #endif // wxUSE_MOUSEWHEEL
941 //----------------------------------------------------------------------------
942 // wxPreviewControlBar
943 //----------------------------------------------------------------------------
945 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
947 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
948 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar
::OnWindowClose
)
949 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar
::OnPrintButton
)
950 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar
::OnPreviousButton
)
951 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar
::OnNextButton
)
952 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar
::OnFirstButton
)
953 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar
::OnLastButton
)
954 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar
::OnGotoButton
)
955 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar
::OnZoom
)
956 EVT_PAINT(wxPreviewControlBar
::OnPaint
)
959 wxPreviewControlBar
::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
960 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
961 long style
, const wxString
& name
):
962 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
964 m_printPreview
= preview
;
965 m_closeButton
= (wxButton
*) NULL
;
966 m_nextPageButton
= (wxButton
*) NULL
;
967 m_previousPageButton
= (wxButton
*) NULL
;
968 m_printButton
= (wxButton
*) NULL
;
969 m_zoomControl
= (wxChoice
*) NULL
;
970 m_buttonFlags
= buttons
;
973 wxPreviewControlBar
::~wxPreviewControlBar()
977 void wxPreviewControlBar
::OnPaint(wxPaintEvent
& WXUNUSED(event
))
983 dc
.SetPen(*wxBLACK_PEN
);
984 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
985 dc
.DrawLine( 0, h
-1, w
, h
-1 );
988 void wxPreviewControlBar
::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
990 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
994 void wxPreviewControlBar
::OnPrint(void)
996 wxPrintPreviewBase
*preview
= GetPrintPreview();
997 preview
->Print(true);
1000 void wxPreviewControlBar
::OnNext(void)
1002 wxPrintPreviewBase
*preview
= GetPrintPreview();
1005 int currentPage
= preview
->GetCurrentPage();
1006 if ((preview
->GetMaxPage() > 0) &&
1007 (currentPage
< preview
->GetMaxPage()) &&
1008 preview
->GetPrintout()->HasPage(currentPage
+ 1))
1010 preview
->SetCurrentPage(currentPage
+ 1);
1015 void wxPreviewControlBar
::OnPrevious(void)
1017 wxPrintPreviewBase
*preview
= GetPrintPreview();
1020 int currentPage
= preview
->GetCurrentPage();
1021 if ((preview
->GetMinPage() > 0) &&
1022 (currentPage
> preview
->GetMinPage()) &&
1023 preview
->GetPrintout()->HasPage(currentPage
- 1))
1025 preview
->SetCurrentPage(currentPage
- 1);
1030 void wxPreviewControlBar
::OnFirst(void)
1032 wxPrintPreviewBase
*preview
= GetPrintPreview();
1035 int currentPage
= preview
->GetMinPage();
1036 if (preview
->GetPrintout()->HasPage(currentPage
))
1038 preview
->SetCurrentPage(currentPage
);
1043 void wxPreviewControlBar
::OnLast(void)
1045 wxPrintPreviewBase
*preview
= GetPrintPreview();
1048 int currentPage
= preview
->GetMaxPage();
1049 if (preview
->GetPrintout()->HasPage(currentPage
))
1051 preview
->SetCurrentPage(currentPage
);
1056 void wxPreviewControlBar
::OnGoto(void)
1058 wxPrintPreviewBase
*preview
= GetPrintPreview();
1063 if (preview
->GetMinPage() > 0)
1068 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
1069 preview
->GetMinPage(), preview
->GetMaxPage());
1070 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
1073 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
1075 if ( strPage
.ToLong( ¤tPage
) )
1076 if (preview
->GetPrintout()->HasPage(currentPage
))
1078 preview
->SetCurrentPage(currentPage
);
1084 void wxPreviewControlBar
::OnZoom(wxCommandEvent
& WXUNUSED(event
))
1086 int zoom
= GetZoomControl();
1087 if (GetPrintPreview())
1088 GetPrintPreview()->SetZoom(zoom
);
1091 void wxPreviewControlBar
::CreateButtons()
1093 SetSize(0, 0, 400, 40);
1095 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
1097 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
1098 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1100 if (m_buttonFlags
& wxPREVIEW_PRINT
)
1102 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1103 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1106 // Exact-fit buttons are too tiny on wxUniversal
1108 wxSize navButtonSize
;
1109 #ifdef __WXUNIVERSAL__
1111 navButtonSize
= wxSize(40, m_closeButton
->GetSize().y
);
1113 navButtonStyle
= wxBU_EXACTFIT
;
1114 navButtonSize
= wxDefaultSize
;
1117 if (m_buttonFlags
& wxPREVIEW_FIRST
)
1119 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1120 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1123 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
1125 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1126 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1129 if (m_buttonFlags
& wxPREVIEW_NEXT
)
1131 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1132 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1135 if (m_buttonFlags
& wxPREVIEW_LAST
)
1137 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, navButtonSize
, navButtonStyle
);
1138 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
1141 if (m_buttonFlags
& wxPREVIEW_GOTO
)
1143 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
1144 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1147 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
1149 wxString choices
[] =
1151 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1152 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1153 wxT("120%"), wxT("150%"), wxT("200%")
1155 int n
= WXSIZEOF(choices
);
1157 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
1158 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
1159 SetZoomControl(m_printPreview
->GetZoom());
1166 void wxPreviewControlBar
::SetZoomControl(int zoom
)
1170 int n
, count
= m_zoomControl
->GetCount();
1172 for (n
=0; n
<count
; n
++)
1174 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
1175 (val
>= long(zoom
)))
1177 m_zoomControl
->SetSelection(n
);
1182 m_zoomControl
->SetSelection(count
-1);
1186 int wxPreviewControlBar
::GetZoomControl()
1188 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
1191 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
1203 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
1205 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
1206 EVT_CLOSE(wxPreviewFrame
::OnCloseWindow
)
1209 wxPreviewFrame
::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
1210 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
1211 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
1213 m_printPreview
= preview
;
1214 m_controlBar
= NULL
;
1215 m_previewCanvas
= NULL
;
1216 m_windowDisabler
= NULL
;
1218 // Give the application icon
1220 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
1222 SetIcon(topFrame
->GetIcon());
1226 wxPreviewFrame
::~wxPreviewFrame()
1230 void wxPreviewFrame
::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
1232 if (m_windowDisabler
)
1233 delete m_windowDisabler
;
1235 // Need to delete the printout and the print preview
1236 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1240 m_printPreview
->SetPrintout(NULL
);
1241 m_printPreview
->SetCanvas(NULL
);
1242 m_printPreview
->SetFrame(NULL
);
1244 delete m_printPreview
;
1249 void wxPreviewFrame
::Initialize()
1257 m_printPreview
->SetCanvas(m_previewCanvas
);
1258 m_printPreview
->SetFrame(this);
1260 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1262 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1263 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1265 SetAutoLayout( true );
1268 m_windowDisabler
= new wxWindowDisabler(this);
1272 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1273 m_previewCanvas
->SetFocus();
1274 m_controlBar
->SetFocus();
1277 void wxPreviewFrame
::CreateCanvas()
1279 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1282 void wxPreviewFrame
::CreateControlBar()
1284 long buttons
= wxPREVIEW_DEFAULT
;
1285 if (m_printPreview
->GetPrintoutForPrinting())
1286 buttons
|= wxPREVIEW_PRINT
;
1288 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1289 m_controlBar
->CreateButtons();
1296 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1298 wxPrintPreviewBase
::wxPrintPreviewBase(wxPrintout
*printout
,
1299 wxPrintout
*printoutForPrinting
,
1303 m_printDialogData
= (*data
);
1305 Init(printout
, printoutForPrinting
);
1308 wxPrintPreviewBase
::wxPrintPreviewBase(wxPrintout
*printout
,
1309 wxPrintout
*printoutForPrinting
,
1310 wxPrintDialogData
*data
)
1313 m_printDialogData
= (*data
);
1315 Init(printout
, printoutForPrinting
);
1318 void wxPrintPreviewBase
::Init(wxPrintout
*printout
,
1319 wxPrintout
*printoutForPrinting
)
1322 m_previewPrintout
= printout
;
1323 if (m_previewPrintout
)
1324 m_previewPrintout
->SetIsPreview(true);
1326 m_printPrintout
= printoutForPrinting
;
1328 m_previewCanvas
= NULL
;
1329 m_previewFrame
= NULL
;
1330 m_previewBitmap
= NULL
;
1337 m_printingPrepared
= false;
1342 wxPrintPreviewBase
::~wxPrintPreviewBase()
1344 if (m_previewPrintout
)
1345 delete m_previewPrintout
;
1346 if (m_previewBitmap
)
1347 delete m_previewBitmap
;
1348 if (m_printPrintout
)
1349 delete m_printPrintout
;
1352 bool wxPrintPreviewBase
::SetCurrentPage(int pageNum
)
1354 if (m_currentPage
== pageNum
)
1357 m_currentPage
= pageNum
;
1358 if (m_previewBitmap
)
1360 delete m_previewBitmap
;
1361 m_previewBitmap
= NULL
;
1364 if (m_previewCanvas
)
1366 AdjustScrollbars(m_previewCanvas
);
1368 if (!RenderPage(pageNum
))
1370 m_previewCanvas
->Refresh();
1371 m_previewCanvas
->SetFocus();
1376 int wxPrintPreviewBase
::GetCurrentPage() const
1377 { return m_currentPage
; }
1378 void wxPrintPreviewBase
::SetPrintout(wxPrintout
*printout
)
1379 { m_previewPrintout
= printout
; }
1380 wxPrintout
*wxPrintPreviewBase
::GetPrintout() const
1381 { return m_previewPrintout
; }
1382 wxPrintout
*wxPrintPreviewBase
::GetPrintoutForPrinting() const
1383 { return m_printPrintout
; }
1384 void wxPrintPreviewBase
::SetFrame(wxFrame
*frame
)
1385 { m_previewFrame
= frame
; }
1386 void wxPrintPreviewBase
::SetCanvas(wxPreviewCanvas
*canvas
)
1387 { m_previewCanvas
= canvas
; }
1388 wxFrame
*wxPrintPreviewBase
::GetFrame() const
1389 { return m_previewFrame
; }
1390 wxPreviewCanvas
*wxPrintPreviewBase
::GetCanvas() const
1391 { return m_previewCanvas
; }
1393 void wxPrintPreviewBase
::CalcRects(wxPreviewCanvas
*canvas
, wxRect
& pageRect
, wxRect
& paperRect
)
1395 // Calculate the rectangles for the printable area of the page and the
1396 // entire paper as they appear on the canvas on-screen.
1397 int canvasWidth
, canvasHeight
;
1398 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1400 float zoomScale
= float(m_currentZoom
) / 100;
1401 float screenPrintableWidth
= zoomScale
* m_pageWidth
* m_previewScaleX
;
1402 float screenPrintableHeight
= zoomScale
* m_pageHeight
* m_previewScaleY
;
1404 wxRect devicePaperRect
= m_previewPrintout
->GetPaperRectPixels();
1405 wxCoord devicePrintableWidth
, devicePrintableHeight
;
1406 m_previewPrintout
->GetPageSizePixels(&devicePrintableWidth
, &devicePrintableHeight
);
1407 float scaleX
= screenPrintableWidth
/ devicePrintableWidth
;
1408 float scaleY
= screenPrintableHeight
/ devicePrintableHeight
;
1409 paperRect
.width
= wxCoord(scaleX
* devicePaperRect
.width
);
1410 paperRect
.height
= wxCoord(scaleY
* devicePaperRect
.height
);
1412 paperRect
.x
= wxCoord((canvasWidth
- paperRect
.width
)/ 2.0);
1413 if (paperRect
.x
< m_leftMargin
)
1414 paperRect
.x
= m_leftMargin
;
1415 paperRect
.y
= wxCoord((canvasHeight
- paperRect
.height
)/ 2.0);
1416 if (paperRect
.y
< m_topMargin
)
1417 paperRect
.y
= m_topMargin
;
1419 pageRect
.x
= paperRect
.x
- wxCoord(scaleX
* devicePaperRect
.x
);
1420 pageRect
.y
= paperRect
.y
- wxCoord(scaleY
* devicePaperRect
.y
);
1421 pageRect
.width
= wxCoord(screenPrintableWidth
);
1422 pageRect
.height
= wxCoord(screenPrintableHeight
);
1426 bool wxPrintPreviewBase
::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1428 DrawBlankPage(canvas
, dc
);
1430 if (!m_previewBitmap
)
1431 if (!RenderPage(m_currentPage
))
1433 if (!m_previewBitmap
)
1438 wxRect pageRect
, paperRect
;
1439 CalcRects(canvas
, pageRect
, paperRect
);
1441 temp_dc
.SelectObject(*m_previewBitmap
);
1443 dc
.Blit(pageRect
.x
, pageRect
.y
,
1444 m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1446 temp_dc
.SelectObject(wxNullBitmap
);
1450 // Adjusts the scrollbars for the current scale
1451 void wxPrintPreviewBase
::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1456 wxRect pageRect
, paperRect
;
1457 CalcRects(canvas
, pageRect
, paperRect
);
1458 int totalWidth
= paperRect
.width
+ 2 * m_leftMargin
;
1459 int totalHeight
= paperRect
.height
+ 2 * m_topMargin
;
1460 int scrollUnitsX
= totalWidth
/ 10;
1461 int scrollUnitsY
= totalHeight
/ 10;
1462 wxSize virtualSize
= canvas
->GetVirtualSize();
1463 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1464 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1467 bool wxPrintPreviewBase
::RenderPage(int pageNum
)
1471 if (!m_previewCanvas
)
1473 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1477 wxRect pageRect
, paperRect
;
1478 CalcRects(m_previewCanvas
, pageRect
, paperRect
);
1480 if (!m_previewBitmap
)
1482 m_previewBitmap
= new wxBitmap(pageRect
.width
, pageRect
.height
);
1484 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1486 if (m_previewBitmap
) {
1487 delete m_previewBitmap
;
1488 m_previewBitmap
= NULL
;
1490 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1495 wxMemoryDC memoryDC
;
1496 memoryDC
.SelectObject(*m_previewBitmap
);
1500 m_previewPrintout
->SetDC(&memoryDC
);
1501 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1503 // Need to delay OnPreparePrinting until here, so we have enough information.
1504 if (!m_printingPrepared
)
1506 m_previewPrintout
->OnPreparePrinting();
1508 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1509 m_printingPrepared
= true;
1512 m_previewPrintout
->OnBeginPrinting();
1514 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1516 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1518 memoryDC
.SelectObject(wxNullBitmap
);
1520 delete m_previewBitmap
;
1521 m_previewBitmap
= NULL
;
1525 m_previewPrintout
->OnPrintPage(pageNum
);
1526 m_previewPrintout
->OnEndDocument();
1527 m_previewPrintout
->OnEndPrinting();
1529 m_previewPrintout
->SetDC(NULL
);
1531 memoryDC
.SelectObject(wxNullBitmap
);
1536 status
= wxString
::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1538 status
= wxString
::Format(_("Page %d"), pageNum
);
1541 m_previewFrame
->SetStatusText(status
);
1547 bool wxPrintPreviewBase
::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1549 wxRect pageRect
, paperRect
;
1551 CalcRects(canvas
, pageRect
, paperRect
);
1553 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1554 wxCoord shadowOffset
= 4;
1556 dc
.SetPen(*wxBLACK_PEN
);
1557 dc
.SetBrush(*wxBLACK_BRUSH
);
1558 dc
.DrawRectangle(paperRect
.x
+ shadowOffset
, paperRect
.y
+ paperRect
.height
+ 1,
1559 paperRect
.width
, shadowOffset
);
1561 dc
.DrawRectangle(paperRect
.x
+ paperRect
.width
, paperRect
.y
+ shadowOffset
,
1562 shadowOffset
, paperRect
.height
);
1564 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1565 dc
.SetPen(*wxBLACK_PEN
);
1566 dc
.SetBrush(*wxWHITE_BRUSH
);
1567 dc
.DrawRectangle(paperRect
.x
- 2, paperRect
.y
- 1,
1568 paperRect
.width
+ 3, paperRect
.height
+ 2);
1573 void wxPrintPreviewBase
::SetZoom(int percent
)
1575 if (m_currentZoom
== percent
)
1578 m_currentZoom
= percent
;
1579 if (m_previewBitmap
)
1581 delete m_previewBitmap
;
1582 m_previewBitmap
= NULL
;
1585 if (m_previewCanvas
)
1587 AdjustScrollbars(m_previewCanvas
);
1588 RenderPage(m_currentPage
);
1589 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1590 m_previewCanvas
->ClearBackground();
1591 m_previewCanvas
->Refresh();
1592 m_previewCanvas
->SetFocus();
1596 wxPrintDialogData
& wxPrintPreviewBase
::GetPrintDialogData()
1598 return m_printDialogData
;
1601 int wxPrintPreviewBase
::GetZoom() const
1602 { return m_currentZoom
; }
1603 int wxPrintPreviewBase
::GetMaxPage() const
1604 { return m_maxPage
; }
1605 int wxPrintPreviewBase
::GetMinPage() const
1606 { return m_minPage
; }
1607 bool wxPrintPreviewBase
::IsOk() const
1609 void wxPrintPreviewBase
::SetOk(bool ok
)
1612 //----------------------------------------------------------------------------
1614 //----------------------------------------------------------------------------
1616 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1618 wxPrintPreview
::wxPrintPreview(wxPrintout
*printout
,
1619 wxPrintout
*printoutForPrinting
,
1620 wxPrintDialogData
*data
) :
1621 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1623 m_pimpl
= wxPrintFactory
::GetFactory()->
1624 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1627 wxPrintPreview
::wxPrintPreview(wxPrintout
*printout
,
1628 wxPrintout
*printoutForPrinting
,
1629 wxPrintData
*data
) :
1630 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1632 m_pimpl
= wxPrintFactory
::GetFactory()->
1633 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1636 wxPrintPreview
::~wxPrintPreview()
1640 // don't delete twice
1641 m_printPrintout
= NULL
;
1642 m_previewPrintout
= NULL
;
1643 m_previewBitmap
= NULL
;
1646 bool wxPrintPreview
::SetCurrentPage(int pageNum
)
1648 return m_pimpl
->SetCurrentPage( pageNum
);
1651 int wxPrintPreview
::GetCurrentPage() const
1653 return m_pimpl
->GetCurrentPage();
1656 void wxPrintPreview
::SetPrintout(wxPrintout
*printout
)
1658 m_pimpl
->SetPrintout( printout
);
1661 wxPrintout
*wxPrintPreview
::GetPrintout() const
1663 return m_pimpl
->GetPrintout();
1666 wxPrintout
*wxPrintPreview
::GetPrintoutForPrinting() const
1668 return m_pimpl
->GetPrintoutForPrinting();
1671 void wxPrintPreview
::SetFrame(wxFrame
*frame
)
1673 m_pimpl
->SetFrame( frame
);
1676 void wxPrintPreview
::SetCanvas(wxPreviewCanvas
*canvas
)
1678 m_pimpl
->SetCanvas( canvas
);
1681 wxFrame
*wxPrintPreview
::GetFrame() const
1683 return m_pimpl
->GetFrame();
1686 wxPreviewCanvas
*wxPrintPreview
::GetCanvas() const
1688 return m_pimpl
->GetCanvas();
1691 bool wxPrintPreview
::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1693 return m_pimpl
->PaintPage( canvas
, dc
);
1696 bool wxPrintPreview
::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1698 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1701 void wxPrintPreview
::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1703 m_pimpl
->AdjustScrollbars( canvas
);
1706 bool wxPrintPreview
::RenderPage(int pageNum
)
1708 return m_pimpl
->RenderPage( pageNum
);
1711 void wxPrintPreview
::SetZoom(int percent
)
1713 m_pimpl
->SetZoom( percent
);
1716 int wxPrintPreview
::GetZoom() const
1718 return m_pimpl
->GetZoom();
1721 wxPrintDialogData
& wxPrintPreview
::GetPrintDialogData()
1723 return m_pimpl
->GetPrintDialogData();
1726 int wxPrintPreview
::GetMaxPage() const
1728 return m_pimpl
->GetMaxPage();
1731 int wxPrintPreview
::GetMinPage() const
1733 return m_pimpl
->GetMinPage();
1736 bool wxPrintPreview
::IsOk() const
1738 return m_pimpl
->Ok();
1741 void wxPrintPreview
::SetOk(bool ok
)
1743 m_pimpl
->SetOk( ok
);
1746 bool wxPrintPreview
::Print(bool interactive
)
1748 return m_pimpl
->Print( interactive
);
1751 void wxPrintPreview
::DetermineScaling()
1753 m_pimpl
->DetermineScaling();
1756 #endif // wxUSE_PRINTING_ARCHITECTURE