]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/generic/printps.cpp
Make wxOwnerDrawnComboBox::DoGetBestSize() twice as fast.
[wxWidgets.git] / src / generic / printps.cpp
... / ...
CommitLineData
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
62wxPostScriptPrinter::wxPostScriptPrinter(wxPrintDialogData *data)
63 : wxPrinterBase(data)
64{
65}
66
67wxPostScriptPrinter::~wxPostScriptPrinter()
68{
69}
70
71bool 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
230wxDC* 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
251bool 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
276void 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
283wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
284 wxPrintout *printoutForPrinting,
285 wxPrintDialogData *data)
286 : wxPrintPreviewBase(printout, printoutForPrinting, data)
287{
288 Init(printout, printoutForPrinting);
289}
290
291wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
292 wxPrintout *printoutForPrinting,
293 wxPrintData *data)
294 : wxPrintPreviewBase(printout, printoutForPrinting, data)
295{
296 Init(printout, printoutForPrinting);
297}
298
299wxPostScriptPrintPreview::~wxPostScriptPrintPreview()
300{
301}
302
303bool 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
320void 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