Enhancement #1884402: Check Library: add delete checkboxes to deletable error categories to select all books in that category.

This commit is contained in:
Charles Haley 2020-06-21 14:45:36 +01:00
parent 9ba6848530
commit 2da65972b7

View File

@ -80,6 +80,9 @@ class Item(QTreeWidgetItem):
class CheckLibraryDialog(QDialog):
is_deletable = 1
is_fixable = 2
def __init__(self, parent, db):
QDialog.__init__(self, parent)
self.db = db
@ -251,33 +254,44 @@ class CheckLibraryDialog(QDialog):
def builder(tree, checker, check):
attr, h, checkable, fixable = check
list = getattr(checker, attr, None)
if list is None:
list_ = getattr(checker, attr, None)
if list_ is None:
self.problem_count[attr] = 0
return
else:
self.problem_count[attr] = len(list)
self.problem_count[attr] = len(list_)
tl = Item()
tl.setText(0, h)
if fixable and list:
tl.setData(1, Qt.UserRole, self.is_fixable)
tl.setText(1, _('(fixable)'))
tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
tl.setCheckState(1, False)
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
for problem in list:
for problem in list_:
it = Item()
if checkable:
it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
it.setCheckState(1, False)
it.setCheckState(2, False)
it.setData(2, Qt.UserRole, self.is_deletable)
else:
it.setFlags(Qt.ItemIsEnabled)
it.setText(0, problem[0])
it.setData(0, Qt.UserRole, problem[2])
it.setText(1, problem[1])
it.setText(2, problem[1])
tl.addChild(it)
self.all_items.append(it)
plaintext.append(','.join([h, problem[0], problem[1]]))
@ -285,8 +299,8 @@ class CheckLibraryDialog(QDialog):
t = self.log
t.clear()
t.setColumnCount(2)
t.setHeaderLabels([_('Name'), _('Path from library')])
t.setColumnCount(3)
t.setHeaderLabels([_('Name'), '', _('Path from library')])
self.all_items = []
self.top_level_items = {}
self.problem_count = {}
@ -304,26 +318,83 @@ class CheckLibraryDialog(QDialog):
self.log.resizeColumnToContents(1)
def item_changed(self, item, column):
self.fix_button.setEnabled(False)
for it in self.top_level_items.values():
if it.checkState(1):
self.fix_button.setEnabled(True)
def set_delete_boxes(node, col, to_what):
self.log.blockSignals(True)
if col:
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)
for it in self.all_items:
if it.checkState(1):
self.delete_button.setEnabled(True)
return
def is_child_delete_checked(node):
checked = False
all_checked = True
for i in range(0, node.childCount()):
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):
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)
def mark_for_delete(self):
for it in self.all_items:
if it.flags() & Qt.ItemIsUserCheckable:
it.setCheckState(1, Qt.Checked)
if (it.flags() & Qt.ItemIsUserCheckable and
it.data(2, Qt.UserRole) == self.is_deletable):
it.setCheckState(2, Qt.Checked)
def delete_marked(self):
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)),
reverse=True)
for it in items:
if it.checkState(1):
if it.checkState(2) == Qt.Checked:
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):
delete_tree(p)
else:
@ -346,7 +417,7 @@ class CheckLibraryDialog(QDialog):
except:
prints('failed to delete',
os.path.join(self.db.library_path,
unicode_type(it.text(1))))
unicode_type(it.text(2))))
self.run_the_check()
def fix_missing_formats(self):