]> git.saurik.com Git - wxWidgets.git/blob - src/common/prntbase.cpp
Don't hardcode wxPreviewControlBar size in print preview code.
[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 SizerWithButtons sizer(this);
1404
1405 // Print button group (a single button).
1406 if (m_buttonFlags & wxPREVIEW_PRINT)
1407 {
1408 sizer.AddButton(wxID_PREVIEW_PRINT, wxART_PRINT, _("Print"));
1409 sizer.EndOfGroup();
1410 }
1411
1412 // Page selection buttons group.
1413 if (m_buttonFlags & wxPREVIEW_FIRST)
1414 {
1415 sizer.AddButton(wxID_PREVIEW_FIRST, wxART_GOTO_FIRST, _("First page"));
1416 }
1417
1418 if (m_buttonFlags & wxPREVIEW_PREVIOUS)
1419 {
1420 sizer.AddButton(wxID_PREVIEW_PREVIOUS, wxART_GO_BACK, _("Previous page"));
1421 }
1422
1423 if (m_buttonFlags & wxPREVIEW_GOTO)
1424 {
1425 int minPage, maxPage, pageFrom, pageTo;
1426 m_printPreview->GetPrintout()->GetPageInfo(&minPage, &maxPage,
1427 &pageFrom, &pageTo);
1428
1429 m_currentPageText = new wxPrintPageTextCtrl(this, minPage, maxPage);
1430 sizer.Add(m_currentPageText);
1431
1432 wxStaticText *
1433 maxPageText = new wxStaticText(this, wxID_ANY,
1434 wxString::Format("/ %d", maxPage));
1435
1436 sizer.Add(maxPageText);
1437 }
1438
1439 if (m_buttonFlags & wxPREVIEW_NEXT)
1440 {
1441 sizer.AddButton(wxID_PREVIEW_NEXT, wxART_GO_FORWARD, _("Next page"));
1442 }
1443
1444 if (m_buttonFlags & wxPREVIEW_LAST)
1445 {
1446 sizer.AddButton(wxID_PREVIEW_LAST, wxART_GOTO_LAST, _("Last page"));
1447 }
1448
1449 sizer.EndOfGroup();
1450
1451 // Zoom controls group.
1452 if (m_buttonFlags & wxPREVIEW_ZOOM)
1453 {
1454 sizer.AddButton(wxID_PREVIEW_ZOOM_OUT, wxART_MINUS, _("Zoom Out"));
1455
1456 wxString choices[] =
1457 {
1458 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
1459 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
1460 wxT("120%"), wxT("150%"), wxT("200%")
1461 };
1462 int n = WXSIZEOF(choices);
1463
1464 m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,wxDefaultCoord), n, choices, 0 );
1465 sizer.Add(m_zoomControl);
1466 SetZoomControl(m_printPreview->GetZoom());
1467
1468 sizer.AddButton(wxID_PREVIEW_ZOOM_IN, wxART_PLUS, _("Zoom In"));
1469
1470 sizer.EndOfGroup();
1471 }
1472
1473 // Close button group (single button again).
1474 m_closeButton = new wxButton(this, wxID_PREVIEW_CLOSE, _("&Close"));
1475 sizer.AddAtEnd(m_closeButton);
1476 }
1477
1478 void wxPreviewControlBar::SetZoomControl(int zoom)
1479 {
1480 if (m_zoomControl)
1481 {
1482 int n, count = m_zoomControl->GetCount();
1483 long val;
1484 for (n=0; n<count; n++)
1485 {
1486 if (m_zoomControl->GetString(n).BeforeFirst(wxT('%')).ToLong(&val) &&
1487 (val >= long(zoom)))
1488 {
1489 m_zoomControl->SetSelection(n);
1490 return;
1491 }
1492 }
1493
1494 m_zoomControl->SetSelection(count-1);
1495 }
1496 }
1497
1498 int wxPreviewControlBar::GetZoomControl()
1499 {
1500 if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxEmptyString))
1501 {
1502 long val;
1503 if (m_zoomControl->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val))
1504 return int(val);
1505 }
1506
1507 return 0;
1508 }
1509
1510
1511 /*
1512 * Preview frame
1513 */
1514
1515 IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
1516
1517 BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
1518 EVT_CHAR_HOOK(wxPreviewFrame::OnChar)
1519 EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
1520 END_EVENT_TABLE()
1521
1522 void wxPreviewFrame::OnChar(wxKeyEvent &event)
1523 {
1524 if ( event.GetKeyCode() == WXK_ESCAPE )
1525 {
1526 Close(true);
1527 }
1528 else
1529 {
1530 event.Skip();
1531 }
1532 }
1533
1534 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title,
1535 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
1536 wxFrame(parent, wxID_ANY, title, pos, size, style, name)
1537 {
1538 m_printPreview = preview;
1539 m_controlBar = NULL;
1540 m_previewCanvas = NULL;
1541 m_windowDisabler = NULL;
1542
1543 // Give the application icon
1544 #ifdef __WXMSW__
1545 wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
1546 if (topFrame)
1547 SetIcons(topFrame->GetIcons());
1548 #endif
1549 }
1550
1551 wxPreviewFrame::~wxPreviewFrame()
1552 {
1553 }
1554
1555 void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
1556 {
1557 if (m_windowDisabler)
1558 delete m_windowDisabler;
1559
1560 // Need to delete the printout and the print preview
1561 wxPrintout *printout = m_printPreview->GetPrintout();
1562 if (printout)
1563 {
1564 delete printout;
1565 m_printPreview->SetPrintout(NULL);
1566 m_printPreview->SetCanvas(NULL);
1567 m_printPreview->SetFrame(NULL);
1568 }
1569
1570 m_previewCanvas->SetPreview(NULL);
1571 wxDELETE(m_printPreview);
1572
1573 Destroy();
1574 }
1575
1576 void wxPreviewFrame::Initialize()
1577 {
1578 #if wxUSE_STATUSBAR
1579 CreateStatusBar();
1580 #endif
1581 CreateCanvas();
1582 CreateControlBar();
1583
1584 m_printPreview->SetCanvas(m_previewCanvas);
1585 m_printPreview->SetFrame(this);
1586
1587 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
1588
1589 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
1590 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
1591
1592 SetAutoLayout( true );
1593 SetSizer( item0 );
1594
1595 m_windowDisabler = new wxWindowDisabler(this);
1596
1597 Layout();
1598
1599 m_printPreview->AdjustScrollbars(m_previewCanvas);
1600 m_previewCanvas->SetFocus();
1601 m_controlBar->SetFocus();
1602 }
1603
1604 void wxPreviewFrame::CreateCanvas()
1605 {
1606 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
1607 }
1608
1609 void wxPreviewFrame::CreateControlBar()
1610 {
1611 long buttons = wxPREVIEW_DEFAULT;
1612 if (m_printPreview->GetPrintoutForPrinting())
1613 buttons |= wxPREVIEW_PRINT;
1614
1615 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this);
1616 m_controlBar->CreateButtons();
1617 }
1618
1619 /*
1620 * Print preview
1621 */
1622
1623 IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
1624
1625 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
1626 wxPrintout *printoutForPrinting,
1627 wxPrintData *data)
1628 {
1629 if (data)
1630 m_printDialogData = (*data);
1631
1632 Init(printout, printoutForPrinting);
1633 }
1634
1635 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
1636 wxPrintout *printoutForPrinting,
1637 wxPrintDialogData *data)
1638 {
1639 if (data)
1640 m_printDialogData = (*data);
1641
1642 Init(printout, printoutForPrinting);
1643 }
1644
1645 void wxPrintPreviewBase::Init(wxPrintout *printout,
1646 wxPrintout *printoutForPrinting)
1647 {
1648 m_isOk = true;
1649 m_previewPrintout = printout;
1650 if (m_previewPrintout)
1651 m_previewPrintout->SetPreview(static_cast<wxPrintPreview *>(this));
1652
1653 m_printPrintout = printoutForPrinting;
1654
1655 m_previewCanvas = NULL;
1656 m_previewFrame = NULL;
1657 m_previewBitmap = NULL;
1658 m_previewFailed = false;
1659 m_currentPage = 1;
1660 m_currentZoom = 70;
1661 m_topMargin = 40;
1662 m_leftMargin = 40;
1663 m_pageWidth = 0;
1664 m_pageHeight = 0;
1665 m_printingPrepared = false;
1666 m_minPage = 1;
1667 m_maxPage = 1;
1668 }
1669
1670 wxPrintPreviewBase::~wxPrintPreviewBase()
1671 {
1672 if (m_previewPrintout)
1673 delete m_previewPrintout;
1674 if (m_previewBitmap)
1675 delete m_previewBitmap;
1676 if (m_printPrintout)
1677 delete m_printPrintout;
1678 }
1679
1680 bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
1681 {
1682 if (m_currentPage == pageNum)
1683 return true;
1684
1685 m_currentPage = pageNum;
1686
1687 InvalidatePreviewBitmap();
1688
1689 if (m_previewCanvas)
1690 {
1691 AdjustScrollbars(m_previewCanvas);
1692
1693 m_previewCanvas->Refresh();
1694 m_previewCanvas->SetFocus();
1695 }
1696 return true;
1697 }
1698
1699 int wxPrintPreviewBase::GetCurrentPage() const
1700 { return m_currentPage; }
1701 void wxPrintPreviewBase::SetPrintout(wxPrintout *printout)
1702 { m_previewPrintout = printout; }
1703 wxPrintout *wxPrintPreviewBase::GetPrintout() const
1704 { return m_previewPrintout; }
1705 wxPrintout *wxPrintPreviewBase::GetPrintoutForPrinting() const
1706 { return m_printPrintout; }
1707 void wxPrintPreviewBase::SetFrame(wxFrame *frame)
1708 { m_previewFrame = frame; }
1709 void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas *canvas)
1710 { m_previewCanvas = canvas; }
1711 wxFrame *wxPrintPreviewBase::GetFrame() const
1712 { return m_previewFrame; }
1713 wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
1714 { return m_previewCanvas; }
1715
1716 void wxPrintPreviewBase::CalcRects(wxPreviewCanvas *canvas, wxRect& pageRect, wxRect& paperRect)
1717 {
1718 // Calculate the rectangles for the printable area of the page and the
1719 // entire paper as they appear on the canvas on-screen.
1720 int canvasWidth, canvasHeight;
1721 canvas->GetSize(&canvasWidth, &canvasHeight);
1722
1723 float zoomScale = float(m_currentZoom) / 100;
1724 float screenPrintableWidth = zoomScale * m_pageWidth * m_previewScaleX;
1725 float screenPrintableHeight = zoomScale * m_pageHeight * m_previewScaleY;
1726
1727 wxRect devicePaperRect = m_previewPrintout->GetPaperRectPixels();
1728 wxCoord devicePrintableWidth, devicePrintableHeight;
1729 m_previewPrintout->GetPageSizePixels(&devicePrintableWidth, &devicePrintableHeight);
1730 float scaleX = screenPrintableWidth / devicePrintableWidth;
1731 float scaleY = screenPrintableHeight / devicePrintableHeight;
1732 paperRect.width = wxCoord(scaleX * devicePaperRect.width);
1733 paperRect.height = wxCoord(scaleY * devicePaperRect.height);
1734
1735 paperRect.x = wxCoord((canvasWidth - paperRect.width)/ 2.0);
1736 if (paperRect.x < m_leftMargin)
1737 paperRect.x = m_leftMargin;
1738 paperRect.y = wxCoord((canvasHeight - paperRect.height)/ 2.0);
1739 if (paperRect.y < m_topMargin)
1740 paperRect.y = m_topMargin;
1741
1742 pageRect.x = paperRect.x - wxCoord(scaleX * devicePaperRect.x);
1743 pageRect.y = paperRect.y - wxCoord(scaleY * devicePaperRect.y);
1744 pageRect.width = wxCoord(screenPrintableWidth);
1745 pageRect.height = wxCoord(screenPrintableHeight);
1746 }
1747
1748
1749 void wxPrintPreviewBase::InvalidatePreviewBitmap()
1750 {
1751 wxDELETE(m_previewBitmap);
1752 // if there was a problem with rendering the preview, try again now
1753 // that it changed in some way (less memory may be needed, for example):
1754 m_previewFailed = false;
1755 }
1756
1757 bool wxPrintPreviewBase::UpdatePageRendering()
1758 {
1759 if ( m_previewBitmap )
1760 return false;
1761
1762 if ( m_previewFailed )
1763 return false;
1764
1765 if ( !RenderPage(m_currentPage) )
1766 {
1767 m_previewFailed = true; // don't waste time failing again
1768 return false;
1769 }
1770
1771 return true;
1772 }
1773
1774 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
1775 {
1776 DrawBlankPage(canvas, dc);
1777
1778 if (!m_previewBitmap)
1779 return false;
1780 if (!canvas)
1781 return false;
1782
1783 wxRect pageRect, paperRect;
1784 CalcRects(canvas, pageRect, paperRect);
1785 wxMemoryDC temp_dc;
1786 temp_dc.SelectObject(*m_previewBitmap);
1787
1788 dc.Blit(pageRect.x, pageRect.y,
1789 m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
1790
1791 temp_dc.SelectObject(wxNullBitmap);
1792 return true;
1793 }
1794
1795 // Adjusts the scrollbars for the current scale
1796 void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
1797 {
1798 if (!canvas)
1799 return ;
1800
1801 wxRect pageRect, paperRect;
1802 CalcRects(canvas, pageRect, paperRect);
1803 int totalWidth = paperRect.width + 2 * m_leftMargin;
1804 int totalHeight = paperRect.height + 2 * m_topMargin;
1805 int scrollUnitsX = totalWidth / 10;
1806 int scrollUnitsY = totalHeight / 10;
1807 wxSize virtualSize = canvas->GetVirtualSize();
1808 if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
1809 canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
1810 }
1811
1812 bool wxPrintPreviewBase::RenderPageIntoDC(wxDC& dc, int pageNum)
1813 {
1814 m_previewPrintout->SetDC(&dc);
1815 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
1816
1817 // Need to delay OnPreparePrinting() until here, so we have enough
1818 // information.
1819 if (!m_printingPrepared)
1820 {
1821 m_previewPrintout->OnPreparePrinting();
1822 int selFrom, selTo;
1823 m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
1824 m_printingPrepared = true;
1825 }
1826
1827 m_previewPrintout->OnBeginPrinting();
1828
1829 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
1830 {
1831 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
1832 return false;
1833 }
1834
1835 m_previewPrintout->OnPrintPage(pageNum);
1836 m_previewPrintout->OnEndDocument();
1837 m_previewPrintout->OnEndPrinting();
1838
1839 m_previewPrintout->SetDC(NULL);
1840
1841 return true;
1842 }
1843
1844 bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum)
1845 {
1846 wxMemoryDC memoryDC;
1847 memoryDC.SelectObject(bmp);
1848 memoryDC.Clear();
1849
1850 return RenderPageIntoDC(memoryDC, pageNum);
1851 }
1852
1853 bool wxPrintPreviewBase::RenderPage(int pageNum)
1854 {
1855 wxBusyCursor busy;
1856
1857 if (!m_previewCanvas)
1858 {
1859 wxFAIL_MSG(wxT("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
1860 return false;
1861 }
1862
1863 wxRect pageRect, paperRect;
1864 CalcRects(m_previewCanvas, pageRect, paperRect);
1865
1866 if (!m_previewBitmap)
1867 {
1868 m_previewBitmap = new wxBitmap(pageRect.width, pageRect.height);
1869
1870 if (!m_previewBitmap || !m_previewBitmap->Ok())
1871 {
1872 InvalidatePreviewBitmap();
1873 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
1874 return false;
1875 }
1876 }
1877
1878 if ( !RenderPageIntoBitmap(*m_previewBitmap, pageNum) )
1879 {
1880 InvalidatePreviewBitmap();
1881 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
1882 return false;
1883 }
1884
1885 #if wxUSE_STATUSBAR
1886 wxString status;
1887 if (m_maxPage != 0)
1888 status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
1889 else
1890 status = wxString::Format(_("Page %d"), pageNum);
1891
1892 if (m_previewFrame)
1893 m_previewFrame->SetStatusText(status);
1894 #endif
1895
1896 return true;
1897 }
1898
1899 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
1900 {
1901 wxRect pageRect, paperRect;
1902
1903 CalcRects(canvas, pageRect, paperRect);
1904
1905 // Draw shadow, allowing for 1-pixel border AROUND the actual paper
1906 wxCoord shadowOffset = 4;
1907
1908 dc.SetPen(*wxBLACK_PEN);
1909 dc.SetBrush(*wxBLACK_BRUSH);
1910 dc.DrawRectangle(paperRect.x + shadowOffset, paperRect.y + paperRect.height + 1,
1911 paperRect.width, shadowOffset);
1912
1913 dc.DrawRectangle(paperRect.x + paperRect.width, paperRect.y + shadowOffset,
1914 shadowOffset, paperRect.height);
1915
1916 // Draw blank page allowing for 1-pixel border AROUND the actual paper
1917 dc.SetPen(*wxBLACK_PEN);
1918 dc.SetBrush(*wxWHITE_BRUSH);
1919 dc.DrawRectangle(paperRect.x - 2, paperRect.y - 1,
1920 paperRect.width + 3, paperRect.height + 2);
1921
1922 return true;
1923 }
1924
1925 void wxPrintPreviewBase::SetZoom(int percent)
1926 {
1927 if (m_currentZoom == percent)
1928 return;
1929
1930 m_currentZoom = percent;
1931
1932 InvalidatePreviewBitmap();
1933
1934 if (m_previewCanvas)
1935 {
1936 AdjustScrollbars(m_previewCanvas);
1937 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
1938 m_previewCanvas->ClearBackground();
1939 m_previewCanvas->Refresh();
1940 m_previewCanvas->SetFocus();
1941 }
1942 }
1943
1944 wxPrintDialogData& wxPrintPreviewBase::GetPrintDialogData()
1945 {
1946 return m_printDialogData;
1947 }
1948
1949 int wxPrintPreviewBase::GetZoom() const
1950 { return m_currentZoom; }
1951 int wxPrintPreviewBase::GetMaxPage() const
1952 { return m_maxPage; }
1953 int wxPrintPreviewBase::GetMinPage() const
1954 { return m_minPage; }
1955 bool wxPrintPreviewBase::IsOk() const
1956 { return m_isOk; }
1957 void wxPrintPreviewBase::SetOk(bool ok)
1958 { m_isOk = ok; }
1959
1960 //----------------------------------------------------------------------------
1961 // wxPrintPreview
1962 //----------------------------------------------------------------------------
1963
1964 IMPLEMENT_CLASS(wxPrintPreview, wxPrintPreviewBase)
1965
1966 wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1967 wxPrintout *printoutForPrinting,
1968 wxPrintDialogData *data) :
1969 wxPrintPreviewBase( printout, printoutForPrinting, data )
1970 {
1971 m_pimpl = wxPrintFactory::GetFactory()->
1972 CreatePrintPreview( printout, printoutForPrinting, data );
1973 }
1974
1975 wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1976 wxPrintout *printoutForPrinting,
1977 wxPrintData *data ) :
1978 wxPrintPreviewBase( printout, printoutForPrinting, data )
1979 {
1980 m_pimpl = wxPrintFactory::GetFactory()->
1981 CreatePrintPreview( printout, printoutForPrinting, data );
1982 }
1983
1984 wxPrintPreview::~wxPrintPreview()
1985 {
1986 delete m_pimpl;
1987
1988 // don't delete twice
1989 m_printPrintout = NULL;
1990 m_previewPrintout = NULL;
1991 m_previewBitmap = NULL;
1992 }
1993
1994 bool wxPrintPreview::SetCurrentPage(int pageNum)
1995 {
1996 return m_pimpl->SetCurrentPage( pageNum );
1997 }
1998
1999 int wxPrintPreview::GetCurrentPage() const
2000 {
2001 return m_pimpl->GetCurrentPage();
2002 }
2003
2004 void wxPrintPreview::SetPrintout(wxPrintout *printout)
2005 {
2006 m_pimpl->SetPrintout( printout );
2007 }
2008
2009 wxPrintout *wxPrintPreview::GetPrintout() const
2010 {
2011 return m_pimpl->GetPrintout();
2012 }
2013
2014 wxPrintout *wxPrintPreview::GetPrintoutForPrinting() const
2015 {
2016 return m_pimpl->GetPrintoutForPrinting();
2017 }
2018
2019 void wxPrintPreview::SetFrame(wxFrame *frame)
2020 {
2021 m_pimpl->SetFrame( frame );
2022 }
2023
2024 void wxPrintPreview::SetCanvas(wxPreviewCanvas *canvas)
2025 {
2026 m_pimpl->SetCanvas( canvas );
2027 }
2028
2029 wxFrame *wxPrintPreview::GetFrame() const
2030 {
2031 return m_pimpl->GetFrame();
2032 }
2033
2034 wxPreviewCanvas *wxPrintPreview::GetCanvas() const
2035 {
2036 return m_pimpl->GetCanvas();
2037 }
2038
2039 bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
2040 {
2041 return m_pimpl->PaintPage( canvas, dc );
2042 }
2043
2044 bool wxPrintPreview::UpdatePageRendering()
2045 {
2046 return m_pimpl->UpdatePageRendering();
2047 }
2048
2049 bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
2050 {
2051 return m_pimpl->DrawBlankPage( canvas, dc );
2052 }
2053
2054 void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas *canvas)
2055 {
2056 m_pimpl->AdjustScrollbars( canvas );
2057 }
2058
2059 bool wxPrintPreview::RenderPage(int pageNum)
2060 {
2061 return m_pimpl->RenderPage( pageNum );
2062 }
2063
2064 void wxPrintPreview::SetZoom(int percent)
2065 {
2066 m_pimpl->SetZoom( percent );
2067 }
2068
2069 int wxPrintPreview::GetZoom() const
2070 {
2071 return m_pimpl->GetZoom();
2072 }
2073
2074 wxPrintDialogData& wxPrintPreview::GetPrintDialogData()
2075 {
2076 return m_pimpl->GetPrintDialogData();
2077 }
2078
2079 int wxPrintPreview::GetMaxPage() const
2080 {
2081 return m_pimpl->GetMaxPage();
2082 }
2083
2084 int wxPrintPreview::GetMinPage() const
2085 {
2086 return m_pimpl->GetMinPage();
2087 }
2088
2089 bool wxPrintPreview::IsOk() const
2090 {
2091 return m_pimpl->Ok();
2092 }
2093
2094 void wxPrintPreview::SetOk(bool ok)
2095 {
2096 m_pimpl->SetOk( ok );
2097 }
2098
2099 bool wxPrintPreview::Print(bool interactive)
2100 {
2101 return m_pimpl->Print( interactive );
2102 }
2103
2104 void wxPrintPreview::DetermineScaling()
2105 {
2106 m_pimpl->DetermineScaling();
2107 }
2108
2109 #endif // wxUSE_PRINTING_ARCHITECTURE