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