fixed wrong range for print progress dialog
[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 and Markus Holzem
9 // Licence: wxWindows license
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 #ifndef WX_PRECOMP
34 #include "wx/utils.h"
35 #include "wx/dc.h"
36 #include "wx/app.h"
37 #include "wx/msgdlg.h"
38 #include "wx/intl.h"
39 #include "wx/progdlg.h"
40 #endif
41
42 #include "wx/generic/printps.h"
43 #include "wx/dcprint.h"
44 #include "wx/printdlg.h"
45 #include "wx/generic/prntdlgg.h"
46 #include "wx/paper.h"
47
48 #include <stdlib.h>
49
50 // ----------------------------------------------------------------------------
51 // wxWin macros
52 // ----------------------------------------------------------------------------
53
54 #if !USE_SHARED_LIBRARY
55 IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter, wxPrinterBase)
56 IMPLEMENT_CLASS(wxPostScriptPrintPreview, wxPrintPreviewBase)
57 #endif
58
59 // ============================================================================
60 // implementation
61 // ============================================================================
62
63 // ----------------------------------------------------------------------------
64 // Printer
65 // ----------------------------------------------------------------------------
66
67 wxPostScriptPrinter::wxPostScriptPrinter(wxPrintDialogData *data)
68 : wxPrinterBase(data)
69 {
70 }
71
72 wxPostScriptPrinter::~wxPostScriptPrinter()
73 {
74 }
75
76 bool wxPostScriptPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
77 {
78 sm_abortIt = FALSE;
79 sm_abortWindow = (wxWindow *) NULL;
80
81 if (!printout)
82 return FALSE;
83
84 printout->SetIsPreview(FALSE);
85 printout->OnPreparePrinting();
86
87 // Get some parameters from the printout, if defined
88 int fromPage, toPage;
89 int minPage, maxPage;
90 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
91
92 if (maxPage == 0)
93 return FALSE;
94
95 m_printDialogData.SetMinPage(minPage);
96 m_printDialogData.SetMaxPage(maxPage);
97 if (fromPage != 0)
98 m_printDialogData.SetFromPage(fromPage);
99 if (toPage != 0)
100 m_printDialogData.SetToPage(toPage);
101
102 if (minPage != 0)
103 {
104 m_printDialogData.EnablePageNumbers(TRUE);
105 if (m_printDialogData.GetFromPage() < m_printDialogData.GetMinPage())
106 m_printDialogData.SetFromPage(m_printDialogData.GetMinPage());
107 else if (m_printDialogData.GetFromPage() > m_printDialogData.GetMaxPage())
108 m_printDialogData.SetFromPage(m_printDialogData.GetMaxPage());
109 if (m_printDialogData.GetToPage() > m_printDialogData.GetMaxPage())
110 m_printDialogData.SetToPage(m_printDialogData.GetMaxPage());
111 else if (m_printDialogData.GetToPage() < m_printDialogData.GetMinPage())
112 m_printDialogData.SetToPage(m_printDialogData.GetMinPage());
113 }
114 else
115 m_printDialogData.EnablePageNumbers(FALSE);
116
117
118 // Create a suitable device context
119 wxDC *dc = (wxDC *) NULL;
120 if (prompt)
121 {
122 dc = PrintDialog(parent);
123 if (!dc)
124 return FALSE;
125 }
126 else
127 {
128 dc = new wxPostScriptDC(wxThePrintSetupData->GetPrinterFile(), FALSE, (wxWindow *) NULL);
129 }
130
131 // May have pressed cancel.
132 if (!dc || !dc->Ok())
133 {
134 if (dc) delete dc;
135 return FALSE;
136 }
137
138 int logPPIScreenX = 0;
139 int logPPIScreenY = 0;
140 int logPPIPrinterX = 0;
141 int logPPIPrinterY = 0;
142
143 logPPIScreenX = 100;
144 logPPIScreenY = 100;
145
146 /*
147 // Correct values for X/PostScript?
148 logPPIPrinterX = 100;
149 logPPIPrinterY = 100;
150 */
151
152 logPPIPrinterX = 72;
153 logPPIPrinterY = 72;
154
155 printout->SetPPIScreen(logPPIScreenX, logPPIScreenY);
156 printout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);
157
158 // Set printout parameters
159 printout->SetDC(dc);
160
161 int w, h;
162 dc->GetSize(&w, &h);
163 printout->SetPageSizePixels((int)w, (int)h);
164 dc->GetSizeMM(&w, &h);
165 printout->SetPageSizeMM((int)w, (int)h);
166
167 // Create an abort window
168 wxBeginBusyCursor();
169
170 // Open the progress bar dialog
171 wxProgressDialog *progressDialog = new wxProgressDialog (
172 printout->GetTitle(),
173 _("Printing..."),
174 maxPage-minPage+1,
175 parent,
176 /* disable parent only */ true,
177 /* show abort button */ true);
178
179 printout->OnBeginPrinting();
180
181 bool keepGoing = TRUE;
182
183 int copyCount;
184 for (copyCount = 1; copyCount <= m_printDialogData.GetNoCopies(); copyCount ++)
185 {
186 if (!printout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
187 {
188 wxEndBusyCursor();
189 wxMessageBox(_("Could not start printing."), _("Print Error"), wxOK, parent);
190 break;
191 }
192 if (sm_abortIt)
193 break;
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 break;
203 }
204 else
205 {
206 wxString msg;
207 msg.Printf(_("Printing page %d..."), pn);
208 if(progressDialog->Update(pn-minPage, msg))
209 {
210 dc->StartPage();
211 printout->OnPrintPage(pn);
212 dc->EndPage();
213 }
214 else
215 {
216 sm_abortIt = true;
217 keepGoing = false; //FIXME: do we need both?
218 }
219 }
220 }
221 delete progressDialog;
222 printout->OnEndDocument();
223 }
224
225 printout->OnEndPrinting();
226
227 wxEndBusyCursor();
228
229 delete dc;
230
231 return TRUE;
232 }
233
234 wxDC* wxPostScriptPrinter::PrintDialog(wxWindow *parent)
235 {
236 wxDC* dc = (wxDC*) NULL;
237 wxGenericPrintDialog* dialog = new wxGenericPrintDialog(parent, & m_printDialogData);
238 int ret = dialog->ShowModal() ;
239 if (ret == wxID_OK)
240 {
241 dc = dialog->GetPrintDC();
242 m_printDialogData = dialog->GetPrintDialogData();
243 }
244 dialog->Destroy();
245
246 return dc;
247 }
248
249 bool wxPostScriptPrinter::Setup(wxWindow *parent)
250 {
251 wxGenericPrintDialog* dialog = new wxGenericPrintDialog(parent, & m_printDialogData);
252 dialog->GetPrintDialogData().SetSetupDialog(TRUE);
253
254 int ret = dialog->ShowModal();
255
256 if (ret == wxID_OK)
257 {
258 m_printDialogData = dialog->GetPrintDialogData();
259 }
260
261 dialog->Destroy();
262
263 return (ret == wxID_OK);
264 }
265
266 // ----------------------------------------------------------------------------
267 // Print preview
268 // ----------------------------------------------------------------------------
269
270 void wxPostScriptPrintPreview::Init(wxPrintout * WXUNUSED(printout),
271 wxPrintout * WXUNUSED(printoutForPrinting))
272 {
273 // Have to call it here since base constructor can't call it
274 DetermineScaling();
275 }
276
277 wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
278 wxPrintout *printoutForPrinting,
279 wxPrintDialogData *data)
280 : wxPrintPreviewBase(printout, printoutForPrinting, data)
281 {
282 Init(printout, printoutForPrinting);
283 }
284
285 wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
286 wxPrintout *printoutForPrinting,
287 wxPrintData *data)
288 : wxPrintPreviewBase(printout, printoutForPrinting, data)
289 {
290 Init(printout, printoutForPrinting);
291 }
292
293 wxPostScriptPrintPreview::~wxPostScriptPrintPreview()
294 {
295 }
296
297 bool wxPostScriptPrintPreview::Print(bool interactive)
298 {
299 if (!m_printPrintout)
300 return FALSE;
301 wxPostScriptPrinter printer(& m_printDialogData);
302 return printer.Print(m_previewFrame, m_printPrintout, interactive);
303 }
304
305 void wxPostScriptPrintPreview::DetermineScaling()
306 {
307 wxPaperSize paperType = m_printDialogData.GetPrintData().GetPaperId();
308 if (paperType == wxPAPER_NONE)
309 paperType = wxPAPER_NONE;
310
311 wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
312 if (!paper)
313 paper = wxThePrintPaperDatabase->FindPaperType(wxPAPER_A4);
314
315 if (paper)
316 {
317 m_previewPrintout->SetPPIScreen(100, 100);
318 // m_previewPrintout->SetPPIPrinter(100, 100);
319 m_previewPrintout->SetPPIPrinter(72, 72);
320
321 wxSize sizeDevUnits(paper->GetSizeDeviceUnits());
322 wxSize sizeTenthsMM(paper->GetSize());
323 wxSize sizeMM(sizeTenthsMM.x / 10, sizeTenthsMM.y / 10);
324
325 // If in landscape mode, we need to swap the width and height.
326 if ( m_printDialogData.GetPrintData().GetOrientation() == wxLANDSCAPE )
327 {
328 m_pageWidth = sizeDevUnits.y;
329 m_pageHeight = sizeDevUnits.x;
330 m_previewPrintout->SetPageSizeMM(sizeMM.y, sizeMM.x);
331 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
332 }
333 else
334 {
335 m_pageWidth = sizeDevUnits.x;
336 m_pageHeight = sizeDevUnits.y;
337 m_previewPrintout->SetPageSizeMM(sizeMM.x, sizeMM.y);
338 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
339 }
340
341 // At 100%, the page should look about page-size on the screen.
342 m_previewScale = (float)0.8;
343 }
344 }
345