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'] = \