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