1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMacPrinter framework
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "printwin.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
19 #if wxUSE_PRINTING_ARCHITECTURE
29 #include "wx/msgdlg.h"
33 #include "wx/mac/uma.h"
35 #include "wx/mac/printmac.h"
36 #include "wx/mac/private/print.h"
38 #include "wx/dcprint.h"
39 #include "wx/printdlg.h"
40 #include "wx/mac/printdlg.h"
44 #if !USE_SHARED_LIBRARY
45 IMPLEMENT_DYNAMIC_CLASS(wxMacPrinter
, wxPrinterBase
)
46 IMPLEMENT_CLASS(wxMacPrintPreview
, wxPrintPreviewBase
)
51 wxNativePrintData
* wxNativePrintData::Create()
53 return new wxMacCarbonPrintData() ;
56 wxMacCarbonPrintData::wxMacCarbonPrintData()
58 m_macPageFormat
= kPMNoPageFormat
;
59 m_macPrintSettings
= kPMNoPrintSettings
;
60 m_macPrintSession
= kPMNoReference
;
64 wxMacCarbonPrintData::~wxMacCarbonPrintData()
66 if (m_macPageFormat
!= kPMNoPageFormat
)
68 (void)PMRelease(m_macPageFormat
);
69 m_macPageFormat
= kPMNoPageFormat
;
72 if (m_macPrintSettings
!= kPMNoPrintSettings
)
74 (void)PMRelease(m_macPrintSettings
);
75 m_macPrintSettings
= kPMNoPrintSettings
;
78 if ( m_macPrintSession
!= kPMNoReference
)
80 (void)PMRelease(m_macPrintSession
);
81 m_macPrintSession
= kPMNoReference
;
85 void wxMacCarbonPrintData::ValidateOrCreate()
87 OSStatus err
= noErr
;
88 if ( m_macPrintSession
== kPMNoReference
)
90 err
= PMCreateSession( (PMPrintSession
*) &m_macPrintSession
) ;
92 // Set up a valid PageFormat object.
93 if ( m_macPageFormat
== kPMNoPageFormat
)
95 err
= PMCreatePageFormat((PMPageFormat
*) &m_macPageFormat
);
97 // Note that PMPageFormat is not session-specific, but calling
98 // PMSessionDefaultPageFormat assigns values specific to the printer
99 // associated with the current printing session.
100 if ((err
== noErr
) &&
101 ( m_macPageFormat
!= kPMNoPageFormat
))
103 err
= PMSessionDefaultPageFormat((PMPrintSession
) m_macPrintSession
,
104 (PMPageFormat
) m_macPageFormat
);
109 err
= PMSessionValidatePageFormat((PMPrintSession
) m_macPrintSession
,
110 (PMPageFormat
) m_macPageFormat
,
114 // Set up a valid PrintSettings object.
115 if ( m_macPrintSettings
== kPMNoPrintSettings
)
117 err
= PMCreatePrintSettings((PMPrintSettings
*) &m_macPrintSettings
);
119 // Note that PMPrintSettings is not session-specific, but calling
120 // PMSessionDefaultPrintSettings assigns values specific to the printer
121 // associated with the current printing session.
122 if ((err
== noErr
) &&
123 ( m_macPrintSettings
!= kPMNoPrintSettings
))
125 err
= PMSessionDefaultPrintSettings((PMPrintSession
) m_macPrintSession
,
126 (PMPrintSettings
) m_macPrintSettings
);
131 err
= PMSessionValidatePrintSettings((PMPrintSession
) m_macPrintSession
,
132 (PMPrintSettings
) m_macPrintSettings
,
137 void wxMacCarbonPrintData::TransferFrom( wxPrintData
* data
)
140 PMSetCopies( (PMPrintSettings
) m_macPrintSettings
, data
->GetNoCopies() , false ) ;
141 PMSetOrientation( (PMPageFormat
) m_macPageFormat
, ( data
->GetOrientation() == wxLANDSCAPE
) ?
142 kPMLandscape
: kPMPortrait
, false ) ;
143 // collate cannot be set
144 #if 0 // not yet tested
145 if ( m_printerName
.Length() > 0 )
146 PMSessionSetCurrentPrinter( (PMPrintSession
) m_macPrintSession
, wxMacCFStringHolder( m_printerName
, wxFont::GetDefaultEncoding() ) ) ;
149 PMGetColorMode( (PMPrintSettings
) m_macPrintSettings
, &color
) ;
150 if ( data
->GetColour() )
152 if ( color
== kPMBlackAndWhite
)
153 PMSetColorMode( (PMPrintSettings
) m_macPrintSettings
, kPMColor
) ;
156 PMSetColorMode( (PMPrintSettings
) m_macPrintSettings
, kPMBlackAndWhite
) ;
158 // PMDuplexMode not yet accessible via API
159 // PMQualityMode not yet accessible via API
163 void wxMacCarbonPrintData::TransferTo( wxPrintData
* data
)
165 OSStatus err
= noErr
;
168 err
= PMGetCopies( m_macPrintSettings
, &copies
) ;
170 data
->SetNoCopies( copies
) ;
172 PMOrientation orientation
;
173 err
= PMGetOrientation( m_macPageFormat
, &orientation
) ;
176 if ( orientation
== kPMPortrait
|| orientation
== kPMReversePortrait
)
177 data
->SetOrientation( wxPORTRAIT
);
179 data
->SetOrientation( wxLANDSCAPE
);
182 // collate cannot be set
185 wxMacCFStringHolder name
;
187 PMSessionGetCurrentPrinter( m_macPrintSession
,
189 m_printerName
= name
.AsString() ;
194 err
= PMGetColorMode( m_macPrintSettings
, &color
) ;
196 data
->SetColour( !(color
== kPMBlackAndWhite
) ) ;
198 // PMDuplexMode not yet accessible via API
199 // PMQualityMode not yet accessible via API
202 err
= PMGetUnadjustedPaperRect( m_macPageFormat
, &rPaper
);
205 data
->SetPaperSize( wxSize (
206 (int)(( rPaper
.right
- rPaper
.left
) * pt2mm
+ 0.5 ) ,
207 (int)(( rPaper
.bottom
- rPaper
.top
) * pt2mm
+ 0.5 ) ) );
211 void wxMacCarbonPrintData::TransferFrom( wxPageSetupData
*data
)
213 // should we setup the page rect here ?
214 // since MacOS sometimes has two same paper rects with different
215 // page rects we could make it roundtrip safe perhaps
221 void wxMacCarbonPrintData::TransferTo( wxPageSetupData
* data
)
224 OSStatus err
= PMGetUnadjustedPaperRect(m_macPageFormat
, &rPaper
);
228 err
= PMGetUnadjustedPageRect(m_macPageFormat
, &rPage
) ;
231 data
->SetMinMarginTopLeft( wxPoint (
232 (int)(((double) rPage
.left
- rPaper
.left
) * pt2mm
) ,
233 (int)(((double) rPage
.top
- rPaper
.top
) * pt2mm
) ) ) ;
235 data
->SetMinMarginBottomRight( wxPoint (
236 (wxCoord
)(((double) rPaper
.right
- rPage
.right
) * pt2mm
),
237 (wxCoord
)(((double) rPaper
.bottom
- rPage
.bottom
) * pt2mm
)) ) ;
242 void wxMacCarbonPrintData::TransferTo( wxPrintDialogData
* data
)
244 UInt32 minPage
, maxPage
;
245 PMGetPageRange( m_macPrintSettings
, &minPage
, &maxPage
) ;
246 data
->SetMinPage( minPage
) ;
247 data
->SetMaxPage( maxPage
) ;
249 PMGetCopies( m_macPrintSettings
, &copies
) ;
250 data
->SetNoCopies( copies
) ;
252 PMGetFirstPage( m_macPrintSettings
, &from
) ;
253 PMGetLastPage( m_macPrintSettings
, &to
) ;
254 data
->SetFromPage( from
) ;
255 data
->SetToPage( to
) ;
258 void wxMacCarbonPrintData::TransferFrom( wxPrintDialogData
* data
)
260 PMSetPageRange( m_macPrintSettings
, data
->GetMinPage() , data
->GetMaxPage() ) ;
261 PMSetCopies( m_macPrintSettings
, data
->GetNoCopies() , false ) ;
262 PMSetFirstPage( m_macPrintSettings
, data
->GetFromPage() , false ) ;
264 int toPage
= data
->GetToPage();
266 toPage
= data
->GetFromPage();
267 PMSetLastPage( m_macPrintSettings
, toPage
, false ) ;
270 void wxMacCarbonPrintData::CopyFrom( wxNativePrintData
* d
)
272 wxMacCarbonPrintData
*data
= (wxMacCarbonPrintData
*) d
;
273 if ( data
->m_macPrintSession
!= kPMNoReference
)
274 PMRetain( data
->m_macPrintSession
) ;
275 if ( m_macPrintSession
!= kPMNoReference
)
277 PMRelease( m_macPrintSession
) ;
278 m_macPrintSession
= kPMNoReference
;
280 if ( data
->m_macPrintSession
!= kPMNoReference
)
281 m_macPrintSession
= data
->m_macPrintSession
;
283 if ( data
->m_macPrintSettings
!= kPMNoPrintSettings
)
284 PMRetain( data
->m_macPrintSettings
) ;
285 if ( m_macPrintSettings
!= kPMNoPrintSettings
)
287 PMRelease( m_macPrintSettings
) ;
288 m_macPrintSettings
= kPMNoPrintSettings
;
290 if ( data
->m_macPrintSettings
!= kPMNoPrintSettings
)
291 m_macPrintSettings
= data
->m_macPrintSettings
;
293 if ( data
->m_macPageFormat
!= kPMNoPageFormat
)
294 PMRetain( data
->m_macPageFormat
) ;
295 if ( m_macPageFormat
!= kPMNoPageFormat
)
297 PMRelease( m_macPageFormat
) ;
298 m_macPageFormat
= kPMNoPageFormat
;
300 if ( data
->m_macPageFormat
!= kPMNoPageFormat
)
301 m_macPageFormat
= data
->m_macPageFormat
;
304 int wxMacCarbonPrintData::ShowPrintDialog()
306 int result
= wxID_CANCEL
;
313 // Display the Print dialog.
316 err
= PMSessionPrintDialog( m_macPrintSession
,
320 if ((err
== noErr
) && !accepted
)
322 err
= kPMCancel
; // user clicked Cancel button
330 if ((err
!= noErr
) && (err
!= kPMCancel
))
332 message
.Printf( wxT("Print Error %d"), err
) ;
333 wxMessageDialog
dialog( NULL
, message
, wxEmptyString
, wxICON_HAND
| wxOK
) ;
340 int wxMacCarbonPrintData::ShowPageSetupDialog()
342 int result
= wxID_CANCEL
;
348 // Display the Page Setup dialog.
351 err
= PMSessionPageSetupDialog( m_macPrintSession
,
354 if ((err
== noErr
) && !accepted
)
356 err
= kPMCancel
; // user clicked Cancel button
360 // If the user did not cancel, flatten and save the PageFormat object
361 // with our document.
366 if ((err
!= noErr
) && (err
!= kPMCancel
))
368 message
.Printf( wxT("Print Error %d"), err
) ;
369 wxMessageDialog
dialog( NULL
, message
, wxEmptyString
, wxICON_HAND
| wxOK
) ;
378 wxNativePrintData
* wxNativePrintData::Create()
380 return new wxMacClassicPrintData() ;
383 wxMacClassicPrintData::wxMacClassicPrintData()
385 m_macPrintSettings
= NULL
;
389 wxMacClassicPrintData::~wxMacClassicPrintData()
391 wxASSERT( m_macPrintSettings
);
392 DisposeHandle( (Handle
) m_macPrintSettings
) ;
395 void wxMacClassicPrintData::ValidateOrCreate()
397 if ( m_macPrintSettings
== NULL
)
399 m_macPrintSettings
= (THPrint
) NewHandleClear( sizeof( TPrint
) );
400 (**m_macPrintSettings
).iPrVersion
= 0; // something invalid
402 (**m_macPrintSettings
).prInfo
.iHRes
= 72;
403 (**m_macPrintSettings
).prInfo
.iVRes
= 72;
404 Rect r1
= { 0, 0, 8*72 - 2 * 18, 11*72 - 2 * 36 };
405 (**m_macPrintSettings
).prInfo
.rPage
= r1
;// must have its top left & (0,0)
407 Rect r2
= { -18, -36, 8*72 - 18, 11*72 - 36 };
408 (**m_macPrintSettings
).rPaper
= r2
;
409 (**m_macPrintSettings
).prStl
.iPageV
= 11 * 120 ; // 11 inches in 120th of an inch
410 (**m_macPrintSettings
).prStl
.iPageH
= 8 * 120 ; // 8 inches in 120th of an inch
417 void wxMacClassicPrintData::TransferFrom( wxPrintData
* data
)
420 (**m_macPrintSettings
).prJob
.iCopies
= data
->GetNoCopies() ;
421 // on mac the paper rect has a negative top left corner, because the page rect (printable area) is at 0,0
422 // if all printing data is consolidated in on structure we will be able to set additional infos about pages
425 void wxMacClassicPrintData::TransferTo( wxPrintData
* data
)
427 data
->SetNoCopies( (**m_macPrintSettings
).prJob
.iCopies
);
428 data
->SetPaperSize( wxSize(
429 ((double) (**m_macPrintSettings
).rPaper
.right
- (**m_macPrintSettings
).rPaper
.left
) * pt2mm
,
430 ((double) (**m_macPrintSettings
).rPaper
.bottom
- (**m_macPrintSettings
).rPaper
.top
) * pt2mm
) ) ;
433 void wxMacClassicPrintData::TransferFrom( wxPageSetupData
*data
)
437 void wxMacClassicPrintData::TransferTo( wxPageSetupData
* data
)
439 data
->SetMinMarginTopLeft( wxPoint(
440 ((double) (**m_macPrintSettings
).prInfo
.rPage
.left
-(**m_macPrintSettings
).rPaper
.left
) * pt2mm
,
441 ((double) (**m_macPrintSettings
).prInfo
.rPage
.top
-(**m_macPrintSettings
).rPaper
.top
) * pt2mm
) ) ;
442 data
->SetMinMarginBottomRight( wxPoint(
443 ((double) (**m_macPrintSettings
).rPaper
.right
- (**m_macPrintSettings
).prInfo
.rPage
.right
) * pt2mm
,
444 ((double)(**m_macPrintSettings
).rPaper
.bottom
- (**m_macPrintSettings
).prInfo
.rPage
.bottom
) * pt2mm
) ) ;
447 void wxMacClassicPrintData::TransferFrom( wxPrintDialogData
* data
)
449 int toPage
= data
->GetToPage();
451 toPage
= data
->GetFromPage();
452 (**m_macPrintSettings
).prJob
.iFstPage
= data
->GetFromPage() ;
453 (**m_macPrintSettings
).prJob
.iLstPage
= toPage
;
456 void wxMacClassicPrintData::TransferTo( wxPrintDialogData
* data
)
458 data
->SetFromPage( (**m_macPrintSettings
).prJob
.iFstPage
) ;
459 data
->SetToPage( (**m_macPrintSettings
).prJob
.iLstPage
) ;
462 void wxMacClassicPrintData::CopyFrom( wxNativePrintData
* data
)
464 DisposeHandle( (Handle
) m_macPrintSettings
) ;
465 m_macPrintSettings
= ((wxMacClassicPrintData
*)data
)->m_macPrintSettings
;
466 HandToHand( (Handle
*) &m_macPrintSettings
);
469 int wxMacClassicPrintData::ShowPrintDialog()
471 int result
= wxID_CANCEL
;
475 err
= ::UMAPrOpen() ;
478 if ( ::PrJobDialog( m_macPrintSettings
) )
486 message
.Printf( wxT("Print Error %d"), err
) ;
487 wxMessageDialog
dialog( NULL
, message
, wxT(""), wxICON_HAND
| wxOK
) ;
495 int wxMacClassicPrintData::ShowPageSetupDialog()
497 int result
= wxID_CANCEL
;
501 err
= ::UMAPrOpen() ;
504 if ( ::PrStlDialog( m_macPrintSettings
) )
512 message
.Printf( wxT("Print Error %d"), err
) ;
513 wxMessageDialog
dialog( NULL
, message
, wxEmptyString
, wxICON_HAND
| wxOK
) ;
526 wxMacPrinter::wxMacPrinter(wxPrintDialogData
*data
):
531 wxMacPrinter::~wxMacPrinter(void)
535 bool wxMacPrinter::Print(wxWindow
*parent
, wxPrintout
*printout
, bool prompt
)
538 sm_abortWindow
= NULL
;
543 printout
->SetIsPreview(FALSE
);
544 if (m_printDialogData
.GetMinPage() < 1)
545 m_printDialogData
.SetMinPage(1);
546 if (m_printDialogData
.GetMaxPage() < 1)
547 m_printDialogData
.SetMaxPage(9999);
549 // Create a suitable device context
553 wxPrintDialog
dialog(parent
, & m_printDialogData
);
554 if (dialog
.ShowModal() == wxID_OK
)
556 dc
= dialog
.GetPrintDC();
557 m_printDialogData
= dialog
.GetPrintDialogData();
562 dc
= new wxPrinterDC( m_printDialogData
.GetPrintData() ) ;
566 // May have pressed cancel.
567 if (!dc
|| !dc
->Ok())
573 // on the mac we have always pixels as addressing mode with 72 dpi
575 printout
->SetPPIScreen(72, 72);
576 printout
->SetPPIPrinter(72, 72);
578 // Set printout parameters
584 printout
->SetPageSizePixels((int)w
, (int)h
);
585 dc
->GetSizeMM(&ww
, &hh
);
586 printout
->SetPageSizeMM((int)ww
, (int)hh
);
588 // Create an abort window
591 printout
->OnPreparePrinting();
593 // Get some parameters from the printout, if defined
594 int fromPage
, toPage
;
595 int minPage
, maxPage
;
596 printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
);
604 // Only set min and max, because from and to have been
606 m_printDialogData
.SetMinPage(minPage
);
607 m_printDialogData
.SetMaxPage(maxPage
);
609 wxWindow
*win
= CreateAbortWindow(parent
, printout
);
610 wxSafeYield(win
,true);
615 wxMessageBox(wxT("Sorry, could not create an abort dialog."), wxT("Print Error"), wxOK
, parent
);
619 sm_abortWindow
= win
;
620 sm_abortWindow
->Show(TRUE
);
621 wxSafeYield(win
,true);
623 printout
->OnBeginPrinting();
625 bool keepGoing
= TRUE
;
628 for (copyCount
= 1; copyCount
<= m_printDialogData
.GetNoCopies(); copyCount
++)
630 if (!printout
->OnBeginDocument(m_printDialogData
.GetFromPage(), m_printDialogData
.GetToPage()))
633 wxMessageBox(wxT("Could not start printing."), wxT("Print Error"), wxOK
, parent
);
640 for (pn
= m_printDialogData
.GetFromPage(); keepGoing
&& (pn
<= m_printDialogData
.GetToPage()) && printout
->HasPage(pn
);
651 if ( UMAGetSystemVersion() >= 0x1000 )
655 GetPort( &thePort
) ;
656 wxSafeYield(win
,true);
660 keepGoing
= printout
->OnPrintPage(pn
);
664 printout
->OnEndDocument();
667 printout
->OnEndPrinting();
671 sm_abortWindow
->Show(FALSE
);
672 delete sm_abortWindow
;
673 sm_abortWindow
= NULL
;
683 wxDC
* wxMacPrinter::PrintDialog(wxWindow
*parent
)
685 wxDC
* dc
= (wxDC
*) NULL
;
687 wxPrintDialog
dialog(parent
, & m_printDialogData
);
688 int ret
= dialog
.ShowModal();
692 dc
= dialog
.GetPrintDC();
693 m_printDialogData
= dialog
.GetPrintDialogData();
699 bool wxMacPrinter::Setup(wxWindow
*parent
)
702 wxPrintDialog
dialog(parent
, & m_printDialogData
);
703 dialog
.GetPrintDialogData().SetSetupDialog(TRUE
);
705 int ret
= dialog
.ShowModal();
709 m_printDialogData
= dialog
.GetPrintDialogData();
712 return (ret
== wxID_OK
);
721 wxMacPrintPreview::wxMacPrintPreview(wxPrintout
*printout
,
722 wxPrintout
*printoutForPrinting
,
723 wxPrintDialogData
*data
)
724 : wxPrintPreviewBase(printout
, printoutForPrinting
, data
)
729 wxMacPrintPreview::wxMacPrintPreview(wxPrintout
*printout
, wxPrintout
*printoutForPrinting
, wxPrintData
*data
):
730 wxPrintPreviewBase(printout
, printoutForPrinting
, data
)
735 wxMacPrintPreview::~wxMacPrintPreview(void)
739 bool wxMacPrintPreview::Print(bool interactive
)
741 if (!m_printPrintout
)
743 wxMacPrinter
printer(&m_printDialogData
);
744 return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
);
747 void wxMacPrintPreview::DetermineScaling(void)
749 int screenWidth
, screenHeight
;
750 wxDisplaySize( &screenWidth
, &screenHeight
) ;
752 m_previewPrintout
->SetPPIScreen( 72 , 72 ) ;
753 m_previewPrintout
->SetPPIPrinter( 72 , 72 ) ;
754 m_previewPrintout
->SetPageSizeMM( (int) (8.0 * 25.6), (int) (11.0 * 25.6) );
755 m_previewPrintout
->SetPageSizePixels( 8 * 72 , 11 * 72 ) ;
756 m_pageWidth
= 8 * 72 ;
757 m_pageHeight
= 11 * 72 ;
760 // Get a device context for the currently selected printer
761 wxPrinterDC
printerDC(m_printDialogData
.GetPrintData());
766 printerDC
.GetSizeMM(&ww
, &hh
);
767 printerDC
.GetSize( &x
, &y
) ;
768 m_previewPrintout
->SetPageSizeMM((int)ww
, (int)hh
);
769 m_previewPrintout
->SetPageSizePixels( x
, y
) ;
778 // At 100%, the page should look about page-size on the screen.
779 // m_previewScale = (float)((float)screenWidth/(float)printerWidth);
780 // m_previewScale = m_previewScale * (float)((float)screenXRes/(float)printerXRes);