mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit book: Allow customizing the base background/foreground and link colors for the preview window. Fixes #1889925 [[Enhancement] Editor Preview customise background colour](https://bugs.launchpad.net/calibre/+bug/1889925)
This commit is contained in:
parent
95c4381900
commit
716db6162b
@ -38,6 +38,9 @@ d['preview_standard_font_family'] = 'serif'
|
||||
d['preview_base_font_size'] = 18
|
||||
d['preview_mono_font_size'] = 14
|
||||
d['preview_minimum_font_size'] = 8
|
||||
d['preview_background'] = 'auto'
|
||||
d['preview_foreground'] = 'auto'
|
||||
d['preview_link_color'] = 'auto'
|
||||
d['remove_existing_links_when_linking_sheets'] = True
|
||||
d['charmap_favorites'] = list(map(ord, '\xa0\u2002\u2003\u2009\xad' '‘’“”‹›«»‚„' '—–§¶†‡©®™' '→⇒•·°±−×÷¼½½¾' '…µ¢£€¿¡¨´¸ˆ˜' 'ÀÁÂÃÄÅÆÇÈÉÊË' 'ÌÍÎÏÐÑÒÓÔÕÖØ' 'ŒŠÙÚÛÜÝŸÞßàá' 'âãäåæçèéêëìí' 'îïðñòóôõöøœš' 'ùúûüýÿþªºαΩ∞')) # noqa
|
||||
d['folders_for_types'] = {'style':'styles', 'image':'images', 'font':'fonts', 'audio':'audio', 'video':'video'}
|
||||
|
@ -207,6 +207,7 @@ class Boss(QObject):
|
||||
setup_css_parser_serialization()
|
||||
self.gui.apply_settings()
|
||||
self.refresh_file_list()
|
||||
self.gui.preview.start_refresh_timer()
|
||||
if ret == p.Accepted or p.dictionaries_changed:
|
||||
for ed in itervalues(editors):
|
||||
ed.apply_settings(dictionaries_changed=p.dictionaries_changed)
|
||||
|
@ -19,7 +19,7 @@ from PyQt5.Qt import (
|
||||
QListWidgetItem, QIcon, QWidget, QSize, QFormLayout, Qt, QSpinBox,
|
||||
QCheckBox, pyqtSignal, QDoubleSpinBox, QComboBox, QLabel, QFont, QApplication,
|
||||
QFontComboBox, QPushButton, QSizePolicy, QHBoxLayout, QGroupBox,
|
||||
QToolButton, QVBoxLayout, QSpacerItem, QTimer)
|
||||
QToolButton, QVBoxLayout, QSpacerItem, QTimer, QRadioButton)
|
||||
|
||||
from calibre import prepare_string_for_xml
|
||||
from calibre.utils.localization import get_lang
|
||||
@ -30,6 +30,7 @@ from calibre.gui2.tweak_book.editor.themes import default_theme, all_theme_names
|
||||
from calibre.gui2.tweak_book.spell import ManageDictionaries
|
||||
from calibre.gui2.font_family_chooser import FontFamilyChooser
|
||||
from calibre.gui2.tweak_book.widgets import Dialog
|
||||
from calibre.gui2.widgets2 import ColorButton
|
||||
|
||||
|
||||
class BasicSettings(QWidget): # {{{
|
||||
@ -154,7 +155,7 @@ class BasicSettings(QWidget): # {{{
|
||||
# }}}
|
||||
|
||||
|
||||
class EditorSettings(BasicSettings):
|
||||
class EditorSettings(BasicSettings): # {{{
|
||||
|
||||
def __init__(self, parent=None):
|
||||
BasicSettings.__init__(self, parent)
|
||||
@ -269,9 +270,10 @@ class EditorSettings(BasicSettings):
|
||||
s.setter(s.widget, current_val)
|
||||
if d.theme_name:
|
||||
s.setter(s.widget, d.theme_name)
|
||||
# }}}
|
||||
|
||||
|
||||
class IntegrationSettings(BasicSettings):
|
||||
class IntegrationSettings(BasicSettings): # {{{
|
||||
|
||||
def __init__(self, parent=None):
|
||||
BasicSettings.__init__(self, parent)
|
||||
@ -293,9 +295,10 @@ class IntegrationSettings(BasicSettings):
|
||||
order.setToolTip(_('When auto-selecting the format to edit for a book with'
|
||||
' multiple formats, this is the preference order.'))
|
||||
l.addRow(_('Preferred format order (drag and drop to change)'), order)
|
||||
# }}}
|
||||
|
||||
|
||||
class MainWindowSettings(BasicSettings):
|
||||
class MainWindowSettings(BasicSettings): # {{{
|
||||
|
||||
def __init__(self, parent=None):
|
||||
BasicSettings.__init__(self, parent)
|
||||
@ -334,9 +337,10 @@ class MainWindowSettings(BasicSettings):
|
||||
' multiple files with the same file name.'
|
||||
))
|
||||
l.addRow(nd)
|
||||
# }}}
|
||||
|
||||
|
||||
class PreviewSettings(BasicSettings):
|
||||
class PreviewSettings(BasicSettings): # {{{
|
||||
|
||||
def __init__(self, parent=None):
|
||||
BasicSettings.__init__(self, parent)
|
||||
@ -377,6 +381,51 @@ class PreviewSettings(BasicSettings):
|
||||
w = self('preview_minimum_font_size')
|
||||
w.setMinimum(4), w.setMaximum(100), w.setSuffix(' px')
|
||||
l.addRow(_('Mi&nimum font size:'), w)
|
||||
l.addRow(_('Background color:'), self.color_override('preview_background'))
|
||||
l.addRow(_('Foreground color:'), self.color_override('preview_foreground'))
|
||||
l.addRow(_('Link color:'), self.color_override('preview_link_color'))
|
||||
|
||||
def color_override(self, name):
|
||||
w = QWidget(self)
|
||||
l = QHBoxLayout(w)
|
||||
|
||||
def b(name, text, tt):
|
||||
ans = QRadioButton(text, w)
|
||||
l.addWidget(ans)
|
||||
ans.setToolTip(tt)
|
||||
setattr(w, name, ans)
|
||||
ans.setObjectName(name)
|
||||
return ans
|
||||
|
||||
b('unset', _('No change'), _('Use the colors from the book styles, defaulting to black-on-white'))
|
||||
b('auto', _('Theme based'), _('When using a dark theme force dark colors, otherwise same as "No change"'))
|
||||
b('manual', _('Custom'), _('Choose a custom color'))
|
||||
|
||||
c = w.color_button = ColorButton(parent=w)
|
||||
l.addWidget(c)
|
||||
connect_lambda(c.clicked, w, lambda w: w.manual.setChecked(True))
|
||||
|
||||
def getter(w):
|
||||
if w.unset.isChecked():
|
||||
return 'unset'
|
||||
if w.auto.isChecked():
|
||||
return 'auto'
|
||||
return w.color_button.color or 'auto'
|
||||
|
||||
def setter(w, val):
|
||||
val = val or 'auto'
|
||||
if val == 'unset':
|
||||
w.unset.setChecked(True)
|
||||
elif val == 'auto':
|
||||
w.auto.setChecked(True)
|
||||
else:
|
||||
w.manual.setChecked(True)
|
||||
w.color_button.color = val
|
||||
self(name, widget=w, getter=getter, setter=setter)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
return w
|
||||
# }}}
|
||||
|
||||
|
||||
# ToolbarSettings {{{
|
||||
|
||||
|
@ -26,7 +26,7 @@ from calibre.constants import (
|
||||
from calibre.ebooks.oeb.base import OEB_DOCS, XHTML_MIME, serialize
|
||||
from calibre.ebooks.oeb.polish.parsing import parse
|
||||
from calibre.gui2 import NO_URL_FORMATTING, error_dialog, is_dark_theme, open_url
|
||||
from calibre.gui2.palette import dark_color, dark_text_color
|
||||
from calibre.gui2.palette import dark_color, dark_link_color, dark_text_color
|
||||
from calibre.gui2.tweak_book import TOP, actions, current_container, editors, tprefs
|
||||
from calibre.gui2.tweak_book.file_list import OpenWithHandler
|
||||
from calibre.gui2.viewer.web_view import handle_mathjax_request, send_reply
|
||||
@ -251,30 +251,35 @@ def create_profile():
|
||||
create_script('csscolorparser.js', cparser),
|
||||
create_script('editor.js', js),
|
||||
create_script('dark-mode.js', '''
|
||||
(function() {if (%s) {
|
||||
var dark_bg = "%s", dark_fg = "%s", css = %s;
|
||||
(function() {
|
||||
var settings = JSON.parse(navigator.userAgent.split('|')[1]);
|
||||
var dark_css = CSS;
|
||||
|
||||
function apply_body_colors(event) {
|
||||
if (document.documentElement) {
|
||||
if (settings.bg) document.documentElement.style.backgroundColor = settings.bg;
|
||||
if (settings.fg) document.documentElement.style.color = settings.fg;
|
||||
}
|
||||
if (document.body) {
|
||||
if (settings.bg) document.body.style.backgroundColor = settings.bg;
|
||||
if (settings.fg) document.body.style.color = settings.fg;
|
||||
}
|
||||
}
|
||||
|
||||
function apply_css() {
|
||||
var css = '';
|
||||
if (settings.link) css += 'html > body :link, html > body :link * { color: ' + settings.link + ' !important; }';
|
||||
if (settings.is_dark_theme) { css += dark_css; }
|
||||
var style = document.createElement('style');
|
||||
style.textContent = css;
|
||||
document.documentElement.appendChild(style);
|
||||
apply_body_colors();
|
||||
}
|
||||
|
||||
function apply_dark_mode(event) {
|
||||
if (document.documentElement) {
|
||||
document.documentElement.style.backgroundColor = dark_bg;
|
||||
document.documentElement.style.color = dark_fg;
|
||||
}
|
||||
if (document.body) {
|
||||
document.body.style.backgroundColor = dark_bg;
|
||||
document.body.style.color = dark_fg;
|
||||
}
|
||||
}
|
||||
apply_dark_mode();
|
||||
apply_body_colors();
|
||||
document.addEventListener("DOMContentLoaded", apply_css);
|
||||
document.addEventListener("DOMContentLoaded", apply_dark_mode);
|
||||
} })();
|
||||
''' % (
|
||||
'true' if is_dark_theme() else 'false', dark_color.name(), dark_text_color.name(), json.dumps(dark_mode_css)),
|
||||
})();
|
||||
'''.replace('CSS', json.dumps(dark_mode_css), 1),
|
||||
injection_point=QWebEngineScript.DocumentCreation)
|
||||
)
|
||||
url_handler = UrlSchemeHandler(ans)
|
||||
@ -392,10 +397,37 @@ class WebView(RestartingWebEngineView, OpenWithHandler):
|
||||
def sizeHint(self):
|
||||
return self._size_hint
|
||||
|
||||
def update_settings(self):
|
||||
dark = is_dark_theme()
|
||||
|
||||
def get_color(name, dark_val):
|
||||
ans = tprefs[name]
|
||||
if ans == 'auto' and dark:
|
||||
ans = dark_val.name()
|
||||
if ans in ('auto', 'unset'):
|
||||
return None
|
||||
return ans
|
||||
|
||||
settings = {
|
||||
'is_dark_theme': dark,
|
||||
'bg': get_color('preview_background', dark_color),
|
||||
'fg': get_color('preview_foreground', dark_text_color),
|
||||
'link': get_color('preview_link_color', dark_link_color),
|
||||
}
|
||||
p = self._page.profile()
|
||||
ua = p.httpUserAgent().split('|')[0] + '|' + json.dumps(settings)
|
||||
p.setHttpUserAgent(ua)
|
||||
|
||||
def refresh(self):
|
||||
self.update_settings()
|
||||
self.pageAction(QWebEnginePage.ReloadAndBypassCache).trigger()
|
||||
|
||||
def set_url(self, qurl):
|
||||
self.update_settings()
|
||||
RestartingWebEngineView.setUrl(self, qurl)
|
||||
|
||||
def clear(self):
|
||||
self.update_settings()
|
||||
self.setHtml(_(
|
||||
'''
|
||||
<h3>Live preview</h3>
|
||||
@ -612,7 +644,7 @@ class Preview(QWidget):
|
||||
self.current_name = name
|
||||
self.report_worker_launch_error()
|
||||
parse_worker.add_request(name)
|
||||
self.view.setUrl(self.name_to_qurl())
|
||||
self.view.set_url(self.name_to_qurl())
|
||||
return True
|
||||
|
||||
def refresh(self):
|
||||
@ -627,7 +659,7 @@ class Preview(QWidget):
|
||||
self.refresh_starting.emit()
|
||||
if current_url != self.view.url():
|
||||
# The container was changed
|
||||
self.view.setUrl(current_url)
|
||||
self.view.set_url(current_url)
|
||||
else:
|
||||
self.view.refresh()
|
||||
self.refreshed.emit()
|
||||
|
Loading…
x
Reference in New Issue
Block a user