From fdf1fca5568a243eec2ee7ddb49cfbabf6e1399a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 15 Sep 2022 11:01:26 +0530 Subject: [PATCH] E-book viewer: When displaying highlights dont group highlights from different chapters when the chapter titles are identical. Fixes #1988590 [Private bug](https://bugs.launchpad.net/calibre/+bug/1988590) --- src/calibre/gui2/viewer/highlights.py | 62 +++++++++++++++++---------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/calibre/gui2/viewer/highlights.py b/src/calibre/gui2/viewer/highlights.py index bd3c277a47..4523cadd4d 100644 --- a/src/calibre/gui2/viewer/highlights.py +++ b/src/calibre/gui2/viewer/highlights.py @@ -220,35 +220,53 @@ class Highlights(QTreeWidget): self.clear() self.uuid_map = {} highlights = (h for h in highlights if not h.get('removed') and h.get('highlighted_text')) - section_map = defaultdict(list) - section_tt_map = {} - for h in self.sorted_highlights(highlights): - 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') + smap = {} + title_counts = defaultdict(lambda : 0) + + @lru_cache + def tooltip_for(tfam): + tooltip = '' 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) + tooltip = ngettext('Table of Contents section:', 'Table of Contents sections:', len(lines)) + tooltip += '\n' + '\n'.join(lines) + return tooltip + + for h in self.sorted_highlights(highlights): + tfam = tuple(h.get('toc_family_titles') or ()) + if tfam: + tsec = tfam[0] + lsec = tfam[-1] + key = tfam + else: + tsec = h.get('top_level_section_title') + lsec = h.get('lowest_level_section_title') + key = (tsec or '', lsec or '') + short_title = lsec or tsec or _('Unknown') + title_counts[short_title] += 1 + section = { + 'title': short_title, 'tfam': tfam, 'tsec': tsec, 'lsec': lsec, 'items': [], 'tooltip': tooltip_for(tfam), 'key': key, + } + smap.setdefault(key, section)['items'].append(h) + + for section in smap.values(): + if title_counts[section['title']] > 1: + if section['tfam']: + section['title'] = ' ➤ '.join(section['tfam']) + elif section['tsec'] and section['lsec']: + section['title'] = ' ➤ '.join((section['tsec'], section['lsec'])) + + for secnum, (sec_key, sec) in enumerate(smap.items()): + section = QTreeWidgetItem([sec['title']], 1) section.setFlags(Qt.ItemFlag.ItemIsEnabled) section.setFont(0, self.section_font) - tt = section_tt_map.get(sec) - if tt: - section.setToolTip(0, tt) + if sec['tooltip']: + section.setToolTip(0, sec['tooltip']) self.addTopLevelItem(section) - section.setExpanded(not preserve_state or sec in expanded_chapters) - for itemnum, h in enumerate(items): + section.setExpanded(not preserve_state or sec['title'] in expanded_chapters) + for itemnum, h in enumerate(sec['items']): txt = h.get('highlighted_text') txt = txt.replace('\n', ' ') if h.get('notes'):