]> git.saurik.com Git - wxWidgets.git/blame - src/common/prntbase.cpp
fixed win32 code to not use MB_ERR_INVALID_CHARS on win version where it isn't availa...
[wxWidgets.git] / src / common / prntbase.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
cb7d7375 2// Name: src/common/prntbase.cpp
c801d85f
KB
3// Purpose: Printing framework base class implementation
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
55d99c7a 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
c801d85f
KB
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
c801d85f
KB
19#include "wx/defs.h"
20
d427503c
VZ
21#if wxUSE_PRINTING_ARCHITECTURE
22
c801d85f
KB
23#ifndef WX_PRECOMP
24#include "wx/utils.h"
25#include "wx/dc.h"
26#include "wx/app.h"
27#include "wx/msgdlg.h"
28#include "wx/layout.h"
29#include "wx/choice.h"
30#include "wx/button.h"
31#include "wx/settings.h"
32#include "wx/dcmemory.h"
33#include "wx/stattext.h"
34#include "wx/intl.h"
384a1303 35#include "wx/textdlg.h"
2b5f62a0
VZ
36#include "wx/sizer.h"
37#endif // !WX_PRECOMP
c801d85f
KB
38
39#include "wx/prntbase.h"
40#include "wx/dcprint.h"
41#include "wx/printdlg.h"
e81e3883 42#include "wx/print.h"
2a47d3c1 43#include "wx/module.h"
c801d85f
KB
44
45#include <stdlib.h>
46#include <string.h>
47
891daf8c
RR
48#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
49#include "wx/msw/printdlg.h"
50#elif defined(__WXMAC__)
51#include "wx/mac/printdlg.h"
dc7ccb9c 52#include "wx/mac/private/print.h"
891daf8c
RR
53#else
54#include "wx/generic/prntdlgg.h"
55#endif
56
2049ba38 57#ifdef __WXMSW__
660296aa 58 #include "wx/msw/wrapcdlg.h"
d427503c
VZ
59 #ifndef __WIN32__
60 #include <print.h>
61 #endif
62#endif // __WXMSW__
c801d85f 63
e81e3883
RR
64//----------------------------------------------------------------------------
65// wxPrintFactory
66//----------------------------------------------------------------------------
67
68wxPrintFactory *wxPrintFactory::m_factory = NULL;
383f6abd 69
e81e3883 70void wxPrintFactory::SetPrintFactory( wxPrintFactory *factory )
383f6abd
WS
71{
72 if (wxPrintFactory::m_factory)
e81e3883 73 delete wxPrintFactory::m_factory;
383f6abd
WS
74
75 wxPrintFactory::m_factory = factory;
e81e3883 76}
c801d85f 77
e81e3883
RR
78wxPrintFactory *wxPrintFactory::GetFactory()
79{
80 if (!wxPrintFactory::m_factory)
383f6abd 81 wxPrintFactory::m_factory = new wxNativePrintFactory;
c801d85f 82
e81e3883
RR
83 return wxPrintFactory::m_factory;
84}
85
86//----------------------------------------------------------------------------
87// wxNativePrintFactory
88//----------------------------------------------------------------------------
89
90wxPrinterBase *wxNativePrintFactory::CreatePrinter( wxPrintDialogData *data )
383f6abd
WS
91{
92#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
e81e3883
RR
93 return new wxWindowsPrinter( data );
94#elif defined(__WXMAC__)
95 return new wxMacPrinter( data );
21708c73
SN
96#elif defined(__WXPM__)
97 return new wxOS2Printer( data );
e81e3883
RR
98#else
99 return new wxPostScriptPrinter( data );
100#endif
259c43f6 101}
e81e3883 102
383f6abd 103wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
e81e3883
RR
104 wxPrintout *printout, wxPrintDialogData *data )
105{
383f6abd 106#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
e81e3883
RR
107 return new wxWindowsPrintPreview( preview, printout, data );
108#elif defined(__WXMAC__)
109 return new wxMacPrintPreview( preview, printout, data );
21708c73
SN
110#elif defined(__WXPM__)
111 return new wxOS2PrintPreview( preview, printout, data );
e81e3883
RR
112#else
113 return new wxPostScriptPrintPreview( preview, printout, data );
114#endif
115}
116
383f6abd 117wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
e81e3883
RR
118 wxPrintout *printout, wxPrintData *data )
119{
383f6abd 120#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
e81e3883
RR
121 return new wxWindowsPrintPreview( preview, printout, data );
122#elif defined(__WXMAC__)
123 return new wxMacPrintPreview( preview, printout, data );
21708c73
SN
124#elif defined(__WXPM__)
125 return new wxOS2PrintPreview( preview, printout, data );
e81e3883
RR
126#else
127 return new wxPostScriptPrintPreview( preview, printout, data );
128#endif
129}
130
2997ca30 131wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
c061373d
RR
132 wxPrintDialogData *data )
133{
134#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
135 return new wxWindowsPrintDialog( parent, data );
136#elif defined(__WXMAC__)
137 return new wxMacPrintDialog( parent, data );
138#else
139 return new wxGenericPrintDialog( parent, data );
140#endif
141}
142
2997ca30 143wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
c061373d
RR
144 wxPrintData *data )
145{
146#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
147 return new wxWindowsPrintDialog( parent, data );
148#elif defined(__WXMAC__)
149 return new wxMacPrintDialog( parent, data );
150#else
151 return new wxGenericPrintDialog( parent, data );
152#endif
153}
154
2997ca30 155wxPageSetupDialogBase *wxNativePrintFactory::CreatePageSetupDialog( wxWindow *parent,
891daf8c
RR
156 wxPageSetupDialogData *data )
157{
158#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
159 return new wxWindowsPageSetupDialog( parent, data );
160#elif defined(__WXMAC__)
161 return new wxMacPageSetupDialog( parent, data );
162#else
163 return new wxGenericPageSetupDialog( parent, data );
164#endif
165}
166
6038ec8e
RR
167bool wxNativePrintFactory::HasPrintSetupDialog()
168{
169#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
170 return false;
171#elif defined(__WXMAC__)
172 return false;
173#else
174 // Only here do we need to provide the print setup
175 // dialog ourselves, the other platforms either have
176 // none, don't make it accessible or let you configure
177 // the printer from the wxPrintDialog anyway.
178 return true;
179#endif
2997ca30 180
6038ec8e
RR
181}
182
2997ca30 183wxDialog *wxNativePrintFactory::CreatePrintSetupDialog( wxWindow *parent,
891daf8c 184 wxPrintData *data )
6038ec8e
RR
185{
186#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
ce403057
WS
187 wxUnusedVar(parent);
188 wxUnusedVar(data);
6038ec8e
RR
189 return NULL;
190#elif defined(__WXMAC__)
ce403057
WS
191 wxUnusedVar(parent);
192 wxUnusedVar(data);
6038ec8e
RR
193 return NULL;
194#else
195 // Only here do we need to provide the print setup
196 // dialog ourselves, the other platforms either have
197 // none, don't make it accessible or let you configure
198 // the printer from the wxPrintDialog anyway.
199 return new wxGenericPrintSetupDialog( parent, data );
200#endif
201}
202
203bool wxNativePrintFactory::HasOwnPrintToFile()
204{
205 // Only relevant for PostScript and here the
2997ca30 206 // setup dialog provides no "print to file"
6038ec8e
RR
207 // option. In the GNOME setup dialog, the
208 // setup dialog has its own print to file.
209 return false;
210}
211
212bool wxNativePrintFactory::HasPrinterLine()
213{
214 // Only relevant for PostScript for now
215 return true;
216}
217
218wxString wxNativePrintFactory::CreatePrinterLine()
219{
220 // Only relevant for PostScript for now
2997ca30 221
6038ec8e
RR
222 // We should query "lpstat -d" here
223 return _("Generic PostScript");
224}
225
226bool wxNativePrintFactory::HasStatusLine()
227{
228 // Only relevant for PostScript for now
2997ca30 229 return true;
6038ec8e
RR
230}
231
232wxString wxNativePrintFactory::CreateStatusLine()
233{
234 // Only relevant for PostScript for now
2997ca30 235
6038ec8e
RR
236 // We should query "lpstat -r" or "lpstat -p" here
237 return _("Ready");
238}
239
8850cbd3
RR
240wxPrintNativeDataBase *wxNativePrintFactory::CreatePrintNativeData()
241{
242#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
243 return new wxWindowsPrintNativeData;
244#elif defined(__WXMAC__)
dc7ccb9c 245 return new wxMacCarbonPrintData;
8850cbd3
RR
246#else
247 return new wxPostScriptPrintNativeData;
248#endif
249}
250
251//----------------------------------------------------------------------------
252// wxPrintNativeDataBase
253//----------------------------------------------------------------------------
254
255IMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase, wxObject)
256
257wxPrintNativeDataBase::wxPrintNativeDataBase()
2997ca30
WS
258{
259 m_ref = 1;
8850cbd3
RR
260}
261
0ab2de15
RR
262//----------------------------------------------------------------------------
263// wxPrintFactoryModule
264//----------------------------------------------------------------------------
265
266class wxPrintFactoryModule: public wxModule
267{
268public:
269 wxPrintFactoryModule() {}
270 bool OnInit() { return true; }
271 void OnExit() { wxPrintFactory::SetPrintFactory( NULL ); }
2997ca30 272
0ab2de15
RR
273private:
274 DECLARE_DYNAMIC_CLASS(wxPrintFactoryModule)
275};
276
277IMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule, wxModule)
278
e81e3883
RR
279//----------------------------------------------------------------------------
280// wxPrinterBase
281//----------------------------------------------------------------------------
282
283IMPLEMENT_CLASS(wxPrinterBase, wxObject)
7bcb11d3
JS
284
285wxPrinterBase::wxPrinterBase(wxPrintDialogData *data)
c801d85f 286{
7bcb11d3
JS
287 m_currentPrintout = (wxPrintout *) NULL;
288 sm_abortWindow = (wxWindow *) NULL;
7e548f6b 289 sm_abortIt = false;
7bcb11d3
JS
290 if (data)
291 m_printDialogData = (*data);
f6bcfd97 292 sm_lastError = wxPRINTER_NO_ERROR;
c801d85f
KB
293}
294
34da0970 295wxWindow *wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
7e548f6b 296bool wxPrinterBase::sm_abortIt = false;
f6bcfd97 297wxPrinterError wxPrinterBase::sm_lastError = wxPRINTER_NO_ERROR;
c801d85f 298
34da0970 299wxPrinterBase::~wxPrinterBase()
c801d85f
KB
300{
301}
302
fc799548 303wxWindow *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout * printout)
c801d85f 304{
fc799548 305 wxPrintAbortDialog *dialog = new wxPrintAbortDialog(parent, _("Printing ") , wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
8826f46f 306
fc799548 307 wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
7e548f6b 308 button_sizer->Add( new wxStaticText(dialog, wxID_ANY, _("Please wait while printing\n") + printout->GetTitle() ), 0, wxALL, 10 );
fc799548 309 button_sizer->Add( new wxButton( dialog, wxID_CANCEL, wxT("Cancel") ), 0, wxALL | wxALIGN_CENTER, 10 );
8826f46f 310
7e548f6b 311 dialog->SetAutoLayout( true );
fc799548
JS
312 dialog->SetSizer( button_sizer );
313
314 button_sizer->Fit(dialog);
315 button_sizer->SetSizeHints (dialog) ;
8826f46f 316
7bcb11d3 317 return dialog;
c801d85f
KB
318}
319
161f4f73 320void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), const wxString& message)
c801d85f 321{
7bcb11d3 322 wxMessageBox(message, _("Printing Error"), wxOK, parent);
c801d85f
KB
323}
324
c061373d
RR
325wxPrintDialogData& wxPrinterBase::GetPrintDialogData() const
326{
327 return (wxPrintDialogData&) m_printDialogData;
328}
329
e81e3883
RR
330//----------------------------------------------------------------------------
331// wxPrinter
332//----------------------------------------------------------------------------
333
334IMPLEMENT_CLASS(wxPrinter, wxPrinterBase)
335
336wxPrinter::wxPrinter(wxPrintDialogData *data)
337{
338 m_pimpl = wxPrintFactory::GetFactory()->CreatePrinter( data );
339}
340
341wxPrinter::~wxPrinter()
342{
343 delete m_pimpl;
344}
345
346wxWindow *wxPrinter::CreateAbortWindow(wxWindow *parent, wxPrintout *printout)
347{
348 return m_pimpl->CreateAbortWindow( parent, printout );
349}
350
351void wxPrinter::ReportError(wxWindow *parent, wxPrintout *printout, const wxString& message)
352{
353 m_pimpl->ReportError( parent, printout, message );
354}
355
356bool wxPrinter::Setup(wxWindow *parent)
357{
358 return m_pimpl->Setup( parent );
359}
360
361bool wxPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
362{
363 return m_pimpl->Print( parent, printout, prompt );
364}
365
366wxDC* wxPrinter::PrintDialog(wxWindow *parent)
367{
368 return m_pimpl->PrintDialog( parent );
369}
370
c061373d
RR
371wxPrintDialogData& wxPrinter::GetPrintDialogData() const
372{
373 return m_pimpl->GetPrintDialogData();
374}
375
376// ---------------------------------------------------------------------------
891daf8c 377// wxPrintDialogBase: the dialog for printing.
c061373d
RR
378// ---------------------------------------------------------------------------
379
891daf8c 380IMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase, wxDialog)
c061373d 381
6ce8c562 382wxPrintDialogBase::wxPrintDialogBase(wxWindow *parent,
2997ca30 383 wxWindowID id,
6ce8c562
VZ
384 const wxString &title,
385 const wxPoint &pos,
386 const wxSize &size,
387 long style)
891daf8c
RR
388 : wxDialog( parent, id, title.empty() ? wxString(_("Print")) : title,
389 pos, size, style )
c061373d
RR
390{
391}
392
393// ---------------------------------------------------------------------------
891daf8c 394// wxPrintDialog: the dialog for printing
c061373d
RR
395// ---------------------------------------------------------------------------
396
397IMPLEMENT_CLASS(wxPrintDialog, wxObject)
398
399wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintDialogData* data)
400{
401 m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
402}
403
404wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintData* data)
405{
406 m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
407}
408
409wxPrintDialog::~wxPrintDialog()
410{
411 delete m_pimpl;
412}
413
414int wxPrintDialog::ShowModal()
415{
416 return m_pimpl->ShowModal();
417}
418
419wxPrintDialogData& wxPrintDialog::GetPrintDialogData()
420{
421 return m_pimpl->GetPrintDialogData();
422}
423
424wxPrintData& wxPrintDialog::GetPrintData()
425{
426 return m_pimpl->GetPrintData();
427}
891daf8c 428
c061373d
RR
429wxDC *wxPrintDialog::GetPrintDC()
430{
431 return m_pimpl->GetPrintDC();
432}
433
891daf8c
RR
434// ---------------------------------------------------------------------------
435// wxPageSetupDialogBase: the page setup dialog
436// ---------------------------------------------------------------------------
437
438IMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase, wxDialog)
439
440wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow *parent,
2997ca30 441 wxWindowID id,
891daf8c
RR
442 const wxString &title,
443 const wxPoint &pos,
444 const wxSize &size,
445 long style)
446 : wxDialog( parent, id, title.empty() ? wxString(_("Page setup")) : title,
447 pos, size, style )
448{
449}
450
451// ---------------------------------------------------------------------------
452// wxPageSetupDialog: the page setup dialog
453// ---------------------------------------------------------------------------
454
455IMPLEMENT_CLASS(wxPageSetupDialog, wxObject)
456
457wxPageSetupDialog::wxPageSetupDialog(wxWindow *parent, wxPageSetupDialogData *data )
458{
459 m_pimpl = wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent, data );
460}
461
462wxPageSetupDialog::~wxPageSetupDialog()
463{
464 delete m_pimpl;
465}
466
467int wxPageSetupDialog::ShowModal()
468{
469 return m_pimpl->ShowModal();
470}
471
472wxPageSetupDialogData& wxPageSetupDialog::GetPageSetupDialogData()
473{
474 return m_pimpl->GetPageSetupDialogData();
475}
476
477// old name
478wxPageSetupDialogData& wxPageSetupDialog::GetPageSetupData()
479{
480 return m_pimpl->GetPageSetupDialogData();
481}
482
e81e3883
RR
483//----------------------------------------------------------------------------
484// wxPrintAbortDialog
485//----------------------------------------------------------------------------
486
487BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
488 EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
489END_EVENT_TABLE()
490
491void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
492{
493 wxPrinterBase::sm_abortIt = true;
494 wxPrinterBase::sm_abortWindow->Show(false);
495 wxPrinterBase::sm_abortWindow->Close(true);
496 wxPrinterBase::sm_abortWindow = (wxWindow *) NULL;
497}
498
499//----------------------------------------------------------------------------
500// wxPrintout
501//----------------------------------------------------------------------------
502
503IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
7bcb11d3 504
34da0970 505wxPrintout::wxPrintout(const wxString& title)
c801d85f 506{
7bcb11d3
JS
507 m_printoutTitle = title ;
508 m_printoutDC = (wxDC *) NULL;
509 m_pageWidthMM = 0;
510 m_pageHeightMM = 0;
511 m_pageWidthPixels = 0;
512 m_pageHeightPixels = 0;
513 m_PPIScreenX = 0;
514 m_PPIScreenY = 0;
515 m_PPIPrinterX = 0;
516 m_PPIPrinterY = 0;
7e548f6b 517 m_isPreview = false;
c801d85f
KB
518}
519
34da0970 520wxPrintout::~wxPrintout()
c801d85f 521{
c801d85f
KB
522}
523
524bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
525{
fc799548 526 return GetDC()->StartDoc(_("Printing ") + m_printoutTitle);
c801d85f
KB
527}
528
34da0970 529void wxPrintout::OnEndDocument()
c801d85f 530{
7bcb11d3 531 GetDC()->EndDoc();
c801d85f
KB
532}
533
34da0970 534void wxPrintout::OnBeginPrinting()
c801d85f
KB
535{
536}
537
34da0970 538void wxPrintout::OnEndPrinting()
c801d85f
KB
539{
540}
541
542bool wxPrintout::HasPage(int page)
543{
7bcb11d3 544 return (page == 1);
c801d85f
KB
545}
546
547void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
548{
7bcb11d3
JS
549 *minPage = 1;
550 *maxPage = 32000;
551 *fromPage = 1;
552 *toPage = 1;
c801d85f
KB
553}
554
e81e3883
RR
555//----------------------------------------------------------------------------
556// wxPreviewCanvas
557//----------------------------------------------------------------------------
558
559IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
560
561BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
562 EVT_PAINT(wxPreviewCanvas::OnPaint)
563 EVT_CHAR(wxPreviewCanvas::OnChar)
564 EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
fb6efdf2
VZ
565#if wxUSE_MOUSEWHEEL
566 EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel)
567#endif
e81e3883 568END_EVENT_TABLE()
7bcb11d3 569
e9cafd42
VZ
570// VZ: the current code doesn't refresh properly without
571// wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
572// really horrible flicker when resizing the preview frame, but without
573// this style it simply doesn't work correctly at all...
c801d85f 574wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
7bcb11d3 575 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
7e548f6b 576wxScrolledWindow(parent, wxID_ANY, pos, size, style | wxFULL_REPAINT_ON_RESIZE, name)
c801d85f 577{
7bcb11d3 578 m_printPreview = preview;
46b24ef9
JS
579#ifdef __WXMAC__
580 // The app workspace colour is always white, but we should have
581 // a contrast with the page.
ca5020c2 582 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
46b24ef9
JS
583#else
584 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
e71fd398 585#endif
46b24ef9 586 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
8826f46f 587
d2b354f9 588 SetScrollbars(10, 10, 100, 100);
c801d85f
KB
589}
590
34da0970 591wxPreviewCanvas::~wxPreviewCanvas()
c801d85f
KB
592{
593}
594
595void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
596{
7bcb11d3
JS
597 wxPaintDC dc(this);
598 PrepareDC( dc );
8826f46f 599
a56fcaaf 600/*
809934d2
RR
601#ifdef __WXGTK__
602 if (!GetUpdateRegion().IsEmpty())
603 dc.SetClippingRegion( GetUpdateRegion() );
604#endif
a56fcaaf 605*/
809934d2 606
7bcb11d3
JS
607 if (m_printPreview)
608 {
609 m_printPreview->PaintPage(this, dc);
610 }
c801d85f
KB
611}
612
613// Responds to colour changes, and passes event on to children.
614void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
615{
46b24ef9
JS
616#ifdef __WXMAC__
617 // The app workspace colour is always white, but we should have
618 // a contrast with the page.
ca5020c2 619 wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
46b24ef9
JS
620#else
621 wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
e71fd398 622#endif
46b24ef9 623 SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
7bcb11d3 624 Refresh();
8826f46f 625
7bcb11d3
JS
626 // Propagate the event to the non-top-level children
627 wxWindow::OnSysColourChanged(event);
c801d85f
KB
628}
629
d2b354f9
JS
630void wxPreviewCanvas::OnChar(wxKeyEvent &event)
631{
b38b0d22 632 wxPreviewControlBar* controlBar = ((wxPreviewFrame*) GetParent())->GetControlBar();
d2b354f9
JS
633 if (event.GetKeyCode() == WXK_ESCAPE)
634 {
7e548f6b 635 ((wxPreviewFrame*) GetParent())->Close(true);
d2b354f9 636 return;
e71fd398 637 }
b38b0d22
JS
638 else if (event.GetKeyCode() == WXK_TAB)
639 {
640 controlBar->OnGoto();
641 return;
d2b354f9 642 }
b38b0d22
JS
643 else if (event.GetKeyCode() == WXK_RETURN)
644 {
645 controlBar->OnPrint();
646 return;
647 }
648
d2b354f9
JS
649 if (!event.ControlDown())
650 {
651 event.Skip();
652 return;
653 }
e71fd398 654
b38b0d22
JS
655 switch(event.GetKeyCode())
656 {
657 case WXK_NEXT:
658 controlBar->OnNext(); break;
659 case WXK_PRIOR:
660 controlBar->OnPrevious(); break;
661 case WXK_HOME:
662 controlBar->OnFirst(); break;
663 case WXK_END:
664 controlBar->OnLast(); break;
665 default:
666 event.Skip();
667 }
d2b354f9
JS
668}
669
fb6efdf2
VZ
670#if wxUSE_MOUSEWHEEL
671
672void wxPreviewCanvas::OnMouseWheel(wxMouseEvent& event)
673{
674 wxPreviewControlBar *
675 controlBar = wxStaticCast(GetParent(), wxPreviewFrame)->GetControlBar();
676
677 if ( controlBar )
678 {
679 if ( event.ControlDown() && event.GetWheelRotation() != 0 )
680 {
681 int currentZoom = controlBar->GetZoomControl();
682
683 int delta;
684 if ( currentZoom < 100 )
685 delta = 5;
686 else if ( currentZoom <= 120 )
687 delta = 10;
688 else
689 delta = 50;
690
691 if ( event.GetWheelRotation() > 0 )
692 delta = -delta;
693
694 int newZoom = currentZoom + delta;
695 if ( newZoom < 10 )
696 newZoom = 10;
697 if ( newZoom > 200 )
698 newZoom = 200;
699 if ( newZoom != currentZoom )
700 {
701 controlBar->SetZoomControl(newZoom);
702 m_printPreview->SetZoom(newZoom);
703 Refresh();
704 }
705 return;
706 }
707 }
708
709 event.Skip();
710}
711
712#endif // wxUSE_MOUSEWHEEL
713
e81e3883
RR
714//----------------------------------------------------------------------------
715// wxPreviewControlBar
716//----------------------------------------------------------------------------
717
718IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
c801d85f
KB
719
720BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
8826f46f 721 EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
90b6b974 722 EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrintButton)
0f90ec93
KB
723 EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
724 EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
bf89b538
JS
725 EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
726 EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
727 EVT_BUTTON(wxID_PREVIEW_GOTO, wxPreviewControlBar::OnGotoButton)
8826f46f
VZ
728 EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoom)
729 EVT_PAINT(wxPreviewControlBar::OnPaint)
c801d85f 730END_EVENT_TABLE()
7bcb11d3 731
c801d85f 732wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
7bcb11d3
JS
733 wxWindow *parent, const wxPoint& pos, const wxSize& size,
734 long style, const wxString& name):
7e548f6b 735wxPanel(parent, wxID_ANY, pos, size, style, name)
c801d85f 736{
7bcb11d3
JS
737 m_printPreview = preview;
738 m_closeButton = (wxButton *) NULL;
739 m_nextPageButton = (wxButton *) NULL;
740 m_previousPageButton = (wxButton *) NULL;
741 m_printButton = (wxButton *) NULL;
742 m_zoomControl = (wxChoice *) NULL;
743 m_buttonFlags = buttons;
c801d85f
KB
744}
745
34da0970 746wxPreviewControlBar::~wxPreviewControlBar()
c801d85f
KB
747{
748}
749
750void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
751{
7bcb11d3 752 wxPaintDC dc(this);
8826f46f 753
7bcb11d3
JS
754 int w, h;
755 GetSize(&w, &h);
756 dc.SetPen(*wxBLACK_PEN);
757 dc.SetBrush(*wxTRANSPARENT_BRUSH);
758 dc.DrawLine( 0, h-1, w, h-1 );
c801d85f
KB
759}
760
c330a2cf 761void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
c801d85f 762{
7bcb11d3 763 wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
7e548f6b 764 frame->Close(true);
c801d85f
KB
765}
766
b38b0d22 767void wxPreviewControlBar::OnPrint(void)
c801d85f 768{
7bcb11d3 769 wxPrintPreviewBase *preview = GetPrintPreview();
7e548f6b 770 preview->Print(true);
c801d85f
KB
771}
772
0f90ec93 773void wxPreviewControlBar::OnNext(void)
c801d85f 774{
7bcb11d3
JS
775 wxPrintPreviewBase *preview = GetPrintPreview();
776 if (preview)
c801d85f 777 {
7bcb11d3
JS
778 int currentPage = preview->GetCurrentPage();
779 if ((preview->GetMaxPage() > 0) &&
780 (currentPage < preview->GetMaxPage()) &&
781 preview->GetPrintout()->HasPage(currentPage + 1))
782 {
783 preview->SetCurrentPage(currentPage + 1);
784 }
c801d85f 785 }
c801d85f
KB
786}
787
0f90ec93 788void wxPreviewControlBar::OnPrevious(void)
c801d85f 789{
7bcb11d3
JS
790 wxPrintPreviewBase *preview = GetPrintPreview();
791 if (preview)
c801d85f 792 {
7bcb11d3
JS
793 int currentPage = preview->GetCurrentPage();
794 if ((preview->GetMinPage() > 0) &&
795 (currentPage > preview->GetMinPage()) &&
796 preview->GetPrintout()->HasPage(currentPage - 1))
797 {
798 preview->SetCurrentPage(currentPage - 1);
799 }
c801d85f 800 }
c801d85f
KB
801}
802
bf89b538
JS
803void wxPreviewControlBar::OnFirst(void)
804{
805 wxPrintPreviewBase *preview = GetPrintPreview();
806 if (preview)
807 {
808 int currentPage = preview->GetMinPage();
809 if (preview->GetPrintout()->HasPage(currentPage))
810 {
811 preview->SetCurrentPage(currentPage);
812 }
813 }
814}
815
816void wxPreviewControlBar::OnLast(void)
817{
818 wxPrintPreviewBase *preview = GetPrintPreview();
819 if (preview)
820 {
821 int currentPage = preview->GetMaxPage();
822 if (preview->GetPrintout()->HasPage(currentPage))
823 {
824 preview->SetCurrentPage(currentPage);
825 }
826 }
827}
828
829void wxPreviewControlBar::OnGoto(void)
830{
831 wxPrintPreviewBase *preview = GetPrintPreview();
832 if (preview)
833 {
834 long currentPage;
835
836 if (preview->GetMinPage() > 0)
837 {
838 wxString strPrompt;
839 wxString strPage;
840
d2b354f9 841 strPrompt.Printf( _("Enter a page number between %d and %d:"),
bf89b538 842 preview->GetMinPage(), preview->GetMaxPage());
7e99eddf 843 strPage.Printf( wxT("%d"), preview->GetCurrentPage() );
bf89b538
JS
844
845 strPage =
d2b354f9 846 wxGetTextFromUser( strPrompt, _("Goto Page"), strPage, GetParent());
bf89b538
JS
847
848 if ( strPage.ToLong( &currentPage ) )
849 if (preview->GetPrintout()->HasPage(currentPage))
850 {
851 preview->SetCurrentPage(currentPage);
852 }
853 }
854 }
855}
856
c801d85f
KB
857void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
858{
7bcb11d3
JS
859 int zoom = GetZoomControl();
860 if (GetPrintPreview())
861 GetPrintPreview()->SetZoom(zoom);
c801d85f
KB
862}
863
34da0970 864void wxPreviewControlBar::CreateButtons()
c801d85f 865{
7bcb11d3 866 SetSize(0, 0, 400, 40);
8826f46f 867
9dff8515 868 wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
e71fd398 869
9dff8515
JS
870 m_closeButton = new wxButton( this, wxID_PREVIEW_CLOSE, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
871 item0->Add( m_closeButton, 0, wxALIGN_CENTRE|wxALL, 5 );
e71fd398 872
7bcb11d3
JS
873 if (m_buttonFlags & wxPREVIEW_PRINT)
874 {
9dff8515
JS
875 m_printButton = new wxButton( this, wxID_PREVIEW_PRINT, _("&Print..."), wxDefaultPosition, wxDefaultSize, 0 );
876 item0->Add( m_printButton, 0, wxALIGN_CENTRE|wxALL, 5 );
7bcb11d3 877 }
e71fd398 878
bf89b538
JS
879 if (m_buttonFlags & wxPREVIEW_FIRST)
880 {
681aeb18 881 m_firstPageButton = new wxButton( this, wxID_PREVIEW_FIRST, _("|<<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
9dff8515 882 item0->Add( m_firstPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
bf89b538 883 }
e71fd398 884
7bcb11d3
JS
885 if (m_buttonFlags & wxPREVIEW_PREVIOUS)
886 {
681aeb18 887 m_previousPageButton = new wxButton( this, wxID_PREVIEW_PREVIOUS, _("<<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
9dff8515 888 item0->Add( m_previousPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
7bcb11d3 889 }
e71fd398 890
7bcb11d3
JS
891 if (m_buttonFlags & wxPREVIEW_NEXT)
892 {
681aeb18 893 m_nextPageButton = new wxButton( this, wxID_PREVIEW_NEXT, _(">>"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
9dff8515 894 item0->Add( m_nextPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
bf89b538 895 }
e71fd398 896
bf89b538
JS
897 if (m_buttonFlags & wxPREVIEW_LAST)
898 {
681aeb18 899 m_lastPageButton = new wxButton( this, wxID_PREVIEW_LAST, _(">>|"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
9dff8515 900 item0->Add( m_lastPageButton, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
bf89b538 901 }
e71fd398 902
bf89b538
JS
903 if (m_buttonFlags & wxPREVIEW_GOTO)
904 {
9dff8515
JS
905 m_gotoPageButton = new wxButton( this, wxID_PREVIEW_GOTO, _("&Goto..."), wxDefaultPosition, wxDefaultSize, 0 );
906 item0->Add( m_gotoPageButton, 0, wxALIGN_CENTRE|wxALL, 5 );
7bcb11d3 907 }
e71fd398 908
7bcb11d3
JS
909 if (m_buttonFlags & wxPREVIEW_ZOOM)
910 {
e71fd398 911 wxString choices[] =
c25ccf85 912 {
2b5f62a0 913 wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
9dff8515
JS
914 wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
915 wxT("120%"), wxT("150%"), wxT("200%")
c25ccf85 916 };
c25ccf85 917 int n = WXSIZEOF(choices);
e71fd398 918
7e548f6b 919 m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxSize(70,wxDefaultCoord), n, choices, 0 );
9dff8515 920 item0->Add( m_zoomControl, 0, wxALIGN_CENTRE|wxALL, 5 );
7bcb11d3
JS
921 SetZoomControl(m_printPreview->GetZoom());
922 }
8826f46f 923
9dff8515
JS
924 SetSizer(item0);
925 item0->Fit(this);
c801d85f
KB
926}
927
928void wxPreviewControlBar::SetZoomControl(int zoom)
929{
7bcb11d3 930 if (m_zoomControl)
963907fa
RR
931 {
932 int n, count = m_zoomControl->GetCount();
933 long val;
934 for (n=0; n<count; n++)
935 {
936 if (m_zoomControl->GetString(n).BeforeFirst(wxT('%')).ToLong(&val) &&
937 (val >= long(zoom)))
938 {
939 m_zoomControl->SetSelection(n);
940 return;
941 }
942 }
7e548f6b 943
963907fa
RR
944 m_zoomControl->SetSelection(count-1);
945 }
c801d85f
KB
946}
947
34da0970 948int wxPreviewControlBar::GetZoomControl()
c801d85f 949{
963907fa 950 if (m_zoomControl && (m_zoomControl->GetStringSelection() != wxEmptyString))
7bcb11d3 951 {
963907fa
RR
952 long val;
953 if (m_zoomControl->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val))
954 return int(val);
7bcb11d3 955 }
7e548f6b 956
963907fa 957 return 0;
c801d85f
KB
958}
959
960
961/*
7bcb11d3
JS
962* Preview frame
963*/
c801d85f 964
e81e3883
RR
965IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
966
e3065973 967BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
0f90ec93 968 EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
e3065973
JS
969END_EVENT_TABLE()
970
a5ae8241 971wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title,
7bcb11d3 972 const wxPoint& pos, const wxSize& size, long style, const wxString& name):
7e548f6b 973wxFrame(parent, wxID_ANY, title, pos, size, style, name)
c801d85f 974{
7bcb11d3
JS
975 m_printPreview = preview;
976 m_controlBar = NULL;
977 m_previewCanvas = NULL;
7c995553 978 m_windowDisabler = NULL;
46b24ef9 979
a5ae8241 980 // Give the application icon
46b24ef9
JS
981#ifdef __WXMSW__
982 wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
983 if (topFrame)
984 SetIcon(topFrame->GetIcon());
e71fd398 985#endif
c801d85f
KB
986}
987
34da0970 988wxPreviewFrame::~wxPreviewFrame()
c801d85f
KB
989{
990}
991
74e3313b 992void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
c801d85f 993{
7c995553
VZ
994 if (m_windowDisabler)
995 delete m_windowDisabler;
8826f46f 996
7bcb11d3
JS
997 // Need to delete the printout and the print preview
998 wxPrintout *printout = m_printPreview->GetPrintout();
999 if (printout)
1000 {
1001 delete printout;
1002 m_printPreview->SetPrintout(NULL);
1003 m_printPreview->SetCanvas(NULL);
1004 m_printPreview->SetFrame(NULL);
1005 }
1006 delete m_printPreview;
8826f46f 1007
7bcb11d3 1008 Destroy();
c801d85f
KB
1009}
1010
34da0970 1011void wxPreviewFrame::Initialize()
c801d85f 1012{
3080bf59 1013#if wxUSE_STATUSBAR
7bcb11d3 1014 CreateStatusBar();
3080bf59 1015#endif
7bcb11d3
JS
1016 CreateCanvas();
1017 CreateControlBar();
8826f46f 1018
7bcb11d3
JS
1019 m_printPreview->SetCanvas(m_previewCanvas);
1020 m_printPreview->SetFrame(this);
8826f46f 1021
9dff8515 1022 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
8826f46f 1023
9dff8515
JS
1024 item0->Add( m_controlBar, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
1025 item0->Add( m_previewCanvas, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
8826f46f 1026
7e548f6b 1027 SetAutoLayout( true );
9dff8515 1028 SetSizer( item0 );
8826f46f 1029
7c995553 1030 m_windowDisabler = new wxWindowDisabler(this);
8826f46f 1031
7bcb11d3 1032 Layout();
e71fd398 1033
d2b354f9
JS
1034 m_printPreview->AdjustScrollbars(m_previewCanvas);
1035 m_previewCanvas->SetFocus();
1036 m_controlBar->SetFocus();
c801d85f
KB
1037}
1038
34da0970 1039void wxPreviewFrame::CreateCanvas()
c801d85f 1040{
7bcb11d3 1041 m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
c801d85f
KB
1042}
1043
34da0970 1044void wxPreviewFrame::CreateControlBar()
c801d85f 1045{
7bcb11d3
JS
1046 long buttons = wxPREVIEW_DEFAULT;
1047 if (m_printPreview->GetPrintoutForPrinting())
1048 buttons |= wxPREVIEW_PRINT;
8826f46f 1049
c47addef 1050 m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this, wxPoint(0,0), wxSize(400, 40));
7bcb11d3 1051 m_controlBar->CreateButtons();
c801d85f 1052}
7bcb11d3 1053
c801d85f 1054/*
7bcb11d3
JS
1055* Print preview
1056*/
c801d85f 1057
891daf8c
RR
1058IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
1059
8826f46f
VZ
1060wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
1061 wxPrintout *printoutForPrinting,
1062 wxPrintData *data)
1063{
1064 if (data)
1065 m_printDialogData = (*data);
1066
1067 Init(printout, printoutForPrinting);
1068}
1069
1070wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
1071 wxPrintout *printoutForPrinting,
1072 wxPrintDialogData *data)
1073{
1074 if (data)
1075 m_printDialogData = (*data);
1076
1077 Init(printout, printoutForPrinting);
1078}
1079
1080void wxPrintPreviewBase::Init(wxPrintout *printout,
1081 wxPrintout *printoutForPrinting)
c801d85f 1082{
7e548f6b 1083 m_isOk = true;
7bcb11d3
JS
1084 m_previewPrintout = printout;
1085 if (m_previewPrintout)
7e548f6b 1086 m_previewPrintout->SetIsPreview(true);
8826f46f 1087
7bcb11d3 1088 m_printPrintout = printoutForPrinting;
8826f46f 1089
7bcb11d3
JS
1090 m_previewCanvas = NULL;
1091 m_previewFrame = NULL;
1092 m_previewBitmap = NULL;
1093 m_currentPage = 1;
c25ccf85 1094 m_currentZoom = 70;
7bcb11d3
JS
1095 m_topMargin = 40;
1096 m_leftMargin = 40;
1097 m_pageWidth = 0;
1098 m_pageHeight = 0;
7e548f6b 1099 m_printingPrepared = false;
d2b354f9
JS
1100 m_minPage = 1;
1101 m_maxPage = 1;
c801d85f
KB
1102}
1103
34da0970 1104wxPrintPreviewBase::~wxPrintPreviewBase()
c801d85f 1105{
7bcb11d3
JS
1106 if (m_previewPrintout)
1107 delete m_previewPrintout;
1108 if (m_previewBitmap)
1109 delete m_previewBitmap;
1110 if (m_printPrintout)
1111 delete m_printPrintout;
c801d85f
KB
1112}
1113
1114bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
1115{
7bcb11d3 1116 if (m_currentPage == pageNum)
7e548f6b 1117 return true;
8826f46f 1118
7bcb11d3
JS
1119 m_currentPage = pageNum;
1120 if (m_previewBitmap)
1121 {
1122 delete m_previewBitmap;
1123 m_previewBitmap = NULL;
1124 }
e71fd398 1125
7bcb11d3
JS
1126 if (m_previewCanvas)
1127 {
d2b354f9 1128 AdjustScrollbars(m_previewCanvas);
e71fd398 1129
9eee81a4 1130 if (!RenderPage(pageNum))
7e548f6b 1131 return false;
7bcb11d3 1132 m_previewCanvas->Refresh();
d2b354f9 1133 m_previewCanvas->SetFocus();
7bcb11d3 1134 }
7e548f6b 1135 return true;
c801d85f
KB
1136}
1137
383f6abd 1138int wxPrintPreviewBase::GetCurrentPage() const
259c43f6 1139 { return m_currentPage; }
383f6abd 1140void wxPrintPreviewBase::SetPrintout(wxPrintout *printout)
259c43f6 1141 { m_previewPrintout = printout; }
383f6abd 1142wxPrintout *wxPrintPreviewBase::GetPrintout() const
259c43f6 1143 { return m_previewPrintout; }
383f6abd 1144wxPrintout *wxPrintPreviewBase::GetPrintoutForPrinting() const
259c43f6 1145 { return m_printPrintout; }
383f6abd 1146void wxPrintPreviewBase::SetFrame(wxFrame *frame)
259c43f6 1147 { m_previewFrame = frame; }
383f6abd 1148void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas *canvas)
259c43f6 1149 { m_previewCanvas = canvas; }
383f6abd 1150wxFrame *wxPrintPreviewBase::GetFrame() const
e81e3883 1151 { return m_previewFrame; }
383f6abd 1152wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
e81e3883
RR
1153 { return m_previewCanvas; }
1154
d2b354f9 1155bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
c801d85f 1156{
7bcb11d3 1157 DrawBlankPage(canvas, dc);
8826f46f 1158
7bcb11d3 1159 if (!m_previewBitmap)
9eee81a4 1160 if (!RenderPage(m_currentPage))
7e548f6b 1161 return false;
8826f46f 1162
7bcb11d3 1163 if (!m_previewBitmap)
7e548f6b 1164 return false;
8826f46f 1165
7bcb11d3 1166 if (!canvas)
7e548f6b 1167 return false;
8826f46f 1168
7bcb11d3
JS
1169 int canvasWidth, canvasHeight;
1170 canvas->GetSize(&canvasWidth, &canvasHeight);
8826f46f 1171
7bcb11d3
JS
1172 double zoomScale = ((float)m_currentZoom/(float)100);
1173 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
1174 // float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
8826f46f 1175
7bcb11d3
JS
1176 int x = (int) ((canvasWidth - actualWidth)/2.0);
1177 if (x < m_leftMargin)
1178 x = m_leftMargin;
1179 int y = m_topMargin;
8826f46f 1180
7bcb11d3
JS
1181 wxMemoryDC temp_dc;
1182 temp_dc.SelectObject(*m_previewBitmap);
8826f46f 1183
7bcb11d3 1184 dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
8826f46f 1185
7bcb11d3 1186 temp_dc.SelectObject(wxNullBitmap);
8826f46f 1187
7e548f6b 1188 return true;
c801d85f
KB
1189}
1190
d2b354f9
JS
1191// Adjusts the scrollbars for the current scale
1192void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
1193{
1194 if (!canvas)
1195 return ;
1196
1197 int canvasWidth, canvasHeight;
1198 canvas->GetSize(&canvasWidth, &canvasHeight);
1199
1200 double zoomScale = ((float)m_currentZoom/(float)100);
1201 double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
1202 double actualHeight = (zoomScale*m_pageHeight*m_previewScale);
1203
1204 // Set the scrollbars appropriately
8b58d2df
VZ
1205 int totalWidth = (int)(actualWidth + 2*m_leftMargin);
1206 int totalHeight = (int)(actualHeight + 2*m_topMargin);
d2b354f9
JS
1207 int scrollUnitsX = totalWidth/10;
1208 int scrollUnitsY = totalHeight/10;
1209 wxSize virtualSize = canvas->GetVirtualSize();
1210 if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
7e548f6b 1211 canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
d2b354f9
JS
1212}
1213
c801d85f
KB
1214bool wxPrintPreviewBase::RenderPage(int pageNum)
1215{
f6bcfd97
BP
1216 wxBusyCursor busy;
1217
7bcb11d3 1218 int canvasWidth, canvasHeight;
8826f46f 1219
7bcb11d3 1220 if (!m_previewCanvas)
c801d85f 1221 {
f6bcfd97 1222 wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
771779ed 1223
7e548f6b 1224 return false;
c801d85f 1225 }
7bcb11d3 1226 m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
8826f46f 1227
7bcb11d3
JS
1228 double zoomScale = (m_currentZoom/100.0);
1229 int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
1230 int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
8826f46f 1231
7bcb11d3
JS
1232 if (!m_previewBitmap)
1233 {
1234 m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
1235 if (!m_previewBitmap || !m_previewBitmap->Ok())
1236 {
9eee81a4 1237 if (m_previewBitmap) {
7bcb11d3 1238 delete m_previewBitmap;
9eee81a4
GD
1239 m_previewBitmap = NULL;
1240 }
7bcb11d3 1241 wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
7e548f6b 1242 return false;
7bcb11d3
JS
1243 }
1244 }
8826f46f 1245
7bcb11d3
JS
1246 wxMemoryDC memoryDC;
1247 memoryDC.SelectObject(*m_previewBitmap);
8826f46f 1248
7bcb11d3 1249 memoryDC.Clear();
8826f46f 1250
7bcb11d3
JS
1251 m_previewPrintout->SetDC(&memoryDC);
1252 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
8826f46f 1253
1044a386
JS
1254 // Need to delay OnPreparePrinting until here, so we have enough information.
1255 if (!m_printingPrepared)
1256 {
1257 m_previewPrintout->OnPreparePrinting();
d2b354f9
JS
1258 int selFrom, selTo;
1259 m_previewPrintout->GetPageInfo(&m_minPage, &m_maxPage, &selFrom, &selTo);
7e548f6b 1260 m_printingPrepared = true;
1044a386
JS
1261 }
1262
7bcb11d3 1263 m_previewPrintout->OnBeginPrinting();
c801d85f 1264
7bcb11d3
JS
1265 if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
1266 {
1267 wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
8826f46f 1268
7bcb11d3 1269 memoryDC.SelectObject(wxNullBitmap);
8826f46f 1270
7bcb11d3 1271 delete m_previewBitmap;
9eee81a4 1272 m_previewBitmap = NULL;
7e548f6b 1273 return false;
7bcb11d3 1274 }
8826f46f 1275
7bcb11d3
JS
1276 m_previewPrintout->OnPrintPage(pageNum);
1277 m_previewPrintout->OnEndDocument();
1278 m_previewPrintout->OnEndPrinting();
8826f46f 1279
7bcb11d3 1280 m_previewPrintout->SetDC(NULL);
8826f46f 1281
c801d85f 1282 memoryDC.SelectObject(wxNullBitmap);
8826f46f 1283
3080bf59
VZ
1284#if wxUSE_STATUSBAR
1285 wxString status;
7bcb11d3 1286 if (m_maxPage != 0)
7e548f6b 1287 status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
7bcb11d3 1288 else
7e548f6b 1289 status = wxString::Format(_("Page %d"), pageNum);
8826f46f 1290
7bcb11d3 1291 if (m_previewFrame)
3080bf59
VZ
1292 m_previewFrame->SetStatusText(status);
1293#endif
8826f46f 1294
7e548f6b 1295 return true;
c801d85f
KB
1296}
1297
1298
d2b354f9 1299bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
c801d85f 1300{
7bcb11d3
JS
1301 int canvasWidth, canvasHeight;
1302 canvas->GetSize(&canvasWidth, &canvasHeight);
8826f46f 1303
7bcb11d3
JS
1304 float zoomScale = (float)((float)m_currentZoom/(float)100);
1305 float actualWidth = zoomScale*m_pageWidth*m_previewScale;
1306 float actualHeight = zoomScale*m_pageHeight*m_previewScale;
8826f46f 1307
7bcb11d3
JS
1308 float x = (float)((canvasWidth - actualWidth)/2.0);
1309 if (x < m_leftMargin)
1310 x = (float)m_leftMargin;
1311 float y = (float)m_topMargin;
8826f46f 1312
7bcb11d3
JS
1313 // Draw shadow, allowing for 1-pixel border AROUND the actual page
1314 int shadowOffset = 4;
1315 dc.SetPen(*wxBLACK_PEN);
1316 dc.SetBrush(*wxBLACK_BRUSH);
1317 /*
1318 dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
1319 */
1320 dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
1321 dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
8826f46f 1322
7bcb11d3
JS
1323 // Draw blank page allowing for 1-pixel border AROUND the actual page
1324 dc.SetPen(*wxBLACK_PEN);
1325 dc.SetBrush(*wxWHITE_BRUSH);
8826f46f 1326
7bcb11d3
JS
1327 /*
1328 wxRegion update_region = canvas->GetUpdateRegion();
1329 wxRect r = update_region.GetBox();
8826f46f 1330
7bcb11d3
JS
1331 printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
1332 */
8826f46f 1333
7bcb11d3 1334 dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
8826f46f 1335
7e548f6b 1336 return true;
2a47d3c1
JS
1337}
1338
7bcb11d3 1339void wxPrintPreviewBase::SetZoom(int percent)
2a47d3c1 1340{
7bcb11d3
JS
1341 if (m_currentZoom == percent)
1342 return;
8826f46f 1343
7bcb11d3
JS
1344 m_currentZoom = percent;
1345 if (m_previewBitmap)
1346 {
1347 delete m_previewBitmap;
1348 m_previewBitmap = NULL;
1349 }
aff37a19 1350
7bcb11d3
JS
1351 if (m_previewCanvas)
1352 {
d2b354f9 1353 AdjustScrollbars(m_previewCanvas);
aff37a19 1354 RenderPage(m_currentPage);
95724b1a 1355 ((wxScrolledWindow *) m_previewCanvas)->Scroll(0, 0);
e71fd398 1356 m_previewCanvas->ClearBackground();
7bcb11d3 1357 m_previewCanvas->Refresh();
d2b354f9 1358 m_previewCanvas->SetFocus();
7bcb11d3 1359 }
2a47d3c1
JS
1360}
1361
383f6abd
WS
1362wxPrintDialogData& wxPrintPreviewBase::GetPrintDialogData()
1363{
e81e3883
RR
1364 return m_printDialogData;
1365}
1366
383f6abd 1367int wxPrintPreviewBase::GetZoom() const
e81e3883 1368{ return m_currentZoom; }
383f6abd 1369int wxPrintPreviewBase::GetMaxPage() const
e81e3883 1370{ return m_maxPage; }
383f6abd 1371int wxPrintPreviewBase::GetMinPage() const
e81e3883 1372{ return m_minPage; }
383f6abd 1373bool wxPrintPreviewBase::Ok() const
e81e3883 1374{ return m_isOk; }
383f6abd 1375void wxPrintPreviewBase::SetOk(bool ok)
e81e3883
RR
1376{ m_isOk = ok; }
1377//----------------------------------------------------------------------------
1378// wxPrintPreview
1379//----------------------------------------------------------------------------
1380
1381IMPLEMENT_CLASS(wxPrintPreview, wxPrintPreviewBase)
1382
1383wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1384 wxPrintout *printoutForPrinting,
1385 wxPrintDialogData *data) :
1386 wxPrintPreviewBase( printout, printoutForPrinting, data )
1387{
1388 m_pimpl = wxPrintFactory::GetFactory()->
1389 CreatePrintPreview( printout, printoutForPrinting, data );
1390}
1391
1392wxPrintPreview::wxPrintPreview(wxPrintout *printout,
1393 wxPrintout *printoutForPrinting,
1394 wxPrintData *data ) :
1395 wxPrintPreviewBase( printout, printoutForPrinting, data )
1396{
1397 m_pimpl = wxPrintFactory::GetFactory()->
1398 CreatePrintPreview( printout, printoutForPrinting, data );
1399}
1400
1401wxPrintPreview::~wxPrintPreview()
1402{
1403 delete m_pimpl;
383f6abd 1404
e81e3883
RR
1405 // don't delete twice
1406 m_printPrintout = NULL;
1407 m_previewPrintout = NULL;
1408 m_previewBitmap = NULL;
1409}
1410
1411bool wxPrintPreview::SetCurrentPage(int pageNum)
1412{
1413 return m_pimpl->SetCurrentPage( pageNum );
1414}
1415
383f6abd
WS
1416int wxPrintPreview::GetCurrentPage() const
1417{
e81e3883
RR
1418 return m_pimpl->GetCurrentPage();
1419}
1420
383f6abd
WS
1421void wxPrintPreview::SetPrintout(wxPrintout *printout)
1422{
e81e3883
RR
1423 m_pimpl->SetPrintout( printout );
1424}
1425
383f6abd
WS
1426wxPrintout *wxPrintPreview::GetPrintout() const
1427{
e81e3883
RR
1428 return m_pimpl->GetPrintout();
1429}
1430
383f6abd
WS
1431wxPrintout *wxPrintPreview::GetPrintoutForPrinting() const
1432{
e81e3883
RR
1433 return m_pimpl->GetPrintoutForPrinting();
1434}
1435
383f6abd
WS
1436void wxPrintPreview::SetFrame(wxFrame *frame)
1437{
e81e3883
RR
1438 m_pimpl->SetFrame( frame );
1439}
1440
383f6abd
WS
1441void wxPrintPreview::SetCanvas(wxPreviewCanvas *canvas)
1442{
e81e3883
RR
1443 m_pimpl->SetCanvas( canvas );
1444}
1445
383f6abd 1446wxFrame *wxPrintPreview::GetFrame() const
e81e3883
RR
1447{
1448 return m_pimpl->GetFrame();
1449}
1450
383f6abd
WS
1451wxPreviewCanvas *wxPrintPreview::GetCanvas() const
1452{
e81e3883
RR
1453 return m_pimpl->GetCanvas();
1454}
1455
1456bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
1457{
1458 return m_pimpl->PaintPage( canvas, dc );
1459}
1460
1461bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
1462{
1463 return m_pimpl->DrawBlankPage( canvas, dc );
1464}
1465
1466void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas *canvas)
1467{
1468 m_pimpl->AdjustScrollbars( canvas );
1469}
1470
1471bool wxPrintPreview::RenderPage(int pageNum)
1472{
1473 return m_pimpl->RenderPage( pageNum );
1474}
1475
1476void wxPrintPreview::SetZoom(int percent)
1477{
1478 m_pimpl->SetZoom( percent );
1479}
1480
1481wxPrintDialogData& wxPrintPreview::GetPrintDialogData()
1482{
1483 return m_pimpl->GetPrintDialogData();
1484}
1485
1486int wxPrintPreview::GetMaxPage() const
1487{
1488 return m_pimpl->GetMaxPage();
1489}
1490
1491int wxPrintPreview::GetMinPage() const
1492{
1493 return m_pimpl->GetMinPage();
1494}
1495
1496bool wxPrintPreview::Ok() const
1497{
1498 return m_pimpl->Ok();
1499}
1500
1501void wxPrintPreview::SetOk(bool ok)
1502{
1503 m_pimpl->SetOk( ok );
1504}
1505
1506bool wxPrintPreview::Print(bool interactive)
1507{
1508 return m_pimpl->Print( interactive );
1509}
1510
1511void wxPrintPreview::DetermineScaling()
1512{
1513 m_pimpl->DetermineScaling();
1514}
1515
d427503c 1516#endif // wxUSE_PRINTING_ARCHITECTURE