Refactor and fix printing

QWebEnginePage::print() changed to QWebEngineView with Qt 6, and emits a new
printFinished() signal instead of taking a callback. Adjust our API accordingly.

There also is a pdfPrintingFinished signal which we now use to get a bit more
feedback to the user.

TODO: Changelog entry for PDF feedback?
This commit is contained in:
Florian Bruhin 2022-05-10 17:20:47 +02:00
parent c7ea2f705f
commit 377749c76f
3 changed files with 52 additions and 28 deletions

View File

@ -225,13 +225,33 @@ class AbstractAction:
self._tab.dump_async(show_source_cb)
class AbstractPrinting:
class AbstractPrinting(QObject):
"""Attribute ``printing`` of AbstractTab for printing the page."""
def __init__(self, tab: 'AbstractTab') -> None:
printing_finished = pyqtSignal(bool)
pdf_printing_finished = pyqtSignal(str, bool) # filename, ok
def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None:
super().__init__(parent)
self._widget = cast(_WidgetType, None)
self._tab = tab
self.printing_finished.connect(self._on_printing_finished)
self.pdf_printing_finished.connect(self._on_pdf_printing_finished)
@pyqtSlot(bool)
def _on_printing_finished(self, ok):
# Only reporting error here, as the user has feedback from the dialog
# (and probably their printer) already.
if not ok:
message.error("Printing failed!")
@pyqtSlot(str, bool)
def _on_pdf_printing_finished(self, path, ok):
if ok:
message.info(f"Printed to {path}")
else:
message.error(f"Printing to {path} failed!")
def check_pdf_support(self) -> None:
"""Check whether writing to PDFs is supported.
@ -249,41 +269,28 @@ class AbstractPrinting:
"""
raise NotImplementedError
def to_pdf(self, filename: str) -> bool:
def to_pdf(self, filename: str) -> None:
"""Print the tab to a PDF with the given filename."""
raise NotImplementedError
def to_printer(self, printer: QPrinter,
callback: Callable[[bool], None] = None) -> None:
def to_printer(self, printer: QPrinter):
"""Print the tab.
Args:
printer: The QPrinter to print to.
callback: Called with a boolean
(True if printing succeeded, False otherwise)
"""
raise NotImplementedError
def show_dialog(self) -> None:
"""Print with a QPrintDialog."""
def print_callback(ok: bool) -> None:
"""Called when printing finished."""
if not ok:
message.error("Printing failed!")
diag.deleteLater()
def do_print() -> None:
"""Called when the dialog was closed."""
self.to_printer(diag.printer(), print_callback)
diag = QPrintDialog(self._tab)
if utils.is_mac:
# For some reason we get a segfault when using open() on macOS
ret = diag.exec()
if ret == QDialog.DialogCode.Accepted:
do_print()
self.to_printer(diag.printer())
else:
diag.open(do_print)
diag.open(lambda: self.to_printer(diag.printer()))
@dataclasses.dataclass

View File

@ -82,6 +82,16 @@ class WebEnginePrinting(browsertab.AbstractPrinting):
_widget: webview.WebEngineView
def connect_signals(self):
page = self._widget.page()
page.pdfPrintingFinished.connect(self.pdf_printing_finished)
try:
# Qt 6
self._widget.printFinished.connect(self.printing_finished)
except AttributeError:
# Qt 5: Uses callbacks instead
pass
def check_pdf_support(self):
pass
@ -92,8 +102,13 @@ class WebEnginePrinting(browsertab.AbstractPrinting):
def to_pdf(self, filename):
self._widget.page().printToPdf(filename)
def to_printer(self, printer, callback=lambda ok: None):
self._widget.page().print(printer, callback)
def to_printer(self, printer):
try:
# Qt 5
self._widget.page().print(printer, self.printing_finished.emit)
except AttributeError:
# Qt 6
self._widget.print(printer)
@dataclasses.dataclass
@ -1278,7 +1293,7 @@ class WebEngineTab(browsertab.AbstractTab):
tab=self, parent=self)
self.zoom = WebEngineZoom(tab=self, parent=self)
self.search = WebEngineSearch(tab=self, parent=self)
self.printing = WebEnginePrinting(tab=self)
self.printing = WebEnginePrinting(tab=self, parent=self)
self.elements = WebEngineElements(tab=self)
self.action = WebEngineAction(tab=self)
self.audio = WebEngineAudio(tab=self, parent=self)
@ -1670,5 +1685,6 @@ class WebEngineTab(browsertab.AbstractTab):
# pylint: disable=protected-access
self.audio._connect_signals()
self.search.connect_signals()
self.printing.connect_signals()
self._permissions.connect_signals()
self._scripts.connect_signals()

View File

@ -92,13 +92,14 @@ class WebKitPrinting(browsertab.AbstractPrinting):
def to_pdf(self, filename):
printer = QPrinter()
printer.setOutputFileName(filename)
self.to_printer(printer)
def to_printer(self, printer, callback=None):
self._widget.print(printer)
# Can't find out whether there was an error...
if callback is not None:
callback(True)
self.pdf_printing_finished.emit(filename, True)
def to_printer(self, printer):
self._widget.print(printer)
# Can't find out whether there was an error...
self.printing_finished.emit(True)
class WebKitSearch(browsertab.AbstractSearch):
@ -881,7 +882,7 @@ class WebKitTab(browsertab.AbstractTab):
tab=self, parent=self)
self.zoom = WebKitZoom(tab=self, parent=self)
self.search = WebKitSearch(tab=self, parent=self)
self.printing = WebKitPrinting(tab=self)
self.printing = WebKitPrinting(tab=self, parent=self)
self.elements = WebKitElements(tab=self)
self.action = WebKitAction(tab=self)
self.audio = WebKitAudio(tab=self, parent=self)