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