mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Tag browser: Move the preferences for controlling the order and display of categories in the Tag browser from Preferences->Tweaks to Preferences->Look & feel->Tag browser. Fixes #1987235 [Enhancement Request: Easier way to rearrange Tag Browser](https://bugs.launchpad.net/calibre/+bug/1987235)
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
fae1682ed8
@ -126,31 +126,6 @@ categories_collapsed_name_template = r'{first.sort:shorten(4,,0)} - {last.sort:s
|
|||||||
categories_collapsed_rating_template = r'{first.avg_rating:4.2f:ifempty(0)} - {last.avg_rating:4.2f:ifempty(0)}'
|
categories_collapsed_rating_template = r'{first.avg_rating:4.2f:ifempty(0)} - {last.avg_rating:4.2f:ifempty(0)}'
|
||||||
categories_collapsed_popularity_template = r'{first.count:d} - {last.count:d}'
|
categories_collapsed_popularity_template = r'{first.count:d} - {last.count:d}'
|
||||||
|
|
||||||
#: Control order of categories in the Tag browser
|
|
||||||
# Change the following dict to change the order that categories are displayed in
|
|
||||||
# the Tag browser. Items are named using their lookup name, and will be sorted
|
|
||||||
# using the number supplied. The lookup name '*' stands for all names that
|
|
||||||
# otherwise do not appear. Two names with the same value will be sorted
|
|
||||||
# using the default order, the one specified by tag_browser_category_default_sort.
|
|
||||||
# Example:
|
|
||||||
# tag_browser_category_order = {'series':1, 'tags':2, '*':3}
|
|
||||||
#
|
|
||||||
# results in the order series, tags, then everything else in default order.
|
|
||||||
# The tweak tag_browser_category_default_sort specifies the sort order before
|
|
||||||
# applying the category order from the dict. The allowed values are:
|
|
||||||
# tag_browser_category_default_sort = 'default' # The calibre default order
|
|
||||||
# tag_browser_category_default_sort = 'display_name' # Sort by the display name of the category
|
|
||||||
# tag_browser_category_default_sort = 'lookup_name' # Sort by the lookup name of the category
|
|
||||||
#
|
|
||||||
# In addition and if the category default sort is not 'default' you can specify
|
|
||||||
# whether the sort is ascending or descending. This is ignored if the sort is 'default'.
|
|
||||||
# tag_browser_category_default_sort_direction = 'ascending'
|
|
||||||
# tag_browser_category_default_sort_direction = 'descending'
|
|
||||||
tag_browser_category_order = {'*':1}
|
|
||||||
tag_browser_category_default_sort = 'default'
|
|
||||||
tag_browser_category_default_sort_direction = 'ascending'
|
|
||||||
|
|
||||||
|
|
||||||
#: Specify columns to sort the booklist by on startup
|
#: Specify columns to sort the booklist by on startup
|
||||||
# Provide a set of columns to be sorted on when calibre starts.
|
# Provide a set of columns to be sorted on when calibre starts.
|
||||||
# The argument is None if saved sort history is to be used
|
# The argument is None if saved sort history is to be used
|
||||||
|
@ -219,13 +219,14 @@ class IdLinksEditor(Dialog):
|
|||||||
|
|
||||||
class DisplayedFields(QAbstractListModel): # {{{
|
class DisplayedFields(QAbstractListModel): # {{{
|
||||||
|
|
||||||
def __init__(self, db, parent=None, pref_name=None):
|
def __init__(self, db, parent=None, pref_name=None, category_icons=None):
|
||||||
self.pref_name = pref_name or 'book_display_fields'
|
self.pref_name = pref_name or 'book_display_fields'
|
||||||
QAbstractListModel.__init__(self, parent)
|
QAbstractListModel.__init__(self, parent)
|
||||||
|
|
||||||
self.fields = []
|
self.fields = []
|
||||||
self.db = db
|
self.db = db
|
||||||
self.changed = False
|
self.changed = False
|
||||||
|
self.category_icons = category_icons
|
||||||
|
|
||||||
def get_field_list(self, use_defaults=False):
|
def get_field_list(self, use_defaults=False):
|
||||||
return get_field_list(self.db.field_metadata, use_defaults=use_defaults, pref_name=self.pref_name)
|
return get_field_list(self.db.field_metadata, use_defaults=use_defaults, pref_name=self.pref_name)
|
||||||
@ -255,8 +256,13 @@ class DisplayedFields(QAbstractListModel): # {{{
|
|||||||
return f'{name} ({field})'
|
return f'{name} ({field})'
|
||||||
if role == Qt.ItemDataRole.CheckStateRole:
|
if role == Qt.ItemDataRole.CheckStateRole:
|
||||||
return Qt.CheckState.Checked if visible else Qt.CheckState.Unchecked
|
return Qt.CheckState.Checked if visible else Qt.CheckState.Unchecked
|
||||||
if role == Qt.ItemDataRole.DecorationRole and field.startswith('#'):
|
if role == Qt.ItemDataRole.DecorationRole:
|
||||||
return QIcon.ic('column.png')
|
if self.category_icons:
|
||||||
|
icon = self.category_icons.get(field, None)
|
||||||
|
if icon is not None:
|
||||||
|
return icon
|
||||||
|
if field.startswith('#'):
|
||||||
|
return QIcon.ic('column.png')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def toggle_all(self, show=True):
|
def toggle_all(self, show=True):
|
||||||
@ -356,6 +362,42 @@ class QVDisplayedFields(DisplayedFields): # {{{
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
|
class TBDisplayedFields(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
|
||||||
|
cat_ord = tv.model().get_ordered_categories(use_defaults=use_defaults,
|
||||||
|
pref_data_override=pref_data_override)
|
||||||
|
if use_defaults:
|
||||||
|
hc = []
|
||||||
|
elif pref_data_override:
|
||||||
|
hc = [k for k,v in pref_data_override if not v]
|
||||||
|
else:
|
||||||
|
hc = tv.hidden_categories
|
||||||
|
|
||||||
|
self.beginResetModel()
|
||||||
|
self.fields = [[x, x not in hc] for x in cat_ord]
|
||||||
|
self.endResetModel()
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
|
def is_standard_category(self, key):
|
||||||
|
return self.gui.tags_view.model().is_standard_category(key)
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
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.new_api.set_pref('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})
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class Background(QWidget): # {{{
|
class Background(QWidget): # {{{
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
@ -572,6 +614,17 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
connect_lambda(self.qv_down_button.clicked, self,
|
connect_lambda(self.qv_down_button.clicked, self,
|
||||||
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_order,
|
||||||
|
category_icons=self.gui.tags_view.model().category_custom_icons)
|
||||||
|
self.tb_display_model.dataChanged.connect(self.changed_signal)
|
||||||
|
self.tb_display_order.setModel(self.tb_display_model)
|
||||||
|
self.tb_reset_layout_button.clicked.connect(self.tb_reset_layout)
|
||||||
|
self.tb_export_layout_button.clicked.connect(self.tb_export_layout)
|
||||||
|
self.tb_import_layout_button.clicked.connect(self.tb_import_layout)
|
||||||
|
self.tb_up_button.clicked.connect(self.tb_up_button_clicked)
|
||||||
|
self.tb_down_button.clicked.connect(self.tb_down_button_clicked)
|
||||||
|
|
||||||
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,
|
||||||
@ -672,6 +725,59 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.em_display_model.initialize(use_defaults=True)
|
self.em_display_model.initialize(use_defaults=True)
|
||||||
self.changed_signal.emit()
|
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()
|
||||||
|
|
||||||
|
def tb_down_button_clicked(self):
|
||||||
|
idx = self.tb_display_order.currentIndex()
|
||||||
|
if idx.isValid():
|
||||||
|
row = idx.row()
|
||||||
|
model = self.tb_display_model
|
||||||
|
fields = model.fields
|
||||||
|
key = fields[row][0]
|
||||||
|
if not model.is_standard_category(key):
|
||||||
|
return
|
||||||
|
if row < len(fields) and model.is_standard_category(fields[row+1][0]):
|
||||||
|
move_field_down(self.tb_display_order, model)
|
||||||
|
|
||||||
|
def tb_up_button_clicked(self):
|
||||||
|
idx = self.tb_display_order.currentIndex()
|
||||||
|
if idx.isValid():
|
||||||
|
row = idx.row()
|
||||||
|
model = self.tb_display_model
|
||||||
|
fields = model.fields
|
||||||
|
key = fields[row][0]
|
||||||
|
if not model.is_standard_category(key):
|
||||||
|
return
|
||||||
|
move_field_up(self.tb_display_order, model)
|
||||||
|
|
||||||
def choose_icon_theme(self):
|
def choose_icon_theme(self):
|
||||||
from calibre.gui2.icon_theme import ChooseTheme
|
from calibre.gui2.icon_theme import ChooseTheme
|
||||||
d = ChooseTheme(self)
|
d = ChooseTheme(self)
|
||||||
@ -732,6 +838,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.display_model.initialize()
|
self.display_model.initialize()
|
||||||
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()
|
||||||
db = self.gui.current_db
|
db = self.gui.current_db
|
||||||
mi = []
|
mi = []
|
||||||
try:
|
try:
|
||||||
@ -866,6 +973,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.display_model.commit()
|
self.display_model.commit()
|
||||||
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.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)
|
||||||
|
@ -1175,7 +1175,119 @@ using the Tab key. The F2 (Edit) key will still open the template editor.</p&
|
|||||||
<property name="fieldGrowthPolicy">
|
<property name="fieldGrowthPolicy">
|
||||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||||
</property>
|
</property>
|
||||||
<item row="1" column="1">
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Select the categories to display in the Tag browser and their order</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>User categories and Saved searches cannot be moved</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QToolButton" name="tb_down_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Move down</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-down.png</normaloff>:/images/arrow-down.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QToolButton" name="tb_up_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Move up</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../../resources/images.qrc">
|
||||||
|
<normaloff>:/images/arrow-up.png</normaloff>:/images/arrow-up.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" rowspan="3">
|
||||||
|
<widget class="QListView" name="tb_display_order">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="tb_reset_layout_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_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 column order for each one. Columns
|
||||||
|
in the imported list that aren't in the current library are ignored. Columns in
|
||||||
|
the library that are not in the imported list are put at the end and marked
|
||||||
|
as displayable.</p></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import list</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="tb_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 column order 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>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
<widget class="QComboBox" name="opt_tags_browser_partition_method">
|
<widget class="QComboBox" name="opt_tags_browser_partition_method">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Choose how Tag browser subcategories are displayed when
|
<string>Choose how Tag browser subcategories are displayed when
|
||||||
@ -1186,7 +1298,7 @@ if you never want subcategories</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_9">
|
<widget class="QLabel" name="label_9">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Category partitioning method:</string>
|
<string>&Category partitioning method:</string>
|
||||||
@ -1196,7 +1308,7 @@ if you never want subcategories</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_10">
|
<widget class="QLabel" name="label_10">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Co&llapse when more items than:</string>
|
<string>Co&llapse when more items than:</string>
|
||||||
@ -1206,7 +1318,7 @@ if you never want subcategories</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QSpinBox" name="opt_tags_browser_collapse_at">
|
<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>If a Tag browser category has more than this number of items, it is divided
|
||||||
@ -1217,7 +1329,7 @@ up into subcategories. If the partition method is set to disable, this value is
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_10">
|
<widget class="QLabel" name="label_10">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Combine letters &when fewer items than:</string>
|
<string>Combine letters &when fewer items than:</string>
|
||||||
@ -1227,7 +1339,7 @@ up into subcategories. If the partition method is set to disable, this value is
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QSpinBox" name="opt_tags_browser_collapse_fl_at">
|
<widget class="QSpinBox" name="opt_tags_browser_collapse_fl_at">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>If collapsing by first letter, combine adjacent letters together if
|
<string>If collapsing by first letter, combine adjacent letters together if
|
||||||
@ -1239,7 +1351,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Spacing between &items:</string>
|
<string>Spacing between &items:</string>
|
||||||
@ -1249,7 +1361,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="6" 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>
|
||||||
@ -1271,7 +1383,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="7" column="0">
|
||||||
<widget class="QLabel" name="label_8111">
|
<widget class="QLabel" name="label_8111">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Categories &not to partition:</string>
|
<string>Categories &not to partition:</string>
|
||||||
@ -1281,7 +1393,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse">
|
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
@ -1298,7 +1410,7 @@ a few top-level elements.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_81">
|
<widget class="QLabel" name="label_81">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>C&ategories with hierarchical items:</string>
|
<string>C&ategories with hierarchical items:</string>
|
||||||
@ -1308,7 +1420,7 @@ a few top-level elements.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="EditWithComplete" name="opt_categories_using_hierarchy">
|
<widget class="EditWithComplete" name="opt_categories_using_hierarchy">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
@ -1326,14 +1438,14 @@ then the tags will be displayed each on their own line.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="9" column="0">
|
||||||
<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="9" column="0">
|
<item row="10" 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>
|
||||||
@ -1343,7 +1455,7 @@ then the tags will be displayed each on their own line.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0" colspan="2">
|
<item row="11" column="0" colspan="2">
|
||||||
<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
|
||||||
@ -1355,14 +1467,14 @@ see the counts by hovering your mouse over any item.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0" colspan="2">
|
<item row="12" column="0" colspan="2">
|
||||||
<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="12" column="0" colspan="2">
|
<item row="13" column="0" colspan="2">
|
||||||
<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
|
||||||
@ -1375,7 +1487,7 @@ see the counts by hovering your mouse over any item.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="0" colspan="2">
|
<item row="14" column="0" colspan="2">
|
||||||
<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
|
||||||
@ -1387,7 +1499,7 @@ see the counts by hovering your mouse over any item.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="0" colspan="2">
|
<item row="15" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="opt_tag_browser_allow_keyboard_focus">
|
<widget class="QCheckBox" name="opt_tag_browser_allow_keyboard_focus">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><p>When checked, the Tag browser can get keyboard focus, allowing
|
<string><p>When checked, the Tag browser can get keyboard focus, allowing
|
||||||
@ -1401,7 +1513,7 @@ using the mouse.</p></string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="15" column="0" colspan="2">
|
<item row="16" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="tb_focus_label">
|
<widget class="QLabel" name="tb_focus_label">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">margin-left: 1.5em</string>
|
<string notr="true">margin-left: 1.5em</string>
|
||||||
@ -1414,7 +1526,7 @@ using the mouse.</p></string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="cover_browser_tab">
|
<widget class="QWidget" name="cover_browser_tab">
|
||||||
<attribute name="icon">
|
<attribute name="icon">
|
||||||
|
@ -390,7 +390,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
if hidden_cats is None:
|
if hidden_cats is None:
|
||||||
hidden_cats = config['tag_browser_hidden_categories']
|
hidden_cats = config['tag_browser_hidden_categories']
|
||||||
self.hidden_categories = set()
|
self.hidden_categories = set()
|
||||||
# strip out any non-existence field keys
|
# strip out any non-existent field keys
|
||||||
for cat in hidden_cats:
|
for cat in hidden_cats:
|
||||||
if cat in db.field_metadata:
|
if cat in db.field_metadata:
|
||||||
self.hidden_categories.add(cat)
|
self.hidden_categories.add(cat)
|
||||||
@ -402,6 +402,12 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
self._run_rebuild()
|
self._run_rebuild()
|
||||||
self.endResetModel()
|
self.endResetModel()
|
||||||
|
|
||||||
|
def set_hidden_categories(self, cats):
|
||||||
|
self.beginResetModel()
|
||||||
|
self.hidden_categories = cats
|
||||||
|
self._run_rebuild()
|
||||||
|
self.endResetModel()
|
||||||
|
|
||||||
def rebuild_node_tree(self, state_map={}):
|
def rebuild_node_tree(self, state_map={}):
|
||||||
if self._build_in_progress:
|
if self._build_in_progress:
|
||||||
print('Tag browser build already in progress')
|
print('Tag browser build already in progress')
|
||||||
@ -1118,6 +1124,33 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
return self.db.search('', return_matches=True, sort_results=False)
|
return self.db.search('', return_matches=True, sort_results=False)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def is_standard_category(self, key):
|
||||||
|
return not (key.startswith('@') or key == 'search')
|
||||||
|
|
||||||
|
def get_ordered_categories(self, use_defaults=False, pref_data_override=None):
|
||||||
|
if use_defaults:
|
||||||
|
tbo = []
|
||||||
|
elif pref_data_override:
|
||||||
|
tbo = [k for k,_ in pref_data_override]
|
||||||
|
else:
|
||||||
|
tbo = self.db.new_api.pref('tag_browser_category_order', [])
|
||||||
|
disp_cats = self.categories.keys()
|
||||||
|
cat_ord = []
|
||||||
|
# Do the standard categories first
|
||||||
|
# Verify all the columns in the pref are actually in the tag browser
|
||||||
|
for key in tbo:
|
||||||
|
if self.is_standard_category(key) and key in disp_cats:
|
||||||
|
cat_ord.append(key)
|
||||||
|
# Add any new standard cats to the order pref at the end of the list
|
||||||
|
for key in disp_cats:
|
||||||
|
if key not in cat_ord and self.is_standard_category(key):
|
||||||
|
cat_ord.append(key)
|
||||||
|
# Now add the non-standard cats (user cats and search)
|
||||||
|
for key in disp_cats:
|
||||||
|
if not self.is_standard_category(key):
|
||||||
|
cat_ord.append(key)
|
||||||
|
return cat_ord
|
||||||
|
|
||||||
def _get_category_nodes(self, sort):
|
def _get_category_nodes(self, sort):
|
||||||
'''
|
'''
|
||||||
Called by __init__. Do not directly call this method.
|
Called by __init__. Do not directly call this method.
|
||||||
@ -1157,32 +1190,37 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
if category in data: # The search category can come and go
|
if category in data: # The search category can come and go
|
||||||
self.categories[category] = tb_categories[category]['name']
|
self.categories[category] = tb_categories[category]['name']
|
||||||
|
|
||||||
# Now build the list of fields in display order
|
# Now build the list of fields in display order. A lot of this is to
|
||||||
order = tweaks.get('tag_browser_category_default_sort', None)
|
# maintain compatibility with the tweaks.
|
||||||
if order not in ('default', 'display_name', 'lookup_name'):
|
order_pref = self.db.new_api.pref('tag_browser_category_order', None)
|
||||||
print('Tweak tag_browser_category_default_sort is not valid. Ignored')
|
if order_pref is not None:
|
||||||
order = 'default'
|
# Keys are in order
|
||||||
if order == 'default':
|
self.row_map = self.get_ordered_categories()
|
||||||
self.row_map = self.categories.keys()
|
|
||||||
else:
|
else:
|
||||||
def key_func(val):
|
order = tweaks.get('tag_browser_category_default_sort', 'default')
|
||||||
if order == 'display_name':
|
self.row_map = list(self.categories.keys())
|
||||||
return icu_lower(self.db.field_metadata[val]['name'])
|
if order not in ('default', 'display_name', 'lookup_name'):
|
||||||
return icu_lower(val[1:] if val.startswith('#') or val.startswith('@') else val)
|
print('Tweak tag_browser_category_default_sort is not valid. Ignored')
|
||||||
direction = tweaks.get('tag_browser_category_default_sort_direction', None)
|
order = 'default'
|
||||||
if direction not in ('ascending', 'descending'):
|
if order != 'default':
|
||||||
print('Tweak tag_browser_category_default_sort_direction is not valid. Ignored')
|
def key_func(val):
|
||||||
direction = 'ascending'
|
if order == 'display_name':
|
||||||
self.row_map = sorted(self.categories, key=key_func, reverse=direction == 'descending')
|
return icu_lower(self.db.field_metadata[val]['name'])
|
||||||
try:
|
return icu_lower(val[1:] if val.startswith('#') or val.startswith('@') else val)
|
||||||
order = tweaks['tag_browser_category_order']
|
direction = tweaks.get('tag_browser_category_default_sort_direction', 'ascending')
|
||||||
if not isinstance(order, dict):
|
if direction not in ('ascending', 'descending'):
|
||||||
raise TypeError()
|
print('Tweak tag_browser_category_default_sort_direction is not valid. Ignored')
|
||||||
except:
|
direction = 'ascending'
|
||||||
print('Tweak tag_browser_category_order is not valid. Ignored')
|
self.row_map.sort(key=key_func, reverse=direction == 'descending')
|
||||||
order = {'*': 100}
|
try:
|
||||||
defvalue = order.get('*', 100)
|
order = tweaks.get('tag_browser_category_order', {'*':1})
|
||||||
self.row_map = sorted(self.row_map, key=lambda x: order.get(x, defvalue))
|
if not isinstance(order, dict):
|
||||||
|
raise TypeError()
|
||||||
|
except:
|
||||||
|
print('Tweak tag_browser_category_order is not valid. Ignored')
|
||||||
|
order = {'*': 1000}
|
||||||
|
defvalue = order.get('*', 1000)
|
||||||
|
self.row_map.sort(key=lambda x: order.get(x, defvalue))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def set_categories_filter(self, txt):
|
def set_categories_filter(self, txt):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user