mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
Remove flake8 E731 Errors
Note: black formatting is now applying correctly as well.
This commit is contained in:
parent
af19660c18
commit
9446f37fad
@ -17,7 +17,11 @@ from hscommon.util import flatten, multi_replace
|
|||||||
from hscommon.trans import tr
|
from hscommon.trans import tr
|
||||||
from hscommon.jobprogress import job
|
from hscommon.jobprogress import job
|
||||||
|
|
||||||
(WEIGHT_WORDS, MATCH_SIMILAR_WORDS, NO_FIELD_ORDER,) = range(3)
|
(
|
||||||
|
WEIGHT_WORDS,
|
||||||
|
MATCH_SIMILAR_WORDS,
|
||||||
|
NO_FIELD_ORDER,
|
||||||
|
) = range(3)
|
||||||
|
|
||||||
JOB_REFRESH_RATE = 100
|
JOB_REFRESH_RATE = 100
|
||||||
|
|
||||||
@ -34,11 +38,9 @@ def getwords(s):
|
|||||||
# of their accents, etc.) are preserved as is. The arbitrary limit is
|
# of their accents, etc.) are preserved as is. The arbitrary limit is
|
||||||
# obtained from this one: ord("\u037e") GREEK QUESTION MARK
|
# obtained from this one: ord("\u037e") GREEK QUESTION MARK
|
||||||
s = "".join(
|
s = "".join(
|
||||||
c for c in s
|
c
|
||||||
if (ord(c) <= 894
|
for c in s
|
||||||
and c in string.ascii_letters + string.digits + string.whitespace
|
if (ord(c) <= 894 and c in string.ascii_letters + string.digits + string.whitespace) or ord(c) > 894
|
||||||
)
|
|
||||||
or ord(c) > 894
|
|
||||||
)
|
)
|
||||||
return [_f for _f in s.split(" ") if _f] # remove empty elements
|
return [_f for _f in s.split(" ") if _f] # remove empty elements
|
||||||
|
|
||||||
@ -115,9 +117,7 @@ def compare_fields(first, second, flags=()):
|
|||||||
if matched_field:
|
if matched_field:
|
||||||
second.remove(matched_field)
|
second.remove(matched_field)
|
||||||
else:
|
else:
|
||||||
results = [
|
results = [compare(field1, field2, flags) for field1, field2 in zip(first, second)]
|
||||||
compare(field1, field2, flags) for field1, field2 in zip(first, second)
|
|
||||||
]
|
|
||||||
return min(results) if results else 0
|
return min(results) if results else 0
|
||||||
|
|
||||||
|
|
||||||
@ -130,9 +130,7 @@ def build_word_dict(objects, j=job.nulljob):
|
|||||||
The result will be a dict with words as keys, lists of objects as values.
|
The result will be a dict with words as keys, lists of objects as values.
|
||||||
"""
|
"""
|
||||||
result = defaultdict(set)
|
result = defaultdict(set)
|
||||||
for object in j.iter_with_progress(
|
for object in j.iter_with_progress(objects, "Prepared %d/%d files", JOB_REFRESH_RATE):
|
||||||
objects, "Prepared %d/%d files", JOB_REFRESH_RATE
|
|
||||||
):
|
|
||||||
for word in unpack_fields(object.words):
|
for word in unpack_fields(object.words):
|
||||||
result[word].add(object)
|
result[word].add(object)
|
||||||
return result
|
return result
|
||||||
@ -167,9 +165,7 @@ def reduce_common_words(word_dict, threshold):
|
|||||||
The exception to this removal are the objects where all the words of the object are common.
|
The exception to this removal are the objects where all the words of the object are common.
|
||||||
Because if we remove them, we will miss some duplicates!
|
Because if we remove them, we will miss some duplicates!
|
||||||
"""
|
"""
|
||||||
uncommon_words = set(
|
uncommon_words = set(word for word, objects in word_dict.items() if len(objects) < threshold)
|
||||||
word for word, objects in word_dict.items() if len(objects) < threshold
|
|
||||||
)
|
|
||||||
for word, objects in list(word_dict.items()):
|
for word, objects in list(word_dict.items()):
|
||||||
if len(objects) < threshold:
|
if len(objects) < threshold:
|
||||||
continue
|
continue
|
||||||
@ -275,10 +271,7 @@ def getmatches(
|
|||||||
# This is the place where the memory usage is at its peak during the scan.
|
# This is the place where the memory usage is at its peak during the scan.
|
||||||
# Just continue the process with an incomplete list of matches.
|
# Just continue the process with an incomplete list of matches.
|
||||||
del compared # This should give us enough room to call logging.
|
del compared # This should give us enough room to call logging.
|
||||||
logging.warning(
|
logging.warning("Memory Overflow. Matches: %d. Word dict: %d" % (len(result), len(word_dict)))
|
||||||
"Memory Overflow. Matches: %d. Word dict: %d"
|
|
||||||
% (len(result), len(word_dict))
|
|
||||||
)
|
|
||||||
return result
|
return result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -408,18 +401,13 @@ class Group:
|
|||||||
|
|
||||||
You can call this after the duplicate scanning process to free a bit of memory.
|
You can call this after the duplicate scanning process to free a bit of memory.
|
||||||
"""
|
"""
|
||||||
discarded = set(
|
discarded = set(m for m in self.matches if not all(obj in self.unordered for obj in [m.first, m.second]))
|
||||||
m
|
|
||||||
for m in self.matches
|
|
||||||
if not all(obj in self.unordered for obj in [m.first, m.second])
|
|
||||||
)
|
|
||||||
self.matches -= discarded
|
self.matches -= discarded
|
||||||
self.candidates = defaultdict(set)
|
self.candidates = defaultdict(set)
|
||||||
return discarded
|
return discarded
|
||||||
|
|
||||||
def get_match_of(self, item):
|
def get_match_of(self, item):
|
||||||
"""Returns the match pair between ``item`` and :attr:`ref`.
|
"""Returns the match pair between ``item`` and :attr:`ref`."""
|
||||||
"""
|
|
||||||
if item is self.ref:
|
if item is self.ref:
|
||||||
return
|
return
|
||||||
for m in self._get_matches_for_ref():
|
for m in self._get_matches_for_ref():
|
||||||
@ -435,8 +423,7 @@ class Group:
|
|||||||
"""
|
"""
|
||||||
# tie_breaker(ref, dupe) --> True if dupe should be ref
|
# tie_breaker(ref, dupe) --> True if dupe should be ref
|
||||||
# Returns True if anything changed during prioritization.
|
# Returns True if anything changed during prioritization.
|
||||||
master_key_func = lambda x: (-x.is_ref, key_func(x))
|
new_order = sorted(self.ordered, key=lambda x: (-x.is_ref, key_func(x)))
|
||||||
new_order = sorted(self.ordered, key=master_key_func)
|
|
||||||
changed = new_order != self.ordered
|
changed = new_order != self.ordered
|
||||||
self.ordered = new_order
|
self.ordered = new_order
|
||||||
if tie_breaker is None:
|
if tie_breaker is None:
|
||||||
@ -459,9 +446,7 @@ class Group:
|
|||||||
self.unordered.remove(item)
|
self.unordered.remove(item)
|
||||||
self._percentage = None
|
self._percentage = None
|
||||||
self._matches_for_ref = None
|
self._matches_for_ref = None
|
||||||
if (len(self) > 1) and any(
|
if (len(self) > 1) and any(not getattr(item, "is_ref", False) for item in self):
|
||||||
not getattr(item, "is_ref", False) for item in self
|
|
||||||
):
|
|
||||||
if discard_matches:
|
if discard_matches:
|
||||||
self.matches = set(m for m in self.matches if item not in m)
|
self.matches = set(m for m in self.matches if item not in m)
|
||||||
else:
|
else:
|
||||||
@ -470,8 +455,7 @@ class Group:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def switch_ref(self, with_dupe):
|
def switch_ref(self, with_dupe):
|
||||||
"""Make the :attr:`ref` dupe of the group switch position with ``with_dupe``.
|
"""Make the :attr:`ref` dupe of the group switch position with ``with_dupe``."""
|
||||||
"""
|
|
||||||
if self.ref.is_ref:
|
if self.ref.is_ref:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
@ -490,9 +474,7 @@ class Group:
|
|||||||
if self._percentage is None:
|
if self._percentage is None:
|
||||||
if self.dupes:
|
if self.dupes:
|
||||||
matches = self._get_matches_for_ref()
|
matches = self._get_matches_for_ref()
|
||||||
self._percentage = sum(match.percentage for match in matches) // len(
|
self._percentage = sum(match.percentage for match in matches) // len(matches)
|
||||||
matches
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self._percentage = 0
|
self._percentage = 0
|
||||||
return self._percentage
|
return self._percentage
|
||||||
@ -547,12 +529,8 @@ def get_groups(matches):
|
|||||||
orphan_matches = []
|
orphan_matches = []
|
||||||
for group in groups:
|
for group in groups:
|
||||||
orphan_matches += {
|
orphan_matches += {
|
||||||
m
|
m for m in group.discard_matches() if not any(obj in matched_files for obj in [m.first, m.second])
|
||||||
for m in group.discard_matches()
|
|
||||||
if not any(obj in matched_files for obj in [m.first, m.second])
|
|
||||||
}
|
}
|
||||||
if groups and orphan_matches:
|
if groups and orphan_matches:
|
||||||
groups += get_groups(
|
groups += get_groups(orphan_matches) # no job, as it isn't supposed to take a long time
|
||||||
orphan_matches
|
|
||||||
) # no job, as it isn't supposed to take a long time
|
|
||||||
return groups
|
return groups
|
||||||
|
@ -106,9 +106,7 @@ class Results(Markable):
|
|||||||
self.groups,
|
self.groups,
|
||||||
)
|
)
|
||||||
if self.__filtered_dupes:
|
if self.__filtered_dupes:
|
||||||
self.__dupes = [
|
self.__dupes = [dupe for dupe in self.__dupes if dupe in self.__filtered_dupes]
|
||||||
dupe for dupe in self.__dupes if dupe in self.__filtered_dupes
|
|
||||||
]
|
|
||||||
sd = self.__dupes_sort_descriptor
|
sd = self.__dupes_sort_descriptor
|
||||||
if sd:
|
if sd:
|
||||||
self.sort_dupes(sd[0], sd[1], sd[2])
|
self.sort_dupes(sd[0], sd[1], sd[2])
|
||||||
@ -127,18 +125,10 @@ class Results(Markable):
|
|||||||
total_count = self.__total_count
|
total_count = self.__total_count
|
||||||
total_size = self.__total_size
|
total_size = self.__total_size
|
||||||
else:
|
else:
|
||||||
mark_count = len(
|
mark_count = len([dupe for dupe in self.__filtered_dupes if self.is_marked(dupe)])
|
||||||
[dupe for dupe in self.__filtered_dupes if self.is_marked(dupe)]
|
marked_size = sum(dupe.size for dupe in self.__filtered_dupes if self.is_marked(dupe))
|
||||||
)
|
total_count = len([dupe for dupe in self.__filtered_dupes if self.is_markable(dupe)])
|
||||||
marked_size = sum(
|
total_size = sum(dupe.size for dupe in self.__filtered_dupes if self.is_markable(dupe))
|
||||||
dupe.size for dupe in self.__filtered_dupes if self.is_marked(dupe)
|
|
||||||
)
|
|
||||||
total_count = len(
|
|
||||||
[dupe for dupe in self.__filtered_dupes if self.is_markable(dupe)]
|
|
||||||
)
|
|
||||||
total_size = sum(
|
|
||||||
dupe.size for dupe in self.__filtered_dupes if self.is_markable(dupe)
|
|
||||||
)
|
|
||||||
if self.mark_inverted:
|
if self.mark_inverted:
|
||||||
marked_size = self.__total_size - marked_size
|
marked_size = self.__total_size - marked_size
|
||||||
result = tr("%d / %d (%s / %s) duplicates marked.") % (
|
result = tr("%d / %d (%s / %s) duplicates marked.") % (
|
||||||
@ -201,11 +191,7 @@ class Results(Markable):
|
|||||||
self.__filters.append(filter_str)
|
self.__filters.append(filter_str)
|
||||||
if self.__filtered_dupes is None:
|
if self.__filtered_dupes is None:
|
||||||
self.__filtered_dupes = flatten(g[:] for g in self.groups)
|
self.__filtered_dupes = flatten(g[:] for g in self.groups)
|
||||||
self.__filtered_dupes = set(
|
self.__filtered_dupes = set(dupe for dupe in self.__filtered_dupes if filter_re.search(str(dupe.path)))
|
||||||
dupe
|
|
||||||
for dupe in self.__filtered_dupes
|
|
||||||
if filter_re.search(str(dupe.path))
|
|
||||||
)
|
|
||||||
filtered_groups = set()
|
filtered_groups = set()
|
||||||
for dupe in self.__filtered_dupes:
|
for dupe in self.__filtered_dupes:
|
||||||
filtered_groups.add(self.get_group_of_duplicate(dupe))
|
filtered_groups.add(self.get_group_of_duplicate(dupe))
|
||||||
@ -217,8 +203,7 @@ class Results(Markable):
|
|||||||
self.__dupes = None
|
self.__dupes = None
|
||||||
|
|
||||||
def get_group_of_duplicate(self, dupe):
|
def get_group_of_duplicate(self, dupe):
|
||||||
"""Returns :class:`~core.engine.Group` in which ``dupe`` belongs.
|
"""Returns :class:`~core.engine.Group` in which ``dupe`` belongs."""
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
return self.__group_of_duplicate[dupe]
|
return self.__group_of_duplicate[dupe]
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
@ -284,8 +269,7 @@ class Results(Markable):
|
|||||||
self.is_modified = False
|
self.is_modified = False
|
||||||
|
|
||||||
def make_ref(self, dupe):
|
def make_ref(self, dupe):
|
||||||
"""Make ``dupe`` take the :attr:`~core.engine.Group.ref` position of its group.
|
"""Make ``dupe`` take the :attr:`~core.engine.Group.ref` position of its group."""
|
||||||
"""
|
|
||||||
g = self.get_group_of_duplicate(dupe)
|
g = self.get_group_of_duplicate(dupe)
|
||||||
r = g.ref
|
r = g.ref
|
||||||
if not g.switch_ref(dupe):
|
if not g.switch_ref(dupe):
|
||||||
@ -412,10 +396,10 @@ class Results(Markable):
|
|||||||
"""
|
"""
|
||||||
if not self.__dupes:
|
if not self.__dupes:
|
||||||
self.__get_dupe_list()
|
self.__get_dupe_list()
|
||||||
keyfunc = lambda d: self.app._get_dupe_sort_key(
|
self.__dupes.sort(
|
||||||
d, lambda: self.get_group_of_duplicate(d), key, delta
|
key=lambda d: self.app._get_dupe_sort_key(d, lambda: self.get_group_of_duplicate(d), key, delta),
|
||||||
|
reverse=not asc,
|
||||||
)
|
)
|
||||||
self.__dupes.sort(key=keyfunc, reverse=not asc)
|
|
||||||
self.__dupes_sort_descriptor = (key, asc, delta)
|
self.__dupes_sort_descriptor = (key, asc, delta)
|
||||||
|
|
||||||
def sort_groups(self, key, asc=True):
|
def sort_groups(self, key, asc=True):
|
||||||
@ -426,8 +410,7 @@ class Results(Markable):
|
|||||||
:param str key: key attribute name to sort with.
|
:param str key: key attribute name to sort with.
|
||||||
:param bool asc: If false, sorting is reversed.
|
:param bool asc: If false, sorting is reversed.
|
||||||
"""
|
"""
|
||||||
keyfunc = lambda g: self.app._get_group_sort_key(g, key)
|
self.groups.sort(key=lambda g: self.app._get_group_sort_key(g, key), reverse=not asc)
|
||||||
self.groups.sort(key=keyfunc, reverse=not asc)
|
|
||||||
self.__groups_sort_descriptor = (key, asc)
|
self.__groups_sort_descriptor = (key, asc)
|
||||||
|
|
||||||
# ---Properties
|
# ---Properties
|
||||||
|
@ -177,9 +177,7 @@ class TestCaseWordCompareWithFields:
|
|||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
eq_(
|
eq_(
|
||||||
67,
|
67,
|
||||||
compare_fields(
|
compare_fields([["a", "b"], ["c", "d", "e"]], [["a", "b"], ["c", "d", "f"]]),
|
||||||
[["a", "b"], ["c", "d", "e"]], [["a", "b"], ["c", "d", "f"]]
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_empty(self):
|
def test_empty(self):
|
||||||
@ -265,9 +263,7 @@ class TestCasebuild_word_dict:
|
|||||||
j = job.Job(1, do_progress)
|
j = job.Job(1, do_progress)
|
||||||
self.log = []
|
self.log = []
|
||||||
s = "foo bar"
|
s = "foo bar"
|
||||||
build_word_dict(
|
build_word_dict([NamedObject(s, True), NamedObject(s, True), NamedObject(s, True)], j)
|
||||||
[NamedObject(s, True), NamedObject(s, True), NamedObject(s, True)], j
|
|
||||||
)
|
|
||||||
# We don't have intermediate log because iter_with_progress is called with every > 1
|
# We don't have intermediate log because iter_with_progress is called with every > 1
|
||||||
eq_(0, self.log[0])
|
eq_(0, self.log[0])
|
||||||
eq_(100, self.log[1])
|
eq_(100, self.log[1])
|
||||||
@ -297,10 +293,7 @@ class TestCasereduce_common_words:
|
|||||||
|
|
||||||
def test_dont_remove_objects_with_only_common_words(self):
|
def test_dont_remove_objects_with_only_common_words(self):
|
||||||
d = {
|
d = {
|
||||||
"common": set(
|
"common": set([NamedObject("common uncommon", True) for i in range(50)] + [NamedObject("common", True)]),
|
||||||
[NamedObject("common uncommon", True) for i in range(50)]
|
|
||||||
+ [NamedObject("common", True)]
|
|
||||||
),
|
|
||||||
"uncommon": set([NamedObject("common uncommon", True)]),
|
"uncommon": set([NamedObject("common uncommon", True)]),
|
||||||
}
|
}
|
||||||
reduce_common_words(d, 50)
|
reduce_common_words(d, 50)
|
||||||
@ -309,10 +302,7 @@ class TestCasereduce_common_words:
|
|||||||
|
|
||||||
def test_values_still_are_set_instances(self):
|
def test_values_still_are_set_instances(self):
|
||||||
d = {
|
d = {
|
||||||
"common": set(
|
"common": set([NamedObject("common uncommon", True) for i in range(50)] + [NamedObject("common", True)]),
|
||||||
[NamedObject("common uncommon", True) for i in range(50)]
|
|
||||||
+ [NamedObject("common", True)]
|
|
||||||
),
|
|
||||||
"uncommon": set([NamedObject("common uncommon", True)]),
|
"uncommon": set([NamedObject("common uncommon", True)]),
|
||||||
}
|
}
|
||||||
reduce_common_words(d, 50)
|
reduce_common_words(d, 50)
|
||||||
@ -352,12 +342,8 @@ class TestCasereduce_common_words:
|
|||||||
# would not stay in 'bar' because 'foo' is not a common word anymore.
|
# would not stay in 'bar' because 'foo' is not a common word anymore.
|
||||||
only_common = NamedObject("foo bar", True)
|
only_common = NamedObject("foo bar", True)
|
||||||
d = {
|
d = {
|
||||||
"foo": set(
|
"foo": set([NamedObject("foo bar baz", True) for i in range(49)] + [only_common]),
|
||||||
[NamedObject("foo bar baz", True) for i in range(49)] + [only_common]
|
"bar": set([NamedObject("foo bar baz", True) for i in range(49)] + [only_common]),
|
||||||
),
|
|
||||||
"bar": set(
|
|
||||||
[NamedObject("foo bar baz", True) for i in range(49)] + [only_common]
|
|
||||||
),
|
|
||||||
"baz": set([NamedObject("foo bar baz", True) for i in range(49)]),
|
"baz": set([NamedObject("foo bar baz", True) for i in range(49)]),
|
||||||
}
|
}
|
||||||
reduce_common_words(d, 50)
|
reduce_common_words(d, 50)
|
||||||
@ -386,9 +372,7 @@ class TestCaseget_match:
|
|||||||
assert object() not in m
|
assert object() not in m
|
||||||
|
|
||||||
def test_word_weight(self):
|
def test_word_weight(self):
|
||||||
m = get_match(
|
m = get_match(NamedObject("foo bar", True), NamedObject("bar bleh", True), (WEIGHT_WORDS,))
|
||||||
NamedObject("foo bar", True), NamedObject("bar bleh", True), (WEIGHT_WORDS,)
|
|
||||||
)
|
|
||||||
eq_(m.percentage, int((6.0 / 13.0) * 100))
|
eq_(m.percentage, int((6.0 / 13.0) * 100))
|
||||||
|
|
||||||
|
|
||||||
@ -554,8 +538,12 @@ class TestCaseGetMatchesByContents:
|
|||||||
def test_big_file_partial_hashes(self):
|
def test_big_file_partial_hashes(self):
|
||||||
smallsize = 1
|
smallsize = 1
|
||||||
bigsize = 100 * 1024 * 1024 # 100MB
|
bigsize = 100 * 1024 * 1024 # 100MB
|
||||||
f = [no("bigfoo", size=bigsize), no("bigbar", size=bigsize),
|
f = [
|
||||||
no("smallfoo", size=smallsize), no("smallbar", size=smallsize)]
|
no("bigfoo", size=bigsize),
|
||||||
|
no("bigbar", size=bigsize),
|
||||||
|
no("smallfoo", size=smallsize),
|
||||||
|
no("smallbar", size=smallsize),
|
||||||
|
]
|
||||||
f[0].md5 = f[0].md5partial = f[0].md5samples = "foobar"
|
f[0].md5 = f[0].md5partial = f[0].md5samples = "foobar"
|
||||||
f[1].md5 = f[1].md5partial = f[1].md5samples = "foobar"
|
f[1].md5 = f[1].md5partial = f[1].md5samples = "foobar"
|
||||||
f[2].md5 = f[2].md5partial = "bleh"
|
f[2].md5 = f[2].md5partial = "bleh"
|
||||||
@ -749,8 +737,7 @@ class TestCaseGroup:
|
|||||||
# if the ref has the same key as one or more of the dupe, run the tie_breaker func among them
|
# if the ref has the same key as one or more of the dupe, run the tie_breaker func among them
|
||||||
g = get_test_group()
|
g = get_test_group()
|
||||||
o1, o2, o3 = g.ordered
|
o1, o2, o3 = g.ordered
|
||||||
tie_breaker = lambda ref, dupe: dupe is o3
|
g.prioritize(lambda x: 0, lambda ref, dupe: dupe is o3)
|
||||||
g.prioritize(lambda x: 0, tie_breaker)
|
|
||||||
assert g.ref is o3
|
assert g.ref is o3
|
||||||
|
|
||||||
def test_prioritize_with_tie_breaker_runs_on_all_dupes(self):
|
def test_prioritize_with_tie_breaker_runs_on_all_dupes(self):
|
||||||
@ -761,8 +748,7 @@ class TestCaseGroup:
|
|||||||
o1.foo = 1
|
o1.foo = 1
|
||||||
o2.foo = 2
|
o2.foo = 2
|
||||||
o3.foo = 3
|
o3.foo = 3
|
||||||
tie_breaker = lambda ref, dupe: dupe.foo > ref.foo
|
g.prioritize(lambda x: 0, lambda ref, dupe: dupe.foo > ref.foo)
|
||||||
g.prioritize(lambda x: 0, tie_breaker)
|
|
||||||
assert g.ref is o3
|
assert g.ref is o3
|
||||||
|
|
||||||
def test_prioritize_with_tie_breaker_runs_only_on_tie_dupes(self):
|
def test_prioritize_with_tie_breaker_runs_only_on_tie_dupes(self):
|
||||||
@ -775,9 +761,7 @@ class TestCaseGroup:
|
|||||||
o1.bar = 1
|
o1.bar = 1
|
||||||
o2.bar = 2
|
o2.bar = 2
|
||||||
o3.bar = 3
|
o3.bar = 3
|
||||||
key_func = lambda x: -x.foo
|
g.prioritize(lambda x: -x.foo, lambda ref, dupe: dupe.bar > ref.bar)
|
||||||
tie_breaker = lambda ref, dupe: dupe.bar > ref.bar
|
|
||||||
g.prioritize(key_func, tie_breaker)
|
|
||||||
assert g.ref is o2
|
assert g.ref is o2
|
||||||
|
|
||||||
def test_prioritize_with_ref_dupe(self):
|
def test_prioritize_with_ref_dupe(self):
|
||||||
@ -909,9 +893,7 @@ class TestCaseget_groups:
|
|||||||
m1 = Match(A, B, 90) # This is the strongest "A" match
|
m1 = Match(A, B, 90) # This is the strongest "A" match
|
||||||
m2 = Match(A, C, 80) # Because C doesn't match with B, it won't be in the group
|
m2 = Match(A, C, 80) # Because C doesn't match with B, it won't be in the group
|
||||||
m3 = Match(A, D, 80) # Same thing for D
|
m3 = Match(A, D, 80) # Same thing for D
|
||||||
m4 = Match(
|
m4 = Match(C, D, 70) # However, because C and D match, they should have their own group.
|
||||||
C, D, 70
|
|
||||||
) # However, because C and D match, they should have their own group.
|
|
||||||
groups = get_groups([m1, m2, m3, m4])
|
groups = get_groups([m1, m2, m3, m4])
|
||||||
eq_(len(groups), 2)
|
eq_(len(groups), 2)
|
||||||
g1, g2 = groups
|
g1, g2 = groups
|
||||||
|
@ -30,8 +30,7 @@ from .util import ensure_folder, delete_files_with_pattern
|
|||||||
|
|
||||||
|
|
||||||
def print_and_do(cmd):
|
def print_and_do(cmd):
|
||||||
"""Prints ``cmd`` and executes it in the shell.
|
"""Prints ``cmd`` and executes it in the shell."""
|
||||||
"""
|
|
||||||
print(cmd)
|
print(cmd)
|
||||||
p = Popen(cmd, shell=True)
|
p = Popen(cmd, shell=True)
|
||||||
return p.wait()
|
return p.wait()
|
||||||
@ -91,16 +90,14 @@ def copy_all(pattern, dst):
|
|||||||
|
|
||||||
|
|
||||||
def ensure_empty_folder(path):
|
def ensure_empty_folder(path):
|
||||||
"""Make sure that the path exists and that it's an empty folder.
|
"""Make sure that the path exists and that it's an empty folder."""
|
||||||
"""
|
|
||||||
if op.exists(path):
|
if op.exists(path):
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
|
|
||||||
|
|
||||||
def filereplace(filename, outfilename=None, **kwargs):
|
def filereplace(filename, outfilename=None, **kwargs):
|
||||||
"""Reads `filename`, replaces all {variables} in kwargs, and writes the result to `outfilename`.
|
"""Reads `filename`, replaces all {variables} in kwargs, and writes the result to `outfilename`."""
|
||||||
"""
|
|
||||||
if outfilename is None:
|
if outfilename is None:
|
||||||
outfilename = filename
|
outfilename = filename
|
||||||
fp = open(filename, "rt", encoding="utf-8")
|
fp = open(filename, "rt", encoding="utf-8")
|
||||||
@ -152,9 +149,7 @@ def package_cocoa_app_in_dmg(app_path, destfolder, args):
|
|||||||
# a valid signature.
|
# a valid signature.
|
||||||
if args.sign_identity:
|
if args.sign_identity:
|
||||||
sign_identity = "Developer ID Application: {}".format(args.sign_identity)
|
sign_identity = "Developer ID Application: {}".format(args.sign_identity)
|
||||||
result = print_and_do(
|
result = print_and_do('codesign --force --deep --sign "{}" "{}"'.format(sign_identity, app_path))
|
||||||
'codesign --force --deep --sign "{}" "{}"'.format(sign_identity, app_path)
|
|
||||||
)
|
|
||||||
if result != 0:
|
if result != 0:
|
||||||
print("ERROR: Signing failed. Aborting packaging.")
|
print("ERROR: Signing failed. Aborting packaging.")
|
||||||
return
|
return
|
||||||
@ -182,10 +177,7 @@ def build_dmg(app_path, destfolder):
|
|||||||
)
|
)
|
||||||
print("Building %s" % dmgname)
|
print("Building %s" % dmgname)
|
||||||
# UDBZ = bzip compression. UDZO (zip compression) was used before, but it compresses much less.
|
# UDBZ = bzip compression. UDZO (zip compression) was used before, but it compresses much less.
|
||||||
print_and_do(
|
print_and_do('hdiutil create "%s" -format UDBZ -nocrossdev -srcdir "%s"' % (op.join(destfolder, dmgname), dmgpath))
|
||||||
'hdiutil create "%s" -format UDBZ -nocrossdev -srcdir "%s"'
|
|
||||||
% (op.join(destfolder, dmgname), dmgpath)
|
|
||||||
)
|
|
||||||
print("Build Complete")
|
print("Build Complete")
|
||||||
|
|
||||||
|
|
||||||
@ -207,8 +199,7 @@ sysconfig.get_config_h_filename = lambda: op.join(op.dirname(__file__), 'pyconfi
|
|||||||
|
|
||||||
|
|
||||||
def add_to_pythonpath(path):
|
def add_to_pythonpath(path):
|
||||||
"""Adds ``path`` to both ``PYTHONPATH`` env and ``sys.path``.
|
"""Adds ``path`` to both ``PYTHONPATH`` env and ``sys.path``."""
|
||||||
"""
|
|
||||||
abspath = op.abspath(path)
|
abspath = op.abspath(path)
|
||||||
pythonpath = os.environ.get("PYTHONPATH", "")
|
pythonpath = os.environ.get("PYTHONPATH", "")
|
||||||
pathsep = ";" if ISWINDOWS else ":"
|
pathsep = ";" if ISWINDOWS else ":"
|
||||||
@ -231,9 +222,7 @@ def copy_packages(packages_names, dest, create_links=False, extra_ignores=None):
|
|||||||
create_links = False
|
create_links = False
|
||||||
if not extra_ignores:
|
if not extra_ignores:
|
||||||
extra_ignores = []
|
extra_ignores = []
|
||||||
ignore = shutil.ignore_patterns(
|
ignore = shutil.ignore_patterns(".hg*", "tests", "testdata", "modules", "docs", "locale", *extra_ignores)
|
||||||
".hg*", "tests", "testdata", "modules", "docs", "locale", *extra_ignores
|
|
||||||
)
|
|
||||||
for package_name in packages_names:
|
for package_name in packages_names:
|
||||||
if op.exists(package_name):
|
if op.exists(package_name):
|
||||||
source_path = package_name
|
source_path = package_name
|
||||||
@ -444,11 +433,10 @@ class OSXFrameworkStructure:
|
|||||||
|
|
||||||
def create_symlinks(self):
|
def create_symlinks(self):
|
||||||
# Only call this after create() and copy_executable()
|
# Only call this after create() and copy_executable()
|
||||||
rel = lambda path: op.relpath(path, self.dest)
|
|
||||||
os.symlink("A", op.join(self.dest, "Versions", "Current"))
|
os.symlink("A", op.join(self.dest, "Versions", "Current"))
|
||||||
os.symlink(rel(self.executablepath), op.join(self.dest, self.executablename))
|
os.symlink(op.relpath(self.executablepath, self.dest), op.join(self.dest, self.executablename))
|
||||||
os.symlink(rel(self.headers), op.join(self.dest, "Headers"))
|
os.symlink(op.relpath(self.headers, self.dest), op.join(self.dest, "Headers"))
|
||||||
os.symlink(rel(self.resources), op.join(self.dest, "Resources"))
|
os.symlink(op.relpath(self.resources, self.dest), op.join(self.dest, "Resources"))
|
||||||
|
|
||||||
def copy_executable(self, executable):
|
def copy_executable(self, executable):
|
||||||
copy(executable, self.executablepath)
|
copy(executable, self.executablepath)
|
||||||
@ -481,9 +469,7 @@ def copy_embeddable_python_dylib(dst):
|
|||||||
def collect_stdlib_dependencies(script, dest_folder, extra_deps=None):
|
def collect_stdlib_dependencies(script, dest_folder, extra_deps=None):
|
||||||
sysprefix = sys.prefix # could be a virtualenv
|
sysprefix = sys.prefix # could be a virtualenv
|
||||||
basesysprefix = sys.base_prefix # seems to be path to non-virtual sys
|
basesysprefix = sys.base_prefix # seems to be path to non-virtual sys
|
||||||
real_lib_prefix = sysconfig.get_config_var(
|
real_lib_prefix = sysconfig.get_config_var("LIBDEST") # leaving this in case it is neede
|
||||||
"LIBDEST"
|
|
||||||
) # leaving this in case it is neede
|
|
||||||
|
|
||||||
def is_stdlib_path(path):
|
def is_stdlib_path(path):
|
||||||
# A module path is only a stdlib path if it's in either sys.prefix or
|
# A module path is only a stdlib path if it's in either sys.prefix or
|
||||||
@ -493,11 +479,7 @@ def collect_stdlib_dependencies(script, dest_folder, extra_deps=None):
|
|||||||
return False
|
return False
|
||||||
if "site-package" in path:
|
if "site-package" in path:
|
||||||
return False
|
return False
|
||||||
if not (
|
if not (path.startswith(sysprefix) or path.startswith(basesysprefix) or path.startswith(real_lib_prefix)):
|
||||||
path.startswith(sysprefix)
|
|
||||||
or path.startswith(basesysprefix)
|
|
||||||
or path.startswith(real_lib_prefix)
|
|
||||||
):
|
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -511,9 +493,7 @@ def collect_stdlib_dependencies(script, dest_folder, extra_deps=None):
|
|||||||
relpath = op.relpath(p, real_lib_prefix)
|
relpath = op.relpath(p, real_lib_prefix)
|
||||||
elif p.startswith(sysprefix):
|
elif p.startswith(sysprefix):
|
||||||
relpath = op.relpath(p, sysprefix)
|
relpath = op.relpath(p, sysprefix)
|
||||||
assert relpath.startswith(
|
assert relpath.startswith("lib/python3.") # we want to get rid of that lib/python3.x part
|
||||||
"lib/python3."
|
|
||||||
) # we want to get rid of that lib/python3.x part
|
|
||||||
relpath = relpath[len("lib/python3.X/") :]
|
relpath = relpath[len("lib/python3.X/") :]
|
||||||
elif p.startswith(basesysprefix):
|
elif p.startswith(basesysprefix):
|
||||||
relpath = op.relpath(p, basesysprefix)
|
relpath = op.relpath(p, basesysprefix)
|
||||||
@ -521,9 +501,7 @@ def collect_stdlib_dependencies(script, dest_folder, extra_deps=None):
|
|||||||
relpath = relpath[len("lib/python3.X/") :]
|
relpath = relpath[len("lib/python3.X/") :]
|
||||||
else:
|
else:
|
||||||
raise AssertionError()
|
raise AssertionError()
|
||||||
if relpath.startswith(
|
if relpath.startswith("lib-dynload"): # We copy .so files in lib-dynload directly in our dest
|
||||||
"lib-dynload"
|
|
||||||
): # We copy .so files in lib-dynload directly in our dest
|
|
||||||
relpath = relpath[len("lib-dynload/") :]
|
relpath = relpath[len("lib-dynload/") :]
|
||||||
if relpath.startswith("encodings") or relpath.startswith("distutils"):
|
if relpath.startswith("encodings") or relpath.startswith("distutils"):
|
||||||
# We force their inclusion later.
|
# We force their inclusion later.
|
||||||
@ -562,9 +540,7 @@ def fix_qt_resource_file(path):
|
|||||||
fp.write(b"\n".join(lines))
|
fp.write(b"\n".join(lines))
|
||||||
|
|
||||||
|
|
||||||
def build_cocoa_ext(
|
def build_cocoa_ext(extname, dest, source_files, extra_frameworks=(), extra_includes=()):
|
||||||
extname, dest, source_files, extra_frameworks=(), extra_includes=()
|
|
||||||
):
|
|
||||||
extra_link_args = ["-framework", "CoreFoundation", "-framework", "Foundation"]
|
extra_link_args = ["-framework", "CoreFoundation", "-framework", "Foundation"]
|
||||||
for extra in extra_frameworks:
|
for extra in extra_frameworks:
|
||||||
extra_link_args += ["-framework", extra]
|
extra_link_args += ["-framework", extra]
|
||||||
|
@ -97,8 +97,7 @@ class Table(MutableSequence, Selectable):
|
|||||||
self._rows.pop(0)
|
self._rows.pop(0)
|
||||||
if self._footer is not None:
|
if self._footer is not None:
|
||||||
self._rows.pop()
|
self._rows.pop()
|
||||||
key = lambda row: row.sort_key_for_column(column_name)
|
self._rows.sort(key=lambda row: row.sort_key_for_column(column_name), reverse=desc)
|
||||||
self._rows.sort(key=key, reverse=desc)
|
|
||||||
if self._header is not None:
|
if self._header is not None:
|
||||||
self._rows.insert(0, self._header)
|
self._rows.insert(0, self._header)
|
||||||
if self._footer is not None:
|
if self._footer is not None:
|
||||||
@ -277,8 +276,7 @@ class GUITable(Table, GUIObject):
|
|||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def _do_delete(self):
|
def _do_delete(self):
|
||||||
"""(Virtual) Delete the selected rows.
|
"""(Virtual) Delete the selected rows."""
|
||||||
"""
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _fill(self):
|
def _fill(self):
|
||||||
|
@ -76,14 +76,10 @@ class PreferencesDialogBase(QDialog):
|
|||||||
super().__init__(parent, flags, **kwargs)
|
super().__init__(parent, flags, **kwargs)
|
||||||
self.app = app
|
self.app = app
|
||||||
all_languages = get_langnames()
|
all_languages = get_langnames()
|
||||||
self.supportedLanguages = sorted(
|
self.supportedLanguages = sorted(SUPPORTED_LANGUAGES, key=lambda lang: all_languages[lang])
|
||||||
SUPPORTED_LANGUAGES, key=lambda lang: all_languages[lang]
|
|
||||||
)
|
|
||||||
self._setupUi()
|
self._setupUi()
|
||||||
|
|
||||||
self.filterHardnessSlider.valueChanged["int"].connect(
|
self.filterHardnessSlider.valueChanged["int"].connect(self.filterHardnessLabel.setNum)
|
||||||
self.filterHardnessLabel.setNum
|
|
||||||
)
|
|
||||||
self.buttonBox.clicked.connect(self.buttonClicked)
|
self.buttonBox.clicked.connect(self.buttonClicked)
|
||||||
self.buttonBox.accepted.connect(self.accept)
|
self.buttonBox.accepted.connect(self.accept)
|
||||||
self.buttonBox.rejected.connect(self.reject)
|
self.buttonBox.rejected.connect(self.reject)
|
||||||
@ -102,9 +98,7 @@ class PreferencesDialogBase(QDialog):
|
|||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
sizePolicy.setHeightForWidth(
|
sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
|
||||||
self.filterHardnessSlider.sizePolicy().hasHeightForWidth()
|
|
||||||
)
|
|
||||||
self.filterHardnessSlider.setSizePolicy(sizePolicy)
|
self.filterHardnessSlider.setSizePolicy(sizePolicy)
|
||||||
self.filterHardnessSlider.setMinimum(1)
|
self.filterHardnessSlider.setMinimum(1)
|
||||||
self.filterHardnessSlider.setMaximum(100)
|
self.filterHardnessSlider.setMaximum(100)
|
||||||
@ -140,9 +134,7 @@ class PreferencesDialogBase(QDialog):
|
|||||||
self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path"))
|
self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path"))
|
||||||
self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox)
|
self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox)
|
||||||
self.customCommandLabel = QLabel(self)
|
self.customCommandLabel = QLabel(self)
|
||||||
self.customCommandLabel.setText(
|
self.customCommandLabel.setText(tr("Custom Command (arguments: %d for dupe, %r for ref):"))
|
||||||
tr("Custom Command (arguments: %d for dupe, %r for ref):")
|
|
||||||
)
|
|
||||||
self.widgetsVLayout.addWidget(self.customCommandLabel)
|
self.widgetsVLayout.addWidget(self.customCommandLabel)
|
||||||
self.customCommandEdit = QLineEdit(self)
|
self.customCommandEdit = QLineEdit(self)
|
||||||
self.widgetsVLayout.addWidget(self.customCommandEdit)
|
self.widgetsVLayout.addWidget(self.customCommandEdit)
|
||||||
@ -154,9 +146,7 @@ class PreferencesDialogBase(QDialog):
|
|||||||
self.languageComboBox = QComboBox(self)
|
self.languageComboBox = QComboBox(self)
|
||||||
for lang in self.supportedLanguages:
|
for lang in self.supportedLanguages:
|
||||||
self.languageComboBox.addItem(get_langnames()[lang])
|
self.languageComboBox.addItem(get_langnames()[lang])
|
||||||
layout.addLayout(
|
layout.addLayout(horizontalWrap([self.languageLabel, self.languageComboBox, None]))
|
||||||
horizontalWrap([self.languageLabel, self.languageComboBox, None])
|
|
||||||
)
|
|
||||||
self._setupAddCheckbox(
|
self._setupAddCheckbox(
|
||||||
"tabs_default_pos",
|
"tabs_default_pos",
|
||||||
tr("Use default position for tab bar (requires restart)"),
|
tr("Use default position for tab bar (requires restart)"),
|
||||||
@ -178,23 +168,15 @@ On MacOS, the tab bar will fill up the window's width instead."
|
|||||||
self.fontSizeSpinBox = QSpinBox()
|
self.fontSizeSpinBox = QSpinBox()
|
||||||
self.fontSizeSpinBox.setMinimum(5)
|
self.fontSizeSpinBox.setMinimum(5)
|
||||||
formlayout.addRow(tr("Font size:"), self.fontSizeSpinBox)
|
formlayout.addRow(tr("Font size:"), self.fontSizeSpinBox)
|
||||||
self._setupAddCheckbox(
|
self._setupAddCheckbox("reference_bold_font", tr("Use bold font for references"))
|
||||||
"reference_bold_font", tr("Use bold font for references")
|
|
||||||
)
|
|
||||||
formlayout.addRow(self.reference_bold_font)
|
formlayout.addRow(self.reference_bold_font)
|
||||||
|
|
||||||
self.result_table_ref_foreground_color = ColorPickerButton(self)
|
self.result_table_ref_foreground_color = ColorPickerButton(self)
|
||||||
formlayout.addRow(
|
formlayout.addRow(tr("Reference foreground color:"), self.result_table_ref_foreground_color)
|
||||||
tr("Reference foreground color:"), self.result_table_ref_foreground_color
|
|
||||||
)
|
|
||||||
self.result_table_ref_background_color = ColorPickerButton(self)
|
self.result_table_ref_background_color = ColorPickerButton(self)
|
||||||
formlayout.addRow(
|
formlayout.addRow(tr("Reference background color:"), self.result_table_ref_background_color)
|
||||||
tr("Reference background color:"), self.result_table_ref_background_color
|
|
||||||
)
|
|
||||||
self.result_table_delta_foreground_color = ColorPickerButton(self)
|
self.result_table_delta_foreground_color = ColorPickerButton(self)
|
||||||
formlayout.addRow(
|
formlayout.addRow(tr("Delta foreground color:"), self.result_table_delta_foreground_color)
|
||||||
tr("Delta foreground color:"), self.result_table_delta_foreground_color
|
|
||||||
)
|
|
||||||
formlayout.setLabelAlignment(Qt.AlignLeft)
|
formlayout.setLabelAlignment(Qt.AlignLeft)
|
||||||
|
|
||||||
# Keep same vertical spacing as parent layout for consistency
|
# Keep same vertical spacing as parent layout for consistency
|
||||||
@ -218,30 +200,20 @@ use the modifier key to drag the floating window around"
|
|||||||
else tr("The title bar can only be disabled while the window is docked")
|
else tr("The title bar can only be disabled while the window is docked")
|
||||||
)
|
)
|
||||||
self.details_groupbox_layout.addWidget(self.details_dialog_titlebar_enabled)
|
self.details_groupbox_layout.addWidget(self.details_dialog_titlebar_enabled)
|
||||||
self._setupAddCheckbox(
|
self._setupAddCheckbox("details_dialog_vertical_titlebar", tr("Vertical title bar"))
|
||||||
"details_dialog_vertical_titlebar", tr("Vertical title bar")
|
|
||||||
)
|
|
||||||
self.details_dialog_vertical_titlebar.setToolTip(
|
self.details_dialog_vertical_titlebar.setToolTip(
|
||||||
tr(
|
tr("Change the title bar from horizontal on top, to vertical on the left side")
|
||||||
"Change the title bar from horizontal on top, to vertical on the left side"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
self.details_groupbox_layout.addWidget(self.details_dialog_vertical_titlebar)
|
self.details_groupbox_layout.addWidget(self.details_dialog_vertical_titlebar)
|
||||||
self.details_dialog_vertical_titlebar.setEnabled(
|
self.details_dialog_vertical_titlebar.setEnabled(self.details_dialog_titlebar_enabled.isChecked())
|
||||||
self.details_dialog_titlebar_enabled.isChecked()
|
self.details_dialog_titlebar_enabled.stateChanged.connect(self.details_dialog_vertical_titlebar.setEnabled)
|
||||||
)
|
|
||||||
self.details_dialog_titlebar_enabled.stateChanged.connect(
|
|
||||||
self.details_dialog_vertical_titlebar.setEnabled
|
|
||||||
)
|
|
||||||
gridlayout = QGridLayout()
|
gridlayout = QGridLayout()
|
||||||
formlayout = QFormLayout()
|
formlayout = QFormLayout()
|
||||||
self.details_table_delta_foreground_color = ColorPickerButton(self)
|
self.details_table_delta_foreground_color = ColorPickerButton(self)
|
||||||
# Padding on the right side and space between label and widget to keep it somewhat consistent across themes
|
# Padding on the right side and space between label and widget to keep it somewhat consistent across themes
|
||||||
gridlayout.setColumnStretch(1, 1)
|
gridlayout.setColumnStretch(1, 1)
|
||||||
formlayout.setHorizontalSpacing(50)
|
formlayout.setHorizontalSpacing(50)
|
||||||
formlayout.addRow(
|
formlayout.addRow(tr("Delta foreground color:"), self.details_table_delta_foreground_color)
|
||||||
tr("Delta foreground color:"), self.details_table_delta_foreground_color
|
|
||||||
)
|
|
||||||
gridlayout.addLayout(formlayout, 0, 0)
|
gridlayout.addLayout(formlayout, 0, 0)
|
||||||
self.details_groupbox_layout.addLayout(gridlayout)
|
self.details_groupbox_layout.addLayout(gridlayout)
|
||||||
details_groupbox.setLayout(self.details_groupbox_layout)
|
details_groupbox.setLayout(self.details_groupbox_layout)
|
||||||
@ -276,9 +248,7 @@ use the modifier key to drag the floating window around"
|
|||||||
# self.mainVLayout.addLayout(self.widgetsVLayout)
|
# self.mainVLayout.addLayout(self.widgetsVLayout)
|
||||||
self.buttonBox = QDialogButtonBox(self)
|
self.buttonBox = QDialogButtonBox(self)
|
||||||
self.buttonBox.setStandardButtons(
|
self.buttonBox.setStandardButtons(
|
||||||
QDialogButtonBox.Cancel
|
QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.RestoreDefaults
|
||||||
| QDialogButtonBox.Ok
|
|
||||||
| QDialogButtonBox.RestoreDefaults
|
|
||||||
)
|
)
|
||||||
self.mainVLayout.addWidget(self.tabwidget)
|
self.mainVLayout.addWidget(self.tabwidget)
|
||||||
self.mainVLayout.addWidget(self.buttonBox)
|
self.mainVLayout.addWidget(self.buttonBox)
|
||||||
@ -299,7 +269,10 @@ use the modifier key to drag the floating window around"
|
|||||||
def load(self, prefs=None, section=Sections.ALL):
|
def load(self, prefs=None, section=Sections.ALL):
|
||||||
if prefs is None:
|
if prefs is None:
|
||||||
prefs = self.app.prefs
|
prefs = self.app.prefs
|
||||||
setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
|
|
||||||
|
def setchecked(cb, b):
|
||||||
|
cb.setCheckState(Qt.Checked if b else Qt.Unchecked)
|
||||||
|
|
||||||
if section & Sections.GENERAL:
|
if section & Sections.GENERAL:
|
||||||
self.filterHardnessSlider.setValue(prefs.filter_hardness)
|
self.filterHardnessSlider.setValue(prefs.filter_hardness)
|
||||||
self.filterHardnessLabel.setNum(prefs.filter_hardness)
|
self.filterHardnessLabel.setNum(prefs.filter_hardness)
|
||||||
@ -322,18 +295,10 @@ use the modifier key to drag the floating window around"
|
|||||||
prefs.details_dialog_vertical_titlebar,
|
prefs.details_dialog_vertical_titlebar,
|
||||||
)
|
)
|
||||||
self.fontSizeSpinBox.setValue(prefs.tableFontSize)
|
self.fontSizeSpinBox.setValue(prefs.tableFontSize)
|
||||||
self.details_table_delta_foreground_color.setColor(
|
self.details_table_delta_foreground_color.setColor(prefs.details_table_delta_foreground_color)
|
||||||
prefs.details_table_delta_foreground_color
|
self.result_table_ref_foreground_color.setColor(prefs.result_table_ref_foreground_color)
|
||||||
)
|
self.result_table_ref_background_color.setColor(prefs.result_table_ref_background_color)
|
||||||
self.result_table_ref_foreground_color.setColor(
|
self.result_table_delta_foreground_color.setColor(prefs.result_table_delta_foreground_color)
|
||||||
prefs.result_table_ref_foreground_color
|
|
||||||
)
|
|
||||||
self.result_table_ref_background_color.setColor(
|
|
||||||
prefs.result_table_ref_background_color
|
|
||||||
)
|
|
||||||
self.result_table_delta_foreground_color.setColor(
|
|
||||||
prefs.result_table_delta_foreground_color
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
langindex = self.supportedLanguages.index(self.app.prefs.language)
|
langindex = self.supportedLanguages.index(self.app.prefs.language)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -344,31 +309,22 @@ use the modifier key to drag the floating window around"
|
|||||||
def save(self):
|
def save(self):
|
||||||
prefs = self.app.prefs
|
prefs = self.app.prefs
|
||||||
prefs.filter_hardness = self.filterHardnessSlider.value()
|
prefs.filter_hardness = self.filterHardnessSlider.value()
|
||||||
ischecked = lambda cb: cb.checkState() == Qt.Checked
|
|
||||||
|
def ischecked(cb):
|
||||||
|
return cb.checkState() == Qt.Checked
|
||||||
|
|
||||||
prefs.mix_file_kind = ischecked(self.mixFileKindBox)
|
prefs.mix_file_kind = ischecked(self.mixFileKindBox)
|
||||||
prefs.use_regexp = ischecked(self.useRegexpBox)
|
prefs.use_regexp = ischecked(self.useRegexpBox)
|
||||||
prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
|
prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
|
||||||
prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
|
prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
|
||||||
prefs.debug_mode = ischecked(self.debugModeBox)
|
prefs.debug_mode = ischecked(self.debugModeBox)
|
||||||
prefs.reference_bold_font = ischecked(self.reference_bold_font)
|
prefs.reference_bold_font = ischecked(self.reference_bold_font)
|
||||||
prefs.details_dialog_titlebar_enabled = ischecked(
|
prefs.details_dialog_titlebar_enabled = ischecked(self.details_dialog_titlebar_enabled)
|
||||||
self.details_dialog_titlebar_enabled
|
prefs.details_dialog_vertical_titlebar = ischecked(self.details_dialog_vertical_titlebar)
|
||||||
)
|
prefs.details_table_delta_foreground_color = self.details_table_delta_foreground_color.color
|
||||||
prefs.details_dialog_vertical_titlebar = ischecked(
|
prefs.result_table_ref_foreground_color = self.result_table_ref_foreground_color.color
|
||||||
self.details_dialog_vertical_titlebar
|
prefs.result_table_ref_background_color = self.result_table_ref_background_color.color
|
||||||
)
|
prefs.result_table_delta_foreground_color = self.result_table_delta_foreground_color.color
|
||||||
prefs.details_table_delta_foreground_color = (
|
|
||||||
self.details_table_delta_foreground_color.color
|
|
||||||
)
|
|
||||||
prefs.result_table_ref_foreground_color = (
|
|
||||||
self.result_table_ref_foreground_color.color
|
|
||||||
)
|
|
||||||
prefs.result_table_ref_background_color = (
|
|
||||||
self.result_table_ref_background_color.color
|
|
||||||
)
|
|
||||||
prefs.result_table_delta_foreground_color = (
|
|
||||||
self.result_table_delta_foreground_color.color
|
|
||||||
)
|
|
||||||
prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
|
prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex()
|
||||||
prefs.custom_command = str(self.customCommandEdit.text())
|
prefs.custom_command = str(self.customCommandEdit.text())
|
||||||
prefs.tableFontSize = self.fontSizeSpinBox.value()
|
prefs.tableFontSize = self.fontSizeSpinBox.value()
|
||||||
@ -411,9 +367,7 @@ class ColorPickerButton(QPushButton):
|
|||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def onClicked(self):
|
def onClicked(self):
|
||||||
color = QColorDialog.getColor(
|
color = QColorDialog.getColor(self.color if self.color is not None else Qt.white, self.parent)
|
||||||
self.color if self.color is not None else Qt.white, self.parent
|
|
||||||
)
|
|
||||||
self.setColor(color)
|
self.setColor(color)
|
||||||
|
|
||||||
def setColor(self, color):
|
def setColor(self, color):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user