Wire up open annotations button and add button to select book in calibre

This commit is contained in:
Kovid Goyal 2020-06-26 09:50:17 +05:30
parent b958361a18
commit 1f253580b5
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 56 additions and 17 deletions

View File

@ -4,6 +4,7 @@
from __future__ import absolute_import, division, print_function, unicode_literals from __future__ import absolute_import, division, print_function, unicode_literals
from PyQt5.Qt import Qt
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
@ -25,7 +26,19 @@ class BrowseAnnotationsAction(InterfaceAction):
if self._browser is None: if self._browser is None:
from calibre.gui2.library.annotations import AnnotationsBrowser from calibre.gui2.library.annotations import AnnotationsBrowser
self._browser = AnnotationsBrowser(self.gui) self._browser = AnnotationsBrowser(self.gui)
self._browser.show_book.connect(self.open_book, type=Qt.QueuedConnection)
self._browser.open_annotation.connect(self.open_annotation, type=Qt.QueuedConnection)
return self._browser return self._browser
def show_browser(self): def show_browser(self):
self.browser.show_dialog() self.browser.show_dialog()
def library_changed(self, db):
if self._browser is not None:
self._browser.reinitialize()
def open_book(self, book_id, fmt):
self.gui.library_view.select_rows({book_id})
def open_annotation(self, book_id, fmt, cfi):
self.gui.iactions['View'].view_format_by_id(book_id, fmt, open_at=cfi)

View File

@ -107,13 +107,13 @@ class ViewAction(InterfaceAction):
'annotations_map': annotations_map, 'annotations_map': annotations_map,
} }
def view_format_by_id(self, id_, format): def view_format_by_id(self, id_, format, open_at=None):
db = self.gui.current_db db = self.gui.current_db
fmt_path = db.format_abspath(id_, format, fmt_path = db.format_abspath(id_, format,
index_is_id=True) index_is_id=True)
if fmt_path: if fmt_path:
title = db.title(id_, index_is_id=True) title = db.title(id_, index_is_id=True)
self._view_file(fmt_path, calibre_book_data=self.calibre_book_data(id_, format)) self._view_file(fmt_path, calibre_book_data=self.calibre_book_data(id_, format), open_at=open_at)
self.update_history([(id_, title)]) self.update_history([(id_, title)])
def book_downloaded_for_viewing(self, job): def book_downloaded_for_viewing(self, job):
@ -122,7 +122,7 @@ class ViewAction(InterfaceAction):
return return
self._view_file(job.result) self._view_file(job.result)
def _launch_viewer(self, name=None, viewer='ebook-viewer', internal=True, calibre_book_data=None): def _launch_viewer(self, name=None, viewer='ebook-viewer', internal=True, calibre_book_data=None, open_at=None):
self.gui.setCursor(Qt.BusyCursor) self.gui.setCursor(Qt.BusyCursor)
try: try:
if internal: if internal:
@ -132,6 +132,8 @@ class ViewAction(InterfaceAction):
if name is not None: if name is not None:
args.append(name) args.append(name)
if open_at is not None:
args.append('--open-at=' + open_at)
if calibre_book_data is not None: if calibre_book_data is not None:
with PersistentTemporaryFile('.json') as ptf: with PersistentTemporaryFile('.json') as ptf:
ptf.write(as_bytes(json.dumps(calibre_book_data))) ptf.write(as_bytes(json.dumps(calibre_book_data)))
@ -162,12 +164,12 @@ class ViewAction(InterfaceAction):
finally: finally:
self.gui.unsetCursor() self.gui.unsetCursor()
def _view_file(self, name, calibre_book_data=None): def _view_file(self, name, calibre_book_data=None, open_at=None):
ext = os.path.splitext(name)[1].upper().replace('.', ext = os.path.splitext(name)[1].upper().replace('.',
'').replace('ORIGINAL_', '') '').replace('ORIGINAL_', '')
viewer = 'lrfviewer' if ext == 'LRF' else 'ebook-viewer' viewer = 'lrfviewer' if ext == 'LRF' else 'ebook-viewer'
internal = self.force_internal_viewer or ext in config['internally_viewed_formats'] internal = self.force_internal_viewer or ext in config['internally_viewed_formats'] or open_at is not None
self._launch_viewer(name, viewer, internal, calibre_book_data=calibre_book_data) self._launch_viewer(name, viewer, internal, calibre_book_data=calibre_book_data, open_at=open_at)
def view_specific_format(self, triggered): def view_specific_format(self, triggered):
rows = list(self.gui.library_view.selectionModel().selectedRows()) rows = list(self.gui.library_view.selectionModel().selectedRows())

View File

@ -63,7 +63,7 @@ class AnnotsResultsDelegate(ResultsDelegate):
class ResultsList(QTreeWidget): class ResultsList(QTreeWidget):
current_result_changed = pyqtSignal(object) current_result_changed = pyqtSignal(object)
open_annotation = pyqtSignal(object) open_annotation = pyqtSignal(object, object, object)
def __init__(self, parent): def __init__(self, parent):
QTreeWidget.__init__(self, parent) QTreeWidget.__init__(self, parent)
@ -80,7 +80,7 @@ class ResultsList(QTreeWidget):
def item_activated(self, item): def item_activated(self, item):
r = item.data(0, Qt.UserRole) r = item.data(0, Qt.UserRole)
if isinstance(r, dict): if isinstance(r, dict):
self.open_annotation.emit(r['annotation']) self.open_annotation.emit(r['book_id'], r['format'], r['annotation'])
def set_results(self, results): def set_results(self, results):
self.clear() self.clear()
@ -206,7 +206,7 @@ class Restrictions(QWidget):
class BrowsePanel(QWidget): class BrowsePanel(QWidget):
current_result_changed = pyqtSignal(object) current_result_changed = pyqtSignal(object)
open_annotation = pyqtSignal(object) open_annotation = pyqtSignal(object, object, object)
def __init__(self, parent): def __init__(self, parent):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
@ -251,6 +251,7 @@ class BrowsePanel(QWidget):
db = current_db() db = current_db()
self.search_box.setFocus(Qt.OtherFocusReason) self.search_box.setFocus(Qt.OtherFocusReason)
self.restrictions.re_initialize(db) self.restrictions.re_initialize(db)
self.cleared()
def sizeHint(self): def sizeHint(self):
return QSize(450, 600) return QSize(450, 600)
@ -316,7 +317,8 @@ class Details(QTextBrowser):
class DetailsPanel(QWidget): class DetailsPanel(QWidget):
open_annotation = pyqtSignal(object) open_annotation = pyqtSignal(object, object, object)
show_book = pyqtSignal(object, object)
def __init__(self, parent): def __init__(self, parent):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
@ -324,14 +326,29 @@ class DetailsPanel(QWidget):
l = QVBoxLayout(self) l = QVBoxLayout(self)
self.text_browser = tb = Details(self) self.text_browser = tb = Details(self)
l.addWidget(tb) l.addWidget(tb)
h = QHBoxLayout()
l.addLayout(h)
self.open_button = ob = QPushButton(QIcon(I('viewer.png')), _('Open in viewer'), self) self.open_button = ob = QPushButton(QIcon(I('viewer.png')), _('Open in viewer'), self)
ob.setToolTip(_('Open the book at this annotation in the calibre viewer'))
ob.clicked.connect(self.open_result) ob.clicked.connect(self.open_result)
l.addWidget(ob) h.addWidget(ob)
self.library_button = lb = QPushButton(QIcon(I('lt.png')), _('Show in calibre'), self)
lb.setToolTip(_('Show this book in the main calibre book list'))
lb.clicked.connect(self.show_in_library)
h.addWidget(lb)
self.show_result(None) self.show_result(None)
def open_result(self): def open_result(self):
if self.current_result is not None: if self.current_result is not None:
self.open_annotation.emit(self.current_result['annotation']) r = self.current_result
self.open_annotation.emit(r['book_id'], r['format'], r['annotation'])
def show_in_library(self):
if self.current_result is not None:
self.show_book.emit(self.current_result['book_id'], self.current_result['format'])
def sizeHint(self): def sizeHint(self):
return QSize(450, 600) return QSize(450, 600)
@ -341,9 +358,11 @@ class DetailsPanel(QWidget):
if r is None: if r is None:
self.text_browser.setVisible(False) self.text_browser.setVisible(False)
self.open_button.setVisible(False) self.open_button.setVisible(False)
self.library_button.setVisible(False)
return return
self.text_browser.setVisible(True) self.text_browser.setVisible(True)
self.open_button.setVisible(True) self.open_button.setVisible(True)
self.library_button.setVisible(True)
db = current_db() db = current_db()
book_id = r['book_id'] book_id = r['book_id']
title, authors = db.field_for('title', book_id), db.field_for('authors', book_id) title, authors = db.field_for('title', book_id), db.field_for('authors', book_id)
@ -385,20 +404,21 @@ class DetailsPanel(QWidget):
class AnnotationsBrowser(Dialog): class AnnotationsBrowser(Dialog):
open_annotation = pyqtSignal(object) open_annotation = pyqtSignal(object, object, object)
show_book = pyqtSignal(object, object)
def __init__(self, parent=None): def __init__(self, parent=None):
Dialog.__init__(self, _('Annotations browser'), 'library-annotations-browser-1', parent=parent) Dialog.__init__(self, _('Annotations browser'), 'library-annotations-browser-1', parent=parent)
self.setAttribute(Qt.WA_DeleteOnClose, False) self.setAttribute(Qt.WA_DeleteOnClose, False)
def do_open_annotation(self, annot): def do_open_annotation(self, book_id, fmt, annot):
atype = annot['type'] atype = annot['type']
if atype == 'bookmark': if atype == 'bookmark':
if annot['pos_type'] == 'epubcfi': if annot['pos_type'] == 'epubcfi':
self.open_annotation.emit(annot['pos']) self.open_annotation.emit(book_id, fmt, annot['pos'])
elif atype == 'highlight': elif atype == 'highlight':
x = 2 * (annot['spine_index'] + 1) x = 2 * (annot['spine_index'] + 1)
self.open_annotation.emit('epubcfi(/{}{})'.format(x, annot['start_cfi'])) self.open_annotation.emit(book_id, fmt, 'epubcfi(/{}{})'.format(x, annot['start_cfi']))
def keyPressEvent(self, ev): def keyPressEvent(self, ev):
if ev.key() not in (Qt.Key_Enter, Qt.Key_Return): if ev.key() not in (Qt.Key_Enter, Qt.Key_Return):
@ -425,6 +445,7 @@ class AnnotationsBrowser(Dialog):
self.details_panel = dp = DetailsPanel(self) self.details_panel = dp = DetailsPanel(self)
s.addWidget(dp) s.addWidget(dp)
dp.open_annotation.connect(self.do_open_annotation) dp.open_annotation.connect(self.do_open_annotation)
dp.show_book.connect(self.show_book)
bp.current_result_changed.connect(dp.show_result) bp.current_result_changed.connect(dp.show_result)
h = QHBoxLayout() h = QHBoxLayout()
@ -432,19 +453,22 @@ class AnnotationsBrowser(Dialog):
h.addWidget(us), h.addStretch(10), h.addWidget(self.bb) h.addWidget(us), h.addStretch(10), h.addWidget(self.bb)
def show_dialog(self): def show_dialog(self):
self.browse_panel.re_initialize()
if self.parent() is None: if self.parent() is None:
self.exec_() self.exec_()
else: else:
self.show() self.show()
self.raise_() self.raise_()
def reinitialize(self):
self.browse_panel.re_initialize()
if __name__ == '__main__': if __name__ == '__main__':
from calibre.library import db from calibre.library import db
app = Application([]) app = Application([])
current_db.ans = db(os.path.expanduser('~/test library')) current_db.ans = db(os.path.expanduser('~/test library'))
br = AnnotationsBrowser() br = AnnotationsBrowser()
br.reinitialize()
br.show_dialog() br.show_dialog()
del br del br
del app del app