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