Edit book: Allow import of multiple files at once, via File->Import files into book

This commit is contained in:
Kovid Goyal 2013-12-23 15:48:00 +05:30
parent 9c27428cf2
commit ebd6f978ac
3 changed files with 99 additions and 4 deletions

View File

@ -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.toc import TOCEditor
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
def get_container(*args, **kwargs):
@ -320,6 +320,37 @@ class Boss(QObject):
else:
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):
self.commit_all_editors_to_container()
self.add_savepoint(_('Edit Table of Contents'))

View File

@ -13,7 +13,8 @@ from PyQt4.Qt import (
QDialog, QGridLayout, QDialogButtonBox, QSize, QListView, QStyledItemDelegate,
QLabel, QPixmap, QApplication, QSizePolicy, QAbstractListModel, QVariant,
Qt, QRect, QPainter, QModelIndex, QSortFilterProxyModel, QLineEdit,
QToolButton, QIcon, QFormLayout, pyqtSignal)
QToolButton, QIcon, QFormLayout, pyqtSignal, QTreeWidget, QTreeWidgetItem,
QVBoxLayout)
from calibre import fit_image
from calibre.constants import plugins
@ -308,6 +309,67 @@ def get_resource_data(rtype, parent):
if d.exec_() == d.Accepted:
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): # {{{
def __init__(self, parent=None):
@ -362,7 +424,7 @@ if __name__ == '__main__':
from calibre.gui2.tweak_book.boss import get_container
set_current_container(get_container(sys.argv[-1]))
d = InsertImage()
d = ChooseFolder()
if d.exec_() == d.Accepted:
print (d.chosen_image, d.chosen_image_is_external)
print (repr(d.chosen_folder))

View File

@ -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,
'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_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)'))
@ -400,6 +401,7 @@ class Main(MainWindow):
f = b.addMenu(_('&File'))
f.addAction(self.action_new_file)
f.addAction(self.action_import_files)
f.addAction(self.action_open_book)
f.addAction(self.action_new_book)
self.recent_books_menu = f.addMenu(_('&Recently opened books'))