mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit book: Allow import of multiple files at once, via File->Import files into book
This commit is contained in:
parent
9c27428cf2
commit
ebd6f978ac
@ -34,7 +34,7 @@ from calibre.gui2.tweak_book.save import SaveManager, save_container
|
|||||||
from calibre.gui2.tweak_book.preview import parse_worker, font_cache
|
from calibre.gui2.tweak_book.preview import parse_worker, font_cache
|
||||||
from calibre.gui2.tweak_book.toc import TOCEditor
|
from calibre.gui2.tweak_book.toc import TOCEditor
|
||||||
from calibre.gui2.tweak_book.editor import editor_from_syntax, syntax_from_mime
|
from calibre.gui2.tweak_book.editor import editor_from_syntax, syntax_from_mime
|
||||||
from calibre.gui2.tweak_book.editor.insert_resource import get_resource_data, NewBook
|
from calibre.gui2.tweak_book.editor.insert_resource import get_resource_data, NewBook, ChooseFolder
|
||||||
from calibre.gui2.tweak_book.preferences import Preferences
|
from calibre.gui2.tweak_book.preferences import Preferences
|
||||||
|
|
||||||
def get_container(*args, **kwargs):
|
def get_container(*args, **kwargs):
|
||||||
@ -320,6 +320,37 @@ class Boss(QObject):
|
|||||||
else:
|
else:
|
||||||
self.edit_file(d.file_name, syntax)
|
self.edit_file(d.file_name, syntax)
|
||||||
|
|
||||||
|
def add_files(self):
|
||||||
|
if current_container() is None:
|
||||||
|
return error_dialog(self.gui, _('No open book'), _(
|
||||||
|
'You must first open a book to tweak, before trying to create new files'
|
||||||
|
' in it.'), show=True)
|
||||||
|
|
||||||
|
files = choose_files(self.gui, 'tweak-book-bulk-import-files', _('Choose files'))
|
||||||
|
if files:
|
||||||
|
d = ChooseFolder(parent=self.gui)
|
||||||
|
if d.exec_() == d.Accepted:
|
||||||
|
base = d.chosen_folder
|
||||||
|
files = {x:'/'.join((base, os.path.basename(x))) for x in files}
|
||||||
|
self.commit_dirty_opf()
|
||||||
|
self.add_savepoint(_('Add files'))
|
||||||
|
c = current_container()
|
||||||
|
for path, name in files.iteritems():
|
||||||
|
i = 0
|
||||||
|
while c.exists(name):
|
||||||
|
i += 1
|
||||||
|
name, ext = name.rpartition('.')[0::2]
|
||||||
|
name = '%s_%d.%s' % (name, i, ext)
|
||||||
|
try:
|
||||||
|
with open(path, 'rb') as f:
|
||||||
|
c.add_file(name, f.read())
|
||||||
|
except:
|
||||||
|
self.rewind_savepoint()
|
||||||
|
raise
|
||||||
|
self.gui.file_list.build(c)
|
||||||
|
if c.opf_name in editors:
|
||||||
|
editors[c.opf_name].replace_data(c.raw_data(c.opf_name))
|
||||||
|
|
||||||
def edit_toc(self):
|
def edit_toc(self):
|
||||||
self.commit_all_editors_to_container()
|
self.commit_all_editors_to_container()
|
||||||
self.add_savepoint(_('Edit Table of Contents'))
|
self.add_savepoint(_('Edit Table of Contents'))
|
||||||
|
@ -13,7 +13,8 @@ from PyQt4.Qt import (
|
|||||||
QDialog, QGridLayout, QDialogButtonBox, QSize, QListView, QStyledItemDelegate,
|
QDialog, QGridLayout, QDialogButtonBox, QSize, QListView, QStyledItemDelegate,
|
||||||
QLabel, QPixmap, QApplication, QSizePolicy, QAbstractListModel, QVariant,
|
QLabel, QPixmap, QApplication, QSizePolicy, QAbstractListModel, QVariant,
|
||||||
Qt, QRect, QPainter, QModelIndex, QSortFilterProxyModel, QLineEdit,
|
Qt, QRect, QPainter, QModelIndex, QSortFilterProxyModel, QLineEdit,
|
||||||
QToolButton, QIcon, QFormLayout, pyqtSignal)
|
QToolButton, QIcon, QFormLayout, pyqtSignal, QTreeWidget, QTreeWidgetItem,
|
||||||
|
QVBoxLayout)
|
||||||
|
|
||||||
from calibre import fit_image
|
from calibre import fit_image
|
||||||
from calibre.constants import plugins
|
from calibre.constants import plugins
|
||||||
@ -308,6 +309,67 @@ def get_resource_data(rtype, parent):
|
|||||||
if d.exec_() == d.Accepted:
|
if d.exec_() == d.Accepted:
|
||||||
return d.chosen_image, d.chosen_image_is_external
|
return d.chosen_image, d.chosen_image_is_external
|
||||||
|
|
||||||
|
def create_folder_tree(container):
|
||||||
|
root = {}
|
||||||
|
|
||||||
|
all_folders = {tuple(x.split('/')[:-1]) for x in container.name_path_map}
|
||||||
|
all_folders.discard(())
|
||||||
|
|
||||||
|
for folder_path in all_folders:
|
||||||
|
current = root
|
||||||
|
for x in folder_path:
|
||||||
|
current[x] = current = current.get(x, {})
|
||||||
|
return root
|
||||||
|
|
||||||
|
class ChooseFolder(Dialog): # {{{
|
||||||
|
|
||||||
|
def __init__(self, msg=None, parent=None):
|
||||||
|
self.msg = msg
|
||||||
|
Dialog.__init__(self, _('Choose folder'), 'choose-folder', parent=parent)
|
||||||
|
|
||||||
|
def setup_ui(self):
|
||||||
|
self.l = l = QVBoxLayout(self)
|
||||||
|
self.setLayout(l)
|
||||||
|
|
||||||
|
self.msg = m = QLabel(self.msg or _(
|
||||||
|
'Choose the folder into which the files will be placed'))
|
||||||
|
l.addWidget(m)
|
||||||
|
m.setWordWrap(True)
|
||||||
|
|
||||||
|
self.folders = f = QTreeWidget(self)
|
||||||
|
f.setHeaderHidden(True)
|
||||||
|
f.itemDoubleClicked.connect(self.accept)
|
||||||
|
l.addWidget(f)
|
||||||
|
self.root = QTreeWidgetItem(f, ('/',))
|
||||||
|
self.root.setExpanded(True)
|
||||||
|
|
||||||
|
def process(node, parent):
|
||||||
|
for child in sorted(node, key=sort_key):
|
||||||
|
c = QTreeWidgetItem(parent, (child,))
|
||||||
|
process(node[child], c)
|
||||||
|
if parent.childCount() == 1:
|
||||||
|
parent.child(0).setExpanded(True)
|
||||||
|
process(create_folder_tree(current_container()), self.root)
|
||||||
|
self.root.setSelected(True)
|
||||||
|
|
||||||
|
l.addWidget(self.bb)
|
||||||
|
|
||||||
|
def folder_path(self, item):
|
||||||
|
ans = []
|
||||||
|
while item is not self.root:
|
||||||
|
ans.append(unicode(item.text(0)))
|
||||||
|
item = item.parent()
|
||||||
|
return tuple(reversed(ans))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def chosen_folder(self):
|
||||||
|
try:
|
||||||
|
return '/'.join(self.folder_path(self.folders.selectedItems()[0]))
|
||||||
|
except IndexError:
|
||||||
|
return ''
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class NewBook(Dialog): # {{{
|
class NewBook(Dialog): # {{{
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -362,7 +424,7 @@ if __name__ == '__main__':
|
|||||||
from calibre.gui2.tweak_book.boss import get_container
|
from calibre.gui2.tweak_book.boss import get_container
|
||||||
set_current_container(get_container(sys.argv[-1]))
|
set_current_container(get_container(sys.argv[-1]))
|
||||||
|
|
||||||
d = InsertImage()
|
d = ChooseFolder()
|
||||||
if d.exec_() == d.Accepted:
|
if d.exec_() == d.Accepted:
|
||||||
print (d.chosen_image, d.chosen_image_is_external)
|
print (repr(d.chosen_folder))
|
||||||
|
|
||||||
|
@ -276,6 +276,7 @@ class Main(MainWindow):
|
|||||||
|
|
||||||
self.action_new_file = reg('document-new.png', _('&New file (images/fonts/HTML/etc.)'), self.boss.add_file,
|
self.action_new_file = reg('document-new.png', _('&New file (images/fonts/HTML/etc.)'), self.boss.add_file,
|
||||||
'new-file', (), _('Create a new file in the current book'))
|
'new-file', (), _('Create a new file in the current book'))
|
||||||
|
self.action_import_files = reg(None, _('&Import files into book'), self.boss.add_files, 'new-files', (), _('Import files into book'))
|
||||||
self.action_open_book = reg('document_open.png', _('Open &book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book'))
|
self.action_open_book = reg('document_open.png', _('Open &book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book'))
|
||||||
self.action_global_undo = reg('back.png', _('&Revert to before'), self.boss.do_global_undo, 'global-undo', 'Ctrl+Left',
|
self.action_global_undo = reg('back.png', _('&Revert to before'), self.boss.do_global_undo, 'global-undo', 'Ctrl+Left',
|
||||||
_('Revert book to before the last action (Undo)'))
|
_('Revert book to before the last action (Undo)'))
|
||||||
@ -400,6 +401,7 @@ class Main(MainWindow):
|
|||||||
|
|
||||||
f = b.addMenu(_('&File'))
|
f = b.addMenu(_('&File'))
|
||||||
f.addAction(self.action_new_file)
|
f.addAction(self.action_new_file)
|
||||||
|
f.addAction(self.action_import_files)
|
||||||
f.addAction(self.action_open_book)
|
f.addAction(self.action_open_book)
|
||||||
f.addAction(self.action_new_book)
|
f.addAction(self.action_new_book)
|
||||||
self.recent_books_menu = f.addMenu(_('&Recently opened books'))
|
self.recent_books_menu = f.addMenu(_('&Recently opened books'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user