diff --git a/resources/default_tweaks.py b/resources/default_tweaks.py index 437eb4834a..68846f1122 100644 --- a/resources/default_tweaks.py +++ b/resources/default_tweaks.py @@ -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 diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 7a7c92cfde..b723c450c7 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -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'), + _('
Could not write field list. Error:
%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'),
+ _('
Could not read field list. Error:
%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)
diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui
index 1ffeed4ce3..4dd4105739 100644
--- a/src/calibre/gui2/preferences/look_feel.ui
+++ b/src/calibre/gui2/preferences/look_feel.ui
@@ -1175,7 +1175,119 @@ using the Tab key. The F2 (Edit) key will still open the template editor.</p&