Visual improvements to the icon rules browser.

This commit is contained in:
Charles Haley 2025-01-22 14:07:02 +00:00
parent a6fda5e749
commit cf4034c2ff

View File

@ -17,18 +17,24 @@ from calibre.gui2 import gprefs
from calibre.gui2.preferences import ConfigTabWidget, ConfigWidgetBase from calibre.gui2.preferences import ConfigTabWidget, ConfigWidgetBase
from calibre.gui2.preferences.look_feel_tabs.tb_icon_rules_ui import Ui_Form from calibre.gui2.preferences.look_feel_tabs.tb_icon_rules_ui import Ui_Form
CATEGORY_COLUMN = 0 DELETED_COLUMN = 0
VALUE_COLUMN = 1 CATEGORY_COLUMN = 1
ICON_COLUMN = 2 VALUE_COLUMN = 2
FOR_CHILDREN_COLUMN = 3 ICON_COLUMN = 3
DELECTED_COLUMN = 4 FOR_CHILDREN_COLUMN = 4
HEADER_SECTION_COUNT = 5
class CategoryTableWidgetItem(QTableWidgetItem): class CategoryTableWidgetItem(QTableWidgetItem):
def __init__(self, txt): def __init__(self, lookup_name, category_icons, deleted_item, field_metadata):
self._lookup_name = lookup_name
txt = field_metadata[lookup_name]['name'] + f' ({lookup_name})'
super().__init__(txt) super().__init__(txt)
self._is_deleted = False self._is_deleted = False
self.setIcon(category_icons[lookup_name])
self._txt = txt
self._deleted_item = deleted_item
@property @property
def is_deleted(self): def is_deleted(self):
@ -37,6 +43,59 @@ class CategoryTableWidgetItem(QTableWidgetItem):
@is_deleted.setter @is_deleted.setter
def is_deleted(self, to_what): def is_deleted(self, to_what):
self._is_deleted = to_what self._is_deleted = to_what
if to_what:
self._deleted_item.setIcon(QIcon.cached_icon('trash.png'))
else:
self._deleted_item.setIcon(QIcon())
@property
def lookup_name(self):
return self._lookup_name
class ValueTableWidgetItem(QTableWidgetItem):
def __init__(self, txt):
self._key = txt
is_template = txt == TEMPLATE_ICON_INDICATOR
super().__init__(_('{template}') if is_template else txt)
self.setIcon(QIcon.cached_icon('debug.png' if is_template else 'icon_choose.png'))
@property
def real_value(self):
return self._key
class IconFileTableWidgetItem(QTableWidgetItem):
def __init__(self, icon_file, value):
self._key = icon_file
is_template = value == TEMPLATE_ICON_INDICATOR
super().__init__(icon_file)
self.setToolTip(icon_file)
if is_template:
self.setIcon(QIcon.cached_icon('blank.png'))
else:
p = os.path.join(config_dir, 'tb_icons', icon_file)
if os.path.exists(p):
icon = QIcon.ic(p)
self.setIcon(icon)
else:
self.setIcon(QIcon.cached_icon('dialog_error.png'))
self.setToolTip(icon_file + '\n' + _("This icon file doesn't exist"))
class ChildrenTableWidgetItem(QTableWidgetItem):
def __init__(self, txt, for_child):
super().__init__(txt)
if for_child is None:
icon = QIcon()
elif for_child:
icon = QIcon.cached_icon('ok.png')
else:
icon = QIcon.cached_icon('list_remove.png')
self.setIcon(QIcon.cached_icon(icon))
class TbIconRulesTab(ConfigTabWidget, Ui_Form): class TbIconRulesTab(ConfigTabWidget, Ui_Form):
@ -49,12 +108,26 @@ class TbIconRulesTab(ConfigTabWidget, Ui_Form):
self.rules_table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) self.rules_table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
self.rules_table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.rules_table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
self.rules_table.setColumnCount(4) self.rules_table.setColumnCount(HEADER_SECTION_COUNT)
self.rules_table.setHorizontalHeaderLabels((_('Category'), _('Value'), _('Icon file or template'), self.rules_table.setHorizontalHeaderLabels(
_('Use for children'))) ('', _('Category'), _('Value'), _('Icon file or template'),_('For children')))
self.rules_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.rules_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.rules_table.customContextMenuRequested.connect(self.show_context_menu) self.rules_table.customContextMenuRequested.connect(self.show_context_menu)
for i in range(0, HEADER_SECTION_COUNT):
item = self.rules_table.horizontalHeaderItem(i)
if i == DELETED_COLUMN:
item.setIcon(QIcon.cached_icon('trash.png'))
item.setToolTip(_('Show this icon if the rule is deleted'))
elif i == CATEGORY_COLUMN:
item.setToolTip(_('The name of the category'))
elif i == VALUE_COLUMN:
item.setToolTip(_('The value in the category the rule is applied to'))
elif i == ICON_COLUMN:
item.setToolTip(_('The file name of the icon or the text of the template'))
elif i == FOR_CHILDREN_COLUMN:
item.setToolTip(_('Indicates whether the rule apples to child values'))
# Capture clicks on the horizontal header to sort the table columns # Capture clicks on the horizontal header to sort the table columns
hh = self.rules_table.horizontalHeader() hh = self.rules_table.horizontalHeader()
hh.sectionResized.connect(self.table_column_resized) hh.sectionResized.connect(self.table_column_resized)
@ -68,22 +141,26 @@ class TbIconRulesTab(ConfigTabWidget, Ui_Form):
self.tb_icon_rules_groupbox.setContentsMargins(0, 0, 0, 0) self.tb_icon_rules_groupbox.setContentsMargins(0, 0, 0, 0)
self.tb_icon_rules_gridlayout.setContentsMargins(2, 2, 2, 2) self.tb_icon_rules_gridlayout.setContentsMargins(2, 2, 2, 2)
field_metadata = gui.current_db.field_metadata
category_icons = gui.tags_view.model().category_custom_icons
v = gprefs['tags_browser_value_icons'] v = gprefs['tags_browser_value_icons']
row = 0 row = 0
for category,vdict in v.items(): for category,vdict in v.items():
for value in vdict: for value in vdict:
self.rules_table.setRowCount(row + 1) self.rules_table.setRowCount(row + 1)
d = v[category][value] d = v[category][value]
self.rules_table.setItem(row, 0, CategoryTableWidgetItem(category)) deleted_item = QTableWidgetItem(None)
self.rules_table.setItem(row, 1, QTableWidgetItem(value)) self.rules_table.setItem(row, DELETED_COLUMN, deleted_item)
self.rules_table.setItem(row, 2, QTableWidgetItem(d[0])) self.rules_table.setItem(row, CATEGORY_COLUMN,
CategoryTableWidgetItem(category, category_icons, deleted_item, field_metadata))
self.rules_table.setItem(row, VALUE_COLUMN, ValueTableWidgetItem(value))
self.rules_table.setItem(row, ICON_COLUMN, IconFileTableWidgetItem(d[0], value))
if value == TEMPLATE_ICON_INDICATOR: if value == TEMPLATE_ICON_INDICATOR:
txt = '' txt = ''
else: else:
txt = _('Yes') if d[1] else _('No') txt = _('Yes') if d[1] else _('No')
item = QTableWidgetItem(txt) item = ChildrenTableWidgetItem(txt, None if value == TEMPLATE_ICON_INDICATOR else d[1])
item.setTextAlignment(Qt.AlignmentFlag.AlignCenter|Qt.AlignmentFlag.AlignVCenter) self.rules_table.setItem(row, FOR_CHILDREN_COLUMN, item)
self.rules_table.setItem(row, 3, item)
row += 1 row += 1
self.category_order = 1 self.category_order = 1
@ -132,7 +209,6 @@ class TbIconRulesTab(ConfigTabWidget, Ui_Form):
if idx.isValid(): if idx.isValid():
item = self.rules_table.item(idx.row(), CATEGORY_COLUMN) item = self.rules_table.item(idx.row(), CATEGORY_COLUMN)
item.is_deleted = True item.is_deleted = True
item.setIcon(QIcon.ic('trash.png'))
self.changed_signal.emit() self.changed_signal.emit()
def undo_delete(self): def undo_delete(self):
@ -140,7 +216,6 @@ class TbIconRulesTab(ConfigTabWidget, Ui_Form):
if idx.isValid(): if idx.isValid():
item = self.rules_table.item(idx.row(), CATEGORY_COLUMN) item = self.rules_table.item(idx.row(), CATEGORY_COLUMN)
item.is_deleted = False item.is_deleted = False
item.setIcon(QIcon())
def table_column_resized(self, col, old, new): def table_column_resized(self, col, old, new):
self.table_column_widths = [] self.table_column_widths = []
@ -184,7 +259,7 @@ class TbIconRulesTab(ConfigTabWidget, Ui_Form):
for r in range(0, self.rules_table.rowCount()): for r in range(0, self.rules_table.rowCount()):
cat_item = self.rules_table.item(r, CATEGORY_COLUMN) cat_item = self.rules_table.item(r, CATEGORY_COLUMN)
if cat_item.is_deleted: if cat_item.is_deleted:
val = self.rules_table.item(r, VALUE_COLUMN).text() val = self.rules_table.item(r, VALUE_COLUMN).real_value
if val != TEMPLATE_ICON_INDICATOR: if val != TEMPLATE_ICON_INDICATOR:
icon_file = self.rules_table.item(r, ICON_COLUMN).text() icon_file = self.rules_table.item(r, ICON_COLUMN).text()
path = os.path.join(config_dir, 'tb_icons', icon_file) path = os.path.join(config_dir, 'tb_icons', icon_file)
@ -192,7 +267,7 @@ class TbIconRulesTab(ConfigTabWidget, Ui_Form):
os.remove(path) os.remove(path)
except: except:
pass pass
v[cat_item.text()].pop(val, None) v[cat_item.lookup_name].pop(val, None)
# Remove categories with no rules # Remove categories with no rules
for category in list(v.keys()): for category in list(v.keys()):
if len(v[category]) == 0: if len(v[category]) == 0: