Icon cache changes:

1. Add an icon cache to QIcon.
2. Use the cache for every icon getter in these dialogs.
This commit is contained in:
Charles Haley 2023-11-06 15:44:26 +00:00 committed by Kovid Goyal
parent b5c649b4de
commit bfdebb1c7e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 65 additions and 64 deletions

View File

@ -59,6 +59,7 @@ class IconResourceManager:
self.user_any_theme_name = self.user_dark_theme_name = self.user_light_theme_name = None self.user_any_theme_name = self.user_dark_theme_name = self.user_light_theme_name = None
self.registered_user_resource_files = () self.registered_user_resource_files = ()
self.color_palette = 'light' self.color_palette = 'light'
self.icon_cache = {}
def user_theme_resource_file(self, which): def user_theme_resource_file(self, which):
return os.path.join(config_dir, f'icons-{which}.rcc') return os.path.join(config_dir, f'icons-{which}.rcc')
@ -125,6 +126,7 @@ class IconResourceManager:
def initialize(self): def initialize(self):
if self.initialized: if self.initialized:
return return
self.icon_cache = {}
self.initialized = True self.initialized = True
QResource.registerResource(P('icons.rcc', allow_user_override=False)) QResource.registerResource(P('icons.rcc', allow_user_override=False))
QIcon.setFallbackSearchPaths([]) QIcon.setFallbackSearchPaths([])
@ -186,6 +188,19 @@ class IconResourceManager:
ans = os.path.join(self.override_icon_path, subfolder, sq) ans = os.path.join(self.override_icon_path, subfolder, sq)
return ans return ans
def cached_icon(self, name=''):
'''
Keep these icons in a cache. This is intended to be used in dialogs like
manage categories where thousands of icon instances can be needed.
It is a new method to avoid breaking QIcon.ic() if names are reused
in different contexts. It isn't clear if this can ever happen.
'''
icon = self.icon_cache.get(name)
if icon is None:
icon = self.icon_cache[name] = self(name)
return icon
def __call__(self, name): def __call__(self, name):
if isinstance(name, QIcon): if isinstance(name, QIcon):
return name return name
@ -221,6 +236,7 @@ class IconResourceManager:
return ba if as_bytearray else ba.data() return ba if as_bytearray else ba.data()
def set_theme(self): def set_theme(self):
self.icon_cache = {}
current = QIcon.themeName() current = QIcon.themeName()
is_dark = QApplication.instance().is_dark_theme is_dark = QApplication.instance().is_dark_theme
self.color_palette = 'dark' if is_dark else 'light' self.color_palette = 'dark' if is_dark else 'light'
@ -236,6 +252,7 @@ icon_resource_manager = IconResourceManager()
QIcon.ic = icon_resource_manager QIcon.ic = icon_resource_manager
QIcon.icon_as_png = icon_resource_manager.icon_as_png QIcon.icon_as_png = icon_resource_manager.icon_as_png
QIcon.is_ok = lambda self: not self.isNull() and len(self.availableSizes()) > 0 QIcon.is_ok = lambda self: not self.isNull() and len(self.availableSizes()) > 0
QIcon.cached_icon = icon_resource_manager.cached_icon
# Setup gprefs {{{ # Setup gprefs {{{

View File

@ -8,8 +8,8 @@ __license__ = 'GPL v3'
from contextlib import contextmanager from contextlib import contextmanager
from functools import partial from functools import partial
from qt.core import ( from qt.core import (
QAbstractItemView, QAction, QApplication, QDialog, QDialogButtonBox, QFrame, QIcon, QAbstractItemView, QAction, QApplication, QDialog, QDialogButtonBox, QFrame,
QLabel, QMenu, QStyledItemDelegate, Qt, QTableWidgetItem, QTimer, QIcon, QLabel, QMenu, QStyledItemDelegate, Qt, QTableWidgetItem, QTimer,
) )
from calibre.ebooks.metadata import author_to_author_sort, string_to_authors from calibre.ebooks.metadata import author_to_author_sort, string_to_authors
@ -81,8 +81,6 @@ class EditColumnDelegate(QStyledItemDelegate):
class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog): class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
edited_icon = QIcon.ic('modified.png')
def __init__(self, parent, db, id_to_select, select_sort, select_link, def __init__(self, parent, db, id_to_select, select_sort, select_link,
find_aut_func, is_first_letter=False): find_aut_func, is_first_letter=False):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
@ -375,7 +373,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
if self.context_item is None: if self.context_item is None:
return return
case_menu = QMenu(_('Change case')) case_menu = QMenu(_('Change case'))
case_menu.setIcon(QIcon.ic('font_size_larger.png')) case_menu.setIcon(QIcon.cached_icon('font_size_larger.png'))
action_upper_case = case_menu.addAction(_('Upper case')) action_upper_case = case_menu.addAction(_('Upper case'))
action_lower_case = case_menu.addAction(_('Lower case')) action_lower_case = case_menu.addAction(_('Lower case'))
action_swap_case = case_menu.addAction(_('Swap case')) action_swap_case = case_menu.addAction(_('Swap case'))
@ -396,17 +394,17 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
self.notes_utilities.context_menu(m, self.context_item, self.notes_utilities.context_menu(m, self.context_item,
self.table.item(idx.row(), AUTHOR_COLUMN).text()) self.table.item(idx.row(), AUTHOR_COLUMN).text())
else: else:
ca = m.addAction(QIcon.ic('edit-copy.png'), _('Copy')) ca = m.addAction(QIcon.cached_icon('edit-copy.png'), _('Copy'))
ca.triggered.connect(self.copy_to_clipboard) ca.triggered.connect(self.copy_to_clipboard)
ca = m.addAction(QIcon.ic('edit-paste.png'), _('Paste')) ca = m.addAction(QIcon.cached_icon('edit-paste.png'), _('Paste'))
ca.triggered.connect(self.paste_from_clipboard) ca.triggered.connect(self.paste_from_clipboard)
ca = m.addAction(QIcon.ic('edit-undo.png'), _('Undo')) ca = m.addAction(QIcon.cached_icon('edit-undo.png'), _('Undo'))
ca.triggered.connect(partial(self.undo_cell, ca.triggered.connect(partial(self.undo_cell,
old_value=self.original_authors[id_].get(sub))) old_value=self.original_authors[id_].get(sub)))
ca.setEnabled(self.context_item is not None and self.item_is_modified(self.context_item, id_)) ca.setEnabled(self.context_item is not None and self.item_is_modified(self.context_item, id_))
ca = m.addAction(QIcon.ic('edit_input.png'), _('Edit')) ca = m.addAction(QIcon.cached_icon('edit_input.png'), _('Edit'))
ca.triggered.connect(partial(self.table.editItem, self.context_item)) ca.triggered.connect(partial(self.table.editItem, self.context_item))
if sub != 'link': if sub != 'link':
@ -415,7 +413,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
ca = m.addAction(_('Copy to author sort')) ca = m.addAction(_('Copy to author sort'))
ca.triggered.connect(self.copy_au_to_aus) ca.triggered.connect(self.copy_au_to_aus)
m.addSeparator() m.addSeparator()
ca = m.addAction(QIcon.ic('lt.png'), _("Show books by author in book list")) ca = m.addAction(QIcon.cached_icon('lt.png'), _("Show books by author in book list"))
ca.triggered.connect(self.search_in_book_list) ca.triggered.connect(self.search_in_book_list)
else: else:
ca = m.addAction(_('Copy to author')) ca = m.addAction(_('Copy to author'))
@ -572,7 +570,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
if item.column() == NOTES_COLUMN: if item.column() == NOTES_COLUMN:
raise ValueError('got set_icon on notes column') raise ValueError('got set_icon on notes column')
modified = self.item_is_modified(item, id_) modified = self.item_is_modified(item, id_)
item.setIcon(self.edited_icon if modified else QIcon()) item.setIcon(QIcon.cached_icon('modified.png') if modified
else QIcon.cached_icon())
def cell_changed(self, row, col): def cell_changed(self, row, col):
if self.ignore_cell_changed: if self.ignore_cell_changed:

View File

@ -13,7 +13,8 @@ from qt.core import (
) )
from calibre import sanitize_file_name from calibre import sanitize_file_name
from calibre.gui2 import error_dialog, gprefs, question_dialog, choose_files, choose_save_file from calibre.gui2 import (error_dialog, gprefs, question_dialog, choose_files,
choose_save_file)
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin from calibre.gui2.actions.show_quickview import get_quickview_action_plugin
from calibre.gui2.complete2 import EditWithComplete from calibre.gui2.complete2 import EditWithComplete
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
@ -28,24 +29,10 @@ from calibre.utils.icu import (
from calibre.utils.titlecase import titlecase from calibre.utils.titlecase import titlecase
QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction' QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction'
CHECK_MARK = ''
icon_cache = {}
def icon(name=''):
def gi(self):
ans = icon_cache.get(name)
if ans is None:
icon_cache[name] = ans = QIcon.ic(name)
return ans
return property(fget=gi)
class NameTableWidgetItem(QTableWidgetItem): class NameTableWidgetItem(QTableWidgetItem):
empty_icon = icon()
trash_icon = icon('trash.png')
def __init__(self, sort_key): def __init__(self, sort_key):
QTableWidgetItem.__init__(self) QTableWidgetItem.__init__(self)
self.initial_value = '' self.initial_value = ''
@ -66,9 +53,9 @@ class NameTableWidgetItem(QTableWidgetItem):
def set_is_deleted(self, to_what): def set_is_deleted(self, to_what):
if to_what: if to_what:
self.setIcon(self.trash_icon) self.setIcon(QIcon.cached_icon('trash.png'))
else: else:
self.setIcon(self.empty_icon) self.setIcon(QIcon.cached_icon())
self.current_value = self.initial_value self.current_value = self.initial_value
self.is_deleted = to_what self.is_deleted = to_what
@ -153,14 +140,14 @@ class NotesTableWidgetItem(QTableWidgetItem):
class NotesUtilities(): class NotesUtilities():
edit_icon = icon('edit_input.png') edit_icon = QIcon.cached_icon('edit_input.png')
edited_icon = icon('modified.png') edited_icon = QIcon.cached_icon('modified.png')
empty_icon = icon() empty_icon = QIcon.cached_icon()
export_icon = icon('forward.png') export_icon = QIcon.cached_icon('forward.png')
import_icon = icon('back.png') import_icon = QIcon.cached_icon('back.png')
pencil_icon = icon('notes.png') pencil_icon = QIcon.cached_icon('notes.png')
trash_icon = icon('trash.png') trash_icon = QIcon.cached_icon('trash.png')
undo_delete_icon = icon('edit-undo.png') undo_delete_icon = QIcon.cached_icon('edit-undo.png')
def __init__(self, table, category, item_id_getter): def __init__(self, table, category, item_id_getter):
self.table = table self.table = table
@ -202,7 +189,7 @@ class NotesUtilities():
item.setIcon(self.empty_icon) item.setIcon(self.empty_icon)
item.set_sort_val(NotesTableWidgetItem.EMPTY) item.set_sort_val(NotesTableWidgetItem.EMPTY)
else: else:
item.setIcon(self.trash_icon) item.setIcon(QIcon.cached_icon('trash.png'))
item.set_sort_val(NotesTableWidgetItem.DELETED) item.set_sort_val(NotesTableWidgetItem.DELETED)
self.table.cellChanged.emit(item.row(), item.column()) self.table.cellChanged.emit(item.row(), item.column())
self.table.itemChanged.emit(item) self.table.itemChanged.emit(item)
@ -278,7 +265,7 @@ class NotesUtilities():
ac = m.addAction(self.edit_icon, _('Edit note') if has_note else _('Create note')) ac = m.addAction(self.edit_icon, _('Edit note') if has_note else _('Create note'))
ac.triggered.connect(partial(self.table.editItem, item)) ac.triggered.connect(partial(self.table.editItem, item))
ac = m.addAction(self.trash_icon, _('Delete note')) ac = m.addAction(QIcon.cached_icon('trash.png'), _('Delete note'))
ac.setEnabled(has_note) ac.setEnabled(has_note)
ac.triggered.connect(partial(self.delete_note, item)) ac.triggered.connect(partial(self.delete_note, item))
@ -350,16 +337,14 @@ def block_signals(widget):
class TagListEditor(QDialog, Ui_TagListEditor): class TagListEditor(QDialog, Ui_TagListEditor):
edited_icon = icon('modified.png')
empty_icon = icon()
def __init__(self, window, cat_name, tag_to_match, get_book_ids, sorter, def __init__(self, window, cat_name, tag_to_match, get_book_ids, sorter,
ttm_is_first_letter=False, category=None, fm=None, link_map=None): ttm_is_first_letter=False, category=None, fm=None, link_map=None):
QDialog.__init__(self, window) QDialog.__init__(self, window)
Ui_TagListEditor.__init__(self) Ui_TagListEditor.__init__(self)
self.setupUi(self)
from calibre.gui2.ui import get_gui from calibre.gui2.ui import get_gui
self.supports_notes = bool(category and get_gui().current_db.new_api.field_supports_notes(category)) self.supports_notes = bool(category and get_gui().current_db.new_api.field_supports_notes(category))
self.setupUi(self)
self.verticalLayout_2.setAlignment(Qt.AlignmentFlag.AlignCenter) self.verticalLayout_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.search_box.setMinimumContentsLength(25) self.search_box.setMinimumContentsLength(25)
if category is not None: if category is not None:
@ -455,26 +440,26 @@ class TagListEditor(QDialog, Ui_TagListEditor):
ca = m.addAction(_('Copy')) ca = m.addAction(_('Copy'))
ca.triggered.connect(partial(self.copy_to_clipboard, item)) ca.triggered.connect(partial(self.copy_to_clipboard, item))
ca.setIcon(QIcon.ic('edit-copy.png')) ca.setIcon(QIcon.cached_icon('edit-copy.png'))
ca.setEnabled(not is_deleted) ca.setEnabled(not is_deleted)
ca = m.addAction(_('Paste')) ca = m.addAction(_('Paste'))
ca.setIcon(QIcon.ic('edit-paste.png')) ca.setIcon(QIcon.cached_icon('edit-paste.png'))
ca.triggered.connect(partial(self.paste_from_clipboard, item)) ca.triggered.connect(partial(self.paste_from_clipboard, item))
ca.setEnabled(not is_deleted) ca.setEnabled(not is_deleted)
ca = m.addAction(_('Undo')) ca = m.addAction(_('Undo'))
ca.setIcon(QIcon.ic('edit-undo.png')) ca.setIcon(QIcon.cached_icon('edit-undo.png'))
ca.triggered.connect(partial(self.undo_link_edit, item, item_id)) ca.triggered.connect(partial(self.undo_link_edit, item, item_id))
ca.setEnabled(not is_deleted and self.link_is_edited(item_id)) ca.setEnabled(not is_deleted and self.link_is_edited(item_id))
ca = m.addAction(_('Edit')) ca = m.addAction(_('Edit'))
ca.setIcon(QIcon.ic('edit_input.png')) ca.setIcon(QIcon.cached_icon('edit_input.png'))
ca.triggered.connect(partial(self.table.editItem, item)) ca.triggered.connect(partial(self.table.editItem, item))
ca.setEnabled(not is_deleted) ca.setEnabled(not is_deleted)
ca = m.addAction(_('Delete link')) ca = m.addAction(_('Delete link'))
ca.setIcon(QIcon.ic('trash.png')) ca.setIcon(QIcon.cached_icon('trash.png'))
def delete_link_text(item): def delete_link_text(item):
item.setText('') item.setText('')
ca.triggered.connect(partial(delete_link_text, item)) ca.triggered.connect(partial(delete_link_text, item))
@ -486,16 +471,16 @@ class TagListEditor(QDialog, Ui_TagListEditor):
ca = m.addAction(_('Copy')) ca = m.addAction(_('Copy'))
ca.triggered.connect(partial(self.copy_to_clipboard, item)) ca.triggered.connect(partial(self.copy_to_clipboard, item))
ca.setIcon(QIcon.ic('edit-copy.png')) ca.setIcon(QIcon.cached_icon('edit-copy.png'))
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
ca = m.addAction(_('Paste')) ca = m.addAction(_('Paste'))
ca.setIcon(QIcon.ic('edit-paste.png')) ca.setIcon(QIcon.cached_icon('edit-paste.png'))
ca.triggered.connect(partial(self.paste_from_clipboard, item)) ca.triggered.connect(partial(self.paste_from_clipboard, item))
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
ca = m.addAction(_('Undo')) ca = m.addAction(_('Undo'))
ca.setIcon(QIcon.ic('edit-undo.png')) ca.setIcon(QIcon.cached_icon('edit-undo.png'))
if item.is_deleted: if item.is_deleted:
ca.triggered.connect(self.undo_edit) ca.triggered.connect(self.undo_edit)
else: else:
@ -503,37 +488,37 @@ class TagListEditor(QDialog, Ui_TagListEditor):
ca.setEnabled(item.is_deleted or item.text() != self.original_names[self.get_item_id(item)]) ca.setEnabled(item.is_deleted or item.text() != self.original_names[self.get_item_id(item)])
ca = m.addAction(_('Edit')) ca = m.addAction(_('Edit'))
ca.setIcon(QIcon.ic('edit_input.png')) ca.setIcon(QIcon.cached_icon('edit_input.png'))
ca.triggered.connect(self.edit_button_clicked) ca.triggered.connect(self.edit_button_clicked)
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
ca = m.addAction(_('Delete')) ca = m.addAction(_('Delete'))
ca.setIcon(QIcon.ic('trash.png')) ca.setIcon(QIcon.cached_icon('trash.png'))
ca.triggered.connect(self.delete_tags) ca.triggered.connect(self.delete_tags)
item_name = str(item.text()) item_name = str(item.text())
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
ca = m.addAction(_('Search for {}').format(item_name)) ca = m.addAction(_('Search for {}').format(item_name))
ca.setIcon(QIcon.ic('search.png')) ca.setIcon(QIcon.cached_icon('search.png'))
ca.triggered.connect(partial(self.set_search_text, item_name)) ca.triggered.connect(partial(self.set_search_text, item_name))
item_name = str(item.text()) item_name = str(item.text())
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
ca = m.addAction(_('Filter by {}').format(item_name)) ca = m.addAction(_('Filter by {}').format(item_name))
ca.setIcon(QIcon.ic('filter.png')) ca.setIcon(QIcon.cached_icon('filter.png'))
ca.triggered.connect(partial(self.set_filter_text, item_name)) ca.triggered.connect(partial(self.set_filter_text, item_name))
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
if self.category is not None: if self.category is not None:
ca = m.addAction(_("Search the library for {0}").format(item_name)) ca = m.addAction(_("Search the library for {0}").format(item_name))
ca.setIcon(QIcon.ic('lt.png')) ca.setIcon(QIcon.cached_icon('lt.png'))
ca.triggered.connect(partial(self.search_for_books, item)) ca.triggered.connect(partial(self.search_for_books, item))
ca.setEnabled(not item.is_deleted) ca.setEnabled(not item.is_deleted)
if self.table.state() == QAbstractItemView.State.EditingState: if self.table.state() == QAbstractItemView.State.EditingState:
m.addSeparator() m.addSeparator()
case_menu = QMenu(_('Change case')) case_menu = QMenu(_('Change case'))
case_menu.setIcon(QIcon.ic('font_size_larger.png')) case_menu.setIcon(QIcon.cached_icon('font_size_larger.png'))
action_upper_case = case_menu.addAction(_('Upper case')) action_upper_case = case_menu.addAction(_('Upper case'))
action_lower_case = case_menu.addAction(_('Lower case')) action_lower_case = case_menu.addAction(_('Lower case'))
action_swap_case = case_menu.addAction(_('Swap case')) action_swap_case = case_menu.addAction(_('Swap case'))
@ -718,9 +703,9 @@ class TagListEditor(QDialog, Ui_TagListEditor):
def set_link_icon(self, id_, item): def set_link_icon(self, id_, item):
with block_signals(self.table): with block_signals(self.table):
if self.link_is_edited(id_): if self.link_is_edited(id_):
item.setIcon(self.edited_icon) item.setIcon(QIcon.cached_icon('modified.png'))
else: else:
item.setIcon(self.empty_icon) item.setIcon(QIcon.cached_icon())
def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter): def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter):
self.create_table() self.create_table()
@ -786,7 +771,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
elif tag == tag_to_match: elif tag == tag_to_match:
select_item = item select_item = item
if item.text_is_modified(): if item.text_is_modified():
item.setIcon(self.edited_icon) item.setIcon(QIcon.cached_icon('modified.png'))
item = CountTableWidgetItem(self.all_tags[tag]['count']) item = CountTableWidgetItem(self.all_tags[tag]['count'])
item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsSelectable|Qt.ItemFlag.ItemIsEditable)) item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsSelectable|Qt.ItemFlag.ItemIsEditable))
@ -933,10 +918,10 @@ class TagListEditor(QDialog, Ui_TagListEditor):
orig = self.table.item(item.row(), WAS_COLUMN) orig = self.table.item(item.row(), WAS_COLUMN)
item.setText(new_text) item.setText(new_text)
if item.text_is_modified(): if item.text_is_modified():
item.setIcon(self.edited_icon) item.setIcon(QIcon.cached_icon('modified.png'))
orig.setData(Qt.ItemDataRole.DisplayRole, item.initial_text()) orig.setData(Qt.ItemDataRole.DisplayRole, item.initial_text())
else: else:
item.setIcon(self.empty_icon) item.setIcon(QIcon.cached_icon())
orig.setData(Qt.ItemDataRole.DisplayRole, '') orig.setData(Qt.ItemDataRole.DisplayRole, '')
def undo_link_edit(self, item, item_id): def undo_link_edit(self, item, item_id):
@ -948,7 +933,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
item = self.table.item(item.row(), LINK_COLUMN) item = self.table.item(item.row(), LINK_COLUMN)
item.setFlags(item.flags() | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsSelectable) item.setFlags(item.flags() | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsSelectable)
item.setText(link_txt) item.setText(link_txt)
item.setIcon(self.empty_icon) item.setIcon(QIcon.cached_icon())
def undo_value_edit(self, item, item_id): def undo_value_edit(self, item, item_id):
with block_signals(self.table): with block_signals(self.table):
@ -956,7 +941,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.to_rename.pop(item_id, None) self.to_rename.pop(item_id, None)
row = item.row() row = item.row()
self.table.item(row, WAS_COLUMN).setData(Qt.ItemDataRole.DisplayRole, '') self.table.item(row, WAS_COLUMN).setData(Qt.ItemDataRole.DisplayRole, '')
item.setIcon(self.edited_icon if item.text_is_modified() else self.empty_icon) item.setIcon(QIcon.cached_icon('modified.png') if item.text_is_modified() else QIcon.cached_icon())
def undo_edit(self): def undo_edit(self):
col_zero_items = (self.table.item(item.row(), VALUE_COLUMN) for item in self.table.selectedItems()) col_zero_items = (self.table.item(item.row(), VALUE_COLUMN) for item in self.table.selectedItems())
@ -986,7 +971,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
item.setFlags(item.flags() | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsSelectable) item.setFlags(item.flags() | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsSelectable)
if id_ in self.notes_utilities.modified_notes: if id_ in self.notes_utilities.modified_notes:
self.notes_utilities.undo_note_edit(item) self.notes_utilities.undo_note_edit(item)
item.setIcon(self.empty_icon) item.setIcon(QIcon.cached_icon())
def selection_changed(self): def selection_changed(self):
if self.table.currentIndex().isValid(): if self.table.currentIndex().isValid():