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 
IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter,wxPrinterBase)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 
~wxPostScriptPrinter()67 wxPostScriptPrinter::~wxPostScriptPrinter()
68 {
69 }
70 
Print(wxWindow * parent,wxPrintout * printout,bool prompt)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 
PrintDialog(wxWindow * parent)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 
Setup(wxWindow * WXUNUSED (parent))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 
Init(wxPrintout * WXUNUSED (printout),wxPrintout * WXUNUSED (printoutForPrinting))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 
wxPostScriptPrintPreview(wxPrintout * printout,wxPrintout * printoutForPrinting,wxPrintDialogData * data)283 wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
284                                                    wxPrintout *printoutForPrinting,
285                                                    wxPrintDialogData *data)
286                         : wxPrintPreviewBase(printout, printoutForPrinting, data)
287 {
288     Init(printout, printoutForPrinting);
289 }
290 
wxPostScriptPrintPreview(wxPrintout * printout,wxPrintout * printoutForPrinting,wxPrintData * data)291 wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout,
292                                                    wxPrintout *printoutForPrinting,
293                                                    wxPrintData *data)
294                         : wxPrintPreviewBase(printout, printoutForPrinting, data)
295 {
296     Init(printout, printoutForPrinting);
297 }
298 
~wxPostScriptPrintPreview()299 wxPostScriptPrintPreview::~wxPostScriptPrintPreview()
300 {
301 }
302 
Print(bool interactive)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 
DetermineScaling()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
372