diff --git a/src/calibre/gui2/actions/similar_books.py b/src/calibre/gui2/actions/similar_books.py
index 31148d6a7c..6967e70db5 100644
--- a/src/calibre/gui2/actions/similar_books.py
+++ b/src/calibre/gui2/actions/similar_books.py
@@ -36,25 +36,28 @@ class SimilarBooksAction(InterfaceAction):
def show_similar_books(self, type, *args):
search, join = [], ' '
idx = self.gui.library_view.currentIndex()
+ db = self.gui.library_view.model().db
if not idx.isValid():
return
row = idx.row()
if type == 'series':
series = idx.model().db.series(row)
if series:
- search = ['series:"'+series+'"']
+ search = [db.prefs['similar_series_search_key'] + ':"'+series+'"']
elif type == 'publisher':
publisher = idx.model().db.publisher(row)
if publisher:
- search = ['publisher:"'+publisher+'"']
+ search = [db.prefs['similar_publisher_search_key'] + ':"'+publisher+'"']
elif type == 'tag':
tags = idx.model().db.tags(row)
if tags:
- search = ['tag:"='+t+'"' for t in tags.split(',')]
+ search = [db.prefs['similar_tags_search_key'] + ':"='+t+'"'
+ for t in tags.split(',')]
elif type in ('author', 'authors'):
authors = idx.model().db.authors(row)
if authors:
- search = ['author:"='+a.strip().replace('|', ',')+'"' \
+ search = [db.prefs['similar_authors_search_key'] +
+ ':"='+a.strip().replace('|', ',')+'"' \
for a in authors.split(',')]
join = ' or '
if search:
diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py
index c86de7f2a3..336e30e4ba 100644
--- a/src/calibre/gui2/preferences/search.py
+++ b/src/calibre/gui2/preferences/search.py
@@ -12,6 +12,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \
from calibre.gui2.preferences.search_ui import Ui_Form
from calibre.gui2 import config, error_dialog
from calibre.utils.config import prefs
+from calibre.utils.icu import sort_key
class ConfigWidget(ConfigWidgetBase, Ui_Form):
@@ -70,6 +71,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.gst_value.update_items_cache(fl)
self.fill_gst_box(select=None)
+ self.set_similar_fields(initial=True)
+ self.similar_authors_search_key.currentIndexChanged[int].connect(self.something_changed)
+ self.similar_tags_search_key.currentIndexChanged[int].connect(self.something_changed)
+ self.similar_series_search_key.currentIndexChanged[int].connect(self.something_changed)
+ self.similar_publisher_search_key.currentIndexChanged[int].connect(self.something_changed)
+
self.gst_delete_button.setEnabled(False)
self.gst_save_button.setEnabled(False)
self.gst_names.currentIndexChanged[int].connect(self.gst_index_changed)
@@ -86,6 +93,33 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.opt_grouped_search_make_user_categories.editingFinished.connect(
self.muc_box_changed)
+ def set_similar_fields(self, initial=False):
+ self.set_similar('similar_authors_search_key', first_item='author', initial=initial)
+ self.set_similar('similar_tags_search_key', first_item='tags', initial=initial)
+ self.set_similar('similar_series_search_key', first_item='series', initial=initial)
+ self.set_similar('similar_publisher_search_key', first_item='publisher', initial=initial)
+
+ def set_similar(self, name, first_item, initial=False):
+ field = getattr(self, name)
+ if not initial:
+ val = field.currentText()
+ else:
+ val = self.db.prefs[name]
+ field.blockSignals(True)
+ field.clear()
+ choices = [first_item]
+ choices.extend(sorted(self.gst.keys(), key=sort_key))
+ field.addItems(choices)
+ dex = field.findText(val)
+ if dex >= 0:
+ field.setCurrentIndex(dex)
+ else:
+ field.setCurrentIndex(0)
+ field.blockSignals(False)
+
+ def something_changed(self, dex):
+ self.changed_signal.emit()
+
def muc_box_changed(self):
self.muc_changed = True
@@ -121,6 +155,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.gst_changed = True
self.gst[name] = val
self.fill_gst_box(select=name)
+ self.set_similar_fields(initial=False)
self.changed_signal.emit()
def gst_delete_clicked(self):
@@ -133,9 +168,10 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.fill_gst_box(select='')
self.changed_signal.emit()
self.gst_changed = True
+ self.set_similar_fields(initial=False)
def fill_gst_box(self, select=None):
- terms = sorted(self.gst.keys())
+ terms = sorted(self.gst.keys(), key=sort_key)
self.opt_grouped_search_make_user_categories.update_items_cache(terms)
self.gst_names.blockSignals(True)
self.gst_names.clear()
@@ -168,6 +204,14 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
if self.gst_changed:
self.db.prefs.set('grouped_search_terms', self.gst)
self.db.field_metadata.add_grouped_search_terms(self.gst)
+ self.db.prefs.set('similar_authors_search_key',
+ unicode(self.similar_authors_search_key.currentText()))
+ self.db.prefs.set('similar_tags_search_key',
+ unicode(self.similar_tags_search_key.currentText()))
+ self.db.prefs.set('similar_series_search_key',
+ unicode(self.similar_series_search_key.currentText()))
+ self.db.prefs.set('similar_publisher_search_key',
+ unicode(self.similar_publisher_search_key.currentText()))
return ConfigWidgetBase.commit(self)
def refresh_gui(self, gui):
diff --git a/src/calibre/gui2/preferences/search.ui b/src/calibre/gui2/preferences/search.ui
index 3f5b43bbb6..527cf8ab85 100644
--- a/src/calibre/gui2/preferences/search.ui
+++ b/src/calibre/gui2/preferences/search.ui
@@ -201,6 +201,84 @@ to be shown as user categories
+ -
+
+
+ What to search when searching similar books
+
+
+
-
+
+
+ <p>When you search for similar books by author, series, etc,
+ calibre constructs a search using the column lookup names defined below.
+ By changing the lookup name to a grouped search term you can
+ search multiple columns.</p>
+
+
+ true
+
+
+
+ -
+
+
+ Similar authors:
+
+
+
+ -
+
+
+
+ 10
+ 0
+
+
+
+
+ -
+
+
+ Similar series:
+
+
+
+ -
+
+
+
+ 10
+ 0
+
+
+
+
+ -
+
+
+ Similar tags:
+
+
+
+ -
+
+
+
+ -
+
+
+ Similar publishers:
+
+
+
+ -
+
+
+
+
+
+
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index 230acf8891..dd2a265dba 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -236,6 +236,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
defs['categories_using_hierarchy'] = []
defs['column_color_rules'] = []
defs['grouped_search_make_user_categories'] = []
+ defs['similar_authors_search_key'] = 'author'
+ defs['similar_publisher_search_key'] = 'publisher'
+ defs['similar_tags_search_key'] = 'tags'
+ defs['similar_series_search_key'] = 'series'
# Migrate the bool tristate tweak
defs['bools_are_tristate'] = \