This commit is contained in:
Kovid Goyal 2022-08-26 14:41:12 +05:30
commit d2d267a576
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 392 additions and 211 deletions

View File

@ -386,7 +386,7 @@ Two variants of equality searches are used for hierarchical items (e.g., A.B.C):
*'Regular expression' searches* *'Regular expression' searches*
Regular expression searches are indicated by prefixing the search string with a tilde (~). Any `Python-compatible regular expression <https://docs.python.org/library/re.html>`__ can be used. Backslashes used to escape special characters in regular expressions must be doubled because single backslashes will be removed during query parsing. For example, to match a literal parenthesis you must enter ``\\(`` or alternatively use `super quotes` (see below). Regular expression searches are 'contains' searches unless the expression is anchored. Character variants are significant: ``~e`` doesn't match ``é``. Regular expression searches are indicated by prefixing the search string with a tilde (~). Any `Python-compatible regular expression <https://docs.python.org/library/re.html>`__ can be used. Backslashes used to escape special characters in regular expressions must be doubled because single backslashes will be removed during query parsing. For example, to match a literal parenthesis you must enter ``\\(`` or alternatively use `super-quotes` (see below). Regular expression searches are 'contains' searches unless the expression is anchored. Character variants are significant: ``~e`` doesn't match ``é``.
*'Character variant' searches* *'Character variant' searches*

View File

@ -8,6 +8,7 @@ __docformat__ = 'restructuredtext en'
import json import json
from collections import defaultdict from collections import defaultdict
from threading import Thread from threading import Thread
from functools import partial
from qt.core import ( from qt.core import (
QApplication, QFont, QFontInfo, QFontDialog, QColorDialog, QPainter, QDialog, QApplication, QFont, QFontInfo, QFontDialog, QColorDialog, QPainter, QDialog,
@ -23,7 +24,7 @@ from calibre.ebooks.metadata.sources.prefs import msprefs
from calibre.gui2.custom_column_widgets import get_field_list as em_get_field_list from calibre.gui2.custom_column_widgets import get_field_list as em_get_field_list
from calibre.gui2 import default_author_link, icon_resource_manager, choose_save_file, choose_files from calibre.gui2 import default_author_link, icon_resource_manager, choose_save_file, choose_files
from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.dialogs.template_dialog import TemplateDialog
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList from calibre.gui2.preferences import ConfigWidgetBase, test_widget
from calibre.gui2.preferences.look_feel_ui import Ui_Form from calibre.gui2.preferences.look_feel_ui import Ui_Form
from calibre.gui2 import config, gprefs, qt_app, open_local_file, question_dialog, error_dialog from calibre.gui2 import config, gprefs, qt_app, open_local_file, question_dialog, error_dialog
from calibre.utils.localization import (available_translations, from calibre.utils.localization import (available_translations,
@ -377,24 +378,101 @@ class TBDisplayedFields(DisplayedFields): # {{{
pref_data_override=pref_data_override) pref_data_override=pref_data_override)
if use_defaults: if use_defaults:
hc = [] hc = []
self.changed = True
elif pref_data_override: elif pref_data_override:
hc = [k for k,v in pref_data_override if not v] hc = [k for k,v in pref_data_override if not v]
self.changed = True
else: else:
hc = tv.hidden_categories hc = tv.hidden_categories
self.beginResetModel() self.beginResetModel()
self.fields = [[x, x not in hc] for x in cat_ord] self.fields = [[x, x not in hc] for x in cat_ord]
self.endResetModel() self.endResetModel()
self.changed = True
def is_standard_category(self, key): def is_standard_category(self, key):
return self.gui.tags_view.model().is_standard_category(key) return self.gui.tags_view.model().is_standard_category(key)
def commit(self): def commit(self):
if self.changed: if self.changed:
self.db.new_api.set_pref('tag_browser_hidden_categories', [k for k,v in self.fields if not v]) self.db.prefs.set('tag_browser_hidden_categories', [k for k,v in self.fields if not v])
self.db.new_api.set_pref('tag_browser_category_order', [k for k,v in self.fields]) self.db.prefs.set('tag_browser_category_order', [k for k,v in self.fields])
self.gui.tags_view.model().set_hidden_categories({k for k,v in self.fields if not v}) self.gui.tags_view.model().reset_tag_browser_categories()
# }}}
class TBPartitionedFields(DisplayedFields): # {{{
# The code in this class depends on the fact that the tag browser is
# initialized before this class is instantiated.
def __init__(self, db, parent=None, category_icons=None):
DisplayedFields.__init__(self, db, parent, category_icons=category_icons)
from calibre.gui2.ui import get_gui
self.gui = get_gui()
def initialize(self, use_defaults=False, pref_data_override=None):
tv = self.gui.tags_view
cats = tv.model().categories
ans = []
if use_defaults:
ans = [[k, True] for k in cats.keys()]
self.changed = True
elif pref_data_override:
po = {k:v for k,v in pref_data_override}
ans = [[k, po.get(k, True)] for k in cats.keys()]
self.changed = True
else:
# Check if setting not migrated yet
cats_to_partition = self.db.prefs.get('tag_browser_dont_collapse',
gprefs.get('tag_browser_dont_collapse'))
for key in cats:
ans.append([key, not key in cats_to_partition])
self.beginResetModel()
self.fields = ans
self.endResetModel()
def commit(self):
if self.changed:
# Migrate to a per-library setting
self.db.prefs.set('tag_browser_dont_collapse', [k for k,v in self.fields if not v])
self.gui.tags_view.model().reset_tag_browser_categories()
# }}}
class TBHierarchicalFields(DisplayedFields): # {{{
# The code in this class depends on the fact that the tag browser is
# initialized before this class is instantiated.
cant_make_hierarical = {'authors', 'publisher', 'formats', 'news',
'identifiers', 'languages', 'rating'}
def __init__(self, db, parent=None, category_icons=None):
DisplayedFields.__init__(self, db, parent, category_icons=category_icons)
from calibre.gui2.ui import get_gui
self.gui = get_gui()
def initialize(self, use_defaults=False, pref_data_override=None):
tv = self.gui.tags_view
cats = [k for k in tv.model().categories.keys() if k not in self.cant_make_hierarical]
ans = []
if use_defaults:
ans = [[k, False] for k in cats]
self.changed = True
elif pref_data_override:
ph = {k:v for k,v in pref_data_override}
ans = [[k, ph.get(k, False)] for k in cats]
self.changed = True
else:
hier_cats = self.db.prefs.get('categories_using_hierarchy')
for key in cats:
ans.append([key, key in hier_cats])
self.beginResetModel()
self.fields = ans
self.endResetModel()
def commit(self):
if self.changed:
self.db.prefs.set('categories_using_hierarchy', [k for k,v in self.fields if v])
self.gui.tags_view.model().reset_tag_browser_categories()
# }}} # }}}
@ -547,20 +625,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('tags_browser_collapse_at', gprefs) r('tags_browser_collapse_at', gprefs)
r('tags_browser_collapse_fl_at', gprefs) r('tags_browser_collapse_fl_at', gprefs)
choices = {k for k in db.field_metadata.all_field_keys()
if (db.field_metadata[k]['is_category'] and (
db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration'
]) and not db.field_metadata[k]['display'].get('is_names', False)) or (
db.field_metadata[k]['datatype'] in ['composite'
] and db.field_metadata[k]['display'].get('make_category', False))}
choices |= {'search'}
r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList,
choices=sorted(choices, key=sort_key))
choices -= {'authors', 'publisher', 'formats', 'news', 'identifiers'}
r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList,
choices=sorted(choices, key=sort_key))
fm = db.field_metadata fm = db.field_metadata
choices = sorted(((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), choices = sorted(((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']),
key=lambda x:sort_key(x[0])) key=lambda x:sort_key(x[0]))
@ -601,9 +665,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
lambda self: move_field_up(self.em_display_order, self.em_display_model)) lambda self: move_field_up(self.em_display_order, self.em_display_model))
connect_lambda(self.em_down_button.clicked, self, connect_lambda(self.em_down_button.clicked, self,
lambda self: move_field_down(self.em_display_order, self.em_display_model)) lambda self: move_field_down(self.em_display_order, self.em_display_model))
self.em_export_layout_button.clicked.connect(self.em_export_layout) self.em_export_layout_button.clicked.connect(partial(self.export_layout,
self.em_import_layout_button.clicked.connect(self.em_import_layout) model=self.em_display_model))
self.em_reset_layout_button.clicked.connect(self.em_reset_layout) self.em_import_layout_button.clicked.connect(partial(self.import_layout,
model=self.em_display_model))
self.em_reset_layout_button.clicked.connect(partial(self.reset_layout,
model=self.em_display_model))
self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_model = QVDisplayedFields(self.gui.current_db,
self.qv_display_order) self.qv_display_order)
@ -619,12 +686,39 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
category_icons=self.gui.tags_view.model().category_custom_icons) category_icons=self.gui.tags_view.model().category_custom_icons)
self.tb_display_model.dataChanged.connect(self.changed_signal) self.tb_display_model.dataChanged.connect(self.changed_signal)
self.tb_display_order.setModel(self.tb_display_model) self.tb_display_order.setModel(self.tb_display_model)
self.tb_reset_layout_button.clicked.connect(self.tb_reset_layout) self.tb_reset_layout_button.clicked.connect(partial(self.reset_layout,
self.tb_export_layout_button.clicked.connect(self.tb_export_layout) model=self.tb_display_model))
self.tb_import_layout_button.clicked.connect(self.tb_import_layout) self.tb_export_layout_button.clicked.connect(partial(self.export_layout,
model=self.tb_display_model))
self.tb_import_layout_button.clicked.connect(partial(self.import_layout,
model=self.tb_display_model))
self.tb_up_button.clicked.connect(self.tb_up_button_clicked) self.tb_up_button.clicked.connect(self.tb_up_button_clicked)
self.tb_down_button.clicked.connect(self.tb_down_button_clicked) self.tb_down_button.clicked.connect(self.tb_down_button_clicked)
self.tb_categories_to_part_model = TBPartitionedFields(self.gui.current_db,
self.tb_cats_to_partition,
category_icons=self.gui.tags_view.model().category_custom_icons)
self.tb_categories_to_part_model.dataChanged.connect(self.changed_signal)
self.tb_cats_to_partition.setModel(self.tb_categories_to_part_model)
self.tb_partition_reset_button.clicked.connect(partial(self.reset_layout,
model=self.tb_categories_to_part_model))
self.tb_partition_export_layout_button.clicked.connect(partial(self.export_layout,
model=self.tb_categories_to_part_model))
self.tb_partition_import_layout_button.clicked.connect(partial(self.import_layout,
model=self.tb_categories_to_part_model))
self.tb_hierarchical_cats_model = TBHierarchicalFields(self.gui.current_db,
self.tb_hierarchical_cats,
category_icons=self.gui.tags_view.model().category_custom_icons)
self.tb_hierarchical_cats_model.dataChanged.connect(self.changed_signal)
self.tb_hierarchical_cats.setModel(self.tb_hierarchical_cats_model)
self.tb_hierarchy_reset_layout_button.clicked.connect(partial(self.reset_layout,
model=self.tb_hierarchical_cats_model))
self.tb_hierarchy_export_layout_button.clicked.connect(partial(self.export_layout,
model=self.tb_hierarchical_cats_model))
self.tb_hierarchy_import_layout_button.clicked.connect(partial(self.import_layout,
model=self.tb_hierarchical_cats_model))
self.edit_rules = EditRules(self.tabWidget) self.edit_rules = EditRules(self.tabWidget)
self.edit_rules.changed.connect(self.changed_signal) self.edit_rules.changed.connect(self.changed_signal)
self.tabWidget.addTab(self.edit_rules, self.tabWidget.addTab(self.edit_rules,
@ -695,19 +789,19 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.opt_color_palette.setEnabled(enabled) self.opt_color_palette.setEnabled(enabled)
self.opt_color_palette_label.setEnabled(enabled) self.opt_color_palette_label.setEnabled(enabled)
def em_export_layout(self): def export_layout(self, model=None):
filename = choose_save_file(self, 'em_import_export_field_list', filename = choose_save_file(self, 'em_import_export_field_list',
_('Save column list to file'), _('Save column list to file'),
filters=[(_('Column list'), ['json'])]) filters=[(_('Column list'), ['json'])])
if filename: if filename:
try: try:
with open(filename, 'w') as f: with open(filename, 'w') as f:
json.dump(self.em_display_model.fields, f, indent=1) json.dump(model.fields, f, indent=1)
except Exception as err: except Exception as err:
error_dialog(self, _('Export field layout'), error_dialog(self, _('Export field layout'),
_('<p>Could not write field list. Error:<br>%s')%err, show=True) _('<p>Could not write field list. Error:<br>%s')%err, show=True)
def em_import_layout(self): def import_layout(self, model=None):
filename = choose_files(self, 'em_import_export_field_list', filename = choose_files(self, 'em_import_export_field_list',
_('Load column list from file'), _('Load column list from file'),
filters=[(_('Column list'), ['json'])]) filters=[(_('Column list'), ['json'])])
@ -715,44 +809,14 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
try: try:
with open(filename[0]) as f: with open(filename[0]) as f:
fields = json.load(f) fields = json.load(f)
self.em_display_model.initialize(pref_data_override=fields) model.initialize(pref_data_override=fields)
self.changed_signal.emit() self.changed_signal.emit()
except Exception as err: except Exception as err:
error_dialog(self, _('Import layout'), error_dialog(self, _('Import layout'),
_('<p>Could not read field list. Error:<br>%s')%err, show=True) _('<p>Could not read field list. Error:<br>%s')%err, show=True)
def em_reset_layout(self): def reset_layout(self, model=None):
self.em_display_model.initialize(use_defaults=True) model.initialize(use_defaults=True)
self.changed_signal.emit()
def tb_export_layout(self):
filename = choose_save_file(self, 'em_import_export_field_list',
_('Save column list to file'),
filters=[(_('Column list'), ['json'])])
if filename:
try:
with open(filename, 'w') as f:
json.dump(self.tb_display_model.fields, f, indent=1)
except Exception as err:
error_dialog(self, _('Export field layout'),
_('<p>Could not write field list. Error:<br>%s')%err, show=True)
def tb_import_layout(self):
filename = choose_files(self, 'em_import_export_field_list',
_('Load column list from file'),
filters=[(_('Column list'), ['json'])])
if filename:
try:
with open(filename[0]) as f:
fields = json.load(f)
self.tb_display_model.initialize(pref_data_override=fields)
self.changed_signal.emit()
except Exception as err:
error_dialog(self, _('Import layout'),
_('<p>Could not read field list. Error:<br>%s')%err, show=True)
def tb_reset_layout(self):
self.tb_display_model.initialize(use_defaults=True)
self.changed_signal.emit() self.changed_signal.emit()
def tb_down_button_clicked(self): def tb_down_button_clicked(self):
@ -839,6 +903,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.em_display_model.initialize() self.em_display_model.initialize()
self.qv_display_model.initialize() self.qv_display_model.initialize()
self.tb_display_model.initialize() self.tb_display_model.initialize()
self.tb_categories_to_part_model.initialize()
self.tb_hierarchical_cats_model.initialize()
db = self.gui.current_db db = self.gui.current_db
mi = [] mi = []
try: try:
@ -974,6 +1040,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.em_display_model.commit() self.em_display_model.commit()
self.qv_display_model.commit() self.qv_display_model.commit()
self.tb_display_model.commit() self.tb_display_model.commit()
self.tb_categories_to_part_model.commit()
self.tb_hierarchical_cats_model.commit()
self.edit_rules.commit(self.gui.current_db.prefs) self.edit_rules.commit(self.gui.current_db.prefs)
self.icon_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs)
self.grid_rules.commit(self.gui.current_db.prefs) self.grid_rules.commit(self.gui.current_db.prefs)

View File

@ -1156,17 +1156,10 @@ using the Tab key. The F2 (Edit) key will still open the template editor.&lt;/p&
<string>Select the categories to display in the Tag browser and their order</string> <string>Select the categories to display in the Tag browser and their order</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>User categories and Saved searches cannot be moved</string>
</property>
</widget>
</item>
<item row="4" column="1"> <item row="4" column="1">
<widget class="QToolButton" name="tb_down_button"> <widget class="QToolButton" name="tb_down_button">
<property name="toolTip"> <property name="toolTip">
<string>Move down</string> <string>Move down. User categories and Saved searches cannot be moved</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
@ -1177,7 +1170,7 @@ using the Tab key. The F2 (Edit) key will still open the template editor.&lt;/p&
<item row="2" column="1"> <item row="2" column="1">
<widget class="QToolButton" name="tb_up_button"> <widget class="QToolButton" name="tb_up_button">
<property name="toolTip"> <property name="toolTip">
<string>Move up</string> <string>Move up. User categories and Saved searches cannot be moved</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
@ -1269,6 +1262,8 @@ structure and you want to use the same column order for each one.&lt;/p&gt;</str
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy"> <property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum> <enum>QFormLayout::ExpandingFieldsGrow</enum>
@ -1295,49 +1290,6 @@ if you never want subcategories</string>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Co&amp;llapse when more items than:</string>
</property>
<property name="buddy">
<cstring>opt_tags_browser_collapse_at</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="opt_tags_browser_collapse_at">
<property name="toolTip">
<string>If a Tag browser category has more than this number of items, it is divided
up into subcategories. If the partition method is set to disable, this value is ignored.</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Combine letters &amp;when fewer items than:</string>
</property>
<property name="buddy">
<cstring>opt_tags_browser_collapse_fl_at</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="opt_tags_browser_collapse_fl_at">
<property name="toolTip">
<string>If collapsing by first letter, combine adjacent letters together if
there are fewer items under a letter than specified here. If the partition method is
not set to first letter, this value is ignored. Set to zero to disable.</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Spacing between &amp;items:</string> <string>Spacing between &amp;items:</string>
@ -1347,7 +1299,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="1" column="1">
<widget class="QDoubleSpinBox" name="opt_tag_browser_item_padding"> <widget class="QDoubleSpinBox" name="opt_tag_browser_item_padding">
<property name="toolTip"> <property name="toolTip">
<string>The spacing between consecutive items in the Tag browser. In units of (ex) which is the approximate height of the letter 'x' in the currently used font. </string> <string>The spacing between consecutive items in the Tag browser. In units of (ex) which is the approximate height of the letter 'x' in the currently used font. </string>
@ -1369,66 +1321,220 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> </layout>
<widget class="QLabel" name="label_8111"> </item>
<item row="0" column="1">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
<string>Categories &amp;not to partition:</string> <string>Combine letters &amp;when fewer items than:</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>opt_tag_browser_dont_collapse</cstring> <cstring>opt_tags_browser_collapse_fl_at</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="0" column="1">
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse"> <widget class="QSpinBox" name="opt_tags_browser_collapse_fl_at">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip"> <property name="toolTip">
<string>A comma-separated list of categories that are not to <string>If collapsing by first letter, combine adjacent letters together if
be partitioned even if the number of items is larger than there are fewer items under a letter than specified here. If the partition method is
the value shown above. This option can be used to not set to first letter, this value is ignored. Set to zero to disable.</string>
avoid collapsing hierarchical categories that have only </property>
a few top-level elements.</string> <property name="maximum">
<number>10000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_81"> <widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
<string>C&amp;ategories with hierarchical items:</string> <string>Co&amp;llapse when more items than:</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>opt_categories_using_hierarchy</cstring> <cstring>opt_tags_browser_collapse_at</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="1" column="1">
<widget class="EditWithComplete" name="opt_categories_using_hierarchy"> <widget class="QSpinBox" name="opt_tags_browser_collapse_at">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip"> <property name="toolTip">
<string>A comma-separated list of categories in which items containing <string>If a Tag browser category has more than this number of items, it is divided
periods are displayed in the Tag browser trees. For example, if up into subcategories. If the partition method is set to disable, this value is ignored.</string>
this box contains 'tags' then tags of the form 'Mystery.English' </property>
and 'Mystery.Thriller' will be displayed with English and Thriller <property name="maximum">
both under 'Mystery'. If 'tags' is not in this box, <number>10000</number>
then the tags will be displayed each on their own line.</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0">
<widget class="QLabel">
<property name="text">
<string>Select categories to &amp;partition:</string>
</property>
<property name="buddy">
<cstring>tb_cats_to_partition</cstring>
</property>
<property name="toolTip">
<string>&lt;p&gt;Check the box for categories that are to
be partitioned using the criteria above. Uncheck the box if you don't want to
partition a category even if the number of items is larger than
the value shown above. This option can be used to
avoid collapsing hierarchical categories that have only
a few top-level elements.&lt;/p&gt;</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QListView" name="tb_cats_to_partition">
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_41">
<item> <item>
<layout class="QGridLayout" name="gridLayout_10"> <widget class="QPushButton" name="tb_partition_reset_button">
<item row="0" column="0"> <property name="toolTip">
<string>&lt;p&gt;Click this button to reset the list to its default order.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Reset list</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tb_partition_import_layout_button">
<property name="toolTip">
<string>&lt;p&gt;Click this button to set the list to one
previously exported. This could be useful if you have several libraries with
similar structure and you want to use the same for each one.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Import list</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tb_partition_export_layout_button">
<property name="toolTip">
<string>&lt;p&gt;Click this button to write the current display
settings to a file. This could be useful if you have several libraries with similar
structure and you want to use the same for each one.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Export list</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QLabel">
<property name="text">
<string>Select categories with &amp;hierarchical items:</string>
</property>
<property name="buddy">
<cstring>tb_hierarchical_cats</cstring>
</property>
<property name="toolTip">
<string>&lt;p&gt;Check the box for an item if it is to be displayed as a
hierarchical tree in the Tag browser. For example, if you check
'tags' then tags of the form 'Mystery.English'
and 'Mystery.Thriller' will be displayed with English and Thriller
both under 'Mystery'. If 'tags' is not checked
then the tags will be displayed each on their own line.&lt;/p&gt;</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QListView" name="tb_hierarchical_cats">
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="tb_hierarchy_reset_layout_button">
<property name="toolTip">
<string>&lt;p&gt;Click this button to reset the list to its default order.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Reset list</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tb_hierarchy_import_layout_button">
<property name="toolTip">
<string>&lt;p&gt;Click this button to set the list to one
previously exported. This could be useful if you have several libraries with
similar structure and you want to use the same for each one.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Import list</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tb_hierarchy_export_layout_button">
<property name="toolTip">
<string>&lt;p&gt;Click this button to write the current display
settings to a file. This could be useful if you have several libraries with similar
structure and you want to use the same for each one.&lt;/p&gt;</string>
</property>
<property name="text">
<string>Export list</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="opt_show_avg_rating"> <widget class="QCheckBox" name="opt_show_avg_rating">
<property name="text"> <property name="text">
<string>Show &amp;average ratings</string> <string>Show &amp;average ratings</string>
@ -1438,14 +1544,14 @@ then the tags will be displayed each on their own line.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="5" column="1">
<widget class="QCheckBox" name="opt_tag_browser_show_tooltips"> <widget class="QCheckBox" name="opt_tag_browser_show_tooltips">
<property name="text"> <property name="text">
<string>Show &amp;tooltips</string> <string>Show &amp;tooltips</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="6" column="0">
<widget class="QCheckBox" name="opt_tag_browser_show_counts"> <widget class="QCheckBox" name="opt_tag_browser_show_counts">
<property name="toolTip"> <property name="toolTip">
<string>Show counts for items in the Tag browser. Such as the number of books <string>Show counts for items in the Tag browser. Such as the number of books
@ -1457,14 +1563,14 @@ see the counts by hovering your mouse over any item.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="6" column="1">
<widget class="QCheckBox" name="opt_tag_browser_old_look"> <widget class="QCheckBox" name="opt_tag_browser_old_look">
<property name="text"> <property name="text">
<string>Use &amp;alternating row colors</string> <string>Use &amp;alternating row colors</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="7" column="0">
<widget class="QCheckBox" name="opt_tag_browser_hide_empty_categories"> <widget class="QCheckBox" name="opt_tag_browser_hide_empty_categories">
<property name="toolTip"> <property name="toolTip">
<string>When checked, calibre will automatically hide any category <string>When checked, calibre will automatically hide any category
@ -1477,7 +1583,7 @@ see the counts by hovering your mouse over any item.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="7" column="1">
<widget class="QCheckBox" name="opt_tag_browser_always_autocollapse"> <widget class="QCheckBox" name="opt_tag_browser_always_autocollapse">
<property name="toolTip"> <property name="toolTip">
<string>When checked, Find in the Tag browser will show all items <string>When checked, Find in the Tag browser will show all items
@ -1489,7 +1595,7 @@ see the counts by hovering your mouse over any item.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="8" column="0" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QCheckBox" name="opt_tag_browser_allow_keyboard_focus"> <widget class="QCheckBox" name="opt_tag_browser_allow_keyboard_focus">

View File

@ -402,9 +402,14 @@ class TagsModel(QAbstractItemModel): # {{{
self._run_rebuild() self._run_rebuild()
self.endResetModel() self.endResetModel()
def set_hidden_categories(self, cats): def reset_tag_browser_categories(self):
self.beginResetModel() self.beginResetModel()
self.hidden_categories = cats hidden_cats = self.db.new_api.pref('tag_browser_hidden_categories', {})
self.hidden_categories = set()
# strip out any non-existent field keys
for cat in hidden_cats:
if cat in self.db.field_metadata:
self.hidden_categories.add(cat)
self._run_rebuild() self._run_rebuild()
self.endResetModel() self.endResetModel()
@ -541,7 +546,9 @@ class TagsModel(QAbstractItemModel): # {{{
is_gst = category.is_gst is_gst = category.is_gst
if key not in data: if key not in data:
return return
if key in self.prefs['tag_browser_dont_collapse']: # Use old pref if new one doesn't exist
if key in self.db.prefs.get('tag_browser_dont_collapse',
self.prefs['tag_browser_dont_collapse']):
collapse_model = 'disable' collapse_model = 'disable'
cat_len = len(data[key]) cat_len = len(data[key])
if cat_len <= 0: if cat_len <= 0: