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