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