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"
50 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
51 #include "wx/msw/printdlg.h"
52 #elif defined(__WXMAC__)
53 #include "wx/mac/printdlg.h"
54 #include "wx/mac/private/print.h"
56 #include "wx/generic/prntdlgg.h"
65 //----------------------------------------------------------------------------
67 //----------------------------------------------------------------------------
69 wxPrintFactory
*wxPrintFactory::m_factory
= NULL
;
71 void wxPrintFactory::SetPrintFactory( wxPrintFactory
*factory
)
73 if (wxPrintFactory::m_factory
)
74 delete wxPrintFactory::m_factory
;
76 wxPrintFactory::m_factory
= factory
;
79 wxPrintFactory
*wxPrintFactory::GetFactory()
81 if (!wxPrintFactory::m_factory
)
82 wxPrintFactory::m_factory
= new wxNativePrintFactory
;
84 return wxPrintFactory::m_factory
;
87 //----------------------------------------------------------------------------
88 // wxNativePrintFactory
89 //----------------------------------------------------------------------------
91 wxPrinterBase
*wxNativePrintFactory::CreatePrinter( wxPrintDialogData
*data
)
93 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
94 return new wxWindowsPrinter( data
);
95 #elif defined(__WXMAC__)
96 return new wxMacPrinter( data
);
97 #elif defined(__WXPM__)
98 return new wxOS2Printer( data
);
100 return new wxPostScriptPrinter( data
);
104 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
105 wxPrintout
*printout
, wxPrintDialogData
*data
)
107 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
108 return new wxWindowsPrintPreview( preview
, printout
, data
);
109 #elif defined(__WXMAC__)
110 return new wxMacPrintPreview( preview
, printout
, data
);
111 #elif defined(__WXPM__)
112 return new wxOS2PrintPreview( preview
, printout
, data
);
114 return new wxPostScriptPrintPreview( preview
, printout
, data
);
118 wxPrintPreviewBase
*wxNativePrintFactory::CreatePrintPreview( wxPrintout
*preview
,
119 wxPrintout
*printout
, wxPrintData
*data
)
121 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
122 return new wxWindowsPrintPreview( preview
, printout
, data
);
123 #elif defined(__WXMAC__)
124 return new wxMacPrintPreview( preview
, printout
, data
);
125 #elif defined(__WXPM__)
126 return new wxOS2PrintPreview( preview
, printout
, data
);
128 return new wxPostScriptPrintPreview( preview
, printout
, data
);
132 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
133 wxPrintDialogData
*data
)
135 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
136 return new wxWindowsPrintDialog( parent
, data
);
137 #elif defined(__WXMAC__)
138 return new wxMacPrintDialog( parent
, data
);
140 return new wxGenericPrintDialog( parent
, data
);
144 wxPrintDialogBase
*wxNativePrintFactory::CreatePrintDialog( wxWindow
*parent
,
147 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
148 return new wxWindowsPrintDialog( parent
, data
);
149 #elif defined(__WXMAC__)
150 return new wxMacPrintDialog( parent
, data
);
152 return new wxGenericPrintDialog( parent
, data
);
156 wxPageSetupDialogBase
*wxNativePrintFactory::CreatePageSetupDialog( wxWindow
*parent
,
157 wxPageSetupDialogData
*data
)
159 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
160 return new wxWindowsPageSetupDialog( parent
, data
);
161 #elif defined(__WXMAC__)
162 return new wxMacPageSetupDialog( parent
, data
);
164 return new wxGenericPageSetupDialog( parent
, data
);
168 bool wxNativePrintFactory::HasPrintSetupDialog()
170 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
172 #elif defined(__WXMAC__)
175 // Only here do we need to provide the print setup
176 // dialog ourselves, the other platforms either have
177 // none, don't make it accessible or let you configure
178 // the printer from the wxPrintDialog anyway.
184 wxDialog
*wxNativePrintFactory::CreatePrintSetupDialog( wxWindow
*parent
,
187 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
191 #elif defined(__WXMAC__)
196 // Only here do we need to provide the print setup
197 // dialog ourselves, the other platforms either have
198 // none, don't make it accessible or let you configure
199 // the printer from the wxPrintDialog anyway.
200 return new wxGenericPrintSetupDialog( parent
, data
);
204 bool wxNativePrintFactory::HasOwnPrintToFile()
206 // Only relevant for PostScript and here the
207 // setup dialog provides no "print to file"
208 // option. In the GNOME setup dialog, the
209 // setup dialog has its own print to file.
213 bool wxNativePrintFactory::HasPrinterLine()
215 // Only relevant for PostScript for now
219 wxString
wxNativePrintFactory::CreatePrinterLine()
221 // Only relevant for PostScript for now
223 // We should query "lpstat -d" here
224 return _("Generic PostScript");
227 bool wxNativePrintFactory::HasStatusLine()
229 // Only relevant for PostScript for now
233 wxString
wxNativePrintFactory::CreateStatusLine()
235 // Only relevant for PostScript for now
237 // We should query "lpstat -r" or "lpstat -p" here
241 wxPrintNativeDataBase
*wxNativePrintFactory::CreatePrintNativeData()
243 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
244 return new wxWindowsPrintNativeData
;
245 #elif defined(__WXMAC__)
246 return new wxMacCarbonPrintData
;
248 return new wxPostScriptPrintNativeData
;
252 //----------------------------------------------------------------------------
253 // wxPrintNativeDataBase
254 //----------------------------------------------------------------------------
256 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase
, wxObject
)
258 wxPrintNativeDataBase::wxPrintNativeDataBase()
263 //----------------------------------------------------------------------------
264 // wxPrintFactoryModule
265 //----------------------------------------------------------------------------
267 class wxPrintFactoryModule
: public wxModule
270 wxPrintFactoryModule() {}
271 bool OnInit() { return true; }
272 void OnExit() { wxPrintFactory::SetPrintFactory( NULL
); }
275 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule
)
278 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule
, wxModule
)
280 //----------------------------------------------------------------------------
282 //----------------------------------------------------------------------------
284 IMPLEMENT_CLASS(wxPrinterBase
, wxObject
)
286 wxPrinterBase::wxPrinterBase(wxPrintDialogData
*data
)
288 m_currentPrintout
= (wxPrintout
*) NULL
;
289 sm_abortWindow
= (wxWindow
*) NULL
;
292 m_printDialogData
= (*data
);
293 sm_lastError
= wxPRINTER_NO_ERROR
;
296 wxWindow
*wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
297 bool wxPrinterBase::sm_abortIt
= false;
298 wxPrinterError
wxPrinterBase::sm_lastError
= wxPRINTER_NO_ERROR
;
300 wxPrinterBase::~wxPrinterBase()
304 wxWindow
*wxPrinterBase::CreateAbortWindow(wxWindow
*parent
, wxPrintout
* printout
)
306 wxPrintAbortDialog
*dialog
= new wxPrintAbortDialog(parent
, _("Printing ") , wxDefaultPosition
, wxDefaultSize
, wxDEFAULT_DIALOG_STYLE
);
308 wxBoxSizer
*button_sizer
= new wxBoxSizer( wxVERTICAL
);
309 button_sizer
->Add( new wxStaticText(dialog
, wxID_ANY
, _("Please wait while printing\n") + printout
->GetTitle() ), 0, wxALL
, 10 );
310 button_sizer
->Add( new wxButton( dialog
, wxID_CANCEL
, wxT("Cancel") ), 0, wxALL
| wxALIGN_CENTER
, 10 );
312 dialog
->SetAutoLayout( true );
313 dialog
->SetSizer( button_sizer
);
315 button_sizer
->Fit(dialog
);
316 button_sizer
->SetSizeHints (dialog
) ;
321 void wxPrinterBase::ReportError(wxWindow
*parent
, wxPrintout
*WXUNUSED(printout
), const wxString
& message
)
323 wxMessageBox(message
, _("Printing Error"), wxOK
, parent
);
326 wxPrintDialogData
& wxPrinterBase::GetPrintDialogData() const
328 return (wxPrintDialogData
&) m_printDialogData
;
331 //----------------------------------------------------------------------------
333 //----------------------------------------------------------------------------
335 IMPLEMENT_CLASS(wxPrinter
, wxPrinterBase
)
337 wxPrinter::wxPrinter(wxPrintDialogData
*data
)
339 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrinter( data
);
342 wxPrinter::~wxPrinter()
347 wxWindow
*wxPrinter::CreateAbortWindow(wxWindow
*parent
, wxPrintout
*printout
)
349 return m_pimpl
->CreateAbortWindow( parent
, printout
);
352 void wxPrinter::ReportError(wxWindow
*parent
, wxPrintout
*printout
, const wxString
& message
)
354 m_pimpl
->ReportError( parent
, printout
, message
);
357 bool wxPrinter::Setup(wxWindow
*parent
)
359 return m_pimpl
->Setup( parent
);
362 bool wxPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
364 return m_pimpl
->Print( parent
, printout
, prompt
);
367 wxDC
* wxPrinter::PrintDialog(wxWindow
*parent
)
369 return m_pimpl
->PrintDialog( parent
);
372 wxPrintDialogData
& wxPrinter::GetPrintDialogData() const
374 return m_pimpl
->GetPrintDialogData();
377 // ---------------------------------------------------------------------------
378 // wxPrintDialogBase: the dialog for printing.
379 // ---------------------------------------------------------------------------
381 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase
, wxDialog
)
383 wxPrintDialogBase::wxPrintDialogBase(wxWindow
*parent
,
385 const wxString
&title
,
389 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Print")) : title
,
394 // ---------------------------------------------------------------------------
395 // wxPrintDialog: the dialog for printing
396 // ---------------------------------------------------------------------------
398 IMPLEMENT_CLASS(wxPrintDialog
, wxObject
)
400 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintDialogData
* data
)
402 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
405 wxPrintDialog::wxPrintDialog(wxWindow
*parent
, wxPrintData
* data
)
407 m_pimpl
= wxPrintFactory::GetFactory()->CreatePrintDialog( parent
, data
);
410 wxPrintDialog::~wxPrintDialog()
415 int wxPrintDialog::ShowModal()
417 return m_pimpl
->ShowModal();
420 wxPrintDialogData
& wxPrintDialog::GetPrintDialogData()
422 return m_pimpl
->GetPrintDialogData();
425 wxPrintData
& wxPrintDialog::GetPrintData()
427 return m_pimpl
->GetPrintData();
430 wxDC
*wxPrintDialog::GetPrintDC()
432 return m_pimpl
->GetPrintDC();
435 // ---------------------------------------------------------------------------
436 // wxPageSetupDialogBase: the page setup dialog
437 // ---------------------------------------------------------------------------
439 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase
, wxDialog
)
441 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow
*parent
,
443 const wxString
&title
,
447 : wxDialog( parent
, id
, title
.empty() ? wxString(_("Page setup")) : title
,
452 // ---------------------------------------------------------------------------
453 // wxPageSetupDialog: the page setup dialog
454 // ---------------------------------------------------------------------------
456 IMPLEMENT_CLASS(wxPageSetupDialog
, wxObject
)
458 wxPageSetupDialog::wxPageSetupDialog(wxWindow
*parent
, wxPageSetupDialogData
*data
)
460 m_pimpl
= wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent
, data
);
463 wxPageSetupDialog::~wxPageSetupDialog()
468 int wxPageSetupDialog::ShowModal()
470 return m_pimpl
->ShowModal();
473 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupDialogData()
475 return m_pimpl
->GetPageSetupDialogData();
479 wxPageSetupDialogData
& wxPageSetupDialog::GetPageSetupData()
481 return m_pimpl
->GetPageSetupDialogData();
484 //----------------------------------------------------------------------------
485 // wxPrintAbortDialog
486 //----------------------------------------------------------------------------
488 BEGIN_EVENT_TABLE(wxPrintAbortDialog
, wxDialog
)
489 EVT_BUTTON(wxID_CANCEL
, wxPrintAbortDialog::OnCancel
)
492 void wxPrintAbortDialog::OnCancel(wxCommandEvent
& WXUNUSED(event
))
494 wxPrinterBase::sm_abortIt
= true;
495 wxPrinterBase::sm_abortWindow
->Show(false);
496 wxPrinterBase::sm_abortWindow
->Close(true);
497 wxPrinterBase::sm_abortWindow
= (wxWindow
*) NULL
;
500 //----------------------------------------------------------------------------
502 //----------------------------------------------------------------------------
504 IMPLEMENT_ABSTRACT_CLASS(wxPrintout
, wxObject
)
506 wxPrintout::wxPrintout(const wxString
& title
)
508 m_printoutTitle
= title
;
509 m_printoutDC
= (wxDC
*) NULL
;
512 m_pageWidthPixels
= 0;
513 m_pageHeightPixels
= 0;
521 wxPrintout::~wxPrintout()
525 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage
), int WXUNUSED(endPage
))
527 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle
);
530 void wxPrintout::OnEndDocument()
535 void wxPrintout::OnBeginPrinting()
539 void wxPrintout::OnEndPrinting()
543 bool wxPrintout::HasPage(int page
)
548 void wxPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *fromPage
, int *toPage
)
556 //----------------------------------------------------------------------------
558 //----------------------------------------------------------------------------
560 IMPLEMENT_CLASS(wxPreviewCanvas
, wxWindow
)
562 BEGIN_EVENT_TABLE(wxPreviewCanvas
, wxScrolledWindow
)
563 EVT_PAINT(wxPreviewCanvas::OnPaint
)
564 EVT_CHAR(wxPreviewCanvas::OnChar
)
565 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged
)
567 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel
)
571 // VZ: the current code doesn't refresh properly without
572 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
573 // really horrible flicker when resizing the preview frame, but without
574 // this style it simply doesn't work correctly at all...
575 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase
*preview
, wxWindow
*parent
,
576 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
577 wxScrolledWindow(parent
, wxID_ANY
, pos
, size
, style
| wxFULL_REPAINT_ON_RESIZE
, name
)
579 m_printPreview
= preview
;
581 // The app workspace colour is always white, but we should have
582 // a contrast with the page.
583 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
585 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
587 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
589 SetScrollbars(10, 10, 100, 100);
592 wxPreviewCanvas::~wxPreviewCanvas()
596 void wxPreviewCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
603 if (!GetUpdateRegion().IsEmpty())
604 dc.SetClippingRegion( GetUpdateRegion() );
610 m_printPreview
->PaintPage(this, dc
);
614 // Responds to colour changes, and passes event on to children.
615 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent
& event
)
618 // The app workspace colour is always white, but we should have
619 // a contrast with the page.
620 wxSystemColour colourIndex
= wxSYS_COLOUR_3DDKSHADOW
;
622 wxSystemColour colourIndex
= wxSYS_COLOUR_APPWORKSPACE
;
624 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex
));
627 // Propagate the event to the non-top-level children
628 wxWindow::OnSysColourChanged(event
);
631 void wxPreviewCanvas::OnChar(wxKeyEvent
&event
)
633 wxPreviewControlBar
* controlBar
= ((wxPreviewFrame
*) GetParent())->GetControlBar();
634 if (event
.GetKeyCode() == WXK_ESCAPE
)
636 ((wxPreviewFrame
*) GetParent())->Close(true);
639 else if (event
.GetKeyCode() == WXK_TAB
)
641 controlBar
->OnGoto();
644 else if (event
.GetKeyCode() == WXK_RETURN
)
646 controlBar
->OnPrint();
650 if (!event
.ControlDown())
656 switch(event
.GetKeyCode())
659 controlBar
->OnNext(); break;
661 controlBar
->OnPrevious(); break;
663 controlBar
->OnFirst(); break;
665 controlBar
->OnLast(); break;
673 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent
& event
)
675 wxPreviewControlBar
*
676 controlBar
= wxStaticCast(GetParent(), wxPreviewFrame
)->GetControlBar();
680 if ( event
.ControlDown() && event
.GetWheelRotation() != 0 )
682 int currentZoom
= controlBar
->GetZoomControl();
685 if ( currentZoom
< 100 )
687 else if ( currentZoom
<= 120 )
692 if ( event
.GetWheelRotation() > 0 )
695 int newZoom
= currentZoom
+ delta
;
700 if ( newZoom
!= currentZoom
)
702 controlBar
->SetZoomControl(newZoom
);
703 m_printPreview
->SetZoom(newZoom
);
713 #endif // wxUSE_MOUSEWHEEL
715 //----------------------------------------------------------------------------
716 // wxPreviewControlBar
717 //----------------------------------------------------------------------------
719 IMPLEMENT_CLASS(wxPreviewControlBar
, wxWindow
)
721 BEGIN_EVENT_TABLE(wxPreviewControlBar
, wxPanel
)
722 EVT_BUTTON(wxID_PREVIEW_CLOSE
, wxPreviewControlBar::OnWindowClose
)
723 EVT_BUTTON(wxID_PREVIEW_PRINT
, wxPreviewControlBar::OnPrintButton
)
724 EVT_BUTTON(wxID_PREVIEW_PREVIOUS
, wxPreviewControlBar::OnPreviousButton
)
725 EVT_BUTTON(wxID_PREVIEW_NEXT
, wxPreviewControlBar::OnNextButton
)
726 EVT_BUTTON(wxID_PREVIEW_FIRST
, wxPreviewControlBar::OnFirstButton
)
727 EVT_BUTTON(wxID_PREVIEW_LAST
, wxPreviewControlBar::OnLastButton
)
728 EVT_BUTTON(wxID_PREVIEW_GOTO
, wxPreviewControlBar::OnGotoButton
)
729 EVT_CHOICE(wxID_PREVIEW_ZOOM
, wxPreviewControlBar::OnZoom
)
730 EVT_PAINT(wxPreviewControlBar::OnPaint
)
733 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase
*preview
, long buttons
,
734 wxWindow
*parent
, const wxPoint
& pos
, const wxSize
& size
,
735 long style
, const wxString
& name
):
736 wxPanel(parent
, wxID_ANY
, pos
, size
, style
, name
)
738 m_printPreview
= preview
;
739 m_closeButton
= (wxButton
*) NULL
;
740 m_nextPageButton
= (wxButton
*) NULL
;
741 m_previousPageButton
= (wxButton
*) NULL
;
742 m_printButton
= (wxButton
*) NULL
;
743 m_zoomControl
= (wxChoice
*) NULL
;
744 m_buttonFlags
= buttons
;
747 wxPreviewControlBar::~wxPreviewControlBar()
751 void wxPreviewControlBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
757 dc
.SetPen(*wxBLACK_PEN
);
758 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
759 dc
.DrawLine( 0, h
-1, w
, h
-1 );
762 void wxPreviewControlBar::OnWindowClose(wxCommandEvent
& WXUNUSED(event
))
764 wxPreviewFrame
*frame
= (wxPreviewFrame
*)GetParent();
768 void wxPreviewControlBar::OnPrint(void)
770 wxPrintPreviewBase
*preview
= GetPrintPreview();
771 preview
->Print(true);
774 void wxPreviewControlBar::OnNext(void)
776 wxPrintPreviewBase
*preview
= GetPrintPreview();
779 int currentPage
= preview
->GetCurrentPage();
780 if ((preview
->GetMaxPage() > 0) &&
781 (currentPage
< preview
->GetMaxPage()) &&
782 preview
->GetPrintout()->HasPage(currentPage
+ 1))
784 preview
->SetCurrentPage(currentPage
+ 1);
789 void wxPreviewControlBar::OnPrevious(void)
791 wxPrintPreviewBase
*preview
= GetPrintPreview();
794 int currentPage
= preview
->GetCurrentPage();
795 if ((preview
->GetMinPage() > 0) &&
796 (currentPage
> preview
->GetMinPage()) &&
797 preview
->GetPrintout()->HasPage(currentPage
- 1))
799 preview
->SetCurrentPage(currentPage
- 1);
804 void wxPreviewControlBar::OnFirst(void)
806 wxPrintPreviewBase
*preview
= GetPrintPreview();
809 int currentPage
= preview
->GetMinPage();
810 if (preview
->GetPrintout()->HasPage(currentPage
))
812 preview
->SetCurrentPage(currentPage
);
817 void wxPreviewControlBar::OnLast(void)
819 wxPrintPreviewBase
*preview
= GetPrintPreview();
822 int currentPage
= preview
->GetMaxPage();
823 if (preview
->GetPrintout()->HasPage(currentPage
))
825 preview
->SetCurrentPage(currentPage
);
830 void wxPreviewControlBar::OnGoto(void)
832 wxPrintPreviewBase
*preview
= GetPrintPreview();
837 if (preview
->GetMinPage() > 0)
842 strPrompt
.Printf( _("Enter a page number between %d and %d:"),
843 preview
->GetMinPage(), preview
->GetMaxPage());
844 strPage
.Printf( wxT("%d"), preview
->GetCurrentPage() );
847 wxGetTextFromUser( strPrompt
, _("Goto Page"), strPage
, GetParent());
849 if ( strPage
.ToLong( ¤tPage
) )
850 if (preview
->GetPrintout()->HasPage(currentPage
))
852 preview
->SetCurrentPage(currentPage
);
858 void wxPreviewControlBar::OnZoom(wxCommandEvent
& WXUNUSED(event
))
860 int zoom
= GetZoomControl();
861 if (GetPrintPreview())
862 GetPrintPreview()->SetZoom(zoom
);
865 void wxPreviewControlBar::CreateButtons()
867 SetSize(0, 0, 400, 40);
869 wxBoxSizer
*item0
= new wxBoxSizer( wxHORIZONTAL
);
871 m_closeButton
= new wxButton( this, wxID_PREVIEW_CLOSE
, _("&Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
872 item0
->Add( m_closeButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
874 if (m_buttonFlags
& wxPREVIEW_PRINT
)
876 m_printButton
= new wxButton( this, wxID_PREVIEW_PRINT
, _("&Print..."), wxDefaultPosition
, wxDefaultSize
, 0 );
877 item0
->Add( m_printButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
880 if (m_buttonFlags
& wxPREVIEW_FIRST
)
882 m_firstPageButton
= new wxButton( this, wxID_PREVIEW_FIRST
, _("|<<"), wxDefaultPosition
, wxDefaultSize
, wxBU_EXACTFIT
);
883 item0
->Add( m_firstPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
886 if (m_buttonFlags
& wxPREVIEW_PREVIOUS
)
888 m_previousPageButton
= new wxButton( this, wxID_PREVIEW_PREVIOUS
, _("<<"), wxDefaultPosition
, wxDefaultSize
, wxBU_EXACTFIT
);
889 item0
->Add( m_previousPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
892 if (m_buttonFlags
& wxPREVIEW_NEXT
)
894 m_nextPageButton
= new wxButton( this, wxID_PREVIEW_NEXT
, _(">>"), wxDefaultPosition
, wxDefaultSize
, wxBU_EXACTFIT
);
895 item0
->Add( m_nextPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
898 if (m_buttonFlags
& wxPREVIEW_LAST
)
900 m_lastPageButton
= new wxButton( this, wxID_PREVIEW_LAST
, _(">>|"), wxDefaultPosition
, wxDefaultSize
, wxBU_EXACTFIT
);
901 item0
->Add( m_lastPageButton
, 0, wxALIGN_CENTRE
|wxRIGHT
|wxTOP
|wxBOTTOM
, 5 );
904 if (m_buttonFlags
& wxPREVIEW_GOTO
)
906 m_gotoPageButton
= new wxButton( this, wxID_PREVIEW_GOTO
, _("&Goto..."), wxDefaultPosition
, wxDefaultSize
, 0 );
907 item0
->Add( m_gotoPageButton
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
910 if (m_buttonFlags
& wxPREVIEW_ZOOM
)
914 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
915 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
916 wxT("120%"), wxT("150%"), wxT("200%")
918 int n
= WXSIZEOF(choices
);
920 m_zoomControl
= new wxChoice( this, wxID_PREVIEW_ZOOM
, wxDefaultPosition
, wxSize(70,wxDefaultCoord
), n
, choices
, 0 );
921 item0
->Add( m_zoomControl
, 0, wxALIGN_CENTRE
|wxALL
, 5 );
922 SetZoomControl(m_printPreview
->GetZoom());
929 void wxPreviewControlBar::SetZoomControl(int zoom
)
933 int n
, count
= m_zoomControl
->GetCount();
935 for (n
=0; n
<count
; n
++)
937 if (m_zoomControl
->GetString(n
).BeforeFirst(wxT('%')).ToLong(&val
) &&
940 m_zoomControl
->SetSelection(n
);
945 m_zoomControl
->SetSelection(count
-1);
949 int wxPreviewControlBar::GetZoomControl()
951 if (m_zoomControl
&& (m_zoomControl
->GetStringSelection() != wxEmptyString
))
954 if (m_zoomControl
->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val
))
966 IMPLEMENT_CLASS(wxPreviewFrame
, wxFrame
)
968 BEGIN_EVENT_TABLE(wxPreviewFrame
, wxFrame
)
969 EVT_CLOSE(wxPreviewFrame::OnCloseWindow
)
972 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase
*preview
, wxWindow
*parent
, const wxString
& title
,
973 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
974 wxFrame(parent
, wxID_ANY
, title
, pos
, size
, style
, name
)
976 m_printPreview
= preview
;
978 m_previewCanvas
= NULL
;
979 m_windowDisabler
= NULL
;
981 // Give the application icon
983 wxFrame
* topFrame
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
);
985 SetIcon(topFrame
->GetIcon());
989 wxPreviewFrame::~wxPreviewFrame()
993 void wxPreviewFrame::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
))
995 if (m_windowDisabler
)
996 delete m_windowDisabler
;
998 // Need to delete the printout and the print preview
999 wxPrintout
*printout
= m_printPreview
->GetPrintout();
1003 m_printPreview
->SetPrintout(NULL
);
1004 m_printPreview
->SetCanvas(NULL
);
1005 m_printPreview
->SetFrame(NULL
);
1007 delete m_printPreview
;
1012 void wxPreviewFrame::Initialize()
1020 m_printPreview
->SetCanvas(m_previewCanvas
);
1021 m_printPreview
->SetFrame(this);
1023 wxBoxSizer
*item0
= new wxBoxSizer( wxVERTICAL
);
1025 item0
->Add( m_controlBar
, 0, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1026 item0
->Add( m_previewCanvas
, 1, wxGROW
|wxALIGN_CENTER_VERTICAL
, 5 );
1028 SetAutoLayout( true );
1031 m_windowDisabler
= new wxWindowDisabler(this);
1035 m_printPreview
->AdjustScrollbars(m_previewCanvas
);
1036 m_previewCanvas
->SetFocus();
1037 m_controlBar
->SetFocus();
1040 void wxPreviewFrame::CreateCanvas()
1042 m_previewCanvas
= new wxPreviewCanvas(m_printPreview
, this);
1045 void wxPreviewFrame::CreateControlBar()
1047 long buttons
= wxPREVIEW_DEFAULT
;
1048 if (m_printPreview
->GetPrintoutForPrinting())
1049 buttons
|= wxPREVIEW_PRINT
;
1051 m_controlBar
= new wxPreviewControlBar(m_printPreview
, buttons
, this, wxPoint(0,0), wxSize(400, 40));
1052 m_controlBar
->CreateButtons();
1059 IMPLEMENT_CLASS(wxPrintPreviewBase
, wxObject
)
1061 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1062 wxPrintout
*printoutForPrinting
,
1066 m_printDialogData
= (*data
);
1068 Init(printout
, printoutForPrinting
);
1071 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout
*printout
,
1072 wxPrintout
*printoutForPrinting
,
1073 wxPrintDialogData
*data
)
1076 m_printDialogData
= (*data
);
1078 Init(printout
, printoutForPrinting
);
1081 void wxPrintPreviewBase::Init(wxPrintout
*printout
,
1082 wxPrintout
*printoutForPrinting
)
1085 m_previewPrintout
= printout
;
1086 if (m_previewPrintout
)
1087 m_previewPrintout
->SetIsPreview(true);
1089 m_printPrintout
= printoutForPrinting
;
1091 m_previewCanvas
= NULL
;
1092 m_previewFrame
= NULL
;
1093 m_previewBitmap
= NULL
;
1100 m_printingPrepared
= false;
1105 wxPrintPreviewBase::~wxPrintPreviewBase()
1107 if (m_previewPrintout
)
1108 delete m_previewPrintout
;
1109 if (m_previewBitmap
)
1110 delete m_previewBitmap
;
1111 if (m_printPrintout
)
1112 delete m_printPrintout
;
1115 bool wxPrintPreviewBase::SetCurrentPage(int pageNum
)
1117 if (m_currentPage
== pageNum
)
1120 m_currentPage
= pageNum
;
1121 if (m_previewBitmap
)
1123 delete m_previewBitmap
;
1124 m_previewBitmap
= NULL
;
1127 if (m_previewCanvas
)
1129 AdjustScrollbars(m_previewCanvas
);
1131 if (!RenderPage(pageNum
))
1133 m_previewCanvas
->Refresh();
1134 m_previewCanvas
->SetFocus();
1139 int wxPrintPreviewBase::GetCurrentPage() const
1140 { return m_currentPage
; }
1141 void wxPrintPreviewBase::SetPrintout(wxPrintout
*printout
)
1142 { m_previewPrintout
= printout
; }
1143 wxPrintout
*wxPrintPreviewBase::GetPrintout() const
1144 { return m_previewPrintout
; }
1145 wxPrintout
*wxPrintPreviewBase::GetPrintoutForPrinting() const
1146 { return m_printPrintout
; }
1147 void wxPrintPreviewBase::SetFrame(wxFrame
*frame
)
1148 { m_previewFrame
= frame
; }
1149 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas
*canvas
)
1150 { m_previewCanvas
= canvas
; }
1151 wxFrame
*wxPrintPreviewBase::GetFrame() const
1152 { return m_previewFrame
; }
1153 wxPreviewCanvas
*wxPrintPreviewBase::GetCanvas() const
1154 { return m_previewCanvas
; }
1156 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1158 DrawBlankPage(canvas
, dc
);
1160 if (!m_previewBitmap
)
1161 if (!RenderPage(m_currentPage
))
1164 if (!m_previewBitmap
)
1170 int canvasWidth
, canvasHeight
;
1171 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1173 double zoomScale
= ((float)m_currentZoom
/(float)100);
1174 double actualWidth
= (zoomScale
*m_pageWidth
*m_previewScale
);
1175 // float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
1177 int x
= (int) ((canvasWidth
- actualWidth
)/2.0);
1178 if (x
< m_leftMargin
)
1180 int y
= m_topMargin
;
1183 temp_dc
.SelectObject(*m_previewBitmap
);
1185 dc
.Blit(x
, y
, m_previewBitmap
->GetWidth(), m_previewBitmap
->GetHeight(), &temp_dc
, 0, 0);
1187 temp_dc
.SelectObject(wxNullBitmap
);
1192 // Adjusts the scrollbars for the current scale
1193 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1198 int canvasWidth
, canvasHeight
;
1199 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1201 double zoomScale
= ((float)m_currentZoom
/(float)100);
1202 double actualWidth
= (zoomScale
*m_pageWidth
*m_previewScale
);
1203 double actualHeight
= (zoomScale
*m_pageHeight
*m_previewScale
);
1205 // Set the scrollbars appropriately
1206 int totalWidth
= (int)(actualWidth
+ 2*m_leftMargin
);
1207 int totalHeight
= (int)(actualHeight
+ 2*m_topMargin
);
1208 int scrollUnitsX
= totalWidth
/10;
1209 int scrollUnitsY
= totalHeight
/10;
1210 wxSize virtualSize
= canvas
->GetVirtualSize();
1211 if (virtualSize
.GetWidth() != totalWidth
|| virtualSize
.GetHeight() != totalHeight
)
1212 canvas
->SetScrollbars(10, 10, scrollUnitsX
, scrollUnitsY
, 0, 0, true);
1215 bool wxPrintPreviewBase::RenderPage(int pageNum
)
1219 int canvasWidth
, canvasHeight
;
1221 if (!m_previewCanvas
)
1223 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1227 m_previewCanvas
->GetSize(&canvasWidth
, &canvasHeight
);
1229 double zoomScale
= (m_currentZoom
/100.0);
1230 int actualWidth
= (int)(zoomScale
*m_pageWidth
*m_previewScale
);
1231 int actualHeight
= (int)(zoomScale
*m_pageHeight
*m_previewScale
);
1233 if (!m_previewBitmap
)
1235 m_previewBitmap
= new wxBitmap((int)actualWidth
, (int)actualHeight
);
1236 if (!m_previewBitmap
|| !m_previewBitmap
->Ok())
1238 if (m_previewBitmap
) {
1239 delete m_previewBitmap
;
1240 m_previewBitmap
= NULL
;
1242 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK
);
1247 wxMemoryDC memoryDC
;
1248 memoryDC
.SelectObject(*m_previewBitmap
);
1252 m_previewPrintout
->SetDC(&memoryDC
);
1253 m_previewPrintout
->SetPageSizePixels(m_pageWidth
, m_pageHeight
);
1255 // Need to delay OnPreparePrinting until here, so we have enough information.
1256 if (!m_printingPrepared
)
1258 m_previewPrintout
->OnPreparePrinting();
1260 m_previewPrintout
->GetPageInfo(&m_minPage
, &m_maxPage
, &selFrom
, &selTo
);
1261 m_printingPrepared
= true;
1264 m_previewPrintout
->OnBeginPrinting();
1266 if (!m_previewPrintout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
1268 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK
);
1270 memoryDC
.SelectObject(wxNullBitmap
);
1272 delete m_previewBitmap
;
1273 m_previewBitmap
= NULL
;
1277 m_previewPrintout
->OnPrintPage(pageNum
);
1278 m_previewPrintout
->OnEndDocument();
1279 m_previewPrintout
->OnEndPrinting();
1281 m_previewPrintout
->SetDC(NULL
);
1283 memoryDC
.SelectObject(wxNullBitmap
);
1288 status
= wxString::Format(_("Page %d of %d"), pageNum
, m_maxPage
);
1290 status
= wxString::Format(_("Page %d"), pageNum
);
1293 m_previewFrame
->SetStatusText(status
);
1300 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1302 int canvasWidth
, canvasHeight
;
1303 canvas
->GetSize(&canvasWidth
, &canvasHeight
);
1305 float zoomScale
= (float)((float)m_currentZoom
/(float)100);
1306 float actualWidth
= zoomScale
*m_pageWidth
*m_previewScale
;
1307 float actualHeight
= zoomScale
*m_pageHeight
*m_previewScale
;
1309 float x
= (float)((canvasWidth
- actualWidth
)/2.0);
1310 if (x
< m_leftMargin
)
1311 x
= (float)m_leftMargin
;
1312 float y
= (float)m_topMargin
;
1314 // Draw shadow, allowing for 1-pixel border AROUND the actual page
1315 int shadowOffset
= 4;
1316 dc
.SetPen(*wxBLACK_PEN
);
1317 dc
.SetBrush(*wxBLACK_BRUSH
);
1319 dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
1321 dc
.DrawRectangle((int)(x
+ shadowOffset
), (int)(y
+ actualHeight
+1), (int)(actualWidth
), shadowOffset
);
1322 dc
.DrawRectangle((int)(x
+ actualWidth
), (int)(y
+ shadowOffset
), shadowOffset
, (int)(actualHeight
));
1324 // Draw blank page allowing for 1-pixel border AROUND the actual page
1325 dc
.SetPen(*wxBLACK_PEN
);
1326 dc
.SetBrush(*wxWHITE_BRUSH
);
1329 wxRegion update_region = canvas->GetUpdateRegion();
1330 wxRect r = update_region.GetBox();
1332 printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
1335 dc
.DrawRectangle((int)(x
-2), (int)(y
-1), (int)(actualWidth
+3), (int)(actualHeight
+2));
1340 void wxPrintPreviewBase::SetZoom(int percent
)
1342 if (m_currentZoom
== percent
)
1345 m_currentZoom
= percent
;
1346 if (m_previewBitmap
)
1348 delete m_previewBitmap
;
1349 m_previewBitmap
= NULL
;
1352 if (m_previewCanvas
)
1354 AdjustScrollbars(m_previewCanvas
);
1355 RenderPage(m_currentPage
);
1356 ((wxScrolledWindow
*) m_previewCanvas
)->Scroll(0, 0);
1357 m_previewCanvas
->ClearBackground();
1358 m_previewCanvas
->Refresh();
1359 m_previewCanvas
->SetFocus();
1363 wxPrintDialogData
& wxPrintPreviewBase::GetPrintDialogData()
1365 return m_printDialogData
;
1368 int wxPrintPreviewBase::GetZoom() const
1369 { return m_currentZoom
; }
1370 int wxPrintPreviewBase::GetMaxPage() const
1371 { return m_maxPage
; }
1372 int wxPrintPreviewBase::GetMinPage() const
1373 { return m_minPage
; }
1374 bool wxPrintPreviewBase::Ok() const
1376 void wxPrintPreviewBase::SetOk(bool ok
)
1378 //----------------------------------------------------------------------------
1380 //----------------------------------------------------------------------------
1382 IMPLEMENT_CLASS(wxPrintPreview
, wxPrintPreviewBase
)
1384 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1385 wxPrintout
*printoutForPrinting
,
1386 wxPrintDialogData
*data
) :
1387 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1389 m_pimpl
= wxPrintFactory::GetFactory()->
1390 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1393 wxPrintPreview::wxPrintPreview(wxPrintout
*printout
,
1394 wxPrintout
*printoutForPrinting
,
1395 wxPrintData
*data
) :
1396 wxPrintPreviewBase( printout
, printoutForPrinting
, data
)
1398 m_pimpl
= wxPrintFactory::GetFactory()->
1399 CreatePrintPreview( printout
, printoutForPrinting
, data
);
1402 wxPrintPreview::~wxPrintPreview()
1406 // don't delete twice
1407 m_printPrintout
= NULL
;
1408 m_previewPrintout
= NULL
;
1409 m_previewBitmap
= NULL
;
1412 bool wxPrintPreview::SetCurrentPage(int pageNum
)
1414 return m_pimpl
->SetCurrentPage( pageNum
);
1417 int wxPrintPreview::GetCurrentPage() const
1419 return m_pimpl
->GetCurrentPage();
1422 void wxPrintPreview::SetPrintout(wxPrintout
*printout
)
1424 m_pimpl
->SetPrintout( printout
);
1427 wxPrintout
*wxPrintPreview::GetPrintout() const
1429 return m_pimpl
->GetPrintout();
1432 wxPrintout
*wxPrintPreview::GetPrintoutForPrinting() const
1434 return m_pimpl
->GetPrintoutForPrinting();
1437 void wxPrintPreview::SetFrame(wxFrame
*frame
)
1439 m_pimpl
->SetFrame( frame
);
1442 void wxPrintPreview::SetCanvas(wxPreviewCanvas
*canvas
)
1444 m_pimpl
->SetCanvas( canvas
);
1447 wxFrame
*wxPrintPreview::GetFrame() const
1449 return m_pimpl
->GetFrame();
1452 wxPreviewCanvas
*wxPrintPreview::GetCanvas() const
1454 return m_pimpl
->GetCanvas();
1457 bool wxPrintPreview::PaintPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1459 return m_pimpl
->PaintPage( canvas
, dc
);
1462 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas
*canvas
, wxDC
& dc
)
1464 return m_pimpl
->DrawBlankPage( canvas
, dc
);
1467 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas
*canvas
)
1469 m_pimpl
->AdjustScrollbars( canvas
);
1472 bool wxPrintPreview::RenderPage(int pageNum
)
1474 return m_pimpl
->RenderPage( pageNum
);
1477 void wxPrintPreview::SetZoom(int percent
)
1479 m_pimpl
->SetZoom( percent
);
1482 int wxPrintPreview::GetZoom() const
1484 return m_pimpl
->GetZoom();
1487 wxPrintDialogData
& wxPrintPreview::GetPrintDialogData()
1489 return m_pimpl
->GetPrintDialogData();
1492 int wxPrintPreview::GetMaxPage() const
1494 return m_pimpl
->GetMaxPage();
1497 int wxPrintPreview::GetMinPage() const
1499 return m_pimpl
->GetMinPage();
1502 bool wxPrintPreview::Ok() const
1504 return m_pimpl
->Ok();
1507 void wxPrintPreview::SetOk(bool ok
)
1509 m_pimpl
->SetOk( ok
);
1512 bool wxPrintPreview::Print(bool interactive
)
1514 return m_pimpl
->Print( interactive
);
1517 void wxPrintPreview::DetermineScaling()
1519 m_pimpl
->DetermineScaling();
1522 #endif // wxUSE_PRINTING_ARCHITECTURE