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