mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Cleanup creation of menus for toolbar buttons and add the keyboard shortcut G for Get Books
This commit is contained in:
parent
a5e8b23bfe
commit
f929fe73df
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
from functools import partial
|
||||
from zipfile import ZipFile
|
||||
|
||||
from PyQt4.Qt import QToolButton, QAction, QIcon, QObject
|
||||
from PyQt4.Qt import QToolButton, QAction, QIcon, QObject, QMenu
|
||||
|
||||
from calibre.gui2 import Dispatcher
|
||||
|
||||
@ -66,6 +66,14 @@ class InterfaceAction(QObject):
|
||||
#: shortcut must be a translated string if not None
|
||||
action_spec = ('text', 'icon', None, None)
|
||||
|
||||
#: If True, a menu is automatically created and added to self.qaction
|
||||
action_add_menu = False
|
||||
|
||||
#: If True, a clone of self.qaction is added to the menu of self.qaction
|
||||
#: If you want the text of this action to be different from that of
|
||||
#: self.qaction, set this variable to the new text
|
||||
action_menu_clone_qaction = False
|
||||
|
||||
#: Set of locations to which this action must not be added.
|
||||
#: See :attr:`all_locations` for a list of possible locations
|
||||
dont_add_to = frozenset([])
|
||||
@ -94,6 +102,7 @@ class InterfaceAction(QObject):
|
||||
self.Dispatcher = partial(Dispatcher, parent=self)
|
||||
self.create_action()
|
||||
self.gui.addAction(self.qaction)
|
||||
self.gui.addAction(self.menuless_qaction)
|
||||
self.genesis()
|
||||
|
||||
def create_action(self, spec=None, attr='qaction'):
|
||||
@ -104,18 +113,29 @@ class InterfaceAction(QObject):
|
||||
action = QAction(QIcon(I(icon)), text, self.gui)
|
||||
else:
|
||||
action = QAction(text, self.gui)
|
||||
action.setAutoRepeat(self.auto_repeat)
|
||||
text = tooltip if tooltip else text
|
||||
action.setToolTip(text)
|
||||
action.setStatusTip(text)
|
||||
action.setWhatsThis(text)
|
||||
action.setAutoRepeat(False)
|
||||
if attr == 'qaction':
|
||||
mt = (action.text() if self.action_menu_clone_qaction is True else
|
||||
unicode(self.action_menu_clone_qaction))
|
||||
self.menuless_qaction = ma = QAction(action.icon(), mt, self.gui)
|
||||
ma.triggered.connect(action.trigger)
|
||||
for a in ((action, ma) if attr == 'qaction' else (action,)):
|
||||
a.setAutoRepeat(self.auto_repeat)
|
||||
text = tooltip if tooltip else text
|
||||
a.setToolTip(text)
|
||||
a.setStatusTip(text)
|
||||
a.setWhatsThis(text)
|
||||
if shortcut:
|
||||
a = ma if attr == 'qaction' else action
|
||||
if isinstance(shortcut, list):
|
||||
action.setShortcuts(shortcut)
|
||||
a.setShortcuts(shortcut)
|
||||
else:
|
||||
action.setShortcut(shortcut)
|
||||
a.setShortcut(shortcut)
|
||||
setattr(self, attr, action)
|
||||
if attr == 'qaction' and self.action_add_menu:
|
||||
menu = QMenu()
|
||||
action.setMenu(menu)
|
||||
if self.action_menu_clone_qaction:
|
||||
menu.addAction(self.menuless_qaction)
|
||||
return action
|
||||
|
||||
def load_resources(self, names):
|
||||
|
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
import os
|
||||
from functools import partial
|
||||
|
||||
from PyQt4.Qt import QPixmap, QMenu, QTimer
|
||||
from PyQt4.Qt import QPixmap, QTimer
|
||||
|
||||
|
||||
from calibre.gui2 import error_dialog, choose_files, \
|
||||
@ -48,12 +48,12 @@ class AddAction(InterfaceAction):
|
||||
_('Add books to the calibre library/device from files on your computer')
|
||||
, _('A'))
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = _('Add books from a single directory')
|
||||
|
||||
def genesis(self):
|
||||
self._add_filesystem_book = self.Dispatcher(self.__add_filesystem_book)
|
||||
self.add_menu = QMenu()
|
||||
self.add_menu.addAction(_('Add books from a single directory'),
|
||||
self.add_books)
|
||||
self.add_menu = self.qaction.menu()
|
||||
self.add_menu.addAction(_('Add books from directories, including '
|
||||
'sub-directories (One book per directory, assumes every ebook '
|
||||
'file is the same book in a different format)'),
|
||||
@ -69,7 +69,6 @@ class AddAction(InterfaceAction):
|
||||
self.add_menu.addAction(_('Add files to selected book records'),
|
||||
self.add_formats, _('Shift+A'))
|
||||
|
||||
self.qaction.setMenu(self.add_menu)
|
||||
self.qaction.triggered.connect(self.add_books)
|
||||
|
||||
def location_selected(self, loc):
|
||||
|
@ -82,23 +82,20 @@ class ChooseLibraryAction(InterfaceAction):
|
||||
action_spec = (_('%d books'), 'lt.png',
|
||||
_('Choose calibre library to work with'), None)
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = _('Switch/create library...')
|
||||
|
||||
def genesis(self):
|
||||
self.count_changed(0)
|
||||
self.qaction.triggered.connect(self.choose_library,
|
||||
type=Qt.QueuedConnection)
|
||||
self.action_choose = self.menuless_qaction
|
||||
|
||||
self.stats = LibraryUsageStats()
|
||||
self.popup_type = (QToolButton.InstantPopup if len(self.stats.stats) > 1 else
|
||||
QToolButton.MenuButtonPopup)
|
||||
|
||||
self.create_action(spec=(_('Switch/create library...'), 'lt.png', None,
|
||||
None), attr='action_choose')
|
||||
self.action_choose.triggered.connect(self.choose_library,
|
||||
type=Qt.QueuedConnection)
|
||||
self.choose_menu = QMenu(self.gui)
|
||||
self.qaction.setMenu(self.choose_menu)
|
||||
|
||||
self.choose_menu = self.qaction.menu()
|
||||
|
||||
if not os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None):
|
||||
self.choose_menu.addAction(self.action_choose)
|
||||
@ -110,7 +107,7 @@ class ChooseLibraryAction(InterfaceAction):
|
||||
self.delete_menu = QMenu(_('Remove library'))
|
||||
self.delete_menu_action = self.choose_menu.addMenu(self.delete_menu)
|
||||
|
||||
ac = self.create_action(spec=(_('Pick a random book'), 'catalog.png',
|
||||
ac = self.create_action(spec=(_('Pick a random book'), 'random.png',
|
||||
None, None), attr='action_pick_random')
|
||||
ac.triggered.connect(self.pick_random)
|
||||
self.choose_menu.addAction(ac)
|
||||
|
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
import os
|
||||
from functools import partial
|
||||
|
||||
from PyQt4.Qt import QModelIndex, QMenu
|
||||
from PyQt4.Qt import QModelIndex, QIcon
|
||||
|
||||
from calibre.gui2 import error_dialog, Dispatcher
|
||||
from calibre.gui2.tools import convert_single_ebook, convert_bulk_ebook
|
||||
@ -22,18 +22,18 @@ class ConvertAction(InterfaceAction):
|
||||
action_spec = (_('Convert books'), 'convert.png', None, _('C'))
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
|
||||
def genesis(self):
|
||||
cm = QMenu()
|
||||
cm.addAction(_('Convert individually'), partial(self.convert_ebook,
|
||||
cm = self.qaction.menu()
|
||||
cm.addAction(self.qaction.icon(), _('Convert individually'), partial(self.convert_ebook,
|
||||
False, bulk=False))
|
||||
cm.addAction(_('Bulk convert'),
|
||||
partial(self.convert_ebook, False, bulk=True))
|
||||
cm.addSeparator()
|
||||
ac = cm.addAction(
|
||||
ac = cm.addAction(QIcon(I('catalog.png')),
|
||||
_('Create a catalog of the books in your calibre library'))
|
||||
ac.triggered.connect(self.gui.iactions['Generate Catalog'].generate_catalog)
|
||||
self.qaction.setMenu(cm)
|
||||
self.qaction.triggered.connect(self.convert_ebook)
|
||||
self.convert_menu = cm
|
||||
self.conversion_jobs = {}
|
||||
|
@ -9,7 +9,7 @@ import os
|
||||
from functools import partial
|
||||
from threading import Thread
|
||||
|
||||
from PyQt4.Qt import QMenu, QToolButton
|
||||
from PyQt4.Qt import QToolButton
|
||||
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
from calibre.gui2 import error_dialog, Dispatcher, warning_dialog
|
||||
@ -95,10 +95,10 @@ class CopyToLibraryAction(InterfaceAction):
|
||||
popup_type = QToolButton.InstantPopup
|
||||
dont_add_to = frozenset(['toolbar-device', 'context-menu-device'])
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
|
||||
def genesis(self):
|
||||
self.menu = QMenu(self.gui)
|
||||
self.qaction.setMenu(self.menu)
|
||||
self.menu = self.qaction.menu()
|
||||
|
||||
@property
|
||||
def stats(self):
|
||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
from functools import partial
|
||||
|
||||
from PyQt4.Qt import QMenu, QObject, QTimer
|
||||
from PyQt4.Qt import QObject, QTimer
|
||||
|
||||
from calibre.gui2 import error_dialog, question_dialog
|
||||
from calibre.gui2.dialogs.delete_matching_from_device import DeleteMatchingFromDeviceDialog
|
||||
@ -18,7 +18,7 @@ from calibre.utils.recycle_bin import can_recycle
|
||||
|
||||
single_shot = partial(QTimer.singleShot, 10)
|
||||
|
||||
class MultiDeleter(QObject):
|
||||
class MultiDeleter(QObject): # {{{
|
||||
|
||||
def __init__(self, gui, ids, callback):
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
@ -77,17 +77,19 @@ class MultiDeleter(QObject):
|
||||
error_dialog(self.gui, _('Failed to delete'),
|
||||
_('Failed to delete some books, click the Show Details button'
|
||||
' for details.'), det_msg='\n\n'.join(msg), show=True)
|
||||
# }}}
|
||||
|
||||
class DeleteAction(InterfaceAction):
|
||||
|
||||
name = 'Remove Books'
|
||||
action_spec = (_('Remove books'), 'trash.png', None, 'Del')
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = _('Remove selected books')
|
||||
|
||||
def genesis(self):
|
||||
self.qaction.triggered.connect(self.delete_books)
|
||||
self.delete_menu = QMenu()
|
||||
self.delete_menu.addAction(_('Remove selected books'), self.delete_books)
|
||||
self.delete_menu = self.qaction.menu()
|
||||
self.delete_menu.addAction(
|
||||
_('Remove files of a specific format from selected books..'),
|
||||
self.delete_selected_formats)
|
||||
|
@ -24,12 +24,13 @@ class EditMetadataAction(InterfaceAction):
|
||||
name = 'Edit Metadata'
|
||||
action_spec = (_('Edit metadata'), 'edit_input.png', None, _('E'))
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
|
||||
def genesis(self):
|
||||
self.create_action(spec=(_('Merge book records'), 'merge_books.png',
|
||||
None, _('M')), attr='action_merge')
|
||||
md = QMenu()
|
||||
md.addAction(_('Edit metadata individually'),
|
||||
md = self.qaction.menu()
|
||||
md.addAction(self.qaction.icon(), _('Edit metadata individually'),
|
||||
partial(self.edit_metadata, False, bulk=False))
|
||||
md.addSeparator()
|
||||
md.addAction(_('Edit metadata in bulk'),
|
||||
@ -56,7 +57,6 @@ class EditMetadataAction(InterfaceAction):
|
||||
md.addAction(self.action_merge)
|
||||
|
||||
self.qaction.triggered.connect(self.edit_metadata)
|
||||
self.qaction.setMenu(md)
|
||||
self.action_merge.triggered.connect(self.merge_books)
|
||||
|
||||
def location_selected(self, loc):
|
||||
|
@ -5,7 +5,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from PyQt4.Qt import QIcon, QMenu, Qt
|
||||
from PyQt4.Qt import QIcon, Qt
|
||||
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
from calibre.gui2.preferences.main import Preferences
|
||||
@ -16,12 +16,13 @@ class PreferencesAction(InterfaceAction):
|
||||
|
||||
name = 'Preferences'
|
||||
action_spec = (_('Preferences'), 'config.png', None, _('Ctrl+P'))
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = _('Change calibre behavior')
|
||||
|
||||
def genesis(self):
|
||||
pm = QMenu()
|
||||
pm.addAction(QIcon(I('config.png')), _('Preferences'), self.do_config)
|
||||
pm = self.qaction.menu()
|
||||
if isosx:
|
||||
pm.addAction(QIcon(I('config.png')), _('Change calibre behavior'), self.do_config)
|
||||
pm.addAction(QIcon(I('config.png')), _('Preferences'), self.do_config)
|
||||
pm.addAction(QIcon(I('wizard.png')), _('Run welcome wizard'),
|
||||
self.gui.run_wizard)
|
||||
pm.addAction(QIcon(I('plugins/plugin_updater.png')),
|
||||
@ -33,7 +34,6 @@ class PreferencesAction(InterfaceAction):
|
||||
ac.setShortcut('Ctrl+Shift+R')
|
||||
self.gui.addAction(ac)
|
||||
|
||||
self.qaction.setMenu(pm)
|
||||
self.preferences_menu = pm
|
||||
for x in (self.gui.preferences_action, self.qaction):
|
||||
x.triggered.connect(self.do_config)
|
||||
|
@ -38,12 +38,12 @@ class SaveToDiskAction(InterfaceAction):
|
||||
name = "Save To Disk"
|
||||
action_spec = (_('Save to disk'), 'save.png', None, _('S'))
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = True
|
||||
|
||||
def genesis(self):
|
||||
self.qaction.triggered.connect(self.save_to_disk)
|
||||
self.save_menu = QMenu()
|
||||
self.save_menu.addAction(_('Save to disk'), partial(self.save_to_disk,
|
||||
False))
|
||||
self.save_menu = self.qaction.menu()
|
||||
self.save_menu.addAction(_('Save to disk in a single directory'),
|
||||
partial(self.save_to_single_dir, False))
|
||||
self.save_menu.addAction(_('Save only %s format to disk')%
|
||||
@ -56,7 +56,6 @@ class SaveToDiskAction(InterfaceAction):
|
||||
self.save_sub_menu = SaveMenu(self.gui)
|
||||
self.save_sub_menu_action = self.save_menu.addMenu(self.save_sub_menu)
|
||||
self.save_sub_menu.save_fmt.connect(self.save_specific_format_disk)
|
||||
self.qaction.setMenu(self.save_menu)
|
||||
|
||||
def location_selected(self, loc):
|
||||
enabled = loc == 'library'
|
||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
from functools import partial
|
||||
|
||||
from PyQt4.Qt import QMenu, QToolButton
|
||||
from PyQt4.Qt import QToolButton
|
||||
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
|
||||
@ -17,9 +17,10 @@ class SimilarBooksAction(InterfaceAction):
|
||||
action_spec = (_('Similar books...'), None, None, None)
|
||||
popup_type = QToolButton.InstantPopup
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
|
||||
def genesis(self):
|
||||
m = QMenu(self.gui)
|
||||
m = self.qaction.menu()
|
||||
for text, icon, target, shortcut in [
|
||||
(_('Books by same author'), 'user_profile.png', 'authors', _('Alt+A')),
|
||||
(_('Books in this series'), 'books_in_series.png', 'series',
|
||||
@ -31,7 +32,6 @@ class SimilarBooksAction(InterfaceAction):
|
||||
m.addAction(ac)
|
||||
ac.triggered.connect(partial(self.show_similar_books, target))
|
||||
self.qaction.setMenu(m)
|
||||
self.similar_menu = m
|
||||
|
||||
def show_similar_books(self, type, *args):
|
||||
search, join = [], ' '
|
||||
|
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
from functools import partial
|
||||
|
||||
from PyQt4.Qt import QMenu, QIcon, QSize
|
||||
from PyQt4.Qt import QIcon, QSize
|
||||
|
||||
from calibre.gui2 import error_dialog
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
@ -17,16 +17,18 @@ from calibre.gui2.dialogs.confirm_delete import confirm
|
||||
class StoreAction(InterfaceAction):
|
||||
|
||||
name = 'Store'
|
||||
action_spec = (_('Get books'), 'store.png', None, None)
|
||||
action_spec = (_('Get books'), 'store.png', None, _('G'))
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = _('Search for ebooks')
|
||||
|
||||
def genesis(self):
|
||||
self.qaction.triggered.connect(self.do_search)
|
||||
self.store_menu = QMenu()
|
||||
self.store_menu = self.qaction.menu()
|
||||
self.load_menu()
|
||||
|
||||
def load_menu(self):
|
||||
self.store_menu.clear()
|
||||
self.store_menu.addAction(_('Search for ebooks'), self.search)
|
||||
self.store_menu.addAction(self.menuless_qaction)
|
||||
self.store_menu.addAction(_('Search for this author'), self.search_author)
|
||||
self.store_menu.addAction(_('Search for this title'), self.search_title)
|
||||
self.store_menu.addAction(_('Search for this book'), self.search_author_title)
|
||||
@ -41,7 +43,6 @@ class StoreAction(InterfaceAction):
|
||||
self.store_list_menu.addAction(n, partial(self.open_store, p))
|
||||
self.store_menu.addSeparator()
|
||||
self.store_menu.addAction(_('Choose stores'), self.choose)
|
||||
self.qaction.setMenu(self.store_menu)
|
||||
|
||||
def do_search(self):
|
||||
return self.search()
|
||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, time
|
||||
|
||||
from PyQt4.Qt import Qt, QMenu, QAction, pyqtSignal
|
||||
from PyQt4.Qt import Qt, QAction, pyqtSignal
|
||||
|
||||
from calibre.constants import isosx
|
||||
from calibre.gui2 import error_dialog, Dispatcher, question_dialog, config, \
|
||||
@ -35,20 +35,19 @@ class ViewAction(InterfaceAction):
|
||||
name = 'View'
|
||||
action_spec = (_('View'), 'view.png', None, _('V'))
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = True
|
||||
|
||||
def genesis(self):
|
||||
self.persistent_files = []
|
||||
self.qaction.triggered.connect(self.view_book)
|
||||
self.view_menu = QMenu()
|
||||
self.view_action = self.menuless_qaction
|
||||
self.view_menu = self.qaction.menu()
|
||||
ac = self.view_specific_action = QAction(_('View specific format'),
|
||||
self.gui)
|
||||
self.qaction.setMenu(self.view_menu)
|
||||
ac.setShortcut(Qt.AltModifier+Qt.Key_V)
|
||||
ac.triggered.connect(self.view_specific_format, type=Qt.QueuedConnection)
|
||||
ac = self.view_action = QAction(self.qaction.icon(),
|
||||
self.qaction.text(), self.gui)
|
||||
ac.triggered.connect(self.view_book)
|
||||
ac = self.create_action(spec=(_('Read a random book'), 'catalog.png',
|
||||
ac = self.create_action(spec=(_('Read a random book'), 'random.png',
|
||||
None, None), attr='action_pick_random')
|
||||
ac.triggered.connect(self.view_random)
|
||||
ac = self.clear_history_action = QAction(
|
||||
|
@ -527,6 +527,8 @@ Calibre has several keyboard shortcuts to save you time and mouse movement. Thes
|
||||
- Remove selected Books
|
||||
* - :kbd:`E`
|
||||
- Edit metadata of selected books
|
||||
* - :kbd:`G`
|
||||
- Get Books
|
||||
* - :kbd:`I`
|
||||
- Show book details
|
||||
* - :kbd:`M`
|
||||
|
Loading…
x
Reference in New Issue
Block a user