From 69eb80544f1c131b62f1e2c847c95872567eadb5 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Sat, 13 Apr 2002 03:53:20 +0000 Subject: [PATCH] * Fixes bug with reloading filters after they get edited. * Adds logical operations XOR and 'Exactly one rule must match' * XOR has no GUI yet, pending 'basic/advanced' preference * Ability to invert the sense of the filter. * What should be speed improvements by passing bound methods to the builtin filter function * Changes to the XML input/output to support new functonality * Changes to UI to support new functionality svn: r919 --- gramps/src/GenericFilter.py | 130 +++++++++++++++++++++++------ gramps/src/const.py | 2 + gramps/src/plugins/FilterEditor.py | 23 ++++- gramps/src/rule.glade | 59 +++++++++++-- 4 files changed, 178 insertions(+), 36 deletions(-) diff --git a/gramps/src/GenericFilter.py b/gramps/src/GenericFilter.py index 1cb25e9c9..c1c3cc118 100644 --- a/gramps/src/GenericFilter.py +++ b/gramps/src/GenericFilter.py @@ -494,6 +494,7 @@ class HasNameOf(Rule): return 1 return 0 + class MatchesFilter(Rule): """Rule that checks against another filter""" @@ -505,10 +506,10 @@ class MatchesFilter(Rule): def apply(self, p): for filter in SystemFilters.get_filters(): if filter.get_name() == self.list[0]: - return len(filter.apply([p])) > 0 + return filter.check(p) for filter in CustomFilters.get_filters(): if filter.get_name() == self.list[0]: - return len(filter.apply([p])) > 0 + return filter.check(p) return 0 #------------------------------------------------------------------------- @@ -524,18 +525,35 @@ class GenericFilter: self.flist = source.flist[:] self.name = source.name self.comment = source.comment - self.logical_or = source.logical_or + self.logical_op = source.logical_op + self.invert = source.invert else: self.flist = [] self.name = '' self.comment = '' - self.logical_or = 0 + self.logical_op = 'and' + self.invert = 0 def set_logical_or(self,val): - self.logical_or = val + self.logical_op = 'or' def get_logical_or(self): - return self.logical_or + return self.logical_op == 'or' + + def set_logical_op(self,val): + if val in const.logical_functions: + self.logical_op = val + else: + self.logical_op = 'and' + + def get_logical_op(self): + return self.logical_op + + def set_invert(self, val): + self.invert = not not val + + def get_invert(self): + return self.invert def get_name(self): return self.name @@ -557,23 +575,66 @@ class GenericFilter: def get_rules(self): return self.flist - - def apply(self,list): - result = [] - if self.logical_or: - for p in list: - for rule in self.flist: - if rule.apply(p): - result.append(p) - break + + def check_or(self,p): + test = 0 + for rule in self.flist: + test = test or rule.apply(p) + if test: + break + if self.invert: + return not test else: - for p in list: - for rule in self.flist: - if rule.apply(p) == 0: - break - else: - result.append(p) - return result + return test + + def check_xor(self,p): + test = 0 + for rule in self.flist: + temp = rule.apply(p) + test = ((not test) and temp) or (test and (not temp)) + if self.invert: + return not test + else: + return test + + def check_one(self,p): + count = 0 + for rule in self.flist: + if rule.apply(p): + count = count + 1 + if count > 1: + break + if self.invert: + return count != 1 + else: + return count == 1 + + def check_and(self,p): + test = 1 + for rule in self.flist: + test = test and rule.apply(p) + if not test: + break + if self.invert: + return not test + else: + return test + + def check(self,p): + try: + m = getattr(self, 'check_' + self.logical_op) + except AttributeError: + m = self.check_and + + return m(p) + + def apply(self,list): + try: + m = getattr(self, 'check_' + self.logical_op) + except AttributeError: + m = self.check_and + + return filter(m, list) #------------------------------------------------------------------------- # @@ -642,8 +703,9 @@ class GenericFilterList: f.write('\n') for i in self.filter_list: f.write(' GtkTable table1 - 4 + 6 2 False 0 @@ -241,17 +241,17 @@ GtkRadioButton - logical_and + logical_one True - - True + + False True logic 1 2 - 2 - 3 + 5 + 6 0 0 False @@ -271,6 +271,30 @@ False True logic + + 1 + 2 + 4 + 5 + 0 + 0 + False + False + False + False + True + False + + + + + GtkRadioButton + logical_and + True + + True + True + logic 1 2 @@ -286,6 +310,29 @@ False + + + GtkCheckButton + logical_not + True + + False + True + + 1 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + +