mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-11 09:13:57 -04:00
More work n annotations browser
This commit is contained in:
parent
95dcc16073
commit
f53ecbf7ba
@ -300,7 +300,7 @@ def save_annotations_for_book(cursor, book_id, fmt, annots_list, user_type='loca
|
|||||||
data = []
|
data = []
|
||||||
fmt = fmt.upper()
|
fmt = fmt.upper()
|
||||||
for annot, timestamp_in_secs in annots_list:
|
for annot, timestamp_in_secs in annots_list:
|
||||||
atype = annot['type']
|
atype = annot['type'].lower()
|
||||||
if atype == 'bookmark':
|
if atype == 'bookmark':
|
||||||
aid = text = annot['title']
|
aid = text = annot['title']
|
||||||
elif atype == 'highlight':
|
elif atype == 'highlight':
|
||||||
@ -1821,6 +1821,13 @@ class DB(object):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def all_annotation_users(self):
|
||||||
|
return self.execute('SELECT DISTINCT user_type, user FROM annotations')
|
||||||
|
|
||||||
|
def all_annotation_types(self):
|
||||||
|
for x in self.execute('SELECT DISTINCT annot_type FROM annotations'):
|
||||||
|
yield x[0]
|
||||||
|
|
||||||
def set_annotations_for_book(self, book_id, fmt, annots_list, user_type='local', user='viewer'):
|
def set_annotations_for_book(self, book_id, fmt, annots_list, user_type='local', user='viewer'):
|
||||||
try:
|
try:
|
||||||
with self.conn: # Disable autocommit mode, for performance
|
with self.conn: # Disable autocommit mode, for performance
|
||||||
|
@ -2301,6 +2301,14 @@ class Cache(object):
|
|||||||
def all_annotations_for_book(self, book_id):
|
def all_annotations_for_book(self, book_id):
|
||||||
return tuple(self.backend.all_annotations_for_book(book_id))
|
return tuple(self.backend.all_annotations_for_book(book_id))
|
||||||
|
|
||||||
|
@read_api
|
||||||
|
def all_annotation_users(self):
|
||||||
|
return tuple(self.backend.all_annotation_users())
|
||||||
|
|
||||||
|
@read_api
|
||||||
|
def all_annotation_types(self):
|
||||||
|
return tuple(self.backend.all_annotation_types())
|
||||||
|
|
||||||
@read_api
|
@read_api
|
||||||
def search_annotations(
|
def search_annotations(
|
||||||
self,
|
self,
|
||||||
|
@ -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, QFont, QHBoxLayout, QIcon, QSize, QSplitter, Qt,
|
QApplication, QComboBox, QCursor, QFont, QHBoxLayout, QIcon, QLabel, QSize,
|
||||||
QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
QSplitter, Qt, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre.gui2 import Application
|
from calibre.gui2 import Application
|
||||||
from calibre.gui2.viewer.search import SearchBox, ResultsDelegate
|
from calibre.gui2.viewer.search import ResultsDelegate, SearchBox
|
||||||
from calibre.gui2.widgets2 import Dialog
|
from calibre.gui2.widgets2 import Dialog
|
||||||
|
|
||||||
|
|
||||||
@ -36,10 +36,11 @@ class AnnotsResultsDelegate(ResultsDelegate):
|
|||||||
if not isinstance(result, dict):
|
if not isinstance(result, dict):
|
||||||
return None, None, None, None
|
return None, None, None, None
|
||||||
full_text = result['text'].replace('0x1f', ' ')
|
full_text = result['text'].replace('0x1f', ' ')
|
||||||
parts = full_text.split('0x1d', 2)
|
parts = full_text.split('\x1d')
|
||||||
before = after = ''
|
before = after = ''
|
||||||
if len(parts) == 3:
|
if len(parts) > 2:
|
||||||
before, text, after = parts
|
before, text = parts[:2]
|
||||||
|
after = ' '.join(parts[2:]).replace('\x1d', '')
|
||||||
elif len(parts) == 2:
|
elif len(parts) == 2:
|
||||||
before, text = parts
|
before, text = parts
|
||||||
else:
|
else:
|
||||||
@ -91,6 +92,7 @@ class BrowsePanel(QWidget):
|
|||||||
sb.initialize('library-annotations-browser-search-box')
|
sb.initialize('library-annotations-browser-search-box')
|
||||||
sb.cleared.connect(self.cleared)
|
sb.cleared.connect(self.cleared)
|
||||||
sb.lineEdit().returnPressed.connect(self.show_next)
|
sb.lineEdit().returnPressed.connect(self.show_next)
|
||||||
|
sb.lineEdit().setPlaceholderText(_('Enter words to search for'))
|
||||||
h.addWidget(sb)
|
h.addWidget(sb)
|
||||||
|
|
||||||
self.next_button = nb = QToolButton(self)
|
self.next_button = nb = QToolButton(self)
|
||||||
@ -107,9 +109,56 @@ class BrowsePanel(QWidget):
|
|||||||
nb.clicked.connect(self.show_previous)
|
nb.clicked.connect(self.show_previous)
|
||||||
nb.setToolTip(_('Find previous match'))
|
nb.setToolTip(_('Find previous match'))
|
||||||
|
|
||||||
|
h = QHBoxLayout()
|
||||||
|
l.addLayout(h)
|
||||||
|
h.addWidget(QLabel(_('Restrict to') + ' '))
|
||||||
|
la = QLabel(_('Types:'))
|
||||||
|
h.addWidget(la)
|
||||||
|
self.types_box = tb = QComboBox(self)
|
||||||
|
tb.currentIndexChanged.connect(self.effective_query_changed)
|
||||||
|
la.setBuddy(tb)
|
||||||
|
h.addWidget(tb)
|
||||||
|
la = QLabel(_('User:'))
|
||||||
|
h.addWidget(la)
|
||||||
|
self.user_box = ub = QComboBox(self)
|
||||||
|
ub.currentIndexChanged.connect(self.effective_query_changed)
|
||||||
|
la.setBuddy(ub)
|
||||||
|
h.addWidget(ub)
|
||||||
|
h.addStretch(10)
|
||||||
|
|
||||||
self.results_list = rl = ResultsList(self)
|
self.results_list = rl = ResultsList(self)
|
||||||
l.addWidget(rl)
|
l.addWidget(rl)
|
||||||
|
|
||||||
|
def re_initialize(self):
|
||||||
|
db = current_db()
|
||||||
|
self.search_box.setFocus(Qt.OtherFocusReason)
|
||||||
|
tb = self.types_box
|
||||||
|
before = tb.currentData()
|
||||||
|
tb.blockSignals(True)
|
||||||
|
tb.clear()
|
||||||
|
tb.addItem(' ', ' ')
|
||||||
|
for atype in db.all_annotation_types():
|
||||||
|
name = {'bookmark': _('Bookmarks'), 'highlight': _('Highlights')}.get(atype, atype)
|
||||||
|
tb.addItem(name, atype)
|
||||||
|
if before:
|
||||||
|
row = tb.findData(before)
|
||||||
|
if row > -1:
|
||||||
|
tb.setCurrentIndex(row)
|
||||||
|
tb.blockSignals(False)
|
||||||
|
tb = self.user_box
|
||||||
|
before = tb.currentData()
|
||||||
|
tb.blockSignals(True)
|
||||||
|
tb.clear()
|
||||||
|
tb.addItem(' ', ' ')
|
||||||
|
for user_type, user in db.all_annotation_users():
|
||||||
|
q = '{}: {}'.format(user_type, user)
|
||||||
|
tb.addItem(q, '{}:{}'.format(user_type, user))
|
||||||
|
if before:
|
||||||
|
row = tb.findData(before)
|
||||||
|
if row > -1:
|
||||||
|
tb.setCurrentIndex(row)
|
||||||
|
tb.blockSignals(False)
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return QSize(450, 600)
|
return QSize(450, 600)
|
||||||
|
|
||||||
@ -118,12 +167,22 @@ class BrowsePanel(QWidget):
|
|||||||
text = self.search_box.lineEdit().text().strip()
|
text = self.search_box.lineEdit().text().strip()
|
||||||
if not text:
|
if not text:
|
||||||
return None
|
return None
|
||||||
|
atype = self.types_box.currentData()
|
||||||
|
if not atype or not atype.strip():
|
||||||
|
atype = None
|
||||||
|
user = self.user_box.currentData()
|
||||||
|
restrict_to_user = None
|
||||||
|
if user and ':' in user:
|
||||||
|
restrict_to_user = user.split(':', 1)
|
||||||
return {
|
return {
|
||||||
'fts_engine_query': text,
|
'fts_engine_query': text,
|
||||||
|
'annotation_type': atype,
|
||||||
|
'restrict_to_user': restrict_to_user
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleared(self):
|
def cleared(self):
|
||||||
self.current_query = None
|
self.current_query = None
|
||||||
|
self.results_list.clear()
|
||||||
|
|
||||||
def do_find(self, backwards=False):
|
def do_find(self, backwards=False):
|
||||||
q = self.effective_query
|
q = self.effective_query
|
||||||
@ -134,10 +193,13 @@ class BrowsePanel(QWidget):
|
|||||||
return
|
return
|
||||||
with BusyCursor():
|
with BusyCursor():
|
||||||
db = current_db()
|
db = current_db()
|
||||||
results = db.search_annotations(highlight_start='0x1d', highlight_end='0x1d', snippet_size=64, **q)
|
results = db.search_annotations(highlight_start='\x1d', highlight_end='\x1d', snippet_size=64, **q)
|
||||||
self.results_list.set_results(results)
|
self.results_list.set_results(results)
|
||||||
self.current_query = q
|
self.current_query = q
|
||||||
|
|
||||||
|
def effective_query_changed(self):
|
||||||
|
self.do_find()
|
||||||
|
|
||||||
def show_next(self):
|
def show_next(self):
|
||||||
self.do_find()
|
self.do_find()
|
||||||
|
|
||||||
@ -181,7 +243,7 @@ class AnnotationsBrowser(Dialog):
|
|||||||
l.addWidget(self.bb)
|
l.addWidget(self.bb)
|
||||||
|
|
||||||
def show_dialog(self):
|
def show_dialog(self):
|
||||||
self.browse_panel.search_box.setFocus(Qt.OtherFocusReason)
|
self.browse_panel.re_initialize()
|
||||||
if self.parent() is None:
|
if self.parent() is None:
|
||||||
self.exec_()
|
self.exec_()
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user