diff --git a/src/calibre/gui2/viewer/highlights.py b/src/calibre/gui2/viewer/highlights.py index 794b530134..648f0b7172 100644 --- a/src/calibre/gui2/viewer/highlights.py +++ b/src/calibre/gui2/viewer/highlights.py @@ -175,11 +175,21 @@ class Highlights(QTreeWidget): section_map = defaultdict(list) section_tt_map = {} for h in self.sorted_highlights(highlights): - tsec = h.get('top_level_section_title') - lsec = h.get('lowest_level_section_title') + tfam = h.get('toc_family_titles') or () + if tfam: + tsec = tfam[0] + lsec = tfam[-1] + else: + tsec = h.get('top_level_section_title') + lsec = h.get('lowest_level_section_title') sec = lsec or tsec or _('Unknown') - if sec != tsec: - section_tt_map[sec] = tsec + if len(tfam) > 1: + lines = [] + for i, node in enumerate(tfam): + lines.append('\xa0\xa0' * i + '➤ ' + node) + tt = ngettext('Table of Contents section:', 'Table of Contents sections:', len(lines)) + tt += '\n' + '\n'.join(lines) + section_tt_map[sec] = tt section_map[sec].append(h) for secnum, (sec, items) in enumerate(section_map.items()): section = QTreeWidgetItem([sec], 1) @@ -187,7 +197,7 @@ class Highlights(QTreeWidget): section.setFont(0, self.section_font) tt = section_tt_map.get(sec) if tt: - section.setToolTip(0, _('Top level section in Table of Contents:') + '\n' + tt) + section.setToolTip(0, tt) self.addTopLevelItem(section) section.setExpanded(True) for itemnum, h in enumerate(items): diff --git a/src/pyj/read_book/annotations.pyj b/src/pyj/read_book/annotations.pyj index a7126ac52e..15e49acdfb 100644 --- a/src/pyj/read_book/annotations.pyj +++ b/src/pyj/read_book/annotations.pyj @@ -189,6 +189,7 @@ class AnnotationsManager: # {{{ v'delete h.notes' v'delete h.spine_name' v'delete h.spine_index' + v'delete h.toc_family_titles' return True def delete_highlight(self, uuid): @@ -237,7 +238,7 @@ class AnnotationsManager: # {{{ x = 2 * (spine_index + 1) return f'epubcfi(/{x}{h.start_cfi})' - def add_highlight(self, msg, style, notes, toplevel_toc_node, toc_node): + def add_highlight(self, msg, style, notes, toc_family): now = Date().toISOString() for uuid in msg.removed_highlights: self.remove_highlight(uuid) @@ -255,10 +256,12 @@ class AnnotationsManager: # {{{ } if notes: annot.notes = notes - if toplevel_toc_node?.title: - annot.top_level_section_title = toplevel_toc_node.title - if toc_node?.title: - annot.lowest_level_section_title = toc_node.title + if toc_family?.length: + toc_family_titles = v'[]' + for x in toc_family: + if x.title: + toc_family_titles.push(x.title) + annot.toc_family_titles = toc_family_titles self.sync_annots_to_server('highlights') def highlights_for_currently_showing(self): diff --git a/src/pyj/read_book/selection_bar.pyj b/src/pyj/read_book/selection_bar.pyj index 862fee6d32..901ec82eec 100644 --- a/src/pyj/read_book/selection_bar.pyj +++ b/src/pyj/read_book/selection_bar.pyj @@ -966,7 +966,7 @@ class SelectionBar: _('Failed to apply highlighting, try adjusting extent of highlight') ) self.annotations_manager.add_highlight( - msg, self.current_highlight_style.style, notes, self.view.current_toc_toplevel_node, self.view.current_toc_node) + msg, self.current_highlight_style.style, notes, self.view.current_toc_family) elif msg.type is 'edit-highlight': if self.state is WAITING: self.create_highlight() diff --git a/src/pyj/read_book/toc.pyj b/src/pyj/read_book/toc.pyj index 9a22b2a88b..b4a9517b0b 100644 --- a/src/pyj/read_book/toc.pyj +++ b/src/pyj/read_book/toc.pyj @@ -78,16 +78,16 @@ def get_current_toc_nodes(): if before: ans[before.id] = True ans = Object.keys(ans) + family = v'[]' if ans.length: - pid = node_id = ans[0] - p = parent_map[pid] - while p and p.title: - pid = p.id - p = parent_map[pid] - p = id_map[pid] - return id_map[node_id], p if p and p.title else None - - return None, None + node = id_map[ans[0]] + while node and node.title: + family.unshift(node) + parent = parent_map[node.id] + node = None + if parent: + node = id_map[parent.id] + return family def get_highlighted_toc_nodes(toc, parent_map, id_map): diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index 7d28c8ceef..ec6ee80d50 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -205,6 +205,7 @@ class View: self.loaded_resources = {} self.current_progress_frac = self.current_file_progress_frac = 0 self.current_toc_node = self.current_toc_toplevel_node = None + self.current_toc_family = v'[]' self.report_cfi_callbacks = {} self.get_cfi_counter = 0 self.show_loading_callback_timer = None @@ -1203,7 +1204,12 @@ class View: def on_update_toc_position(self, data): update_visible_toc_nodes(data.visible_anchors) - self.current_toc_node, self.current_toc_toplevel_node = get_current_toc_nodes() + self.current_toc_family = get_current_toc_nodes() + if self.current_toc_family.length: + self.current_toc_node = self.current_toc_family[-1] + self.current_toc_toplevel_node = self.current_toc_family[0] + else: + self.current_toc_node = self.current_toc_toplevel_node = None if runtime.is_standalone_viewer: ui_operations.update_current_toc_nodes(self.current_toc_node?.id, self.current_toc_toplevel_node?.id) self.update_header_footer()