From 09cff3f69325515fbc9174cf572c3b161be03706 Mon Sep 17 00:00:00 2001 From: Martin Hawlisch Date: Wed, 16 Mar 2005 14:13:33 +0000 Subject: [PATCH] * src/GenericFilter.py (HasTextMatchingSubstringOf): add checkboxes for case and regexp matching; (HasTextMatchingRegexpOf) Added wrapper to use regexp matching in HasTextMatchingSubstringOf * src/gramps_main.py: Add new regular expression filter * src/plugins/FilterEditor.py (EditRule:__init__): Treat params of new filter as boolean. * TODO: Add parameter definition of Filter Rules to the filter itself, so it can be removed from the filter editor and used by PeopleView. svn: r4193 --- gramps2/ChangeLog | 9 +++++ gramps2/TODO | 2 + gramps2/src/GenericFilter.py | 59 +++++++++++++++++++++++++---- gramps2/src/gramps_main.py | 5 +++ gramps2/src/plugins/FilterEditor.py | 4 ++ 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index d97c661f9..b9ee5cbe4 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,12 @@ +2005-03-16 Martin Hawlisch + * src/GenericFilter.py (HasTextMatchingSubstringOf): add checkboxes for case and + regexp matching; (HasTextMatchingRegexpOf) Added wrapper to use regexp matching + in HasTextMatchingSubstringOf + * src/gramps_main.py: Add new regular expression filter + * src/plugins/FilterEditor.py (EditRule:__init__): Treat params of new filter as boolean. + * TODO: Add parameter definition of Filter Rules to the filter itself, so + it can be removed from the filter editor and used by PeopleView. + 2005-03-16 Richard Taylor * src/ScratchPad.py (ScratchPad): improved the generation of tooltip information for most object types. diff --git a/gramps2/TODO b/gramps2/TODO index 9cee845ca..7796fcc6e 100644 --- a/gramps2/TODO +++ b/gramps2/TODO @@ -19,4 +19,6 @@ 3 entries per page. * Add slideshow generation ability to web page generator * Enhance privacy handling +* Add parameter definition of Filter Rules to the filter itself, so it can be + removed from the filter editor and used by PeopleView. * And a whole lot more.... diff --git a/gramps2/src/GenericFilter.py b/gramps2/src/GenericFilter.py index c7a935a18..5b539f761 100644 --- a/gramps2/src/GenericFilter.py +++ b/gramps2/src/GenericFilter.py @@ -1825,27 +1825,45 @@ class IsWitness(Rule): if w.get_type() == RelLib.Event.ID: self.map.append(w.get_value()) + #------------------------------------------------------------------------- # "HasTextMatchingSubstringOf" #------------------------------------------------------------------------- - class HasTextMatchingSubstringOf(Rule): """Rule that checks for string matches in any textual information""" - labels = [_('Substring:')] + labels = [_('Substring:'), _('Case sensitive:'), _('Regular-Expression matching:')] def prepare(self,db): self.db = db + self.person_map = {} self.event_map = {} self.source_map = {} self.family_map = {} self.place_map = {} + try: + if int(self.list[1]): + self.case_sensitive = True + else: + self.case_sensitive = False + except IndexError: + self.case_sensitive = False + try: + if int(self.list[2]): + self.regexp_match = True + else: + self.regexp_match = False + except IndexError: + self.regexp_match = False self.cache_sources() def reset(self): + self.person_map = {} self.event_map = {} + self.source_map = {} self.family_map = {} + self.place_map = {} def name(self): return 'Has text matching substring of' @@ -1857,8 +1875,10 @@ class HasTextMatchingSubstringOf(Rule): return _('General filters') def apply(self,db,p_id): + if p_id in self.person_map: # Cached by matching Source? + return self.person_map[p_id] p = db.get_person_from_handle(p_id) - if p.matches_string(self.list[0]): # first match the person itself + if self.match_object(p): # first match the person itself return 1 for event_handle in p.get_event_list()+[p.get_birth_handle(), p.get_death_handle()]: if self.search_event(event_handle): # match referenced events @@ -1875,7 +1895,7 @@ class HasTextMatchingSubstringOf(Rule): if not family_handle in self.family_map: match = 0 family = self.db.get_family_from_handle(family_handle) - if family.matches_string(self.list[0]): + if self.match_object(family): match = 1 else: for event_handle in family.get_event_list(): @@ -1892,7 +1912,7 @@ class HasTextMatchingSubstringOf(Rule): if not event_handle in self.event_map: match = 0 event = self.db.get_event_from_handle(event_handle) - if event.matches_string(self.list[0]): + if self.match_object(event): match = 1 else: place_handle = event.get_place_handle() @@ -1908,14 +1928,14 @@ class HasTextMatchingSubstringOf(Rule): # search inside the place and cache the result if not place_handle in self.place_map: place = self.db.get_place_from_handle(place_handle) - self.place_map[place_handle] = place.matches_string(self.list[0]) + self.place_map[place_handle] = self.match_object(place) return self.place_map[place_handle] def cache_sources(self): # search all sources and match all referents of a matching source for source_handle in self.db.get_source_handles(): source = self.db.get_source_from_handle(source_handle) - if source.matches_string(self.list[0]): + if self.match_object(source): (person_list,family_list,event_list, place_list,source_list,media_list ) = get_source_referents(source_handle,self.db) @@ -1928,6 +1948,31 @@ class HasTextMatchingSubstringOf(Rule): for handle in place_list: self.place_map[handle] = 1 + def match_object(self,object): + if self.regexp_match: + return object.matches_regexp(self.list[0],self.case_sensitive) + return object.matches_string(self.list[0],self.case_sensitive) + +#------------------------------------------------------------------------- +# "HasTextMatchingRegexOf" +#------------------------------------------------------------------------- +class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): + """This is wrapping HasTextMatchingSubstringOf to enable the regex_match parameter""" + def __init__(self,list): + HasTextMatchingSubstringOf.__init__(self,list) + + def prepare(self,db): + self.db = db + self.person_map = {} + self.event_map = {} + self.source_map = {} + self.family_map = {} + self.place_map = {} + self.case_sensitive = False + self.regexp_match = True + self.cache_sources() + + #------------------------------------------------------------------------- # # GenericFilter diff --git a/gramps2/src/gramps_main.py b/gramps2/src/gramps_main.py index c32d91352..6f4d3ad44 100755 --- a/gramps2/src/gramps_main.py +++ b/gramps2/src/gramps_main.py @@ -952,6 +952,11 @@ class Gramps: all.add_rule(GenericFilter.HasTextMatchingSubstringOf([])) filter_list.append(all) + all = GenericFilter.ParamFilter() + all.set_name(_("Any textual record matches regular expression...")) + all.add_rule(GenericFilter.HasTextMatchingRegexpOf([])) + filter_list.append(all) + self.filter_model = GenericFilter.FilterStore(filter_list) self.filter_list.set_model(self.filter_model) self.filter_list.set_active(self.filter_model.default_index()) diff --git a/gramps2/src/plugins/FilterEditor.py b/gramps2/src/plugins/FilterEditor.py index 65f933fa6..d4c62102f 100644 --- a/gramps2/src/plugins/FilterEditor.py +++ b/gramps2/src/plugins/FilterEditor.py @@ -637,6 +637,10 @@ class EditRule: t = MyListSelect(data) elif v == _('Inclusive:'): t = MyBoolean(_('Include original person')) + elif v == _('Case sensitive:'): + t = MyBoolean(_('Use exact case of letters:')) + elif v == _('Regular-Expression matching:'): + t = MyBoolean(_('Use regular expression')) else: t = MyEntry() tlist.append(t)