Fix #396
Use a QWebEngineView if QtWebEngine is available. If QtWebEngine is not available replace figure tags with div's to allow the QTextEdit to render the rest of the html properly
This commit is contained in:
parent
19986b64d0
commit
f43f51aa2f
@ -63,6 +63,14 @@ try:
|
||||
qt_exception_hook = UncaughtHook()
|
||||
from comictaggerlib.taggerwindow import TaggerWindow
|
||||
|
||||
try:
|
||||
# needed here to initialize QWebEngine
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView # noqa: F401
|
||||
|
||||
qt_webengine_available = True
|
||||
except ImportError:
|
||||
qt_webengine_available = False
|
||||
|
||||
class Application(QtWidgets.QApplication):
|
||||
openFileRequest = QtCore.pyqtSignal(QtCore.QUrl, name="openfileRequest")
|
||||
|
||||
|
@ -23,7 +23,7 @@ from comicapi.issuestring import IssueString
|
||||
from comictaggerlib.coverimagewidget import CoverImageWidget
|
||||
from comictaggerlib.ctsettings import ct_ns
|
||||
from comictaggerlib.ui import ui_path
|
||||
from comictaggerlib.ui.qtutils import reduce_widget_font_size
|
||||
from comictaggerlib.ui.qtutils import new_web_view, reduce_widget_font_size
|
||||
from comictalker.comictalker import ComicTalker, TalkerError
|
||||
from comictalker.resulttypes import ComicIssue
|
||||
|
||||
@ -58,6 +58,19 @@ class IssueSelectionWindow(QtWidgets.QDialog):
|
||||
gridlayout.addWidget(self.coverWidget)
|
||||
gridlayout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.teDescription: QtWidgets.QWidget
|
||||
webengine = new_web_view(self)
|
||||
if webengine:
|
||||
self.teDescription.hide()
|
||||
self.teDescription.deleteLater()
|
||||
# I don't know how to replace teDescription, this is the result of teDescription.height() once rendered
|
||||
webengine.resize(webengine.width(), 141)
|
||||
self.splitter.addWidget(webengine)
|
||||
self.teDescription = webengine
|
||||
logger.info("successfully loaded QWebEngineView")
|
||||
else:
|
||||
logger.info("failed to open QWebEngineView")
|
||||
|
||||
reduce_widget_font_size(self.twList)
|
||||
reduce_widget_font_size(self.teDescription, 1)
|
||||
|
||||
@ -189,6 +202,13 @@ class IssueSelectionWindow(QtWidgets.QDialog):
|
||||
def cell_double_clicked(self, r: int, c: int) -> None:
|
||||
self.accept()
|
||||
|
||||
def set_description(self, widget: QtWidgets.QWidget, text: str) -> None:
|
||||
if isinstance(widget, QtWidgets.QTextEdit):
|
||||
widget.setText(text.replace("</figure>", "</div>").replace("<figure", "<div"))
|
||||
else:
|
||||
html = text
|
||||
widget.setHtml(html, QtCore.QUrl(self.talker.website))
|
||||
|
||||
def current_item_changed(self, curr: QtCore.QModelIndex | None, prev: QtCore.QModelIndex | None) -> None:
|
||||
if curr is None:
|
||||
return
|
||||
@ -203,8 +223,8 @@ class IssueSelectionWindow(QtWidgets.QDialog):
|
||||
self.issue_number = record.issue_number
|
||||
self.coverWidget.set_issue_details(self.issue_id, [record.image_url, *record.alt_image_urls])
|
||||
if record.description is None:
|
||||
self.teDescription.setText("")
|
||||
self.set_description(self.teDescription, "")
|
||||
else:
|
||||
self.teDescription.setText(record.description)
|
||||
self.set_description(self.teDescription, record.description)
|
||||
|
||||
break
|
||||
|
@ -20,7 +20,7 @@ import logging
|
||||
from collections import deque
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets, uic
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtCore import QUrl, pyqtSignal
|
||||
|
||||
from comicapi import utils
|
||||
from comicapi.comicarchive import ComicArchive
|
||||
@ -32,7 +32,7 @@ from comictaggerlib.issueselectionwindow import IssueSelectionWindow
|
||||
from comictaggerlib.matchselectionwindow import MatchSelectionWindow
|
||||
from comictaggerlib.progresswindow import IDProgressWindow
|
||||
from comictaggerlib.ui import ui_path
|
||||
from comictaggerlib.ui.qtutils import reduce_widget_font_size
|
||||
from comictaggerlib.ui.qtutils import new_web_view, reduce_widget_font_size
|
||||
from comictalker.comictalker import ComicTalker, TalkerError
|
||||
from comictalker.resulttypes import ComicSeries
|
||||
|
||||
@ -122,6 +122,16 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
gridlayout.addWidget(self.imageWidget)
|
||||
gridlayout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.teDetails: QtWidgets.QWidget
|
||||
webengine = new_web_view(self)
|
||||
if webengine:
|
||||
self.teDetails.hide()
|
||||
self.teDetails.deleteLater()
|
||||
# I don't know how to replace teDetails, this is the result of teDetails.height() once rendered
|
||||
webengine.resize(webengine.width(), 141)
|
||||
self.splitter.addWidget(webengine)
|
||||
self.teDetails = webengine
|
||||
|
||||
reduce_widget_font_size(self.teDetails, 1)
|
||||
reduce_widget_font_size(self.twList)
|
||||
|
||||
@ -533,6 +543,13 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
def cell_double_clicked(self, r: int, c: int) -> None:
|
||||
self.show_issues()
|
||||
|
||||
def set_description(self, widget: QtWidgets.QWidget, text: str) -> None:
|
||||
if isinstance(widget, QtWidgets.QTextEdit):
|
||||
widget.setText(text.replace("</figure>", "</div>").replace("<figure", "<div"))
|
||||
else:
|
||||
html = text
|
||||
widget.setHtml(html, QUrl(self.talker.website))
|
||||
|
||||
def current_item_changed(self, curr: QtCore.QModelIndex | None, prev: QtCore.QModelIndex | None) -> None:
|
||||
if curr is None:
|
||||
return
|
||||
@ -545,8 +562,8 @@ class SeriesSelectionWindow(QtWidgets.QDialog):
|
||||
for record in self.ct_search_results:
|
||||
if record.id == self.series_id:
|
||||
if record.description is None:
|
||||
self.teDetails.setText("")
|
||||
self.set_description(self.teDetails, "")
|
||||
else:
|
||||
self.teDetails.setText(record.description)
|
||||
self.set_description(self.teDetails, record.description)
|
||||
self.imageWidget.set_url(record.image_url)
|
||||
break
|
||||
|
@ -5,6 +5,10 @@ from __future__ import annotations
|
||||
import io
|
||||
import logging
|
||||
import traceback
|
||||
import webbrowser
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
|
||||
@ -12,6 +16,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from PyQt5 import QtGui, QtWidgets
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
qt_available = True
|
||||
except ImportError:
|
||||
@ -25,6 +30,68 @@ if qt_available:
|
||||
except ImportError:
|
||||
pil_available = False
|
||||
|
||||
try:
|
||||
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineView
|
||||
|
||||
class WebPage(QWebEnginePage):
|
||||
def acceptNavigationRequest(
|
||||
self, url: QUrl, n_type: QWebEnginePage.NavigationType, isMainFrame: bool
|
||||
) -> bool:
|
||||
if n_type in (
|
||||
QWebEnginePage.NavigationType.NavigationTypeOther,
|
||||
QWebEnginePage.NavigationType.NavigationTypeTyped,
|
||||
):
|
||||
return True
|
||||
if n_type in (QWebEnginePage.NavigationType.NavigationTypeLinkClicked,) and url.scheme() in (
|
||||
"http",
|
||||
"https",
|
||||
):
|
||||
webbrowser.open(url.toString())
|
||||
return False
|
||||
|
||||
def new_web_view(parent: QWidget) -> QWebEngineView:
|
||||
webengine = QWebEngineView(parent)
|
||||
webengine.setPage(WebPage(parent))
|
||||
webengine.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
|
||||
settings = webengine.settings()
|
||||
settings.setAttribute(settings.WebAttribute.AutoLoadImages, True)
|
||||
settings.setAttribute(settings.WebAttribute.JavascriptEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.JavascriptCanOpenWindows, False)
|
||||
settings.setAttribute(settings.WebAttribute.JavascriptCanAccessClipboard, False)
|
||||
settings.setAttribute(settings.WebAttribute.LinksIncludedInFocusChain, False)
|
||||
settings.setAttribute(settings.WebAttribute.LocalStorageEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.LocalContentCanAccessRemoteUrls, False)
|
||||
settings.setAttribute(settings.WebAttribute.XSSAuditingEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.SpatialNavigationEnabled, True)
|
||||
settings.setAttribute(settings.WebAttribute.LocalContentCanAccessFileUrls, False)
|
||||
settings.setAttribute(settings.WebAttribute.HyperlinkAuditingEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.ScrollAnimatorEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.ErrorPageEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.PluginsEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.FullScreenSupportEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.ScreenCaptureEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.WebGLEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.Accelerated2dCanvasEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.AutoLoadIconsForPage, False)
|
||||
settings.setAttribute(settings.WebAttribute.TouchIconsEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.FocusOnNavigationEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.PrintElementBackgrounds, False)
|
||||
settings.setAttribute(settings.WebAttribute.AllowRunningInsecureContent, False)
|
||||
settings.setAttribute(settings.WebAttribute.AllowGeolocationOnInsecureOrigins, False)
|
||||
settings.setAttribute(settings.WebAttribute.AllowWindowActivationFromJavaScript, False)
|
||||
settings.setAttribute(settings.WebAttribute.ShowScrollBars, True)
|
||||
settings.setAttribute(settings.WebAttribute.PlaybackRequiresUserGesture, True)
|
||||
settings.setAttribute(settings.WebAttribute.JavascriptCanPaste, False)
|
||||
settings.setAttribute(settings.WebAttribute.WebRTCPublicInterfacesOnly, False)
|
||||
settings.setAttribute(settings.WebAttribute.DnsPrefetchEnabled, False)
|
||||
settings.setAttribute(settings.WebAttribute.PdfViewerEnabled, False)
|
||||
return webengine
|
||||
|
||||
except ImportError:
|
||||
|
||||
def new_web_view(parent: QWidget) -> QWebEngineView:
|
||||
...
|
||||
|
||||
def reduce_widget_font_size(widget: QtWidgets.QWidget, delta: int = 2) -> None:
|
||||
f = widget.font()
|
||||
if f.pointSize() > 10:
|
||||
|
Loading…
Reference in New Issue
Block a user