mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Render annots browser list
This commit is contained in:
parent
a283014fe4
commit
95dcc16073
@ -7,12 +7,12 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
||||
import os
|
||||
|
||||
from PyQt5.Qt import (
|
||||
QApplication, QCursor, QHBoxLayout, QIcon, QListWidget, QSize, QSplitter, Qt,
|
||||
QToolButton, QVBoxLayout, QWidget
|
||||
QApplication, QCursor, QFont, QHBoxLayout, QIcon, QSize, QSplitter, Qt,
|
||||
QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
||||
)
|
||||
|
||||
from calibre.gui2 import Application
|
||||
from calibre.gui2.viewer.search import SearchBox
|
||||
from calibre.gui2.viewer.search import SearchBox, ResultsDelegate
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
|
||||
|
||||
@ -30,15 +30,52 @@ class BusyCursor(object):
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
|
||||
class ResultsList(QListWidget):
|
||||
class AnnotsResultsDelegate(ResultsDelegate):
|
||||
|
||||
def result_data(self, result):
|
||||
if not isinstance(result, dict):
|
||||
return None, None, None, None
|
||||
full_text = result['text'].replace('0x1f', ' ')
|
||||
parts = full_text.split('0x1d', 2)
|
||||
before = after = ''
|
||||
if len(parts) == 3:
|
||||
before, text, after = parts
|
||||
elif len(parts) == 2:
|
||||
before, text = parts
|
||||
else:
|
||||
text = parts[0]
|
||||
return False, before, text, after
|
||||
|
||||
|
||||
class ResultsList(QTreeWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
QListWidget.__init__(self, parent)
|
||||
QTreeWidget.__init__(self, parent)
|
||||
self.setHeaderHidden(True)
|
||||
self.delegate = AnnotsResultsDelegate(self)
|
||||
self.setItemDelegate(self.delegate)
|
||||
self.section_font = QFont(self.font())
|
||||
self.section_font.setItalic(True)
|
||||
|
||||
def set_results(self, results):
|
||||
self.clear()
|
||||
book_id_map = {}
|
||||
db = current_db()
|
||||
for result in results:
|
||||
print(result)
|
||||
book_id = result['book_id']
|
||||
if book_id not in book_id_map:
|
||||
book_id_map[book_id] = {'title': db.field_for('title', book_id), 'matches': []}
|
||||
book_id_map[book_id]['matches'].append(result)
|
||||
for book_id, entry in book_id_map.items():
|
||||
section = QTreeWidgetItem([entry['title']], 1)
|
||||
section.setFlags(Qt.ItemIsEnabled)
|
||||
section.setFont(0, self.section_font)
|
||||
self.addTopLevelItem(section)
|
||||
section.setExpanded(True)
|
||||
for result in entry['matches']:
|
||||
item = QTreeWidgetItem(section, [' '], 2)
|
||||
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemNeverHasChildren)
|
||||
item.setData(0, Qt.UserRole, result)
|
||||
|
||||
|
||||
class BrowsePanel(QWidget):
|
||||
@ -97,8 +134,9 @@ class BrowsePanel(QWidget):
|
||||
return
|
||||
with BusyCursor():
|
||||
db = current_db()
|
||||
results = db.search_annotations(**q)
|
||||
results = db.search_annotations(highlight_start='0x1d', highlight_end='0x1d', snippet_size=64, **q)
|
||||
self.results_list.set_results(results)
|
||||
self.current_query = q
|
||||
|
||||
def show_next(self):
|
||||
self.do_find()
|
||||
|
@ -449,10 +449,16 @@ class SearchInput(QWidget): # {{{
|
||||
|
||||
class ResultsDelegate(QStyledItemDelegate): # {{{
|
||||
|
||||
def result_data(self, result):
|
||||
if not isinstance(result, SearchResult):
|
||||
return None, None, None, None
|
||||
return result.is_hidden, result.before, result.text, result.text
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
QStyledItemDelegate.paint(self, painter, option, index)
|
||||
result = index.data(Qt.UserRole)
|
||||
if not isinstance(result, SearchResult):
|
||||
is_hidden, result_before, result_text, result_after = self.result_data(result)
|
||||
if result_text is None:
|
||||
return
|
||||
painter.save()
|
||||
try:
|
||||
@ -465,19 +471,19 @@ class ResultsDelegate(QStyledItemDelegate): # {{{
|
||||
emphasis_font = QFont(font)
|
||||
emphasis_font.setBold(True)
|
||||
flags = Qt.AlignTop | Qt.TextSingleLine | Qt.TextIncludeTrailingSpaces
|
||||
rect = option.rect.adjusted(option.decorationSize.width() + 4 if result.is_hidden else 0, 0, 0, 0)
|
||||
rect = option.rect.adjusted(option.decorationSize.width() + 4 if is_hidden else 0, 0, 0, 0)
|
||||
painter.setClipRect(rect)
|
||||
before = re.sub(r'\s+', ' ', result.before)
|
||||
before = re.sub(r'\s+', ' ', result_before)
|
||||
before_width = 0
|
||||
if before:
|
||||
before_width = painter.boundingRect(rect, flags, before).width()
|
||||
after = re.sub(r'\s+', ' ', result.after.rstrip())
|
||||
after = re.sub(r'\s+', ' ', result_after.rstrip())
|
||||
after_width = 0
|
||||
if after:
|
||||
after_width = painter.boundingRect(rect, flags, after).width()
|
||||
ellipsis_width = painter.boundingRect(rect, flags, '...').width()
|
||||
painter.setFont(emphasis_font)
|
||||
text = re.sub(r'\s+', ' ', result.text)
|
||||
text = re.sub(r'\s+', ' ', result_text)
|
||||
match_width = painter.boundingRect(rect, flags, text).width()
|
||||
if match_width >= rect.width() - 3 * ellipsis_width:
|
||||
efm = QFontMetrics(emphasis_font)
|
||||
|
Loading…
x
Reference in New Issue
Block a user