mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
When adding multiple books and duplicates are found, allow the user to select which of the duplicate books will be added. Fixes #1095256 (Wishlist item - select what duplicates to add in adding duplicates dialog)
This commit is contained in:
parent
d2abb0d3d4
commit
a0759cd45b
@ -8,10 +8,10 @@ from functools import partial
|
||||
from PyQt4.Qt import QThread, QObject, Qt, QProgressDialog, pyqtSignal, QTimer
|
||||
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
from calibre.gui2 import (question_dialog, error_dialog, info_dialog, gprefs,
|
||||
from calibre.gui2 import (error_dialog, info_dialog, gprefs,
|
||||
warning_dialog, available_width)
|
||||
from calibre.ebooks.metadata.opf2 import OPF
|
||||
from calibre.ebooks.metadata import MetaInformation, authors_to_string
|
||||
from calibre.ebooks.metadata import MetaInformation
|
||||
from calibre.constants import preferred_encoding, filesystem_encoding, DEBUG
|
||||
from calibre.utils.config import prefs
|
||||
from calibre import prints, force_unicode, as_unicode
|
||||
@ -391,25 +391,10 @@ class Adder(QObject): # {{{
|
||||
if not duplicates:
|
||||
return self.duplicates_processed()
|
||||
self.pd.hide()
|
||||
duplicate_message = []
|
||||
for x in duplicates:
|
||||
duplicate_message.append(_('Already in calibre:'))
|
||||
matching_books = self.db.books_with_same_title(x[0])
|
||||
for book_id in matching_books:
|
||||
aut = [a.replace('|', ',') for a in (self.db.authors(book_id,
|
||||
index_is_id=True) or '').split(',')]
|
||||
duplicate_message.append('\t'+ _('%(title)s by %(author)s')%
|
||||
dict(title=self.db.title(book_id, index_is_id=True),
|
||||
author=authors_to_string(aut)))
|
||||
duplicate_message.append(_('You are trying to add:'))
|
||||
duplicate_message.append('\t'+_('%(title)s by %(author)s')%
|
||||
dict(title=x[0].title,
|
||||
author=x[0].format_field('authors')[1]))
|
||||
duplicate_message.append('')
|
||||
if question_dialog(self._parent, _('Duplicates found!'),
|
||||
_('Books with the same title as the following already '
|
||||
'exist in calibre. Add them anyway?'),
|
||||
'\n'.join(duplicate_message)):
|
||||
from calibre.gui2.dialogs.duplicates import DuplicatesQuestion
|
||||
d = DuplicatesQuestion(self.db, duplicates, self._parent)
|
||||
duplicates = tuple(d.duplicates)
|
||||
if duplicates:
|
||||
pd = QProgressDialog(_('Adding duplicates...'), '', 0, len(duplicates),
|
||||
self._parent)
|
||||
pd.setCancelButton(None)
|
||||
|
118
src/calibre/gui2/dialogs/duplicates.py
Normal file
118
src/calibre/gui2/dialogs/duplicates.py
Normal file
@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from PyQt4.Qt import (QDialog, QGridLayout, QIcon, QLabel, QTreeWidget,
|
||||
QTreeWidgetItem, Qt, QFont, QDialogButtonBox)
|
||||
|
||||
from calibre.ebooks.metadata import authors_to_string
|
||||
|
||||
class DuplicatesQuestion(QDialog):
|
||||
|
||||
def __init__(self, db, duplicates, parent=None):
|
||||
QDialog.__init__(self, parent)
|
||||
self.l = l = QGridLayout()
|
||||
self.setLayout(l)
|
||||
self.setWindowTitle(_('Duplicates found!'))
|
||||
self.i = i = QIcon(I('dialog_question.png'))
|
||||
self.setWindowIcon(i)
|
||||
|
||||
self.l1 = l1 = QLabel()
|
||||
self.l2 = l2 = QLabel(_(
|
||||
'Books with the same titles as the following already '
|
||||
'exist in calibre. Select which books you want added anyway.'))
|
||||
l2.setWordWrap(True)
|
||||
l1.setPixmap(i.pixmap(128, 128))
|
||||
l.addWidget(l1, 0, 0)
|
||||
l.addWidget(l2, 0, 1)
|
||||
|
||||
self.dup_list = dl = QTreeWidget(self)
|
||||
l.addWidget(dl, 1, 0, 1, 2)
|
||||
dl.setHeaderHidden(True)
|
||||
dl.addTopLevelItems(list(self.process_duplicates(db, duplicates)))
|
||||
dl.expandAll()
|
||||
dl.setIndentation(30)
|
||||
|
||||
self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
|
||||
bb.accepted.connect(self.accept)
|
||||
bb.rejected.connect(self.reject)
|
||||
l.addWidget(bb, 2, 0, 1, 2)
|
||||
self.ab = ab = bb.addButton(_('Select &all'), bb.ActionRole)
|
||||
ab.clicked.connect(self.select_all)
|
||||
self.nb = ab = bb.addButton(_('Select &none'), bb.ActionRole)
|
||||
ab.clicked.connect(self.select_none)
|
||||
|
||||
self.resize(self.sizeHint())
|
||||
self.exec_()
|
||||
|
||||
def select_all(self):
|
||||
for i in xrange(self.dup_list.topLevelItemCount()):
|
||||
x = self.dup_list.topLevelItem(i)
|
||||
x.setCheckState(0, Qt.Checked)
|
||||
|
||||
def select_none(self):
|
||||
for i in xrange(self.dup_list.topLevelItemCount()):
|
||||
x = self.dup_list.topLevelItem(i)
|
||||
x.setCheckState(0, Qt.Unchecked)
|
||||
|
||||
def reject(self):
|
||||
self.select_none()
|
||||
QDialog.reject(self)
|
||||
|
||||
def process_duplicates(self, db, duplicates):
|
||||
ta = _('%(title)s by %(author)s')
|
||||
bf = QFont(self.dup_list.font())
|
||||
bf.setBold(True)
|
||||
itf = QFont(self.dup_list.font())
|
||||
itf.setItalic(True)
|
||||
|
||||
for mi, cover, formats in duplicates:
|
||||
item = QTreeWidgetItem([ta%dict(
|
||||
title=mi.title, author=mi.format_field('authors')[1])] , 0)
|
||||
item.setCheckState(0, Qt.Checked)
|
||||
item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable)
|
||||
item.setData(0, Qt.FontRole, bf)
|
||||
item.setData(0, Qt.UserRole, (mi, cover, formats))
|
||||
matching_books = db.books_with_same_title(mi)
|
||||
|
||||
def add_child(text):
|
||||
c = QTreeWidgetItem([text], 1)
|
||||
c.setFlags(Qt.ItemIsEnabled)
|
||||
item.addChild(c)
|
||||
return c
|
||||
|
||||
add_child(_('Already in calibre:')).setData(0, Qt.FontRole, itf)
|
||||
|
||||
for book_id in matching_books:
|
||||
aut = [a.replace('|', ',') for a in (db.authors(book_id,
|
||||
index_is_id=True) or '').split(',')]
|
||||
add_child(ta%dict(
|
||||
title=db.title(book_id, index_is_id=True),
|
||||
author=authors_to_string(aut)))
|
||||
add_child('')
|
||||
|
||||
yield item
|
||||
|
||||
@property
|
||||
def duplicates(self):
|
||||
for i in xrange(self.dup_list.topLevelItemCount()):
|
||||
x = self.dup_list.topLevelItem(i)
|
||||
if x.checkState(0) == Qt.Checked:
|
||||
yield x.data(0, Qt.UserRole).toPyObject()
|
||||
|
||||
if __name__ == '__main__':
|
||||
from PyQt4.Qt import QApplication
|
||||
from calibre.ebooks.metadata.book.base import Metadata as M
|
||||
from calibre.library import db
|
||||
|
||||
app = QApplication([])
|
||||
db = db()
|
||||
d = DuplicatesQuestion(db, [(M('Life of Pi', ['Yann Martel']), None, None),
|
||||
(M('Heirs of the blade', ['Adrian Tchaikovsky']), None, None)])
|
||||
print (tuple(d.duplicates))
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user