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