Fix the icon not being updated if notes are changed from within book details.

While fixing this I found other places with both notes and links weren't refreshed in book details.
This commit is contained in:
Charles Haley 2023-09-22 18:00:36 +01:00 committed by Kovid Goyal
parent 071145e70c
commit f099932882
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 41 additions and 17 deletions

View File

@ -68,6 +68,10 @@ def search_action_with_data(search_term, value, book_id, field=None, **k):
return search_action(search_term, value, field=field, book_id=book_id, **k)
def notes_action(**keys):
return 'notes:' + as_hex_unicode(json_dumps(keys))
DEFAULT_AUTHOR_LINK = f'search-{DEFAULT_AUTHOR_SOURCE}'
@ -128,7 +132,9 @@ def mi_to_html(
link = ''
if field_value in all_notes.get(field, set()):
note = ' <a title="{0}" href="{1}">{2}</a>'.format(_('Click to open note'),
action('note', field=field, value=field_value), note_markup)
notes_action(field=field, value=field_value,
item_id=all_notes.get(field).get(field_value)),
note_markup)
else:
note = ''
return link + note

View File

@ -179,7 +179,8 @@ def add_edit_notes_action(menu, book_info, field, value):
gui = get_gui()
from calibre.gui2.dialogs.edit_category_notes import EditNoteDialog
d = EditNoteDialog(field, item_id, gui.current_db.new_api, parent=book_info)
d.exec()
if d.exec() == QDialog.DialogCode.Accepted:
gui.do_field_item_value_changed()
ac = menu.addAction(_('Edit notes for {}').format(escape_for_menu(value)))
ac.triggered.connect(edit_note)
ac.setIcon(QIcon.ic('edit_input.png'))
@ -321,8 +322,8 @@ def render_data(mi, use_roman_numbers=True, all_fields=False, pref_name='book_di
field_list = [(x, all_fields or display) for x, display in field_list]
db, _ = db_for_mi(mi)
db = db.new_api
all_notes = db.get_all_items_that_have_notes()
all_notes = {fld: {db.get_item_name(fld, id_) for id_ in all_notes[fld]} for fld in all_notes.keys()}
an = db.get_all_items_that_have_notes()
all_notes = {fld: {db.get_item_name(fld, id_):id_ for id_ in an[fld]} for fld in an.keys()}
return mi_to_html(
mi, field_list=field_list, use_roman_numbers=use_roman_numbers, rtl=is_rtl(),
rating_font=rating_font(), default_author_link=default_author_link(),
@ -577,6 +578,11 @@ def details_context_menu_event(view, ev, book_info, add_popup_action=False, edit
create_copy_links(copy_menu, data)
copy_links_added = True
reindex_fmt_added = 'reindex_fmt_added' in data
elif url and url.startswith('notes:'):
copy_links_added = True
search_internet_added = True
data = json_loads(from_hex_bytes(url.split(':', 1)[1]))
add_edit_notes_action(menu, view, data['field'], data['value'])
elif url and not url.startswith('#'):
ac = book_info.copy_link_action
ac.current_url = url
@ -1296,14 +1302,6 @@ class BookDetails(DetailsLayout): # {{{
if dt == 'search':
field = data.get('field')
search_term(data['term'], data['value'])
elif dt == 'note':
field = data.get('field')
# It shouldn't be possible for the field to be invalid or the
# note not to exist, but ...
if field and db.field_supports_notes(field):
item_id = db.get_item_id(field, data['value'])
if item_id is not None and db.notes_for(field, item_id):
return self.show_notes(field, item_id)
elif dt == 'author':
url = data['url']
if url == 'calibre':
@ -1322,6 +1320,15 @@ class BookDetails(DetailsLayout): # {{{
self.open_data_folder.emit(int(data['loc']))
elif dt == 'devpath':
self.view_device_book.emit(data['loc'])
elif typ == 'notes':
data = json_loads(from_hex_bytes(val))
field = data.get('field')
# It shouldn't be possible for the field to be invalid or the
# note not to exist, but ...
if field and db.field_supports_notes(field):
item_id = data['item_id']
if item_id is not None and db.notes_for(field, item_id):
return self.show_notes(field, item_id)
else:
browse(link)

View File

@ -124,6 +124,10 @@ class ShowNoteDialog(Dialog):
def edit(self):
d = EditNoteDialog(self.field, self.item_id, self.db, self)
if d.exec() == QDialog.DialogCode.Accepted:
# Tell the rest of calibre that the note has changed
gui = get_gui()
if gui is not None:
gui.do_field_item_value_changed()
self.refresh()
def find_books(self):

View File

@ -88,7 +88,7 @@ class TagBrowserMixin: # {{{
self.tags_view.saved_search_edit.connect(self.do_saved_search_edit)
self.tags_view.rebuild_saved_searches.connect(self.do_rebuild_saved_searches)
self.tags_view.author_sort_edit.connect(self.do_author_sort_edit)
self.tags_view.tag_item_renamed.connect(self.do_tag_item_renamed)
self.tags_view.tag_item_renamed.connect(self.do_field_item_value_changed)
self.tags_view.search_item_renamed.connect(self.saved_searches_changed)
self.tags_view.drag_drop_finished.connect(self.drag_drop_finished)
self.tags_view.restriction_error.connect(self.do_restriction_error,
@ -321,7 +321,7 @@ class TagBrowserMixin: # {{{
db.new_api.set_link_map(category, d.links)
# Clean up the library view
self.do_tag_item_renamed()
self.do_field_item_value_changed()
self.tags_view.recount()
def do_tag_item_delete(self, category, item_id, orig_name,
@ -373,7 +373,7 @@ class TagBrowserMixin: # {{{
m.delete_item_from_all_user_categories(orig_name, category)
# Clean up the library view
self.do_tag_item_renamed()
self.do_field_item_value_changed()
self.tags_view.recount()
def apply_tag_to_selected(self, field_name, item_name, remove):
@ -451,7 +451,13 @@ class TagBrowserMixin: # {{{
d.exec()
def do_tag_item_renamed(self):
# Clean up library view and search
# The method name was changed. Keep the old one here for compatibility,
# in case some plugin uses it.
self.do_field_item_value_changed()
def do_field_item_value_changed(self):
# Clean up library view and search, which also cleans up book details
# get information to redo the selection
rows = [r.row() for r in
self.library_view.selectionModel().selectedRows()]
@ -495,7 +501,8 @@ class TagBrowserMixin: # {{{
sort_map = {id_map.get(author_id, author_id):new_sort for author_id, old_author, new_author, new_sort, new_link in editor.result}
affected_books |= db.set_sort_for_authors(sort_map)
self.library_view.model().refresh_ids(affected_books, current_row=self.library_view.currentIndex().row())
self.tags_view.recount()
self.do_field_item_value_changed()
self.tags_view.recount()
def drag_drop_finished(self, ids):
self.library_view.model().refresh_ids(ids)