mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Windows: Fix a regression in 7.0 that caused images referring to files on the disk within comments columns to not display in some circumstances
This commit is contained in:
parent
7e3ac04222
commit
90a0a33723
@ -1680,3 +1680,23 @@ def timed_print(*a, **kw):
|
||||
if not hasattr(timed_print, 'startup_time'):
|
||||
timed_print.startup_time = monotonic()
|
||||
print(f'[{monotonic() - timed_print.startup_time:.2f}]', *a, **kw)
|
||||
|
||||
|
||||
def local_path_for_resource(qurl: QUrl, base_qurl: 'QUrl | None' = None) -> str:
|
||||
import re
|
||||
|
||||
def fix_qt_bodging_windows_paths(path: str) -> str:
|
||||
# When loading <img src="file:///c:/path/to/img.png"> Qt gives us the
|
||||
# URL: //c/path/to/img.png Le bubbling sigh
|
||||
if iswindows and re.match(r'//[a-zA-Z]/', path) is not None and not os.path.exists(path):
|
||||
path = os.path.normpath(path[2] + ':' + path[3:])
|
||||
return path
|
||||
|
||||
if base_qurl and qurl.isRelative():
|
||||
qurl = base_qurl.resolved(qurl)
|
||||
|
||||
if qurl.isLocalFile():
|
||||
return fix_qt_bodging_windows_paths(qurl.toLocalFile())
|
||||
if qurl.isRelative(): # this means has no scheme
|
||||
return fix_qt_bodging_windows_paths(qurl.path())
|
||||
return ''
|
||||
|
@ -998,6 +998,7 @@ class BookInfo(HTMLDisplay):
|
||||
HTMLDisplay.__init__(self, parent=parent, save_resources_in_document=False)
|
||||
self.vertical = vertical
|
||||
self.last_rendered_html = '', '', ''
|
||||
self.base_url_for_current_book = None
|
||||
self.anchor_clicked.connect(self.link_activated)
|
||||
for x, icon in [
|
||||
('remove_format', 'trash.png'), ('save_format', 'save.png'),
|
||||
@ -1088,8 +1089,13 @@ class BookInfo(HTMLDisplay):
|
||||
|
||||
def show_data(self, mi):
|
||||
html, table, comments = self.last_rendered_html = render_html(mi, self.vertical, self.parent())
|
||||
path = getattr(mi, 'path', None)
|
||||
self.base_url_for_current_book = QUrl.fromLocalFile(os.path.join(path, 'metadata.opf')) if path else None
|
||||
set_html(mi, html, self)
|
||||
|
||||
def get_base_qurl(self):
|
||||
return self.base_url_for_current_book
|
||||
|
||||
def process_external_css(self, css):
|
||||
return resolve_colors(css)
|
||||
|
||||
|
@ -7,7 +7,6 @@ import re
|
||||
import sys
|
||||
import weakref
|
||||
from collections import defaultdict
|
||||
from threading import Thread
|
||||
from contextlib import contextmanager
|
||||
from functools import partial
|
||||
from html5_parser import parse
|
||||
@ -21,15 +20,16 @@ from qt.core import (
|
||||
QTextFrameFormat, QTextImageFormat, QTextListFormat, QTimer, QToolButton, QUrl,
|
||||
QVBoxLayout, QWidget, pyqtSignal, pyqtSlot,
|
||||
)
|
||||
from threading import Thread
|
||||
|
||||
from calibre import browser, fit_image, xml_replace_entities
|
||||
from calibre.constants import iswindows
|
||||
from calibre.db.constants import DATA_DIR_NAME
|
||||
from calibre.ebooks.chardet import xml_to_unicode
|
||||
from calibre.gui2 import (
|
||||
NO_URL_FORMATTING, choose_dir, choose_files, error_dialog, gprefs, is_dark_theme,
|
||||
question_dialog, safe_open_url,
|
||||
NO_URL_FORMATTING, FunctionDispatcher, choose_dir, choose_files, error_dialog,
|
||||
gprefs, is_dark_theme, local_path_for_resource, question_dialog, safe_open_url,
|
||||
)
|
||||
from calibre.gui2 import FunctionDispatcher
|
||||
from calibre.gui2.book_details import resolved_css
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
from calibre.gui2.flow_toolbar import create_flow_toolbar
|
||||
@ -38,6 +38,7 @@ from calibre.gui2.widgets2 import to_plain_text
|
||||
from calibre.startup import connect_lambda
|
||||
from calibre.utils.cleantext import clean_xml_chars
|
||||
from calibre.utils.config import tweaks
|
||||
from calibre.utils.filenames import make_long_path_useable
|
||||
from calibre.utils.imghdr import what
|
||||
from polyglot.builtins import iteritems, itervalues
|
||||
|
||||
@ -929,14 +930,11 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
|
||||
|
||||
@pyqtSlot(int, 'QUrl', result='QVariant')
|
||||
def loadResource(self, rtype, qurl):
|
||||
if self.base_url:
|
||||
if qurl.isRelative():
|
||||
qurl = self.base_url.resolved(qurl)
|
||||
if qurl.isLocalFile():
|
||||
path = local_path_for_resource(qurl, base_qurl=self.base_url)
|
||||
if path:
|
||||
data = None
|
||||
path = qurl.toLocalFile()
|
||||
try:
|
||||
with open(path, 'rb') as f:
|
||||
with open(make_long_path_useable(path), 'rb') as f:
|
||||
data = f.read()
|
||||
except OSError:
|
||||
if path.rpartition('.')[-1].lower() in {'jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'}:
|
||||
|
@ -129,6 +129,9 @@ class Details(HTMLDisplay):
|
||||
self.allow_context_menu = allow_context_menu
|
||||
self.is_locked = is_locked
|
||||
|
||||
def get_base_qurl(self):
|
||||
return getattr(self.book_info, 'base_url_for_current_book', None)
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(350, 350)
|
||||
|
||||
|
@ -16,7 +16,9 @@ from qt.core import (
|
||||
from calibre import prepare_string_for_xml
|
||||
from calibre.constants import builtin_colors_dark, builtin_colors_light
|
||||
from calibre.ebooks.metadata import rating_to_stars
|
||||
from calibre.gui2 import UNDEFINED_QDATETIME, gprefs, rating_font
|
||||
from calibre.gui2 import (
|
||||
UNDEFINED_QDATETIME, gprefs, local_path_for_resource, rating_font,
|
||||
)
|
||||
from calibre.gui2.complete2 import EditWithComplete, LineEdit
|
||||
from calibre.gui2.widgets import history
|
||||
from calibre.utils.config_base import tweaks
|
||||
@ -543,6 +545,9 @@ class HTMLDisplay(QTextBrowser):
|
||||
self.setAcceptDrops(False)
|
||||
self.anchorClicked.connect(self.on_anchor_clicked)
|
||||
|
||||
def get_base_qurl(self):
|
||||
return None
|
||||
|
||||
def setHtml(self, html):
|
||||
self.last_set_html = html
|
||||
QTextBrowser.setHtml(self, html)
|
||||
@ -573,11 +578,10 @@ class HTMLDisplay(QTextBrowser):
|
||||
return
|
||||
self.anchor_clicked.emit(qurl)
|
||||
|
||||
def loadResource(self, rtype, qurl):
|
||||
if qurl.isLocalFile():
|
||||
path = qurl.toLocalFile()
|
||||
def load_local_file_resource(self, rtype, qurl, path):
|
||||
from calibre.utils.filenames import make_long_path_useable
|
||||
try:
|
||||
with open(path, 'rb') as f:
|
||||
with open(make_long_path_useable(path), 'rb') as f:
|
||||
data = f.read()
|
||||
except OSError:
|
||||
if path.rpartition('.')[-1].lower() in {'jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'}:
|
||||
@ -595,7 +599,13 @@ class HTMLDisplay(QTextBrowser):
|
||||
if self.save_resources_in_document:
|
||||
self.document().addResource(rtype, qurl, r)
|
||||
return r
|
||||
elif qurl.scheme() == 'calibre-icon':
|
||||
return super().loadResource(rtype, qurl)
|
||||
|
||||
def loadResource(self, rtype, qurl):
|
||||
path = local_path_for_resource(qurl, base_qurl=self.get_base_qurl())
|
||||
if path:
|
||||
return self.load_local_file_resource(rtype, qurl, path)
|
||||
if qurl.scheme() == 'calibre-icon':
|
||||
r = QIcon.icon_as_png(qurl.path().lstrip('/'), as_bytearray=True)
|
||||
self.document().addResource(rtype, qurl, r)
|
||||
return r
|
||||
@ -611,7 +621,7 @@ class HTMLDisplay(QTextBrowser):
|
||||
self.document().addResource(rtype, qurl, r)
|
||||
return r
|
||||
else:
|
||||
return QTextBrowser.loadResource(self, rtype, qurl)
|
||||
return super().loadResource(rtype, qurl)
|
||||
|
||||
def anchorAt(self, pos):
|
||||
# Anchors in a document can be "focused" with the tab key.
|
||||
|
Loading…
x
Reference in New Issue
Block a user