diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index ae8549e38..4105816b1 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,10 @@ +2005-03-15 Martin Hawlisch + * src/GenericFilter.py (FullTextSearch): Added new filter thad provides + a full-text search thru (nearly) all attributes and linked objexts of a person. + * src/gramps_main.py: add the new filter to the menu. + * src/RelLib.py (Event,Source): fix get_text_data_child_list() to correct + attributes of the class; (Family): fix get_sourcref_child_list(). + 2005-03-14 Alex Roitman * src/AddSpouse.py (select_spouse_clicked): Prevent adding oneself and oneself's parents as a spouse; When aborting, do not close dialog. diff --git a/gramps2/src/GenericFilter.py b/gramps2/src/GenericFilter.py index 03595daf6..8c8b209c5 100644 --- a/gramps2/src/GenericFilter.py +++ b/gramps2/src/GenericFilter.py @@ -59,6 +59,7 @@ import NameDisplay from TransTable import TransTable from Utils import for_each_ancestor from Utils import probably_alive +from Utils import get_source_referents #------------------------------------------------------------------------- # @@ -1825,7 +1826,110 @@ class IsWitness(Rule): for w in wlist: if w.get_type() == RelLib.Event.ID: self.map.append(w.get_value()) + +#------------------------------------------------------------------------- +# "FullTextSearch" +#------------------------------------------------------------------------- + + +class FullTextSearch(Rule): + """Full-text serach for ...""" + + labels = [_('Substring:')] + + def prepare(self,db): + self.db = db + self.event_map = {} + self.source_map = {} + self.family_map = {} + self.place_map = {} + self.cache_sources() + + def reset(self): + self.event_map = {} + self.family_map = {} + + def name(self): + return 'Full-text serach for ...' + def description(self): + return _("Does a full-text search in all text values of the verson and all linked events and families") + + def category(self): + return _('General filters') + + def apply(self,db,p_id): + p = db.get_person_from_handle(p_id) + if p.matches_string(self.list[0]): # 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 + return 1 + for family_handle in p.get_family_handle_list(): # match families + if self.search_family(family_handle): + return 1 + return 0 + + def search_family(self,family_handle): + if not family_handle: + return 0 + # search inside the family and cache the result to not search a family twice + 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]): + match = 1 + else: + for event_handle in family.get_event_list(): + if self.search_event(event_handle): + match = 1 + break + self.family_map[family_handle] = match + return self.family_map[family_handle] + + def search_event(self,event_handle): + if not event_handle: + return 0 + # search inside the event and cache the result (event sharing) + 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]): + match = 1 + else: + place_handle = event.get_place_handle() + if place_handle: + if self.search_place(place_handle): + match = 1 + self.event_map[event_handle] = match + return self.event_map[event_handle] + + def search_place(self,place_handle): + if not place_handle: + return 0 + # 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]) + 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]): + (person_list,family_list,event_list, + place_list,source_list,media_list + ) = get_source_referents(source_handle,self.db) + for handle in person_list: + self.person_map[handle] = 1 + for handle in family_list: + self.family_map[handle] = 1 + for handle in event_list: + self.event_map[handle] = 1 + for handle in place_list: + self.place_map[handle] = 1 + #------------------------------------------------------------------------- # # GenericFilter @@ -2014,7 +2118,9 @@ tasks = { unicode(_("People probably alive")) : ProbablyAlive, unicode(_("People marked private")) : PeoplePrivate, unicode(_("Witnesses")) : IsWitness, - } + + unicode(_("Full-text search ...")) : FullTextSearch, +} #------------------------------------------------------------------------- # diff --git a/gramps2/src/RelLib.py b/gramps2/src/RelLib.py index 343794e22..aaf3cf1bb 100644 --- a/gramps2/src/RelLib.py +++ b/gramps2/src/RelLib.py @@ -1316,7 +1316,7 @@ class Family(PrimaryObject,SourceNote): @return: Returns the list of child secondary child objects that may refer sources. @rtype: list """ - check_list = self.media_list + self.attribute_list + self.source_list + check_list = self.media_list + self.attribute_list if self.lds_seal: check_list.append(self.lds_seal) return check_list @@ -1689,7 +1689,7 @@ class Event(PrimaryObject,DataObj): if self.witness: check_list = check_list + self.witness if self.note: - check_list.append(note) + check_list.append(self.note) return check_list def get_sourcref_child_list(self): @@ -2501,7 +2501,7 @@ class Source(PrimaryObject): @return: Returns the list of child objects that may carry textual data. @rtype: list """ - check_list = self.attrlist + self.source_list + check_list = [] if self.note: check_list.append(self.note) return check_list diff --git a/gramps2/src/gramps_main.py b/gramps2/src/gramps_main.py index 960dad5ff..e5c1b0589 100755 --- a/gramps2/src/gramps_main.py +++ b/gramps2/src/gramps_main.py @@ -947,6 +947,11 @@ class Gramps: all.add_rule(GenericFilter.IsWitness([])) filter_list.append(all) + all = GenericFilter.ParamFilter() + all.set_name(_("Full-text search ...")) + all.add_rule(GenericFilter.FullTextSearch([])) + 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())