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