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.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'))
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user