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