mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
d2d267a576
@ -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*
|
||||||
|
|
||||||
|
@ -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)
|
||||||
@ -615,16 +682,43 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
lambda self: move_field_down(self.qv_display_order, self.qv_display_model))
|
lambda self: move_field_down(self.qv_display_order, self.qv_display_model))
|
||||||
|
|
||||||
self.tb_display_model = TBDisplayedFields(self.gui.current_db,
|
self.tb_display_model = TBDisplayedFields(self.gui.current_db,
|
||||||
self.tb_display_order,
|
self.tb_display_order,
|
||||||
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)
|
||||||
|
@ -1156,17 +1156,10 @@ using the Tab key. The F2 (Edit) key will still open the template editor.</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.</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,166 +1262,279 @@ structure and you want to use the same column order for each one.</p></str
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QGridLayout" name="gridLayout_10">
|
||||||
<property name="fieldGrowthPolicy">
|
|
||||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label_9">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<property name="text">
|
<property name="fieldGrowthPolicy">
|
||||||
<string>&Category partitioning method:</string>
|
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<item row="0" column="0">
|
||||||
<cstring>opt_tags_browser_partition_method</cstring>
|
<widget class="QLabel" name="label_9">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>&Category partitioning method:</string>
|
||||||
</item>
|
</property>
|
||||||
<item row="0" column="1">
|
<property name="buddy">
|
||||||
<widget class="QComboBox" name="opt_tags_browser_partition_method">
|
<cstring>opt_tags_browser_partition_method</cstring>
|
||||||
<property name="toolTip">
|
</property>
|
||||||
<string>Choose how Tag browser subcategories are displayed when
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_tags_browser_partition_method">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Choose how Tag browser subcategories are displayed when
|
||||||
there are more items than the limit. Select by first
|
there are more items than the limit. Select by first
|
||||||
letter to see an A, B, C list. Choose partitioned to
|
letter to see an A, B, C list. Choose partitioned to
|
||||||
have a list of fixed-sized groups. Set to disabled
|
have a list of fixed-sized groups. Set to disabled
|
||||||
if you never want subcategories</string>
|
if you never want subcategories</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spacing between &items:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_tag_browser_item_padding</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="opt_tag_browser_item_padding">
|
||||||
|
<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>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> ex</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>2.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</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">
|
||||||
|
<string>Combine letters &when fewer items than:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_tags_browser_collapse_fl_at</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" 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="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Co&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>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_10">
|
<widget class="QLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Co&llapse when more items than:</string>
|
<string>Select categories to &partition:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="buddy">
|
||||||
<cstring>opt_tags_browser_collapse_at</cstring>
|
<cstring>tb_cats_to_partition</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QSpinBox" name="opt_tags_browser_collapse_at">
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>If a Tag browser category has more than this number of items, it is divided
|
<string><p>Check the box for categories that are to
|
||||||
up into subcategories. If the partition method is set to disable, this value is ignored.</string>
|
be partitioned using the criteria above. Uncheck the box if you don't want to
|
||||||
</property>
|
partition a category even if the number of items is larger than
|
||||||
<property name="maximum">
|
the value shown above. This option can be used to
|
||||||
<number>10000</number>
|
avoid collapsing hierarchical categories that have only
|
||||||
|
a few top-level elements.</p></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_10">
|
<widget class="QListView" name="tb_cats_to_partition">
|
||||||
<property name="text">
|
<property name="minimumSize">
|
||||||
<string>Combine letters &when fewer items than:</string>
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>200</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="alternatingRowColors">
|
||||||
<cstring>opt_tags_browser_collapse_fl_at</cstring>
|
<bool>true</bool>
|
||||||
</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>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<layout class="QHBoxLayout" name="horizontalLayout_41">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="tb_partition_reset_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><p>Click this button to reset the list to its default order.</p></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><p>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.</p></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><p>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.</p></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">
|
<property name="text">
|
||||||
<string>Spacing between &items:</string>
|
<string>Select categories with &hierarchical items:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="buddy">
|
||||||
<cstring>opt_tag_browser_item_padding</cstring>
|
<cstring>tb_hierarchical_cats</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><p>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.</p></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>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="opt_tag_browser_item_padding">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<property name="toolTip">
|
<item>
|
||||||
<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>
|
<widget class="QPushButton" name="tb_hierarchy_reset_layout_button">
|
||||||
</property>
|
<property name="toolTip">
|
||||||
<property name="suffix">
|
<string><p>Click this button to reset the list to its default order.</p></string>
|
||||||
<string> ex</string>
|
</property>
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="decimals">
|
<string>Reset list</string>
|
||||||
<number>1</number>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<property name="minimum">
|
</item>
|
||||||
<double>-1.000000000000000</double>
|
<item>
|
||||||
</property>
|
<widget class="QPushButton" name="tb_hierarchy_import_layout_button">
|
||||||
<property name="maximum">
|
<property name="toolTip">
|
||||||
<double>2.000000000000000</double>
|
<string><p>Click this button to set the list to one
|
||||||
</property>
|
previously exported. This could be useful if you have several libraries with
|
||||||
<property name="singleStep">
|
similar structure and you want to use the same for each one.</p></string>
|
||||||
<double>0.100000000000000</double>
|
</property>
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Import list</string>
|
||||||
</item>
|
</property>
|
||||||
<item row="4" column="0">
|
</widget>
|
||||||
<widget class="QLabel" name="label_8111">
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Categories &not to partition:</string>
|
<widget class="QPushButton" name="tb_hierarchy_export_layout_button">
|
||||||
</property>
|
<property name="toolTip">
|
||||||
<property name="buddy">
|
<string><p>Click this button to write the current display
|
||||||
<cstring>opt_tag_browser_dont_collapse</cstring>
|
settings to a file. This could be useful if you have several libraries with similar
|
||||||
</property>
|
structure and you want to use the same for each one.</p></string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="text">
|
||||||
<item row="4" column="1">
|
<string>Export list</string>
|
||||||
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse">
|
</property>
|
||||||
<property name="sizePolicy">
|
</widget>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
</item>
|
||||||
<horstretch>0</horstretch>
|
<item>
|
||||||
<verstretch>0</verstretch>
|
<spacer name="horizontalSpacer">
|
||||||
</sizepolicy>
|
<property name="orientation">
|
||||||
</property>
|
<enum>Qt::Horizontal</enum>
|
||||||
<property name="toolTip">
|
</property>
|
||||||
<string>A comma-separated list of categories that are not to
|
<property name="sizeHint" stdset="0">
|
||||||
be partitioned even if the number of items is larger than
|
<size>
|
||||||
the value shown above. This option can be used to
|
<width>40</width>
|
||||||
avoid collapsing hierarchical categories that have only
|
<height>20</height>
|
||||||
a few top-level elements.</string>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_81">
|
|
||||||
<property name="text">
|
|
||||||
<string>C&ategories with hierarchical items:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>opt_categories_using_hierarchy</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="EditWithComplete" name="opt_categories_using_hierarchy">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>A comma-separated list of categories in which items containing
|
|
||||||
periods are displayed in the Tag browser trees. For example, if
|
|
||||||
this box contains '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 in this box,
|
|
||||||
then the tags will be displayed each on their own line.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_10">
|
|
||||||
<item row="0" 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 &average ratings</string>
|
<string>Show &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 &tooltips</string>
|
<string>Show &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 &alternating row colors</string>
|
<string>Use &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">
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user