Added stubs for OS/2 to new printing system.
[wxWidgets.git] / src / common / prntbase.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: prntbase.cpp
3 // Purpose: Printing framework base class implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "prntbase.h"
14 #pragma implementation "printdlg.h"
15 #endif
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #include "wx/defs.h"
25
26 #if wxUSE_PRINTING_ARCHITECTURE
27
28 #ifndef WX_PRECOMP
29 #include "wx/utils.h"
30 #include "wx/dc.h"
31 #include "wx/app.h"
32 #include "wx/msgdlg.h"
33 #include "wx/layout.h"
34 #include "wx/choice.h"
35 #include "wx/button.h"
36 #include "wx/settings.h"
37 #include "wx/dcmemory.h"
38 #include "wx/stattext.h"
39 #include "wx/intl.h"
40 #include "wx/textdlg.h"
41 #include "wx/sizer.h"
42 #endif // !WX_PRECOMP
43
44 #include "wx/prntbase.h"
45 #include "wx/dcprint.h"
46 #include "wx/printdlg.h"
47 #include "wx/print.h"
48 #include "wx/module.h"
49
50 #include <stdlib.h>
51 #include <string.h>
52
53 #ifdef __WXMSW__
54 #include "wx/msw/private.h"
55 #include <commdlg.h>
56
57 #ifndef __WIN32__
58 #include <print.h>
59 #endif
60 #endif // __WXMSW__
61
62 IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
63
64 //----------------------------------------------------------------------------
65 // wxPrintFactory
66 //----------------------------------------------------------------------------
67
68 wxPrintFactory *wxPrintFactory::m_factory = NULL;
69
70 void wxPrintFactory::SetPrintFactory( wxPrintFactory *factory )
71 {
72 if (wxPrintFactory::m_factory)
73 delete wxPrintFactory::m_factory;
74
75 wxPrintFactory::m_factory = factory;
76 }
77
78 wxPrintFactory *wxPrintFactory::GetFactory()
79 {
80 if (!wxPrintFactory::m_factory)
81 wxPrintFactory::m_factory = new wxNativePrintFactory;
82
83 return wxPrintFactory::m_factory;
84 }
85
86 //----------------------------------------------------------------------------
87 // wxNativePrintFactory
88 //----------------------------------------------------------------------------
89
90 wxPrinterBase *wxNativePrintFactory::CreatePrinter( wxPrintDialogData *data )
91 {
92 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
93 return new wxWindowsPrinter( data );
94 #elif defined(__WXMAC__)
95 return new wxMacPrinter( data );
96 #elif defined(__WXPM__)
97 return new wxOS2Printer( data );
98 #else
99 return new wxPostScriptPrinter( data );
100 #endif
101 };
102
103 wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
104 wxPrintout *printout, wxPrintDialogData *data )
105 {
106 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
107 return new wxWindowsPrintPreview( preview, printout, data );
108 #elif defined(__WXMAC__)
109 return new wxMacPrintPreview( preview, printout, data );
110 #elif defined(__WXPM__)
111 return new wxOS2PrintPreview( preview, printout, data );
112 #else
113 return new wxPostScriptPrintPreview( preview, printout, data );
114 #endif
115 }
116
117 wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
118 wxPrintout *printout, wxPrintData *data )
119 {
120 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
121 return new wxWindowsPrintPreview( preview, printout, data );
122 #elif defined(__WXMAC__)
123 return new wxMacPrintPreview( preview, printout, data );
124 #elif defined(__WXPM__)
125 return new wxOS2PrintPreview( preview, printout, data );
126 #else
127 return new wxPostScriptPrintPreview( preview, printout, data );
128 #endif
129 }
130
131 wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
132 wxPrintDialogData *data )
133 {
134 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
135 return new wxWindowsPrintDialog( parent, data );
136 #elif defined(__WXMAC__)
137 return new wxMacPrintDialog( parent, data );
138 #else
139 return new wxGenericPrintDialog( parent, data );
140 #endif
141 }
142
143 wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
144 wxPrintData *data )
145 {
146 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
147 return new wxWindowsPrintDialog( parent, data );
148 #elif defined(__WXMAC__)
149 return new wxMacPrintDialog( parent, data );
150 #else
151 return new wxGenericPrintDialog( parent, data );
152 #endif
153 }
154
155 wxPrintNativeDataBase *wxNativePrintFactory::CreatePrintNativeData()
156 {
157 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
158 return new wxWindowsPrintNativeData;
159 #elif defined(__WXMAC__)
160 return new wxMacPrintNativeData;
161 #else
162 return new wxPostScriptPrintNativeData;
163 #endif
164 }
165
166 //----------------------------------------------------------------------------
167 // wxPrintNativeDataBase
168 //----------------------------------------------------------------------------
169
170 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase, wxObject)
171
172 wxPrintNativeDataBase::wxPrintNativeDataBase()
173 {
174 m_ref = 1;
175 }
176
177 //----------------------------------------------------------------------------
178 // wxPrinterBase
179 //----------------------------------------------------------------------------
180
181 IMPLEMENT_CLASS(wxPrinterBase, wxObject)
182
183 wxPrinterBase::wxPrinterBase(wxPrintDialogData *data)
184 {
185 m_currentPrintout = (wxPrintout *) NULL;
186 sm_abortWindow = (wxWindow *) NULL;
187 sm_abortIt = false;
188 if (data)
189 m_printDialogData = (*data);
190 sm_lastError = wxPRINTER_NO_ERROR;
191 }
192
193 wxWindow *wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
194 bool wxPrinterBase::sm_abortIt = false;
195 wxPrinterError wxPrinterBase::sm_lastError = wxPRINTER_NO_ERROR;
196
197 wxPrinterBase::~wxPrinterBase()
198 {
199 }
200
201 wxWindow *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout * printout)
202 {
203 wxPrintAbortDialog *dialog = new wxPrintAbortDialog(parent, _("Printing ") , wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
204
205 wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
206 button_sizer->Add( new wxStaticText(dialog, wxID_ANY, _("Please wait while printing\n") + printout->GetTitle() ), 0, wxALL, 10 );
207 button_sizer->Add( new wxButton( dialog, wxID_CANCEL, wxT("Cancel") ), 0, wxALL | wxALIGN_CENTER, 10 );
208
209 dialog->SetAutoLayout( true );
210 dialog->SetSizer( button_sizer );
211
212 button_sizer->Fit(dialog);
213 button_sizer->SetSizeHints (dialog) ;
214
215 return dialog;
216 }
217
218 void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), const wxString& message)
219 {
220 wxMessageBox(message, _("Printing Error"), wxOK, parent);
221 }
222
223 wxPrintDialogData& wxPrinterBase::GetPrintDialogData() const
224 {
225 return (wxPrintDialogData&) m_printDialogData;
226 }
227
228 //----------------------------------------------------------------------------
229 // wxPrinter
230 //----------------------------------------------------------------------------
231
232 IMPLEMENT_CLASS(wxPrinter, wxPrinterBase)
233
234 wxPrinter::wxPrinter(wxPrintDialogData *data)
235 {
236 m_pimpl = wxPrintFactory::GetFactory()->CreatePrinter( data );
237 }
238
239 wxPrinter::~wxPrinter()
240 {
241 delete m_pimpl;
242 }
243
244 wxWindow *wxPrinter::CreateAbortWindow(wxWindow *parent, wxPrintout *printout)
245 {
246 return m_pimpl->CreateAbortWindow( parent, printout );
247 }
248
249 void wxPrinter::ReportError(wxWindow *parent, wxPrintout *printout, const wxString& message)
250 {
251 m_pimpl->ReportError( parent, printout, message );
252 }
253
254 bool wxPrinter::Setup(wxWindow *parent)
255 {
256 return m_pimpl->Setup( parent );
257 }
258
259 bool wxPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
260 {
261 return m_pimpl->Print( parent, printout, prompt );
262 }
263
264 wxDC* wxPrinter::PrintDialog(wxWindow *parent)
265 {
266 return m_pimpl->PrintDialog( parent );
267 }
268
269 wxPrintDialogData& wxPrinter::GetPrintDialogData() const
270 {
271 return m_pimpl->GetPrintDialogData();
272 }
273
274 // ---------------------------------------------------------------------------
275 // wxPrintDialogBase: the common dialog for printing.
276 // ---------------------------------------------------------------------------
277
278 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase, wxObject)
279
280 wxPrintDialogBase::wxPrintDialogBase(wxWindow *parent, wxWindowID id,
281 const wxString &title, const wxPoint &pos, const wxSize &size, long style ) :
282 wxDialog( parent, id, title, pos, size, style )
283 {
284 }
285
286 // ---------------------------------------------------------------------------
287 // wxPrintDialog: the common dialog for printing.
288 // ---------------------------------------------------------------------------
289
290 IMPLEMENT_CLASS(wxPrintDialog, wxObject)
291
292 wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintDialogData* data)
293 {
294 m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
295 }
296
297 wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintData* data)
298 {
299 m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
300 }
301
302 wxPrintDialog::~wxPrintDialog()
303 {
304 delete m_pimpl;
305 }
306
307 int wxPrintDialog::ShowModal()
308 {
309 return m_pimpl->ShowModal();
310 }
311
312 wxPrintDialogData& wxPrintDialog::GetPrintDialogData()
313 {
314 return m_pimpl->GetPrintDialogData();
315 }
316
317 wxPrintData& wxPrintDialog::GetPrintData()
318 {
319 return m_pimpl->GetPrintData();
320 }
321 wxDC *wxPrintDialog::GetPrintDC()
322 {
323 return m_pimpl->GetPrintDC();
324 }
325
326 //----------------------------------------------------------------------------
327 // wxPrintAbortDialog
328 //----------------------------------------------------------------------------
329
330 BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
331 EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
332 END_EVENT_TABLE()
333
334 void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
335 {
336 wxPrinterBase::sm_abortIt = true;
337 wxPrinterBase::sm_abortWindow->Show(false);
338 wxPrinterBase::sm_abortWindow->Close(true);
339 wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
340 }
341
342 //----------------------------------------------------------------------------
343 // wxPrintout
344 //----------------------------------------------------------------------------
345
346 IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
347
348 wxPrintout::wxPrintout(const wxString& title)
349 {
350 m_printoutTitle = title ;
351 m_printoutDC = (wxDC *) NULL;
352 m_pageWidthMM = 0;
353 m_pageHeightMM = 0;
354 m_pageWidthPixels = 0;
355 m_pageHeightPixels = 0;
356 m_PPIScreenX = 0;
357 m_PPIScreenY = 0;
358 m_PPIPrinterX = 0;
359 m_PPIPrinterY = 0;
360 m_isPreview = false;
361 }
362
363 wxPrintout::~wxPrintout()
364 {
365 }
366
367 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
368 {
369 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle);
370 }
371
372 void wxPrintout::OnEndDocument()
373 {
374 GetDC()->EndDoc();
375 }
376
377 void wxPrintout::OnBeginPrinting()
378 {
379 }
380
381 void wxPrintout::OnEndPrinting()
382 {
383 }
384
385 bool wxPrintout::HasPage(int page)
386 {
387 return (page == 1);
388 }
389
390 void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
391 {
392 *minPage = 1;
393 *maxPage = 32000;
394 *fromPage = 1;
395 *toPage = 1;
396 }
397
398 //----------------------------------------------------------------------------
399 // wxPreviewCanvas
400 //----------------------------------------------------------------------------
401
402 IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
403
404 BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
405 EVT_PAINT(wxPreviewCanvas::OnPaint)
406 EVT_CHAR(wxPreviewCanvas::OnChar)
407 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
408 END_EVENT_TABLE()
409
410 // VZ: the current code doesn't refresh properly without
411 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
412 // really horrible flicker when resizing the preview frame, but without
413 // this style it simply doesn't work correctly at all...
414 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
415 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
416 wxScrolledWindow(parent, wxID_ANY, pos, size, style | wxFULL_REPAINT_ON_RESIZE, name)
417 {
418 m_printPreview = preview;
419 #ifdef __WXMAC__
420 // The app workspace colour is always white, but we should have
421 // a contrast with the page.
422 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
423 #else
424 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
425 #endif
426 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
427
428 SetScrollbars(10, 10, 100, 100);
429 }
430
431 wxPreviewCanvas::~wxPreviewCanvas()
432 {
433 }
434
435 void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
436 {
437 wxPaintDC dc(this);
438 PrepareDC( dc );
439
440 /*
441 #ifdef __WXGTK__
442 if (!GetUpdateRegion().IsEmpty())
443 dc.SetClippingRegion( GetUpdateRegion() );
444 #endif
445 */
446
447 if (m_printPreview)
448 {
449 m_printPreview->PaintPage(this, dc);
450 }
451 }
452
453 // Responds to colour changes, and passes event on to children.
454 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
455 {
456 #ifdef __WXMAC__
457 // The app workspace colour is always white, but we should have
458 // a contrast with the page.
459 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
460 #else
461 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
462 #endif
463 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
464 Refresh();
465
466 // Propagate the event to the non-top-level children
467 wxWindow::OnSysColourChanged(event);
468 }
469
470 void wxPreviewCanvas::OnChar(wxKeyEvent &event)
471 {
472 wxPreviewControlBar* controlBar = ((wxPreviewFrame*) GetParent())->GetControlBar();
473 if (event.GetKeyCode() == WXK_ESCAPE)
474 {
475 ((wxPreviewFrame*) GetParent())->Close(true);
476 return;
477 }
478 else if (event.GetKeyCode() == WXK_TAB)
479 {
480 controlBar->OnGoto();
481 return;
482 }
483 else if (event.GetKeyCode() == WXK_RETURN)
484 {
485 controlBar->OnPrint();
486 return;
487 }
488
489 if (!event.ControlDown())
490 {
491 event.Skip();
492 return;
493 }
494
495 switch(event.GetKeyCode())
496 {
497 case WXK_NEXT:
498 controlBar->OnNext(); break;
499 case WXK_PRIOR:
500 controlBar->OnPrevious(); break;
501 case WXK_HOME:
502 controlBar->OnFirst(); break;
503 case WXK_END:
504 controlBar->OnLast(); break;
505 default:
506 event.Skip();
507 }
508 }
509
510 //----------------------------------------------------------------------------
511 // wxPreviewControlBar
512 //----------------------------------------------------------------------------
513
514 IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
515
516 BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
517 EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
518 EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrintButton)
519 EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
520 EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
521 EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
522 EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
523 EVT_BUTTON(wxID_PREVIEW_GOTO, wxPreviewControlBar::OnGotoButton)
524 EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoom)
525 EVT_PAINT(wxPreviewControlBar::OnPaint)
526 END_EVENT_TABLE()
527
528 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
529 wxWindow *parent, const wxPoint& pos, const wxSize& size,
530 long style, const wxString& name):
531 wxPanel(parent, wxID_ANY, pos, size, style, name)
532 {
533 m_printPreview = preview;
534 m_closeButton = (wxButton *) NULL;
535 m_nextPageButton = (wxButton *) NULL;
536 m_previousPageButton = (wxButton *) NULL;
537 m_printButton = (wxButton *) NULL;
538 m_zoomControl = (wxChoice *) NULL;
539 m_buttonFlags = buttons;
540 }
541
542 wxPreviewControlBar::~wxPreviewControlBar()
543 {
544 }
545
546 void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
547 {
548 wxPaintDC dc(this);
549
550 int w, h;
551 GetSize(&w, &h);
552 dc.SetPen(*wxBLACK_PEN);
553 dc.SetBrush(*wxTRANSPARENT_BRUSH);
554 dc.DrawLine( 0, h-1, w, h-1 );
555 }
556
557 void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
558 {
559 wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
560 frame->Close(true);
561 }
562
563 void wxPreviewControlBar::OnPrint(void)
564 {
565 wxPrintPreviewBase *preview = GetPrintPreview();
566 preview->Print(true);
567 }
568
569 void wxPreviewControlBar::OnNext(void)
570 {
571 wxPrintPreviewBase *preview = GetPrintPreview();
572 if (preview)
573 {
574 int currentPage = preview->GetCurrentPage();
575 if ((preview->GetMaxPage() > 0) &&
576 (currentPage < preview->GetMaxPage()) &&
577 preview->GetPrintout()->HasPage(currentPage + 1))
578 {
579 preview->SetCurrentPage(currentPage + 1);
580 }
581 }
582 }
583
584 void wxPreviewControlBar::OnPrevious(void)
585 {
586 wxPrintPreviewBase *preview = GetPrintPreview();
587 if (preview)
588 {
589 int currentPage = preview->GetCurrentPage();
590 if ((preview->GetMinPage() > 0) &&
591 (currentPage > preview->GetMinPage()) &&
592 preview->GetPrintout()->HasPage(currentPage - 1))
593 {
594 preview->SetCurrentPage(currentPage - 1);
595 }
596 }
597 }
598
599 void wxPreviewControlBar::OnFirst(void)
600 {
601 wxPrintPreviewBase *preview = GetPrintPreview();
602 if (preview)
603 {
604 int currentPage = preview->GetMinPage();
605 if (preview->GetPrintout()->HasPage(currentPage))
606 {
607 preview->SetCurrentPage(currentPage);
608 }
609 }
610 }
611
612 void wxPreviewControlBar::OnLast(void)
613 {
614 wxPrintPreviewBase *preview = GetPrintPreview();
615 if (preview)
616 {
617 int currentPage = preview->GetMaxPage();
618 if (preview->GetPrintout()->HasPage(currentPage))
619 {
620 preview->SetCurrentPage(currentPage);
621 }
622 }
623 }
624
625 void wxPreviewControlBar::OnGoto(void)
626 {
627 wxPrintPreviewBase *preview = GetPrintPreview();
628 if (preview)
629 {
630 long currentPage;
631
632 if (preview->GetMinPage() > 0)
633 {
634 wxString strPrompt;
635 wxString strPage;
636
637 strPrompt.Printf( _("Enter a page number between %d and %d:"),
638 preview->GetMinPage(), preview->GetMaxPage());
639 strPage.Printf( wxT("%d"), preview->GetCurrentPage() );
640
641 strPage =
642 wxGetTextFromUser( strPrompt, _("Goto Page"), strPage, GetParent());
643
644 if ( strPage.ToLong( &currentPage ) )
645 if (preview->GetPrintout()->HasPage(currentPage))
646 {
647 preview->SetCurrentPage(currentPage);
648 }
649 }
650 }
651 }
652
653 void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
654 {
655 int zoom = GetZoomControl();
656 if (GetPrintPreview())
657 GetPrintPreview()->SetZoom(zoom);
658 }
659
660 void wxPreviewControlBar::CreateButtons()
661 {
662 SetSize(0, 0, 400, 40);
663
664 wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
665
666 m_closeButton = new wxButton( this, wxID_PREVIEW_CLOSE, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
667 item0->Add( m_closeButton, 0, wxALIGN_CENTRE|wxALL, 5 );
668
669 if (m_buttonFlags & wxPREVIEW_PRINT)
670 {
671 m_printButton = new wxButton( this, wxID_PREVIEW_PRINT, _("&Print..."), wxDefaultPosition, wxDefaultSize, 0 );
672 item0->Add( m_printButton, 0, wxALIGN_CENTRE|wxALL, 5 );
673 }
674
675 if (m_buttonFlags & wxPREVIEW_FIRST)
676 {
677 m_firstPageButton = new wxButton( this, wxID_PREVIEW_FIRST, _("|<<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
678 item0->Add( m_firstPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
679 }
680
681 if (m_buttonFlags & wxPREVIEW_PREVIOUS)
682 {
683 m_previousPageButton = new wxButton( this, wxID_PREVIEW_PREVIOUS, _("<<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
684 item0->Add( m_previousPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
685 }
686
687 if (m_buttonFlags & wxPREVIEW_NEXT)
688 {
689 m_nextPageButton = new wxButton( this, wxID_PREVIEW_NEXT, _(">>"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
690 item0->Add( m_nextPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
691 }
692
693 if (m_buttonFlags & wxPREVIEW_LAST)
694 {
695 m_lastPageButton = new wxButton( this, wxID_PREVIEW_LAST, _(">>|"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
696 item0->Add( m_lastPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
697 }
698
699 if (m_buttonFlags & wxPREVIEW_GOTO)
700 {
701 m_gotoPageButton = new wxButton( this, wxID_PREVIEW_GOTO, _("&Goto..."), wxDefaultPosition, wxDefaultSize, 0 );
702 item0->Add( m_gotoPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
703 }
704
705 if (m_buttonFlags & wxPREVIEW_ZOOM)
706 {
707 wxString choices[] =
708 {
709 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
710 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
711 wxT("120%"), wxT("150%"), wxT("200%")
712 };
713 int n = WXSIZEOF(choices);
714
715 m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,wxDefaultCoord), n, choices, 0 );
716 item0->Add( m_zoomControl, 0, wxALIGN_CENTRE|wxALL, 5 );
717 SetZoomControl(m_printPreview->GetZoom());
718 }
719
720 SetSizer(item0);
721 item0->Fit(this);
722 }
723
724 void wxPreviewControlBar::SetZoomControl(int zoom)
725 {
726 if (m_zoomControl)
727 {
728 int n, count = m_zoomControl->GetCount();
729 long val;
730 for (n=0; n<count; n++)
731 {
732 if (m_zoomControl->GetString(n).BeforeFirst(wxT('%')).ToLong(&val) &&
733 (val >= long(zoom)))
734 {
735 m_zoomControl->SetSelection(n);
736 return;
737 }
738 }
739
740 m_zoomControl->SetSelection(count-1);
741 }
742 }
743
744 int wxPreviewControlBar::GetZoomControl()
745 {
746 if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxEmptyString))
747 {
748 long val;
749 if (m_zoomControl->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val))
750 return int(val);
751 }
752
753 return 0;
754 }
755
756
757 /*
758 * Preview frame
759 */
760
761 IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
762
763 BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
764 EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
765 END_EVENT_TABLE()
766
767 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title,
768 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
769 wxFrame(parent, wxID_ANY, title, pos, size, style, name)
770 {
771 m_printPreview = preview;
772 m_controlBar = NULL;
773 m_previewCanvas = NULL;
774 m_windowDisabler = NULL;
775
776 // Give the application icon
777 #ifdef __WXMSW__
778 wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
779 if (topFrame)
780 SetIcon(topFrame->GetIcon());
781 #endif
782 }
783
784 wxPreviewFrame::~wxPreviewFrame()
785 {
786 }
787
788 void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
789 {
790 if (m_windowDisabler)
791 delete m_windowDisabler;
792
793 // Need to delete the printout and the print preview
794 wxPrintout *printout = m_printPreview->GetPrintout();
795 if (printout)
796 {
797 delete printout;
798 m_printPreview->SetPrintout(NULL);
799 m_printPreview->SetCanvas(NULL);
800 m_printPreview->SetFrame(NULL);
801 }
802 delete m_printPreview;
803
804 Destroy();
805 }
806
807 void wxPreviewFrame::Initialize()
808 {
809 #if wxUSE_STATUSBAR
810 CreateStatusBar();
811 #endif
812 CreateCanvas();
813 CreateControlBar();
814
815 m_printPreview->SetCanvas(m_previewCanvas);
816 m_printPreview->SetFrame(this);
817
818 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
819
820 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
821 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
822
823 SetAutoLayout( true );
824 SetSizer( item0 );
825
826 m_windowDisabler = new wxWindowDisabler(this);
827
828 Layout();
829
830 m_printPreview->AdjustScrollbars(m_previewCanvas);
831 m_previewCanvas->SetFocus();
832 m_controlBar->SetFocus();
833 }
834
835 void wxPreviewFrame::CreateCanvas()
836 {
837 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
838 }
839
840 void wxPreviewFrame::CreateControlBar()
841 {
842 long buttons = wxPREVIEW_DEFAULT;
843 if (m_printPreview->GetPrintoutForPrinting())
844 buttons |= wxPREVIEW_PRINT;
845
846 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0, 0), wxSize(400, 40));
847 m_controlBar->CreateButtons();
848 }
849
850 /*
851 * Print preview
852 */
853
854 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
855 wxPrintout *printoutForPrinting,
856 wxPrintData *data)
857 {
858 if (data)
859 m_printDialogData = (*data);
860
861 Init(printout, printoutForPrinting);
862 }
863
864 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
865 wxPrintout *printoutForPrinting,
866 wxPrintDialogData *data)
867 {
868 if (data)
869 m_printDialogData = (*data);
870
871 Init(printout, printoutForPrinting);
872 }
873
874 void wxPrintPreviewBase::Init(wxPrintout *printout,
875 wxPrintout *printoutForPrinting)
876 {
877 m_isOk = true;
878 m_previewPrintout = printout;
879 if (m_previewPrintout)
880 m_previewPrintout->SetIsPreview(true);
881
882 m_printPrintout = printoutForPrinting;
883
884 m_previewCanvas = NULL;
885 m_previewFrame = NULL;
886 m_previewBitmap = NULL;
887 m_currentPage = 1;
888 m_currentZoom = 70;
889 m_topMargin = 40;
890 m_leftMargin = 40;
891 m_pageWidth = 0;
892 m_pageHeight = 0;
893 m_printingPrepared = false;
894 m_minPage = 1;
895 m_maxPage = 1;
896 }
897
898 wxPrintPreviewBase::~wxPrintPreviewBase()
899 {
900 if (m_previewPrintout)
901 delete m_previewPrintout;
902 if (m_previewBitmap)
903 delete m_previewBitmap;
904 if (m_printPrintout)
905 delete m_printPrintout;
906 }
907
908 bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
909 {
910 if (m_currentPage == pageNum)
911 return true;
912
913 m_currentPage = pageNum;
914 if (m_previewBitmap)
915 {
916 delete m_previewBitmap;
917 m_previewBitmap = NULL;
918 }
919
920 if (m_previewCanvas)
921 {
922 AdjustScrollbars(m_previewCanvas);
923
924 if (!RenderPage(pageNum))
925 return false;
926 m_previewCanvas->Refresh();
927 m_previewCanvas->SetFocus();
928 }
929 return true;
930 }
931
932 int wxPrintPreviewBase::GetCurrentPage() const
933 { return m_currentPage; };
934 void wxPrintPreviewBase::SetPrintout(wxPrintout *printout)
935 { m_previewPrintout = printout; };
936 wxPrintout *wxPrintPreviewBase::GetPrintout() const
937 { return m_previewPrintout; };
938 wxPrintout *wxPrintPreviewBase::GetPrintoutForPrinting() const
939 { return m_printPrintout; };
940 void wxPrintPreviewBase::SetFrame(wxFrame *frame)
941 { m_previewFrame = frame; };
942 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas *canvas)
943 { m_previewCanvas = canvas; };
944 wxFrame *wxPrintPreviewBase::GetFrame() const
945 { return m_previewFrame; }
946 wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
947 { return m_previewCanvas; }
948
949 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
950 {
951 DrawBlankPage(canvas, dc);
952
953 if (!m_previewBitmap)
954 if (!RenderPage(m_currentPage))
955 return false;
956
957 if (!m_previewBitmap)
958 return false;
959
960 if (!canvas)
961 return false;
962
963 int canvasWidth, canvasHeight;
964 canvas->GetSize(&canvasWidth, &canvasHeight);
965
966 double zoomScale = ((float)m_currentZoom/(float)100);
967 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
968 // float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
969
970 int x = (int) ((canvasWidth - actualWidth)/2.0);
971 if (x < m_leftMargin)
972 x = m_leftMargin;
973 int y = m_topMargin;
974
975 wxMemoryDC temp_dc;
976 temp_dc.SelectObject(*m_previewBitmap);
977
978 dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
979
980 temp_dc.SelectObject(wxNullBitmap);
981
982 return true;
983 }
984
985 // Adjusts the scrollbars for the current scale
986 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
987 {
988 if (!canvas)
989 return ;
990
991 int canvasWidth, canvasHeight;
992 canvas->GetSize(&canvasWidth, &canvasHeight);
993
994 double zoomScale = ((float)m_currentZoom/(float)100);
995 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
996 double actualHeight = (zoomScale*m_pageHeight*m_previewScale);
997
998 // Set the scrollbars appropriately
999 int totalWidth = (int)(actualWidth + 2*m_leftMargin);
1000 int totalHeight = (int)(actualHeight + 2*m_topMargin);
1001 int scrollUnitsX = totalWidth/10;
1002 int scrollUnitsY = totalHeight/10;
1003 wxSize virtualSize = canvas->GetVirtualSize();
1004 if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
1005 canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
1006 }
1007
1008 bool wxPrintPreviewBase::RenderPage(int pageNum)
1009 {
1010 wxBusyCursor busy;
1011
1012 int canvasWidth, canvasHeight;
1013
1014 if (!m_previewCanvas)
1015 {
1016 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1017
1018 return false;
1019 }
1020 m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
1021
1022 double zoomScale = (m_currentZoom/100.0);
1023 int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
1024 int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
1025
1026 if (!m_previewBitmap)
1027 {
1028 m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
1029 if (!m_previewBitmap || !m_previewBitmap->Ok())
1030 {
1031 if (m_previewBitmap) {
1032 delete m_previewBitmap;
1033 m_previewBitmap = NULL;
1034 }
1035 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
1036 return false;
1037 }
1038 }
1039
1040 wxMemoryDC memoryDC;
1041 memoryDC.SelectObject(*m_previewBitmap);
1042
1043 memoryDC.Clear();
1044
1045 m_previewPrintout->SetDC(&memoryDC);
1046 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
1047
1048 // Need to delay OnPreparePrinting until here, so we have enough information.
1049 if (!m_printingPrepared)
1050 {
1051 m_previewPrintout->OnPreparePrinting();
1052 int selFrom, selTo;
1053 m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
1054 m_printingPrepared = true;
1055 }
1056
1057 m_previewPrintout->OnBeginPrinting();
1058
1059 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
1060 {
1061 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
1062
1063 memoryDC.SelectObject(wxNullBitmap);
1064
1065 delete m_previewBitmap;
1066 m_previewBitmap = NULL;
1067 return false;
1068 }
1069
1070 m_previewPrintout->OnPrintPage(pageNum);
1071 m_previewPrintout->OnEndDocument();
1072 m_previewPrintout->OnEndPrinting();
1073
1074 m_previewPrintout->SetDC(NULL);
1075
1076 memoryDC.SelectObject(wxNullBitmap);
1077
1078 #if wxUSE_STATUSBAR
1079 wxString status;
1080 if (m_maxPage != 0)
1081 status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
1082 else
1083 status = wxString::Format(_("Page %d"), pageNum);
1084
1085 if (m_previewFrame)
1086 m_previewFrame->SetStatusText(status);
1087 #endif
1088
1089 return true;
1090 }
1091
1092
1093 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
1094 {
1095 int canvasWidth, canvasHeight;
1096 canvas->GetSize(&canvasWidth, &canvasHeight);
1097
1098 float zoomScale = (float)((float)m_currentZoom/(float)100);
1099 float actualWidth = zoomScale*m_pageWidth*m_previewScale;
1100 float actualHeight = zoomScale*m_pageHeight*m_previewScale;
1101
1102 float x = (float)((canvasWidth - actualWidth)/2.0);
1103 if (x < m_leftMargin)
1104 x = (float)m_leftMargin;
1105 float y = (float)m_topMargin;
1106
1107 // Draw shadow, allowing for 1-pixel border AROUND the actual page
1108 int shadowOffset = 4;
1109 dc.SetPen(*wxBLACK_PEN);
1110 dc.SetBrush(*wxBLACK_BRUSH);
1111 /*
1112 dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
1113 */
1114 dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
1115 dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
1116
1117 // Draw blank page allowing for 1-pixel border AROUND the actual page
1118 dc.SetPen(*wxBLACK_PEN);
1119 dc.SetBrush(*wxWHITE_BRUSH);
1120
1121 /*
1122 wxRegion update_region = canvas->GetUpdateRegion();
1123 wxRect r = update_region.GetBox();
1124
1125 printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
1126 */
1127
1128 dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
1129
1130 return true;
1131 }
1132
1133 void wxPrintPreviewBase::SetZoom(int percent)
1134 {
1135 if (m_currentZoom == percent)
1136 return;
1137
1138 m_currentZoom = percent;
1139 if (m_previewBitmap)
1140 {
1141 delete m_previewBitmap;
1142 m_previewBitmap = NULL;
1143 }
1144
1145 if (m_previewCanvas)
1146 {
1147 AdjustScrollbars(m_previewCanvas);
1148 RenderPage(m_currentPage);
1149 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
1150 m_previewCanvas->ClearBackground();
1151 m_previewCanvas->Refresh();
1152 m_previewCanvas->SetFocus();
1153 }
1154 }
1155
1156 wxPrintDialogData& wxPrintPreviewBase::GetPrintDialogData()
1157 {
1158 return m_printDialogData;
1159 }
1160
1161 int wxPrintPreviewBase::GetZoom() const
1162 { return m_currentZoom; }
1163 int wxPrintPreviewBase::GetMaxPage() const
1164 { return m_maxPage; }
1165 int wxPrintPreviewBase::GetMinPage() const
1166 { return m_minPage; }
1167 bool wxPrintPreviewBase::Ok() const
1168 { return m_isOk; }
1169 void wxPrintPreviewBase::SetOk(bool ok)
1170 { m_isOk = ok; }
1171 //----------------------------------------------------------------------------
1172 // wxPrintPreview
1173 //----------------------------------------------------------------------------
1174
1175 IMPLEMENT_CLASS(wxPrintPreview, wxPrintPreviewBase)
1176
1177 wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1178 wxPrintout *printoutForPrinting,
1179 wxPrintDialogData *data) :
1180 wxPrintPreviewBase( printout, printoutForPrinting, data )
1181 {
1182 m_pimpl = wxPrintFactory::GetFactory()->
1183 CreatePrintPreview( printout, printoutForPrinting, data );
1184 }
1185
1186 wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1187 wxPrintout *printoutForPrinting,
1188 wxPrintData *data ) :
1189 wxPrintPreviewBase( printout, printoutForPrinting, data )
1190 {
1191 m_pimpl = wxPrintFactory::GetFactory()->
1192 CreatePrintPreview( printout, printoutForPrinting, data );
1193 }
1194
1195 wxPrintPreview::~wxPrintPreview()
1196 {
1197 delete m_pimpl;
1198
1199 // don't delete twice
1200 m_printPrintout = NULL;
1201 m_previewPrintout = NULL;
1202 m_previewBitmap = NULL;
1203 }
1204
1205 bool wxPrintPreview::SetCurrentPage(int pageNum)
1206 {
1207 return m_pimpl->SetCurrentPage( pageNum );
1208 }
1209
1210 int wxPrintPreview::GetCurrentPage() const
1211 {
1212 return m_pimpl->GetCurrentPage();
1213 }
1214
1215 void wxPrintPreview::SetPrintout(wxPrintout *printout)
1216 {
1217 m_pimpl->SetPrintout( printout );
1218 }
1219
1220 wxPrintout *wxPrintPreview::GetPrintout() const
1221 {
1222 return m_pimpl->GetPrintout();
1223 }
1224
1225 wxPrintout *wxPrintPreview::GetPrintoutForPrinting() const
1226 {
1227 return m_pimpl->GetPrintoutForPrinting();
1228 }
1229
1230 void wxPrintPreview::SetFrame(wxFrame *frame)
1231 {
1232 m_pimpl->SetFrame( frame );
1233 }
1234
1235 void wxPrintPreview::SetCanvas(wxPreviewCanvas *canvas)
1236 {
1237 m_pimpl->SetCanvas( canvas );
1238 }
1239
1240 wxFrame *wxPrintPreview::GetFrame() const
1241 {
1242 return m_pimpl->GetFrame();
1243 }
1244
1245 wxPreviewCanvas *wxPrintPreview::GetCanvas() const
1246 {
1247 return m_pimpl->GetCanvas();
1248 }
1249
1250 bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
1251 {
1252 return m_pimpl->PaintPage( canvas, dc );
1253 }
1254
1255 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
1256 {
1257 return m_pimpl->DrawBlankPage( canvas, dc );
1258 }
1259
1260 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas *canvas)
1261 {
1262 m_pimpl->AdjustScrollbars( canvas );
1263 }
1264
1265 bool wxPrintPreview::RenderPage(int pageNum)
1266 {
1267 return m_pimpl->RenderPage( pageNum );
1268 }
1269
1270 void wxPrintPreview::SetZoom(int percent)
1271 {
1272 m_pimpl->SetZoom( percent );
1273 }
1274
1275 wxPrintDialogData& wxPrintPreview::GetPrintDialogData()
1276 {
1277 return m_pimpl->GetPrintDialogData();
1278 }
1279
1280 int wxPrintPreview::GetMaxPage() const
1281 {
1282 return m_pimpl->GetMaxPage();
1283 }
1284
1285 int wxPrintPreview::GetMinPage() const
1286 {
1287 return m_pimpl->GetMinPage();
1288 }
1289
1290 bool wxPrintPreview::Ok() const
1291 {
1292 return m_pimpl->Ok();
1293 }
1294
1295 void wxPrintPreview::SetOk(bool ok)
1296 {
1297 m_pimpl->SetOk( ok );
1298 }
1299
1300 bool wxPrintPreview::Print(bool interactive)
1301 {
1302 return m_pimpl->Print( interactive );
1303 }
1304
1305 void wxPrintPreview::DetermineScaling()
1306 {
1307 m_pimpl->DetermineScaling();
1308 }
1309
1310
1311 #endif // wxUSE_PRINTING_ARCHITECTURE