diff --git a/resources/templates/book_details.css b/resources/templates/book_details.css
index 5fc2691850..6c06296cb1 100644
--- a/resources/templates/book_details.css
+++ b/resources/templates/book_details.css
@@ -31,12 +31,12 @@ table.fields td.title {
}
/*
-The HTML that this styleshhet applies to looks like this:
+The HTML that this stylesheet applies to looks like this:
diff --git a/src/calibre/ebooks/metadata/book/render.py b/src/calibre/ebooks/metadata/book/render.py
index 4a14208e4f..9c2c655225 100644
--- a/src/calibre/ebooks/metadata/book/render.py
+++ b/src/calibre/ebooks/metadata/book/render.py
@@ -8,6 +8,7 @@ __copyright__ = '2014, Kovid Goyal '
import os
from functools import partial
+from binascii import hexlify
from calibre import prepare_string_for_xml, force_unicode
from calibre.ebooks.metadata import fmt_sidx
@@ -45,6 +46,10 @@ def get_field_list(mi):
for field in sorted(displayable_field_keys(mi), key=partial(field_sort, mi)):
yield field, True
+def search_href(search_term, value):
+ search = '%s:"=%s"' % (search_term, value.replace('"', '\\"'))
+ return prepare_string_for_xml('search:' + hexlify(search.encode('utf-8')), True)
+
def mi_to_html(mi, field_list=None, default_author_link=None, use_roman_numbers=True, rating_font='Liberation Serif'):
if field_list is None:
field_list = get_field_list(mi)
@@ -166,13 +171,36 @@ def mi_to_html(mi, field_list=None, default_author_link=None, use_roman_numbers=
sidx = mi.get(field+'_index')
if sidx is None:
sidx = 1.0
- val = _('Book %(sidx)s of %(series)s')%dict(
- sidx=fmt_sidx(sidx, use_roman=use_roman_numbers),
- series=p(getattr(mi, field)))
+ try:
+ st = metadata['search_terms'][0]
+ except Exception:
+ st = field
+ series = getattr(mi, field)
+ val = _(
+ 'Book %(sidx)s of '
+ '%(series)s') % dict(
+ sidx=fmt_sidx(sidx, use_roman=use_roman_numbers), cls="series_name",
+ series=p(series), href=search_href(st, series),
+ tt=p(_('Click to see books in this series')))
elif metadata['datatype'] == 'datetime':
aval = getattr(mi, field)
if is_date_undefined(aval):
continue
+ elif metadata['datatype'] == 'text' and metadata['is_multiple']:
+ try:
+ st = metadata['search_terms'][0]
+ except Exception:
+ st = field
+ links = ['%s' % (
+ search_href(st, x), _('Click to see books with {0}: {1}').format(metadata['name'], x), x)
+ for x in mi.get(field)]
+ val = metadata['is_multiple']['list_to_ui'].join(links)
+ elif metadata['datatype'] == 'enumeration':
+ try:
+ st = metadata['search_terms'][0]
+ except Exception:
+ st = field
+ val = '%s' % (search_href(st, val), _('Click to see books with {0}: {1}').format(metadata['name'], val), val)
ans.append((field, row % (name, val)))
diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py
index c3df9f019e..71f5e9f5d6 100644
--- a/src/calibre/gui2/book_details.py
+++ b/src/calibre/gui2/book_details.py
@@ -5,6 +5,8 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal '
__docformat__ = 'restructuredtext en'
+from binascii import unhexlify
+
from PyQt4.Qt import (QPixmap, QSize, QWidget, Qt, pyqtSignal, QUrl, QIcon,
QPropertyAnimation, QEasingCurve, QApplication, QFontInfo, QAction,
QSizePolicy, QPainter, QRect, pyqtProperty, QLayout, QPalette, QMenu,
@@ -500,6 +502,7 @@ class BookDetails(QWidget): # {{{
show_book_info = pyqtSignal()
open_containing_folder = pyqtSignal(int)
view_specific_format = pyqtSignal(int, object)
+ search_requested = pyqtSignal(object)
remove_specific_format = pyqtSignal(int, object)
save_specific_format = pyqtSignal(int, object)
restore_specific_format = pyqtSignal(int, object)
@@ -581,7 +584,7 @@ class BookDetails(QWidget): # {{{
self.setCursor(Qt.PointingHandCursor)
def handle_click(self, link):
- typ, _, val = link.partition(':')
+ typ, val = link.partition(':')[0::2]
if typ == 'path':
self.open_containing_folder.emit(int(val))
elif typ == 'format':
@@ -589,6 +592,8 @@ class BookDetails(QWidget): # {{{
self.view_specific_format.emit(int(id_), fmt)
elif typ == 'devpath':
self.view_device_book.emit(val)
+ elif typ == 'search':
+ self.search_requested.emit(unhexlify(val).decode('utf-8'))
else:
try:
open_url(QUrl(link, QUrl.TolerantMode))
diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py
index 083b1a4cc5..23188aa4ab 100644
--- a/src/calibre/gui2/init.py
+++ b/src/calibre/gui2/init.py
@@ -445,6 +445,7 @@ class LayoutMixin(object): # {{{
type=Qt.QueuedConnection)
self.book_details.open_containing_folder.connect(self.iactions['View'].view_folder_for_id)
self.book_details.view_specific_format.connect(self.iactions['View'].view_format_by_id)
+ self.book_details.search_requested.connect(self.search.set_search_string)
self.book_details.remove_specific_format.connect(
self.iactions['Remove Books'].remove_format_by_id)
self.book_details.save_specific_format.connect(