From ee21e8411051c71ff8d81cab4f3fe061916472fe Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:12:22 +0100 Subject: [PATCH 1/8] ... --- src/calibre/gui2/tag_browser/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index ba9d713902..283b9d44ba 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -458,7 +458,7 @@ class TagsModel(QAbstractItemModel): # {{{ def remove_value_icon(self, key, value, file_name): self.value_icons = self.prefs['tags_browser_value_icons'] - self.value_icons.get(key).pop(value, None) + self.value_icons.get(key, {}).pop(value, None) self.prefs['tags_browser_value_icons'] =self.value_icons if file_name is not None: path = os.path.join(config_dir, 'tb_icons', file_name) From a503f07bfdc225571f087d454be46b2453ba2027 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:09:33 +0100 Subject: [PATCH 2/8] DRY --- src/calibre/gui2/tag_browser/model.py | 28 ++++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index 283b9d44ba..5ad4cf1618 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -424,10 +424,10 @@ class TagsModel(QAbstractItemModel): # {{{ ''' old_icon = self.prefs['tags_browser_category_icons'].get(old_key, None) if old_icon is not None: - old_path = os.path.join(config_dir, 'tb_icons', old_icon) + old_path = os.path.join(self.icon_config_dir, old_icon) _, ext = os.path.splitext(old_path) new_icon = new_key + ext - new_path = os.path.join(config_dir, 'tb_icons', new_icon) + new_path = os.path.join(self.icon_config_dir, new_icon) os.replace(old_path, new_path) self.set_custom_category_icon(new_key, new_icon) self.set_custom_category_icon(old_key, None) @@ -456,31 +456,27 @@ class TagsModel(QAbstractItemModel): # {{{ self.value_icon_cache.pop(file_name, None) self.prefs['tags_browser_value_icons'] = self.value_icons - def remove_value_icon(self, key, value, file_name): - self.value_icons = self.prefs['tags_browser_value_icons'] - self.value_icons.get(key, {}).pop(value, None) - self.prefs['tags_browser_value_icons'] =self.value_icons + def _remove_icon_file(self, file_name): if file_name is not None: - path = os.path.join(config_dir, 'tb_icons', file_name) + path = os.path.join(self.icon_config_dir, file_name) try: os.remove(path) except: pass + def remove_value_icon(self, key, value, file_name): + self.value_icons = self.prefs['tags_browser_value_icons'] + self.value_icons.get(key, {}).pop(value, None) + self.prefs['tags_browser_value_icons'] =self.value_icons + self._remove_icon_file(file_name) + def set_custom_category_icon(self, key, path): d = self.prefs['tags_browser_category_icons'] if path: d[key] = path - self.category_custom_icons[key] = QIcon(os.path.join(config_dir, - 'tb_icons', path)) + self.category_custom_icons[key] = QIcon(os.path.join(self.icon_config_dir, path)) else: - if key in d: - path = os.path.join(config_dir, 'tb_icons', d[key]) - try: - os.remove(path) - except: - pass - d.pop(key, None) + self._remove_icon_file(d.pop(key, None)) self.category_custom_icons.pop(key, None) self.prefs['tags_browser_category_icons'] = d From e9dd0c5c4f150956e3037e161f027bc3ab1fa95b Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:14:33 +0100 Subject: [PATCH 3/8] improve reset to default icons --- src/calibre/gui2/tag_browser/model.py | 9 +++++++++ src/calibre/gui2/tag_browser/view.py | 12 ++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index 5ad4cf1618..a58480e791 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -470,6 +470,15 @@ class TagsModel(QAbstractItemModel): # {{{ self.prefs['tags_browser_value_icons'] =self.value_icons self._remove_icon_file(file_name) + def remove_all_value_icons(self, key): + self.value_icons = self.prefs['tags_browser_value_icons'] + values = self.value_icons.pop(key, {}) + self.value_icons[key] = {} + self.prefs['tags_browser_value_icons'] = self.value_icons + values.pop(TEMPLATE_ICON_INDICATOR, None) + for file_name,child in values.values(): + self._remove_icon_file(file_name) + def set_custom_category_icon(self, key, path): d = self.prefs['tags_browser_category_icons'] if path: diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index d691cbcd70..dacfee0827 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -734,15 +734,19 @@ class TagsView(QTreeView): # {{{ self._model.set_value_icon(key, item_val, icon_file_name, bool(for_children)) self.recount() return - if action == 'clear_icon': + if action == 'clear_icon_value': if index is not None: val, icon_name = make_icon_name(key, index) self._model.remove_value_icon(key, val, icon_name) else: - self._model.set_custom_category_icon(key, None) self._model.remove_value_icon(key, TEMPLATE_ICON_INDICATOR, None) self.recount() return + if action == 'clear_icon': + self._model.set_custom_category_icon(key, None) + self._model.remove_all_value_icons(key) + self.recount() + return if action == 'edit_item_no_vl': item = self.model().get_node(index) @@ -1283,7 +1287,7 @@ class TagsView(QTreeView): # {{{ key=key, index=index, category=category, extra=(icon_name, True))) ma.setEnabled(icon_name is not None and not for_child) ma = im.addAction(_('Use the default icon for {}').format(for_name), - partial(self.context_menu_handler, action='clear_icon', + partial(self.context_menu_handler, action='clear_icon_value', key=key, index=index, category=category)) ma.setEnabled(name is not None and icon_name is not None) im.addSection(_('Defaults')) @@ -1291,7 +1295,7 @@ class TagsView(QTreeView): # {{{ partial(self.context_menu_handler, action='set_icon', key=key, index=index, category=None, extra=(None, None))) ma = im.addAction(_('Use the category icon for the default value icon'), - partial(self.context_menu_handler, action='clear_icon', + partial(self.context_menu_handler, action='clear_icon_value', key=key, index=None, category=category)) ma.setEnabled(self._model.value_icons.get(key, {}).get(TEMPLATE_ICON_INDICATOR) is not None) im.addSeparator() From 6ecf4e88581d560b0ecb98e1320409e45587a34b Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Sat, 18 Jan 2025 14:14:43 +0100 Subject: [PATCH 4/8] ... --- src/calibre/gui2/tag_browser/view.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index dacfee0827..ab1ba9b2f6 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -729,10 +729,9 @@ class TagsView(QTreeView): # {{{ icon_file_name = desired_file_name if index is None: # category icon self._model.set_custom_category_icon(key, str(icon_file_name)) - self.recount() else: # value icon self._model.set_value_icon(key, item_val, icon_file_name, bool(for_children)) - self.recount() + self.recount() return if action == 'clear_icon_value': if index is not None: From a1aba91928bd64169ed635d255193e56456e0c88 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Sat, 18 Jan 2025 14:21:58 +0100 Subject: [PATCH 5/8] add action to reset all value icons --- src/calibre/gui2/tag_browser/view.py | 32 ++++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index ab1ba9b2f6..a9fd94ef8f 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -733,17 +733,17 @@ class TagsView(QTreeView): # {{{ self._model.set_value_icon(key, item_val, icon_file_name, bool(for_children)) self.recount() return - if action == 'clear_icon_value': - if index is not None: - val, icon_name = make_icon_name(key, index) - self._model.remove_value_icon(key, val, icon_name) - else: - self._model.remove_value_icon(key, TEMPLATE_ICON_INDICATOR, None) - self.recount() - return if action == 'clear_icon': - self._model.set_custom_category_icon(key, None) - self._model.remove_all_value_icons(key) + if extra == 'all': + self._model.remove_all_value_icons(key) + elif extra == 'value': + if index is not None: + val, icon_name = make_icon_name(key, index) + self._model.remove_value_icon(key, val, icon_name) + else: + self._model.remove_value_icon(key, TEMPLATE_ICON_INDICATOR, None) + else: + self._model.set_custom_category_icon(key, None) self.recount() return @@ -1286,17 +1286,21 @@ class TagsView(QTreeView): # {{{ key=key, index=index, category=category, extra=(icon_name, True))) ma.setEnabled(icon_name is not None and not for_child) ma = im.addAction(_('Use the default icon for {}').format(for_name), - partial(self.context_menu_handler, action='clear_icon_value', - key=key, index=index, category=category)) + partial(self.context_menu_handler, action='clear_icon', + key=key, index=index, category=category, extra='value')) ma.setEnabled(name is not None and icon_name is not None) im.addSection(_('Defaults')) im.addAction(_('Use/edit a template to choose the default value icon'), partial(self.context_menu_handler, action='set_icon', key=key, index=index, category=None, extra=(None, None))) ma = im.addAction(_('Use the category icon for the default value icon'), - partial(self.context_menu_handler, action='clear_icon_value', - key=key, index=None, category=category)) + partial(self.context_menu_handler, action='clear_icon', + key=key, index=None, category=category, extra='value')) ma.setEnabled(self._model.value_icons.get(key, {}).get(TEMPLATE_ICON_INDICATOR) is not None) + im.addSection(_('All values')) + ma = im.addAction(_('Reset all value icons to category icon'), + partial(self.context_menu_handler, action='clear_icon', + key=key, index=None, category=category, extra='all')) im.addSeparator() # Always show the User categories editor self.context_menu.addSeparator() From b4cef06f6192839bdc3b3a2ca2d65d78a4300173 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Sat, 18 Jan 2025 14:57:28 +0100 Subject: [PATCH 6/8] reset only value icons and not template --- src/calibre/gui2/tag_browser/model.py | 6 ++++-- src/calibre/gui2/tag_browser/view.py | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index a58480e791..6919800ca4 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -470,12 +470,14 @@ class TagsModel(QAbstractItemModel): # {{{ self.prefs['tags_browser_value_icons'] =self.value_icons self._remove_icon_file(file_name) - def remove_all_value_icons(self, key): + def remove_all_value_icons(self, key, keep_template=True): self.value_icons = self.prefs['tags_browser_value_icons'] values = self.value_icons.pop(key, {}) self.value_icons[key] = {} + template = values.pop(TEMPLATE_ICON_INDICATOR, None) + if keep_template and template is not None: + self.value_icons[key][TEMPLATE_ICON_INDICATOR] = template self.prefs['tags_browser_value_icons'] = self.value_icons - values.pop(TEMPLATE_ICON_INDICATOR, None) for file_name,child in values.values(): self._remove_icon_file(file_name) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index a9fd94ef8f..a8fd07ff17 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -735,7 +735,7 @@ class TagsView(QTreeView): # {{{ return if action == 'clear_icon': if extra == 'all': - self._model.remove_all_value_icons(key) + self._model.remove_all_value_icons(key, keep_template=True) elif extra == 'value': if index is not None: val, icon_name = make_icon_name(key, index) @@ -1298,7 +1298,7 @@ class TagsView(QTreeView): # {{{ key=key, index=None, category=category, extra='value')) ma.setEnabled(self._model.value_icons.get(key, {}).get(TEMPLATE_ICON_INDICATOR) is not None) im.addSection(_('All values')) - ma = im.addAction(_('Reset all value icons to category icon'), + ma = im.addAction(_('Reset all value icons to the default icon'), partial(self.context_menu_handler, action='clear_icon', key=key, index=None, category=category, extra='all')) im.addSeparator() From 9ec00f0ca5d42de423e60868a664aef284e00933 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Sat, 18 Jan 2025 15:53:03 +0100 Subject: [PATCH 7/8] add confirm dialog for all deleting icon action --- src/calibre/gui2/tag_browser/view.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index a8fd07ff17..7a2ad0acbc 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -47,6 +47,7 @@ from calibre.constants import config_dir from calibre.ebooks.metadata import rating_to_stars from calibre.gui2 import FunctionDispatcher, choose_files, config, empty_index, gprefs, pixmap_to_data, question_dialog, rating_font, safe_open_url from calibre.gui2.complete2 import EditWithComplete +from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.edit_category_notes import EditNoteDialog from calibre.gui2.tag_browser.model import ( COUNT_ROLE, @@ -735,14 +736,34 @@ class TagsView(QTreeView): # {{{ return if action == 'clear_icon': if extra == 'all': + if not confirm( + _('All the value icons for the category "{}" ' + 'will be permanently deleted. Are you sure?').format(category), + 'clear_category_all_value_icons', parent=get_gui()): + return self._model.remove_all_value_icons(key, keep_template=True) elif extra == 'value': if index is not None: val, icon_name = make_icon_name(key, index) + if not confirm( + _('The icon for the value "{0}" of the "{1}" category ' + 'will be permanently deleted. Are you sure?').format(val, category), + 'clear_category_value_icon_single', parent=get_gui()): + return self._model.remove_value_icon(key, val, icon_name) else: + if not confirm( + _('The template to choose the default value icons for the category "{}" ' + 'will be permanently deleted. Are you sure?').format(category), + 'clear_category_value_icon_template', parent=get_gui()): + return self._model.remove_value_icon(key, TEMPLATE_ICON_INDICATOR, None) else: + if not confirm( + _('The icon for the category "{}" ' + 'will be permanently deleted. Are you sure?').format(category), + 'clear_category_icon', parent=get_gui()): + return self._model.set_custom_category_icon(key, None) self.recount() return From cb09c9058f8897eb3a8280304dba565e854458f5 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Sat, 18 Jan 2025 20:00:54 +0100 Subject: [PATCH 8/8] move 'reset all value icons' into the values section --- src/calibre/gui2/tag_browser/view.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 7a2ad0acbc..9eac4bfee5 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -1310,6 +1310,10 @@ class TagsView(QTreeView): # {{{ partial(self.context_menu_handler, action='clear_icon', key=key, index=index, category=category, extra='value')) ma.setEnabled(name is not None and icon_name is not None) + im.addSeparator() + ma = im.addAction(_('Reset all value icons to the default icon'), + partial(self.context_menu_handler, action='clear_icon', + key=key, index=None, category=category, extra='all')) im.addSection(_('Defaults')) im.addAction(_('Use/edit a template to choose the default value icon'), partial(self.context_menu_handler, action='set_icon', @@ -1318,10 +1322,6 @@ class TagsView(QTreeView): # {{{ partial(self.context_menu_handler, action='clear_icon', key=key, index=None, category=category, extra='value')) ma.setEnabled(self._model.value_icons.get(key, {}).get(TEMPLATE_ICON_INDICATOR) is not None) - im.addSection(_('All values')) - ma = im.addAction(_('Reset all value icons to the default icon'), - partial(self.context_menu_handler, action='clear_icon', - key=key, index=None, category=category, extra='all')) im.addSeparator() # Always show the User categories editor self.context_menu.addSeparator()