]> git.saurik.com Git - wxWidgets.git/blob - src/common/prntbase.cpp
Improve print preview appearance and functionality.
[wxWidgets.git] / src / common / prntbase.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_PRINTING_ARCHITECTURE
20
21 #include "wx/dcprint.h"
22
23 #ifndef WX_PRECOMP
24 #if defined(__WXMSW__)
25 #include "wx/msw/wrapcdlg.h"
26 #endif // MSW
27 #include "wx/utils.h"
28 #include "wx/dc.h"
29 #include "wx/app.h"
30 #include "wx/math.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/dcclient.h"
38 #include "wx/stattext.h"
39 #include "wx/intl.h"
40 #include "wx/textdlg.h"
41 #include "wx/sizer.h"
42 #include "wx/module.h"
43 #endif // !WX_PRECOMP
44
45 #include "wx/prntbase.h"
46 #include "wx/printdlg.h"
47 #include "wx/print.h"
48 #include "wx/dcprint.h"
49 #include "wx/artprov.h"
50
51 #include <stdlib.h>
52 #include <string.h>
53
54 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
55 #include "wx/msw/printdlg.h"
56 #include "wx/msw/dcprint.h"
57 #elif defined(__WXMAC__)
58 #include "wx/osx/printdlg.h"
59 #include "wx/osx/private/print.h"
60 #include "wx/osx/dcprint.h"
61 #elif defined(__WXPM__)
62 #include "wx/os2/dcprint.h"
63 #include "wx/generic/prntdlgg.h"
64 #else
65 #include "wx/generic/prntdlgg.h"
66 #include "wx/dcps.h"
67 #endif
68
69 #ifdef __WXMSW__
70 #ifndef __WIN32__
71 #include <print.h>
72 #endif
73 #endif // __WXMSW__
74
75 //----------------------------------------------------------------------------
76 // wxPrintFactory
77 //----------------------------------------------------------------------------
78
79 wxPrintFactory *wxPrintFactory::m_factory = NULL;
80
81 void wxPrintFactory::SetPrintFactory( wxPrintFactory *factory )
82 {
83 if (wxPrintFactory::m_factory)
84 delete wxPrintFactory::m_factory;
85
86 wxPrintFactory::m_factory = factory;
87 }
88
89 wxPrintFactory *wxPrintFactory::GetFactory()
90 {
91 if (!wxPrintFactory::m_factory)
92 wxPrintFactory::m_factory = new wxNativePrintFactory;
93
94 return wxPrintFactory::m_factory;
95 }
96
97 //----------------------------------------------------------------------------
98 // wxNativePrintFactory
99 //----------------------------------------------------------------------------
100
101 wxPrinterBase *wxNativePrintFactory::CreatePrinter( wxPrintDialogData *data )
102 {
103 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
104 return new wxWindowsPrinter( data );
105 #elif defined(__WXMAC__)
106 return new wxMacPrinter( data );
107 #elif defined(__WXPM__)
108 return new wxOS2Printer( data );
109 #else
110 return new wxPostScriptPrinter( data );
111 #endif
112 }
113
114 wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
115 wxPrintout *printout, wxPrintDialogData *data )
116 {
117 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
118 return new wxWindowsPrintPreview( preview, printout, data );
119 #elif defined(__WXMAC__)
120 return new wxMacPrintPreview( preview, printout, data );
121 #elif defined(__WXPM__)
122 return new wxOS2PrintPreview( preview, printout, data );
123 #else
124 return new wxPostScriptPrintPreview( preview, printout, data );
125 #endif
126 }
127
128 wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
129 wxPrintout *printout, wxPrintData *data )
130 {
131 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
132 return new wxWindowsPrintPreview( preview, printout, data );
133 #elif defined(__WXMAC__)
134 return new wxMacPrintPreview( preview, printout, data );
135 #elif defined(__WXPM__)
136 return new wxOS2PrintPreview( preview, printout, data );
137 #else
138 return new wxPostScriptPrintPreview( preview, printout, data );
139 #endif
140 }
141
142 wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
143 wxPrintDialogData *data )
144 {
145 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
146 return new wxWindowsPrintDialog( parent, data );
147 #elif defined(__WXMAC__)
148 return new wxMacPrintDialog( parent, data );
149 #else
150 return new wxGenericPrintDialog( parent, data );
151 #endif
152 }
153
154 wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
155 wxPrintData *data )
156 {
157 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
158 return new wxWindowsPrintDialog( parent, data );
159 #elif defined(__WXMAC__)
160 return new wxMacPrintDialog( parent, data );
161 #else
162 return new wxGenericPrintDialog( parent, data );
163 #endif
164 }
165
166 wxPageSetupDialogBase *wxNativePrintFactory::CreatePageSetupDialog( wxWindow *parent,
167 wxPageSetupDialogData *data )
168 {
169 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
170 return new wxWindowsPageSetupDialog( parent, data );
171 #elif defined(__WXMAC__)
172 return new wxMacPageSetupDialog( parent, data );
173 #else
174 return new wxGenericPageSetupDialog( parent, data );
175 #endif
176 }
177
178 bool wxNativePrintFactory::HasPrintSetupDialog()
179 {
180 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
181 return false;
182 #elif defined(__WXMAC__)
183 return false;
184 #else
185 // Only here do we need to provide the print setup
186 // dialog ourselves, the other platforms either have
187 // none, don't make it accessible or let you configure
188 // the printer from the wxPrintDialog anyway.
189 return true;
190 #endif
191
192 }
193
194 wxDialog *wxNativePrintFactory::CreatePrintSetupDialog( wxWindow *parent,
195 wxPrintData *data )
196 {
197 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
198 wxUnusedVar(parent);
199 wxUnusedVar(data);
200 return NULL;
201 #elif defined(__WXMAC__)
202 wxUnusedVar(parent);
203 wxUnusedVar(data);
204 return NULL;
205 #else
206 // Only here do we need to provide the print setup
207 // dialog ourselves, the other platforms either have
208 // none, don't make it accessible or let you configure
209 // the printer from the wxPrintDialog anyway.
210 return new wxGenericPrintSetupDialog( parent, data );
211 #endif
212 }
213
214 wxDCImpl* wxNativePrintFactory::CreatePrinterDCImpl( wxPrinterDC *owner, const wxPrintData& data )
215 {
216 #if defined(__WXGTK__) || defined(__WXMOTIF__) || ( defined(__WXUNIVERSAL__) && !defined(__WXMAC__) )
217 return new wxPostScriptDCImpl( owner, data );
218 #else
219 return new wxPrinterDCImpl( owner, data );
220 #endif
221 }
222
223 bool wxNativePrintFactory::HasOwnPrintToFile()
224 {
225 // Only relevant for PostScript and here the
226 // setup dialog provides no "print to file"
227 // option. In the GNOME setup dialog, the
228 // setup dialog has its own print to file.
229 return false;
230 }
231
232 bool wxNativePrintFactory::HasPrinterLine()
233 {
234 // Only relevant for PostScript for now
235 return true;
236 }
237
238 wxString wxNativePrintFactory::CreatePrinterLine()
239 {
240 // Only relevant for PostScript for now
241
242 // We should query "lpstat -d" here
243 return _("Generic PostScript");
244 }
245
246 bool wxNativePrintFactory::HasStatusLine()
247 {
248 // Only relevant for PostScript for now
249 return true;
250 }
251
252 wxString wxNativePrintFactory::CreateStatusLine()
253 {
254 // Only relevant for PostScript for now
255
256 // We should query "lpstat -r" or "lpstat -p" here
257 return _("Ready");
258 }
259
260 wxPrintNativeDataBase *wxNativePrintFactory::CreatePrintNativeData()
261 {
262 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
263 return new wxWindowsPrintNativeData;
264 #elif defined(__WXMAC__)
265 return wxOSXCreatePrintData();
266 #else
267 return new wxPostScriptPrintNativeData;
268 #endif
269 }
270
271 //----------------------------------------------------------------------------
272 // wxPrintNativeDataBase
273 //----------------------------------------------------------------------------
274
275 IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase, wxObject)
276
277 wxPrintNativeDataBase::wxPrintNativeDataBase()
278 {
279 m_ref = 1;
280 }
281
282 //----------------------------------------------------------------------------
283 // wxPrintFactoryModule
284 //----------------------------------------------------------------------------
285
286 class wxPrintFactoryModule: public wxModule
287 {
288 public:
289 wxPrintFactoryModule() {}
290 bool OnInit() { return true; }
291 void OnExit() { wxPrintFactory::SetPrintFactory( NULL ); }
292
293 private:
294 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule)
295 };
296
297 IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule, wxModule)
298
299 //----------------------------------------------------------------------------
300 // wxPrinterBase
301 //----------------------------------------------------------------------------
302
303 IMPLEMENT_CLASS(wxPrinterBase, wxObject)
304
305 wxPrinterBase::wxPrinterBase(wxPrintDialogData *data)
306 {
307 m_currentPrintout = NULL;
308 sm_abortWindow = NULL;
309 sm_abortIt = false;
310 if (data)
311 m_printDialogData = (*data);
312 sm_lastError = wxPRINTER_NO_ERROR;
313 }
314
315 wxWindow *wxPrinterBase::sm_abortWindow = NULL;
316 bool wxPrinterBase::sm_abortIt = false;
317 wxPrinterError wxPrinterBase::sm_lastError = wxPRINTER_NO_ERROR;
318
319 wxPrinterBase::~wxPrinterBase()
320 {
321 }
322
323 wxWindow *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout * printout)
324 {
325 wxPrintAbortDialog *dialog = new wxPrintAbortDialog(parent, _("Printing ") , wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
326
327 wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
328 button_sizer->Add( new wxStaticText(dialog, wxID_ANY, _("Please wait while printing\n") + printout->GetTitle() ), 0, wxALL, 10 );
329 button_sizer->Add( new wxButton( dialog, wxID_CANCEL, wxT("Cancel") ), 0, wxALL | wxALIGN_CENTER, 10 );
330
331 dialog->SetAutoLayout( true );
332 dialog->SetSizer( button_sizer );
333
334 button_sizer->Fit(dialog);
335 button_sizer->SetSizeHints (dialog) ;
336
337 return dialog;
338 }
339
340 void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), const wxString& message)
341 {
342 wxMessageBox(message, _("Printing Error"), wxOK, parent);
343 }
344
345 wxPrintDialogData& wxPrinterBase::GetPrintDialogData() const
346 {
347 return (wxPrintDialogData&) m_printDialogData;
348 }
349
350 //----------------------------------------------------------------------------
351 // wxPrinter
352 //----------------------------------------------------------------------------
353
354 IMPLEMENT_CLASS(wxPrinter, wxPrinterBase)
355
356 wxPrinter::wxPrinter(wxPrintDialogData *data)
357 {
358 m_pimpl = wxPrintFactory::GetFactory()->CreatePrinter( data );
359 }
360
361 wxPrinter::~wxPrinter()
362 {
363 delete m_pimpl;
364 }
365
366 wxWindow *wxPrinter::CreateAbortWindow(wxWindow *parent, wxPrintout *printout)
367 {
368 return m_pimpl->CreateAbortWindow( parent, printout );
369 }
370
371 void wxPrinter::ReportError(wxWindow *parent, wxPrintout *printout, const wxString& message)
372 {
373 m_pimpl->ReportError( parent, printout, message );
374 }
375
376 bool wxPrinter::Setup(wxWindow *parent)
377 {
378 return m_pimpl->Setup( parent );
379 }
380
381 bool wxPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
382 {
383 return m_pimpl->Print( parent, printout, prompt );
384 }
385
386 wxDC* wxPrinter::PrintDialog(wxWindow *parent)
387 {
388 return m_pimpl->PrintDialog( parent );
389 }
390
391 wxPrintDialogData& wxPrinter::GetPrintDialogData() const
392 {
393 return m_pimpl->GetPrintDialogData();
394 }
395
396 // ---------------------------------------------------------------------------
397 // wxPrintDialogBase: the dialog for printing.
398 // ---------------------------------------------------------------------------
399
400 IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase, wxDialog)
401
402 wxPrintDialogBase::wxPrintDialogBase(wxWindow *parent,
403 wxWindowID id,
404 const wxString &title,
405 const wxPoint &pos,
406 const wxSize &size,
407 long style)
408 : wxDialog( parent, id, title.empty() ? wxString(_("Print")) : title,
409 pos, size, style )
410 {
411 }
412
413 // ---------------------------------------------------------------------------
414 // wxPrintDialog: the dialog for printing
415 // ---------------------------------------------------------------------------
416
417 IMPLEMENT_CLASS(wxPrintDialog, wxObject)
418
419 wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintDialogData* data)
420 {
421 m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
422 }
423
424 wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintData* data)
425 {
426 m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
427 }
428
429 wxPrintDialog::~wxPrintDialog()
430 {
431 delete m_pimpl;
432 }
433
434 int wxPrintDialog::ShowModal()
435 {
436 return m_pimpl->ShowModal();
437 }
438
439 wxPrintDialogData& wxPrintDialog::GetPrintDialogData()
440 {
441 return m_pimpl->GetPrintDialogData();
442 }
443
444 wxPrintData& wxPrintDialog::GetPrintData()
445 {
446 return m_pimpl->GetPrintData();
447 }
448
449 wxDC *wxPrintDialog::GetPrintDC()
450 {
451 return m_pimpl->GetPrintDC();
452 }
453
454 // ---------------------------------------------------------------------------
455 // wxPageSetupDialogBase: the page setup dialog
456 // ---------------------------------------------------------------------------
457
458 IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase, wxDialog)
459
460 wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow *parent,
461 wxWindowID id,
462 const wxString &title,
463 const wxPoint &pos,
464 const wxSize &size,
465 long style)
466 : wxDialog( parent, id, title.empty() ? wxString(_("Page setup")) : title,
467 pos, size, style )
468 {
469 }
470
471 // ---------------------------------------------------------------------------
472 // wxPageSetupDialog: the page setup dialog
473 // ---------------------------------------------------------------------------
474
475 IMPLEMENT_CLASS(wxPageSetupDialog, wxObject)
476
477 wxPageSetupDialog::wxPageSetupDialog(wxWindow *parent, wxPageSetupDialogData *data )
478 {
479 m_pimpl = wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent, data );
480 }
481
482 wxPageSetupDialog::~wxPageSetupDialog()
483 {
484 delete m_pimpl;
485 }
486
487 int wxPageSetupDialog::ShowModal()
488 {
489 return m_pimpl->ShowModal();
490 }
491
492 wxPageSetupDialogData& wxPageSetupDialog::GetPageSetupDialogData()
493 {
494 return m_pimpl->GetPageSetupDialogData();
495 }
496
497 // old name
498 wxPageSetupDialogData& wxPageSetupDialog::GetPageSetupData()
499 {
500 return m_pimpl->GetPageSetupDialogData();
501 }
502
503 //----------------------------------------------------------------------------
504 // wxPrintAbortDialog
505 //----------------------------------------------------------------------------
506
507 BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
508 EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
509 END_EVENT_TABLE()
510
511 void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
512 {
513 wxPrinterBase::sm_abortIt = true;
514 wxPrinterBase::sm_abortWindow->Show(false);
515 wxPrinterBase::sm_abortWindow->Close(true);
516 wxPrinterBase::sm_abortWindow->Destroy();
517 wxPrinterBase::sm_abortWindow = NULL;
518 }
519
520 //----------------------------------------------------------------------------
521 // wxPrintout
522 //----------------------------------------------------------------------------
523
524 IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
525
526 wxPrintout::wxPrintout(const wxString& title)
527 {
528 m_printoutTitle = title ;
529 m_printoutDC = NULL;
530 m_pageWidthMM = 0;
531 m_pageHeightMM = 0;
532 m_pageWidthPixels = 0;
533 m_pageHeightPixels = 0;
534 m_PPIScreenX = 0;
535 m_PPIScreenY = 0;
536 m_PPIPrinterX = 0;
537 m_PPIPrinterY = 0;
538 m_preview = NULL;
539 }
540
541 wxPrintout::~wxPrintout()
542 {
543 }
544
545 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
546 {
547 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle);
548 }
549
550 void wxPrintout::OnEndDocument()
551 {
552 GetDC()->EndDoc();
553 }
554
555 void wxPrintout::OnBeginPrinting()
556 {
557 }
558
559 void wxPrintout::OnEndPrinting()
560 {
561 }
562
563 bool wxPrintout::HasPage(int page)
564 {
565 return (page == 1);
566 }
567
568 void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
569 {
570 *minPage = 1;
571 *maxPage = 32000;
572 *fromPage = 1;
573 *toPage = 1;
574 }
575
576 void wxPrintout::FitThisSizeToPaper(const wxSize& imageSize)
577 {
578 // Set the DC scale and origin so that the given image size fits within the
579 // entire page and the origin is at the top left corner of the page. Note
580 // that with most printers, portions of the page will be non-printable. Use
581 // this if you're managing your own page margins.
582 if (!m_printoutDC) return;
583 wxRect paperRect = GetPaperRectPixels();
584 wxCoord pw, ph;
585 GetPageSizePixels(&pw, &ph);
586 wxCoord w, h;
587 m_printoutDC->GetSize(&w, &h);
588 float scaleX = ((float(paperRect.width) * w) / (float(pw) * imageSize.x));
589 float scaleY = ((float(paperRect.height) * h) / (float(ph) * imageSize.y));
590 float actualScale = wxMin(scaleX, scaleY);
591 m_printoutDC->SetUserScale(actualScale, actualScale);
592 m_printoutDC->SetDeviceOrigin(0, 0);
593 wxRect logicalPaperRect = GetLogicalPaperRect();
594 SetLogicalOrigin(logicalPaperRect.x, logicalPaperRect.y);
595 }
596
597 void wxPrintout::FitThisSizeToPage(const wxSize& imageSize)
598 {
599 // Set the DC scale and origin so that the given image size fits within the
600 // printable area of the page and the origin is at the top left corner of
601 // the printable area.
602 if (!m_printoutDC) return;
603 int w, h;
604 m_printoutDC->GetSize(&w, &h);
605 float scaleX = float(w) / imageSize.x;
606 float scaleY = float(h) / imageSize.y;
607 float actualScale = wxMin(scaleX, scaleY);
608 m_printoutDC->SetUserScale(actualScale, actualScale);
609 m_printoutDC->SetDeviceOrigin(0, 0);
610 }
611
612 void wxPrintout::FitThisSizeToPageMargins(const wxSize& imageSize, const wxPageSetupDialogData& pageSetupData)
613 {
614 // Set the DC scale and origin so that the given image size fits within the
615 // page margins defined in the given wxPageSetupDialogData object and the
616 // origin is at the top left corner of the page margins.
617 if (!m_printoutDC) return;
618 wxRect paperRect = GetPaperRectPixels();
619 wxCoord pw, ph;
620 GetPageSizePixels(&pw, &ph);
621 wxPoint topLeft = pageSetupData.GetMarginTopLeft();
622 wxPoint bottomRight = pageSetupData.GetMarginBottomRight();
623 wxCoord mw, mh;
624 GetPageSizeMM(&mw, &mh);
625 float mmToDeviceX = float(pw) / mw;
626 float mmToDeviceY = float(ph) / mh;
627 wxRect pageMarginsRect(paperRect.x + wxRound(mmToDeviceX * topLeft.x),
628 paperRect.y + wxRound(mmToDeviceY * topLeft.y),
629 paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)),
630 paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y)));
631 wxCoord w, h;
632 m_printoutDC->GetSize(&w, &h);
633 float scaleX = (float(pageMarginsRect.width) * w) / (float(pw) * imageSize.x);
634 float scaleY = (float(pageMarginsRect.height) * h) / (float(ph) * imageSize.y);
635 float actualScale = wxMin(scaleX, scaleY);
636 m_printoutDC->SetUserScale(actualScale, actualScale);
637 m_printoutDC->SetDeviceOrigin(0, 0);
638 wxRect logicalPageMarginsRect = GetLogicalPageMarginsRect(pageSetupData);
639 SetLogicalOrigin(logicalPageMarginsRect.x, logicalPageMarginsRect.y);
640 }
641
642 void wxPrintout::MapScreenSizeToPaper()
643 {
644 // Set the DC scale so that an image on the screen is the same size on the
645 // paper and the origin is at the top left of the paper. Note that with most
646 // printers, portions of the page will be cut off. Use this if you're
647 // managing your own page margins.
648 if (!m_printoutDC) return;
649 MapScreenSizeToPage();
650 wxRect logicalPaperRect = GetLogicalPaperRect();
651 SetLogicalOrigin(logicalPaperRect.x, logicalPaperRect.y);
652 }
653
654 void wxPrintout::MapScreenSizeToPage()
655 {
656 // Set the DC scale and origin so that an image on the screen is the same
657 // size on the paper and the origin is at the top left of the printable area.
658 if (!m_printoutDC) return;
659 int ppiScreenX, ppiScreenY;
660 GetPPIScreen(&ppiScreenX, &ppiScreenY);
661 int ppiPrinterX, ppiPrinterY;
662 GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
663 int w, h;
664 m_printoutDC->GetSize(&w, &h);
665 int pageSizePixelsX, pageSizePixelsY;
666 GetPageSizePixels(&pageSizePixelsX, &pageSizePixelsY);
667 float userScaleX = (float(ppiPrinterX) * w) / (float(ppiScreenX) * pageSizePixelsX);
668 float userScaleY = (float(ppiPrinterY) * h) / (float(ppiScreenY) * pageSizePixelsY);
669 m_printoutDC->SetUserScale(userScaleX, userScaleY);
670 m_printoutDC->SetDeviceOrigin(0, 0);
671 }
672
673 void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData& pageSetupData)
674 {
675 // Set the DC scale so that an image on the screen is the same size on the
676 // paper and the origin is at the top left of the page margins defined by
677 // the given wxPageSetupDialogData object.
678 if (!m_printoutDC) return;
679 MapScreenSizeToPage();
680 wxRect logicalPageMarginsRect = GetLogicalPageMarginsRect(pageSetupData);
681 SetLogicalOrigin(logicalPageMarginsRect.x, logicalPageMarginsRect.y);
682 }
683
684 void wxPrintout::MapScreenSizeToDevice()
685 {
686 // Set the DC scale so that a screen pixel is the same size as a device
687 // pixel and the origin is at the top left of the printable area.
688 if (!m_printoutDC) return;
689 int w, h;
690 m_printoutDC->GetSize(&w, &h);
691 int pageSizePixelsX, pageSizePixelsY;
692 GetPageSizePixels(&pageSizePixelsX, &pageSizePixelsY);
693 float userScaleX = float(w) / pageSizePixelsX;
694 float userScaleY = float(h) / pageSizePixelsY;
695 m_printoutDC->SetUserScale(userScaleX, userScaleY);
696 m_printoutDC->SetDeviceOrigin(0, 0);
697 }
698
699 wxRect wxPrintout::GetLogicalPaperRect() const
700 {
701 // Return the rectangle in logical units that corresponds to the paper
702 // rectangle.
703 wxRect paperRect = GetPaperRectPixels();
704 wxCoord pw, ph;
705 GetPageSizePixels(&pw, &ph);
706 wxCoord w, h;
707 m_printoutDC->GetSize(&w, &h);
708 if (w == pw && h == ph) {
709 // this DC matches the printed page, so no scaling
710 return wxRect(m_printoutDC->DeviceToLogicalX(paperRect.x),
711 m_printoutDC->DeviceToLogicalY(paperRect.y),
712 m_printoutDC->DeviceToLogicalXRel(paperRect.width),
713 m_printoutDC->DeviceToLogicalYRel(paperRect.height));
714 }
715 // This DC doesn't match the printed page, so we have to scale.
716 float scaleX = float(w) / pw;
717 float scaleY = float(h) / ph;
718 return wxRect(m_printoutDC->DeviceToLogicalX(wxRound(paperRect.x * scaleX)),
719 m_printoutDC->DeviceToLogicalY(wxRound(paperRect.y * scaleY)),
720 m_printoutDC->DeviceToLogicalXRel(wxRound(paperRect.width * scaleX)),
721 m_printoutDC->DeviceToLogicalYRel(wxRound(paperRect.height * scaleY)));
722 }
723
724 wxRect wxPrintout::GetLogicalPageRect() const
725 {
726 // Return the rectangle in logical units that corresponds to the printable
727 // area.
728 int w, h;
729 m_printoutDC->GetSize(&w, &h);
730 return wxRect(m_printoutDC->DeviceToLogicalX(0),
731 m_printoutDC->DeviceToLogicalY(0),
732 m_printoutDC->DeviceToLogicalXRel(w),
733 m_printoutDC->DeviceToLogicalYRel(h));
734 }
735
736 wxRect wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData& pageSetupData) const
737 {
738 // Return the rectangle in logical units that corresponds to the region
739 // within the page margins as specified by the given wxPageSetupDialogData
740 // object.
741
742 // We get the paper size in device units and the margins in mm,
743 // so we need to calculate the conversion with this trick
744 wxCoord pw, ph;
745 GetPageSizePixels(&pw, &ph);
746 wxCoord mw, mh;
747 GetPageSizeMM(&mw, &mh);
748 float mmToDeviceX = float(pw) / mw;
749 float mmToDeviceY = float(ph) / mh;
750
751 // paper size in device units
752 wxRect paperRect = GetPaperRectPixels();
753
754 // margins in mm
755 wxPoint topLeft = pageSetupData.GetMarginTopLeft();
756 wxPoint bottomRight = pageSetupData.GetMarginBottomRight();
757
758 // calculate margins in device units
759 wxRect pageMarginsRect(
760 paperRect.x + wxRound(mmToDeviceX * topLeft.x),
761 paperRect.y + wxRound(mmToDeviceY * topLeft.y),
762 paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)),
763 paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y)));
764
765 wxCoord w, h;
766 m_printoutDC->GetSize(&w, &h);
767 if (w == pw && h == ph)
768 {
769 // this DC matches the printed page, so no scaling
770 return wxRect(
771 m_printoutDC->DeviceToLogicalX(pageMarginsRect.x),
772 m_printoutDC->DeviceToLogicalY(pageMarginsRect.y),
773 m_printoutDC->DeviceToLogicalXRel(pageMarginsRect.width),
774 m_printoutDC->DeviceToLogicalYRel(pageMarginsRect.height));
775 }
776
777 // This DC doesn't match the printed page, so we have to scale.
778 float scaleX = float(w) / pw;
779 float scaleY = float(h) / ph;
780 return wxRect(m_printoutDC->DeviceToLogicalX(wxRound(pageMarginsRect.x * scaleX)),
781 m_printoutDC->DeviceToLogicalY(wxRound(pageMarginsRect.y * scaleY)),
782 m_printoutDC->DeviceToLogicalXRel(wxRound(pageMarginsRect.width * scaleX)),
783 m_printoutDC->DeviceToLogicalYRel(wxRound(pageMarginsRect.height * scaleY)));
784 }
785
786 void wxPrintout::SetLogicalOrigin(wxCoord x, wxCoord y)
787 {
788 // Set the device origin by specifying a point in logical coordinates.
789 m_printoutDC->SetDeviceOrigin(
790 m_printoutDC->LogicalToDeviceX(x),
791 m_printoutDC->LogicalToDeviceY(y) );
792 }
793
794 void wxPrintout::OffsetLogicalOrigin(wxCoord xoff, wxCoord yoff)
795 {
796 // Offset the device origin by a specified distance in device coordinates.
797 wxPoint dev_org = m_printoutDC->GetDeviceOrigin();
798 m_printoutDC->SetDeviceOrigin(
799 dev_org.x + m_printoutDC->LogicalToDeviceXRel(xoff),
800 dev_org.y + m_printoutDC->LogicalToDeviceYRel(yoff) );
801 }
802
803
804 //----------------------------------------------------------------------------
805 // wxPreviewCanvas
806 //----------------------------------------------------------------------------
807
808 IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
809
810 BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
811 EVT_PAINT(wxPreviewCanvas::OnPaint)
812 EVT_CHAR(wxPreviewCanvas::OnChar)
813 EVT_IDLE(wxPreviewCanvas::OnIdle)
814 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
815 #if wxUSE_MOUSEWHEEL
816 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel)
817 #endif
818 END_EVENT_TABLE()
819
820 // VZ: the current code doesn't refresh properly without
821 // wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
822 // really horrible flicker when resizing the preview frame, but without
823 // this style it simply doesn't work correctly at all...
824 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
825 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
826 wxScrolledWindow(parent, wxID_ANY, pos, size, style | wxFULL_REPAINT_ON_RESIZE, name)
827 {
828 m_printPreview = preview;
829 #ifdef __WXMAC__
830 // The app workspace colour is always white, but we should have
831 // a contrast with the page.
832 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
833 #elif defined(__WXGTK__)
834 wxSystemColour colourIndex = wxSYS_COLOUR_BTNFACE;
835 #else
836 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
837 #endif
838 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
839
840 SetScrollbars(10, 10, 100, 100);
841 }
842
843 wxPreviewCanvas::~wxPreviewCanvas()
844 {
845 }
846
847 void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
848 {
849 wxPaintDC dc(this);
850 PrepareDC( dc );
851
852 /*
853 #ifdef __WXGTK__
854 if (!GetUpdateRegion().IsEmpty())
855 dc.SetClippingRegion( GetUpdateRegion() );
856 #endif
857 */
858
859 if (m_printPreview)
860 {
861 m_printPreview->PaintPage(this, dc);
862 }
863 }
864
865 void wxPreviewCanvas::OnIdle(wxIdleEvent& event)
866 {
867 event.Skip();
868
869 // prevent UpdatePageRendering() from being called recursively:
870 static bool s_inIdle = false;
871 if ( s_inIdle )
872 return;
873 s_inIdle = true;
874
875 if ( m_printPreview )
876 {
877 if ( m_printPreview->UpdatePageRendering() )
878 Refresh();
879 }
880
881 s_inIdle = false;
882 }
883
884 // Responds to colour changes, and passes event on to children.
885 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
886 {
887 #ifdef __WXMAC__
888 // The app workspace colour is always white, but we should have
889 // a contrast with the page.
890 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
891 #elif defined(__WXGTK__)
892 wxSystemColour colourIndex = wxSYS_COLOUR_BTNFACE;
893 #else
894 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
895 #endif
896 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
897 Refresh();
898
899 // Propagate the event to the non-top-level children
900 wxWindow::OnSysColourChanged(event);
901 }
902
903 void wxPreviewCanvas::OnChar(wxKeyEvent &event)
904 {
905 wxPreviewControlBar* controlBar = ((wxPreviewFrame*) GetParent())->GetControlBar();
906 switch (event.GetKeyCode())
907 {
908 case WXK_RETURN:
909 controlBar->OnPrint();
910 return;
911 case (int)'+':
912 case WXK_NUMPAD_ADD:
913 case WXK_ADD:
914 controlBar->DoZoomIn();
915 return;
916 case (int)'-':
917 case WXK_NUMPAD_SUBTRACT:
918 case WXK_SUBTRACT:
919 controlBar->DoZoomOut();
920 return;
921 }
922
923 if (!event.ControlDown())
924 {
925 event.Skip();
926 return;
927 }
928
929 switch(event.GetKeyCode())
930 {
931 case WXK_PAGEDOWN:
932 controlBar->OnNext(); break;
933 case WXK_PAGEUP:
934 controlBar->OnPrevious(); break;
935 case WXK_HOME:
936 controlBar->OnFirst(); break;
937 case WXK_END:
938 controlBar->OnLast(); break;
939 default:
940 event.Skip();
941 }
942 }
943
944 #if wxUSE_MOUSEWHEEL
945
946 void wxPreviewCanvas::OnMouseWheel(wxMouseEvent& event)
947 {
948 wxPreviewControlBar *
949 controlBar = wxStaticCast(GetParent(), wxPreviewFrame)->GetControlBar();
950
951 if ( controlBar )
952 {
953 if ( event.ControlDown() && event.GetWheelRotation() != 0 )
954 {
955 int currentZoom = controlBar->GetZoomControl();
956
957 int delta;
958 if ( currentZoom < 100 )
959 delta = 5;
960 else if ( currentZoom <= 120 )
961 delta = 10;
962 else
963 delta = 50;
964
965 if ( event.GetWheelRotation() > 0 )
966 delta = -delta;
967
968 int newZoom = currentZoom + delta;
969 if ( newZoom < 10 )
970 newZoom = 10;
971 if ( newZoom > 200 )
972 newZoom = 200;
973 if ( newZoom != currentZoom )
974 {
975 controlBar->SetZoomControl(newZoom);
976 m_printPreview->SetZoom(newZoom);
977 Refresh();
978 }
979 return;
980 }
981 }
982
983 event.Skip();
984 }
985
986 #endif // wxUSE_MOUSEWHEEL
987
988 // ----------------------------------------------------------------------------
989 // wxPrintPageTextCtrl
990 // ----------------------------------------------------------------------------
991
992 // This text control contains the page number in the interval specified during
993 // its construction. Invalid pages are not accepted and the control contents is
994 // validated when it loses focus. Conversely, if the user changes the page to
995 // another valid one or presses Enter, OnGotoPage() method of the preview object
996 // will be called.
997 class wxPrintPageTextCtrl : public wxTextCtrl
998 {
999 public:
1000 wxPrintPageTextCtrl(wxPreviewControlBar *preview, int minPage, int maxPage)
1001 : wxTextCtrl(preview,
1002 wxID_PREVIEW_GOTO,
1003 PageAsString(minPage),
1004 wxDefaultPosition,
1005 // We use hardcoded 99999 for the width instead of fitting
1006 // it to the values we can show because the control looks
1007 // uncomfortably narrow if the real page number is just
1008 // one or two digits.
1009 wxSize(preview->GetTextExtent("99999").x, wxDefaultCoord),
1010 wxTE_PROCESS_ENTER
1011 #if wxUSE_VALIDATORS
1012 , wxTextValidator(wxFILTER_DIGITS)
1013 #endif // wxUSE_VALIDATORS
1014 ),
1015 m_preview(preview),
1016 m_minPage(minPage),
1017 m_maxPage(maxPage)
1018 {
1019 m_page = minPage;
1020
1021 Connect(wxEVT_KILL_FOCUS,
1022 wxFocusEventHandler(wxPrintPageTextCtrl::OnKillFocus));
1023 Connect(wxEVT_COMMAND_TEXT_ENTER,
1024 wxCommandEventHandler(wxPrintPageTextCtrl::OnTextEnter));
1025 }
1026
1027 // Helpers to conveniently set or get the current page number. Return value
1028 // is 0 if the current controls contents is invalid.
1029 void SetPageNumber(int page)
1030 {
1031 wxASSERT( IsValidPage(page) );
1032
1033 SetValue(PageAsString(page));
1034 }
1035
1036 int GetPageNumber() const
1037 {
1038 long value;
1039 if ( !GetValue().ToLong(&value) || !IsValidPage(value) )
1040 return 0;
1041
1042 // Cast is safe because the value is less than (int) m_maxPage.
1043 return static_cast<int>(value);
1044 }
1045
1046 private:
1047 static wxString PageAsString(int page)
1048 {
1049 return wxString::Format("%d", page);
1050 }
1051
1052 bool IsValidPage(int page) const
1053 {
1054 return page >= m_minPage && page <= m_maxPage;
1055 }
1056
1057 bool DoChangePage()
1058 {
1059 const int page = GetPageNumber();
1060
1061 if ( !page )
1062 return false;
1063
1064 if ( page != m_page )
1065 {
1066 // We have a valid page, remember it.
1067 m_page = page;
1068
1069 // And notify the owner about the change.
1070 m_preview->OnGotoPage();
1071 }
1072 //else: Nothing really changed.
1073
1074 return true;
1075 }
1076
1077 void OnKillFocus(wxFocusEvent& event)
1078 {
1079 if ( !DoChangePage() )
1080 {
1081 // The current contents is invalid so reset it back to the last
1082 // known good page index.
1083 SetPageNumber(m_page);
1084 }
1085
1086 event.Skip();
1087 }
1088
1089 void OnTextEnter(wxCommandEvent& WXUNUSED(event))
1090 {
1091 DoChangePage();
1092 }
1093
1094
1095 wxPreviewControlBar * const m_preview;
1096
1097 const int m_minPage,
1098 m_maxPage;
1099
1100 // This is the last valid page value that we had, we revert to it if an
1101 // invalid page is entered.
1102 int m_page;
1103
1104 wxDECLARE_NO_COPY_CLASS(wxPrintPageTextCtrl);
1105 };
1106
1107 //----------------------------------------------------------------------------
1108 // wxPreviewControlBar
1109 //----------------------------------------------------------------------------
1110
1111 IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
1112
1113 BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
1114 EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
1115 EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrintButton)
1116 EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
1117 EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
1118 EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
1119 EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
1120 EVT_BUTTON(wxID_PREVIEW_ZOOM_IN, wxPreviewControlBar::OnZoomInButton)
1121 EVT_BUTTON(wxID_PREVIEW_ZOOM_OUT, wxPreviewControlBar::OnZoomOutButton)
1122
1123 EVT_UPDATE_UI(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnUpdatePreviousButton)
1124 EVT_UPDATE_UI(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnUpdateNextButton)
1125 EVT_UPDATE_UI(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnUpdateFirstButton)
1126 EVT_UPDATE_UI(wxID_PREVIEW_LAST, wxPreviewControlBar::OnUpdateLastButton)
1127 EVT_UPDATE_UI(wxID_PREVIEW_ZOOM_IN, wxPreviewControlBar::OnUpdateZoomInButton)
1128 EVT_UPDATE_UI(wxID_PREVIEW_ZOOM_OUT, wxPreviewControlBar::OnUpdateZoomOutButton)
1129
1130 EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoomChoice)
1131 EVT_PAINT(wxPreviewControlBar::OnPaint)
1132
1133 END_EVENT_TABLE()
1134
1135 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
1136 wxWindow *parent, const wxPoint& pos, const wxSize& size,
1137 long style, const wxString& name):
1138 wxPanel(parent, wxID_ANY, pos, size, style, name)
1139 {
1140 m_printPreview = preview;
1141 m_closeButton = NULL;
1142 m_zoomControl = NULL;
1143 m_currentPageText = NULL;
1144 m_buttonFlags = buttons;
1145 }
1146
1147 wxPreviewControlBar::~wxPreviewControlBar()
1148 {
1149 }
1150
1151 void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
1152 {
1153 wxPaintDC dc(this);
1154
1155 int w, h;
1156 GetSize(&w, &h);
1157 dc.SetPen(*wxBLACK_PEN);
1158 dc.SetBrush(*wxTRANSPARENT_BRUSH);
1159 dc.DrawLine( 0, h-1, w, h-1 );
1160 }
1161
1162 void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
1163 {
1164 wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
1165 frame->Close(true);
1166 }
1167
1168 void wxPreviewControlBar::OnPrint(void)
1169 {
1170 wxPrintPreviewBase *preview = GetPrintPreview();
1171 preview->Print(true);
1172 }
1173
1174 void wxPreviewControlBar::OnNext()
1175 {
1176 if ( IsNextEnabled() )
1177 DoGotoPage(GetPrintPreview()->GetCurrentPage() + 1);
1178 }
1179
1180 void wxPreviewControlBar::OnPrevious()
1181 {
1182 if ( IsPreviousEnabled() )
1183 DoGotoPage(GetPrintPreview()->GetCurrentPage() - 1);
1184 }
1185
1186 void wxPreviewControlBar::OnFirst()
1187 {
1188 if ( IsFirstEnabled() )
1189 DoGotoPage(GetPrintPreview()->GetMinPage());
1190 }
1191
1192 void wxPreviewControlBar::OnLast()
1193 {
1194 if ( IsLastEnabled() )
1195 DoGotoPage(GetPrintPreview()->GetMaxPage());
1196 }
1197
1198 bool wxPreviewControlBar::IsNextEnabled() const
1199 {
1200 wxPrintPreviewBase *preview = GetPrintPreview();
1201 if ( !preview )
1202 return false;
1203
1204 const int currentPage = preview->GetCurrentPage();
1205 return currentPage < preview->GetMaxPage() &&
1206 preview->GetPrintout()->HasPage(currentPage + 1);
1207 }
1208
1209 bool wxPreviewControlBar::IsPreviousEnabled() const
1210 {
1211 wxPrintPreviewBase *preview = GetPrintPreview();
1212 if ( !preview )
1213 return false;
1214
1215 const int currentPage = preview->GetCurrentPage();
1216 return currentPage > preview->GetMinPage() &&
1217 preview->GetPrintout()->HasPage(currentPage - 1);
1218 }
1219
1220 bool wxPreviewControlBar::IsFirstEnabled() const
1221 {
1222 wxPrintPreviewBase *preview = GetPrintPreview();
1223 if (!preview)
1224 return false;
1225
1226 return preview->GetPrintout()->HasPage(preview->GetMinPage());
1227 }
1228
1229 bool wxPreviewControlBar::IsLastEnabled() const
1230 {
1231 wxPrintPreviewBase *preview = GetPrintPreview();
1232 if (!preview)
1233 return false;
1234
1235 return preview->GetPrintout()->HasPage(preview->GetMaxPage());
1236 }
1237
1238 void wxPreviewControlBar::DoGotoPage(int page)
1239 {
1240 wxPrintPreviewBase *preview = GetPrintPreview();
1241 wxCHECK_RET( preview, "Shouldn't be called if there is no preview." );
1242
1243 preview->SetCurrentPage(page);
1244
1245 if ( m_currentPageText )
1246 m_currentPageText->SetPageNumber(page);
1247 }
1248
1249 void wxPreviewControlBar::OnGotoPage()
1250 {
1251 wxPrintPreviewBase *preview = GetPrintPreview();
1252 if (preview)
1253 {
1254 if (preview->GetMinPage() > 0)
1255 {
1256 long currentPage = m_currentPageText->GetPageNumber();
1257 if ( currentPage )
1258 {
1259 if (preview->GetPrintout()->HasPage(currentPage))
1260 {
1261 preview->SetCurrentPage(currentPage);
1262 }
1263 }
1264 }
1265 }
1266 }
1267
1268 void wxPreviewControlBar::DoZoom()
1269 {
1270 int zoom = GetZoomControl();
1271 if (GetPrintPreview())
1272 GetPrintPreview()->SetZoom(zoom);
1273 }
1274
1275 bool wxPreviewControlBar::IsZoomInEnabled() const
1276 {
1277 if ( !m_zoomControl )
1278 return false;
1279
1280 const unsigned sel = m_zoomControl->GetSelection();
1281 return sel < m_zoomControl->GetCount() - 1;
1282 }
1283
1284 bool wxPreviewControlBar::IsZoomOutEnabled() const
1285 {
1286 return m_zoomControl && m_zoomControl->GetSelection() > 0;
1287 }
1288
1289 void wxPreviewControlBar::DoZoomIn()
1290 {
1291 if (IsZoomInEnabled())
1292 {
1293 m_zoomControl->SetSelection(m_zoomControl->GetSelection() + 1);
1294 DoZoom();
1295 }
1296 }
1297
1298 void wxPreviewControlBar::DoZoomOut()
1299 {
1300 if (IsZoomOutEnabled())
1301 {
1302 m_zoomControl->SetSelection(m_zoomControl->GetSelection() - 1);
1303 DoZoom();
1304 }
1305 }
1306
1307 namespace
1308 {
1309
1310 // Helper class used by wxPreviewControlBar::CreateButtons() to add buttons
1311 // sequentially to it in the simplest way possible.
1312 class SizerWithButtons
1313 {
1314 public:
1315 // Constructor creates the sizer that will hold the buttons and stores the
1316 // parent that will be used for their creation.
1317 SizerWithButtons(wxWindow *parent)
1318 : m_sizer(new wxBoxSizer(wxHORIZONTAL)),
1319 m_parent(parent)
1320 {
1321 m_hasContents =
1322 m_needsSeparator = false;
1323 }
1324
1325 // Destructor associates the sizer with the parent window.
1326 ~SizerWithButtons()
1327 {
1328 m_parent->SetSizer(m_sizer);
1329 m_sizer->Fit(m_parent);
1330 }
1331
1332
1333 // Add an arbitrary window to the sizer.
1334 void Add(wxWindow *win)
1335 {
1336 if ( m_needsSeparator )
1337 {
1338 m_needsSeparator = false;
1339
1340 m_sizer->AddSpacer(2*wxSizerFlags::GetDefaultBorder());
1341 }
1342
1343 m_hasContents = true;
1344
1345 m_sizer->Add(win,
1346 wxSizerFlags().Border(wxLEFT | wxTOP | wxBOTTOM).Center());
1347 }
1348
1349 // Add a button with the specified id, bitmap and tooltip.
1350 void AddButton(wxWindowID btnId,
1351 const wxArtID& artId,
1352 const wxString& tooltip)
1353 {
1354 // We don't use (smaller) images inside a button with a text label but
1355 // rather toolbar-like bitmap buttons hence use wxART_TOOLBAR and not
1356 // wxART_BUTTON here.
1357 wxBitmap bmp = wxArtProvider::GetBitmap(artId, wxART_TOOLBAR);
1358 wxBitmapButton * const btn = new wxBitmapButton(m_parent, btnId, bmp);
1359 btn->SetToolTip(tooltip);
1360
1361 Add(btn);
1362 }
1363
1364 // Add a control at the right end of the window. This should be called last
1365 // as everything else added after it will be added on the right side too.
1366 void AddAtEnd(wxWindow *win)
1367 {
1368 m_sizer->AddStretchSpacer();
1369 m_sizer->Add(win,
1370 wxSizerFlags().Border(wxTOP | wxBOTTOM | wxRIGHT).Center());
1371 }
1372
1373 // Indicates the end of a group of buttons, a separator will be added after
1374 // it.
1375 void EndOfGroup()
1376 {
1377 if ( m_hasContents )
1378 {
1379 m_needsSeparator = true;
1380 m_hasContents = false;
1381 }
1382 }
1383
1384 private:
1385 wxSizer * const m_sizer;
1386 wxWindow * const m_parent;
1387
1388 // If true, we have some controls since the last group beginning. This is
1389 // used to avoid inserting two consecutive separators if EndOfGroup() is
1390 // called twice.
1391 bool m_hasContents;
1392
1393 // If true, a separator should be inserted before adding the next button.
1394 bool m_needsSeparator;
1395
1396 wxDECLARE_NO_COPY_CLASS(SizerWithButtons);
1397 };
1398
1399 } // anonymous namespace
1400
1401 void wxPreviewControlBar::CreateButtons()
1402 {
1403 SetSize(0, 0, 400, 40);
1404
1405 SizerWithButtons sizer(this);
1406
1407 // Print button group (a single button).
1408 if (m_buttonFlags & wxPREVIEW_PRINT)
1409 {
1410 sizer.AddButton(wxID_PREVIEW_PRINT, wxART_PRINT, _("Print"));
1411 sizer.EndOfGroup();
1412 }
1413
1414 // Page selection buttons group.
1415 if (m_buttonFlags & wxPREVIEW_FIRST)
1416 {
1417 sizer.AddButton(wxID_PREVIEW_FIRST, wxART_GOTO_FIRST, _("First page"));
1418 }
1419
1420 if (m_buttonFlags & wxPREVIEW_PREVIOUS)
1421 {
1422 sizer.AddButton(wxID_PREVIEW_PREVIOUS, wxART_GO_BACK, _("Previous page"));
1423 }
1424
1425 if (m_buttonFlags & wxPREVIEW_GOTO)
1426 {
1427 int minPage, maxPage, pageFrom, pageTo;
1428 m_printPreview->GetPrintout()->GetPageInfo(&minPage, &maxPage,
1429 &pageFrom, &pageTo);
1430
1431 m_currentPageText = new wxPrintPageTextCtrl(this, minPage, maxPage);
1432 sizer.Add(m_currentPageText);
1433
1434 wxStaticText *
1435 maxPageText = new wxStaticText(this, wxID_ANY,
1436 wxString::Format("/ %d", maxPage));
1437
1438 sizer.Add(maxPageText);
1439 }
1440
1441 if (m_buttonFlags & wxPREVIEW_NEXT)
1442 {
1443 sizer.AddButton(wxID_PREVIEW_NEXT, wxART_GO_FORWARD, _("Next page"));
1444 }
1445
1446 if (m_buttonFlags & wxPREVIEW_LAST)
1447 {
1448 sizer.AddButton(wxID_PREVIEW_LAST, wxART_GOTO_LAST, _("Last page"));
1449 }
1450
1451 sizer.EndOfGroup();
1452
1453 // Zoom controls group.
1454 if (m_buttonFlags & wxPREVIEW_ZOOM)
1455 {
1456 sizer.AddButton(wxID_PREVIEW_ZOOM_OUT, wxART_MINUS, _("Zoom Out"));
1457
1458 wxString choices[] =
1459 {
1460 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1461 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1462 wxT("120%"), wxT("150%"), wxT("200%")
1463 };
1464 int n = WXSIZEOF(choices);
1465
1466 m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,wxDefaultCoord), n, choices, 0 );
1467 sizer.Add(m_zoomControl);
1468 SetZoomControl(m_printPreview->GetZoom());
1469
1470 sizer.AddButton(wxID_PREVIEW_ZOOM_IN, wxART_PLUS, _("Zoom In"));
1471
1472 sizer.EndOfGroup();
1473 }
1474
1475 // Close button group (single button again).
1476 m_closeButton = new wxButton(this, wxID_PREVIEW_CLOSE, _("&Close"));
1477 sizer.AddAtEnd(m_closeButton);
1478 }
1479
1480 void wxPreviewControlBar::SetZoomControl(int zoom)
1481 {
1482 if (m_zoomControl)
1483 {
1484 int n, count = m_zoomControl->GetCount();
1485 long val;
1486 for (n=0; n<count; n++)
1487 {
1488 if (m_zoomControl->GetString(n).BeforeFirst(wxT('%')).ToLong(&val) &&
1489 (val >= long(zoom)))
1490 {
1491 m_zoomControl->SetSelection(n);
1492 return;
1493 }
1494 }
1495
1496 m_zoomControl->SetSelection(count-1);
1497 }
1498 }
1499
1500 int wxPreviewControlBar::GetZoomControl()
1501 {
1502 if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxEmptyString))
1503 {
1504 long val;
1505 if (m_zoomControl->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val))
1506 return int(val);
1507 }
1508
1509 return 0;
1510 }
1511
1512
1513 /*
1514 * Preview frame
1515 */
1516
1517 IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
1518
1519 BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
1520 EVT_CHAR_HOOK(wxPreviewFrame::OnChar)
1521 EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
1522 END_EVENT_TABLE()
1523
1524 void wxPreviewFrame::OnChar(wxKeyEvent &event)
1525 {
1526 if ( event.GetKeyCode() == WXK_ESCAPE )
1527 {
1528 Close(true);
1529 }
1530 else
1531 {
1532 event.Skip();
1533 }
1534 }
1535
1536 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title,
1537 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
1538 wxFrame(parent, wxID_ANY, title, pos, size, style, name)
1539 {
1540 m_printPreview = preview;
1541 m_controlBar = NULL;
1542 m_previewCanvas = NULL;
1543 m_windowDisabler = NULL;
1544
1545 // Give the application icon
1546 #ifdef __WXMSW__
1547 wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
1548 if (topFrame)
1549 SetIcons(topFrame->GetIcons());
1550 #endif
1551 }
1552
1553 wxPreviewFrame::~wxPreviewFrame()
1554 {
1555 }
1556
1557 void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
1558 {
1559 if (m_windowDisabler)
1560 delete m_windowDisabler;
1561
1562 // Need to delete the printout and the print preview
1563 wxPrintout *printout = m_printPreview->GetPrintout();
1564 if (printout)
1565 {
1566 delete printout;
1567 m_printPreview->SetPrintout(NULL);
1568 m_printPreview->SetCanvas(NULL);
1569 m_printPreview->SetFrame(NULL);
1570 }
1571
1572 m_previewCanvas->SetPreview(NULL);
1573 wxDELETE(m_printPreview);
1574
1575 Destroy();
1576 }
1577
1578 void wxPreviewFrame::Initialize()
1579 {
1580 #if wxUSE_STATUSBAR
1581 CreateStatusBar();
1582 #endif
1583 CreateCanvas();
1584 CreateControlBar();
1585
1586 m_printPreview->SetCanvas(m_previewCanvas);
1587 m_printPreview->SetFrame(this);
1588
1589 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
1590
1591 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
1592 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
1593
1594 SetAutoLayout( true );
1595 SetSizer( item0 );
1596
1597 m_windowDisabler = new wxWindowDisabler(this);
1598
1599 Layout();
1600
1601 m_printPreview->AdjustScrollbars(m_previewCanvas);
1602 m_previewCanvas->SetFocus();
1603 m_controlBar->SetFocus();
1604 }
1605
1606 void wxPreviewFrame::CreateCanvas()
1607 {
1608 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
1609 }
1610
1611 void wxPreviewFrame::CreateControlBar()
1612 {
1613 long buttons = wxPREVIEW_DEFAULT;
1614 if (m_printPreview->GetPrintoutForPrinting())
1615 buttons |= wxPREVIEW_PRINT;
1616
1617 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0,0), wxSize(400, 40));
1618 m_controlBar->CreateButtons();
1619 }
1620
1621 /*
1622 * Print preview
1623 */
1624
1625 IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
1626
1627 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
1628 wxPrintout *printoutForPrinting,
1629 wxPrintData *data)
1630 {
1631 if (data)
1632 m_printDialogData = (*data);
1633
1634 Init(printout, printoutForPrinting);
1635 }
1636
1637 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
1638 wxPrintout *printoutForPrinting,
1639 wxPrintDialogData *data)
1640 {
1641 if (data)
1642 m_printDialogData = (*data);
1643
1644 Init(printout, printoutForPrinting);
1645 }
1646
1647 void wxPrintPreviewBase::Init(wxPrintout *printout,
1648 wxPrintout *printoutForPrinting)
1649 {
1650 m_isOk = true;
1651 m_previewPrintout = printout;
1652 if (m_previewPrintout)
1653 m_previewPrintout->SetPreview(static_cast<wxPrintPreview *>(this));
1654
1655 m_printPrintout = printoutForPrinting;
1656
1657 m_previewCanvas = NULL;
1658 m_previewFrame = NULL;
1659 m_previewBitmap = NULL;
1660 m_previewFailed = false;
1661 m_currentPage = 1;
1662 m_currentZoom = 70;
1663 m_topMargin = 40;
1664 m_leftMargin = 40;
1665 m_pageWidth = 0;
1666 m_pageHeight = 0;
1667 m_printingPrepared = false;
1668 m_minPage = 1;
1669 m_maxPage = 1;
1670 }
1671
1672 wxPrintPreviewBase::~wxPrintPreviewBase()
1673 {
1674 if (m_previewPrintout)
1675 delete m_previewPrintout;
1676 if (m_previewBitmap)
1677 delete m_previewBitmap;
1678 if (m_printPrintout)
1679 delete m_printPrintout;
1680 }
1681
1682 bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
1683 {
1684 if (m_currentPage == pageNum)
1685 return true;
1686
1687 m_currentPage = pageNum;
1688
1689 InvalidatePreviewBitmap();
1690
1691 if (m_previewCanvas)
1692 {
1693 AdjustScrollbars(m_previewCanvas);
1694
1695 m_previewCanvas->Refresh();
1696 m_previewCanvas->SetFocus();
1697 }
1698 return true;
1699 }
1700
1701 int wxPrintPreviewBase::GetCurrentPage() const
1702 { return m_currentPage; }
1703 void wxPrintPreviewBase::SetPrintout(wxPrintout *printout)
1704 { m_previewPrintout = printout; }
1705 wxPrintout *wxPrintPreviewBase::GetPrintout() const
1706 { return m_previewPrintout; }
1707 wxPrintout *wxPrintPreviewBase::GetPrintoutForPrinting() const
1708 { return m_printPrintout; }
1709 void wxPrintPreviewBase::SetFrame(wxFrame *frame)
1710 { m_previewFrame = frame; }
1711 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas *canvas)
1712 { m_previewCanvas = canvas; }
1713 wxFrame *wxPrintPreviewBase::GetFrame() const
1714 { return m_previewFrame; }
1715 wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
1716 { return m_previewCanvas; }
1717
1718 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas *canvas, wxRect& pageRect, wxRect& paperRect)
1719 {
1720 // Calculate the rectangles for the printable area of the page and the
1721 // entire paper as they appear on the canvas on-screen.
1722 int canvasWidth, canvasHeight;
1723 canvas->GetSize(&canvasWidth, &canvasHeight);
1724
1725 float zoomScale = float(m_currentZoom) / 100;
1726 float screenPrintableWidth = zoomScale * m_pageWidth * m_previewScaleX;
1727 float screenPrintableHeight = zoomScale * m_pageHeight * m_previewScaleY;
1728
1729 wxRect devicePaperRect = m_previewPrintout->GetPaperRectPixels();
1730 wxCoord devicePrintableWidth, devicePrintableHeight;
1731 m_previewPrintout->GetPageSizePixels(&devicePrintableWidth, &devicePrintableHeight);
1732 float scaleX = screenPrintableWidth / devicePrintableWidth;
1733 float scaleY = screenPrintableHeight / devicePrintableHeight;
1734 paperRect.width = wxCoord(scaleX * devicePaperRect.width);
1735 paperRect.height = wxCoord(scaleY * devicePaperRect.height);
1736
1737 paperRect.x = wxCoord((canvasWidth - paperRect.width)/ 2.0);
1738 if (paperRect.x < m_leftMargin)
1739 paperRect.x = m_leftMargin;
1740 paperRect.y = wxCoord((canvasHeight - paperRect.height)/ 2.0);
1741 if (paperRect.y < m_topMargin)
1742 paperRect.y = m_topMargin;
1743
1744 pageRect.x = paperRect.x - wxCoord(scaleX * devicePaperRect.x);
1745 pageRect.y = paperRect.y - wxCoord(scaleY * devicePaperRect.y);
1746 pageRect.width = wxCoord(screenPrintableWidth);
1747 pageRect.height = wxCoord(screenPrintableHeight);
1748 }
1749
1750
1751 void wxPrintPreviewBase::InvalidatePreviewBitmap()
1752 {
1753 wxDELETE(m_previewBitmap);
1754 // if there was a problem with rendering the preview, try again now
1755 // that it changed in some way (less memory may be needed, for example):
1756 m_previewFailed = false;
1757 }
1758
1759 bool wxPrintPreviewBase::UpdatePageRendering()
1760 {
1761 if ( m_previewBitmap )
1762 return false;
1763
1764 if ( m_previewFailed )
1765 return false;
1766
1767 if ( !RenderPage(m_currentPage) )
1768 {
1769 m_previewFailed = true; // don't waste time failing again
1770 return false;
1771 }
1772
1773 return true;
1774 }
1775
1776 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
1777 {
1778 DrawBlankPage(canvas, dc);
1779
1780 if (!m_previewBitmap)
1781 return false;
1782 if (!canvas)
1783 return false;
1784
1785 wxRect pageRect, paperRect;
1786 CalcRects(canvas, pageRect, paperRect);
1787 wxMemoryDC temp_dc;
1788 temp_dc.SelectObject(*m_previewBitmap);
1789
1790 dc.Blit(pageRect.x, pageRect.y,
1791 m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
1792
1793 temp_dc.SelectObject(wxNullBitmap);
1794 return true;
1795 }
1796
1797 // Adjusts the scrollbars for the current scale
1798 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
1799 {
1800 if (!canvas)
1801 return ;
1802
1803 wxRect pageRect, paperRect;
1804 CalcRects(canvas, pageRect, paperRect);
1805 int totalWidth = paperRect.width + 2 * m_leftMargin;
1806 int totalHeight = paperRect.height + 2 * m_topMargin;
1807 int scrollUnitsX = totalWidth / 10;
1808 int scrollUnitsY = totalHeight / 10;
1809 wxSize virtualSize = canvas->GetVirtualSize();
1810 if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
1811 canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
1812 }
1813
1814 bool wxPrintPreviewBase::RenderPageIntoDC(wxDC& dc, int pageNum)
1815 {
1816 m_previewPrintout->SetDC(&dc);
1817 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
1818
1819 // Need to delay OnPreparePrinting() until here, so we have enough
1820 // information.
1821 if (!m_printingPrepared)
1822 {
1823 m_previewPrintout->OnPreparePrinting();
1824 int selFrom, selTo;
1825 m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
1826 m_printingPrepared = true;
1827 }
1828
1829 m_previewPrintout->OnBeginPrinting();
1830
1831 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
1832 {
1833 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
1834 return false;
1835 }
1836
1837 m_previewPrintout->OnPrintPage(pageNum);
1838 m_previewPrintout->OnEndDocument();
1839 m_previewPrintout->OnEndPrinting();
1840
1841 m_previewPrintout->SetDC(NULL);
1842
1843 return true;
1844 }
1845
1846 bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum)
1847 {
1848 wxMemoryDC memoryDC;
1849 memoryDC.SelectObject(bmp);
1850 memoryDC.Clear();
1851
1852 return RenderPageIntoDC(memoryDC, pageNum);
1853 }
1854
1855 bool wxPrintPreviewBase::RenderPage(int pageNum)
1856 {
1857 wxBusyCursor busy;
1858
1859 if (!m_previewCanvas)
1860 {
1861 wxFAIL_MSG(wxT("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1862 return false;
1863 }
1864
1865 wxRect pageRect, paperRect;
1866 CalcRects(m_previewCanvas, pageRect, paperRect);
1867
1868 if (!m_previewBitmap)
1869 {
1870 m_previewBitmap = new wxBitmap(pageRect.width, pageRect.height);
1871
1872 if (!m_previewBitmap || !m_previewBitmap->Ok())
1873 {
1874 InvalidatePreviewBitmap();
1875 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
1876 return false;
1877 }
1878 }
1879
1880 if ( !RenderPageIntoBitmap(*m_previewBitmap, pageNum) )
1881 {
1882 InvalidatePreviewBitmap();
1883 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
1884 return false;
1885 }
1886
1887 #if wxUSE_STATUSBAR
1888 wxString status;
1889 if (m_maxPage != 0)
1890 status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
1891 else
1892 status = wxString::Format(_("Page %d"), pageNum);
1893
1894 if (m_previewFrame)
1895 m_previewFrame->SetStatusText(status);
1896 #endif
1897
1898 return true;
1899 }
1900
1901 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
1902 {
1903 wxRect pageRect, paperRect;
1904
1905 CalcRects(canvas, pageRect, paperRect);
1906
1907 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1908 wxCoord shadowOffset = 4;
1909
1910 dc.SetPen(*wxBLACK_PEN);
1911 dc.SetBrush(*wxBLACK_BRUSH);
1912 dc.DrawRectangle(paperRect.x + shadowOffset, paperRect.y + paperRect.height + 1,
1913 paperRect.width, shadowOffset);
1914
1915 dc.DrawRectangle(paperRect.x + paperRect.width, paperRect.y + shadowOffset,
1916 shadowOffset, paperRect.height);
1917
1918 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1919 dc.SetPen(*wxBLACK_PEN);
1920 dc.SetBrush(*wxWHITE_BRUSH);
1921 dc.DrawRectangle(paperRect.x - 2, paperRect.y - 1,
1922 paperRect.width + 3, paperRect.height + 2);
1923
1924 return true;
1925 }
1926
1927 void wxPrintPreviewBase::SetZoom(int percent)
1928 {
1929 if (m_currentZoom == percent)
1930 return;
1931
1932 m_currentZoom = percent;
1933
1934 InvalidatePreviewBitmap();
1935
1936 if (m_previewCanvas)
1937 {
1938 AdjustScrollbars(m_previewCanvas);
1939 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
1940 m_previewCanvas->ClearBackground();
1941 m_previewCanvas->Refresh();
1942 m_previewCanvas->SetFocus();
1943 }
1944 }
1945
1946 wxPrintDialogData& wxPrintPreviewBase::GetPrintDialogData()
1947 {
1948 return m_printDialogData;
1949 }
1950
1951 int wxPrintPreviewBase::GetZoom() const
1952 { return m_currentZoom; }
1953 int wxPrintPreviewBase::GetMaxPage() const
1954 { return m_maxPage; }
1955 int wxPrintPreviewBase::GetMinPage() const
1956 { return m_minPage; }
1957 bool wxPrintPreviewBase::IsOk() const
1958 { return m_isOk; }
1959 void wxPrintPreviewBase::SetOk(bool ok)
1960 { m_isOk = ok; }
1961
1962 //----------------------------------------------------------------------------
1963 // wxPrintPreview
1964 //----------------------------------------------------------------------------
1965
1966 IMPLEMENT_CLASS(wxPrintPreview, wxPrintPreviewBase)
1967
1968 wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1969 wxPrintout *printoutForPrinting,
1970 wxPrintDialogData *data) :
1971 wxPrintPreviewBase( printout, printoutForPrinting, data )
1972 {
1973 m_pimpl = wxPrintFactory::GetFactory()->
1974 CreatePrintPreview( printout, printoutForPrinting, data );
1975 }
1976
1977 wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1978 wxPrintout *printoutForPrinting,
1979 wxPrintData *data ) :
1980 wxPrintPreviewBase( printout, printoutForPrinting, data )
1981 {
1982 m_pimpl = wxPrintFactory::GetFactory()->
1983 CreatePrintPreview( printout, printoutForPrinting, data );
1984 }
1985
1986 wxPrintPreview::~wxPrintPreview()
1987 {
1988 delete m_pimpl;
1989
1990 // don't delete twice
1991 m_printPrintout = NULL;
1992 m_previewPrintout = NULL;
1993 m_previewBitmap = NULL;
1994 }
1995
1996 bool wxPrintPreview::SetCurrentPage(int pageNum)
1997 {
1998 return m_pimpl->SetCurrentPage( pageNum );
1999 }
2000
2001 int wxPrintPreview::GetCurrentPage() const
2002 {
2003 return m_pimpl->GetCurrentPage();
2004 }
2005
2006 void wxPrintPreview::SetPrintout(wxPrintout *printout)
2007 {
2008 m_pimpl->SetPrintout( printout );
2009 }
2010
2011 wxPrintout *wxPrintPreview::GetPrintout() const
2012 {
2013 return m_pimpl->GetPrintout();
2014 }
2015
2016 wxPrintout *wxPrintPreview::GetPrintoutForPrinting() const
2017 {
2018 return m_pimpl->GetPrintoutForPrinting();
2019 }
2020
2021 void wxPrintPreview::SetFrame(wxFrame *frame)
2022 {
2023 m_pimpl->SetFrame( frame );
2024 }
2025
2026 void wxPrintPreview::SetCanvas(wxPreviewCanvas *canvas)
2027 {
2028 m_pimpl->SetCanvas( canvas );
2029 }
2030
2031 wxFrame *wxPrintPreview::GetFrame() const
2032 {
2033 return m_pimpl->GetFrame();
2034 }
2035
2036 wxPreviewCanvas *wxPrintPreview::GetCanvas() const
2037 {
2038 return m_pimpl->GetCanvas();
2039 }
2040
2041 bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
2042 {
2043 return m_pimpl->PaintPage( canvas, dc );
2044 }
2045
2046 bool wxPrintPreview::UpdatePageRendering()
2047 {
2048 return m_pimpl->UpdatePageRendering();
2049 }
2050
2051 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
2052 {
2053 return m_pimpl->DrawBlankPage( canvas, dc );
2054 }
2055
2056 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas *canvas)
2057 {
2058 m_pimpl->AdjustScrollbars( canvas );
2059 }
2060
2061 bool wxPrintPreview::RenderPage(int pageNum)
2062 {
2063 return m_pimpl->RenderPage( pageNum );
2064 }
2065
2066 void wxPrintPreview::SetZoom(int percent)
2067 {
2068 m_pimpl->SetZoom( percent );
2069 }
2070
2071 int wxPrintPreview::GetZoom() const
2072 {
2073 return m_pimpl->GetZoom();
2074 }
2075
2076 wxPrintDialogData& wxPrintPreview::GetPrintDialogData()
2077 {
2078 return m_pimpl->GetPrintDialogData();
2079 }
2080
2081 int wxPrintPreview::GetMaxPage() const
2082 {
2083 return m_pimpl->GetMaxPage();
2084 }
2085
2086 int wxPrintPreview::GetMinPage() const
2087 {
2088 return m_pimpl->GetMinPage();
2089 }
2090
2091 bool wxPrintPreview::IsOk() const
2092 {
2093 return m_pimpl->Ok();
2094 }
2095
2096 void wxPrintPreview::SetOk(bool ok)
2097 {
2098 m_pimpl->SetOk( ok );
2099 }
2100
2101 bool wxPrintPreview::Print(bool interactive)
2102 {
2103 return m_pimpl->Print( interactive );
2104 }
2105
2106 void wxPrintPreview::DetermineScaling()
2107 {
2108 m_pimpl->DetermineScaling();
2109 }
2110
2111 #endif // wxUSE_PRINTING_ARCHITECTURE