]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/dcprint.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / osx / carbon / dcprint.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
524c47aa 2// Name: src/osx/carbon/dcprint.cpp
489468fe
SC
3// Purpose: wxPrinterDC class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
489468fe
SC
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#if wxUSE_PRINTING_ARCHITECTURE
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
20#include "wx/dcprint.h"
21
22#ifndef WX_PRECOMP
23 #include "wx/msgdlg.h"
24 #include "wx/math.h"
25#endif
26
524c47aa 27#include "wx/osx/private.h"
1f0c8f31 28#include "wx/osx/private/print.h"
e158da36 29#include "wx/osx/dcprint.h"
489468fe
SC
30#include "wx/graphics.h"
31
32IMPLEMENT_ABSTRACT_CLASS(wxPrinterDCImpl, wxGCDCImpl)
33
34class wxNativePrinterDC
35{
36public :
37 wxNativePrinterDC() {}
38 virtual ~wxNativePrinterDC() {}
39 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) = 0;
40 virtual void EndDoc( wxPrinterDC* dc ) = 0;
41 virtual void StartPage( wxPrinterDC* dc ) = 0;
42 virtual void EndPage( wxPrinterDC* dc ) = 0;
43 virtual void GetSize( int *w , int *h) const = 0 ;
44 virtual wxSize GetPPI() const = 0 ;
45
46 // returns 0 in case of no Error, otherwise platform specific error codes
47 virtual wxUint32 GetStatus() const = 0 ;
a1b806b9 48 bool IsOk() { return GetStatus() == 0 ; }
489468fe
SC
49
50 static wxNativePrinterDC* Create(wxPrintData* data) ;
51} ;
52
53class wxMacCarbonPrinterDC : public wxNativePrinterDC
54{
55public :
56 wxMacCarbonPrinterDC( wxPrintData* data ) ;
57 virtual ~wxMacCarbonPrinterDC() ;
58 virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ;
59 virtual void EndDoc( wxPrinterDC* dc ) ;
60 virtual void StartPage( wxPrinterDC* dc ) ;
61 virtual void EndPage( wxPrinterDC* dc ) ;
62 virtual wxUint32 GetStatus() const { return m_err ; }
63 virtual void GetSize( int *w , int *h) const ;
64 virtual wxSize GetPPI() const ;
65private :
66 wxCoord m_maxX ;
67 wxCoord m_maxY ;
68 wxSize m_ppi ;
69 OSStatus m_err ;
70} ;
71
72wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
73{
74 m_err = noErr ;
c347101b 75 wxOSXPrintData *native = (wxOSXPrintData*) data->GetNativeData() ;
ce00f59b 76
489468fe 77 PMRect rPage;
c347101b 78 m_err = PMGetAdjustedPageRect(native->GetPageFormat(), &rPage);
489468fe
SC
79 if ( m_err != noErr )
80 return;
ce00f59b 81
489468fe
SC
82 m_maxX = wxCoord(rPage.right - rPage.left) ;
83 m_maxY = wxCoord(rPage.bottom - rPage.top);
ce00f59b 84
489468fe 85 PMResolution res;
884dad83
SC
86 PMPrinter printer;
87 m_err = PMSessionGetCurrentPrinter(native->GetPrintSession(), &printer);
88 if ( m_err == noErr )
ce00f59b 89 {
4f134f0c
SC
90 m_err = PMPrinterGetOutputResolution( printer, native->GetPrintSettings(), &res) ;
91 if ( m_err == -9589 /* kPMKeyNotFound */ )
489468fe 92 {
4f134f0c
SC
93 m_err = noErr ;
94 res.hRes = res.vRes = 300;
884dad83 95 }
489468fe 96 }
dcc5dc59
SC
97 else
98 {
99 res.hRes = res.vRes = 300;
100 }
ce00f59b 101
884dad83
SC
102 m_maxX = wxCoord((double)m_maxX * res.hRes / 72.0);
103 m_maxY = wxCoord((double)m_maxY * res.vRes / 72.0);
6d52ca53 104
489468fe
SC
105 m_ppi = wxSize(int(res.hRes), int(res.vRes));
106}
107
108wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
109{
110}
111
112wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
113{
114 return new wxMacCarbonPrinterDC(data) ;
115}
116
e9e767f1 117bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& message )
489468fe
SC
118{
119 if ( m_err )
120 return false ;
121
122 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 123 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 124
884dad83 125 PMPrintSettingsSetJobName(native->GetPrintSettings(), wxCFStringRef(message));
e9e767f1 126
c347101b
SC
127 m_err = PMSessionBeginCGDocumentNoDialog(native->GetPrintSession(),
128 native->GetPrintSettings(),
129 native->GetPageFormat());
489468fe
SC
130 if ( m_err != noErr )
131 return false;
132
133 PMRect rPage;
c347101b 134 m_err = PMGetAdjustedPageRect(native->GetPageFormat(), &rPage);
489468fe
SC
135 if ( m_err != noErr )
136 return false ;
137
138 m_maxX = wxCoord(rPage.right - rPage.left) ;
139 m_maxY = wxCoord(rPage.bottom - rPage.top);
140
141 PMResolution res;
884dad83
SC
142 PMPrinter printer;
143
144 m_err = PMSessionGetCurrentPrinter(native->GetPrintSession(), &printer);
145 if (m_err == noErr)
489468fe 146 {
4f134f0c
SC
147 m_err = PMPrinterGetOutputResolution( printer, native->GetPrintSettings(), &res) ;
148 if ( m_err == -9589 /* kPMKeyNotFound */ )
489468fe 149 {
4f134f0c
SC
150 m_err = noErr ;
151 res.hRes = res.vRes = 300;
884dad83 152 }
489468fe 153 }
4f134f0c 154
884dad83
SC
155 m_maxX = wxCoord((double)m_maxX * res.hRes / 72.0);
156 m_maxY = wxCoord((double)m_maxY * res.vRes / 72.0);
489468fe
SC
157
158 m_ppi = wxSize(int(res.hRes), int(res.vRes));
159 return true ;
160}
161
162void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
163{
164 if ( m_err )
165 return ;
166
167 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 168 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 169
c347101b 170 m_err = PMSessionEndDocumentNoDialog(native->GetPrintSession());
489468fe
SC
171}
172
173void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
174{
175 if ( m_err )
176 return ;
177
178 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 179 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 180
c347101b
SC
181 m_err = PMSessionBeginPageNoDialog(native->GetPrintSession(),
182 native->GetPageFormat(),
884dad83 183 NULL);
489468fe
SC
184
185 CGContextRef pageContext;
186
187 if ( m_err == noErr )
188 {
c347101b 189 m_err = PMSessionGetCGGraphicsContext(native->GetPrintSession(),
489468fe
SC
190 &pageContext );
191 }
192
193 if ( m_err != noErr )
194 {
c347101b
SC
195 PMSessionEndPageNoDialog(native->GetPrintSession());
196 PMSessionEndDocumentNoDialog(native->GetPrintSession());
489468fe
SC
197 }
198 else
199 {
884dad83
SC
200 PMRect paperRect ;
201 m_err = PMGetAdjustedPaperRect( native->GetPageFormat() , &paperRect ) ;
202 // make sure (0,0) is at the upper left of the printable area (wx conventions)
203 // Core Graphics initially has the lower left of the paper as 0,0
489468fe 204 if ( !m_err )
489468fe 205 CGContextTranslateCTM( pageContext , (CGFloat) -paperRect.left , (CGFloat) paperRect.bottom ) ;
ce00f59b 206
489468fe
SC
207 // since this is a non-critical error, we set the flag back
208 m_err = noErr ;
884dad83
SC
209
210 // Leopard deprecated PMSetResolution() which will not be available in 64 bit mode, so we avoid using it.
211 // To set the proper drawing resolution, the docs suggest the use of CGContextScaleCTM(), so here we go; as a
212 // consequence though, PMGetAdjustedPaperRect() and PMGetAdjustedPageRect() return unscaled rects, so we
213 // have to manually scale them later.
214 CGContextScaleCTM( pageContext, 72.0 / (double)m_ppi.x, -72.0 / (double)m_ppi.y);
215
216 impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( pageContext ) );
489468fe 217 }
489468fe
SC
218}
219
220void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
221{
222 if ( m_err )
223 return ;
224
225 wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();
c347101b 226 wxOSXPrintData *native = (wxOSXPrintData*) impl->GetPrintData().GetNativeData() ;
489468fe 227
c347101b 228 m_err = PMSessionEndPageNoDialog(native->GetPrintSession());
489468fe
SC
229 if ( m_err != noErr )
230 {
c347101b 231 PMSessionEndDocumentNoDialog(native->GetPrintSession());
489468fe
SC
232 }
233 // the cg context we got when starting the page isn't valid anymore, so replace it
234 impl->SetGraphicsContext( wxGraphicsContext::Create() );
235}
236
237void wxMacCarbonPrinterDC::GetSize( int *w , int *h) const
238{
239 if ( w )
240 *w = m_maxX ;
241 if ( h )
242 *h = m_maxY ;
243}
244
6d52ca53 245wxSize wxMacCarbonPrinterDC::GetPPI() const
489468fe
SC
246{
247 return m_ppi ;
248};
249
250//
251//
252//
253
254wxPrinterDCImpl::wxPrinterDCImpl( wxPrinterDC *owner, const wxPrintData& printdata )
255 : wxGCDCImpl( owner )
256{
257 m_ok = false ;
258 m_printData = printdata ;
259 m_printData.ConvertToNative() ;
260 m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
261 if ( m_nativePrinterDC )
262 {
a1b806b9 263 m_ok = m_nativePrinterDC->IsOk() ;
489468fe
SC
264 if ( !m_ok )
265 {
266 wxString message ;
267 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
268 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
269 dialog.ShowModal();
270 }
271 else
272 {
273 wxSize sz = GetPPI();
274 m_mm_to_pix_x = mm2inches * sz.x;
6d52ca53 275 m_mm_to_pix_y = mm2inches * sz.y;
489468fe
SC
276 }
277 // we need at least a measuring context because people start measuring before a page
278 // gets printed at all
279 SetGraphicsContext( wxGraphicsContext::Create() );
280 }
281}
282
283wxSize wxPrinterDCImpl::GetPPI() const
284{
285 return m_nativePrinterDC->GetPPI() ;
286}
287
288wxPrinterDCImpl::~wxPrinterDCImpl()
289{
290 delete m_nativePrinterDC ;
291}
292
293bool wxPrinterDCImpl::StartDoc( const wxString& message )
294{
295 wxASSERT_MSG( IsOk() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
296
297 if ( !m_ok )
298 return false ;
299
300 if ( m_nativePrinterDC->StartDoc( (wxPrinterDC*) GetOwner(), message ) )
301 {
302 // in case we have to do additional things when successful
303 }
a1b806b9 304 m_ok = m_nativePrinterDC->IsOk() ;
489468fe
SC
305 if ( !m_ok )
306 {
307 wxString message ;
308 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
309 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
310 dialog.ShowModal();
311 }
312
313 return m_ok ;
314}
315
316void wxPrinterDCImpl::EndDoc(void)
317{
318 if ( !m_ok )
319 return ;
320
321 m_nativePrinterDC->EndDoc( (wxPrinterDC*) GetOwner() ) ;
a1b806b9 322 m_ok = m_nativePrinterDC->IsOk() ;
489468fe
SC
323
324 if ( !m_ok )
325 {
326 wxString message ;
327 message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
328 wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
329 dialog.ShowModal();
330 }
331}
332
6d52ca53 333wxRect wxPrinterDCImpl::GetPaperRect() const
489468fe
SC
334{
335 wxCoord w, h;
336 GetOwner()->GetSize(&w, &h);
337 wxRect pageRect(0, 0, w, h);
c347101b 338 wxOSXPrintData *native = (wxOSXPrintData*) m_printData.GetNativeData() ;
489468fe
SC
339 OSStatus err = noErr ;
340 PMRect rPaper;
c347101b 341 err = PMGetAdjustedPaperRect(native->GetPageFormat(), &rPaper);
489468fe
SC
342 if ( err != noErr )
343 return pageRect;
884dad83
SC
344
345 wxSize ppi = GetOwner()->GetPPI();
346 rPaper.right *= (ppi.x / 72.0);
347 rPaper.bottom *= (ppi.y / 72.0);
348 rPaper.left *= (ppi.x / 72.0);
349 rPaper.top *= (ppi.y / 72.0);
350
489468fe
SC
351 return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top),
352 wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top));
353}
354
355void wxPrinterDCImpl::StartPage()
356{
357 if ( !m_ok )
358 return ;
359
360 m_logicalFunction = wxCOPY;
361 // m_textAlignment = wxALIGN_TOP_LEFT;
362 m_backgroundMode = wxTRANSPARENT;
363
364 m_textForegroundColour = *wxBLACK;
365 m_textBackgroundColour = *wxWHITE;
366 m_pen = *wxBLACK_PEN;
367 m_font = *wxNORMAL_FONT;
368 m_brush = *wxTRANSPARENT_BRUSH;
369 m_backgroundBrush = *wxWHITE_BRUSH;
370
371 m_nativePrinterDC->StartPage( (wxPrinterDC*) GetOwner() ) ;
a1b806b9 372 m_ok = m_nativePrinterDC->IsOk() ;
489468fe
SC
373
374}
375
376void wxPrinterDCImpl::EndPage()
377{
378 if ( !m_ok )
379 return ;
380
381 m_nativePrinterDC->EndPage( (wxPrinterDC*) GetOwner() );
a1b806b9 382 m_ok = m_nativePrinterDC->IsOk() ;
489468fe
SC
383}
384
385void wxPrinterDCImpl::DoGetSize(int *width, int *height) const
386{
9a83f860 387 wxCHECK_RET( m_ok , wxT("GetSize() doesn't work without a valid wxPrinterDC") );
489468fe
SC
388 m_nativePrinterDC->GetSize(width, height ) ;
389}
390
391#endif