diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoaprintdevice.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaprintdevice.mm | 498 |
1 files changed, 0 insertions, 498 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm deleted file mode 100644 index ab304d9c04..0000000000 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ /dev/null @@ -1,498 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 John Layt <jlayt@kde.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <ApplicationServices/ApplicationServices.h> - -#include "qcocoaprintdevice.h" - -#if QT_CONFIG(mimetype) -#include <QtCore/qmimedatabase.h> -#endif -#include <qdebug.h> - -#include <QtCore/private/qcore_mac_p.h> - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_PRINTER - -// The CUPS PPD APIs were deprecated in CUPS 1.6/macOS 10.8, but -// as long as we're supporting RHEL 6, which still ships CUPS 1.4 -// we're not going to rewrite this, as we want to share the code -// between macOS and Linux for the CUPS-bits. See discussion in -// https://bugreports.qt.io/browse/QTBUG-56545 -#pragma message "Disabling CUPS PPD deprecation warnings. This should be fixed once we drop support for RHEL6 (QTBUG-56545)" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -static QPrint::DuplexMode macToDuplexMode(const PMDuplexMode &mode) -{ - if (mode == kPMDuplexTumble) - return QPrint::DuplexShortSide; - else if (mode == kPMDuplexNoTumble) - return QPrint::DuplexLongSide; - else // kPMDuplexNone or kPMSimplexTumble - return QPrint::DuplexNone; -} - -QCocoaPrintDevice::QCocoaPrintDevice() - : QPlatformPrintDevice(), - m_printer(nullptr), - m_session(nullptr), - m_ppd(nullptr) -{ -} - -QCocoaPrintDevice::QCocoaPrintDevice(const QString &id) - : QPlatformPrintDevice(id), - m_printer(nullptr), - m_session(nullptr), - m_ppd(nullptr) -{ - if (!id.isEmpty()) { - m_printer = PMPrinterCreateFromPrinterID(id.toCFString()); - if (m_printer) { - m_name = QString::fromCFString(PMPrinterGetName(m_printer)); - m_location = QString::fromCFString(PMPrinterGetLocation(m_printer)); - CFStringRef cfMakeAndModel; - if (PMPrinterGetMakeAndModelName(m_printer, &cfMakeAndModel) == noErr) - m_makeAndModel = QString::fromCFString(cfMakeAndModel); - Boolean isRemote; - if (PMPrinterIsRemote(m_printer, &isRemote) == noErr) - m_isRemote = isRemote; - if (PMCreateSession(&m_session) == noErr) - PMSessionSetCurrentPMPrinter(m_session, m_printer); - - // No native api to query these options, need to use PPD directly, note is deprecated from 1.6 onwards - if (openPpdFile()) { - // Note this is if the hardware does multiple copies, not if Cups can - m_supportsMultipleCopies = !m_ppd->manual_copies; - // Note this is if the hardware does collation, not if Cups can - ppd_option_t *collate = ppdFindOption(m_ppd, "Collate"); - if (collate) - m_supportsCollateCopies = true; - m_supportsCustomPageSizes = m_ppd->custom_max[0] > 0 && m_ppd->custom_max[1] > 0; - m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]); - m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]); - m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3], - m_ppd->custom_margins[2], m_ppd->custom_margins[1]); - } - } - } -} - -QCocoaPrintDevice::~QCocoaPrintDevice() -{ - if (m_ppd) - ppdClose(m_ppd); - for (PMPaper paper : m_macPapers) - PMRelease(paper); - // Releasing the session appears to also release the printer - if (m_session) - PMRelease(m_session); - else if (m_printer) - PMRelease(m_printer); -} - -bool QCocoaPrintDevice::isValid() const -{ - return m_printer ? true : false; -} - -bool QCocoaPrintDevice::isDefault() const -{ - return PMPrinterIsDefault(m_printer); -} - -QPrint::DeviceState QCocoaPrintDevice::state() const -{ - PMPrinterState state; - if (PMPrinterGetState(m_printer, &state) == noErr) { - if (state == kPMPrinterIdle) - return QPrint::Idle; - else if (state == kPMPrinterProcessing) - return QPrint::Active; - else if (state == kPMPrinterStopped) - return QPrint::Error; - } - return QPrint::Error; -} - -QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const -{ - CFStringRef key; - double width; - double height; - CFStringRef localizedName; - if (PMPaperGetPPDPaperName(paper, &key) == noErr - && PMPaperGetWidth(paper, &width) == noErr - && PMPaperGetHeight(paper, &height) == noErr - && PMPaperCreateLocalizedName(paper, m_printer, &localizedName) == noErr) { - QPageSize pageSize = QPlatformPrintDevice::createPageSize(QString::fromCFString(key),QSize(width, height), - QString::fromCFString(localizedName)); - CFRelease(localizedName); - return pageSize; - } - return QPageSize(); -} - -void QCocoaPrintDevice::loadPageSizes() const -{ - m_pageSizes.clear(); - for (PMPaper paper : m_macPapers) - PMRelease(paper); - m_macPapers.clear(); - m_printableMargins.clear(); - CFArrayRef paperSizes; - if (PMPrinterGetPaperList(m_printer, &paperSizes) == noErr) { - int count = CFArrayGetCount(paperSizes); - for (int i = 0; i < count; ++i) { - PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(paperSizes, i))); - QPageSize pageSize = createPageSize(paper); - if (pageSize.isValid()) { - m_pageSizes.append(pageSize); - PMRetain(paper); - m_macPapers.insert(pageSize.key(), paper); - PMPaperMargins printMargins; - PMPaperGetMargins(paper, &printMargins); - m_printableMargins.insert(pageSize.key(), QMarginsF(printMargins.left, printMargins.top, - printMargins.right, printMargins.bottom)); - } - } - } - m_havePageSizes = true; -} - -QPageSize QCocoaPrintDevice::defaultPageSize() const -{ - QPageSize pageSize; - PMPageFormat pageFormat; - PMPaper paper; - if (PMCreatePageFormat(&pageFormat) == noErr) { - if (PMSessionDefaultPageFormat(m_session, pageFormat) == noErr - && PMGetPageFormatPaper(pageFormat, &paper) == noErr) { - pageSize = createPageSize(paper); - } - PMRelease(pageFormat); - } - return pageSize; -} - -QMarginsF QCocoaPrintDevice::printableMargins(const QPageSize &pageSize, - QPageLayout::Orientation orientation, - int resolution) const -{ - Q_UNUSED(orientation) - Q_UNUSED(resolution) - if (!m_havePageSizes) - loadPageSizes(); - if (m_printableMargins.contains(pageSize.key())) - return m_printableMargins.value(pageSize.key()); - return m_customMargins; -} - -void QCocoaPrintDevice::loadResolutions() const -{ - m_resolutions.clear(); - UInt32 count; - if (PMPrinterGetPrinterResolutionCount(m_printer, &count) == noErr) { - // 1-based index - for (UInt32 i = 1; i <= count; ++i) { - PMResolution resolution; - if (PMPrinterGetIndexedPrinterResolution(m_printer, i, &resolution) == noErr) - m_resolutions.append(int(resolution.hRes)); - } - } - m_haveResolutions = true; -} - -int QCocoaPrintDevice::defaultResolution() const -{ - int defaultResolution = 72; - PMPrintSettings settings; - if (PMCreatePrintSettings(&settings) == noErr) { - PMResolution resolution; - if (PMSessionDefaultPrintSettings(m_session, settings) == noErr - && PMPrinterGetOutputResolution(m_printer, settings, &resolution) == noErr) { - // PMPrinterGetOutputResolution usually fails with -9589 kPMKeyNotFound as not set in PPD - defaultResolution = int(resolution.hRes); - } - PMRelease(settings); - } - // If no value returned (usually means not set in PPD) then use supported resolutions which - // OSX will have populated with at least one default value (but why not returned by call?) - if (defaultResolution <= 0) { - if (!m_haveResolutions) - loadResolutions(); - if (m_resolutions.count() > 0) - return m_resolutions.at(0); // First value or highest? Only likely to be one anyway. - return 72; // TDOD More sensible default value??? - } - return defaultResolution; -} - -void QCocoaPrintDevice::loadInputSlots() const -{ - // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync - // TODO Deal with concatenated names like Tray1Manual or Tray1_Man, - // will currently show as CustomInputSlot - // TODO Deal with separate ManualFeed key - // Try load standard PPD options first - m_inputSlots.clear(); - if (m_ppd) { - ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot"); - if (inputSlots) { - for (int i = 0; i < inputSlots->num_choices; ++i) - m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i])); - } - // If no result, try just the default - if (m_inputSlots.size() == 0) { - inputSlots = ppdFindOption(m_ppd, "DefaultInputSlot"); - if (inputSlots) - m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0])); - } - } - // If still no result, just use Auto - if (m_inputSlots.size() == 0) - m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot()); - m_haveInputSlots = true; -} - -QPrint::InputSlot QCocoaPrintDevice::defaultInputSlot() const -{ - // No native api to query, use PPD directly - // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync - // Try load standard PPD option first - if (m_ppd) { - ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultInputSlot"); - if (inputSlot) - return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]); - // If no result, then try a marked option - ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "InputSlot"); - if (defaultChoice) - return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice); - } - // Otherwise return Auto - return QPlatformPrintDevice::defaultInputSlot(); -} - -void QCocoaPrintDevice::loadOutputBins() const -{ - // No native api to query, use PPD directly - // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync - m_outputBins.clear(); - if (m_ppd) { - ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin"); - if (outputBins) { - for (int i = 0; i < outputBins->num_choices; ++i) - m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i])); - } - // If no result, try just the default - if (m_outputBins.size() == 0) { - outputBins = ppdFindOption(m_ppd, "DefaultOutputBin"); - if (outputBins) - m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0])); - } - } - // If still no result, just use Auto - if (m_outputBins.size() == 0) - m_outputBins.append(QPlatformPrintDevice::defaultOutputBin()); - m_haveOutputBins = true; -} - -QPrint::OutputBin QCocoaPrintDevice::defaultOutputBin() const -{ - // No native api to query, use PPD directly - // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync - // Try load standard PPD option first - if (m_ppd) { - ppd_option_t *outputBin = ppdFindOption(m_ppd, "DefaultOutputBin"); - if (outputBin) - return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]); - // If no result, then try a marked option - ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "OutputBin"); - if (defaultChoice) - return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice); - } - // Otherwise return AutoBin - return QPlatformPrintDevice::defaultOutputBin(); -} - -void QCocoaPrintDevice::loadDuplexModes() const -{ - // No native api to query, use PPD directly - // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync - // Try load standard PPD options first - m_duplexModes.clear(); - if (m_ppd) { - ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex"); - if (duplexModes) { - for (int i = 0; i < duplexModes->num_choices; ++i) - m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice)); - } - // If no result, try just the default - if (m_duplexModes.size() == 0) { - duplexModes = ppdFindOption(m_ppd, "DefaultDuplex"); - if (duplexModes) - m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice)); - } - } - // If still no result, or not added in PPD, then add None - if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone)) - m_duplexModes.append(QPrint::DuplexNone); - // If have both modes, then can support DuplexAuto - if (m_duplexModes.contains(QPrint::DuplexLongSide) && m_duplexModes.contains(QPrint::DuplexShortSide)) - m_duplexModes.append(QPrint::DuplexAuto); - m_haveDuplexModes = true; -} - -QPrint::DuplexMode QCocoaPrintDevice::defaultDuplexMode() const -{ - QPrint::DuplexMode defaultMode = QPrint::DuplexNone; - PMPrintSettings settings; - if (PMCreatePrintSettings(&settings) == noErr) { - PMDuplexMode duplexMode; - if (PMSessionDefaultPrintSettings(m_session, settings) == noErr - && PMGetDuplex(settings, &duplexMode) == noErr) { - defaultMode = macToDuplexMode(duplexMode); - } - PMRelease(settings); - } - return defaultMode; -} - -void QCocoaPrintDevice::loadColorModes() const -{ - // No native api to query, use PPD directly - m_colorModes.clear(); - m_colorModes.append(QPrint::GrayScale); - if (!m_ppd || (m_ppd && m_ppd->color_device)) - m_colorModes.append(QPrint::Color); - m_haveColorModes = true; -} - -QPrint::ColorMode QCocoaPrintDevice::defaultColorMode() const -{ - // No native api to query, use PPD directly - // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync - // Not a proper option, usually only know if supports color or not, but some - // users known to abuse ColorModel to always force GrayScale. - if (m_ppd && supportedColorModes().contains(QPrint::Color)) { - ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel"); - if (!colorModel) - colorModel = ppdFindOption(m_ppd, "ColorModel"); - if (!colorModel || qstrcmp(colorModel->defchoice, "Gray") != 0) - return QPrint::Color; - } - return QPrint::GrayScale; -} - -#if QT_CONFIG(mimetype) -void QCocoaPrintDevice::loadMimeTypes() const -{ - // TODO Check how settings affect returned list - m_mimeTypes.clear(); - QMimeDatabase db; - PMPrintSettings settings; - if (PMCreatePrintSettings(&settings) == noErr) { - CFArrayRef mimeTypes; - if (PMPrinterGetMimeTypes(m_printer, settings, &mimeTypes) == noErr) { - int count = CFArrayGetCount(mimeTypes); - for (int i = 0; i < count; ++i) { - CFStringRef mimeName = static_cast<CFStringRef>(const_cast<void *>(CFArrayGetValueAtIndex(mimeTypes, i))); - QMimeType mimeType = db.mimeTypeForName(QString::fromCFString(mimeName)); - if (mimeType.isValid()) - m_mimeTypes.append(mimeType); - } - } - PMRelease(settings); - } - m_haveMimeTypes = true; -} -#endif // mimetype - -bool QCocoaPrintDevice::openPpdFile() -{ - if (m_ppd) - ppdClose(m_ppd); - m_ppd = nullptr; - CFURLRef ppdURL = nullptr; - char ppdPath[MAXPATHLEN]; - if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr - && ppdURL) { - if (CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath))) - m_ppd = ppdOpenFile(ppdPath); - CFRelease(ppdURL); - } - return m_ppd ? true : false; -} - -PMPrinter QCocoaPrintDevice::macPrinter() const -{ - return m_printer; -} - -// Returns a cached printer PMPaper, or creates and caches a new custom PMPaper -// Caller should never release a cached PMPaper! -PMPaper QCocoaPrintDevice::macPaper(const QPageSize &pageSize) const -{ - if (!m_havePageSizes) - loadPageSizes(); - // If keys match, then is a supported size or an existing custom size - if (m_macPapers.contains(pageSize.key())) - return m_macPapers.value(pageSize.key()); - // For any other page size, whether custom or just unsupported, needs to be a custom PMPaper - PMPaper paper = nullptr; - PMPaperMargins paperMargins; - paperMargins.left = m_customMargins.left(); - paperMargins.right = m_customMargins.right(); - paperMargins.top = m_customMargins.top(); - paperMargins.bottom = m_customMargins.bottom(); - PMPaperCreateCustom(m_printer, QCFString(pageSize.key()), QCFString(pageSize.name()), - pageSize.sizePoints().width(), pageSize.sizePoints().height(), - &paperMargins, &paper); - m_macPapers.insert(pageSize.key(), paper); - return paper; -} - -#pragma clang diagnostic pop - -#endif // QT_NO_PRINTER - -QT_END_NAMESPACE |