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