WebBrowser/WebBrowserTabWidget.py

changeset 5182
e2782c9a43d4
parent 5181
1948b27d7b21
child 5192
a10fb04f3edd
--- 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):

eric ide

mercurial