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