E-book viewer: Make all keyboard shortcuts configurable

Fixes #1232019 [[Enhancement] Allow shortcut for Font Increase/Decrease in Viewer](https://bugs.launchpad.net/calibre/+bug/1232019)
This commit is contained in:
Kovid Goyal 2013-10-05 15:37:24 +05:30
parent f55b13aeb0
commit 441dca72de
4 changed files with 77 additions and 45 deletions

View File

@ -498,12 +498,10 @@ class DocumentView(QWebView): # {{{
d.OpenImageInNewWindow, d.OpenLink, d.Reload, d.InspectElement])) d.OpenImageInNewWindow, d.OpenLink, d.Reload, d.InspectElement]))
self.search_online_action = QAction(QIcon(I('search.png')), '', self) self.search_online_action = QAction(QIcon(I('search.png')), '', self)
self.search_online_action.setShortcut(Qt.CTRL+Qt.Key_E)
self.search_online_action.triggered.connect(self.search_online) self.search_online_action.triggered.connect(self.search_online)
self.addAction(self.search_online_action) self.addAction(self.search_online_action)
self.dictionary_action = QAction(QIcon(I('dictionary.png')), self.dictionary_action = QAction(QIcon(I('dictionary.png')),
_('&Lookup in dictionary'), self) _('&Lookup in dictionary'), self)
self.dictionary_action.setShortcut(Qt.CTRL+Qt.Key_L)
self.dictionary_action.triggered.connect(self.lookup) self.dictionary_action.triggered.connect(self.lookup)
self.addAction(self.dictionary_action) self.addAction(self.dictionary_action)
self.image_popup = ImagePopup(self) self.image_popup = ImagePopup(self)
@ -514,7 +512,6 @@ class DocumentView(QWebView): # {{{
self.view_table_action.triggered.connect(self.popup_table) self.view_table_action.triggered.connect(self.popup_table)
self.search_action = QAction(QIcon(I('dictionary.png')), self.search_action = QAction(QIcon(I('dictionary.png')),
_('&Search for next occurrence'), self) _('&Search for next occurrence'), self)
self.search_action.setShortcut(Qt.CTRL+Qt.Key_S)
self.search_action.triggered.connect(self.search_next) self.search_action.triggered.connect(self.search_next)
self.addAction(self.search_action) self.addAction(self.search_action)
@ -652,9 +649,9 @@ class DocumentView(QWebView): # {{{
text = self._selectedText() text = self._selectedText()
if text and img.isNull(): if text and img.isNull():
self.search_online_action.setText(text) self.search_online_action.setText(text)
menu.addAction(self.search_online_action) for x, sc in (('search_online', 'Search online'), ('dictionary', 'Lookup word'), ('search', 'Next occurrence')):
menu.addAction(self.dictionary_action) ac = getattr(self, '%s_action' % x)
menu.addAction(self.search_action) menu.addAction(ac.icon(), '%s [%s]' % (unicode(ac.text()), ','.join(self.shortcuts.get_shortcuts(sc))), ac.trigger)
if not text and img.isNull(): if not text and img.isNull():
menu.addSeparator() menu.addSeparator()

View File

@ -6,6 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
from calibre.constants import isosx
SHORTCUTS = { SHORTCUTS = {
'Next Page' : (['PgDown', 'Space'], 'Next Page' : (['PgDown', 'Space'],
@ -50,4 +51,37 @@ SHORTCUTS = {
'Forward': (['Alt+Right'], 'Forward': (['Alt+Right'],
_('Forward')), _('Forward')),
'Quit': (['Ctrl+Q', 'Ctrl+W', 'Alt+F4'],
_('Quit')),
'Focus Search': (['/', 'Ctrl+F'],
_('Start search')),
'Show metadata': (['Ctrl+I'],
_('Show metadata')),
'Font larger': (['Ctrl+='],
_('Font size larger')),
'Font smaller': (['Ctrl+-'],
_('Font size smaller')),
'Fullscreen': ((['Ctrl+Meta+F'] if isosx else ['Ctrl+Shift+F', 'F11']),
_('Fullscreen')),
'Find next': (['F3'],
_('Find next')),
'Find previous': (['Shift+F3'],
_('Find previous')),
'Search online': (['Ctrl+E'],
_('Search online for word')),
'Lookup word': (['Ctrl+L'],
_('Lookup word in dictionary')),
'Next occurrence': (['Ctrl+S'],
_('Go to next occurrence of selected word')),
} }

View File

@ -8,7 +8,7 @@ from threading import Thread
from PyQt4.Qt import (QApplication, Qt, QIcon, QTimer, QByteArray, QSize, from PyQt4.Qt import (QApplication, Qt, QIcon, QTimer, QByteArray, QSize,
QTime, QDoubleSpinBox, QLabel, QTextBrowser, QPropertyAnimation, QTime, QDoubleSpinBox, QLabel, QTextBrowser, QPropertyAnimation,
QPainter, QBrush, QColor, pyqtSignal, QUrl, QRegExpValidator, QRegExp, QPainter, QBrush, QColor, pyqtSignal, QUrl, QRegExpValidator, QRegExp,
QLineEdit, QToolButton, QMenu, QInputDialog, QAction, QKeySequence, QLineEdit, QToolButton, QMenu, QInputDialog, QAction,
QModelIndex) QModelIndex)
from calibre.gui2.viewer.main_ui import Ui_EbookViewer from calibre.gui2.viewer.main_ui import Ui_EbookViewer
@ -234,18 +234,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.view_resized_timer.timeout.connect(self.viewport_resize_finished) self.view_resized_timer.timeout.connect(self.viewport_resize_finished)
self.view_resized_timer.setSingleShot(True) self.view_resized_timer.setSingleShot(True)
self.resize_in_progress = False self.resize_in_progress = False
qs = [Qt.CTRL+Qt.Key_Q,Qt.CTRL+Qt.Key_W]
self.action_quit.setShortcuts(qs)
self.action_quit.triggered.connect(self.quit) self.action_quit.triggered.connect(self.quit)
self.action_focus_search = QAction(self)
self.addAction(self.action_focus_search)
self.action_focus_search.setShortcuts([Qt.Key_Slash,
QKeySequence(QKeySequence.Find)])
self.action_focus_search.triggered.connect(lambda x:
self.search.setFocus(Qt.OtherFocusReason))
self.action_copy.setDisabled(True) self.action_copy.setDisabled(True)
self.action_metadata.setCheckable(True) self.action_metadata.setCheckable(True)
self.action_metadata.setShortcut(Qt.CTRL+Qt.Key_I)
self.action_table_of_contents.setCheckable(True) self.action_table_of_contents.setCheckable(True)
self.toc.setMinimumWidth(80) self.toc.setMinimumWidth(80)
self.action_reference_mode.setCheckable(True) self.action_reference_mode.setCheckable(True)
@ -255,18 +246,14 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.action_copy.triggered[bool].connect(self.copy) self.action_copy.triggered[bool].connect(self.copy)
self.action_font_size_larger.triggered.connect(self.font_size_larger) self.action_font_size_larger.triggered.connect(self.font_size_larger)
self.action_font_size_smaller.triggered.connect(self.font_size_smaller) self.action_font_size_smaller.triggered.connect(self.font_size_smaller)
self.action_font_size_larger.setShortcut(Qt.CTRL+Qt.Key_Equal)
self.action_font_size_smaller.setShortcut(Qt.CTRL+Qt.Key_Minus)
self.action_open_ebook.triggered[bool].connect(self.open_ebook) self.action_open_ebook.triggered[bool].connect(self.open_ebook)
self.action_next_page.triggered.connect(self.view.next_page) self.action_next_page.triggered.connect(self.view.next_page)
self.action_previous_page.triggered.connect(self.view.previous_page) self.action_previous_page.triggered.connect(self.view.previous_page)
self.action_find_next.triggered.connect(self.find_next) self.action_find_next.triggered.connect(self.find_next)
self.action_find_previous.triggered.connect(self.find_previous) self.action_find_previous.triggered.connect(self.find_previous)
self.action_full_screen.triggered[bool].connect(self.toggle_fullscreen) self.action_full_screen.triggered[bool].connect(self.toggle_fullscreen)
self.action_full_screen.setShortcuts([Qt.Key_F11, Qt.CTRL+Qt.SHIFT+Qt.Key_F]) self.action_full_screen.setToolTip(_('Toggle full screen [%s]') %
self.action_full_screen.setToolTip(_('Toggle full screen (%s)') % _(' or ').join([x for x in self.view.shortcuts.get_shortcuts('Fullscreen')]))
_(' or ').join([unicode(x.toString(x.NativeText)) for x in
self.action_full_screen.shortcuts()]))
self.action_back.triggered[bool].connect(self.back) self.action_back.triggered[bool].connect(self.back)
self.action_forward.triggered[bool].connect(self.forward) self.action_forward.triggered[bool].connect(self.forward)
self.action_preferences.triggered.connect(self.do_config) self.action_preferences.triggered.connect(self.do_config)
@ -348,11 +335,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.pos_label.setFocusPolicy(Qt.NoFocus) self.pos_label.setFocusPolicy(Qt.NoFocus)
self.clock_timer = QTimer(self) self.clock_timer = QTimer(self)
self.clock_timer.timeout.connect(self.update_clock) self.clock_timer.timeout.connect(self.update_clock)
self.esc_full_screen_action = a = QAction(self)
self.addAction(a)
a.setShortcut(Qt.Key_Escape)
a.setEnabled(False)
a.triggered.connect(self.action_full_screen.trigger)
self.print_menu = QMenu() self.print_menu = QMenu()
self.print_menu.addAction(QIcon(I('print-preview.png')), _('Print Preview')) self.print_menu.addAction(QIcon(I('print-preview.png')), _('Print Preview'))
@ -360,9 +342,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup) self.tool_bar.widgetForAction(self.action_print).setPopupMode(QToolButton.MenuButtonPopup)
self.action_print.triggered.connect(self.print_book) self.action_print.triggered.connect(self.print_book)
self.print_menu.actions()[0].triggered.connect(self.print_preview) self.print_menu.actions()[0].triggered.connect(self.print_preview)
ca = self.view.copy_action
ca.setShortcut(QKeySequence.Copy)
self.addAction(ca)
self.open_history_menu = QMenu() self.open_history_menu = QMenu()
self.clear_recent_history_action = QAction( self.clear_recent_history_action = QAction(
_('Clear list of recently opened books'), self) _('Clear list of recently opened books'), self)
@ -518,7 +497,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
p = Printing(self.iterator, self) p = Printing(self.iterator, self)
p.start_preview() p.start_preview()
def toggle_fullscreen(self, x): def toggle_fullscreen(self):
if self.isFullScreen(): if self.isFullScreen():
self.showNormal() self.showNormal()
else: else:
@ -544,7 +523,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
def show_full_screen_label(self): def show_full_screen_label(self):
f = self.full_screen_label f = self.full_screen_label
self.esc_full_screen_action.setEnabled(True)
height = 200 height = 200
width = int(0.7*self.view.width()) width = int(0.7*self.view.width())
f.resize(width, height) f.resize(width, height)
@ -609,7 +587,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.clock_timer.stop() self.clock_timer.stop()
self.vertical_scrollbar.setVisible(True) self.vertical_scrollbar.setVisible(True)
self.window_mode_changed = 'normal' self.window_mode_changed = 'normal'
self.esc_full_screen_action.setEnabled(False)
self.settings_changed() self.settings_changed()
self.full_screen_label.setVisible(False) self.full_screen_label.setVisible(False)
if hasattr(self, '_original_frame_margins'): if hasattr(self, '_original_frame_margins'):
@ -732,11 +709,11 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
def magnification_changed(self, val): def magnification_changed(self, val):
tt = '%(action)s [%(sc)s]\n'+_('Current magnification: %(mag).1f') tt = '%(action)s [%(sc)s]\n'+_('Current magnification: %(mag).1f')
sc = unicode(self.action_font_size_larger.shortcut().toString()) sc = _(' or ').join(self.view.shortcuts.get_shortcuts('Font larger'))
self.action_font_size_larger.setToolTip( self.action_font_size_larger.setToolTip(
tt %dict(action=unicode(self.action_font_size_larger.text()), tt %dict(action=unicode(self.action_font_size_larger.text()),
mag=val, sc=sc)) mag=val, sc=sc))
sc = unicode(self.action_font_size_smaller.shortcut().toString()) sc = _(' or ').join(self.view.shortcuts.get_shortcuts('Font smaller'))
self.action_font_size_smaller.setToolTip( self.action_font_size_smaller.setToolTip(
tt %dict(action=unicode(self.action_font_size_smaller.text()), tt %dict(action=unicode(self.action_font_size_smaller.text()),
mag=val, sc=sc)) mag=val, sc=sc))
@ -1121,10 +1098,40 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.load_path(self.iterator.spine[self.current_index-1], pos=1.0) self.load_path(self.iterator.spine[self.current_index-1], pos=1.0)
def keyPressEvent(self, event): def keyPressEvent(self, event):
MainWindow.keyPressEvent(self, event) if event.key() == Qt.Key_Escape:
if not event.isAccepted(): if self.metadata.isVisible():
if not self.view.handle_key_press(event): self.metadata.setVisible(False)
event.ignore() event.accept()
return
if self.isFullScreen():
self.toggle_fullscreen()
event.accept()
return
try:
key = self.view.shortcuts.get_match(event)
except AttributeError:
return MainWindow.keyPressEvent(self, event)
action = {
'Quit':self.action_quit,
'Show metadata':self.action_metadata,
'Copy':self.view.copy_action,
'Font larger': self.action_font_size_larger,
'Font smaller': self.action_font_size_smaller,
'Fullscreen': self.action_full_screen,
'Find next': self.action_find_next,
'Find previous': self.action_find_previous,
'Search online': self.view.search_online_action,
'Lookup word': self.view.dictionary_action,
'Next occurrence': self.view.search_action,
}.get(key, None)
if action is not None:
event.accept()
action.trigger()
return
if key == 'Focus Search':
self.search.setFocus(Qt.OtherFocusReason)
if not self.view.handle_key_press(event):
event.ignore()
def __enter__(self): def __enter__(self):
return self return self

View File

@ -248,9 +248,6 @@
<property name="toolTip"> <property name="toolTip">
<string>Find next occurrence</string> <string>Find next occurrence</string>
</property> </property>
<property name="shortcut">
<string>F3</string>
</property>
</action> </action>
<action name="action_copy"> <action name="action_copy">
<property name="icon"> <property name="icon">
@ -317,9 +314,6 @@
<property name="toolTip"> <property name="toolTip">
<string>Find previous occurrence</string> <string>Find previous occurrence</string>
</property> </property>
<property name="shortcut">
<string>Shift+F3</string>
</property>
</action> </action>
<action name="action_toggle_paged_mode"> <action name="action_toggle_paged_mode">
<property name="checkable"> <property name="checkable">