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