void wxOSXPrintData::TransferPrinterNameFrom( const wxPrintData &data ) { CFArrayRef printerList; CFIndex index, count; CFStringRef name; if (PMServerCreatePrinterList(kPMServerLocal, &printerList) == noErr) { PMPrinter printer = NULL; count = CFArrayGetCount(printerList); for (index = 0; index < count; index++) { printer = (PMPrinter)CFArrayGetValueAtIndex(printerList, index); if ((data.GetPrinterName().empty()) && (PMPrinterIsDefault(printer))) break; else { name = PMPrinterGetName(printer); CFRetain(name); if (data.GetPrinterName() == wxCFStringRef(name).AsString()) break; } } if (index < count) PMSessionSetCurrentPMPrinter(m_macPrintSession, printer); CFRelease(printerList); } }
bool wxOSXPrintData::TransferFrom( const wxPrintData &data ) { PMPrinter printer; PMSessionGetCurrentPrinter(m_macPrintSession, &printer); wxSize papersize = wxDefaultSize; const wxPaperSize paperId = data.GetPaperId(); if ( paperId != wxPAPER_NONE && wxThePrintPaperDatabase ) { papersize = wxThePrintPaperDatabase->GetSize(paperId); if ( papersize != wxDefaultSize ) { papersize.x /= 10; papersize.y /= 10; } } else { papersize = data.GetPaperSize(); } if ( papersize != wxDefaultSize ) { papersize.x = (wxInt32) (papersize.x * mm2pt); papersize.y = (wxInt32) (papersize.y * mm2pt); double height, width; PMPaperGetHeight(m_macPaper, &height); PMPaperGetWidth(m_macPaper, &width); if ( fabs( width - papersize.x ) >= 5 || fabs( height - papersize.y ) >= 5 ) { // we have to change the current paper CFArrayRef paperlist = 0 ; if ( PMPrinterGetPaperList( printer, &paperlist ) == noErr ) { PMPaper bestPaper = kPMNoData ; CFIndex top = CFArrayGetCount(paperlist); for ( CFIndex i = 0 ; i < top ; ++ i ) { PMPaper paper = (PMPaper) CFArrayGetValueAtIndex( paperlist, i ); PMPaperGetHeight(paper, &height); PMPaperGetWidth(paper, &width); if ( fabs( width - papersize.x ) < 5 && fabs( height - papersize.y ) < 5 ) { // TODO test for duplicate hits and use additional // criteria for best match bestPaper = paper; } } PMPaper paper = kPMNoData; if ( bestPaper == kPMNoData ) { const PMPaperMargins margins = { 0.0, 0.0, 0.0, 0.0 }; wxString id, name(_T("Custom paper")); id.Printf(_T("wxPaperCustom%dx%d"), papersize.x, papersize.y); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if ( PMPaperCreateCustom != NULL) { PMPaperCreateCustom(printer, wxCFStringRef( id, wxFont::GetDefaultEncoding() ), wxCFStringRef( name, wxFont::GetDefaultEncoding() ), papersize.x, papersize.y, &margins, &paper); } #endif #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 if ( paper == kPMNoData ) { PMPaperCreate(printer, wxCFStringRef( id, wxFont::GetDefaultEncoding() ), wxCFStringRef( name, wxFont::GetDefaultEncoding() ), papersize.x, papersize.y, &margins, &paper); } #endif } if ( bestPaper != kPMNoData ) { PMPageFormat pageFormat; PMCreatePageFormatWithPMPaper(&pageFormat, bestPaper); PMCopyPageFormat( pageFormat, m_macPageFormat ); PMRelease(pageFormat); PMGetPageFormatPaper(m_macPageFormat, &m_macPaper); } PMRelease(paper); } } } CFArrayRef printerList; CFIndex index, count; CFStringRef name; if (PMServerCreatePrinterList(kPMServerLocal, &printerList) == noErr) { count = CFArrayGetCount(printerList); for (index = 0; index < count; index++) { printer = (PMPrinter)CFArrayGetValueAtIndex(printerList, index); if ((data.GetPrinterName().empty()) && (PMPrinterIsDefault(printer))) break; else { name = PMPrinterGetName(printer); CFRetain(name); if (data.GetPrinterName() == wxCFStringRef(name).AsString()) break; } } if (index < count) PMSessionSetCurrentPMPrinter(m_macPrintSession, printer); CFRelease(printerList); } PMSetCopies( m_macPrintSettings , data.GetNoCopies() , false ) ; PMSetCollate(m_macPrintSettings, data.GetCollate()); if ( data.IsOrientationReversed() ) PMSetOrientation( m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ? kPMReverseLandscape : kPMReversePortrait , false ) ; else PMSetOrientation( m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ? kPMLandscape : kPMPortrait , false ) ; PMDuplexMode mode = 0 ; switch( data.GetDuplex() ) { case wxDUPLEX_HORIZONTAL : mode = kPMDuplexNoTumble ; break ; case wxDUPLEX_VERTICAL : mode = kPMDuplexTumble ; break ; case wxDUPLEX_SIMPLEX : default : mode = kPMDuplexNone ; break ; } PMSetDuplex( m_macPrintSettings, mode ) ; // PMQualityMode not yet accessible via API if ( data.IsOrientationReversed() ) PMSetOrientation( m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ? kPMReverseLandscape : kPMReversePortrait , false ) ; else PMSetOrientation( m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ? kPMLandscape : kPMPortrait , false ) ; #ifndef __LP64__ // PMQualityMode not accessible via API // TODO: use our quality property to determine optimal resolution PMResolution res; PMTag tag = kPMMaxSquareResolution; PMPrinterGetPrinterResolution(printer, tag, &res); PMSetResolution( m_macPageFormat, &res); #endif // after setting the new resolution the format has to be updated, otherwise the page rect remains // at the 'old' scaling PMSessionValidatePageFormat(m_macPrintSession, m_macPageFormat, kPMDontWantBoolean); PMSessionValidatePrintSettings(m_macPrintSession, m_macPrintSettings, kPMDontWantBoolean); #if wxOSX_USE_COCOA UpdateFromPMState(); #endif return true ; }
void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) { Q_D(QMacPrintEngine); d->valueCache.insert(key, value); if (!d->session) return; switch (key) { case PPK_CollateCopies: break; case PPK_ColorMode: break; case PPK_Creator: break; case PPK_DocumentName: break; case PPK_PageOrder: break; case PPK_PaperSource: break; case PPK_SelectionOption: break; case PPK_Resolution: { PMPrinter printer; UInt32 count; if (PMSessionGetCurrentPrinter(d->session, &printer) != noErr) break; if (PMPrinterGetPrinterResolutionCount(printer, &count) != noErr) break; PMResolution resolution = { 0.0, 0.0 }; PMResolution bestResolution = { 0.0, 0.0 }; int dpi = value.toInt(); int bestDistance = INT_MAX; for (UInt32 i = 1; i <= count; ++i) { // Yes, it starts at 1 if (PMPrinterGetIndexedPrinterResolution(printer, i, &resolution) == noErr) { if (dpi == int(resolution.hRes)) { bestResolution = resolution; break; } else { int distance = qAbs(dpi - int(resolution.hRes)); if (distance < bestDistance) { bestDistance = distance; bestResolution = resolution; } } } } PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean); break; } case PPK_FullPage: d->fullPage = value.toBool(); break; case PPK_NumberOfCopies: PMSetCopies(d->settings, value.toInt(), false); break; case PPK_Orientation: { if (d->state == QPrinter::Active) { qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change"); } else { QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt()); if (d->hasCustomPaperSize && (d->orient != newOrientation)) d->customSize = QSizeF(d->customSize.height(), d->customSize.width()); d->orient = newOrientation; PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape; PMSetOrientation(d->format, o, false); PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean); } break; } case PPK_OutputFileName: d->outputFilename = value.toString(); break; case PPK_PaperSize: d->setPaperSize(QPrinter::PaperSize(value.toInt())); break; case PPK_PrinterName: { OSStatus status = noErr; QCFType<CFArrayRef> printerList; status = PMServerCreatePrinterList(kPMServerLocal, &printerList); if (status == noErr) { CFIndex count = CFArrayGetCount(printerList); for (CFIndex i=0; i<count; ++i) { PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i))); QString name = QCFString::toQString(PMPrinterGetName(printer)); if (name == value.toString()) { status = PMSessionSetCurrentPMPrinter(d->session, printer); break; } } } if (status != noErr) qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status)); break; } case PPK_SuppressSystemPrintStatus: d->suppressStatus = value.toBool(); break; case PPK_CustomPaperSize: { PMOrientation orientation; PMGetOrientation(d->format, &orientation); d->hasCustomPaperSize = true; d->customSize = value.toSizeF(); if (orientation != kPMPortrait) d->customSize = QSizeF(d->customSize.height(), d->customSize.width()); break; } case PPK_PageMargins: { QList<QVariant> margins(value.toList()); Q_ASSERT(margins.size() == 4); d->leftMargin = margins.at(0).toDouble(); d->topMargin = margins.at(1).toDouble(); d->rightMargin = margins.at(2).toDouble(); d->bottomMargin = margins.at(3).toDouble(); d->hasCustomPageMargins = true; break; } default: break; } }