1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMacPrinter framework
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
25 #include "wx/msgdlg.h"
28 #include "wx/mac/uma.h"
30 #include "wx/mac/printmac.h"
31 #include "wx/mac/private/print.h"
33 #define mm2pt 2.83464566929
34 #define pt2mm 0.352777777778
36 #include "wx/dcprint.h"
37 #include "wx/printdlg.h"
41 IMPLEMENT_DYNAMIC_CLASS(wxMacPrinter
, wxPrinterBase
)
42 IMPLEMENT_CLASS(wxMacPrintPreview
, wxPrintPreviewBase
)
46 wxNativePrintData
* wxNativePrintData::Create()
48 return new wxMacCarbonPrintData() ;
51 wxMacCarbonPrintData::wxMacCarbonPrintData()
53 m_macPageFormat
= kPMNoPageFormat
;
54 m_macPrintSettings
= kPMNoPrintSettings
;
55 m_macPrintSession
= kPMNoReference
;
59 wxMacCarbonPrintData::~wxMacCarbonPrintData()
61 if (m_macPageFormat
!= kPMNoPageFormat
)
63 (void)PMRelease(m_macPageFormat
);
64 m_macPageFormat
= kPMNoPageFormat
;
67 if (m_macPrintSettings
!= kPMNoPrintSettings
)
69 (void)PMRelease(m_macPrintSettings
);
70 m_macPrintSettings
= kPMNoPrintSettings
;
73 if ( m_macPrintSession
!= kPMNoReference
)
75 (void)PMRelease(m_macPrintSession
);
76 m_macPrintSession
= kPMNoReference
;
80 void wxMacCarbonPrintData::ValidateOrCreate()
82 OSStatus err
= noErr
;
83 if ( m_macPrintSession
== kPMNoReference
)
85 err
= PMCreateSession( (PMPrintSession
*) &m_macPrintSession
) ;
87 // Set up a valid PageFormat object.
88 if ( m_macPageFormat
== kPMNoPageFormat
)
90 err
= PMCreatePageFormat((PMPageFormat
*) &m_macPageFormat
);
92 // Note that PMPageFormat is not session-specific, but calling
93 // PMSessionDefaultPageFormat assigns values specific to the printer
94 // associated with the current printing session.
96 ( m_macPageFormat
!= kPMNoPageFormat
))
98 err
= PMSessionDefaultPageFormat((PMPrintSession
) m_macPrintSession
,
99 (PMPageFormat
) m_macPageFormat
);
104 err
= PMSessionValidatePageFormat((PMPrintSession
) m_macPrintSession
,
105 (PMPageFormat
) m_macPageFormat
,
109 // Set up a valid PrintSettings object.
110 if ( m_macPrintSettings
== kPMNoPrintSettings
)
112 err
= PMCreatePrintSettings((PMPrintSettings
*) &m_macPrintSettings
);
114 // Note that PMPrintSettings is not session-specific, but calling
115 // PMSessionDefaultPrintSettings assigns values specific to the printer
116 // associated with the current printing session.
117 if ((err
== noErr
) &&
118 ( m_macPrintSettings
!= kPMNoPrintSettings
))
120 err
= PMSessionDefaultPrintSettings((PMPrintSession
) m_macPrintSession
,
121 (PMPrintSettings
) m_macPrintSettings
);
126 err
= PMSessionValidatePrintSettings((PMPrintSession
) m_macPrintSession
,
127 (PMPrintSettings
) m_macPrintSettings
,
132 void wxMacCarbonPrintData::TransferFrom( wxPrintData
* data
)
135 PMSetCopies( (PMPrintSettings
) m_macPrintSettings
, data
->GetNoCopies() , false ) ;
136 PMSetOrientation( (PMPageFormat
) m_macPageFormat
, ( data
->GetOrientation() == wxLANDSCAPE
) ?
137 kPMLandscape
: kPMPortrait
, false ) ;
138 // collate cannot be set
139 #if 0 // not yet tested
140 if ( m_printerName
.Length() > 0 )
141 PMSessionSetCurrentPrinter( (PMPrintSession
) m_macPrintSession
, wxMacCFStringHolder( m_printerName
, wxFont::GetDefaultEncoding() ) ) ;
144 PMGetColorMode( (PMPrintSettings
) m_macPrintSettings
, &color
) ;
145 if ( data
->GetColour() )
147 if ( color
== kPMBlackAndWhite
)
148 PMSetColorMode( (PMPrintSettings
) m_macPrintSettings
, kPMColor
) ;
151 PMSetColorMode( (PMPrintSettings
) m_macPrintSettings
, kPMBlackAndWhite
) ;
153 // PMDuplexMode not yet accessible via API
154 // PMQualityMode not yet accessible via API
158 void wxMacCarbonPrintData::TransferTo( wxPrintData
* data
)
160 OSStatus err
= noErr
;
163 err
= PMGetCopies( m_macPrintSettings
, &copies
) ;
165 data
->SetNoCopies( copies
) ;
167 PMOrientation orientation
;
168 err
= PMGetOrientation( m_macPageFormat
, &orientation
) ;
171 if ( orientation
== kPMPortrait
|| orientation
== kPMReversePortrait
)
172 data
->SetOrientation( wxPORTRAIT
);
174 data
->SetOrientation( wxLANDSCAPE
);
177 // collate cannot be set
180 wxMacCFStringHolder name
;
182 PMSessionGetCurrentPrinter( m_macPrintSession
,
184 m_printerName
= name
.AsString() ;
189 err
= PMGetColorMode( m_macPrintSettings
, &color
) ;
191 data
->SetColour( !(color
== kPMBlackAndWhite
) ) ;
193 // PMDuplexMode not yet accessible via API
194 // PMQualityMode not yet accessible via API
197 err
= PMGetUnadjustedPaperRect( m_macPageFormat
, &rPaper
);
200 data
->SetPaperSize( wxSize (
201 (int)(( rPaper
.right
- rPaper
.left
) * pt2mm
+ 0.5 ) ,
202 (int)(( rPaper
.bottom
- rPaper
.top
) * pt2mm
+ 0.5 ) ) );
206 void wxMacCarbonPrintData::TransferFrom( wxPageSetupData
*data
)
208 // should we setup the page rect here ?
209 // since MacOS sometimes has two same paper rects with different
210 // page rects we could make it roundtrip safe perhaps
216 void wxMacCarbonPrintData::TransferTo( wxPageSetupData
* data
)
219 OSStatus err
= PMGetUnadjustedPaperRect(m_macPageFormat
, &rPaper
);
223 err
= PMGetUnadjustedPageRect(m_macPageFormat
, &rPage
) ;
226 data
->SetMinMarginTopLeft( wxPoint (
227 (int)(((double) rPage
.left
- rPaper
.left
) * pt2mm
) ,
228 (int)(((double) rPage
.top
- rPaper
.top
) * pt2mm
) ) ) ;
230 data
->SetMinMarginBottomRight( wxPoint (
231 (wxCoord
)(((double) rPaper
.right
- rPage
.right
) * pt2mm
),
232 (wxCoord
)(((double) rPaper
.bottom
- rPage
.bottom
) * pt2mm
)) ) ;
237 void wxMacCarbonPrintData::TransferTo( wxPrintDialogData
* data
)
239 UInt32 minPage
, maxPage
;
240 PMGetPageRange( m_macPrintSettings
, &minPage
, &maxPage
) ;
241 data
->SetMinPage( minPage
) ;
242 data
->SetMaxPage( maxPage
) ;
244 PMGetCopies( m_macPrintSettings
, &copies
) ;
245 data
->SetNoCopies( copies
) ;
247 PMGetFirstPage( m_macPrintSettings
, &from
) ;
248 PMGetLastPage( m_macPrintSettings
, &to
) ;
249 data
->SetFromPage( from
) ;
250 data
->SetToPage( to
) ;
253 void wxMacCarbonPrintData::TransferFrom( wxPrintDialogData
* data
)
255 PMSetPageRange( m_macPrintSettings
, data
->GetMinPage() , data
->GetMaxPage() ) ;
256 PMSetCopies( m_macPrintSettings
, data
->GetNoCopies() , false ) ;
257 PMSetFirstPage( m_macPrintSettings
, data
->GetFromPage() , false ) ;
259 int toPage
= data
->GetToPage();
261 toPage
= data
->GetFromPage();
262 PMSetLastPage( m_macPrintSettings
, toPage
, false ) ;
265 void wxMacCarbonPrintData::CopyFrom( wxNativePrintData
* d
)
267 wxMacCarbonPrintData
*data
= (wxMacCarbonPrintData
*) d
;
268 if ( data
->m_macPrintSession
!= kPMNoReference
)
269 PMRetain( data
->m_macPrintSession
) ;
270 if ( m_macPrintSession
!= kPMNoReference
)
272 PMRelease( m_macPrintSession
) ;
273 m_macPrintSession
= kPMNoReference
;
275 if ( data
->m_macPrintSession
!= kPMNoReference
)
276 m_macPrintSession
= data
->m_macPrintSession
;
278 if ( data
->m_macPrintSettings
!= kPMNoPrintSettings
)
279 PMRetain( data
->m_macPrintSettings
) ;
280 if ( m_macPrintSettings
!= kPMNoPrintSettings
)
282 PMRelease( m_macPrintSettings
) ;
283 m_macPrintSettings
= kPMNoPrintSettings
;
285 if ( data
->m_macPrintSettings
!= kPMNoPrintSettings
)
286 m_macPrintSettings
= data
->m_macPrintSettings
;
288 if ( data
->m_macPageFormat
!= kPMNoPageFormat
)
289 PMRetain( data
->m_macPageFormat
) ;
290 if ( m_macPageFormat
!= kPMNoPageFormat
)
292 PMRelease( m_macPageFormat
) ;
293 m_macPageFormat
= kPMNoPageFormat
;
295 if ( data
->m_macPageFormat
!= kPMNoPageFormat
)
296 m_macPageFormat
= data
->m_macPageFormat
;
299 int wxMacCarbonPrintData::ShowPrintDialog()
301 int result
= wxID_CANCEL
;
308 // Display the Print dialog.
311 err
= PMSessionPrintDialog( m_macPrintSession
,
315 if ((err
== noErr
) && !accepted
)
317 err
= kPMCancel
; // user clicked Cancel button
325 if ((err
!= noErr
) && (err
!= kPMCancel
))
327 message
.Printf( wxT("Print Error %d"), err
) ;
328 wxMessageDialog
dialog( NULL
, message
, wxEmptyString
, wxICON_HAND
| wxOK
) ;
335 int wxMacCarbonPrintData::ShowPageSetupDialog()
337 int result
= wxID_CANCEL
;
343 // Display the Page Setup dialog.
346 err
= PMSessionPageSetupDialog( m_macPrintSession
,
349 if ((err
== noErr
) && !accepted
)
351 err
= kPMCancel
; // user clicked Cancel button
355 // If the user did not cancel, flatten and save the PageFormat object
356 // with our document.
361 if ((err
!= noErr
) && (err
!= kPMCancel
))
363 message
.Printf( wxT("Print Error %d"), err
) ;
364 wxMessageDialog
dialog( NULL
, message
, wxEmptyString
, wxICON_HAND
| wxOK
) ;
373 wxNativePrintData
* wxNativePrintData::Create()
375 return new wxMacClassicPrintData() ;
378 wxMacClassicPrintData::wxMacClassicPrintData()
380 m_macPrintSettings
= NULL
;
384 wxMacClassicPrintData::~wxMacClassicPrintData()
386 wxASSERT( m_macPrintSettings
);
387 DisposeHandle( (Handle
) m_macPrintSettings
) ;
390 void wxMacClassicPrintData::ValidateOrCreate()
392 if ( m_macPrintSettings
== NULL
)
394 m_macPrintSettings
= (THPrint
) NewHandleClear( sizeof( TPrint
) );
395 (**m_macPrintSettings
).iPrVersion
= 0; // something invalid
397 (**m_macPrintSettings
).prInfo
.iHRes
= 72;
398 (**m_macPrintSettings
).prInfo
.iVRes
= 72;
399 Rect r1
= { 0, 0, 8*72 - 2 * 18, 11*72 - 2 * 36 };
400 (**m_macPrintSettings
).prInfo
.rPage
= r1
;// must have its top left & (0,0)
402 Rect r2
= { -18, -36, 8*72 - 18, 11*72 - 36 };
403 (**m_macPrintSettings
).rPaper
= r2
;
404 (**m_macPrintSettings
).prStl
.iPageV
= 11 * 120 ; // 11 inches in 120th of an inch
405 (**m_macPrintSettings
).prStl
.iPageH
= 8 * 120 ; // 8 inches in 120th of an inch
412 void wxMacClassicPrintData::TransferFrom( wxPrintData
* data
)
415 (**m_macPrintSettings
).prJob
.iCopies
= data
->GetNoCopies() ;
416 // on mac the paper rect has a negative top left corner, because the page rect (printable area) is at 0,0
417 // if all printing data is consolidated in on structure we will be able to set additional infos about pages
420 void wxMacClassicPrintData::TransferTo( wxPrintData
* data
)
422 data
->SetNoCopies( (**m_macPrintSettings
).prJob
.iCopies
);
423 data
->SetPaperSize( wxSize(
424 ((double) (**m_macPrintSettings
).rPaper
.right
- (**m_macPrintSettings
).rPaper
.left
) * pt2mm
,
425 ((double) (**m_macPrintSettings
).rPaper
.bottom
- (**m_macPrintSettings
).rPaper
.top
) * pt2mm
) ) ;
428 void wxMacClassicPrintData::TransferFrom( wxPageSetupData
*data
)
432 void wxMacClassicPrintData::TransferTo( wxPageSetupData
* data
)
434 data
->SetMinMarginTopLeft( wxPoint(
435 ((double) (**m_macPrintSettings
).prInfo
.rPage
.left
-(**m_macPrintSettings
).rPaper
.left
) * pt2mm
,
436 ((double) (**m_macPrintSettings
).prInfo
.rPage
.top
-(**m_macPrintSettings
).rPaper
.top
) * pt2mm
) ) ;
437 data
->SetMinMarginBottomRight( wxPoint(
438 ((double) (**m_macPrintSettings
).rPaper
.right
- (**m_macPrintSettings
).prInfo
.rPage
.right
) * pt2mm
,
439 ((double)(**m_macPrintSettings
).rPaper
.bottom
- (**m_macPrintSettings
).prInfo
.rPage
.bottom
) * pt2mm
) ) ;
442 void wxMacClassicPrintData::TransferFrom( wxPrintDialogData
* data
)
444 int toPage
= data
->GetToPage();
446 toPage
= data
->GetFromPage();
447 (**m_macPrintSettings
).prJob
.iFstPage
= data
->GetFromPage() ;
448 (**m_macPrintSettings
).prJob
.iLstPage
= toPage
;
451 void wxMacClassicPrintData::TransferTo( wxPrintDialogData
* data
)
453 data
->SetFromPage( (**m_macPrintSettings
).prJob
.iFstPage
) ;
454 data
->SetToPage( (**m_macPrintSettings
).prJob
.iLstPage
) ;
457 void wxMacClassicPrintData::CopyFrom( wxNativePrintData
* data
)
459 DisposeHandle( (Handle
) m_macPrintSettings
) ;
460 m_macPrintSettings
= ((wxMacClassicPrintData
*)data
)->m_macPrintSettings
;
461 HandToHand( (Handle
*) &m_macPrintSettings
);
464 int wxMacClassicPrintData::ShowPrintDialog()
466 int result
= wxID_CANCEL
;
470 err
= ::UMAPrOpen() ;
473 if ( ::PrJobDialog( m_macPrintSettings
) )
481 message
.Printf( wxT("Print Error %d"), err
) ;
482 wxMessageDialog
dialog( NULL
, message
, wxT(""), wxICON_HAND
| wxOK
) ;
490 int wxMacClassicPrintData::ShowPageSetupDialog()
492 int result
= wxID_CANCEL
;
496 err
= ::UMAPrOpen() ;
499 if ( ::PrStlDialog( m_macPrintSettings
) )
507 message
.Printf( wxT("Print Error %d"), err
) ;
508 wxMessageDialog
dialog( NULL
, message
, wxEmptyString
, wxICON_HAND
| wxOK
) ;
521 wxMacPrinter::wxMacPrinter(wxPrintDialogData
*data
):
526 wxMacPrinter::~wxMacPrinter(void)
530 bool wxMacPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
533 sm_abortWindow
= NULL
;
538 printout
->SetIsPreview(FALSE
);
539 if (m_printDialogData
.GetMinPage() < 1)
540 m_printDialogData
.SetMinPage(1);
541 if (m_printDialogData
.GetMaxPage() < 1)
542 m_printDialogData
.SetMaxPage(9999);
544 // Create a suitable device context
548 wxPrintDialog
dialog(parent
, & m_printDialogData
);
549 if (dialog
.ShowModal() == wxID_OK
)
551 dc
= dialog
.GetPrintDC();
552 m_printDialogData
= dialog
.GetPrintDialogData();
557 dc
= new wxPrinterDC( m_printDialogData
.GetPrintData() ) ;
561 // May have pressed cancel.
562 if (!dc
|| !dc
->Ok())
568 // on the mac we have always pixels as addressing mode with 72 dpi
570 printout
->SetPPIScreen(72, 72);
571 printout
->SetPPIPrinter(72, 72);
573 // Set printout parameters
579 printout
->SetPageSizePixels((int)w
, (int)h
);
580 dc
->GetSizeMM(&ww
, &hh
);
581 printout
->SetPageSizeMM((int)ww
, (int)hh
);
583 // Create an abort window
586 printout
->OnPreparePrinting();
588 // Get some parameters from the printout, if defined
589 int fromPage
, toPage
;
590 int minPage
, maxPage
;
591 printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
);
599 // Only set min and max, because from and to have been
601 m_printDialogData
.SetMinPage(minPage
);
602 m_printDialogData
.SetMaxPage(maxPage
);
604 wxWindow
*win
= CreateAbortWindow(parent
, printout
);
605 wxSafeYield(win
,true);
610 wxMessageBox(wxT("Sorry, could not create an abort dialog."), wxT("Print Error"), wxOK
, parent
);
614 sm_abortWindow
= win
;
615 sm_abortWindow
->Show(TRUE
);
616 wxSafeYield(win
,true);
618 printout
->OnBeginPrinting();
620 bool keepGoing
= TRUE
;
623 for (copyCount
= 1; copyCount
<= m_printDialogData
.GetNoCopies(); copyCount
++)
625 if (!printout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
628 wxMessageBox(wxT("Could not start printing."), wxT("Print Error"), wxOK
, parent
);
635 for (pn
= m_printDialogData
.GetFromPage(); keepGoing
&& (pn
<= m_printDialogData
.GetToPage()) && printout
->HasPage(pn
);
646 if ( UMAGetSystemVersion() >= 0x1000 )
650 GetPort( &thePort
) ;
651 wxSafeYield(win
,true);
655 keepGoing
= printout
->OnPrintPage(pn
);
659 printout
->OnEndDocument();
662 printout
->OnEndPrinting();
666 sm_abortWindow
->Show(FALSE
);
667 delete sm_abortWindow
;
668 sm_abortWindow
= NULL
;
678 wxDC
* wxMacPrinter::PrintDialog(wxWindow
*parent
)
680 wxDC
* dc
= (wxDC
*) NULL
;
682 wxPrintDialog
dialog(parent
, & m_printDialogData
);
683 int ret
= dialog
.ShowModal();
687 dc
= dialog
.GetPrintDC();
688 m_printDialogData
= dialog
.GetPrintDialogData();
694 bool wxMacPrinter::Setup(wxWindow
*parent
)
697 wxPrintDialog
dialog(parent
, & m_printDialogData
);
698 dialog
.GetPrintDialogData().SetSetupDialog(TRUE
);
700 int ret
= dialog
.ShowModal();
704 m_printDialogData
= dialog
.GetPrintDialogData();
707 return (ret
== wxID_OK
);
716 wxMacPrintPreview::wxMacPrintPreview(wxPrintout
*printout
,
717 wxPrintout
*printoutForPrinting
,
718 wxPrintDialogData
*data
)
719 : wxPrintPreviewBase(printout
, printoutForPrinting
, data
)
724 wxMacPrintPreview::wxMacPrintPreview(wxPrintout
*printout
, wxPrintout
*printoutForPrinting
, wxPrintData
*data
):
725 wxPrintPreviewBase(printout
, printoutForPrinting
, data
)
730 wxMacPrintPreview::~wxMacPrintPreview(void)
734 bool wxMacPrintPreview::Print(bool interactive
)
736 if (!m_printPrintout
)
738 wxMacPrinter
printer(&m_printDialogData
);
739 return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
);
742 void wxMacPrintPreview::DetermineScaling(void)
744 int screenWidth
, screenHeight
;
745 wxDisplaySize( &screenWidth
, &screenHeight
) ;
747 m_previewPrintout
->SetPPIScreen( 72 , 72 ) ;
748 m_previewPrintout
->SetPPIPrinter( 72 , 72 ) ;
749 m_previewPrintout
->SetPageSizeMM( (int) (8.0 * 25.6), (int) (11.0 * 25.6) );
750 m_previewPrintout
->SetPageSizePixels( 8 * 72 , 11 * 72 ) ;
751 m_pageWidth
= 8 * 72 ;
752 m_pageHeight
= 11 * 72 ;
755 // Get a device context for the currently selected printer
756 wxPrinterDC
printerDC(m_printDialogData
.GetPrintData());
761 printerDC
.GetSizeMM(&ww
, &hh
);
762 printerDC
.GetSize( &x
, &y
) ;
763 m_previewPrintout
->SetPageSizeMM((int)ww
, (int)hh
);
764 m_previewPrintout
->SetPageSizePixels( x
, y
) ;
773 // At 100%, the page should look about page-size on the screen.
774 // m_previewScale = (float)((float)screenWidth/(float)printerWidth);
775 // m_previewScale = m_previewScale * (float)((float)screenXRes/(float)printerXRes);