mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Book details: When dropping files add an option to add them to the book as data files. Fixes #2072442 [[Enhancement] New option when dropping file onto Book Details](https://bugs.launchpad.net/calibre/+bug/2072442)
This commit is contained in:
parent
decbb7edd2
commit
be0dc294a2
@ -145,6 +145,14 @@ class AddAction(InterfaceAction):
|
|||||||
if books:
|
if books:
|
||||||
self._add_formats(books, ids)
|
self._add_formats(books, ids)
|
||||||
|
|
||||||
|
def _add_extra_files(self, book_ids, paths):
|
||||||
|
rmap = {'data/' + os.path.basename(x): x for x in paths}
|
||||||
|
db = self.gui.current_db.new_api
|
||||||
|
for book_id in book_ids:
|
||||||
|
db.add_extra_files(book_id, rmap)
|
||||||
|
self.gui.library_view.model().refresh_ids(book_ids,
|
||||||
|
current_row=self.gui.library_view.currentIndex().row())
|
||||||
|
|
||||||
def add_extra_files(self):
|
def add_extra_files(self):
|
||||||
ids = self._check_add_formats_ok()
|
ids = self._check_add_formats_ok()
|
||||||
if not ids:
|
if not ids:
|
||||||
@ -152,12 +160,7 @@ class AddAction(InterfaceAction):
|
|||||||
books = choose_files_and_remember_all_files(self.gui, 'add extra data files dialog dir',
|
books = choose_files_and_remember_all_files(self.gui, 'add extra data files dialog dir',
|
||||||
_('Select extra data files'), filters=get_filters())
|
_('Select extra data files'), filters=get_filters())
|
||||||
if books:
|
if books:
|
||||||
rmap = {'data/' + os.path.basename(x): x for x in books}
|
self._add_extra_files(ids, books)
|
||||||
db = self.gui.current_db.new_api
|
|
||||||
for book_id in ids:
|
|
||||||
db.add_extra_files(book_id, rmap)
|
|
||||||
self.gui.library_view.model().refresh_ids(ids,
|
|
||||||
current_row=self.gui.library_view.currentIndex().row())
|
|
||||||
|
|
||||||
def _add_formats(self, paths, ids):
|
def _add_formats(self, paths, ids):
|
||||||
if len(ids) > 1 and not question_dialog(
|
if len(ids) > 1 and not question_dialog(
|
||||||
@ -507,16 +510,24 @@ class AddAction(InterfaceAction):
|
|||||||
accept = True
|
accept = True
|
||||||
if accept and event is not None:
|
if accept and event is not None:
|
||||||
event.accept()
|
event.accept()
|
||||||
add_as_book = False
|
add_as_book = add_as_data_files = False
|
||||||
if do_confirm and formats:
|
if do_confirm and formats:
|
||||||
ok, add_as_book = confirm(
|
ok, add_as = confirm(
|
||||||
_('You have dropped some files onto the book <b>%s</b>. This will'
|
_('You have dropped some files onto the book <b>%s</b>. This will'
|
||||||
' add or replace the files for this book. Do you want to proceed?') % db.title(cid, index_is_id=True),
|
' add or replace the files for this book. Do you want to proceed?') % db.title(cid, index_is_id=True),
|
||||||
'confirm_drop_on_book', parent=self.gui,
|
'confirm_drop_on_book', parent=self.gui,
|
||||||
extra_button=ngettext('Add as new book', 'Add as new books', len(formats)))
|
extra_button=_('Add as...'), extra_button_choices={
|
||||||
if ok and add_as_book:
|
'book': ngettext('Add as new book', 'Add as new books', len(formats)),
|
||||||
add_as_book = [path for ext, path in formats]
|
'data_files': ngettext('Add as data file', 'Add as data files', len(formats)),
|
||||||
if not ok or add_as_book:
|
})
|
||||||
|
if ok:
|
||||||
|
if add_as == 'book':
|
||||||
|
add_as_book = [path for ext, path in formats]
|
||||||
|
formats = []
|
||||||
|
elif add_as == 'data_files':
|
||||||
|
add_as_data_files = [path for ext, path in formats]
|
||||||
|
formats = []
|
||||||
|
else:
|
||||||
formats = []
|
formats = []
|
||||||
for ext, path in formats:
|
for ext, path in formats:
|
||||||
db.add_format_with_hooks(cid, ext, path, index_is_id=True)
|
db.add_format_with_hooks(cid, ext, path, index_is_id=True)
|
||||||
@ -526,6 +537,8 @@ class AddAction(InterfaceAction):
|
|||||||
self.gui.refresh_cover_browser()
|
self.gui.refresh_cover_browser()
|
||||||
if add_as_book:
|
if add_as_book:
|
||||||
self.files_dropped(add_as_book)
|
self.files_dropped(add_as_book)
|
||||||
|
if add_as_data_files:
|
||||||
|
self._add_extra_files({cid}, add_as_data_files)
|
||||||
|
|
||||||
def __add_filesystem_book(self, paths, allow_device=True):
|
def __add_filesystem_book(self, paths, allow_device=True):
|
||||||
if isinstance(paths, string_or_bytes):
|
if isinstance(paths, string_or_bytes):
|
||||||
|
@ -5,7 +5,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
from qt.core import QCheckBox, QDialog, QDialogButtonBox, QHBoxLayout, QIcon, QLabel, Qt, QVBoxLayout
|
from qt.core import QCheckBox, QDialog, QDialogButtonBox, QHBoxLayout, QIcon, QLabel, QMenu, Qt, QVBoxLayout
|
||||||
|
|
||||||
from calibre import confirm_config_name
|
from calibre import confirm_config_name
|
||||||
from calibre.gui2 import dynamic
|
from calibre.gui2 import dynamic
|
||||||
@ -14,8 +14,11 @@ from calibre.gui2.dialogs.message_box import Icon
|
|||||||
|
|
||||||
class Dialog(QDialog):
|
class Dialog(QDialog):
|
||||||
|
|
||||||
def __init__(self, msg, name, parent, config_set=dynamic, icon='dialog_warning.png',
|
def __init__(
|
||||||
title=None, confirm_msg=None, show_cancel_button=True, extra_button=None):
|
self, msg, name, parent, config_set=dynamic, icon='dialog_warning.png',
|
||||||
|
title=None, confirm_msg=None, show_cancel_button=True, extra_button=None,
|
||||||
|
extra_button_choices=None
|
||||||
|
):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
self.setWindowTitle(title or _("Are you sure?"))
|
self.setWindowTitle(title or _("Are you sure?"))
|
||||||
self.setWindowIcon(QIcon.ic(icon))
|
self.setWindowIcon(QIcon.ic(icon))
|
||||||
@ -50,9 +53,18 @@ class Dialog(QDialog):
|
|||||||
bb.setFocus(Qt.FocusReason.OtherFocusReason)
|
bb.setFocus(Qt.FocusReason.OtherFocusReason)
|
||||||
bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
|
bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
|
||||||
self.extra_button_clicked = False
|
self.extra_button_clicked = False
|
||||||
|
self.extra_button_choice = None
|
||||||
if extra_button:
|
if extra_button:
|
||||||
b = bb.addButton(extra_button, QDialogButtonBox.ButtonRole.AcceptRole)
|
b = bb.addButton(extra_button, QDialogButtonBox.ButtonRole.AcceptRole)
|
||||||
b.clicked.connect(self.on_extra_button_click)
|
if extra_button_choices:
|
||||||
|
m = QMenu()
|
||||||
|
b.setMenu(m)
|
||||||
|
for acname, text in extra_button_choices.items():
|
||||||
|
ac = m.addAction(text)
|
||||||
|
ac.setObjectName(acname)
|
||||||
|
ac.triggered.connect(self.on_extra_choice_click)
|
||||||
|
else:
|
||||||
|
b.clicked.connect(self.on_extra_button_click)
|
||||||
l.addWidget(bb)
|
l.addWidget(bb)
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -64,20 +76,32 @@ class Dialog(QDialog):
|
|||||||
def on_extra_button_click(self):
|
def on_extra_button_click(self):
|
||||||
self.extra_button_clicked = True
|
self.extra_button_clicked = True
|
||||||
|
|
||||||
|
def on_extra_choice_click(self):
|
||||||
|
ac = self.sender()
|
||||||
|
self.extra_button_choice = ac.objectName()
|
||||||
|
self.accept()
|
||||||
|
|
||||||
def toggle(self, *args):
|
def toggle(self, *args):
|
||||||
self.config_set[confirm_config_name(self.name)] = self.again.isChecked()
|
self.config_set[confirm_config_name(self.name)] = self.again.isChecked()
|
||||||
|
|
||||||
|
|
||||||
def confirm(msg, name, parent=None, pixmap='dialog_warning.png', title=None,
|
def confirm(
|
||||||
show_cancel_button=True, confirm_msg=None, config_set=None, extra_button=None):
|
msg, name, parent=None, pixmap='dialog_warning.png', title=None,
|
||||||
|
show_cancel_button=True, confirm_msg=None, config_set=None, extra_button=None, extra_button_choices=None
|
||||||
|
):
|
||||||
config_set = config_set or dynamic
|
config_set = config_set or dynamic
|
||||||
if not config_set.get(confirm_config_name(name), True):
|
if not config_set.get(confirm_config_name(name), True):
|
||||||
if extra_button:
|
if extra_button:
|
||||||
|
if extra_button_choices:
|
||||||
|
return True, None
|
||||||
return True, False
|
return True, False
|
||||||
return True
|
return True
|
||||||
d = Dialog(msg, name, parent, config_set=config_set, icon=pixmap, extra_button=extra_button,
|
d = Dialog(msg, name, parent, config_set=config_set, icon=pixmap, extra_button=extra_button,
|
||||||
title=title, confirm_msg=confirm_msg, show_cancel_button=show_cancel_button)
|
title=title, confirm_msg=confirm_msg, show_cancel_button=show_cancel_button, extra_button_choices=extra_button_choices)
|
||||||
ret = d.exec() == QDialog.DialogCode.Accepted
|
ret = d.exec() == QDialog.DialogCode.Accepted
|
||||||
if extra_button:
|
if extra_button:
|
||||||
ret = ret, d.extra_button_clicked
|
if extra_button_choices:
|
||||||
|
ret = ret, d.extra_button_choice
|
||||||
|
else:
|
||||||
|
ret = ret, d.extra_button_clicked
|
||||||
return ret
|
return ret
|
||||||
|
Loading…
x
Reference in New Issue
Block a user