mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Enhancement #1884402: Check Library: add delete checkboxes to deletable error categories to select all books in that category.
This commit is contained in:
parent
9ba6848530
commit
2da65972b7
@ -80,6 +80,9 @@ class Item(QTreeWidgetItem):
|
|||||||
|
|
||||||
class CheckLibraryDialog(QDialog):
|
class CheckLibraryDialog(QDialog):
|
||||||
|
|
||||||
|
is_deletable = 1
|
||||||
|
is_fixable = 2
|
||||||
|
|
||||||
def __init__(self, parent, db):
|
def __init__(self, parent, db):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
self.db = db
|
self.db = db
|
||||||
@ -251,33 +254,44 @@ class CheckLibraryDialog(QDialog):
|
|||||||
|
|
||||||
def builder(tree, checker, check):
|
def builder(tree, checker, check):
|
||||||
attr, h, checkable, fixable = check
|
attr, h, checkable, fixable = check
|
||||||
list = getattr(checker, attr, None)
|
list_ = getattr(checker, attr, None)
|
||||||
if list is None:
|
if list_ is None:
|
||||||
self.problem_count[attr] = 0
|
self.problem_count[attr] = 0
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.problem_count[attr] = len(list)
|
self.problem_count[attr] = len(list_)
|
||||||
|
|
||||||
tl = Item()
|
tl = Item()
|
||||||
tl.setText(0, h)
|
tl.setText(0, h)
|
||||||
if fixable and list:
|
if fixable and list:
|
||||||
|
tl.setData(1, Qt.UserRole, self.is_fixable)
|
||||||
tl.setText(1, _('(fixable)'))
|
tl.setText(1, _('(fixable)'))
|
||||||
tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
||||||
tl.setCheckState(1, False)
|
tl.setCheckState(1, False)
|
||||||
else:
|
else:
|
||||||
tl.setFlags(Qt.ItemIsEnabled)
|
tl.setData(1, Qt.UserRole, self.is_deletable)
|
||||||
|
tl.setData(2, Qt.UserRole, self.is_deletable)
|
||||||
|
tl.setText(1, _('(deletable)'))
|
||||||
|
tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
||||||
|
tl.setCheckState(1, False)
|
||||||
|
if attr == 'extra_covers':
|
||||||
|
tl.setData(2, Qt.UserRole, self.is_deletable)
|
||||||
|
tl.setText(2, _('(deletable)'))
|
||||||
|
tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
||||||
|
tl.setCheckState(2, False)
|
||||||
self.top_level_items[attr] = tl
|
self.top_level_items[attr] = tl
|
||||||
|
|
||||||
for problem in list:
|
for problem in list_:
|
||||||
it = Item()
|
it = Item()
|
||||||
if checkable:
|
if checkable:
|
||||||
it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
||||||
it.setCheckState(1, False)
|
it.setCheckState(2, False)
|
||||||
|
it.setData(2, Qt.UserRole, self.is_deletable)
|
||||||
else:
|
else:
|
||||||
it.setFlags(Qt.ItemIsEnabled)
|
it.setFlags(Qt.ItemIsEnabled)
|
||||||
it.setText(0, problem[0])
|
it.setText(0, problem[0])
|
||||||
it.setData(0, Qt.UserRole, problem[2])
|
it.setData(0, Qt.UserRole, problem[2])
|
||||||
it.setText(1, problem[1])
|
it.setText(2, problem[1])
|
||||||
tl.addChild(it)
|
tl.addChild(it)
|
||||||
self.all_items.append(it)
|
self.all_items.append(it)
|
||||||
plaintext.append(','.join([h, problem[0], problem[1]]))
|
plaintext.append(','.join([h, problem[0], problem[1]]))
|
||||||
@ -285,8 +299,8 @@ class CheckLibraryDialog(QDialog):
|
|||||||
|
|
||||||
t = self.log
|
t = self.log
|
||||||
t.clear()
|
t.clear()
|
||||||
t.setColumnCount(2)
|
t.setColumnCount(3)
|
||||||
t.setHeaderLabels([_('Name'), _('Path from library')])
|
t.setHeaderLabels([_('Name'), '', _('Path from library')])
|
||||||
self.all_items = []
|
self.all_items = []
|
||||||
self.top_level_items = {}
|
self.top_level_items = {}
|
||||||
self.problem_count = {}
|
self.problem_count = {}
|
||||||
@ -304,26 +318,83 @@ class CheckLibraryDialog(QDialog):
|
|||||||
self.log.resizeColumnToContents(1)
|
self.log.resizeColumnToContents(1)
|
||||||
|
|
||||||
def item_changed(self, item, column):
|
def item_changed(self, item, column):
|
||||||
self.fix_button.setEnabled(False)
|
def set_delete_boxes(node, col, to_what):
|
||||||
for it in self.top_level_items.values():
|
self.log.blockSignals(True)
|
||||||
if it.checkState(1):
|
if col:
|
||||||
self.fix_button.setEnabled(True)
|
node.setCheckState(col, to_what)
|
||||||
|
for i in range(0, node.childCount()):
|
||||||
|
node.child(i).setCheckState(2, to_what)
|
||||||
|
self.log.blockSignals(False)
|
||||||
|
|
||||||
self.delete_button.setEnabled(False)
|
def is_child_delete_checked(node):
|
||||||
for it in self.all_items:
|
checked = False
|
||||||
if it.checkState(1):
|
all_checked = True
|
||||||
self.delete_button.setEnabled(True)
|
for i in range(0, node.childCount()):
|
||||||
return
|
c = node.child(i).checkState(2)
|
||||||
|
checked = checked or c == Qt.Checked
|
||||||
|
all_checked = all_checked and c == Qt.Checked
|
||||||
|
return (checked, all_checked)
|
||||||
|
|
||||||
|
def any_child_delete_checked():
|
||||||
|
for parent in self.top_level_items.values():
|
||||||
|
(c, _) = is_child_delete_checked(parent)
|
||||||
|
if c:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def any_fix_checked():
|
||||||
|
for parent in self.top_level_items.values():
|
||||||
|
if (parent.data(1, Qt.UserRole) == self.is_fixable and
|
||||||
|
parent.checkState(1) == Qt.Checked):
|
||||||
|
return True;
|
||||||
|
return False
|
||||||
|
|
||||||
|
if item in self.top_level_items.values():
|
||||||
|
if item.childCount() > 0:
|
||||||
|
if item.data(1, Qt.UserRole) == self.is_fixable and column == 1:
|
||||||
|
if item.data(2, Qt.UserRole) == self.is_deletable:
|
||||||
|
set_delete_boxes(item, 2, False)
|
||||||
|
else:
|
||||||
|
set_delete_boxes(item, column, item.checkState(column))
|
||||||
|
if column == 2:
|
||||||
|
self.log.blockSignals(True)
|
||||||
|
item.setCheckState(1, False)
|
||||||
|
self.log.blockSignals(False)
|
||||||
|
else:
|
||||||
|
item.setCheckState(column, Qt.Unchecked)
|
||||||
|
else:
|
||||||
|
for parent in self.top_level_items.values():
|
||||||
|
if parent.data(2, Qt.UserRole) == self.is_deletable:
|
||||||
|
(child_chkd, all_chkd) = is_child_delete_checked(parent)
|
||||||
|
if all_chkd and child_chkd:
|
||||||
|
check_state = Qt.Checked
|
||||||
|
elif child_chkd:
|
||||||
|
check_state = Qt.PartiallyChecked
|
||||||
|
else:
|
||||||
|
check_state = Qt.Unchecked
|
||||||
|
self.log.blockSignals(True)
|
||||||
|
if parent.data(1, Qt.UserRole) == self.is_fixable:
|
||||||
|
parent.setCheckState(2, check_state)
|
||||||
|
else:
|
||||||
|
parent.setCheckState(1, check_state)
|
||||||
|
if child_chkd and parent.data(1, Qt.UserRole) == self.is_fixable:
|
||||||
|
parent.setCheckState(1, Qt.Unchecked)
|
||||||
|
self.log.blockSignals(False)
|
||||||
|
self.delete_button.setEnabled(any_child_delete_checked())
|
||||||
|
self.fix_button.setEnabled(any_fix_checked())
|
||||||
|
|
||||||
def mark_for_fix(self):
|
def mark_for_fix(self):
|
||||||
for it in self.top_level_items.values():
|
for it in self.top_level_items.values():
|
||||||
if it.flags() & Qt.ItemIsUserCheckable:
|
if (it.flags() & Qt.ItemIsUserCheckable and
|
||||||
|
it.data(1, Qt.UserRole) == self.is_fixable and
|
||||||
|
it.childCount() > 0):
|
||||||
it.setCheckState(1, Qt.Checked)
|
it.setCheckState(1, Qt.Checked)
|
||||||
|
|
||||||
def mark_for_delete(self):
|
def mark_for_delete(self):
|
||||||
for it in self.all_items:
|
for it in self.all_items:
|
||||||
if it.flags() & Qt.ItemIsUserCheckable:
|
if (it.flags() & Qt.ItemIsUserCheckable and
|
||||||
it.setCheckState(1, Qt.Checked)
|
it.data(2, Qt.UserRole) == self.is_deletable):
|
||||||
|
it.setCheckState(2, Qt.Checked)
|
||||||
|
|
||||||
def delete_marked(self):
|
def delete_marked(self):
|
||||||
if not confirm('<p>'+_('The marked files and folders will be '
|
if not confirm('<p>'+_('The marked files and folders will be '
|
||||||
@ -336,9 +407,9 @@ class CheckLibraryDialog(QDialog):
|
|||||||
key=lambda x: len(x.text(1)),
|
key=lambda x: len(x.text(1)),
|
||||||
reverse=True)
|
reverse=True)
|
||||||
for it in items:
|
for it in items:
|
||||||
if it.checkState(1):
|
if it.checkState(2) == Qt.Checked:
|
||||||
try:
|
try:
|
||||||
p = os.path.join(self.db.library_path, unicode_type(it.text(1)))
|
p = os.path.join(self.db.library_path, unicode_type(it.text(2)))
|
||||||
if os.path.isdir(p):
|
if os.path.isdir(p):
|
||||||
delete_tree(p)
|
delete_tree(p)
|
||||||
else:
|
else:
|
||||||
@ -346,7 +417,7 @@ class CheckLibraryDialog(QDialog):
|
|||||||
except:
|
except:
|
||||||
prints('failed to delete',
|
prints('failed to delete',
|
||||||
os.path.join(self.db.library_path,
|
os.path.join(self.db.library_path,
|
||||||
unicode_type(it.text(1))))
|
unicode_type(it.text(2))))
|
||||||
self.run_the_check()
|
self.run_the_check()
|
||||||
|
|
||||||
def fix_missing_formats(self):
|
def fix_missing_formats(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user