mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
move "Look & Feel/Book details" to its own widget
This commit is contained in:
parent
7622074887
commit
b32e1beaf4
@ -5,33 +5,11 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
|
||||
from qt.core import (
|
||||
QComboBox,
|
||||
QDialog,
|
||||
QDialogButtonBox,
|
||||
QFormLayout,
|
||||
QHeaderView,
|
||||
QIcon,
|
||||
QKeySequence,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QListWidgetItem,
|
||||
QPushButton,
|
||||
QSize,
|
||||
Qt,
|
||||
QTableWidget,
|
||||
QTableWidgetItem,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
pyqtSignal,
|
||||
)
|
||||
from qt.core import QIcon, QKeySequence, QListWidgetItem, Qt
|
||||
|
||||
from calibre.ebooks.metadata.book.render import DEFAULT_AUTHOR_LINK
|
||||
from calibre.ebooks.metadata.sources.prefs import msprefs
|
||||
from calibre.gui2 import config, default_author_link, error_dialog, gprefs
|
||||
from calibre.gui2 import gprefs
|
||||
from calibre.gui2.custom_column_widgets import get_field_list as em_get_field_list
|
||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
||||
from calibre.gui2.preferences.coloring import EditRules
|
||||
@ -46,187 +24,6 @@ from calibre.gui2.preferences.look_feel_tabs import (
|
||||
)
|
||||
from calibre.gui2.preferences.look_feel_ui import Ui_Form
|
||||
from calibre.gui2.widgets import BusyCursor
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
from calibre.startup import connect_lambda
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.resources import get_path as P
|
||||
from calibre.utils.resources import set_data
|
||||
from polyglot.builtins import iteritems
|
||||
|
||||
|
||||
class DefaultAuthorLink(QWidget): # {{{
|
||||
|
||||
changed_signal = pyqtSignal()
|
||||
|
||||
def __init__(self, parent):
|
||||
QWidget.__init__(self, parent)
|
||||
l = QVBoxLayout(parent)
|
||||
l.addWidget(self)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
l = QFormLayout(self)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
l.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
|
||||
self.choices = c = QComboBox()
|
||||
c.setMinimumContentsLength(30)
|
||||
for text, data in [
|
||||
(_('Search for the author on Goodreads'), 'search-goodreads'),
|
||||
(_('Search for the author on Amazon'), 'search-amzn'),
|
||||
(_('Search for the author in your calibre library'), 'search-calibre'),
|
||||
(_('Search for the author on Wikipedia'), 'search-wikipedia'),
|
||||
(_('Search for the author on Google Books'), 'search-google'),
|
||||
(_('Search for the book on Goodreads'), 'search-goodreads-book'),
|
||||
(_('Search for the book on Amazon'), 'search-amzn-book'),
|
||||
(_('Search for the book on Google Books'), 'search-google-book'),
|
||||
(_('Use a custom search URL'), 'url'),
|
||||
]:
|
||||
c.addItem(text, data)
|
||||
l.addRow(_('Clicking on &author names should:'), c)
|
||||
self.custom_url = u = QLineEdit(self)
|
||||
u.setToolTip(_(
|
||||
'Enter the URL to search. It should contain the string {0}'
|
||||
'\nwhich will be replaced by the author name. For example,'
|
||||
'\n{1}').format('{author}', 'https://en.wikipedia.org/w/index.php?search={author}'))
|
||||
u.textChanged.connect(self.changed_signal)
|
||||
u.setPlaceholderText(_('Enter the URL'))
|
||||
c.currentIndexChanged.connect(self.current_changed)
|
||||
l.addRow(u)
|
||||
self.current_changed()
|
||||
c.currentIndexChanged.connect(self.changed_signal)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
k = self.choices.currentData()
|
||||
if k == 'url':
|
||||
return self.custom_url.text()
|
||||
return k if k != DEFAULT_AUTHOR_LINK else None
|
||||
|
||||
@value.setter
|
||||
def value(self, val):
|
||||
i = self.choices.findData(val)
|
||||
if i < 0:
|
||||
i = self.choices.findData('url')
|
||||
self.custom_url.setText(val)
|
||||
self.choices.setCurrentIndex(i)
|
||||
|
||||
def current_changed(self):
|
||||
k = self.choices.currentData()
|
||||
self.custom_url.setVisible(k == 'url')
|
||||
# }}}
|
||||
|
||||
|
||||
# IdLinksEditor {{{
|
||||
class IdLinksRuleEdit(Dialog):
|
||||
|
||||
def __init__(self, key='', name='', template='', parent=None):
|
||||
title = _('Edit rule') if key else _('Create a new rule')
|
||||
Dialog.__init__(self, title=title, name='id-links-rule-editor', parent=parent)
|
||||
self.key.setText(key), self.nw.setText(name), self.template.setText(template or 'https://example.com/{id}')
|
||||
if self.size().height() < self.sizeHint().height():
|
||||
self.resize(self.sizeHint())
|
||||
|
||||
@property
|
||||
def rule(self):
|
||||
return self.key.text().lower(), self.nw.text(), self.template.text()
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QFormLayout(self)
|
||||
l.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
|
||||
l.addRow(QLabel(_(
|
||||
'The key of the identifier, for example, in isbn:XXX, the key is "isbn"')))
|
||||
self.key = k = QLineEdit(self)
|
||||
l.addRow(_('&Key:'), k)
|
||||
l.addRow(QLabel(_(
|
||||
'The name that will appear in the Book details panel')))
|
||||
self.nw = n = QLineEdit(self)
|
||||
l.addRow(_('&Name:'), n)
|
||||
la = QLabel(_(
|
||||
'The template used to create the link.'
|
||||
' The placeholder {0} in the template will be replaced'
|
||||
' with the actual identifier value. Use {1} to avoid the value'
|
||||
' being quoted.').format('{id}', '{id_unquoted}'))
|
||||
la.setWordWrap(True)
|
||||
l.addRow(la)
|
||||
self.template = t = QLineEdit(self)
|
||||
l.addRow(_('&Template:'), t)
|
||||
t.selectAll()
|
||||
t.setFocus(Qt.FocusReason.OtherFocusReason)
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def accept(self):
|
||||
r = self.rule
|
||||
for i, which in enumerate([_('Key'), _('Name'), _('Template')]):
|
||||
if not r[i]:
|
||||
return error_dialog(self, _('Value needed'), _(
|
||||
'The %s field cannot be empty') % which, show=True)
|
||||
Dialog.accept(self)
|
||||
|
||||
|
||||
class IdLinksEditor(Dialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
Dialog.__init__(self, title=_('Create rules for identifiers'), name='id-links-rules-editor', parent=parent)
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QVBoxLayout(self)
|
||||
self.la = la = QLabel(_(
|
||||
'Create rules to convert identifiers into links.'))
|
||||
la.setWordWrap(True)
|
||||
l.addWidget(la)
|
||||
items = []
|
||||
for k, lx in iteritems(msprefs['id_link_rules']):
|
||||
for n, t in lx:
|
||||
items.append((k, n, t))
|
||||
items.sort(key=lambda x: sort_key(x[1]))
|
||||
self.table = t = QTableWidget(len(items), 3, self)
|
||||
t.setHorizontalHeaderLabels([_('Key'), _('Name'), _('Template')])
|
||||
for r, (key, val, template) in enumerate(items):
|
||||
t.setItem(r, 0, QTableWidgetItem(key))
|
||||
t.setItem(r, 1, QTableWidgetItem(val))
|
||||
t.setItem(r, 2, QTableWidgetItem(template))
|
||||
l.addWidget(t)
|
||||
t.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
|
||||
self.cb = b = QPushButton(QIcon.ic('plus.png'), _('&Add rule'), self)
|
||||
connect_lambda(b.clicked, self, lambda self: self.edit_rule())
|
||||
self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.rb = b = QPushButton(QIcon.ic('minus.png'), _('&Remove rule'), self)
|
||||
connect_lambda(b.clicked, self, lambda self: self.remove_rule())
|
||||
self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.eb = b = QPushButton(QIcon.ic('modified.png'), _('&Edit rule'), self)
|
||||
connect_lambda(b.clicked, self, lambda self: self.edit_rule(self.table.currentRow()))
|
||||
self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(700, 550)
|
||||
|
||||
def accept(self):
|
||||
rules = defaultdict(list)
|
||||
for r in range(self.table.rowCount()):
|
||||
def item(c):
|
||||
return self.table.item(r, c).text()
|
||||
rules[item(0)].append([item(1), item(2)])
|
||||
msprefs['id_link_rules'] = dict(rules)
|
||||
Dialog.accept(self)
|
||||
|
||||
def edit_rule(self, r=-1):
|
||||
key = name = template = ''
|
||||
if r > -1:
|
||||
key, name, template = (self.table.item(r, c).text() for c in range(3))
|
||||
d = IdLinksRuleEdit(key, name, template, self)
|
||||
if d.exec() == QDialog.DialogCode.Accepted:
|
||||
if r < 0:
|
||||
self.table.setRowCount(self.table.rowCount() + 1)
|
||||
r = self.table.rowCount() - 1
|
||||
rule = d.rule
|
||||
for c in range(3):
|
||||
self.table.setItem(r, c, QTableWidgetItem(rule[c]))
|
||||
self.table.scrollToItem(self.table.item(r, 0))
|
||||
|
||||
def remove_rule(self):
|
||||
r = self.table.currentRow()
|
||||
if r > -1:
|
||||
self.table.removeRow(r)
|
||||
# }}}
|
||||
|
||||
|
||||
class EMDisplayedFields(DisplayedFields): # {{{
|
||||
@ -246,40 +43,6 @@ class EMDisplayedFields(DisplayedFields): # {{{
|
||||
# }}}
|
||||
|
||||
|
||||
class BDVerticalCats(DisplayedFields): # {{{
|
||||
|
||||
def __init__(self, db, parent=None, category_icons=None):
|
||||
DisplayedFields.__init__(self, db, parent, category_icons=category_icons)
|
||||
from calibre.gui2.ui import get_gui
|
||||
self.gui = get_gui()
|
||||
|
||||
def initialize(self, use_defaults=False, pref_data_override=None):
|
||||
fm = self.db.field_metadata
|
||||
cats = [k for k in fm if fm[k]['name'] and fm[k]['is_multiple'] and not k.startswith('#')]
|
||||
cats.append('path')
|
||||
cats.extend([k for k in fm if fm[k]['name'] and fm[k]['is_multiple'] and k.startswith('#')])
|
||||
ans = []
|
||||
if use_defaults:
|
||||
ans = [[k, False] for k in cats]
|
||||
self.changed = True
|
||||
elif pref_data_override:
|
||||
ph = dict(pref_data_override)
|
||||
ans = [[k, ph.get(k, False)] for k in cats]
|
||||
self.changed = True
|
||||
else:
|
||||
vertical_cats = self.db.prefs.get('book_details_vertical_categories') or ()
|
||||
for key in cats:
|
||||
ans.append([key, key in vertical_cats])
|
||||
self.beginResetModel()
|
||||
self.fields = ans
|
||||
self.endResetModel()
|
||||
|
||||
def commit(self):
|
||||
if self.changed:
|
||||
self.db.prefs.set('book_details_vertical_categories', [k for k,v in self.fields if v])
|
||||
# }}}
|
||||
|
||||
|
||||
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
|
||||
def genesis(self, gui):
|
||||
@ -289,17 +52,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
|
||||
r = self.register
|
||||
|
||||
self.default_author_link = DefaultAuthorLink(self.default_author_link_container)
|
||||
self.default_author_link.changed_signal.connect(self.changed_signal)
|
||||
r('bd_show_cover', gprefs)
|
||||
r('bd_overlay_cover_size', gprefs)
|
||||
r('book_details_comments_heading_pos', gprefs, choices=[
|
||||
(_('Never'), 'hide'), (_('Above text'), 'above'), (_('Beside text'), 'side')])
|
||||
r('book_details_note_link_icon_width', gprefs)
|
||||
self.id_links_button.clicked.connect(self.edit_id_link_rules)
|
||||
|
||||
r('use_roman_numerals_for_series_number', config)
|
||||
|
||||
choices = [(_('Default'), 'default'), (_('Compact metadata'), 'alt1'),
|
||||
(_('All on 1 tab'), 'alt2')]
|
||||
r('edit_metadata_single_layout', gprefs,
|
||||
@ -315,15 +67,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('edit_metadata_single_cc_label_length', gprefs)
|
||||
r('edit_metadata_templates_only_F2_on_booklist', gprefs)
|
||||
|
||||
self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order)
|
||||
self.display_model.dataChanged.connect(self.changed_signal)
|
||||
self.field_display_order.setModel(self.display_model)
|
||||
mu = partial(move_field_up, self.field_display_order, self.display_model)
|
||||
md = partial(move_field_down, self.field_display_order, self.display_model)
|
||||
self.df_up_button.clicked.connect(mu)
|
||||
self.df_down_button.clicked.connect(md)
|
||||
self.field_display_order.set_movement_functions(mu, md)
|
||||
|
||||
self.em_display_model = EMDisplayedFields(self.gui.current_db, self.em_display_order)
|
||||
self.em_display_model.dataChanged.connect(self.changed_signal)
|
||||
self.em_display_order.setModel(self.em_display_model)
|
||||
@ -336,10 +79,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.em_import_layout_button.clicked.connect(partial(import_layout, self, model=self.em_display_model))
|
||||
self.em_reset_layout_button.clicked.connect(partial(reset_layout, model=self.em_display_model))
|
||||
|
||||
self.bd_vertical_cats_model = BDVerticalCats(self.gui.current_db, self.tb_hierarchy_tab.tb_hierarchical_cats)
|
||||
self.bd_vertical_cats_model.dataChanged.connect(self.changed_signal)
|
||||
self.bd_vertical_cats.setModel(self.bd_vertical_cats_model)
|
||||
|
||||
self.edit_rules = EditRules(self.tabWidget)
|
||||
self.edit_rules.changed.connect(self.changed_signal)
|
||||
self.tabWidget.addTab(self.edit_rules, QIcon.ic('format-fill-color.png'), _('Column &coloring'))
|
||||
@ -354,11 +93,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
'Ctrl+Shift+F', QKeySequence.SequenceFormat.PortableText)]
|
||||
keys = [str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in keys]
|
||||
|
||||
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())
|
||||
for i in range(self.tabWidget.count()):
|
||||
self.sections_view.addItem(QListWidgetItem(self.tabWidget.tabIcon(i), self.tabWidget.tabText(i).replace('&', '')))
|
||||
self.sections_view.setCurrentRow(self.tabWidget.currentIndex())
|
||||
@ -371,58 +105,33 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
def initial_tab_changed(self):
|
||||
self.sections_view.setCurrentRow(self.tabWidget.currentIndex())
|
||||
|
||||
def edit_id_link_rules(self):
|
||||
if IdLinksEditor(self).exec() == QDialog.DialogCode.Accepted:
|
||||
self.changed_signal.emit()
|
||||
|
||||
def initialize(self):
|
||||
ConfigWidgetBase.initialize(self)
|
||||
|
||||
self.default_author_link.value = default_author_link()
|
||||
self.display_model.initialize()
|
||||
self.em_display_model.initialize()
|
||||
self.bd_vertical_cats_model.initialize()
|
||||
db = self.gui.current_db
|
||||
mi = selected_rows_metadatas()
|
||||
self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules')
|
||||
self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules')
|
||||
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 restore_defaults(self):
|
||||
ConfigWidgetBase.restore_defaults(self)
|
||||
self.default_author_link.value = DEFAULT_AUTHOR_LINK
|
||||
self.display_model.restore_defaults()
|
||||
self.em_display_model.restore_defaults()
|
||||
self.bd_vertical_cats_model.restore_defaults()
|
||||
self.edit_rules.clear()
|
||||
self.icon_rules.clear()
|
||||
self.changed_signal.emit()
|
||||
self.opt_book_details_css.setPlainText(P('templates/book_details.css', allow_user_override=False, data=True).decode('utf-8'))
|
||||
|
||||
def commit(self, *args):
|
||||
with BusyCursor():
|
||||
self.display_model.commit()
|
||||
self.em_display_model.commit()
|
||||
self.bd_vertical_cats_model.commit()
|
||||
self.edit_rules.commit(self.gui.current_db.prefs)
|
||||
self.icon_rules.commit(self.gui.current_db.prefs)
|
||||
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)
|
||||
|
||||
def refresh_gui(self, gui):
|
||||
gui.book_details.book_info.refresh_css()
|
||||
m = gui.library_view.model()
|
||||
m.update_db_prefs_cache()
|
||||
m.beginResetModel(), m.endResetModel()
|
||||
gui.tags_view.model().reset_tag_browser()
|
||||
gui.library_view.refresh_book_details(force=True)
|
||||
gui.library_view.refresh_composite_edit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -37,7 +37,7 @@
|
||||
<string>Cover &grid</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="book_details_tab">
|
||||
<widget class="BookDetailsTab" name="book_details_tab">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
<normaloff>:/images/book.png</normaloff>:/images/book.png</iconset>
|
||||
@ -45,243 +45,6 @@
|
||||
<attribute name="title">
|
||||
<string>&Book details</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="6" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Text styling</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="opt_book_details_css"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QPushButton" name="id_links_button">
|
||||
<property name="text">
|
||||
<string>Create rules to convert &identifiers into links</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QWidget" name="default_author_link_container" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QGroupBox" name="categories_on_separate_lines_group_box">
|
||||
<property name="toolTip">
|
||||
<string><p>Check the box if you want the category's values displayed on separate lines instead of separated by commas</p></string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Categories on separate lines</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="vblayout_3">
|
||||
<item>
|
||||
<widget class="QListView" name="bd_vertical_cats">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" 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. Keyboard shortcut: Ctrl-Down arrow</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. Keyboard shortcut: Ctrl-Up arrow</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="ListViewWithMoveByKeyPress" name="field_display_order">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string><p>Note: <b>comments</b>-like columns will always
|
||||
be displayed at the end unless their "Heading position" is
|
||||
"Show heading to the side".</p></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_bd_show_cover">
|
||||
<property name="text">
|
||||
<string>Show &cover</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_bd_overlay_cover_size">
|
||||
<property name="toolTip">
|
||||
<string>Show the size of the book's cover in pixels</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show cover &size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_use_roman_numerals_for_series_number">
|
||||
<property name="text">
|
||||
<string>Use &Roman numerals for series</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_bd1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Show comments &heading:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_book_details_comments_heading_pos</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="opt_book_details_comments_heading_pos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_bd13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1022">
|
||||
<property name="text">
|
||||
<string>Link and note icon si&ze:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_book_details_note_link_icon_width</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="opt_book_details_note_link_icon_width">
|
||||
<property name="toolTip">
|
||||
<string>Increase or decrease the size of the links and notes icons by this number. Larger
|
||||
than one increases the icon size while smaller than one decreases it.</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.5</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>4.0</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.1</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_bd13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="edit_metadata_tab">
|
||||
<attribute name="icon">
|
||||
@ -631,6 +394,11 @@ columns". Editing with mouse clicks and the Tab key will be disabled.</p
|
||||
<extends>ConfigWidgetBase</extends>
|
||||
<header>calibre/gui2/preferences/look_feel_tabs/cover_grid.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BookDetailsTab</class>
|
||||
<extends>ConfigWidgetBase</extends>
|
||||
<header>calibre/gui2/preferences/look_feel_tabs/book_details.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TbDisplayTab</class>
|
||||
<extends>ConfigWidgetBase</extends>
|
||||
|
@ -7,13 +7,76 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import json
|
||||
|
||||
from qt.core import QAbstractListModel, QIcon, QItemSelectionModel, Qt
|
||||
from qt.core import QAbstractListModel, QComboBox, QFormLayout, QIcon, QItemSelectionModel, QLineEdit, Qt, QVBoxLayout, QWidget, pyqtSignal
|
||||
|
||||
from calibre.ebooks.metadata.book.render import DEFAULT_AUTHOR_LINK
|
||||
from calibre.gui2 import choose_files, choose_save_file, error_dialog
|
||||
from calibre.gui2.book_details import get_field_list
|
||||
from calibre.gui2.ui import get_gui
|
||||
|
||||
|
||||
class DefaultAuthorLink(QWidget):
|
||||
|
||||
changed_signal = pyqtSignal()
|
||||
|
||||
def __init__(self, parent):
|
||||
QWidget.__init__(self, parent)
|
||||
l = QVBoxLayout()
|
||||
l.addWidget(self)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
l = QFormLayout(self)
|
||||
l.setContentsMargins(0, 0, 0, 0)
|
||||
l.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
|
||||
self.choices = c = QComboBox()
|
||||
c.setMinimumContentsLength(30)
|
||||
for text, data in [
|
||||
(_('Search for the author on Goodreads'), 'search-goodreads'),
|
||||
(_('Search for the author on Amazon'), 'search-amzn'),
|
||||
(_('Search for the author in your calibre library'), 'search-calibre'),
|
||||
(_('Search for the author on Wikipedia'), 'search-wikipedia'),
|
||||
(_('Search for the author on Google Books'), 'search-google'),
|
||||
(_('Search for the book on Goodreads'), 'search-goodreads-book'),
|
||||
(_('Search for the book on Amazon'), 'search-amzn-book'),
|
||||
(_('Search for the book on Google Books'), 'search-google-book'),
|
||||
(_('Use a custom search URL'), 'url'),
|
||||
]:
|
||||
c.addItem(text, data)
|
||||
l.addRow(_('Clicking on &author names should:'), c)
|
||||
self.custom_url = u = QLineEdit(self)
|
||||
u.setToolTip(_(
|
||||
'Enter the URL to search. It should contain the string {0}'
|
||||
'\nwhich will be replaced by the author name. For example,'
|
||||
'\n{1}').format('{author}', 'https://en.wikipedia.org/w/index.php?search={author}'))
|
||||
u.textChanged.connect(self.changed_signal)
|
||||
u.setPlaceholderText(_('Enter the URL'))
|
||||
c.currentIndexChanged.connect(self.current_changed)
|
||||
l.addRow(u)
|
||||
self.current_changed()
|
||||
c.currentIndexChanged.connect(self.changed_signal)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
k = self.choices.currentData()
|
||||
if k == 'url':
|
||||
return self.custom_url.text()
|
||||
return k if k != DEFAULT_AUTHOR_LINK else None
|
||||
|
||||
@value.setter
|
||||
def value(self, val):
|
||||
i = self.choices.findData(val)
|
||||
if i < 0:
|
||||
i = self.choices.findData('url')
|
||||
self.custom_url.setText(val)
|
||||
self.choices.setCurrentIndex(i)
|
||||
|
||||
def current_changed(self):
|
||||
k = self.choices.currentData()
|
||||
self.custom_url.setVisible(k == 'url')
|
||||
|
||||
def restore_defaults(self):
|
||||
self.value = DEFAULT_AUTHOR_LINK
|
||||
|
||||
|
||||
class DisplayedFields(QAbstractListModel):
|
||||
|
||||
def __init__(self, db, parent=None, pref_name=None, category_icons=None):
|
||||
|
256
src/calibre/gui2/preferences/look_feel_tabs/book_details.py
Normal file
256
src/calibre/gui2/preferences/look_feel_tabs/book_details.py
Normal file
@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2025, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
|
||||
from qt.core import (
|
||||
QDialog,
|
||||
QDialogButtonBox,
|
||||
QFormLayout,
|
||||
QHeaderView,
|
||||
QIcon,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QPushButton,
|
||||
QSize,
|
||||
Qt,
|
||||
QTableWidget,
|
||||
QTableWidgetItem,
|
||||
QVBoxLayout,
|
||||
)
|
||||
|
||||
from calibre.ebooks.metadata.sources.prefs import msprefs
|
||||
from calibre.gui2 import config, default_author_link, error_dialog, gprefs
|
||||
from calibre.gui2.preferences import LazyConfigWidgetBase
|
||||
from calibre.gui2.preferences.look_feel_tabs import DisplayedFields, move_field_down, move_field_up
|
||||
from calibre.gui2.preferences.look_feel_tabs.book_details_ui import Ui_Form
|
||||
from calibre.gui2.widgets import BusyCursor
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
from calibre.startup import connect_lambda
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.resources import set_data
|
||||
from polyglot.builtins import iteritems
|
||||
|
||||
|
||||
class IdLinksRuleEdit(Dialog):
|
||||
|
||||
def __init__(self, key='', name='', template='', parent=None):
|
||||
title = _('Edit rule') if key else _('Create a new rule')
|
||||
Dialog.__init__(self, title=title, name='id-links-rule-editor', parent=parent)
|
||||
self.key.setText(key), self.nw.setText(name), self.template.setText(template or 'https://example.com/{id}')
|
||||
if self.size().height() < self.sizeHint().height():
|
||||
self.resize(self.sizeHint())
|
||||
|
||||
@property
|
||||
def rule(self):
|
||||
return self.key.text().lower(), self.nw.text(), self.template.text()
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QFormLayout(self)
|
||||
l.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
|
||||
l.addRow(QLabel(_(
|
||||
'The key of the identifier, for example, in isbn:XXX, the key is "isbn"')))
|
||||
self.key = k = QLineEdit(self)
|
||||
l.addRow(_('&Key:'), k)
|
||||
l.addRow(QLabel(_(
|
||||
'The name that will appear in the Book details panel')))
|
||||
self.nw = n = QLineEdit(self)
|
||||
l.addRow(_('&Name:'), n)
|
||||
la = QLabel(_(
|
||||
'The template used to create the link.'
|
||||
' The placeholder {0} in the template will be replaced'
|
||||
' with the actual identifier value. Use {1} to avoid the value'
|
||||
' being quoted.').format('{id}', '{id_unquoted}'))
|
||||
la.setWordWrap(True)
|
||||
l.addRow(la)
|
||||
self.template = t = QLineEdit(self)
|
||||
l.addRow(_('&Template:'), t)
|
||||
t.selectAll()
|
||||
t.setFocus(Qt.FocusReason.OtherFocusReason)
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def accept(self):
|
||||
r = self.rule
|
||||
for i, which in enumerate([_('Key'), _('Name'), _('Template')]):
|
||||
if not r[i]:
|
||||
return error_dialog(self, _('Value needed'), _(
|
||||
'The %s field cannot be empty') % which, show=True)
|
||||
Dialog.accept(self)
|
||||
|
||||
|
||||
class IdLinksEditor(Dialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
Dialog.__init__(self, title=_('Create rules for identifiers'), name='id-links-rules-editor', parent=parent)
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QVBoxLayout(self)
|
||||
self.la = la = QLabel(_(
|
||||
'Create rules to convert identifiers into links.'))
|
||||
la.setWordWrap(True)
|
||||
l.addWidget(la)
|
||||
items = []
|
||||
for k, lx in iteritems(msprefs['id_link_rules']):
|
||||
for n, t in lx:
|
||||
items.append((k, n, t))
|
||||
items.sort(key=lambda x: sort_key(x[1]))
|
||||
self.table = t = QTableWidget(len(items), 3, self)
|
||||
t.setHorizontalHeaderLabels([_('Key'), _('Name'), _('Template')])
|
||||
for r, (key, val, template) in enumerate(items):
|
||||
t.setItem(r, 0, QTableWidgetItem(key))
|
||||
t.setItem(r, 1, QTableWidgetItem(val))
|
||||
t.setItem(r, 2, QTableWidgetItem(template))
|
||||
l.addWidget(t)
|
||||
t.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
|
||||
self.cb = b = QPushButton(QIcon.ic('plus.png'), _('&Add rule'), self)
|
||||
connect_lambda(b.clicked, self, lambda self: self.edit_rule())
|
||||
self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.rb = b = QPushButton(QIcon.ic('minus.png'), _('&Remove rule'), self)
|
||||
connect_lambda(b.clicked, self, lambda self: self.remove_rule())
|
||||
self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.eb = b = QPushButton(QIcon.ic('modified.png'), _('&Edit rule'), self)
|
||||
connect_lambda(b.clicked, self, lambda self: self.edit_rule(self.table.currentRow()))
|
||||
self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(700, 550)
|
||||
|
||||
def accept(self):
|
||||
rules = defaultdict(list)
|
||||
for r in range(self.table.rowCount()):
|
||||
def item(c):
|
||||
return self.table.item(r, c).text()
|
||||
rules[item(0)].append([item(1), item(2)])
|
||||
msprefs['id_link_rules'] = dict(rules)
|
||||
Dialog.accept(self)
|
||||
|
||||
def edit_rule(self, r=-1):
|
||||
key = name = template = ''
|
||||
if r > -1:
|
||||
key, name, template = (self.table.item(r, c).text() for c in range(3))
|
||||
d = IdLinksRuleEdit(key, name, template, self)
|
||||
if d.exec() == QDialog.DialogCode.Accepted:
|
||||
if r < 0:
|
||||
self.table.setRowCount(self.table.rowCount() + 1)
|
||||
r = self.table.rowCount() - 1
|
||||
rule = d.rule
|
||||
for c in range(3):
|
||||
self.table.setItem(r, c, QTableWidgetItem(rule[c]))
|
||||
self.table.scrollToItem(self.table.item(r, 0))
|
||||
|
||||
def remove_rule(self):
|
||||
r = self.table.currentRow()
|
||||
if r > -1:
|
||||
self.table.removeRow(r)
|
||||
|
||||
|
||||
class BDVerticalCats(DisplayedFields):
|
||||
|
||||
def __init__(self, db, parent=None, category_icons=None):
|
||||
DisplayedFields.__init__(self, db, parent, category_icons=category_icons)
|
||||
from calibre.gui2.ui import get_gui
|
||||
self.gui = get_gui()
|
||||
|
||||
def initialize(self, use_defaults=False, pref_data_override=None):
|
||||
fm = self.db.field_metadata
|
||||
cats = [k for k in fm if fm[k]['name'] and fm[k]['is_multiple'] and not k.startswith('#')]
|
||||
cats.append('path')
|
||||
cats.extend([k for k in fm if fm[k]['name'] and fm[k]['is_multiple'] and k.startswith('#')])
|
||||
ans = []
|
||||
if use_defaults:
|
||||
ans = [[k, False] for k in cats]
|
||||
self.changed = True
|
||||
elif pref_data_override:
|
||||
ph = dict(pref_data_override)
|
||||
ans = [[k, ph.get(k, False)] for k in cats]
|
||||
self.changed = True
|
||||
else:
|
||||
vertical_cats = self.db.prefs.get('book_details_vertical_categories') or ()
|
||||
for key in cats:
|
||||
ans.append([key, key in vertical_cats])
|
||||
self.beginResetModel()
|
||||
self.fields = ans
|
||||
self.endResetModel()
|
||||
|
||||
def commit(self):
|
||||
if self.changed:
|
||||
self.db.prefs.set('book_details_vertical_categories', [k for k,v in self.fields if v])
|
||||
|
||||
|
||||
class BookDetailsTab(LazyConfigWidgetBase, Ui_Form):
|
||||
|
||||
def genesis(self, gui):
|
||||
self.gui = gui
|
||||
r = self.register
|
||||
|
||||
self.default_author_link.changed_signal.connect(self.changed_signal)
|
||||
r('bd_show_cover', gprefs)
|
||||
r('bd_overlay_cover_size', gprefs)
|
||||
r('book_details_comments_heading_pos', gprefs, choices=[
|
||||
(_('Never'), 'hide'), (_('Above text'), 'above'), (_('Beside text'), 'side')])
|
||||
r('book_details_note_link_icon_width', gprefs)
|
||||
self.id_links_button.clicked.connect(self.edit_id_link_rules)
|
||||
|
||||
r('use_roman_numerals_for_series_number', config)
|
||||
|
||||
self.bd_vertical_cats_model = BDVerticalCats(self.gui.current_db, parent=self)
|
||||
self.bd_vertical_cats_model.dataChanged.connect(self.changed_signal)
|
||||
self.bd_vertical_cats.setModel(self.bd_vertical_cats_model)
|
||||
|
||||
self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order)
|
||||
self.display_model.dataChanged.connect(self.changed_signal)
|
||||
self.field_display_order.setModel(self.display_model)
|
||||
mu = partial(move_field_up, self.field_display_order, self.display_model)
|
||||
md = partial(move_field_down, self.field_display_order, self.display_model)
|
||||
self.df_up_button.clicked.connect(mu)
|
||||
self.df_down_button.clicked.connect(md)
|
||||
self.field_display_order.set_movement_functions(mu, md)
|
||||
|
||||
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 lazy_initialize(self):
|
||||
self.default_author_link.value = default_author_link()
|
||||
self.display_model.initialize()
|
||||
self.blockSignals(True)
|
||||
self.bd_vertical_cats_model.initialize()
|
||||
self.opt_book_details_css.setPlainText(P('templates/book_details.css', data=True).decode('utf-8'))
|
||||
self.blockSignals(False)
|
||||
|
||||
def edit_id_link_rules(self):
|
||||
if IdLinksEditor(self).exec() == QDialog.DialogCode.Accepted:
|
||||
self.changed_signal.emit()
|
||||
|
||||
def commit(self):
|
||||
with BusyCursor():
|
||||
self.display_model.commit()
|
||||
self.bd_vertical_cats_model.commit()
|
||||
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 LazyConfigWidgetBase.commit(self)
|
||||
|
||||
def restore_defaults(self):
|
||||
LazyConfigWidgetBase.restore_defaults(self)
|
||||
self.default_author_link.restore_defaults()
|
||||
self.display_model.restore_defaults()
|
||||
self.bd_vertical_cats_model.restore_defaults()
|
||||
self.opt_book_details_css.setPlainText(P('templates/book_details.css', allow_user_override=False, data=True).decode('utf-8'))
|
||||
self.changed_signal.emit()
|
||||
|
||||
def refresh_gui(self, gui):
|
||||
gui.book_details.book_info.refresh_css()
|
||||
gui.library_view.refresh_book_details(force=True)
|
||||
gui.library_view.refresh_composite_edit()
|
258
src/calibre/gui2/preferences/look_feel_tabs/book_details.ui
Normal file
258
src/calibre/gui2/preferences/look_feel_tabs/book_details.ui
Normal file
@ -0,0 +1,258 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="book_details_tab">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="6" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Text styling</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="opt_book_details_css"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QPushButton" name="id_links_button">
|
||||
<property name="text">
|
||||
<string>Create rules to convert &identifiers into links</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="DefaultAuthorLink" name="default_author_link" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QGroupBox" name="categories_on_separate_lines_group_box">
|
||||
<property name="toolTip">
|
||||
<string><p>Check the box if you want the category's values displayed on separate lines instead of separated by commas</p></string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Categories on separate lines</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="vblayout_3">
|
||||
<item>
|
||||
<widget class="QListView" name="bd_vertical_cats">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" 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. Keyboard shortcut: Ctrl-Down arrow</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. Keyboard shortcut: Ctrl-Up arrow</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="ListViewWithMoveByKeyPress" name="field_display_order">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string><p>Note: <b>comments</b>-like columns will always
|
||||
be displayed at the end unless their "Heading position" is
|
||||
"Show heading to the side".</p></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_bd_show_cover">
|
||||
<property name="text">
|
||||
<string>Show &cover</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_bd_overlay_cover_size">
|
||||
<property name="toolTip">
|
||||
<string>Show the size of the book's cover in pixels</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show cover &size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_use_roman_numerals_for_series_number">
|
||||
<property name="text">
|
||||
<string>Use &Roman numerals for series</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_bd1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Show comments &heading:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_book_details_comments_heading_pos</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="opt_book_details_comments_heading_pos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_bd13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1022">
|
||||
<property name="text">
|
||||
<string>Link and note icon si&ze:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_book_details_note_link_icon_width</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="opt_book_details_note_link_icon_width">
|
||||
<property name="toolTip">
|
||||
<string>Increase or decrease the size of the links and notes icons by this number. Larger
|
||||
than one increases the icon size while smaller than one decreases it.</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.5</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>4.0</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.1</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_bd13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ListViewWithMoveByKeyPress</class>
|
||||
<extends>QListView</extends>
|
||||
<header>calibre/gui2/preferences.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>DefaultAuthorLink</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>calibre/gui2/preferences/look_feel_tabs.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../../resources/images.qrc"/>
|
||||
</resources>
|
||||
</ui>
|
Loading…
x
Reference in New Issue
Block a user