From cf6ee757a8d1a1f513411fef4db14cd5c17c7051 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 9 Apr 2015 10:05:16 +0530 Subject: [PATCH] Make the context menu for the book details popup window work the same way as for the book details panel --- src/calibre/gui2/book_details.py | 158 +++++++++++++------------- src/calibre/gui2/dialogs/book_info.py | 17 ++- 2 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index 442c64f091..9e18237c3e 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -104,6 +104,86 @@ def render_data(mi, use_roman_numbers=True, all_fields=False): # }}} +def details_context_menu_event(view, ev, self): # {{{ + p = view.page() + mf = p.mainFrame() + r = mf.hitTestContent(ev.pos()) + url = unicode(r.linkUrl().toString(QUrl.None)).strip() + menu = p.createStandardContextMenu() + ca = view.pageAction(p.Copy) + for action in list(menu.actions()): + if action is not ca: + menu.removeAction(action) + if not r.isNull(): + if url.startswith('format:'): + parts = url.split(':') + try: + book_id, fmt = int(parts[1]), parts[2].upper() + except: + import traceback + traceback.print_exc() + else: + from calibre.gui2.ui import get_gui + from calibre.ebooks.oeb.polish.main import SUPPORTED + db = get_gui().current_db.new_api + ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt + nfmt = ofmt[len('ORIGINAL_'):] + fmts = {x.upper() for x in db.formats(book_id)} + for a, t in [('remove', _('Delete the %s format')), + ('save', _('Save the %s format to disk')), + ('restore', _('Restore the %s format')), + ('compare', ''), + ]: + if a == 'restore' and not fmt.startswith('ORIGINAL_'): + continue + if a == 'compare': + if ofmt not in fmts or nfmt not in SUPPORTED: + continue + t = _('Compare to the %s format') % (fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt) + else: + t = t % fmt + ac = getattr(self, '%s_format_action'%a) + ac.current_fmt = (book_id, fmt) + ac.setText(t) + menu.addAction(ac) + if not fmt.upper().startswith('ORIGINAL_'): + from calibre.gui2.open_with import populate_menu, edit_programs + m = QMenu(_('Open %s with...') % fmt.upper()) + populate_menu(m, partial(self.open_with, book_id, fmt), fmt) + if len(m.actions()) == 0: + menu.addAction(_('Open %s with...') % fmt.upper(), partial(self.choose_open_with, book_id, fmt)) + else: + m.addSeparator() + m.addAction(_('Add other application for %s files...') % fmt.upper(), partial(self.choose_open_with, book_id, fmt)) + m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, self)) + menu.addMenu(m) + ac = self.copy_link_action + ac.current_url = r.linkElement().attribute('data-full-path') + if ac.current_url: + ac.setText(_('&Copy path to file')) + menu.addAction(ac) + else: + el = r.linkElement() + author = el.toPlainText() if unicode(el.attribute('calibre-data')) == u'authors' else None + if not url.startswith('search:'): + for a, t in [('copy', _('&Copy Link')), + ]: + ac = getattr(self, '%s_link_action'%a) + ac.current_url = url + if url.startswith('path:'): + ac.current_url = el.attribute('title') + ac.setText(t) + menu.addAction(ac) + if author is not None: + ac = self.manage_author_action + ac.current_fmt = author + ac.setText(_('Manage %s') % author) + menu.addAction(ac) + + if len(menu.actions()) > 0: + menu.exec_(ev.globalPos()) +# }}} + class CoverView(QWidget): # {{{ cover_changed = pyqtSignal(object, object) @@ -389,83 +469,7 @@ class BookInfo(QWebView): ev.ignore() def contextMenuEvent(self, ev): - p = self.page() - mf = p.mainFrame() - r = mf.hitTestContent(ev.pos()) - url = unicode(r.linkUrl().toString(QUrl.None)).strip() - menu = p.createStandardContextMenu() - ca = self.pageAction(p.Copy) - for action in list(menu.actions()): - if action is not ca: - menu.removeAction(action) - if not r.isNull(): - if url.startswith('format:'): - parts = url.split(':') - try: - book_id, fmt = int(parts[1]), parts[2].upper() - except: - import traceback - traceback.print_exc() - else: - from calibre.gui2.ui import get_gui - from calibre.ebooks.oeb.polish.main import SUPPORTED - db = get_gui().current_db.new_api - ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt - nfmt = ofmt[len('ORIGINAL_'):] - fmts = {x.upper() for x in db.formats(book_id)} - for a, t in [('remove', _('Delete the %s format')), - ('save', _('Save the %s format to disk')), - ('restore', _('Restore the %s format')), - ('compare', ''), - ]: - if a == 'restore' and not fmt.startswith('ORIGINAL_'): - continue - if a == 'compare': - if ofmt not in fmts or nfmt not in SUPPORTED: - continue - t = _('Compare to the %s format') % (fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt) - else: - t = t % fmt - ac = getattr(self, '%s_format_action'%a) - ac.current_fmt = (book_id, fmt) - ac.setText(t) - menu.addAction(ac) - if not fmt.upper().startswith('ORIGINAL_'): - from calibre.gui2.open_with import populate_menu, edit_programs - m = QMenu(_('Open %s with...') % fmt.upper()) - populate_menu(m, partial(self.open_with, book_id, fmt), fmt) - if len(m.actions()) == 0: - menu.addAction(_('Open %s with...') % fmt.upper(), partial(self.choose_open_with, book_id, fmt)) - else: - m.addSeparator() - m.addAction(_('Add other application for %s files...') % fmt.upper(), partial(self.choose_open_with, book_id, fmt)) - m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, self)) - menu.addMenu(m) - ac = self.copy_link_action - ac.current_url = r.linkElement().attribute('data-full-path') - if ac.current_url: - ac.setText(_('&Copy path to file')) - menu.addAction(ac) - else: - el = r.linkElement() - author = el.toPlainText() if unicode(el.attribute('calibre-data')) == u'authors' else None - if not url.startswith('search:'): - for a, t in [('copy', _('&Copy Link')), - ]: - ac = getattr(self, '%s_link_action'%a) - ac.current_url = url - if url.startswith('path:'): - ac.current_url = el.attribute('title') - ac.setText(t) - menu.addAction(ac) - if author is not None: - ac = self.manage_author_action - ac.current_fmt = author - ac.setText(_('Manage %s') % author) - menu.addAction(ac) - - if len(menu.actions()) > 0: - menu.exec_(ev.globalPos()) + details_context_menu_event(self, ev, self) def open_with(self, book_id, fmt, entry): self.open_fmt_with.emit(book_id, fmt, entry) diff --git a/src/calibre/gui2/dialogs/book_info.py b/src/calibre/gui2/dialogs/book_info.py index 2893bc3142..24128c2017 100644 --- a/src/calibre/gui2/dialogs/book_info.py +++ b/src/calibre/gui2/dialogs/book_info.py @@ -14,7 +14,7 @@ from PyQt5.QtWebKitWidgets import QWebView from calibre.gui2 import gprefs from calibre import fit_image -from calibre.gui2.book_details import render_html +from calibre.gui2.book_details import render_html, details_context_menu_event from calibre.gui2.widgets import CoverView _css = None @@ -24,6 +24,18 @@ def css(): _css = P('templates/book_details.css', data=True).decode('utf-8') return _css +class Details(QWebView): + + def __init__(self, book_info, parent=None): + QWebView.__init__(self, parent) + self.book_info = book_info + + def sizeHint(self): + return QSize(350, 350) + + def contextMenuEvent(self, ev): + details_context_menu_event(self, ev, self.book_info) + class BookInfo(QDialog): closed = pyqtSignal(object) @@ -46,8 +58,7 @@ class BookInfo(QDialog): self.cover.sizeHint = self.details_size_hint self.splitter.addWidget(self.cover) - self.details = QWebView(self) - self.details.sizeHint = self.details_size_hint + self.details = Details(parent.book_details.book_info, self) self.details.page().setLinkDelegationPolicy(self.details.page().DelegateAllLinks) self.details.linkClicked.connect(self.link_clicked) s = self.details.page().settings()