diff --git a/src/calibre/ebooks/metadata/book/render.py b/src/calibre/ebooks/metadata/book/render.py
index 64c75c5f6c..90c707c8c4 100644
--- a/src/calibre/ebooks/metadata/book/render.py
+++ b/src/calibre/ebooks/metadata/book/render.py
@@ -89,7 +89,7 @@ def mi_to_html(
mi,
field_list=None, default_author_link=None, use_roman_numbers=True,
rating_font='Liberation Serif', rtl=False, comments_heading_pos='hide',
- for_qt=False,
+ for_qt=False, vertical_fields=()
):
if field_list is None:
field_list = get_field_list(mi)
@@ -108,6 +108,12 @@ def mi_to_html(
continue
if not metadata:
continue
+
+ def value_list(sep, vals):
+ if field in vertical_fields:
+ return '
'.join(vals)
+ return sep.join(vals)
+
if field == 'sort':
field = 'title_sort'
if metadata['is_custom'] and metadata['datatype'] in {'bool', 'int', 'float'}:
@@ -162,11 +168,11 @@ def mi_to_html(
_('Click to see books with {0}: {1}').format(metadata['name'], a(val)), p(val))
else:
all_vals = [v.strip()
- for v in val.split(metadata['is_multiple']['list_to_ui']) if v.strip()]
+ for v in val.split(metadata['is_multiple']['cache_to_list']) if v.strip()]
links = ['{}'.format(
search_action(field, x), _('Click to see books with {0}: {1}').format(
metadata['name'], a(x)), p(x)) for x in all_vals]
- val = metadata['is_multiple']['list_to_ui'].join(links)
+ val = value_list(metadata['is_multiple']['list_to_ui'], links)
ans.append((field, row % (name, val)))
elif field == 'path':
if mi.path:
@@ -199,7 +205,7 @@ def mi_to_html(
} for x in mi.formats)
fmts = ['{fmt}'.format(**x)
for x in data]
- ans.append((field, row % (name, ', '.join(fmts))))
+ ans.append((field, row % (name, value_list(', ', fmts))))
elif field == 'identifiers':
urls = urls_from_identifiers(mi.identifiers, sort_results=True)
links = [
@@ -207,7 +213,7 @@ def mi_to_html(
action('identifier', url=url, name=namel, id_type=id_typ, value=id_val, field='identifiers', book_id=book_id),
a(id_typ), a(id_val), p(namel))
for namel, id_typ, id_val, url in urls]
- links = ', '.join(links)
+ links = value_list(', ', links)
if links:
ans.append((field, row % (_('Ids')+':', links)))
elif field == 'authors':
@@ -233,14 +239,14 @@ def mi_to_html(
authors.append('%s'%(a(lt), action('author', url=link, name=aut, title=lt), aut))
else:
authors.append(aut)
- ans.append((field, row % (name, ' & '.join(authors))))
+ ans.append((field, row % (name, value_list(' & ', authors))))
elif field == 'languages':
if not mi.languages:
continue
names = filter(None, map(calibre_langcode_to_name, mi.languages))
names = ['{}'.format(search_action_with_data('languages', n, book_id), _(
'Search calibre for books with the language: {}').format(n), n) for n in names]
- ans.append((field, row % (name, ', '.join(names))))
+ ans.append((field, row % (name, value_list(', ', names))))
elif field == 'publisher':
if not mi.publisher:
continue
@@ -303,7 +309,7 @@ def mi_to_html(
search_action_with_data(st, x, book_id, field), _('Click to see books with {0}: {1}').format(
metadata['name'] or field, a(x)), p(x))
for x in all_vals]
- val = metadata['is_multiple']['list_to_ui'].join(links)
+ val = value_list(metadata['is_multiple']['list_to_ui'], links)
elif metadata['datatype'] == 'text' or metadata['datatype'] == 'enumeration':
# text/is_multiple handled above so no need to add the test to the if
try:
diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py
index d57926665a..f9214fbd09 100644
--- a/src/calibre/gui2/book_details.py
+++ b/src/calibre/gui2/book_details.py
@@ -176,7 +176,9 @@ def init_find_in_grouped_search(menu, field, value, book_info):
def render_html(mi, vertical, widget, all_fields=False, render_data_func=None, pref_name='book_display_fields'): # {{{
- func = render_data_func or render_data
+ from calibre.gui2.ui import get_gui
+ func = render_data_func or partial(render_data,
+ vertical_fields=get_gui().current_db.prefs.get('book_details_vertical_categories') or ())
try:
table, comment_fields = func(mi, all_fields=all_fields,
use_roman_numbers=config['use_roman_numerals_for_series_number'], pref_name=pref_name)
@@ -233,13 +235,15 @@ def get_field_list(fm, use_defaults=False, pref_name='book_display_fields'):
return [(f, d) for f, d in fieldlist if f in available]
-def render_data(mi, use_roman_numbers=True, all_fields=False, pref_name='book_display_fields'):
+def render_data(mi, use_roman_numbers=True, all_fields=False, pref_name='book_display_fields',
+ vertical_fields=()):
field_list = get_field_list(getattr(mi, 'field_metadata', field_metadata), pref_name=pref_name)
field_list = [(x, all_fields or display) for x, display in field_list]
return mi_to_html(
mi, field_list=field_list, use_roman_numbers=use_roman_numbers, rtl=is_rtl(),
rating_font=rating_font(), default_author_link=default_author_link(),
- comments_heading_pos=gprefs['book_details_comments_heading_pos'], for_qt=True
+ comments_heading_pos=gprefs['book_details_comments_heading_pos'], for_qt=True,
+ vertical_fields=vertical_fields
)
# }}}
diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py
index 750ca86ce8..71437c65fa 100644
--- a/src/calibre/gui2/preferences/look_feel.py
+++ b/src/calibre/gui2/preferences/look_feel.py
@@ -470,6 +470,38 @@ class TBHierarchicalFields(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']]
+ ans = []
+ if use_defaults:
+ ans = [[k, False] for k in cats]
+ self.changed = True
+ elif pref_data_override:
+ ph = {k:v for k,v in 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 Background(QWidget): # {{{
def __init__(self, parent):
@@ -706,6 +738,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.tb_hierarchy_import_layout_button.clicked.connect(partial(self.import_layout,
model=self.tb_hierarchical_cats_model))
+ self.bd_vertical_cats_model = BDVerticalCats(self.gui.current_db, self.tb_hierarchical_cats)
+ self.bd_vertical_cats_model.dataChanged.connect(self.changed_signal)
+ self.bd_vertical_cats.setModel(self.bd_vertical_cats_model)
+
self.fill_tb_search_order_box()
self.tb_search_order_up_button.clicked.connect(self.move_tb_search_up)
self.tb_search_order_down_button.clicked.connect(self.move_tb_search_down)
@@ -959,6 +995,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.tb_display_model.initialize()
self.tb_categories_to_part_model.initialize()
self.tb_hierarchical_cats_model.initialize()
+ self.bd_vertical_cats_model.initialize()
db = self.gui.current_db
mi = []
try:
@@ -1022,6 +1059,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.display_model.restore_defaults()
self.em_display_model.restore_defaults()
self.qv_display_model.restore_defaults()
+ self.bd_vertical_cats_model.restore_defaults()
gprefs.set('tb_search_order', gprefs.defaults['tb_search_order'])
self.edit_rules.clear()
self.icon_rules.clear()
@@ -1097,6 +1135,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.tb_display_model.commit()
self.tb_categories_to_part_model.commit()
self.tb_hierarchical_cats_model.commit()
+ self.bd_vertical_cats_model.commit()
self.tb_search_order_commit()
self.edit_rules.commit(self.gui.current_db.prefs)
self.icon_rules.commit(self.gui.current_db.prefs)
diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui
index 940b3febb1..9ef0610c3f 100644
--- a/src/calibre/gui2/preferences/look_feel.ui
+++ b/src/calibre/gui2/preferences/look_feel.ui
@@ -733,14 +733,14 @@ A value of zero means calculate automatically.
- -
+
-
Create rules to convert &identifiers into links
- -
+
-
@@ -750,6 +750,25 @@ A value of zero means calculate automatically.
+ -
+
+
+ Categories on separate lines
+
+
+ <p>Check the box if you want the category's values displayed on separate lines instead of separated by commas</p>
+
+
+
-
+
+
+ true
+
+
+
+
+
+
-
@@ -811,7 +830,7 @@ A value of zero means calculate automatically.
- -
+
-
-
@@ -855,7 +874,7 @@ A value of zero means calculate automatically.
- -
+
-
-