From 8beee15db5c71e1b84f691b851b2a9aae4b4f785 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 27 Feb 2015 16:39:03 +0530 Subject: [PATCH] Implement keyboard shortcuts for Open With --- src/calibre/gui2/init.py | 16 ++++++++++++++- src/calibre/gui2/open_with.py | 38 ++++++++++++++++++++++++++++++++--- src/calibre/gui2/ui.py | 2 ++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py index 70240c41ba..267d8cec0a 100644 --- a/src/calibre/gui2/init.py +++ b/src/calibre/gui2/init.py @@ -15,7 +15,7 @@ from calibre.utils.config import prefs from calibre.utils.icu import sort_key from calibre.constants import (isosx, __appname__, preferred_encoding, get_version) -from calibre.gui2 import config, is_widescreen, gprefs +from calibre.gui2 import config, is_widescreen, gprefs, error_dialog from calibre.gui2.library.views import BooksView, DeviceBooksView from calibre.gui2.library.alternate_views import GridView from calibre.gui2.widgets import Splitter, LayoutButton @@ -540,6 +540,20 @@ class LayoutMixin(object): # {{{ if path: from calibre.gui2.open_with import run_program run_program(entry, path, self) + else: + fmt = fmt.upper() + error_dialog(self, _('No %s format') % fmt, _( + 'The book {0} does not have the {1} format').format( + self.current_db.new_api.field_for('title', book_id, default_value=_('Unknown')), + fmt), show=True) + + def open_with_action_triggerred(self, fmt, entry, *args): + book_id = self.library_view.current_book + if book_id is not None: + if fmt == 'cover_image': + self.bd_open_cover_with(book_id, entry) + else: + self.bd_open_fmt_with(book_id, fmt, entry) def bd_cover_removed(self, id_): self.library_view.model().db.remove_cover(id_, commit=True, diff --git a/src/calibre/gui2/open_with.py b/src/calibre/gui2/open_with.py index 5f5110f623..06156c91aa 100644 --- a/src/calibre/gui2/open_with.py +++ b/src/calibre/gui2/open_with.py @@ -13,7 +13,7 @@ from functools import partial from PyQt5.Qt import ( QApplication, QStackedLayout, QVBoxLayout, QWidget, QLabel, Qt, QListWidget, QSize, pyqtSignal, QListWidgetItem, QIcon, QByteArray, - QBuffer, QPixmap) + QBuffer, QPixmap, QAction) from calibre import as_unicode from calibre.constants import iswindows, isosx @@ -60,7 +60,9 @@ else: oprefs = JSONConfig('xdg_open_with') from calibre.utils.open_with.linux import entry_to_cmdline, find_programs, entry_sort_key - def entry_to_icon_text(entry): + def entry_to_icon_text(entry, only_text=False): + if only_text: + return entry['Name'] data = entry.get('icon_data') if data is None: icon = QIcon(I('blank.png')) @@ -194,6 +196,7 @@ def choose_program(file_type='jpeg', parent=None, prefs=oprefs): entries[oft].append(entry) entries[oft].sort(key=entry_sort_key) oprefs['entries'] = entries + register_keyboard_shortcuts(finalize=True) return entry def populate_menu(menu, receiver, file_type): @@ -205,7 +208,7 @@ def populate_menu(menu, receiver, file_type): # }}} -class EditPrograms(Dialog): +class EditPrograms(Dialog): # {{{ def __init__(self, file_type='jpeg', parent=None): self.file_type = file_type.lower() @@ -262,6 +265,7 @@ class EditPrograms(Dialog): row = self.plist.row(ci) self.plist.takeItem(row) self.update_stored_config() + register_keyboard_shortcuts(finalize=True) def update_stored_config(self): entries = [self.plist.item(i).data(ENTRY_ROLE) for i in xrange(self.plist.count())] @@ -271,6 +275,34 @@ class EditPrograms(Dialog): def edit_programs(file_type, parent): d = EditPrograms(file_type, parent) d.exec_() +# }}} + +registered_shortcuts = {} + +def register_keyboard_shortcuts(gui=None, finalize=False): + if gui is None: + from calibre.gui2.ui import get_gui + gui = get_gui() + if gui is None: + return + for unique_name, action in registered_shortcuts.iteritems(): + gui.keyboard.unregister_shortcut(unique_name) + gui.removeAction(action) + registered_shortcuts.clear() + + for filetype, applications in oprefs['entries'].iteritems(): + for application in applications: + text = entry_to_icon_text(application, only_text=True) + t = _('cover image') if filetype.upper() == 'COVER_IMAGE' else filetype.upper() + name = _('Open %s files with %s') % (t, text) + ac = QAction(gui) + unique_name = application['uuid'] + ac.triggered.connect(partial(gui.open_with_action_triggerred, filetype, application)) + gui.keyboard.register_shortcut(unique_name, name, action=ac, group=_('Open With')) + gui.addAction(ac) + registered_shortcuts[unique_name] = ac + if finalize: + gui.keyboard.finalize() if __name__ == '__main__': from pprint import pprint diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index cd22760e22..c05f8012e1 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -48,6 +48,7 @@ from calibre.gui2.proceed import ProceedQuestion from calibre.gui2.dialogs.message_box import JobError from calibre.gui2.job_indicator import Pointer from calibre.gui2.dbus_export.widgets import factory +from calibre.gui2.open_with import register_keyboard_shortcuts from calibre.library import current_library_name class Listener(Thread): # {{{ @@ -406,6 +407,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ self.set_current_library_information(current_library_name(), db.library_id, db.field_metadata) + register_keyboard_shortcuts() self.keyboard.finalize() self.auto_adder = AutoAdder(gprefs['auto_add_path'], self)