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
|
import os
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QApplication, QCursor, QHBoxLayout, QIcon, QListWidget, QSize, QSplitter, Qt,
|
QApplication, QCursor, QFont, QHBoxLayout, QIcon, QSize, QSplitter, Qt,
|
||||||
QToolButton, QVBoxLayout, QWidget
|
QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre.gui2 import Application
|
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
|
from calibre.gui2.widgets2 import Dialog
|
||||||
|
|
||||||
|
|
||||||
@ -30,15 +30,52 @@ class BusyCursor(object):
|
|||||||
QApplication.restoreOverrideCursor()
|
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):
|
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):
|
def set_results(self, results):
|
||||||
self.clear()
|
self.clear()
|
||||||
|
book_id_map = {}
|
||||||
|
db = current_db()
|
||||||
for result in results:
|
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):
|
class BrowsePanel(QWidget):
|
||||||
@ -97,8 +134,9 @@ class BrowsePanel(QWidget):
|
|||||||
return
|
return
|
||||||
with BusyCursor():
|
with BusyCursor():
|
||||||
db = current_db()
|
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.results_list.set_results(results)
|
||||||
|
self.current_query = q
|
||||||
|
|
||||||
def show_next(self):
|
def show_next(self):
|
||||||
self.do_find()
|
self.do_find()
|
||||||
|
@ -449,10 +449,16 @@ class SearchInput(QWidget): # {{{
|
|||||||
|
|
||||||
class ResultsDelegate(QStyledItemDelegate): # {{{
|
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):
|
def paint(self, painter, option, index):
|
||||||
QStyledItemDelegate.paint(self, painter, option, index)
|
QStyledItemDelegate.paint(self, painter, option, index)
|
||||||
result = index.data(Qt.UserRole)
|
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
|
return
|
||||||
painter.save()
|
painter.save()
|
||||||
try:
|
try:
|
||||||
@ -465,19 +471,19 @@ class ResultsDelegate(QStyledItemDelegate): # {{{
|
|||||||
emphasis_font = QFont(font)
|
emphasis_font = QFont(font)
|
||||||
emphasis_font.setBold(True)
|
emphasis_font.setBold(True)
|
||||||
flags = Qt.AlignTop | Qt.TextSingleLine | Qt.TextIncludeTrailingSpaces
|
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)
|
painter.setClipRect(rect)
|
||||||
before = re.sub(r'\s+', ' ', result.before)
|
before = re.sub(r'\s+', ' ', result_before)
|
||||||
before_width = 0
|
before_width = 0
|
||||||
if before:
|
if before:
|
||||||
before_width = painter.boundingRect(rect, flags, before).width()
|
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
|
after_width = 0
|
||||||
if after:
|
if after:
|
||||||
after_width = painter.boundingRect(rect, flags, after).width()
|
after_width = painter.boundingRect(rect, flags, after).width()
|
||||||
ellipsis_width = painter.boundingRect(rect, flags, '...').width()
|
ellipsis_width = painter.boundingRect(rect, flags, '...').width()
|
||||||
painter.setFont(emphasis_font)
|
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()
|
match_width = painter.boundingRect(rect, flags, text).width()
|
||||||
if match_width >= rect.width() - 3 * ellipsis_width:
|
if match_width >= rect.width() - 3 * ellipsis_width:
|
||||||
efm = QFontMetrics(emphasis_font)
|
efm = QFontMetrics(emphasis_font)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user