Make the context menu for the book details popup window work the same way as for the book details panel

This commit is contained in:
Kovid Goyal 2015-04-09 10:05:16 +05:30
parent d893b8c9c6
commit cf6ee757a8
2 changed files with 95 additions and 80 deletions

View File

@ -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)

View File

@ -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()