diff --git a/src/calibre/ebooks/metadata/book/render.py b/src/calibre/ebooks/metadata/book/render.py index c4912894f2..6341d1b816 100644 --- a/src/calibre/ebooks/metadata/book/render.py +++ b/src/calibre/ebooks/metadata/book/render.py @@ -60,9 +60,9 @@ def search_action(search_term, value, **k): return action('search', term=search_term, value=value, **k) -def search_action_with_data(search_term, value, book_id, field=None): +def search_action_with_data(search_term, value, book_id, field=None, **k): field = field or search_term - return search_action(search_term, value, field=field, book_id=book_id) + return search_action(search_term, value, field=field, book_id=book_id, **k) DEFAULT_AUTHOR_LINK = 'search-{}'.format(DEFAULT_AUTHOR_SOURCE) @@ -281,6 +281,10 @@ def mi_to_html( aval = getattr(mi, field) if is_date_undefined(aval): continue + val = '%s' % ( + search_action_with_data(field, str(aval), book_id, None, original_value=val), a( + _('Click to see books with {0}: {1} (derived from {2})').format( + metadata['name'] or field, aval, val)), val) elif metadata['datatype'] == 'text' and metadata['is_multiple']: try: st = metadata['search_terms'][0] @@ -303,6 +307,27 @@ def mi_to_html( val = '%s' % ( search_action_with_data(st, val, book_id, field), a( _('Click to see books with {0}: {1}').format(metadata['name'] or field, val)), p(val)) + elif metadata['datatype'] == 'bool': + val = '%s' % ( + search_action_with_data(field, val, book_id, None), a( + _('Click to see books with {0}: {1}').format(metadata['name'] or field, val)), val) + else: + try: + aval = str(getattr(mi, field)) + if not aval: + continue + if val == aval: + val = '%s' % ( + search_action_with_data(field, str(aval), book_id, None, original_value=val), a( + _('Click to see books with {0}: {1}').format(metadata['name'] or field, val)), val) + else: + val = '%s' % ( + search_action_with_data(field, str(aval), book_id, None, original_value=val), a( + _('Click to see books with {0}: {1} (derived from {2})').format( + metadata['name'] or field, aval, val)), val) + except: + import traceback + traceback.print_exc() ans.append((field, row % (name, val))) diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index c5177b022b..3239a16484 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -92,6 +92,13 @@ def is_category(field): return field in {x[0] for x in find_categories(fm) if fm.is_custom_field(x[0])} +def is_boolean(field): + from calibre.gui2.ui import get_gui + gui = get_gui() + fm = gui.current_db.field_metadata + return fm.get(field, {}).get('datatype') == 'bool' + + def escape_for_menu(x): return x.replace('&', '&&') @@ -365,10 +372,18 @@ def add_item_specific_entries(menu, data, book_info, copy_menu, search_menu): remove_value = langnames_to_langcodes((value,)).get(value, 'Unknown') init_find_in_tag_browser(search_menu, find_action, field, value) init_find_in_grouped_search(search_menu, field, value, book_info) + else: + v = data.get('original_value') or data.get('value') + copy_menu.addAction(QIcon(I('edit-copy.png')), _('The text: {}').format(v), + lambda: QApplication.instance().clipboard().setText(v)) ac = book_info.remove_item_action ac.data = (field, remove_value, book_id) ac.setText(_('Remove %s from this book') % escape_for_menu(value)) menu.addAction(ac) + else: + v = data.get('original_value') or data.get('value') + copy_menu.addAction(QIcon(I('edit-copy.png')), _('The text: {}').format(v), + lambda: QApplication.instance().clipboard().setText(v)) return search_internet_added @@ -1034,8 +1049,9 @@ class BookDetails(QWidget): # {{{ if mods & Qt.KeyboardModifier.ControlModifier: append = 'AND' if mods & Qt.KeyboardModifier.ShiftModifier else 'OR' + fmt = '{}:{}' if is_boolean(field) else '{}:"={}"' self.search_requested.emit( - '{}:"={}"'.format(field, val.replace('"', '\\"')), + fmt.format(field, val.replace('"', '\\"')), append )