Don't call MakeModal on the Mac -- it leaves
[wxWidgets.git] / src / common / prntbase.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: prntbase.cpp
3 // Purpose: Printing framework base class implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "prntbase.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #include "wx/defs.h"
24
25 #if wxUSE_PRINTING_ARCHITECTURE
26
27 #ifndef WX_PRECOMP
28 #include "wx/utils.h"
29 #include "wx/dc.h"
30 #include "wx/app.h"
31 #include "wx/msgdlg.h"
32 #include "wx/layout.h"
33 #include "wx/choice.h"
34 #include "wx/button.h"
35 #include "wx/settings.h"
36 #include "wx/dcmemory.h"
37 #include "wx/stattext.h"
38 #include "wx/intl.h"
39 #include "wx/textdlg.h"
40 #include "wx/sizer.h"
41 #endif // !WX_PRECOMP
42
43 #include "wx/prntbase.h"
44 #include "wx/dcprint.h"
45 #include "wx/printdlg.h"
46 #include "wx/module.h"
47
48 #include <stdlib.h>
49 #include <string.h>
50
51 #ifdef __WXMSW__
52 #include "wx/msw/private.h"
53 #include <commdlg.h>
54
55 #ifndef __WIN32__
56 #include <print.h>
57 #endif
58 #endif // __WXMSW__
59
60 IMPLEMENT_CLASS(wxPrinterBase, wxObject)
61 IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
62 IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
63 IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
64 IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
65 IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
66
67 BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
68 EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
69 END_EVENT_TABLE()
70
71 BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
72 EVT_PAINT(wxPreviewCanvas::OnPaint)
73 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
74 END_EVENT_TABLE()
75
76 /*
77 * Printer
78 */
79
80 wxPrinterBase::wxPrinterBase(wxPrintDialogData *data)
81 {
82 m_currentPrintout = (wxPrintout *) NULL;
83 sm_abortWindow = (wxWindow *) NULL;
84 sm_abortIt = FALSE;
85 if (data)
86 m_printDialogData = (*data);
87 sm_lastError = wxPRINTER_NO_ERROR;
88 }
89
90 wxWindow *wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
91 bool wxPrinterBase::sm_abortIt = FALSE;
92 wxPrinterError wxPrinterBase::sm_lastError = wxPRINTER_NO_ERROR;
93
94 wxPrinterBase::~wxPrinterBase()
95 {
96 }
97
98 void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
99 {
100 wxPrinterBase::sm_abortIt = TRUE;
101 wxPrinterBase::sm_abortWindow->Show(FALSE);
102 wxPrinterBase::sm_abortWindow->Close(TRUE);
103 wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
104 }
105
106 wxWindow *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout * printout)
107 {
108 wxPrintAbortDialog *dialog = new wxPrintAbortDialog(parent, _("Printing ") , wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
109
110 wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
111 button_sizer->Add( new wxStaticText(dialog, -1, _("Please wait while printing\n") + printout->GetTitle() ), 0, wxALL, 10 );
112 button_sizer->Add( new wxButton( dialog, wxID_CANCEL, wxT("Cancel") ), 0, wxALL | wxALIGN_CENTER, 10 );
113
114 dialog->SetAutoLayout( TRUE );
115 dialog->SetSizer( button_sizer );
116
117 button_sizer->Fit(dialog);
118 button_sizer->SetSizeHints (dialog) ;
119
120 return dialog;
121 }
122
123 void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), const wxString& message)
124 {
125 wxMessageBox(message, _("Printing Error"), wxOK, parent);
126 }
127
128 /*
129 * Printout class
130 */
131
132 wxPrintout::wxPrintout(const wxString& title)
133 {
134 m_printoutTitle = title ;
135 m_printoutDC = (wxDC *) NULL;
136 m_pageWidthMM = 0;
137 m_pageHeightMM = 0;
138 m_pageWidthPixels = 0;
139 m_pageHeightPixels = 0;
140 m_PPIScreenX = 0;
141 m_PPIScreenY = 0;
142 m_PPIPrinterX = 0;
143 m_PPIPrinterY = 0;
144 m_isPreview = FALSE;
145 }
146
147 wxPrintout::~wxPrintout()
148 {
149 }
150
151 bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
152 {
153 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle);
154 }
155
156 void wxPrintout::OnEndDocument()
157 {
158 GetDC()->EndDoc();
159 }
160
161 void wxPrintout::OnBeginPrinting()
162 {
163 }
164
165 void wxPrintout::OnEndPrinting()
166 {
167 }
168
169 bool wxPrintout::HasPage(int page)
170 {
171 return (page == 1);
172 }
173
174 void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
175 {
176 *minPage = 1;
177 *maxPage = 32000;
178 *fromPage = 1;
179 *toPage = 1;
180 }
181
182 /*
183 * Preview canvas
184 */
185
186 wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
187 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
188 wxScrolledWindow(parent, -1, pos, size, style, name)
189 {
190 m_printPreview = preview;
191 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
192
193 SetScrollbars(15, 18, 100, 100);
194 }
195
196 wxPreviewCanvas::~wxPreviewCanvas()
197 {
198 }
199
200 void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
201 {
202 wxPaintDC dc(this);
203 PrepareDC( dc );
204
205 /*
206 #ifdef __WXGTK__
207 if (!GetUpdateRegion().IsEmpty())
208 dc.SetClippingRegion( GetUpdateRegion() );
209 #endif
210 */
211
212 if (m_printPreview)
213 {
214 m_printPreview->PaintPage(this, dc);
215 }
216 }
217
218 // Responds to colour changes, and passes event on to children.
219 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
220 {
221 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
222 Refresh();
223
224 // Propagate the event to the non-top-level children
225 wxWindow::OnSysColourChanged(event);
226 }
227
228 /*
229 * Preview control bar
230 */
231
232 BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
233 EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
234 EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrint)
235 EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
236 EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
237 EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
238 EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
239 EVT_BUTTON(wxID_PREVIEW_GOTO, wxPreviewControlBar::OnGotoButton)
240 EVT_CHAR(wxPreviewControlBar::OnChar)
241 EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoom)
242 EVT_PAINT(wxPreviewControlBar::OnPaint)
243 END_EVENT_TABLE()
244
245 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
246 wxWindow *parent, const wxPoint& pos, const wxSize& size,
247 long style, const wxString& name):
248 wxPanel(parent, -1, pos, size, style, name)
249 {
250 m_printPreview = preview;
251 m_closeButton = (wxButton *) NULL;
252 m_nextPageButton = (wxButton *) NULL;
253 m_previousPageButton = (wxButton *) NULL;
254 m_printButton = (wxButton *) NULL;
255 m_zoomControl = (wxChoice *) NULL;
256 m_buttonFlags = buttons;
257 }
258
259 wxPreviewControlBar::~wxPreviewControlBar()
260 {
261 }
262
263 void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
264 {
265 wxPaintDC dc(this);
266
267 int w, h;
268 GetSize(&w, &h);
269 dc.SetPen(*wxBLACK_PEN);
270 dc.SetBrush(*wxTRANSPARENT_BRUSH);
271 dc.DrawLine( 0, h-1, w, h-1 );
272 }
273
274 void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
275 {
276 wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
277 frame->Close(TRUE);
278 }
279
280 void wxPreviewControlBar::OnPrint(wxCommandEvent& WXUNUSED(event))
281 {
282 wxPrintPreviewBase *preview = GetPrintPreview();
283 preview->Print(TRUE);
284 }
285
286 void wxPreviewControlBar::OnChar(wxKeyEvent &event)
287 {
288 switch(event.GetKeyCode())
289 {
290 case WXK_NEXT:
291 OnNext(); break;
292 case WXK_PRIOR:
293 OnPrevious(); break;
294 case WXK_HOME:
295 OnFirst(); break;
296 case WXK_END:
297 OnLast(); break;
298 case WXK_TAB:
299 OnGoto(); break;
300 default:
301 event.Skip();
302 }
303 }
304
305 void wxPreviewControlBar::OnNext(void)
306 {
307 wxPrintPreviewBase *preview = GetPrintPreview();
308 if (preview)
309 {
310 int currentPage = preview->GetCurrentPage();
311 if ((preview->GetMaxPage() > 0) &&
312 (currentPage < preview->GetMaxPage()) &&
313 preview->GetPrintout()->HasPage(currentPage + 1))
314 {
315 preview->SetCurrentPage(currentPage + 1);
316 }
317 }
318 }
319
320 void wxPreviewControlBar::OnPrevious(void)
321 {
322 wxPrintPreviewBase *preview = GetPrintPreview();
323 if (preview)
324 {
325 int currentPage = preview->GetCurrentPage();
326 if ((preview->GetMinPage() > 0) &&
327 (currentPage > preview->GetMinPage()) &&
328 preview->GetPrintout()->HasPage(currentPage - 1))
329 {
330 preview->SetCurrentPage(currentPage - 1);
331 }
332 }
333 }
334
335 void wxPreviewControlBar::OnFirst(void)
336 {
337 wxPrintPreviewBase *preview = GetPrintPreview();
338 if (preview)
339 {
340 int currentPage = preview->GetMinPage();
341 if (preview->GetPrintout()->HasPage(currentPage))
342 {
343 preview->SetCurrentPage(currentPage);
344 }
345 }
346 }
347
348 void wxPreviewControlBar::OnLast(void)
349 {
350 wxPrintPreviewBase *preview = GetPrintPreview();
351 if (preview)
352 {
353 int currentPage = preview->GetMaxPage();
354 if (preview->GetPrintout()->HasPage(currentPage))
355 {
356 preview->SetCurrentPage(currentPage);
357 }
358 }
359 }
360
361 void wxPreviewControlBar::OnGoto(void)
362 {
363 wxPrintPreviewBase *preview = GetPrintPreview();
364 if (preview)
365 {
366 long currentPage;
367
368 if (preview->GetMinPage() > 0)
369 {
370 wxString strPrompt;
371 wxString strPage;
372
373 strPrompt.Printf( wxT("%d...%d"),
374 preview->GetMinPage(), preview->GetMaxPage());
375 strPage.Printf( wxT("%d"), preview->GetCurrentPage() );
376
377 strPage =
378 wxGetTextFromUser( strPrompt, _("Goto Page"), strPage);
379
380 if ( strPage.ToLong( &currentPage ) )
381 if (preview->GetPrintout()->HasPage(currentPage))
382 {
383 preview->SetCurrentPage(currentPage);
384 }
385 }
386 }
387 }
388
389 void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
390 {
391 int zoom = GetZoomControl();
392 if (GetPrintPreview())
393 GetPrintPreview()->SetZoom(zoom);
394 }
395
396 void wxPreviewControlBar::CreateButtons()
397 {
398 SetSize(0, 0, 400, 40);
399
400 wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
401
402 int smallButtonWidth = 45;
403
404 m_closeButton = new wxButton( this, wxID_PREVIEW_CLOSE, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
405 item0->Add( m_closeButton, 0, wxALIGN_CENTRE|wxALL, 5 );
406
407 if (m_buttonFlags & wxPREVIEW_PRINT)
408 {
409 m_printButton = new wxButton( this, wxID_PREVIEW_PRINT, _("&Print..."), wxDefaultPosition, wxDefaultSize, 0 );
410 item0->Add( m_printButton, 0, wxALIGN_CENTRE|wxALL, 5 );
411 }
412
413 if (m_buttonFlags & wxPREVIEW_FIRST)
414 {
415 m_firstPageButton = new wxButton( this, wxID_PREVIEW_FIRST, _("|<<"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
416 item0->Add( m_firstPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
417 }
418
419 if (m_buttonFlags & wxPREVIEW_PREVIOUS)
420 {
421 m_previousPageButton = new wxButton( this, wxID_PREVIEW_PREVIOUS, _("<<"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
422 item0->Add( m_previousPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
423 }
424
425 if (m_buttonFlags & wxPREVIEW_NEXT)
426 {
427 m_nextPageButton = new wxButton( this, wxID_PREVIEW_NEXT, _(">>"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
428 item0->Add( m_nextPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
429 }
430
431 if (m_buttonFlags & wxPREVIEW_LAST)
432 {
433 m_lastPageButton = new wxButton( this, wxID_PREVIEW_LAST, _(">>|"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
434 item0->Add( m_lastPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
435 }
436
437 if (m_buttonFlags & wxPREVIEW_GOTO)
438 {
439 m_gotoPageButton = new wxButton( this, wxID_PREVIEW_GOTO, _("&Goto..."), wxDefaultPosition, wxDefaultSize, 0 );
440 item0->Add( m_gotoPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
441 }
442
443 if (m_buttonFlags & wxPREVIEW_ZOOM)
444 {
445 wxString choices[] =
446 {
447 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
448 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
449 wxT("120%"), wxT("150%"), wxT("200%")
450 };
451 int n = WXSIZEOF(choices);
452
453 m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,-1), n, choices, 0 );
454 item0->Add( m_zoomControl, 0, wxALIGN_CENTRE|wxALL, 5 );
455 SetZoomControl(m_printPreview->GetZoom());
456 }
457
458 SetSizer(item0);
459 item0->Fit(this);
460 }
461
462 void wxPreviewControlBar::SetZoomControl(int zoom)
463 {
464 wxChar buf[20];
465 wxSprintf( buf, wxT("%d%%"), zoom );
466
467 if (m_zoomControl)
468 m_zoomControl->SetStringSelection(buf);
469 }
470
471 int wxPreviewControlBar::GetZoomControl()
472 {
473 wxChar buf[20];
474 if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxT("")))
475 {
476 wxStrcpy(buf, m_zoomControl->GetStringSelection());
477 buf[wxStrlen(buf) - 1] = 0;
478 return (int)wxAtoi(buf);
479 }
480 else return 0;
481 }
482
483
484 /*
485 * Preview frame
486 */
487
488 BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
489 EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
490 END_EVENT_TABLE()
491
492 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxFrame *parent, const wxString& title,
493 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
494 wxFrame(parent, -1, title, pos, size, style, name)
495 {
496 m_printPreview = preview;
497 m_controlBar = NULL;
498 m_previewCanvas = NULL;
499 }
500
501 wxPreviewFrame::~wxPreviewFrame()
502 {
503 }
504
505 void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
506 {
507 // MakeModal doesn't work on wxMac, especially when there
508 // are multiple top-level windows.
509 #ifndef __WXMAC__
510 MakeModal(FALSE);
511 #endif
512
513 // Need to delete the printout and the print preview
514 wxPrintout *printout = m_printPreview->GetPrintout();
515 if (printout)
516 {
517 delete printout;
518 m_printPreview->SetPrintout(NULL);
519 m_printPreview->SetCanvas(NULL);
520 m_printPreview->SetFrame(NULL);
521 }
522 delete m_printPreview;
523
524 Destroy();
525 }
526
527 void wxPreviewFrame::Initialize()
528 {
529 CreateStatusBar();
530 CreateCanvas();
531 CreateControlBar();
532
533 m_printPreview->SetCanvas(m_previewCanvas);
534 m_printPreview->SetFrame(this);
535
536 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
537
538 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
539 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
540
541 SetAutoLayout( TRUE );
542 SetSizer( item0 );
543
544 // MakeModal doesn't work on wxMac, especially when there
545 // are multiple top-level windows.
546 #ifndef __WXMAC__
547 MakeModal(TRUE);
548 #endif
549
550 Layout();
551 }
552
553 void wxPreviewFrame::CreateCanvas()
554 {
555 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
556 }
557
558 void wxPreviewFrame::CreateControlBar()
559 {
560 long buttons = wxPREVIEW_DEFAULT;
561 if (m_printPreview->GetPrintoutForPrinting())
562 buttons |= wxPREVIEW_PRINT;
563
564 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0, 0), wxSize(400, 40));
565 m_controlBar->CreateButtons();
566 }
567
568 /*
569 * Print preview
570 */
571
572 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
573 wxPrintout *printoutForPrinting,
574 wxPrintData *data)
575 {
576 if (data)
577 m_printDialogData = (*data);
578
579 Init(printout, printoutForPrinting);
580 }
581
582 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
583 wxPrintout *printoutForPrinting,
584 wxPrintDialogData *data)
585 {
586 if (data)
587 m_printDialogData = (*data);
588
589 Init(printout, printoutForPrinting);
590 }
591
592 void wxPrintPreviewBase::Init(wxPrintout *printout,
593 wxPrintout *printoutForPrinting)
594 {
595 m_isOk = TRUE;
596 m_previewPrintout = printout;
597 if (m_previewPrintout)
598 m_previewPrintout->SetIsPreview(TRUE);
599
600 m_printPrintout = printoutForPrinting;
601
602 m_previewCanvas = NULL;
603 m_previewFrame = NULL;
604 m_previewBitmap = NULL;
605 m_currentPage = 1;
606 m_currentZoom = 70;
607 m_topMargin = 40;
608 m_leftMargin = 40;
609 m_pageWidth = 0;
610 m_pageHeight = 0;
611 m_printingPrepared = FALSE;
612
613 // Too soon! Moved to RenderPage.
614 // printout->OnPreparePrinting();
615
616 // Get some parameters from the printout, if defined
617 int selFrom, selTo;
618 printout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
619 }
620
621 wxPrintPreviewBase::~wxPrintPreviewBase()
622 {
623 if (m_previewPrintout)
624 delete m_previewPrintout;
625 if (m_previewBitmap)
626 delete m_previewBitmap;
627 if (m_printPrintout)
628 delete m_printPrintout;
629 }
630
631 bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
632 {
633 if (m_currentPage == pageNum)
634 return TRUE;
635
636 m_currentPage = pageNum;
637 if (m_previewBitmap)
638 {
639 delete m_previewBitmap;
640 m_previewBitmap = NULL;
641 }
642
643 if (m_previewCanvas)
644 {
645 if (!RenderPage(pageNum))
646 return FALSE;
647 m_previewCanvas->Refresh();
648 }
649 return TRUE;
650 }
651
652 bool wxPrintPreviewBase::PaintPage(wxWindow *canvas, wxDC& dc)
653 {
654 DrawBlankPage(canvas, dc);
655
656 if (!m_previewBitmap)
657 if (!RenderPage(m_currentPage))
658 return FALSE;
659
660 if (!m_previewBitmap)
661 return FALSE;
662
663 if (!canvas)
664 return FALSE;
665
666 int canvasWidth, canvasHeight;
667 canvas->GetSize(&canvasWidth, &canvasHeight);
668
669 double zoomScale = ((float)m_currentZoom/(float)100);
670 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
671 // float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
672
673 int x = (int) ((canvasWidth - actualWidth)/2.0);
674 if (x < m_leftMargin)
675 x = m_leftMargin;
676 int y = m_topMargin;
677
678 wxMemoryDC temp_dc;
679 temp_dc.SelectObject(*m_previewBitmap);
680
681 dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
682
683 temp_dc.SelectObject(wxNullBitmap);
684
685 return TRUE;
686 }
687
688 bool wxPrintPreviewBase::RenderPage(int pageNum)
689 {
690 wxBusyCursor busy;
691
692 int canvasWidth, canvasHeight;
693
694 if (!m_previewCanvas)
695 {
696 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
697
698 return FALSE;
699 }
700 m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
701
702 double zoomScale = (m_currentZoom/100.0);
703 int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
704 int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
705
706 int x = (int)((canvasWidth - actualWidth)/2.0);
707 if (x < m_leftMargin)
708 x = m_leftMargin;
709 // int y = m_topMargin;
710
711
712 if (!m_previewBitmap)
713 {
714 m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
715 if (!m_previewBitmap || !m_previewBitmap->Ok())
716 {
717 if (m_previewBitmap) {
718 delete m_previewBitmap;
719 m_previewBitmap = NULL;
720 }
721 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
722 return FALSE;
723 }
724 }
725
726 wxMemoryDC memoryDC;
727 memoryDC.SelectObject(*m_previewBitmap);
728
729 memoryDC.Clear();
730
731 m_previewPrintout->SetDC(&memoryDC);
732 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
733
734 // Need to delay OnPreparePrinting until here, so we have enough information.
735 if (!m_printingPrepared)
736 {
737 m_previewPrintout->OnPreparePrinting();
738 m_printingPrepared = TRUE;
739 }
740
741 m_previewPrintout->OnBeginPrinting();
742
743 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
744 {
745 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
746
747 memoryDC.SelectObject(wxNullBitmap);
748
749 delete m_previewBitmap;
750 m_previewBitmap = NULL;
751 return FALSE;
752 }
753
754 m_previewPrintout->OnPrintPage(pageNum);
755 m_previewPrintout->OnEndDocument();
756 m_previewPrintout->OnEndPrinting();
757
758 m_previewPrintout->SetDC(NULL);
759
760 memoryDC.SelectObject(wxNullBitmap);
761
762 wxChar buf[200];
763 if (m_maxPage != 0)
764 wxSprintf(buf, _("Page %d of %d"), pageNum, m_maxPage);
765 else
766 wxSprintf(buf, _("Page %d"), pageNum);
767
768 if (m_previewFrame)
769 m_previewFrame->SetStatusText(buf);
770
771 return TRUE;
772 }
773
774
775 bool wxPrintPreviewBase::DrawBlankPage(wxWindow *canvas, wxDC& dc)
776 {
777 int canvasWidth, canvasHeight;
778 canvas->GetSize(&canvasWidth, &canvasHeight);
779
780 float zoomScale = (float)((float)m_currentZoom/(float)100);
781 float actualWidth = zoomScale*m_pageWidth*m_previewScale;
782 float actualHeight = zoomScale*m_pageHeight*m_previewScale;
783
784 float x = (float)((canvasWidth - actualWidth)/2.0);
785 if (x < m_leftMargin)
786 x = (float)m_leftMargin;
787 float y = (float)m_topMargin;
788
789 // Draw shadow, allowing for 1-pixel border AROUND the actual page
790 int shadowOffset = 4;
791 dc.SetPen(*wxBLACK_PEN);
792 dc.SetBrush(*wxBLACK_BRUSH);
793 /*
794 dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
795 */
796 dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
797 dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
798
799 // Draw blank page allowing for 1-pixel border AROUND the actual page
800 dc.SetPen(*wxBLACK_PEN);
801 dc.SetBrush(*wxWHITE_BRUSH);
802
803 /*
804 wxRegion update_region = canvas->GetUpdateRegion();
805 wxRect r = update_region.GetBox();
806
807 printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
808 */
809
810 dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
811
812 return TRUE;
813 }
814
815 void wxPrintPreviewBase::SetZoom(int percent)
816 {
817 if (m_currentZoom == percent)
818 return;
819
820 m_currentZoom = percent;
821 if (m_previewBitmap)
822 {
823 delete m_previewBitmap;
824 m_previewBitmap = NULL;
825 }
826
827 if (m_previewCanvas)
828 {
829 RenderPage(m_currentPage);
830 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
831 m_previewCanvas->Clear();
832 m_previewCanvas->Refresh();
833 }
834 }
835
836 #endif // wxUSE_PRINTING_ARCHITECTURE