diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py index 437706d653..9e63829e29 100644 --- a/src/calibre/gui2/actions/edit_metadata.py +++ b/src/calibre/gui2/actions/edit_metadata.py @@ -408,6 +408,7 @@ class EditMetadataAction(InterfaceAction): ''' Merge selected books in library. ''' + from calibre.gui2.dialogs.confirm_merge import confirm_merge if self.gui.stack.currentIndex() != 0: return rows = self.gui.library_view.selectionModel().selectedRows() @@ -425,20 +426,21 @@ class EditMetadataAction(InterfaceAction): return dest_id, src_ids = self.books_to_merge(rows) - title = self.gui.library_view.model().db.title(dest_id, index_is_id=True) + mi = self.gui.current_db.new_api.get_proxy_metadata(dest_id) + title = mi.title if safe_merge: - if not confirm('

'+_( + if not confirm_merge('

'+_( 'Book formats and metadata from the selected books ' 'will be added to the first selected book (%s).
' 'The second and subsequently selected books will not ' 'be deleted or changed.

' 'Please confirm you want to proceed.')%title + - '

', 'merge_books_safe', self.gui): + '

', 'merge_books_safe', self.gui, mi): return self.add_formats(dest_id, self.formats_for_books(rows)) self.merge_metadata(dest_id, src_ids) elif merge_only_formats: - if not confirm('

'+_( + if not confirm_merge('

'+_( 'Book formats from the selected books will be merged ' 'into the first selected book (%s). ' 'Metadata in the first selected book will not be changed. ' @@ -449,12 +451,12 @@ class EditMetadataAction(InterfaceAction): 'and any duplicate formats in the second and subsequently selected books ' 'will be permanently deleted from your calibre library.

' 'Are you sure you want to proceed?')%title + - '

', 'merge_only_formats', self.gui): + '

', 'merge_only_formats', self.gui, mi): return self.add_formats(dest_id, self.formats_for_books(rows)) self.delete_books_after_merge(src_ids) else: - if not confirm('

'+_( + if not confirm_merge('

'+_( 'Book formats and metadata from the selected books will be merged ' 'into the first selected book (%s).

' 'After merger the second and ' @@ -463,7 +465,7 @@ class EditMetadataAction(InterfaceAction): 'and any duplicate formats in the second and subsequently selected books ' 'will be permanently deleted from your calibre library.

' 'Are you sure you want to proceed?')%title + - '

', 'merge_books', self.gui): + '

', 'merge_books', self.gui, mi): return self.add_formats(dest_id, self.formats_for_books(rows)) self.merge_metadata(dest_id, src_ids) diff --git a/src/calibre/gui2/dialogs/confirm_merge.py b/src/calibre/gui2/dialogs/confirm_merge.py new file mode 100644 index 0000000000..ad2957c468 --- /dev/null +++ b/src/calibre/gui2/dialogs/confirm_merge.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python2 +# vim:fileencoding=utf-8 +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2015, Kovid Goyal ' + +from PyQt5.Qt import ( + QVBoxLayout, QSplitter, QWidget, QLabel, QCheckBox, QTextBrowser +) + +from calibre.ebooks.metadata import authors_to_string +from calibre.ebooks.metadata.book.base import field_metadata +from calibre.gui2 import dynamic +from calibre.gui2.widgets2 import Dialog +from calibre.gui2.dialogs.confirm_delete import confirm_config_name +from calibre.utils.config import tweaks +from calibre.utils.date import format_date + +class ConfirmMerge(Dialog): + + def __init__(self, msg, name, parent, mi): + self.msg, self.mi, self.conf_name = msg, mi, name + Dialog.__init__(self, _('Are you sure?'), 'confirm-merge-dialog', parent) + + def setup_ui(self): + self.l = l = QVBoxLayout(self) + self.splitter = s = QSplitter(self) + s.setChildrenCollapsible(False) + l.addWidget(s), l.addWidget(self.bb) + self.bb.setStandardButtons(self.bb.Yes | self.bb.No) + + self.left = w = QWidget(self) + s.addWidget(w) + w.l = l = QVBoxLayout(w) + l.setContentsMargins(0, 0, 0, 0) + self.la = la = QLabel(self.msg) + la.setWordWrap(True) + l.addWidget(la) + self.confirm = c = QCheckBox(_('Show this confirmation again'), self) + c.setChecked(True) + c.stateChanged.connect(self.toggle) + l.addWidget(c) + + self.right = r = QTextBrowser(self) + series = '' + mi, fm = self.mi, field_metadata + if mi.series: + series = _('{num} of {series}').format(num=mi.format_series_index(), series='%s' % mi.series) + r.setHtml(''' +

{mb}

+

{title} - {authors}

+ + + + + +
{fm[timestamp][name]}:{date}
{fm[pubdate][name]}:{published}
{fm[formats][name]}:{formats}
{fm[series][name]}:{series}
+ '''.format( + mb=_('Target book'), + title=mi.title, + authors=authors_to_string(mi.authors), + date=format_date(mi.timestamp, tweaks['gui_timestamp_display_format']), fm=fm, + published=(format_date(mi.pubdate, tweaks['gui_pubdate_display_format']) if mi.pubdate else ''), + formats=', '.join(mi.formats or ()), + series=series + )) + s.addWidget(r) + + def toggle(self): + dynamic[confirm_config_name(self.conf_name)] = self.confirm.isChecked() + + def sizeHint(self): + ans = Dialog.sizeHint(self) + ans.setWidth(max(700, ans.width())) + return ans + + +def confirm_merge(msg, name, parent, mi): + config_set = dynamic + if not config_set.get(confirm_config_name(name), True): + return True + d = ConfirmMerge(msg, name, parent, mi) + return d.exec_() == d.Accepted