Add printing to tab API
This fixes printing for QtWebKit, and hopefully will make printing to PDF work with QtWebEngine with Qt >= 5.7
This commit is contained in:
parent
7a39021d41
commit
cd4eff364a
@ -24,6 +24,7 @@ import itertools
|
|||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QPoint
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QPoint
|
||||||
from PyQt5.QtGui import QIcon
|
from PyQt5.QtGui import QIcon
|
||||||
from PyQt5.QtWidgets import QWidget, QLayout
|
from PyQt5.QtWidgets import QWidget, QLayout
|
||||||
|
from PyQt5.QtPrintSupport import QPrinter
|
||||||
|
|
||||||
from qutebrowser.keyinput import modeman
|
from qutebrowser.keyinput import modeman
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
@ -105,6 +106,27 @@ class TabData:
|
|||||||
self.inspector = None
|
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):
|
class AbstractSearch(QObject):
|
||||||
|
|
||||||
"""Attribute of AbstractTab for doing searches.
|
"""Attribute of AbstractTab for doing searches.
|
||||||
@ -468,6 +490,7 @@ class AbstractTab(QWidget):
|
|||||||
# parent=self)
|
# parent=self)
|
||||||
# self.zoom = AbstractZoom(win_id=win_id)
|
# self.zoom = AbstractZoom(win_id=win_id)
|
||||||
# self.search = AbstractSearch(parent=self)
|
# self.search = AbstractSearch(parent=self)
|
||||||
|
# self.printing = AbstractPrinting()
|
||||||
self.data = TabData()
|
self.data = TabData()
|
||||||
self._layout = None
|
self._layout = None
|
||||||
self._widget = None
|
self._widget = None
|
||||||
@ -485,6 +508,7 @@ class AbstractTab(QWidget):
|
|||||||
self.caret._widget = widget
|
self.caret._widget = widget
|
||||||
self.zoom._widget = widget
|
self.zoom._widget = widget
|
||||||
self.search._widget = widget
|
self.search._widget = widget
|
||||||
|
self.printing._widget = widget
|
||||||
widget.mouse_wheel_zoom.connect(self.zoom._on_mouse_wheel_zoom)
|
widget.mouse_wheel_zoom.connect(self.zoom._on_mouse_wheel_zoom)
|
||||||
widget.setParent(self)
|
widget.setParent(self)
|
||||||
self.setFocusProxy(widget)
|
self.setFocusProxy(widget)
|
||||||
|
@ -28,7 +28,7 @@ import functools
|
|||||||
from PyQt5.QtWidgets import QApplication, QTabBar
|
from PyQt5.QtWidgets import QApplication, QTabBar
|
||||||
from PyQt5.QtCore import Qt, QUrl, QEvent
|
from PyQt5.QtCore import Qt, QUrl, QEvent
|
||||||
from PyQt5.QtGui import QKeyEvent
|
from PyQt5.QtGui import QKeyEvent
|
||||||
from PyQt5.QtPrintSupport import QPrintDialog, QPrinter, QPrintPreviewDialog
|
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
|
||||||
from PyQt5.QtWebKitWidgets import QWebPage
|
from PyQt5.QtWebKitWidgets import QWebPage
|
||||||
try:
|
try:
|
||||||
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
||||||
@ -308,33 +308,37 @@ class CommandDispatcher:
|
|||||||
count: The tab index to print, or None.
|
count: The tab index to print, or None.
|
||||||
pdf: The file path to write the PDF to.
|
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)
|
tab = self._cntwidget(count)
|
||||||
if tab is not None:
|
if tab is None:
|
||||||
if preview:
|
return
|
||||||
diag = QPrintPreviewDialog()
|
|
||||||
diag.setAttribute(Qt.WA_DeleteOnClose)
|
try:
|
||||||
diag.setWindowFlags(diag.windowFlags() |
|
if pdf:
|
||||||
Qt.WindowMaximizeButtonHint |
|
tab.printing.check_pdf_support()
|
||||||
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))
|
|
||||||
else:
|
else:
|
||||||
diag = QPrintDialog()
|
tab.printing.check_printer_support()
|
||||||
diag.setAttribute(Qt.WA_DeleteOnClose)
|
except browsertab.WebTabError as e:
|
||||||
diag.open(lambda: tab.print(diag.printer()))
|
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')
|
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||||
def tab_clone(self, bg=False, window=False):
|
def tab_clone(self, bg=False, window=False):
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint
|
from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint
|
||||||
from PyQt5.QtGui import QKeyEvent, QIcon
|
from PyQt5.QtGui import QKeyEvent, QIcon
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
from PyQt5.QtPrintSupport import QPrinter
|
||||||
# pylint: disable=no-name-in-module,import-error,useless-suppression
|
# pylint: disable=no-name-in-module,import-error,useless-suppression
|
||||||
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
||||||
# pylint: enable=no-name-in-module,import-error,useless-suppression
|
# pylint: enable=no-name-in-module,import-error,useless-suppression
|
||||||
@ -34,6 +35,28 @@ from qutebrowser.browser.webengine import webview
|
|||||||
from qutebrowser.utils import usertypes, qtutils, log
|
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):
|
class WebEngineSearch(browsertab.AbstractSearch):
|
||||||
|
|
||||||
"""QtWebEngine implementations related to searching on the page."""
|
"""QtWebEngine implementations related to searching on the page."""
|
||||||
@ -256,6 +279,7 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
tab=self, parent=self)
|
tab=self, parent=self)
|
||||||
self.zoom = WebEngineZoom(win_id=win_id, parent=self)
|
self.zoom = WebEngineZoom(win_id=win_id, parent=self)
|
||||||
self.search = WebEngineSearch(parent=self)
|
self.search = WebEngineSearch(parent=self)
|
||||||
|
self.printing = WebEnginePrinting()
|
||||||
self._set_widget(widget)
|
self._set_widget(widget)
|
||||||
self._connect_signals()
|
self._connect_signals()
|
||||||
self.backend = usertypes.Backend.QtWebEngine
|
self.backend = usertypes.Backend.QtWebEngine
|
||||||
|
@ -27,12 +27,39 @@ from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QUrl, QPoint, QTimer
|
|||||||
from PyQt5.QtGui import QKeyEvent
|
from PyQt5.QtGui import QKeyEvent
|
||||||
from PyQt5.QtWebKitWidgets import QWebPage
|
from PyQt5.QtWebKitWidgets import QWebPage
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
|
from PyQt5.QtPrintSupport import QPrinter
|
||||||
|
|
||||||
from qutebrowser.browser import browsertab
|
from qutebrowser.browser import browsertab
|
||||||
from qutebrowser.browser.webkit import webview, tabhistory
|
from qutebrowser.browser.webkit import webview, tabhistory
|
||||||
from qutebrowser.utils import qtutils, objreg, usertypes, utils
|
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):
|
class WebKitSearch(browsertab.AbstractSearch):
|
||||||
|
|
||||||
"""QtWebKit implementations related to searching on the page."""
|
"""QtWebKit implementations related to searching on the page."""
|
||||||
@ -461,6 +488,7 @@ class WebKitTab(browsertab.AbstractTab):
|
|||||||
tab=self, parent=self)
|
tab=self, parent=self)
|
||||||
self.zoom = WebKitZoom(win_id=win_id, parent=self)
|
self.zoom = WebKitZoom(win_id=win_id, parent=self)
|
||||||
self.search = WebKitSearch(parent=self)
|
self.search = WebKitSearch(parent=self)
|
||||||
|
self.printing = WebKitPrinting()
|
||||||
self._set_widget(widget)
|
self._set_widget(widget)
|
||||||
self._connect_signals()
|
self._connect_signals()
|
||||||
self.zoom.set_default()
|
self.zoom.set_default()
|
||||||
|
@ -77,6 +77,7 @@ def test_tab(qtbot, view, config_stub, tab_registry):
|
|||||||
tab=tab_w, parent=tab_w)
|
tab=tab_w, parent=tab_w)
|
||||||
tab_w.zoom = browsertab.AbstractZoom(win_id=tab_w.win_id)
|
tab_w.zoom = browsertab.AbstractZoom(win_id=tab_w.win_id)
|
||||||
tab_w.search = browsertab.AbstractSearch(parent=tab_w)
|
tab_w.search = browsertab.AbstractSearch(parent=tab_w)
|
||||||
|
tab_w.printing = browsertab.AbstractPrinting()
|
||||||
|
|
||||||
tab_w._set_widget(w)
|
tab_w._set_widget(w)
|
||||||
assert tab_w._widget is w
|
assert tab_w._widget is w
|
||||||
|
Loading…
Reference in New Issue
Block a user