mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-11-14 10:32:59 -05:00
190 lines
8.0 KiB
Python
190 lines
8.0 KiB
Python
#!/usr/bin/env python
|
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
|
|
|
__license__ = 'GPL v3'
|
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
|
__docformat__ = 'restructuredtext en'
|
|
|
|
from PyQt4.Qt import QApplication
|
|
|
|
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \
|
|
CommaSeparatedList
|
|
from calibre.gui2.preferences.search_ui import Ui_Form
|
|
from calibre.gui2 import config, error_dialog
|
|
from calibre.utils.config import prefs
|
|
|
|
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|
|
|
def genesis(self, gui):
|
|
self.gui = gui
|
|
db = gui.library_view.model().db
|
|
self.db = db
|
|
|
|
r = self.register
|
|
|
|
r('search_as_you_type', config)
|
|
r('highlight_search_matches', config)
|
|
r('limit_search_columns', prefs)
|
|
r('limit_search_columns_to', prefs, setting=CommaSeparatedList)
|
|
fl = db.field_metadata.get_search_terms()
|
|
self.opt_limit_search_columns_to.update_items_cache(fl)
|
|
self.clear_history_button.clicked.connect(self.clear_histories)
|
|
|
|
self.gst_explanation.setText('<p>' + _(
|
|
"<b>Grouped search terms</b> are search names that permit a query to automatically "
|
|
"search across more than one column. For example, if you create a grouped "
|
|
"search term <code>allseries</code> with the value "
|
|
"<code>series, #myseries, #myseries2</code>, then "
|
|
"the query <code>allseries:adhoc</code> will find 'adhoc' in any of the "
|
|
"columns <code>series</code>, <code>#myseries</code>, and "
|
|
"<code>#myseries2</code>.<p> Enter the name of the "
|
|
"grouped search term in the drop-down box, enter the list of columns "
|
|
"to search in the value box, then push the Save button. "
|
|
"<p>Note: Search terms are forced to lower case; <code>MySearch</code> "
|
|
"and <code>mysearch</code> are the same term."
|
|
"<p>You can have your grouped search term show up as user categories in "
|
|
" the Tag Browser. Just add the grouped search term names to the Make user "
|
|
"categories from box. You can add multiple terms separated by commas. "
|
|
"The new user category will be automatically "
|
|
"populated with all the items in the categories included in the grouped "
|
|
"search term. <p>Automatic user categories permit you to see easily "
|
|
"all the category items that "
|
|
"are in the columns contained in the grouped search term. Using the above "
|
|
"<code>allseries</code> example, the automatically-generated user category "
|
|
"will contain all the series mentioned in <code>series</code>, "
|
|
"<code>#myseries</code>, and <code>#myseries2</code>. This "
|
|
"can be useful to check for duplicates, to find which column contains "
|
|
"a particular item, or to have hierarchical categories (categories "
|
|
"that contain categories)."))
|
|
self.gst = db.prefs.get('grouped_search_terms', {})
|
|
self.orig_gst_keys = self.gst.keys()
|
|
|
|
fl = []
|
|
for f in db.all_field_keys():
|
|
fm = db.metadata_for_field(f)
|
|
if not fm['search_terms']:
|
|
continue
|
|
if not fm['is_category']:
|
|
continue
|
|
fl.append(f)
|
|
self.gst_value.update_items_cache(fl)
|
|
self.fill_gst_box(select=None)
|
|
|
|
self.gst_delete_button.setEnabled(False)
|
|
self.gst_save_button.setEnabled(False)
|
|
self.gst_names.currentIndexChanged[int].connect(self.gst_index_changed)
|
|
self.gst_names.editTextChanged.connect(self.gst_text_changed)
|
|
self.gst_value.textChanged.connect(self.gst_text_changed)
|
|
self.gst_save_button.clicked.connect(self.gst_save_clicked)
|
|
self.gst_delete_button.clicked.connect(self.gst_delete_clicked)
|
|
self.gst_changed = False
|
|
|
|
if db.prefs.get('grouped_search_make_user_categories', None) is None:
|
|
db.prefs.set('grouped_search_make_user_categories', [])
|
|
r('grouped_search_make_user_categories', db.prefs, setting=CommaSeparatedList)
|
|
self.muc_changed = False
|
|
self.opt_grouped_search_make_user_categories.editingFinished.connect(
|
|
self.muc_box_changed)
|
|
|
|
def muc_box_changed(self):
|
|
self.muc_changed = True
|
|
|
|
def gst_save_clicked(self):
|
|
idx = self.gst_names.currentIndex()
|
|
name = icu_lower(unicode(self.gst_names.currentText()))
|
|
if not name:
|
|
return error_dialog(self.gui, _('Grouped Search Terms'),
|
|
_('The search term cannot be blank'),
|
|
show=True)
|
|
if idx != 0:
|
|
orig_name = unicode(self.gst_names.itemData(idx).toString())
|
|
else:
|
|
orig_name = ''
|
|
if name != orig_name:
|
|
if name in self.db.field_metadata.get_search_terms() and \
|
|
name not in self.orig_gst_keys:
|
|
return error_dialog(self.gui, _('Grouped Search Terms'),
|
|
_('That name is already used for a column or grouped search term'),
|
|
show=True)
|
|
if name in [icu_lower(p) for p in self.db.prefs.get('user_categories', {})]:
|
|
return error_dialog(self.gui, _('Grouped Search Terms'),
|
|
_('That name is already used for user category'),
|
|
show=True)
|
|
|
|
val = [v.strip() for v in unicode(self.gst_value.text()).split(',') if v.strip()]
|
|
if not val:
|
|
return error_dialog(self.gui, _('Grouped Search Terms'),
|
|
_('The value box cannot be empty'), show=True)
|
|
|
|
if orig_name and name != orig_name:
|
|
del self.gst[orig_name]
|
|
self.gst_changed = True
|
|
self.gst[name] = val
|
|
self.fill_gst_box(select=name)
|
|
self.changed_signal.emit()
|
|
|
|
def gst_delete_clicked(self):
|
|
if self.gst_names.currentIndex() == 0:
|
|
return error_dialog(self.gui, _('Grouped Search Terms'),
|
|
_('The empty grouped search term cannot be deleted'), show=True)
|
|
name = unicode(self.gst_names.currentText())
|
|
if name in self.gst:
|
|
del self.gst[name]
|
|
self.fill_gst_box(select='')
|
|
self.changed_signal.emit()
|
|
self.gst_changed = True
|
|
|
|
def fill_gst_box(self, select=None):
|
|
terms = sorted(self.gst.keys())
|
|
self.opt_grouped_search_make_user_categories.update_items_cache(terms)
|
|
self.gst_names.blockSignals(True)
|
|
self.gst_names.clear()
|
|
self.gst_names.addItem('', '')
|
|
for t in terms:
|
|
self.gst_names.addItem(t, t)
|
|
self.gst_names.blockSignals(False)
|
|
if select is not None:
|
|
if select == '':
|
|
self.gst_index_changed(0)
|
|
elif select in terms:
|
|
self.gst_names.setCurrentIndex(self.gst_names.findText(select))
|
|
|
|
def gst_text_changed(self):
|
|
self.gst_delete_button.setEnabled(False)
|
|
self.gst_save_button.setEnabled(True)
|
|
|
|
def gst_index_changed(self, idx):
|
|
self.gst_delete_button.setEnabled(idx != 0)
|
|
self.gst_save_button.setEnabled(False)
|
|
self.gst_value.blockSignals(True)
|
|
if idx == 0:
|
|
self.gst_value.setText('')
|
|
else:
|
|
name = unicode(self.gst_names.itemData(idx).toString())
|
|
self.gst_value.setText(','.join(self.gst[name]))
|
|
self.gst_value.blockSignals(False)
|
|
|
|
def commit(self):
|
|
if self.gst_changed:
|
|
self.db.prefs.set('grouped_search_terms', self.gst)
|
|
self.db.field_metadata.add_grouped_search_terms(self.gst)
|
|
return ConfigWidgetBase.commit(self)
|
|
|
|
def refresh_gui(self, gui):
|
|
gui.set_highlight_only_button_icon()
|
|
if self.muc_changed:
|
|
gui.tags_view.set_new_model()
|
|
gui.search.search_as_you_type(config['search_as_you_type'])
|
|
gui.search.do_search()
|
|
|
|
def clear_histories(self, *args):
|
|
for key, val in config.defaults.iteritems():
|
|
if key.endswith('_search_history') and isinstance(val, list):
|
|
config[key] = []
|
|
self.gui.search.clear_history()
|
|
|
|
if __name__ == '__main__':
|
|
app = QApplication([])
|
|
test_widget('Interface', 'Search')
|
|
|