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