Darkened preview background for Mac (else get stripey background)
[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 #ifdef __WXMAC__
192 // The app workspace colour is always white, but we should have
193 // a contrast with the page.
194 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
195 #else
196 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
197 #endif
198 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
199
200 SetScrollbars(15, 18, 100, 100);
201 }
202
203 wxPreviewCanvas::~wxPreviewCanvas()
204 {
205 }
206
207 void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
208 {
209 wxPaintDC dc(this);
210 PrepareDC( dc );
211
212 /*
213 #ifdef __WXGTK__
214 if (!GetUpdateRegion().IsEmpty())
215 dc.SetClippingRegion( GetUpdateRegion() );
216 #endif
217 */
218
219 if (m_printPreview)
220 {
221 m_printPreview->PaintPage(this, dc);
222 }
223 }
224
225 // Responds to colour changes, and passes event on to children.
226 void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
227 {
228 #ifdef __WXMAC__
229 // The app workspace colour is always white, but we should have
230 // a contrast with the page.
231 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
232 #else
233 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
234 #endif
235 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
236 Refresh();
237
238 // Propagate the event to the non-top-level children
239 wxWindow::OnSysColourChanged(event);
240 }
241
242 /*
243 * Preview control bar
244 */
245
246 BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
247 EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
248 EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrint)
249 EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
250 EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
251 EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
252 EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
253 EVT_BUTTON(wxID_PREVIEW_GOTO, wxPreviewControlBar::OnGotoButton)
254 EVT_CHAR(wxPreviewControlBar::OnChar)
255 EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoom)
256 EVT_PAINT(wxPreviewControlBar::OnPaint)
257 END_EVENT_TABLE()
258
259 wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
260 wxWindow *parent, const wxPoint& pos, const wxSize& size,
261 long style, const wxString& name):
262 wxPanel(parent, -1, pos, size, style, name)
263 {
264 m_printPreview = preview;
265 m_closeButton = (wxButton *) NULL;
266 m_nextPageButton = (wxButton *) NULL;
267 m_previousPageButton = (wxButton *) NULL;
268 m_printButton = (wxButton *) NULL;
269 m_zoomControl = (wxChoice *) NULL;
270 m_buttonFlags = buttons;
271 }
272
273 wxPreviewControlBar::~wxPreviewControlBar()
274 {
275 }
276
277 void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
278 {
279 wxPaintDC dc(this);
280
281 int w, h;
282 GetSize(&w, &h);
283 dc.SetPen(*wxBLACK_PEN);
284 dc.SetBrush(*wxTRANSPARENT_BRUSH);
285 dc.DrawLine( 0, h-1, w, h-1 );
286 }
287
288 void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
289 {
290 wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
291 frame->Close(TRUE);
292 }
293
294 void wxPreviewControlBar::OnPrint(wxCommandEvent& WXUNUSED(event))
295 {
296 wxPrintPreviewBase *preview = GetPrintPreview();
297 preview->Print(TRUE);
298 }
299
300 void wxPreviewControlBar::OnChar(wxKeyEvent &event)
301 {
302 switch(event.GetKeyCode())
303 {
304 case WXK_NEXT:
305 OnNext(); break;
306 case WXK_PRIOR:
307 OnPrevious(); break;
308 case WXK_HOME:
309 OnFirst(); break;
310 case WXK_END:
311 OnLast(); break;
312 case WXK_TAB:
313 OnGoto(); break;
314 default:
315 event.Skip();
316 }
317 }
318
319 void wxPreviewControlBar::OnNext(void)
320 {
321 wxPrintPreviewBase *preview = GetPrintPreview();
322 if (preview)
323 {
324 int currentPage = preview->GetCurrentPage();
325 if ((preview->GetMaxPage() > 0) &&
326 (currentPage < preview->GetMaxPage()) &&
327 preview->GetPrintout()->HasPage(currentPage + 1))
328 {
329 preview->SetCurrentPage(currentPage + 1);
330 }
331 }
332 }
333
334 void wxPreviewControlBar::OnPrevious(void)
335 {
336 wxPrintPreviewBase *preview = GetPrintPreview();
337 if (preview)
338 {
339 int currentPage = preview->GetCurrentPage();
340 if ((preview->GetMinPage() > 0) &&
341 (currentPage > preview->GetMinPage()) &&
342 preview->GetPrintout()->HasPage(currentPage - 1))
343 {
344 preview->SetCurrentPage(currentPage - 1);
345 }
346 }
347 }
348
349 void wxPreviewControlBar::OnFirst(void)
350 {
351 wxPrintPreviewBase *preview = GetPrintPreview();
352 if (preview)
353 {
354 int currentPage = preview->GetMinPage();
355 if (preview->GetPrintout()->HasPage(currentPage))
356 {
357 preview->SetCurrentPage(currentPage);
358 }
359 }
360 }
361
362 void wxPreviewControlBar::OnLast(void)
363 {
364 wxPrintPreviewBase *preview = GetPrintPreview();
365 if (preview)
366 {
367 int currentPage = preview->GetMaxPage();
368 if (preview->GetPrintout()->HasPage(currentPage))
369 {
370 preview->SetCurrentPage(currentPage);
371 }
372 }
373 }
374
375 void wxPreviewControlBar::OnGoto(void)
376 {
377 wxPrintPreviewBase *preview = GetPrintPreview();
378 if (preview)
379 {
380 long currentPage;
381
382 if (preview->GetMinPage() > 0)
383 {
384 wxString strPrompt;
385 wxString strPage;
386
387 strPrompt.Printf( wxT("%d...%d"),
388 preview->GetMinPage(), preview->GetMaxPage());
389 strPage.Printf( wxT("%d"), preview->GetCurrentPage() );
390
391 strPage =
392 wxGetTextFromUser( strPrompt, _("Goto Page"), strPage);
393
394 if ( strPage.ToLong( &currentPage ) )
395 if (preview->GetPrintout()->HasPage(currentPage))
396 {
397 preview->SetCurrentPage(currentPage);
398 }
399 }
400 }
401 }
402
403 void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
404 {
405 int zoom = GetZoomControl();
406 if (GetPrintPreview())
407 GetPrintPreview()->SetZoom(zoom);
408 }
409
410 void wxPreviewControlBar::CreateButtons()
411 {
412 SetSize(0, 0, 400, 40);
413
414 wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
415
416 int smallButtonWidth = 45;
417
418 m_closeButton = new wxButton( this, wxID_PREVIEW_CLOSE, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
419 item0->Add( m_closeButton, 0, wxALIGN_CENTRE|wxALL, 5 );
420
421 if (m_buttonFlags & wxPREVIEW_PRINT)
422 {
423 m_printButton = new wxButton( this, wxID_PREVIEW_PRINT, _("&Print..."), wxDefaultPosition, wxDefaultSize, 0 );
424 item0->Add( m_printButton, 0, wxALIGN_CENTRE|wxALL, 5 );
425 }
426
427 if (m_buttonFlags & wxPREVIEW_FIRST)
428 {
429 m_firstPageButton = new wxButton( this, wxID_PREVIEW_FIRST, _("|<<"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
430 item0->Add( m_firstPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
431 }
432
433 if (m_buttonFlags & wxPREVIEW_PREVIOUS)
434 {
435 m_previousPageButton = new wxButton( this, wxID_PREVIEW_PREVIOUS, _("<<"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
436 item0->Add( m_previousPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
437 }
438
439 if (m_buttonFlags & wxPREVIEW_NEXT)
440 {
441 m_nextPageButton = new wxButton( this, wxID_PREVIEW_NEXT, _(">>"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
442 item0->Add( m_nextPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
443 }
444
445 if (m_buttonFlags & wxPREVIEW_LAST)
446 {
447 m_lastPageButton = new wxButton( this, wxID_PREVIEW_LAST, _(">>|"), wxDefaultPosition, wxSize(smallButtonWidth,-1), 0 );
448 item0->Add( m_lastPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
449 }
450
451 if (m_buttonFlags & wxPREVIEW_GOTO)
452 {
453 m_gotoPageButton = new wxButton( this, wxID_PREVIEW_GOTO, _("&Goto..."), wxDefaultPosition, wxDefaultSize, 0 );
454 item0->Add( m_gotoPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
455 }
456
457 if (m_buttonFlags & wxPREVIEW_ZOOM)
458 {
459 wxString choices[] =
460 {
461 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
462 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
463 wxT("120%"), wxT("150%"), wxT("200%")
464 };
465 int n = WXSIZEOF(choices);
466
467 m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,-1), n, choices, 0 );
468 item0->Add( m_zoomControl, 0, wxALIGN_CENTRE|wxALL, 5 );
469 SetZoomControl(m_printPreview->GetZoom());
470 }
471
472 SetSizer(item0);
473 item0->Fit(this);
474 }
475
476 void wxPreviewControlBar::SetZoomControl(int zoom)
477 {
478 wxChar buf[20];
479 wxSprintf( buf, wxT("%d%%"), zoom );
480
481 if (m_zoomControl)
482 m_zoomControl->SetStringSelection(buf);
483 }
484
485 int wxPreviewControlBar::GetZoomControl()
486 {
487 wxChar buf[20];
488 if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxT("")))
489 {
490 wxStrcpy(buf, m_zoomControl->GetStringSelection());
491 buf[wxStrlen(buf) - 1] = 0;
492 return (int)wxAtoi(buf);
493 }
494 else return 0;
495 }
496
497
498 /*
499 * Preview frame
500 */
501
502 BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
503 EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
504 END_EVENT_TABLE()
505
506 wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxFrame *parent, const wxString& title,
507 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
508 wxFrame(parent, -1, title, pos, size, style, name)
509 {
510 m_printPreview = preview;
511 m_controlBar = NULL;
512 m_previewCanvas = NULL;
513
514 // Looks silly on Windows with a standard Windows icon
515 #ifdef __WXMSW__
516 wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
517 if (topFrame)
518 SetIcon(topFrame->GetIcon());
519 #endif
520 }
521
522 wxPreviewFrame::~wxPreviewFrame()
523 {
524 }
525
526 void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
527 {
528 // MakeModal doesn't work on wxMac, especially when there
529 // are multiple top-level windows.
530 #ifndef __WXMAC__
531 MakeModal(FALSE);
532 #endif
533
534 // Need to delete the printout and the print preview
535 wxPrintout *printout = m_printPreview->GetPrintout();
536 if (printout)
537 {
538 delete printout;
539 m_printPreview->SetPrintout(NULL);
540 m_printPreview->SetCanvas(NULL);
541 m_printPreview->SetFrame(NULL);
542 }
543 delete m_printPreview;
544
545 Destroy();
546 }
547
548 void wxPreviewFrame::Initialize()
549 {
550 CreateStatusBar();
551 CreateCanvas();
552 CreateControlBar();
553
554 m_printPreview->SetCanvas(m_previewCanvas);
555 m_printPreview->SetFrame(this);
556
557 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
558
559 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
560 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
561
562 SetAutoLayout( TRUE );
563 SetSizer( item0 );
564
565 // MakeModal doesn't work on wxMac, especially when there
566 // are multiple top-level windows.
567 #ifndef __WXMAC__
568 MakeModal(TRUE);
569 #endif
570
571 Layout();
572 }
573
574 void wxPreviewFrame::CreateCanvas()
575 {
576 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
577 }
578
579 void wxPreviewFrame::CreateControlBar()
580 {
581 long buttons = wxPREVIEW_DEFAULT;
582 if (m_printPreview->GetPrintoutForPrinting())
583 buttons |= wxPREVIEW_PRINT;
584
585 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0, 0), wxSize(400, 40));
586 m_controlBar->CreateButtons();
587 }
588
589 /*
590 * Print preview
591 */
592
593 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
594 wxPrintout *printoutForPrinting,
595 wxPrintData *data)
596 {
597 if (data)
598 m_printDialogData = (*data);
599
600 Init(printout, printoutForPrinting);
601 }
602
603 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
604 wxPrintout *printoutForPrinting,
605 wxPrintDialogData *data)
606 {
607 if (data)
608 m_printDialogData = (*data);
609
610 Init(printout, printoutForPrinting);
611 }
612
613 void wxPrintPreviewBase::Init(wxPrintout *printout,
614 wxPrintout *printoutForPrinting)
615 {
616 m_isOk = TRUE;
617 m_previewPrintout = printout;
618 if (m_previewPrintout)
619 m_previewPrintout->SetIsPreview(TRUE);
620
621 m_printPrintout = printoutForPrinting;
622
623 m_previewCanvas = NULL;
624 m_previewFrame = NULL;
625 m_previewBitmap = NULL;
626 m_currentPage = 1;
627 m_currentZoom = 70;
628 m_topMargin = 40;
629 m_leftMargin = 40;
630 m_pageWidth = 0;
631 m_pageHeight = 0;
632 m_printingPrepared = FALSE;
633
634 // Too soon! Moved to RenderPage.
635 // printout->OnPreparePrinting();
636
637 // Get some parameters from the printout, if defined
638 int selFrom, selTo;
639 printout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
640 }
641
642 wxPrintPreviewBase::~wxPrintPreviewBase()
643 {
644 if (m_previewPrintout)
645 delete m_previewPrintout;
646 if (m_previewBitmap)
647 delete m_previewBitmap;
648 if (m_printPrintout)
649 delete m_printPrintout;
650 }
651
652 bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
653 {
654 if (m_currentPage == pageNum)
655 return TRUE;
656
657 m_currentPage = pageNum;
658 if (m_previewBitmap)
659 {
660 delete m_previewBitmap;
661 m_previewBitmap = NULL;
662 }
663
664 if (m_previewCanvas)
665 {
666 if (!RenderPage(pageNum))
667 return FALSE;
668 m_previewCanvas->Refresh();
669 }
670 return TRUE;
671 }
672
673 bool wxPrintPreviewBase::PaintPage(wxWindow *canvas, wxDC& dc)
674 {
675 DrawBlankPage(canvas, dc);
676
677 if (!m_previewBitmap)
678 if (!RenderPage(m_currentPage))
679 return FALSE;
680
681 if (!m_previewBitmap)
682 return FALSE;
683
684 if (!canvas)
685 return FALSE;
686
687 int canvasWidth, canvasHeight;
688 canvas->GetSize(&canvasWidth, &canvasHeight);
689
690 double zoomScale = ((float)m_currentZoom/(float)100);
691 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
692 // float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
693
694 int x = (int) ((canvasWidth - actualWidth)/2.0);
695 if (x < m_leftMargin)
696 x = m_leftMargin;
697 int y = m_topMargin;
698
699 wxMemoryDC temp_dc;
700 temp_dc.SelectObject(*m_previewBitmap);
701
702 dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
703
704 temp_dc.SelectObject(wxNullBitmap);
705
706 return TRUE;
707 }
708
709 bool wxPrintPreviewBase::RenderPage(int pageNum)
710 {
711 wxBusyCursor busy;
712
713 int canvasWidth, canvasHeight;
714
715 if (!m_previewCanvas)
716 {
717 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
718
719 return FALSE;
720 }
721 m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
722
723 double zoomScale = (m_currentZoom/100.0);
724 int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
725 int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
726
727 int x = (int)((canvasWidth - actualWidth)/2.0);
728 if (x < m_leftMargin)
729 x = m_leftMargin;
730 // int y = m_topMargin;
731
732
733 if (!m_previewBitmap)
734 {
735 m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
736 if (!m_previewBitmap || !m_previewBitmap->Ok())
737 {
738 if (m_previewBitmap) {
739 delete m_previewBitmap;
740 m_previewBitmap = NULL;
741 }
742 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
743 return FALSE;
744 }
745 }
746
747 wxMemoryDC memoryDC;
748 memoryDC.SelectObject(*m_previewBitmap);
749
750 memoryDC.Clear();
751
752 m_previewPrintout->SetDC(&memoryDC);
753 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
754
755 // Need to delay OnPreparePrinting until here, so we have enough information.
756 if (!m_printingPrepared)
757 {
758 m_previewPrintout->OnPreparePrinting();
759 m_printingPrepared = TRUE;
760 }
761
762 m_previewPrintout->OnBeginPrinting();
763
764 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
765 {
766 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
767
768 memoryDC.SelectObject(wxNullBitmap);
769
770 delete m_previewBitmap;
771 m_previewBitmap = NULL;
772 return FALSE;
773 }
774
775 m_previewPrintout->OnPrintPage(pageNum);
776 m_previewPrintout->OnEndDocument();
777 m_previewPrintout->OnEndPrinting();
778
779 m_previewPrintout->SetDC(NULL);
780
781 memoryDC.SelectObject(wxNullBitmap);
782
783 wxChar buf[200];
784 if (m_maxPage != 0)
785 wxSprintf(buf, _("Page %d of %d"), pageNum, m_maxPage);
786 else
787 wxSprintf(buf, _("Page %d"), pageNum);
788
789 if (m_previewFrame)
790 m_previewFrame->SetStatusText(buf);
791
792 return TRUE;
793 }
794
795
796 bool wxPrintPreviewBase::DrawBlankPage(wxWindow *canvas, wxDC& dc)
797 {
798 int canvasWidth, canvasHeight;
799 canvas->GetSize(&canvasWidth, &canvasHeight);
800
801 float zoomScale = (float)((float)m_currentZoom/(float)100);
802 float actualWidth = zoomScale*m_pageWidth*m_previewScale;
803 float actualHeight = zoomScale*m_pageHeight*m_previewScale;
804
805 float x = (float)((canvasWidth - actualWidth)/2.0);
806 if (x < m_leftMargin)
807 x = (float)m_leftMargin;
808 float y = (float)m_topMargin;
809
810 // Draw shadow, allowing for 1-pixel border AROUND the actual page
811 int shadowOffset = 4;
812 dc.SetPen(*wxBLACK_PEN);
813 dc.SetBrush(*wxBLACK_BRUSH);
814 /*
815 dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
816 */
817 dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
818 dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
819
820 // Draw blank page allowing for 1-pixel border AROUND the actual page
821 dc.SetPen(*wxBLACK_PEN);
822 dc.SetBrush(*wxWHITE_BRUSH);
823
824 /*
825 wxRegion update_region = canvas->GetUpdateRegion();
826 wxRect r = update_region.GetBox();
827
828 printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
829 */
830
831 dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
832
833 return TRUE;
834 }
835
836 void wxPrintPreviewBase::SetZoom(int percent)
837 {
838 if (m_currentZoom == percent)
839 return;
840
841 m_currentZoom = percent;
842 if (m_previewBitmap)
843 {
844 delete m_previewBitmap;
845 m_previewBitmap = NULL;
846 }
847
848 if (m_previewCanvas)
849 {
850 RenderPage(m_currentPage);
851 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
852 m_previewCanvas->Clear();
853 m_previewCanvas->Refresh();
854 }
855 }
856
857 #endif // wxUSE_PRINTING_ARCHITECTURE