mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add some UI to edit the book details CSS
This commit is contained in:
parent
286f69bf9d
commit
a37805bdc9
@ -36,7 +36,6 @@ from calibre.utils.serialize import json_loads
|
|||||||
from polyglot.binary import from_hex_bytes
|
from polyglot.binary import from_hex_bytes
|
||||||
from polyglot.builtins import unicode_type
|
from polyglot.builtins import unicode_type
|
||||||
|
|
||||||
_css = None
|
|
||||||
InternetSearch = namedtuple('InternetSearch', 'author where')
|
InternetSearch = namedtuple('InternetSearch', 'author where')
|
||||||
|
|
||||||
|
|
||||||
@ -53,12 +52,13 @@ def set_html(mi, html, text_browser):
|
|||||||
text_browser.setHtml(html)
|
text_browser.setHtml(html)
|
||||||
|
|
||||||
|
|
||||||
def css():
|
def css(reset=False):
|
||||||
global _css
|
if reset:
|
||||||
if _css is None:
|
del css.ans
|
||||||
|
if not hasattr(css, 'ans'):
|
||||||
val = P('templates/book_details.css', data=True).decode('utf-8')
|
val = P('templates/book_details.css', data=True).decode('utf-8')
|
||||||
_css = re.sub(unicode_type(r'/\*.*?\*/'), '', val, flags=re.DOTALL)
|
css.ans = re.sub(unicode_type(r'/\*.*?\*/'), '', val, flags=re.DOTALL)
|
||||||
return _css
|
return css.ans
|
||||||
|
|
||||||
|
|
||||||
def copy_all(text_browser):
|
def copy_all(text_browser):
|
||||||
|
@ -37,6 +37,7 @@ from calibre.gui2.preferences.coloring import EditRules
|
|||||||
from calibre.gui2.library.alternate_views import auto_height, CM_TO_INCH
|
from calibre.gui2.library.alternate_views import auto_height, CM_TO_INCH
|
||||||
from calibre.gui2.widgets2 import Dialog
|
from calibre.gui2.widgets2 import Dialog
|
||||||
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
|
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
|
||||||
|
from calibre.utils.resources import set_data
|
||||||
from polyglot.builtins import iteritems, unicode_type, map
|
from polyglot.builtins import iteritems, unicode_type, map
|
||||||
|
|
||||||
|
|
||||||
@ -571,6 +572,11 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100)
|
self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100)
|
||||||
self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio)
|
self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio)
|
||||||
self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio)
|
self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio)
|
||||||
|
self.opt_book_details_css.textChanged.connect(self.changed_signal)
|
||||||
|
from calibre.gui2.tweak_book.editor.text import get_highlighter, get_theme
|
||||||
|
self.css_highlighter = get_highlighter('css')()
|
||||||
|
self.css_highlighter.apply_theme(get_theme(None))
|
||||||
|
self.css_highlighter.set_document(self.opt_book_details_css.document())
|
||||||
|
|
||||||
def choose_icon_theme(self):
|
def choose_icon_theme(self):
|
||||||
from calibre.gui2.icon_theme import ChooseTheme
|
from calibre.gui2.icon_theme import ChooseTheme
|
||||||
@ -643,6 +649,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.set_cg_color(gprefs['cover_grid_color'])
|
self.set_cg_color(gprefs['cover_grid_color'])
|
||||||
self.set_cg_texture(gprefs['cover_grid_texture'])
|
self.set_cg_texture(gprefs['cover_grid_texture'])
|
||||||
self.update_aspect_ratio()
|
self.update_aspect_ratio()
|
||||||
|
self.opt_book_details_css.blockSignals(True)
|
||||||
|
self.opt_book_details_css.setPlainText(P('templates/book_details.css', data=True).decode('utf-8'))
|
||||||
|
self.opt_book_details_css.blockSignals(False)
|
||||||
|
|
||||||
def open_cg_cache(self):
|
def open_cg_cache(self):
|
||||||
open_local_file(self.gui.grid_view.thumbnail_cache.location)
|
open_local_file(self.gui.grid_view.thumbnail_cache.location)
|
||||||
@ -691,6 +700,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
||||||
self.set_cg_texture(gprefs.defaults['cover_grid_texture'])
|
self.set_cg_texture(gprefs.defaults['cover_grid_texture'])
|
||||||
|
self.opt_book_details_css.setPlainText(P('templates/book_details.css', allow_user_override=False, data=True).decode('utf-8'))
|
||||||
|
|
||||||
def change_cover_grid_color(self):
|
def change_cover_grid_color(self):
|
||||||
col = QColorDialog.getColor(self.cg_bg_widget.bcol,
|
col = QColorDialog.getColor(self.cg_bg_widget.bcol,
|
||||||
@ -763,6 +773,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.commit_icon_theme()
|
self.commit_icon_theme()
|
||||||
rr = True
|
rr = True
|
||||||
gprefs['default_author_link'] = self.default_author_link.value
|
gprefs['default_author_link'] = self.default_author_link.value
|
||||||
|
bcss = self.opt_book_details_css.toPlainText().encode('utf-8')
|
||||||
|
defcss = P('templates/book_details.css', data=True, allow_user_override=False)
|
||||||
|
if defcss == bcss:
|
||||||
|
bcss = None
|
||||||
|
set_data('templates/book_details.css', bcss)
|
||||||
|
|
||||||
return rr
|
return rr
|
||||||
|
|
||||||
def refresh_gui(self, gui):
|
def refresh_gui(self, gui):
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>843</width>
|
<width>839</width>
|
||||||
<height>580</height>
|
<height>580</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -727,57 +727,6 @@ A value of zero means calculate automatically.</string>
|
|||||||
<string>&Book details</string>
|
<string>&Book details</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout_12">
|
<layout class="QGridLayout" name="gridLayout_12">
|
||||||
<item row="3" column="0" rowspan="2">
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Select displayed metadata</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QToolButton" name="df_up_button">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Move up</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../../resources/images.qrc">
|
|
||||||
<normaloff>:/images/arrow-up.png</normaloff>:/images/arrow-up.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QToolButton" name="df_down_button">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Move down</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../../resources/images.qrc">
|
|
||||||
<normaloff>:/images/arrow-down.png</normaloff>:/images/arrow-down.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" rowspan="3">
|
|
||||||
<widget class="QListView" name="field_display_order">
|
|
||||||
<property name="alternatingRowColors">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<spacer name="verticalSpacer_5">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QHBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -822,13 +771,6 @@ A value of zero means calculate automatically.</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QPushButton" name="id_links_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Create rules to convert &identifiers into links</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QWidget" name="default_author_link_container" native="true">
|
<widget class="QWidget" name="default_author_link_container" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -839,14 +781,84 @@ A value of zero means calculate automatically.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QPushButton" name="id_links_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Note that <b>comments</b> will always be displayed at the end, regardless of the position you assign here.</string>
|
<string>Create rules to convert &identifiers into links</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
</widget>
|
||||||
<bool>true</bool>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="title">
|
||||||
|
<string>Text styling</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="opt_book_details_css"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Select displayed metadata</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QToolButton" name="df_down_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Move down</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-down.png</normaloff>:/images/arrow-down.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QToolButton" name="df_up_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Move up</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-up.png</normaloff>:/images/arrow-up.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" rowspan="3">
|
||||||
|
<widget class="QListView" name="field_display_order">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Note that <b>comments</b> will always be displayed at the end, regardless of the position you assign here.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -13,6 +13,9 @@ from calibre import config_dir
|
|||||||
from polyglot.builtins import builtins
|
from polyglot.builtins import builtins
|
||||||
|
|
||||||
|
|
||||||
|
user_dir = os.path.join(config_dir, 'resources')
|
||||||
|
|
||||||
|
|
||||||
class PathResolver(object):
|
class PathResolver(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -39,11 +42,10 @@ class PathResolver(object):
|
|||||||
self.default_path = dev_path
|
self.default_path = dev_path
|
||||||
self.using_develop_from = True
|
self.using_develop_from = True
|
||||||
|
|
||||||
user_path = os.path.join(config_dir, 'resources')
|
|
||||||
self.user_path = None
|
self.user_path = None
|
||||||
if suitable(user_path):
|
if suitable(user_dir):
|
||||||
self.locations.insert(0, user_path)
|
self.locations.insert(0, user_dir)
|
||||||
self.user_path = user_path
|
self.user_path = user_dir
|
||||||
|
|
||||||
def __call__(self, path, allow_user_override=True):
|
def __call__(self, path, allow_user_override=True):
|
||||||
path = path.replace(os.sep, '/')
|
path = path.replace(os.sep, '/')
|
||||||
@ -65,6 +67,19 @@ class PathResolver(object):
|
|||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
def set_data(self, path, data=None):
|
||||||
|
self.cache.pop((path, True), None)
|
||||||
|
fpath = os.path.join(user_dir, *path.split('/'))
|
||||||
|
if data is None:
|
||||||
|
if os.path.exists(fpath):
|
||||||
|
os.remove(fpath)
|
||||||
|
else:
|
||||||
|
base = os.path.dirname(fpath)
|
||||||
|
if not os.path.exists(base):
|
||||||
|
os.makedirs(base)
|
||||||
|
with open(fpath, 'wb') as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
|
||||||
_resolver = PathResolver()
|
_resolver = PathResolver()
|
||||||
|
|
||||||
@ -83,5 +98,9 @@ def get_image_path(path, data=False, allow_user_override=True):
|
|||||||
return get_path('images/'+path, data=data, allow_user_override=allow_user_override)
|
return get_path('images/'+path, data=data, allow_user_override=allow_user_override)
|
||||||
|
|
||||||
|
|
||||||
|
def set_data(path, data=None):
|
||||||
|
return _resolver.set_data(path, data)
|
||||||
|
|
||||||
|
|
||||||
builtins.__dict__['P'] = get_path
|
builtins.__dict__['P'] = get_path
|
||||||
builtins.__dict__['I'] = get_image_path
|
builtins.__dict__['I'] = get_image_path
|
||||||
|
Loading…
x
Reference in New Issue
Block a user