mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Edit Book: Allow editing an unzipped EPUB (a folder) as a book
Useful if you wish to store your ebook in a version control system and edit it directly with the calibre ebook editor
This commit is contained in:
parent
f8670c524c
commit
c8ad7b203a
@ -27,7 +27,7 @@ from calibre.ebooks.oeb.polish.replace import rename_files, replace_file, get_re
|
||||
from calibre.ebooks.oeb.polish.split import split, merge, AbortError, multisplit
|
||||
from calibre.ebooks.oeb.polish.toc import remove_names_from_toc, find_existing_toc, create_inline_toc
|
||||
from calibre.ebooks.oeb.polish.utils import link_stylesheets, setup_cssutils_serialization as scs
|
||||
from calibre.gui2 import error_dialog, choose_files, question_dialog, info_dialog, choose_save_file, open_url
|
||||
from calibre.gui2 import error_dialog, choose_files, question_dialog, info_dialog, choose_save_file, open_url, choose_dir
|
||||
from calibre.gui2.dialogs.confirm_delete import confirm
|
||||
from calibre.gui2.tweak_book import (
|
||||
set_current_container, current_container, tprefs, actions, editors,
|
||||
@ -243,7 +243,7 @@ class Boss(QObject):
|
||||
return get_container(dest, tdir=tdir)
|
||||
self.gui.blocking_job('import_book', _('Importing book, please wait...'), self.book_opened, func, src, dest, tdir=self.mkdtemp())
|
||||
|
||||
def open_book(self, path=None, edit_file=None, clear_notify_data=True):
|
||||
def open_book(self, path=None, edit_file=None, clear_notify_data=True, open_folder=False):
|
||||
'''
|
||||
Open the ebook at ``path`` for editing. Will show an error if the ebook is not in a supported format or the current book has unsaved changes.
|
||||
|
||||
@ -256,14 +256,24 @@ class Boss(QObject):
|
||||
if not self._check_before_open():
|
||||
return
|
||||
if not hasattr(path, 'rpartition'):
|
||||
if open_folder:
|
||||
path = choose_dir(self.gui, 'open-book-folder-for-tweaking', _('Choose book folder'))
|
||||
if path:
|
||||
path = [path]
|
||||
else:
|
||||
path = choose_files(self.gui, 'open-book-for-tweaking', _('Choose book'),
|
||||
[(_('Books'), [x.lower() for x in SUPPORTED])], all_files=False, select_only_single_file=True)
|
||||
|
||||
if not path:
|
||||
return
|
||||
path = path[0]
|
||||
|
||||
if not os.path.exists(path):
|
||||
return error_dialog(self.gui, _('File not found'), _(
|
||||
'The file %s does not exist.') % path, show=True)
|
||||
isdir = os.path.isdir(path)
|
||||
ext = path.rpartition('.')[-1].upper()
|
||||
if ext not in SUPPORTED:
|
||||
if ext not in SUPPORTED and not isdir:
|
||||
from calibre.ebooks.oeb.polish.import_book import IMPORTABLE
|
||||
if ext.lower() in IMPORTABLE:
|
||||
return self.import_book(path)
|
||||
@ -271,9 +281,6 @@ class Boss(QObject):
|
||||
_('Tweaking is only supported for books in the %s formats.'
|
||||
' Convert your book to one of these formats first.') % _(' and ').join(sorted(SUPPORTED)),
|
||||
show=True)
|
||||
if not os.path.exists(path):
|
||||
return error_dialog(self.gui, _('File not found'), _(
|
||||
'The file %s does not exist.') % path, show=True)
|
||||
|
||||
for name in tuple(editors):
|
||||
self.close_editor(name)
|
||||
@ -972,7 +979,7 @@ class Boss(QObject):
|
||||
ed.is_modified = False
|
||||
path_to_ebook = os.path.abspath(c.path_to_ebook)
|
||||
destdir = os.path.dirname(path_to_ebook)
|
||||
if not os.path.exists(destdir):
|
||||
if not c.is_dir and not os.path.exists(destdir):
|
||||
info_dialog(self.gui, _('Path does not exist'), _(
|
||||
'The file you are editing (%s) no longer exists. You have to choose a new save location.') % path_to_ebook,
|
||||
show_copy_button=False, show=True)
|
||||
@ -996,6 +1003,9 @@ class Boss(QObject):
|
||||
|
||||
def save_copy(self):
|
||||
c = current_container()
|
||||
if c.is_dir:
|
||||
return error_dialog(self.gui, _('Cannot save a copy'), _(
|
||||
'Saving a copy of a folder based book is not supported'), show=True)
|
||||
ext = c.path_to_ebook.rpartition('.')[-1]
|
||||
path = choose_save_file(self.gui, 'tweak_book_save_copy', _(
|
||||
'Choose path'), filters=[(_('Book (%s)') % ext.upper(), [ext.lower()])], all_files=False)
|
||||
|
@ -19,7 +19,16 @@ from calibre.utils import join_with_timeout
|
||||
from calibre.utils.filenames import atomic_rename, format_permissions
|
||||
from calibre.utils.ipc import RC
|
||||
|
||||
def save_dir_container(container, path):
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
if not os.path.isdir(path):
|
||||
raise ValueError('%s is not a folder, cannot save a directory based container to it' % path)
|
||||
container.commit(path)
|
||||
|
||||
def save_container(container, path):
|
||||
if container.is_dir:
|
||||
return save_dir_container(container, path)
|
||||
temp = PersistentTemporaryFile(
|
||||
prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
|
||||
if hasattr(os, 'fchmod'):
|
||||
|
@ -327,6 +327,8 @@ class Main(MainWindow):
|
||||
'new-file', (), _('Create a new file in the current book'))
|
||||
self.action_import_files = treg('document-import.png', _('&Import files into book'), self.boss.add_files, 'new-files', (), _('Import files into book'))
|
||||
self.action_open_book = treg('document_open.png', _('Open &book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book'))
|
||||
self.action_open_book_folder = treg('mimetypes/dir.png', _('Open &folder (unzipped EPUB) as book'), partial(self.boss.open_book, open_folder=True),
|
||||
'open-folder-as-book', (), _('Open a folder (unzipped EPUB) as a book'))
|
||||
# Qt does not generate shortcut overrides for cmd+arrow on os x which
|
||||
# means these shortcuts interfere with editing
|
||||
self.action_global_undo = treg('back.png', _('&Revert to before'), self.boss.do_global_undo, 'global-undo', () if isosx else 'Ctrl+Left',
|
||||
@ -503,6 +505,7 @@ class Main(MainWindow):
|
||||
f.addAction(self.action_open_book)
|
||||
f.addAction(self.action_new_book)
|
||||
f.addAction(self.action_import_book)
|
||||
f.addAction(self.action_open_book_folder)
|
||||
self.recent_books_menu = f.addMenu(_('&Recently opened books'))
|
||||
self.update_recent_books()
|
||||
f.addSeparator()
|
||||
|
Loading…
x
Reference in New Issue
Block a user