From b4c15a0e5546b4ba34cd26ed806077904724514a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 30 Sep 2023 14:28:36 +0530 Subject: [PATCH] Edit book: When saving a copy add some convenience actions to edit the copy immediately iether in the current editor window or a new window --- src/calibre/gui2/actions/tweak_epub.py | 3 +-- src/calibre/gui2/tweak_book/boss.py | 34 +++++++++++++++++++++----- src/calibre/gui2/tweak_book/ui.py | 9 ++++++- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/actions/tweak_epub.py b/src/calibre/gui2/actions/tweak_epub.py index 05d2cc943c..03cd65e523 100644 --- a/src/calibre/gui2/actions/tweak_epub.py +++ b/src/calibre/gui2/actions/tweak_epub.py @@ -153,13 +153,12 @@ class TweakEpubAction(InterfaceAction): return error_dialog(self.gui, _('File missing'), _( 'The %s format is missing from the calibre library. You should run' ' library maintenance.') % fmt, show=True) - tweak = 'ebook-edit' try: self.gui.setCursor(Qt.CursorShape.BusyCursor) if tprefs['update_metadata_from_calibre']: db.new_api.embed_metadata((book_id,), only_fmts={fmt}) notify = '%d:%s:%s:%s' % (book_id, fmt, db.library_id, db.library_path) - self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(path=path, notify=notify)) + self.gui.job_manager.launch_gui_app('ebook-edit', kwargs=dict(path=path, notify=notify)) time.sleep(2) finally: self.gui.unsetCursor() diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index bef6d0b2d8..ed7484a847 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -4,6 +4,7 @@ import errno import os import shutil +import subprocess import sys import tempfile from functools import partial, wraps @@ -14,7 +15,7 @@ from qt.core import ( ) from calibre import isbytestring, prints -from calibre.constants import cache_dir, iswindows +from calibre.constants import cache_dir, islinux, ismacos, iswindows from calibre.ebooks.oeb.base import urlnormalize from calibre.ebooks.oeb.polish.container import ( OEB_DOCS, OEB_STYLES, clone_container, get_container as _gc, guess_type, @@ -35,7 +36,7 @@ from calibre.ebooks.oeb.polish.utils import ( ) from calibre.gui2 import ( add_to_recent_docs, choose_dir, choose_files, choose_save_file, error_dialog, - info_dialog, open_url, question_dialog, warning_dialog, + info_dialog, open_url, question_dialog, sanitize_env_vars, warning_dialog, ) from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.tweak_book import ( @@ -65,6 +66,7 @@ from calibre.startup import connect_lambda from calibre.utils.config import JSONConfig from calibre.utils.icu import numeric_sort_key from calibre.utils.imghdr import identify +from calibre.utils.ipc.launch import exe_path, macos_edit_book_bundle_path from calibre.utils.localization import ngettext from calibre.utils.tdir_in_cache import tdir_in_cache from polyglot.builtins import as_bytes, iteritems, itervalues, string_or_bytes @@ -1312,7 +1314,7 @@ class Boss(QObject): container = clone_container(c, tdir) self.save_manager.schedule(tdir, container) - def save_copy(self): + def _save_copy(self, post_action=None): self.gui.update_window_title() c = current_container() if c.is_dir: @@ -1338,14 +1340,34 @@ class Boss(QObject): shutil.rmtree(tdir, ignore_errors=True) return path - self.gui.blocking_job('save_copy', _('Saving copy, please wait...'), self.copy_saved, do_save, container, path, tdir) + self.gui.blocking_job('save_copy', _('Saving copy, please wait...'), partial(self.copy_saved, post_action=post_action), do_save, container, path, tdir) - def copy_saved(self, job): + def save_copy(self): + self._save_copy() + + def copy_saved(self, job, post_action=None): if job.traceback is not None: return error_dialog(self.gui, _('Failed to save copy'), _('Failed to save copy, click "Show details" for more information.'), det_msg=job.traceback, show=True) msg = _('Copy saved to %s') % job.result - info_dialog(self.gui, _('Copy saved'), msg, show=True) + if post_action is None: + info_dialog(self.gui, _('Copy saved'), msg, show=True) + elif post_action == 'replace': + msg = _('Editing saved copy at: %s') % job.result + self.open_book(job.result, edit_file=self.currently_editing) + elif post_action == 'edit': + if ismacos: + cmd = ['open', '-F', '-n', '-a', os.path.dirname(os.path.dirname(os.path.dirname(macos_edit_book_bundle_path()))), '--args'] + else: + cmd = [exe_path('ebook-edit')] + if islinux: + cmd.append('--detach') + cmd.append(job.result) + ce = self.currently_editing + if ce: + cmd.append(ce) + with sanitize_env_vars(): + subprocess.Popen(cmd) self.gui.show_status_message(msg, 5) def report_save_error(self, tb): diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index dc1157a3d2..9723e8a9fe 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -380,6 +380,10 @@ class Main(MainWindow): self.action_save = treg('save.png', _('&Save'), self.boss.save_book, 'save-book', 'Ctrl+S', _('Save book')) self.action_save.setEnabled(False) self.action_save_copy = treg('save.png', _('Save a ©'), self.boss.save_copy, 'save-copy', 'Ctrl+Alt+S', _('Save a copy of the book')) + self.action_save_copy_edit = treg('save.png', _('Save a © and edit in new window'), partial(self.boss._save_copy, 'edit'), 'save-copy-edit', + 'Ctrl+Shift+S', _( 'Save a copy of the book and edit it in a new window')) + self.action_save_copy_replace = treg('save.png', _('Save a © and edit here'), partial(self.boss._save_copy, 'replace'), + 'save-copy-replace', 'Ctrl+Alt+Shift+S', _('Save a copy of the book and edit it in this window')) self.action_quit = treg('window-close.png', _('&Quit'), self.boss.quit, 'quit', 'Ctrl+Q', _('Quit')) self.action_preferences = treg('config.png', _('&Preferences'), self.boss.preferences, 'preferences', 'Ctrl+P', _('Preferences')) self.action_new_book = treg('plus.png', _('Create new, &empty book'), self.boss.new_book, 'new-book', (), _('Create a new, empty book')) @@ -572,7 +576,10 @@ class Main(MainWindow): self.update_recent_books() f.addSeparator() f.addAction(self.action_save) - f.addAction(self.action_save_copy) + m = f.addMenu(_('Save a copy')) + m.addAction(self.action_save_copy) + m.addAction(self.action_save_copy_edit) + m.addAction(self.action_save_copy_replace) f.addSeparator() f.addAction(self.action_compare_book) f.addAction(self.action_quit)