diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index d64f36adc9..22730ba53f 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -609,6 +609,10 @@ class ActionFetchNews(InterfaceActionBase): name = 'Fetch News' actual_plugin = 'calibre.gui2.actions.fetch_news:FetchNewsAction' +class ActionSaveToDisk(InterfaceActionBase): + name = 'Save To Disk' + actual_plugin = 'calibre.gui2.actions.save_to_disk:SaveToDiskAction' + plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog, ActionConvert, ActionDelete, ActionEditMetadata, ActionView, - ActionFetchNews] + ActionFetchNews, ActionSaveToDisk] diff --git a/src/calibre/gui2/actions/save_to_disk.py b/src/calibre/gui2/actions/save_to_disk.py index 39df0948d2..4cfcc4d692 100644 --- a/src/calibre/gui2/actions/save_to_disk.py +++ b/src/calibre/gui2/actions/save_to_disk.py @@ -6,13 +6,65 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' import os +from functools import partial + +from PyQt4.Qt import QMenu, pyqtSignal from calibre.utils.config import prefs from calibre.gui2 import error_dialog, Dispatcher, \ choose_dir, warning_dialog, open_local_file +from calibre.gui2.actions import InterfaceAction +from calibre.ebooks import BOOK_EXTENSIONS + +class SaveMenu(QMenu): # {{{ + + save_fmt = pyqtSignal(object) + + def __init__(self, parent): + QMenu.__init__(self, _('Save single format to disk...'), parent) + for ext in sorted(BOOK_EXTENSIONS): + action = self.addAction(ext.upper()) + setattr(self, 'do_'+ext, partial(self.do, ext)) + action.triggered.connect( + getattr(self, 'do_'+ext)) + + def do(self, ext, *args): + self.save_fmt.emit(ext) + +# }}} -class SaveToDiskAction(object): +class SaveToDiskAction(InterfaceAction): + + name = "Save To Disk" + action_spec = (_('Save to disk'), 'save.svg', None, _('S')) + + 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.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')% + prefs['output_format'].upper(), + partial(self.save_single_format_to_disk, False)) + self.save_menu.addAction( + _('Save only %s format to disk in a single directory')% + prefs['output_format'].upper(), + partial(self.save_single_fmt_to_single_dir, False)) + 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 reread_prefs(self): + self.save_menu.actions()[2].setText( + _('Save only %s format to disk')% + prefs['output_format'].upper()) + self.save_menu.actions()[3].setText( + _('Save only %s format to disk in a single directory')% + prefs['output_format'].upper()) def save_single_format_to_disk(self, checked): self.save_to_disk(checked, False, prefs['output_format']) @@ -32,7 +84,7 @@ class SaveToDiskAction(object): if not rows or len(rows) == 0: return error_dialog(self.gui, _('Cannot save to disk'), _('No books selected'), show=True) - path = choose_dir(self, 'save to disk dialog', + path = choose_dir(self.gui, 'save to disk dialog', _('Choose destination directory')) if not path: return @@ -61,13 +113,13 @@ class SaveToDiskAction(object): opts.template = opts.template.split('/')[-1].strip() if not opts.template: opts.template = '{title} - {authors}' - self._saver = Saver(self, self.gui.library_view.model().db, + self._saver = Saver(self.gui, self.gui.library_view.model().db, Dispatcher(self._books_saved), rows, path, opts, - spare_server=self.spare_server) + spare_server=self.gui.spare_server) else: paths = self.gui.current_view().model().paths(rows) - self.device_manager.save_books( + self.gui.device_manager.save_books( Dispatcher(self.books_saved), paths, path) @@ -90,6 +142,6 @@ class SaveToDiskAction(object): def books_saved(self, job): if job.failed: - return self.device_job_exception(job) + return self.gui.device_job_exception(job) diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py index c5ed84ff00..fcd3be398b 100644 --- a/src/calibre/gui2/layout.py +++ b/src/calibre/gui2/layout.py @@ -19,28 +19,10 @@ from calibre.gui2.throbber import ThrobbingButton from calibre.gui2 import config, open_url, gprefs from calibre.gui2.widgets import ComboBoxWithHelp from calibre import human_readable -from calibre.utils.config import prefs -from calibre.ebooks import BOOK_EXTENSIONS from calibre.gui2.dialogs.scheduler import Scheduler from calibre.utils.smtp import config as email_config -class SaveMenu(QMenu): # {{{ - - save_fmt = pyqtSignal(object) - - def __init__(self, parent): - QMenu.__init__(self, _('Save single format to disk...'), parent) - for ext in sorted(BOOK_EXTENSIONS): - action = self.addAction(ext.upper()) - setattr(self, 'do_'+ext, partial(self.do, ext)) - action.triggered.connect( - getattr(self, 'do_'+ext)) - - def do(self, ext, *args): - self.save_fmt.emit(ext) - -# }}} class LocationManager(QObject): # {{{ @@ -463,9 +445,7 @@ class MainWindowMixin(object): ac(-1, 4, 0, 'sync', _('Send to device'), 'sync.svg') ac(5, 5, 3, 'choose_library', _('%d books')%0, 'lt.png', tooltip=_('Choose calibre library to work with')) - ac(7, 7, 0, 'save', _('Save to disk'), 'save.svg', _('S')) ac(8, 8, 0, 'conn_share', _('Connect/share'), 'connect_share.svg') - ac(9, 9, 3, 'del', _('Remove books'), 'trash.svg', _('Del')) ac(10, 10, 3, 'help', _('Help'), 'help.svg', _('F1'), _("Browse the calibre User Manual")) ac(11, 11, 0, 'preferences', _('Preferences'), 'config.svg', _('Ctrl+P')) @@ -490,23 +470,6 @@ class MainWindowMixin(object): self.action_help.triggered.connect(self.show_help) - self.action_save.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.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')% - prefs['output_format'].upper(), - partial(self.save_single_format_to_disk, False)) - self.save_menu.addAction( - _('Save only %s format to disk in a single directory')% - prefs['output_format'].upper(), - partial(self.save_single_fmt_to_single_dir, False)) - self.save_sub_menu = SaveMenu(self) - self.save_menu.addMenu(self.save_sub_menu) - self.save_sub_menu.save_fmt.connect(self.save_specific_format_disk) - self.action_open_containing_folder.setShortcut(Qt.Key_O) self.addAction(self.action_open_containing_folder) @@ -517,7 +480,6 @@ class MainWindowMixin(object): self.action_sync.triggered.connect( self._sync_action_triggered) - self.action_save.setMenu(self.save_menu) pm = QMenu() diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 2ba2a4ec52..581d02f9ab 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -387,13 +387,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{ if d.result() == d.Accepted: self.read_toolbar_settings() self.search.search_as_you_type(config['search_as_you_type']) - self.save_menu.actions()[2].setText( - _('Save only %s format to disk')% - prefs['output_format'].upper()) - self.save_menu.actions()[3].setText( - _('Save only %s format to disk in a single directory')% - prefs['output_format'].upper()) self.tags_view.set_new_model() # in case columns changed + self.iactions['Save To Disk'].reread_prefs() self.tags_view.recount() self.create_device_menu() self.set_device_menu_items_state(bool(self.device_connected))