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