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