--- a/WebBrowser/WebBrowserTabWidget.py Tue Sep 27 19:41:11 2016 +0200 +++ b/WebBrowser/WebBrowserTabWidget.py Wed Sep 28 20:04:44 2016 +0200 @@ -11,10 +11,11 @@ import os -from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QFile, qVersion +from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QDir, QFile, \ + QFileDevice, QTemporaryFile, qVersion from PyQt5.QtGui import QIcon, QPixmap, QPainter from PyQt5.QtWidgets import QWidget, QHBoxLayout, QMenu, QToolButton, QDialog -from PyQt5.QtPrintSupport import QPrinter, QPrintDialog +from PyQt5.QtPrintSupport import QPrinter, QPrintDialog, QAbstractPrintDialog from E5Gui.E5TabWidget import E5TabWidget from E5Gui import E5MessageBox @@ -23,6 +24,7 @@ from .WebBrowserView import WebBrowserView from .WebBrowserPage import WebBrowserPage from .Tools import WebBrowserTools +from .Tools import FilePrinter from . import WebInspector import UI.PixmapCache @@ -150,6 +152,8 @@ self.__initTabContextMenu() self.__historyCompleter = None + + self.__pdfPrinter = None def __initTabContextMenu(self): """ @@ -179,11 +183,11 @@ self.__tabContextMenu.addAction( self.tr('Close All'), self.closeAllBrowsers) self.__tabContextMenu.addSeparator() - if not Globals.isWindowsPlatform(): - # TODO: implement printing based on printToPdf() + if not Globals.isWindowsPlatform() and qVersion() < "5.7.0": self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("printPreview.png"), self.tr('Print Preview'), self.__tabContextMenuPrintPreview) + if not Globals.isWindowsPlatform() or qVersion() >= "5.7.0": self.__tabContextMenu.addAction( UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__tabContextMenuPrint) @@ -624,10 +628,32 @@ if printerName: printer.setPrinterName(printerName) printer.setResolution(Preferences.getPrinter("Resolution")) + documentName = WebBrowserTools.getFileNameFromUrl(browser.url()) + printer.setDocName(documentName) printDialog = QPrintDialog(printer, self) + printDialog.setOptions(QAbstractPrintDialog.PrintToFile | + QAbstractPrintDialog.PrintShowPageSize) + if not Globals.isWindowsPlatform(): + if FilePrinter.isCupsAvailable(): + printDialog.setOption(QAbstractPrintDialog.PrintCollateCopies) + printDialog.setOption(QAbstractPrintDialog.PrintPageRange) if printDialog.exec_() == QDialog.Accepted: - browser.render(printer) + if not hasattr(browser.page(), "printToPdf"): + browser.render(printer) + else: + if printer.outputFormat() == QPrinter.PdfFormat: + # print to PDF file selected + browser.page().printToPdf( + lambda pdf: self.__pdfGeneratedForSave( + printer.outputFileName(), pdf), + printer.pageLayout()) + else: + # print to printer + self.__pdfPrinter = printer + browser.page().printToPdf( + self.__pdfGeneratedForPrinting, + printer.pageLayout()) @pyqtSlot() def printBrowserPdf(self, browser=None): @@ -652,20 +678,20 @@ filePath, pageLayout = dlg.getData() if filePath: if os.path.exists(filePath): - res = E5MessageBox.warning( - self, - self.tr("Print to PDF"), + res = E5MessageBox.warning( + self, + self.tr("Print to PDF"), self.tr("""<p>The file <b>{0}</b> exists""" """ already. Shall it be""" - """ overwritten?</p>""").format(filePath), - E5MessageBox.StandardButtons( - E5MessageBox.No | - E5MessageBox.Yes), - E5MessageBox.No) + """ overwritten?</p>""").format(filePath), + E5MessageBox.StandardButtons( + E5MessageBox.No | + E5MessageBox.Yes), + E5MessageBox.No) if res == E5MessageBox.No: return browser.page().printToPdf( - lambda p: self.__pdfGenerated(filePath, p), + lambda pdf: self.__pdfGeneratedForSave(filePath, pdf), pageLayout) elif Globals.isLinuxPlatform(): printer = QPrinter(mode=QPrinter.HighResolution) @@ -685,9 +711,9 @@ if printDialog.exec_() == QDialog.Accepted: browser.render(printer) - def __pdfGenerated(self, filePath, pdfData): + def __pdfGeneratedForSave(self, filePath, pdfData): """ - Private slot handling the generated PDF data. + Private slot to save the generated PDF data to a file. @param filePath path to save the PDF to @type str @@ -698,11 +724,50 @@ return pdfFile = QFile(filePath) - if not pdfFile.open(QFile.WriteOnly): + if pdfFile.open(QFile.WriteOnly): + pdfFile.write(pdfData) + pdfFile.close() + if pdfFile.error() != QFileDevice.NoError: + E5MessageBox.critical( + self, + self.tr("Print to PDF"), + self.tr("""<p>The PDF could not be written to file <b>{0}""" + """</b>.</p><p><b>Error:</b> {1}</p>""").format( + filePath, pdfFile.errorString()), + E5MessageBox.StandardButtons( + E5MessageBox.Ok)) + + def __pdfGeneratedForPrinting(self, pdfData): + """ + Private slot to print the generated PDF data. + + @param pdfData generated PDF document + @type QByteArray + """ + if self.__pdfPrinter is None or pdfData.isEmpty(): return - pdfFile.write(pdfData) - pdfFile.close() + tempFile = QTemporaryFile(QDir.tempPath() + "/ericBrowserXXXXXX.pdf") + tempFile.setAutoRemove(False) + if tempFile.open(): + bytesWritten = tempFile.write(pdfData) + tempFile.close() + if bytesWritten == pdfData.size(): + if Globals.isWindowsPlatform(): + printerName = self.__pdfPrinter.printerName() + import ctypes + ctypes.windll.shell32.ShellExecuteW( + self.winId(), "printto", tempFile.fileName(), + '"{0}"'.format(printerName), None, 0) + else: + FilePrinter.printFile( + self.__pdfPrinter, tempFile.fileName(), + FilePrinter.FilePrinter.SystemDeletesFiles, + FilePrinter.FilePrinter.SystemSelectsPages) + else: + tempFile.remove() + + self.__pdfPrinter = None @pyqtSlot() def printPreviewBrowser(self, browser=None):