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