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_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
|
||||
# Provide a set of columns to be sorted on when calibre starts.
|
||||
# The argument is None if saved sort history is to be used
|
||||
|
@ -219,13 +219,14 @@ class IdLinksEditor(Dialog):
|
||||
|
||||
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'
|
||||
QAbstractListModel.__init__(self, parent)
|
||||
|
||||
self.fields = []
|
||||
self.db = db
|
||||
self.changed = False
|
||||
self.category_icons = category_icons
|
||||
|
||||
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)
|
||||
@ -255,8 +256,13 @@ class DisplayedFields(QAbstractListModel): # {{{
|
||||
return f'{name} ({field})'
|
||||
if role == Qt.ItemDataRole.CheckStateRole:
|
||||
return Qt.CheckState.Checked if visible else Qt.CheckState.Unchecked
|
||||
if role == Qt.ItemDataRole.DecorationRole and field.startswith('#'):
|
||||
return QIcon.ic('column.png')
|
||||
if role == Qt.ItemDataRole.DecorationRole:
|
||||
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
|
||||
|
||||
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): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
@ -572,6 +614,17 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
connect_lambda(self.qv_down_button.clicked, self,
|
||||
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.changed.connect(self.changed_signal)
|
||||
self.tabWidget.addTab(self.edit_rules,
|
||||
@ -672,6 +725,59 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.em_display_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()
|
||||
|
||||
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):
|
||||
from calibre.gui2.icon_theme import ChooseTheme
|
||||
d = ChooseTheme(self)
|
||||
@ -732,6 +838,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.display_model.initialize()
|
||||
self.em_display_model.initialize()
|
||||
self.qv_display_model.initialize()
|
||||
self.tb_display_model.initialize()
|
||||
db = self.gui.current_db
|
||||
mi = []
|
||||
try:
|
||||
@ -866,6 +973,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
self.display_model.commit()
|
||||
self.em_display_model.commit()
|
||||
self.qv_display_model.commit()
|
||||
self.tb_display_model.commit()
|
||||
self.edit_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)
|
||||
|
@ -1175,7 +1175,119 @@ using the Tab key. The F2 (Edit) key will still open the template editor.</p&
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</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">
|
||||
<property name="toolTip">
|
||||
<string>Choose how Tag browser subcategories are displayed when
|
||||
@ -1186,7 +1298,7 @@ if you never want subcategories</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>&Category partitioning method:</string>
|
||||
@ -1196,7 +1308,7 @@ if you never want subcategories</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Co&llapse when more items than:</string>
|
||||
@ -1206,7 +1318,7 @@ if you never want subcategories</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" 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
|
||||
@ -1217,7 +1329,7 @@ up into subcategories. If the partition method is set to disable, this value is
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" 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
|
||||
@ -1239,7 +1351,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" 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>
|
||||
@ -1271,7 +1383,7 @@ not set to first letter, this value is ignored. Set to zero to disable.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8111">
|
||||
<property name="text">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@ -1298,7 +1410,7 @@ a few top-level elements.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_81">
|
||||
<property name="text">
|
||||
<string>C&ategories with hierarchical items:</string>
|
||||
@ -1308,7 +1420,7 @@ a few top-level elements.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="EditWithComplete" name="opt_categories_using_hierarchy">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@ -1326,14 +1438,14 @@ then the tags will be displayed each on their own line.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QCheckBox" name="opt_tag_browser_show_tooltips">
|
||||
<property name="text">
|
||||
<string>Show &tooltips</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QCheckBox" name="opt_show_avg_rating">
|
||||
<property name="text">
|
||||
<string>Show &average ratings</string>
|
||||
@ -1343,7 +1455,7 @@ then the tags will be displayed each on their own line.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="opt_tag_browser_show_counts">
|
||||
<property name="toolTip">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<item row="12" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="opt_tag_browser_old_look">
|
||||
<property name="text">
|
||||
<string>Use &alternating row colors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</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">
|
||||
<property name="toolTip">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="2">
|
||||
<item row="14" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="opt_tag_browser_always_autocollapse">
|
||||
<property name="toolTip">
|
||||
<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>
|
||||
</widget>
|
||||
</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">
|
||||
<property name="toolTip">
|
||||
<string><p>When checked, the Tag browser can get keyboard focus, allowing
|
||||
@ -1401,7 +1513,7 @@ using the mouse.</p></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0" colspan="2">
|
||||
<item row="16" column="0" colspan="2">
|
||||
<widget class="QLabel" name="tb_focus_label">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">margin-left: 1.5em</string>
|
||||
@ -1414,7 +1526,7 @@ using the mouse.</p></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="cover_browser_tab">
|
||||
<attribute name="icon">
|
||||
|
@ -390,7 +390,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
if hidden_cats is None:
|
||||
hidden_cats = config['tag_browser_hidden_categories']
|
||||
self.hidden_categories = set()
|
||||
# strip out any non-existence field keys
|
||||
# strip out any non-existent field keys
|
||||
for cat in hidden_cats:
|
||||
if cat in db.field_metadata:
|
||||
self.hidden_categories.add(cat)
|
||||
@ -402,6 +402,12 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
self._run_rebuild()
|
||||
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={}):
|
||||
if self._build_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 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):
|
||||
'''
|
||||
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
|
||||
self.categories[category] = tb_categories[category]['name']
|
||||
|
||||
# Now build the list of fields in display order
|
||||
order = tweaks.get('tag_browser_category_default_sort', None)
|
||||
if order not in ('default', 'display_name', 'lookup_name'):
|
||||
print('Tweak tag_browser_category_default_sort is not valid. Ignored')
|
||||
order = 'default'
|
||||
if order == 'default':
|
||||
self.row_map = self.categories.keys()
|
||||
# Now build the list of fields in display order. A lot of this is to
|
||||
# maintain compatibility with the tweaks.
|
||||
order_pref = self.db.new_api.pref('tag_browser_category_order', None)
|
||||
if order_pref is not None:
|
||||
# Keys are in order
|
||||
self.row_map = self.get_ordered_categories()
|
||||
else:
|
||||
def key_func(val):
|
||||
if order == 'display_name':
|
||||
return icu_lower(self.db.field_metadata[val]['name'])
|
||||
return icu_lower(val[1:] if val.startswith('#') or val.startswith('@') else val)
|
||||
direction = tweaks.get('tag_browser_category_default_sort_direction', None)
|
||||
if direction not in ('ascending', 'descending'):
|
||||
print('Tweak tag_browser_category_default_sort_direction is not valid. Ignored')
|
||||
direction = 'ascending'
|
||||
self.row_map = sorted(self.categories, key=key_func, reverse=direction == 'descending')
|
||||
try:
|
||||
order = tweaks['tag_browser_category_order']
|
||||
if not isinstance(order, dict):
|
||||
raise TypeError()
|
||||
except:
|
||||
print('Tweak tag_browser_category_order is not valid. Ignored')
|
||||
order = {'*': 100}
|
||||
defvalue = order.get('*', 100)
|
||||
self.row_map = sorted(self.row_map, key=lambda x: order.get(x, defvalue))
|
||||
order = tweaks.get('tag_browser_category_default_sort', 'default')
|
||||
self.row_map = list(self.categories.keys())
|
||||
if order not in ('default', 'display_name', 'lookup_name'):
|
||||
print('Tweak tag_browser_category_default_sort is not valid. Ignored')
|
||||
order = 'default'
|
||||
if order != 'default':
|
||||
def key_func(val):
|
||||
if order == 'display_name':
|
||||
return icu_lower(self.db.field_metadata[val]['name'])
|
||||
return icu_lower(val[1:] if val.startswith('#') or val.startswith('@') else val)
|
||||
direction = tweaks.get('tag_browser_category_default_sort_direction', 'ascending')
|
||||
if direction not in ('ascending', 'descending'):
|
||||
print('Tweak tag_browser_category_default_sort_direction is not valid. Ignored')
|
||||
direction = 'ascending'
|
||||
self.row_map.sort(key=key_func, reverse=direction == 'descending')
|
||||
try:
|
||||
order = tweaks.get('tag_browser_category_order', {'*':1})
|
||||
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
|
||||
|
||||
def set_categories_filter(self, txt):
|
||||
|
Loading…
x
Reference in New Issue
Block a user