]> git.saurik.com Git - wxWidgets.git/blob - src/common/prntbase.cpp
wxCocoa: Added preliminary Blit support
[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, wxWindow *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 // Give the application 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 #if wxUSE_STATUSBAR
551 CreateStatusBar();
552 #endif
553 CreateCanvas();
554 CreateControlBar();
555
556 m_printPreview->SetCanvas(m_previewCanvas);
557 m_printPreview->SetFrame(this);
558
559 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
560
561 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
562 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
563
564 SetAutoLayout( TRUE );
565 SetSizer( item0 );
566
567 // MakeModal doesn't work on wxMac, especially when there
568 // are multiple top-level windows.
569 #ifndef __WXMAC__
570 MakeModal(TRUE);
571 #endif
572
573 Layout();
574 }
575
576 void wxPreviewFrame::CreateCanvas()
577 {
578 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
579 }
580
581 void wxPreviewFrame::CreateControlBar()
582 {
583 long buttons = wxPREVIEW_DEFAULT;
584 if (m_printPreview->GetPrintoutForPrinting())
585 buttons |= wxPREVIEW_PRINT;
586
587 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0, 0), wxSize(400, 40));
588 m_controlBar->CreateButtons();
589 }
590
591 /*
592 * Print preview
593 */
594
595 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
596 wxPrintout *printoutForPrinting,
597 wxPrintData *data)
598 {
599 if (data)
600 m_printDialogData = (*data);
601
602 Init(printout, printoutForPrinting);
603 }
604
605 wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
606 wxPrintout *printoutForPrinting,
607 wxPrintDialogData *data)
608 {
609 if (data)
610 m_printDialogData = (*data);
611
612 Init(printout, printoutForPrinting);
613 }
614
615 void wxPrintPreviewBase::Init(wxPrintout *printout,
616 wxPrintout *printoutForPrinting)
617 {
618 m_isOk = TRUE;
619 m_previewPrintout = printout;
620 if (m_previewPrintout)
621 m_previewPrintout->SetIsPreview(TRUE);
622
623 m_printPrintout = printoutForPrinting;
624
625 m_previewCanvas = NULL;
626 m_previewFrame = NULL;
627 m_previewBitmap = NULL;
628 m_currentPage = 1;
629 m_currentZoom = 70;
630 m_topMargin = 40;
631 m_leftMargin = 40;
632 m_pageWidth = 0;
633 m_pageHeight = 0;
634 m_printingPrepared = FALSE;
635
636 // Too soon! Moved to RenderPage.
637 // printout->OnPreparePrinting();
638
639 // Get some parameters from the printout, if defined
640 int selFrom, selTo;
641 printout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
642 }
643
644 wxPrintPreviewBase::~wxPrintPreviewBase()
645 {
646 if (m_previewPrintout)
647 delete m_previewPrintout;
648 if (m_previewBitmap)
649 delete m_previewBitmap;
650 if (m_printPrintout)
651 delete m_printPrintout;
652 }
653
654 bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
655 {
656 if (m_currentPage == pageNum)
657 return TRUE;
658
659 m_currentPage = pageNum;
660 if (m_previewBitmap)
661 {
662 delete m_previewBitmap;
663 m_previewBitmap = NULL;
664 }
665
666 if (m_previewCanvas)
667 {
668 if (!RenderPage(pageNum))
669 return FALSE;
670 m_previewCanvas->Refresh();
671 }
672 return TRUE;
673 }
674
675 bool wxPrintPreviewBase::PaintPage(wxWindow *canvas, wxDC& dc)
676 {
677 DrawBlankPage(canvas, dc);
678
679 if (!m_previewBitmap)
680 if (!RenderPage(m_currentPage))
681 return FALSE;
682
683 if (!m_previewBitmap)
684 return FALSE;
685
686 if (!canvas)
687 return FALSE;
688
689 int canvasWidth, canvasHeight;
690 canvas->GetSize(&canvasWidth, &canvasHeight);
691
692 double zoomScale = ((float)m_currentZoom/(float)100);
693 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
694 // float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
695
696 int x = (int) ((canvasWidth - actualWidth)/2.0);
697 if (x < m_leftMargin)
698 x = m_leftMargin;
699 int y = m_topMargin;
700
701 wxMemoryDC temp_dc;
702 temp_dc.SelectObject(*m_previewBitmap);
703
704 dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
705
706 temp_dc.SelectObject(wxNullBitmap);
707
708 return TRUE;
709 }
710
711 bool wxPrintPreviewBase::RenderPage(int pageNum)
712 {
713 wxBusyCursor busy;
714
715 int canvasWidth, canvasHeight;
716
717 if (!m_previewCanvas)
718 {
719 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
720
721 return FALSE;
722 }
723 m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
724
725 double zoomScale = (m_currentZoom/100.0);
726 int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
727 int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
728
729 int x = (int)((canvasWidth - actualWidth)/2.0);
730 if (x < m_leftMargin)
731 x = m_leftMargin;
732 // int y = m_topMargin;
733
734
735 if (!m_previewBitmap)
736 {
737 m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
738 if (!m_previewBitmap || !m_previewBitmap->Ok())
739 {
740 if (m_previewBitmap) {
741 delete m_previewBitmap;
742 m_previewBitmap = NULL;
743 }
744 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
745 return FALSE;
746 }
747 }
748
749 wxMemoryDC memoryDC;
750 memoryDC.SelectObject(*m_previewBitmap);
751
752 memoryDC.Clear();
753
754 m_previewPrintout->SetDC(&memoryDC);
755 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
756
757 // Need to delay OnPreparePrinting until here, so we have enough information.
758 if (!m_printingPrepared)
759 {
760 m_previewPrintout->OnPreparePrinting();
761 m_printingPrepared = TRUE;
762 }
763
764 m_previewPrintout->OnBeginPrinting();
765
766 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
767 {
768 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
769
770 memoryDC.SelectObject(wxNullBitmap);
771
772 delete m_previewBitmap;
773 m_previewBitmap = NULL;
774 return FALSE;
775 }
776
777 m_previewPrintout->OnPrintPage(pageNum);
778 m_previewPrintout->OnEndDocument();
779 m_previewPrintout->OnEndPrinting();
780
781 m_previewPrintout->SetDC(NULL);
782
783 memoryDC.SelectObject(wxNullBitmap);
784
785 #if wxUSE_STATUSBAR
786 wxString status;
787 if (m_maxPage != 0)
788 status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
789 else
790 status = wxString::Format(_("Page %d"), pageNum);
791
792 if (m_previewFrame)
793 m_previewFrame->SetStatusText(status);
794 #endif
795
796 return TRUE;
797 }
798
799
800 bool wxPrintPreviewBase::DrawBlankPage(wxWindow *canvas, wxDC& dc)
801 {
802 int canvasWidth, canvasHeight;
803 canvas->GetSize(&canvasWidth, &canvasHeight);
804
805 float zoomScale = (float)((float)m_currentZoom/(float)100);
806 float actualWidth = zoomScale*m_pageWidth*m_previewScale;
807 float actualHeight = zoomScale*m_pageHeight*m_previewScale;
808
809 float x = (float)((canvasWidth - actualWidth)/2.0);
810 if (x < m_leftMargin)
811 x = (float)m_leftMargin;
812 float y = (float)m_topMargin;
813
814 // Draw shadow, allowing for 1-pixel border AROUND the actual page
815 int shadowOffset = 4;
816 dc.SetPen(*wxBLACK_PEN);
817 dc.SetBrush(*wxBLACK_BRUSH);
818 /*
819 dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
820 */
821 dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
822 dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
823
824 // Draw blank page allowing for 1-pixel border AROUND the actual page
825 dc.SetPen(*wxBLACK_PEN);
826 dc.SetBrush(*wxWHITE_BRUSH);
827
828 /*
829 wxRegion update_region = canvas->GetUpdateRegion();
830 wxRect r = update_region.GetBox();
831
832 printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
833 */
834
835 dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
836
837 return TRUE;
838 }
839
840 void wxPrintPreviewBase::SetZoom(int percent)
841 {
842 if (m_currentZoom == percent)
843 return;
844
845 m_currentZoom = percent;
846 if (m_previewBitmap)
847 {
848 delete m_previewBitmap;
849 m_previewBitmap = NULL;
850 }
851
852 if (m_previewCanvas)
853 {
854 RenderPage(m_currentPage);
855 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
856 m_previewCanvas->Clear();
857 m_previewCanvas->Refresh();
858 }
859 }
860
861 #endif // wxUSE_PRINTING_ARCHITECTURE