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): 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):