diff options
author | Tor Arne Vestbø <torarnv@gmail.com> | 2020-03-02 16:10:35 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2020-03-09 14:53:50 +0100 |
commit | cc59f0de557e2d8fba274a86ba43afc4ffcd935b (patch) | |
tree | 482d030cbde609c118ead158b4e3e20da5f602e5 /src | |
parent | 2097932dc54b3ef9a369da956704733792e965b3 (diff) |
macOS: Support printing when no printers are installed
Even if there are no printers installed, we can still show the print
dialog, which gives the user feedback about no printers being installed,
allows them to install one, or allows them to print to PDF as a
fallback.
The code for printing to PDF has been re-enabled, and the conditions
of QTBUG-38820 have been removed as the problem is no longer present.
The code also takes into account the possibility that the user chose
to print to PostScript, which we don't yet support, but warn about.
We now also support opening the printed document in Preview. This
requires a minor assumption about the print operation being done
synchronously after the print dialog is accepted, but this is
something we can improve in the future with internal APIs if it
turns out to be a problem.
Printing workflows such as sending the printed document via mail
or messenger are not not supported, and will give a warning.
Fixes: QTBUG-36112
Change-Id: I8ba9e2c5ce31a5a06542c4a7126d005e4b27f2be
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/printsupport/dialogs/qprintdialog_mac.mm | 72 |
1 files changed, 37 insertions, 35 deletions
diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index ed2d0908c4..a4101f7ec0 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -42,6 +42,7 @@ #include "qprintdialog.h" #include "qabstractprintdialog_p.h" +#include <QtCore/qtemporarydir.h> #include <QtCore/private/qcore_mac_p.h> #include <QtWidgets/private/qapplication_p.h> #include <QtPrintSupport/qprinter.h> @@ -127,21 +128,36 @@ QT_USE_NAMESPACE PMDestinationType dest; PMSessionGetDestinationType(session, settings, &dest); if (dest == kPMDestinationFile) { - // QTBUG-38820 - // If user selected Print to File, leave OSX to generate the PDF, - // otherwise setting PdfFormat would prevent us showing dialog again. - // TODO Restore this when QTBUG-36112 is fixed. - /* QCFType<CFURLRef> file; PMSessionCopyDestinationLocation(session, settings, &file); UInt8 localFile[2048]; // Assuming there's a POSIX file system here. CFURLGetFileSystemRepresentation(file, true, localFile, sizeof(localFile)); - printer->setOutputFileName(QString::fromUtf8(reinterpret_cast<const char *>(localFile))); - */ - } else { + auto outputFile = QFileInfo(QString::fromUtf8(reinterpret_cast<const char *>(localFile))); + if (outputFile.suffix() == QLatin1String("pdf")) + printer->setOutputFileName(outputFile.absoluteFilePath()); + else + qWarning() << "Can not print to file type" << outputFile.suffix(); + } else if (dest == kPMDestinationPreview) { + static QTemporaryDir printPreviews; + auto documentName = printer->docName(); + if (documentName.isEmpty()) + documentName = QGuiApplication::applicationDisplayName(); + auto fileName = printPreviews.filePath(QString(QLatin1String("%1.pdf")).arg(documentName)); + printer->setOutputFileName(fileName); + // Ideally we would have a callback when the PDF engine is done writing + // to the file, and open Preview in response to that. Lacking that, we + // use the quick and dirty assumption that the the print operation will + // happen synchronously after the dialog is accepted, so we can defer + // the opening of the file to the next runloop pass. + dispatch_async(dispatch_get_main_queue(), ^{ + [NSWorkspace.sharedWorkspace openFile:fileName.toNSString()]; + }); + } else if (dest == kPMDestinationProcessPDF) { + qWarning("Printing workflows are not supported"); + } else if (dest == kPMDestinationPrinter) { PMPrinter macPrinter; PMSessionGetCurrentPrinter(session, &macPrinter); - QString printerId = QString::fromCFString(PMPrinterGetID(macPrinter)); + QString printerId = QString::fromCFString(PMPrinterGetID(macPrinter)).trimmed(); if (printer->printerName() != printerId) printer->setPrinterName(printerId); } @@ -199,14 +215,18 @@ void QPrintDialogPrivate::openCocoaPrintPanel(Qt::WindowModality modality) { Q_Q(QPrintDialog); - // get the NSPrintInfo from the print engine in the platform plugin - void *voidp = 0; - (void) QMetaObject::invokeMethod(qApp->platformNativeInterface(), - "NSPrintInfoForPrintEngine", - Q_RETURN_ARG(void *, voidp), - Q_ARG(QPrintEngine *, printer->printEngine())); - printInfo = static_cast<NSPrintInfo *>(voidp); - [printInfo retain]; + if (printer->outputFormat() == QPrinter::NativeFormat) { + // get the NSPrintInfo from the print engine in the platform plugin + void *voidp = 0; + (void) QMetaObject::invokeMethod(qApp->platformNativeInterface(), + "NSPrintInfoForPrintEngine", + Q_RETURN_ARG(void *, voidp), + Q_ARG(QPrintEngine *, printer->printEngine())); + printInfo = static_cast<NSPrintInfo *>(voidp); + [printInfo retain]; + } else { + printInfo = [NSPrintInfo.sharedPrintInfo retain]; + } // It seems the only way that PM lets you use all is if the minimum // for the page range is 1. This _kind of_ makes sense if you think about @@ -269,31 +289,15 @@ void QPrintDialogPrivate::closeCocoaPrintPanel() printPanel = 0; } -static bool warnIfNotNative(QPrinter *printer) -{ - if (printer->outputFormat() != QPrinter::NativeFormat) { - qWarning("QPrintDialog: Cannot be used on non-native printers"); - return false; - } - return true; -} - - QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent) : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent) { - Q_D(QPrintDialog); - if (!warnIfNotNative(d->printer)) - return; setAttribute(Qt::WA_DontShowOnScreen); } QPrintDialog::QPrintDialog(QWidget *parent) : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent) { - Q_D(QPrintDialog); - if (!warnIfNotNative(d->printer)) - return; setAttribute(Qt::WA_DontShowOnScreen); } @@ -304,8 +308,6 @@ QPrintDialog::~QPrintDialog() int QPrintDialog::exec() { Q_D(QPrintDialog); - if (!warnIfNotNative(d->printer)) - return QDialog::Rejected; QDialog::setVisible(true); |