]> git.saurik.com Git - wxWidgets.git/blame - src/generic/printps.cpp
don't dereference NULL parent in wxMDIChildFrame dtor if it hadn't been really created
[wxWidgets.git] / src / generic / printps.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
93763ad5 2// Name: src/generic/printps.cpp
c801d85f
KB
3// Purpose: Postscript print/preview framework
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6aa89a22 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__
8826f46f 16 #pragma hdrstop
c801d85f
KB
17#endif
18
93763ad5
WS
19// ============================================================================
20// declarations
21// ============================================================================
22
23// ----------------------------------------------------------------------------
24// headers
25// ----------------------------------------------------------------------------
c801d85f 26
12bdd77c 27#if wxUSE_PRINTING_ARCHITECTURE && wxUSE_POSTSCRIPT && (!defined(__WXMSW__) || wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW)
ce4169a4 28
c801d85f 29#ifndef WX_PRECOMP
8826f46f
VZ
30 #include "wx/utils.h"
31 #include "wx/dc.h"
32 #include "wx/app.h"
33 #include "wx/msgdlg.h"
8fa2e6a2
KB
34 #include "wx/intl.h"
35 #include "wx/progdlg.h"
ca65c044 36 #include "wx/log.h"
6d50343d 37 #include "wx/dcprint.h"
c801d85f
KB
38#endif
39
40#include "wx/generic/printps.h"
c801d85f
KB
41#include "wx/printdlg.h"
42#include "wx/generic/prntdlgg.h"
2179d579 43#include "wx/generic/progdlgg.h"
7bcb11d3 44#include "wx/paper.h"
c801d85f
KB
45
46#include <stdlib.h>
47
8826f46f
VZ
48// ----------------------------------------------------------------------------
49// wxWin macros
50// ----------------------------------------------------------------------------
51
8826f46f
VZ
52 IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter, wxPrinterBase)
53 IMPLEMENT_CLASS(wxPostScriptPrintPreview, wxPrintPreviewBase)
ca65c044 54
8826f46f
VZ
55// ============================================================================
56// implementation
57// ============================================================================
7bcb11d3 58
8826f46f
VZ
59// ----------------------------------------------------------------------------
60// Printer
61// ----------------------------------------------------------------------------
62
63wxPostScriptPrinter::wxPostScriptPrinter(wxPrintDialogData *data)
64 : wxPrinterBase(data)
c801d85f
KB
65{
66}
67
8826f46f 68wxPostScriptPrinter::~wxPostScriptPrinter()
c801d85f
KB
69{
70}
71
72bool wxPostScriptPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
73{
ca65c044 74 sm_abortIt = false;
7bcb11d3 75 sm_abortWindow = (wxWindow *) NULL;
8826f46f 76
7bcb11d3 77 if (!printout)
f6bcfd97
BP
78 {
79 sm_lastError = wxPRINTER_ERROR;
ca65c044 80 return false;
f6bcfd97 81 }
8826f46f 82
ca65c044 83 printout->SetIsPreview(false);
1044a386 84
d2b354f9
JS
85 if (m_printDialogData.GetMinPage() < 1)
86 m_printDialogData.SetMinPage(1);
87 if (m_printDialogData.GetMaxPage() < 1)
88 m_printDialogData.SetMaxPage(9999);
8fa2e6a2 89
8826f46f 90 // Create a suitable device context
999836aa 91 wxDC *dc;
7bcb11d3 92 if (prompt)
c801d85f 93 {
7bcb11d3
JS
94 dc = PrintDialog(parent);
95 if (!dc)
ca65c044 96 return false;
c801d85f 97 }
7bcb11d3
JS
98 else
99 {
f6bcfd97 100 dc = new wxPostScriptDC(GetPrintDialogData().GetPrintData());
7bcb11d3 101 }
8826f46f 102
7bcb11d3
JS
103 // May have pressed cancel.
104 if (!dc || !dc->Ok())
105 {
106 if (dc) delete dc;
f6bcfd97 107 sm_lastError = wxPRINTER_ERROR;
ca65c044 108 return false;
7bcb11d3 109 }
8826f46f 110
904a68b6
RL
111 wxSize ScreenPixels = wxGetDisplaySize();
112 wxSize ScreenMM = wxGetDisplaySizeMM();
8826f46f 113
7a5e6267
JS
114 printout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()),
115 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) );
904a68b6
RL
116 printout->SetPPIPrinter( wxPostScriptDC::GetResolution(),
117 wxPostScriptDC::GetResolution() );
8826f46f
VZ
118
119 // Set printout parameters
7bcb11d3 120 printout->SetDC(dc);
8826f46f 121
7bcb11d3
JS
122 int w, h;
123 dc->GetSize(&w, &h);
124 printout->SetPageSizePixels((int)w, (int)h);
f415cab9
JS
125 printout->SetPaperRectPixels(wxRect(0, 0, w, h));
126 int mw, mh;
127 dc->GetSizeMM(&mw, &mh);
128 printout->SetPageSizeMM((int)mw, (int)mh);
8826f46f 129
7bcb11d3
JS
130 // Create an abort window
131 wxBeginBusyCursor();
8826f46f 132
1044a386
JS
133 printout->OnPreparePrinting();
134
d2b354f9
JS
135 // Get some parameters from the printout, if defined
136 int fromPage, toPage;
137 int minPage, maxPage;
138 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
139
140 if (maxPage == 0)
141 {
142 sm_lastError = wxPRINTER_ERROR;
143 wxEndBusyCursor();
ca65c044 144 return false;
d2b354f9
JS
145 }
146
147 // Only set min and max, because from and to have been
148 // set by the user
149 m_printDialogData.SetMinPage(minPage);
150 m_printDialogData.SetMaxPage(maxPage);
398c701f 151
01b5396f
RR
152 if (m_printDialogData.GetFromPage() < minPage)
153 m_printDialogData.SetFromPage( minPage );
154 if (m_printDialogData.GetToPage() > maxPage)
155 m_printDialogData.SetToPage( maxPage );
398c701f 156
67df9783 157 int
e0eeb9b3 158 pagesPerCopy = m_printDialogData.GetToPage()-m_printDialogData.GetFromPage()+1,
67df9783
KB
159 totalPages = pagesPerCopy * m_printDialogData.GetNoCopies(),
160 printedPages = 0;
8fa2e6a2
KB
161 // Open the progress bar dialog
162 wxProgressDialog *progressDialog = new wxProgressDialog (
163 printout->GetTitle(),
164 _("Printing..."),
67df9783 165 totalPages,
ffdaed2f
KB
166 parent,
167 wxPD_CAN_ABORT|wxPD_AUTO_HIDE|wxPD_APP_MODAL);
2179d579 168
7bcb11d3 169 printout->OnBeginPrinting();
8826f46f 170
f6bcfd97
BP
171 sm_lastError = wxPRINTER_NO_ERROR;
172
ca65c044 173 bool keepGoing = true;
8826f46f 174
7bcb11d3
JS
175 int copyCount;
176 for (copyCount = 1; copyCount <= m_printDialogData.GetNoCopies(); copyCount ++)
177 {
178 if (!printout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
179 {
180 wxEndBusyCursor();
f6bcfd97
BP
181 wxLogError(_("Could not start printing."));
182 sm_lastError = wxPRINTER_ERROR;
7bcb11d3
JS
183 break;
184 }
185 if (sm_abortIt)
f6bcfd97
BP
186 {
187 sm_lastError = wxPRINTER_CANCELLED;
7bcb11d3 188 break;
f6bcfd97 189 }
8826f46f 190
7bcb11d3
JS
191 int pn;
192 for (pn = m_printDialogData.GetFromPage(); keepGoing && (pn <= m_printDialogData.GetToPage()) && printout->HasPage(pn);
193 pn++)
194 {
195 if (sm_abortIt)
196 {
ca65c044 197 keepGoing = false;
f6bcfd97 198 sm_lastError = wxPRINTER_CANCELLED;
7bcb11d3
JS
199 break;
200 }
201 else
202 {
8fa2e6a2 203 wxString msg;
67df9783
KB
204 msg.Printf(_("Printing page %d..."), printedPages+1);
205 if(progressDialog->Update(printedPages++, msg))
8fa2e6a2
KB
206 {
207 dc->StartPage();
208 printout->OnPrintPage(pn);
209 dc->EndPage();
210 }
211 else
212 {
ca65c044 213 sm_abortIt = true;
f6bcfd97 214 sm_lastError = wxPRINTER_CANCELLED;
ca65c044 215 keepGoing = false;
8fa2e6a2 216 }
7bcb11d3 217 }
ca65c044 218 wxYield();
7bcb11d3
JS
219 }
220 printout->OnEndDocument();
221 }
8826f46f 222
7bcb11d3 223 printout->OnEndPrinting();
67df9783 224 delete progressDialog;
8826f46f 225
7bcb11d3 226 wxEndBusyCursor();
8826f46f 227
7bcb11d3 228 delete dc;
8826f46f 229
f6bcfd97 230 return (sm_lastError == wxPRINTER_NO_ERROR);
c801d85f
KB
231}
232
7bcb11d3 233wxDC* wxPostScriptPrinter::PrintDialog(wxWindow *parent)
c801d85f 234{
7bcb11d3 235 wxDC* dc = (wxDC*) NULL;
398c701f 236
01b5396f
RR
237 wxGenericPrintDialog dialog( parent, &m_printDialogData );
238 if (dialog.ShowModal() == wxID_OK)
7bcb11d3 239 {
01b5396f
RR
240 dc = dialog.GetPrintDC();
241 m_printDialogData = dialog.GetPrintDialogData();
398c701f 242
f6bcfd97
BP
243 if (dc == NULL)
244 sm_lastError = wxPRINTER_ERROR;
245 else
246 sm_lastError = wxPRINTER_NO_ERROR;
7bcb11d3 247 }
f6bcfd97
BP
248 else
249 sm_lastError = wxPRINTER_CANCELLED;
250
7bcb11d3 251 return dc;
c801d85f
KB
252}
253
4e4528f6 254bool wxPostScriptPrinter::Setup(wxWindow *WXUNUSED(parent))
c801d85f 255{
04a014a5 256#if 0
7bcb11d3 257 wxGenericPrintDialog* dialog = new wxGenericPrintDialog(parent, & m_printDialogData);
ca65c044 258 dialog->GetPrintDialogData().SetSetupDialog(true);
7bcb11d3
JS
259
260 int ret = dialog->ShowModal();
261
262 if (ret == wxID_OK)
263 {
264 m_printDialogData = dialog->GetPrintDialogData();
265 }
266
267 dialog->Destroy();
398c701f 268
7bcb11d3 269 return (ret == wxID_OK);
04a014a5
RR
270#endif
271
4e4528f6 272 return false;
c801d85f
KB
273}
274
8826f46f
VZ
275// ----------------------------------------------------------------------------
276// Print preview
277// ----------------------------------------------------------------------------
c801d85f 278
8826f46f
VZ
279void wxPostScriptPrintPreview::Init(wxPrintout * WXUNUSED(printout),
280 wxPrintout * WXUNUSED(printoutForPrinting))
c801d85f 281{
7bcb11d3
JS
282 // Have to call it here since base constructor can't call it
283 DetermineScaling();
c801d85f
KB
284}
285
8826f46f
VZ
286wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
287 wxPrintout *printoutForPrinting,
288 wxPrintDialogData *data)
289 : wxPrintPreviewBase(printout, printoutForPrinting, data)
290{
291 Init(printout, printoutForPrinting);
292}
293
294wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
295 wxPrintout *printoutForPrinting,
296 wxPrintData *data)
297 : wxPrintPreviewBase(printout, printoutForPrinting, data)
298{
299 Init(printout, printoutForPrinting);
300}
301
302wxPostScriptPrintPreview::~wxPostScriptPrintPreview()
c801d85f
KB
303{
304}
305
306bool wxPostScriptPrintPreview::Print(bool interactive)
307{
7bcb11d3 308 if (!m_printPrintout)
ca65c044 309 return false;
398c701f
JS
310
311 // Assume that on Unix, the preview may use the PostScript
312 // (generic) version, but printing using the native system is required.
313 // TODO: make a generic print preview class from which wxPostScriptPrintPreview
314 // is derived.
315#ifdef __UNIX__
316 wxPrinter printer(& m_printDialogData);
317#else
7bcb11d3 318 wxPostScriptPrinter printer(& m_printDialogData);
398c701f 319#endif
7bcb11d3 320 return printer.Print(m_previewFrame, m_printPrintout, interactive);
c801d85f
KB
321}
322
8826f46f 323void wxPostScriptPrintPreview::DetermineScaling()
c801d85f 324{
7bcb11d3
JS
325 wxPaperSize paperType = m_printDialogData.GetPrintData().GetPaperId();
326 if (paperType == wxPAPER_NONE)
327 paperType = wxPAPER_NONE;
8826f46f 328
c801d85f
KB
329 wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
330 if (!paper)
7bcb11d3
JS
331 paper = wxThePrintPaperDatabase->FindPaperType(wxPAPER_A4);
332
c801d85f
KB
333 if (paper)
334 {
904a68b6
RL
335 wxSize ScreenPixels = wxGetDisplaySize();
336 wxSize ScreenMM = wxGetDisplaySizeMM();
337
7a5e6267
JS
338 m_previewPrintout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()),
339 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) );
ca65c044 340 m_previewPrintout->SetPPIPrinter(wxPostScriptDC::GetResolution(), wxPostScriptDC::GetResolution());
8826f46f 341
7bcb11d3 342 wxSize sizeDevUnits(paper->GetSizeDeviceUnits());
b64de916
VS
343 sizeDevUnits.x = (wxCoord)((float)sizeDevUnits.x * wxPostScriptDC::GetResolution() / 72.0);
344 sizeDevUnits.y = (wxCoord)((float)sizeDevUnits.y * wxPostScriptDC::GetResolution() / 72.0);
7bcb11d3
JS
345 wxSize sizeTenthsMM(paper->GetSize());
346 wxSize sizeMM(sizeTenthsMM.x / 10, sizeTenthsMM.y / 10);
347
348 // If in landscape mode, we need to swap the width and height.
349 if ( m_printDialogData.GetPrintData().GetOrientation() == wxLANDSCAPE )
350 {
351 m_pageWidth = sizeDevUnits.y;
352 m_pageHeight = sizeDevUnits.x;
353 m_previewPrintout->SetPageSizeMM(sizeMM.y, sizeMM.x);
7bcb11d3
JS
354 }
355 else
356 {
357 m_pageWidth = sizeDevUnits.x;
358 m_pageHeight = sizeDevUnits.y;
359 m_previewPrintout->SetPageSizeMM(sizeMM.x, sizeMM.y);
7bcb11d3 360 }
f415cab9
JS
361 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
362 m_previewPrintout->SetPaperRectPixels(wxRect(0, 0, m_pageWidth, m_pageHeight));
8826f46f 363
7bcb11d3 364 // At 100%, the page should look about page-size on the screen.
f415cab9
JS
365 m_previewScaleX = (float)0.8 * 72.0 / (float)wxPostScriptDC::GetResolution();
366 m_previewScaleY = m_previewScaleX;
c801d85f
KB
367 }
368}
369
ce4169a4 370#endif