From 865b911be684717c88a3365c8588bbfb11fd5f24 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 17 Nov 2019 12:37:25 +0530 Subject: [PATCH] Book details popup window: Add Open with actions to context menu when right clicking the cover image. Fixes #1852626 [[Enhancement] Open image by double clicking on the cover](https://bugs.launchpad.net/calibre/+bug/1852626) --- src/calibre/gui2/actions/show_book_details.py | 1 + src/calibre/gui2/book_details.py | 36 ++++++++++--------- src/calibre/gui2/dialogs/book_info.py | 35 ++++++++++++++++-- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/calibre/gui2/actions/show_book_details.py b/src/calibre/gui2/actions/show_book_details.py index 1736a6fc9d..07a039eb4a 100644 --- a/src/calibre/gui2/actions/show_book_details.py +++ b/src/calibre/gui2/actions/show_book_details.py @@ -39,6 +39,7 @@ class ShowBookDetailsAction(InterfaceAction): if index.isValid(): d = BookInfo(self.gui, self.gui.library_view, index, self.gui.book_details.handle_click) + d.open_cover_with.connect(self.gui.bd_open_cover_with, type=Qt.QueuedConnection) self.memory.append(d) d.closed.connect(self.closed, type=Qt.QueuedConnection) d.show() diff --git a/src/calibre/gui2/book_details.py b/src/calibre/gui2/book_details.py index 4d19a0c1dd..a3efd68a86 100644 --- a/src/calibre/gui2/book_details.py +++ b/src/calibre/gui2/book_details.py @@ -298,6 +298,25 @@ def details_context_menu_event(view, ev, book_info): # }}} +def create_open_cover_with_menu(self, parent_menu): + from calibre.gui2.open_with import populate_menu, edit_programs + m = QMenu(_('Open cover with...')) + + def connect_action(ac, entry): + connect_lambda(ac.triggered, self, lambda self: self.open_with(entry)) + + populate_menu(m, connect_action, 'cover_image') + if len(m.actions()) == 0: + parent_menu.addAction(_('Open cover with...'), self.choose_open_with) + else: + m.addSeparator() + m.addAction(_('Add another application to open cover...'), self.choose_open_with) + m.addAction(_('Edit Open with applications...'), partial(edit_programs, 'cover_image', self)) + parent_menu.ocw = m + parent_menu.addMenu(m) + return m + + class CoverView(QWidget): # {{{ cover_changed = pyqtSignal(object, object) @@ -405,7 +424,6 @@ class CoverView(QWidget): # {{{ ) def contextMenuEvent(self, ev): - from calibre.gui2.open_with import populate_menu, edit_programs cm = QMenu(self) paste = cm.addAction(_('Paste cover')) copy = cm.addAction(_('Copy cover')) @@ -420,21 +438,7 @@ class CoverView(QWidget): # {{{ remove.triggered.connect(self.remove_cover) gc.triggered.connect(self.generate_cover) save.triggered.connect(self.save_cover) - - m = QMenu(_('Open cover with...')) - - def connect_action(ac, entry): - connect_lambda(ac.triggered, self, lambda self: self.open_with(entry)) - - populate_menu(m, connect_action, 'cover_image') - if len(m.actions()) == 0: - cm.addAction(_('Open cover with...'), self.choose_open_with) - else: - m.addSeparator() - m.addAction(_('Add another application to open cover...'), self.choose_open_with) - m.addAction(_('Edit Open with applications...'), partial(edit_programs, 'cover_image', self)) - cm.ocw = m - cm.addMenu(m) + create_open_cover_with_menu(self, cm) cm.si = m = create_search_internet_menu(self.search_internet.emit) cm.addMenu(m) cm.exec_(ev.globalPos()) diff --git a/src/calibre/gui2/dialogs/book_info.py b/src/calibre/gui2/dialogs/book_info.py index 1eb7ac532a..d5f7313efc 100644 --- a/src/calibre/gui2/dialogs/book_info.py +++ b/src/calibre/gui2/dialogs/book_info.py @@ -12,7 +12,8 @@ from PyQt5.Qt import ( from calibre import fit_image from calibre.gui2 import NO_URL_FORMATTING, gprefs from calibre.gui2.book_details import ( - css, details_context_menu_event, render_html, set_html + create_open_cover_with_menu, css, details_context_menu_event, render_html, + set_html ) from calibre.gui2.ui import get_gui from calibre.gui2.widgets import CoverView @@ -20,6 +21,23 @@ from calibre.gui2.widgets2 import Dialog, HTMLDisplay from polyglot.builtins import unicode_type +class Cover(CoverView): + + open_with_requested = pyqtSignal(object) + choose_open_with_requested = pyqtSignal() + + def build_context_menu(self): + ans = CoverView.build_context_menu(self) + create_open_cover_with_menu(self, ans) + return ans + + def open_with(self, entry): + self.open_with_requested.emit(entry) + + def choose_open_with(self): + self.choose_open_with_requested.emit() + + class Configure(Dialog): def __init__(self, db, parent=None): @@ -95,6 +113,7 @@ class Details(HTMLDisplay): class BookInfo(QDialog): closed = pyqtSignal(object) + open_cover_with = pyqtSignal(object, object) def __init__(self, parent, view, row, link_delegate): QDialog.__init__(self, parent) @@ -107,9 +126,11 @@ class BookInfo(QDialog): self.setLayout(l) l.addWidget(self.splitter) - self.cover = CoverView(self, show_size=gprefs['bd_overlay_cover_size']) + self.cover = Cover(self, show_size=gprefs['bd_overlay_cover_size']) self.cover.resizeEvent = self.cover_view_resized self.cover.cover_changed.connect(self.cover_changed) + self.cover.open_with_requested.connect(self.open_with) + self.cover.choose_open_with_requested.connect(self.choose_open_with) self.cover_pixmap = None self.cover.sizeHint = self.details_size_hint self.splitter.addWidget(self.cover) @@ -291,6 +312,16 @@ class BookInfo(QDialog): self.cover.setBackgroundBrush(self.marked_brush if mi.marked else self.normal_brush) self.update_cover_tooltip() + def open_with(self, entry): + id_ = self.view.model().id(self.current_row) + self.open_cover_with.emit(id_, entry) + + def choose_open_with(self): + from calibre.gui2.open_with import choose_program + entry = choose_program('cover_image', self) + if entry is not None: + self.open_with(entry) + if __name__ == '__main__': from calibre.gui2 import Application