Permalink
Browse files

Add printing to tab API

This fixes printing for QtWebKit, and hopefully will make printing to
PDF work with QtWebEngine with Qt >= 5.7
  • Loading branch information...
The-Compiler committed Jul 12, 2016
1 parent 7a39021 commit cd4eff364a841b36c6fa1653ef8f0284ab1beef0
@@ -24,6 +24,7 @@
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QPoint
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QLayout
from PyQt5.QtPrintSupport import QPrinter
from qutebrowser.keyinput import modeman
from qutebrowser.config import config
@@ -105,6 +106,27 @@ def __init__(self):
self.inspector = None
class AbstractPrinting:
"""Attribute of AbstractTab for printing the page."""
def __init__(self):
self._widget = None
def check_pdf_support(self):
raise NotImplementedError
def check_printer_support(self):
raise NotImplementedError
def to_pdf(self, filename):
raise NotImplementedError
@pyqtSlot(QPrinter)
def to_printer(self, printer):
raise NotImplementedError
class AbstractSearch(QObject):
"""Attribute of AbstractTab for doing searches.
@@ -468,6 +490,7 @@ def __init__(self, win_id, parent=None):
# parent=self)
# self.zoom = AbstractZoom(win_id=win_id)
# self.search = AbstractSearch(parent=self)
# self.printing = AbstractPrinting()
self.data = TabData()
self._layout = None
self._widget = None
@@ -485,6 +508,7 @@ def _set_widget(self, widget):
self.caret._widget = widget
self.zoom._widget = widget
self.search._widget = widget
self.printing._widget = widget
widget.mouse_wheel_zoom.connect(self.zoom._on_mouse_wheel_zoom)
widget.setParent(self)
self.setFocusProxy(widget)
@@ -28,7 +28,7 @@
from PyQt5.QtWidgets import QApplication, QTabBar
from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtPrintSupport import QPrintDialog, QPrinter, QPrintPreviewDialog
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
from PyQt5.QtWebKitWidgets import QWebPage
try:
from PyQt5.QtWebEngineWidgets import QWebEnginePage
@@ -308,33 +308,37 @@ def printpage(self, preview=False, count=None, *, pdf=None):
count: The tab index to print, or None.
pdf: The file path to write the PDF to.
"""
if not qtutils.check_print_compat():
# WORKAROUND (remove this when we bump the requirements to 5.3.0)
raise cmdexc.CommandError(
"Printing on Qt < 5.3.0 on Windows is broken, please upgrade!")
tab = self._cntwidget(count)
if tab is not None:
if preview:
diag = QPrintPreviewDialog()
diag.setAttribute(Qt.WA_DeleteOnClose)
diag.setWindowFlags(diag.windowFlags() |
Qt.WindowMaximizeButtonHint |
Qt.WindowMinimizeButtonHint)
diag.paintRequested.connect(tab.print)
diag.exec_()
elif pdf:
pdf = os.path.expanduser(pdf)
directory = os.path.dirname(pdf)
if directory and not os.path.exists(directory):
os.mkdir(directory)
printer = QPrinter()
printer.setOutputFileName(pdf)
tab.print(printer)
log.misc.debug("Print to file: {}".format(pdf))
if tab is None:
return
try:
if pdf:
tab.printing.check_pdf_support()
else:
diag = QPrintDialog()
diag.setAttribute(Qt.WA_DeleteOnClose)
diag.open(lambda: tab.print(diag.printer()))
tab.printing.check_printer_support()
except browsertab.WebTabError as e:
raise cmdexc.CommandError(e)
if preview:
diag = QPrintPreviewDialog()
diag.setAttribute(Qt.WA_DeleteOnClose)
diag.setWindowFlags(diag.windowFlags() |
Qt.WindowMaximizeButtonHint |
Qt.WindowMinimizeButtonHint)
diag.paintRequested.connect(tab.printing.to_printer)
diag.exec_()
elif pdf:
pdf = os.path.expanduser(pdf)
directory = os.path.dirname(pdf)
if directory and not os.path.exists(directory):
os.mkdir(directory)
tab.printing.to_pdf(pdf)
log.misc.debug("Print to file: {}".format(pdf))
else:
diag = QPrintDialog()
diag.setAttribute(Qt.WA_DeleteOnClose)
diag.open(lambda: tab.printing.to_printer(diag.printer()))
@cmdutils.register(instance='command-dispatcher', scope='window')
def tab_clone(self, bg=False, window=False):
@@ -25,6 +25,7 @@
from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint
from PyQt5.QtGui import QKeyEvent, QIcon
from PyQt5.QtWidgets import QApplication
from PyQt5.QtPrintSupport import QPrinter
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEnginePage
# pylint: enable=no-name-in-module,import-error,useless-suppression
@@ -34,6 +35,28 @@
from qutebrowser.utils import usertypes, qtutils, log
class WebEnginePrinting(browsertab.AbstractPrinting):
"""QtWebEngine implementations related to printing."""
def check_pdf_support(self):
if not hasattr(self._widget.page(), 'printToPdf'):
raise browsertab.WebTabError(
"Printing to PDF is unsupported with QtWebEngine on Qt > 5.7")
def check_printer_support(self):
raise browsertab.WebTabError(
"Printing is unsupported with QtWebEngine")
def to_pdf(self, filename):
self._widget.page().printToPdf(filename)
@pyqtSlot(QPrinter)
def to_printer(self, printer):
# Should never be called
assert False
class WebEngineSearch(browsertab.AbstractSearch):
"""QtWebEngine implementations related to searching on the page."""
@@ -256,6 +279,7 @@ def __init__(self, win_id, mode_manager, parent=None):
tab=self, parent=self)
self.zoom = WebEngineZoom(win_id=win_id, parent=self)
self.search = WebEngineSearch(parent=self)
self.printing = WebEnginePrinting()
self._set_widget(widget)
self._connect_signals()
self.backend = usertypes.Backend.QtWebEngine
@@ -27,12 +27,39 @@
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtPrintSupport import QPrinter
from qutebrowser.browser import browsertab
from qutebrowser.browser.webkit import webview, tabhistory
from qutebrowser.utils import qtutils, objreg, usertypes, utils
class WebKitPrinting(browsertab.AbstractPrinting):
"""QtWebKit implementations related to printing."""
def _do_check(self):
if not qtutils.check_print_compat():
# WORKAROUND (remove this when we bump the requirements to 5.3.0)
raise browsertab.WebTabError(
"Printing on Qt < 5.3.0 on Windows is broken, please upgrade!")
def check_pdf_support(self):
self._do_check()
def check_printer_support(self):
self._do_check()
def to_pdf(self, filename):
printer = QPrinter()
printer.setOutputFileName(filename)
self.to_printer(printer)
@pyqtSlot(QPrinter)
def to_printer(self, printer):
self._widget.print(printer)
class WebKitSearch(browsertab.AbstractSearch):
"""QtWebKit implementations related to searching on the page."""
@@ -461,6 +488,7 @@ def __init__(self, win_id, mode_manager, parent=None):
tab=self, parent=self)
self.zoom = WebKitZoom(win_id=win_id, parent=self)
self.search = WebKitSearch(parent=self)
self.printing = WebKitPrinting()
self._set_widget(widget)
self._connect_signals()
self.zoom.set_default()
@@ -77,6 +77,7 @@ def test_tab(qtbot, view, config_stub, tab_registry):
tab=tab_w, parent=tab_w)
tab_w.zoom = browsertab.AbstractZoom(win_id=tab_w.win_id)
tab_w.search = browsertab.AbstractSearch(parent=tab_w)
tab_w.printing = browsertab.AbstractPrinting()
tab_w._set_widget(w)
assert tab_w._widget is w

0 comments on commit cd4eff3

Please sign in to comment.