diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 8fc14dc3c..fb2a129b8 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,8 @@ +2005-05-18 Alex Roitman + * src/GenericFilter.py: Use class names for internal work; Rework + ID-based filters to use gramps-id instead of a handle. + * src/plugins/FilterEditor.py: Use class names for internal work. + 2005-05-18 Don Allingham * src/ReadGedcom.py: grab description for birth and death events * src/WriteGedcom.py: export description for birth and death events diff --git a/gramps2/src/GenericFilter.py b/gramps2/src/GenericFilter.py index d7ad3e232..c068fb101 100644 --- a/gramps2/src/GenericFilter.py +++ b/gramps2/src/GenericFilter.py @@ -85,8 +85,11 @@ def date_cmp(rule,value): class Rule: """Base rule class""" - labels = [] - + labels = [] + name = '' + category = _('Miscellaneous filters') + description = _('No description') + def __init__(self,list): self.set_list(list) @@ -102,23 +105,11 @@ class Rule: def values(self): return self.list - - def trans_name(self): - return _(self.name()) - def name(self): - return 'None' - - def category(self): - return _('Miscellaneous filters') - - def description(self): - return _('No description') - def check(self): return len(self.list) == len(self.labels) - def apply(self,db,p): + def apply(self,db,handle): return 1 def display_values(self): @@ -136,18 +127,11 @@ class Rule: class Everyone(Rule): """Matches Everyone""" - labels = [] - - def name(self): - return 'Everyone' + name = _('Everyone') + category = _('General filters') + description = _('Matches everyone in the database') - def category(self): - return _('General filters') - - def description(self): - return _('Matches everyone in the database') - - def apply(self,db,p_id): + def apply(self,db,handle): return 1 #------------------------------------------------------------------------- @@ -158,20 +142,13 @@ class Everyone(Rule): class Disconnected(Rule): """Matches disconnected people""" - labels = [] - - def name(self): - return 'Disconnected people' - - def category(self): - return _('General filters') - - def description(self): - return _('Matches people that have no family relationships ' + name = _('Disconnected people') + category = _('General filters') + description = _('Matches people that have no family relationships ' 'to any other person in the database') - def apply(self,db,p_id): - person = db.get_person_from_handle(p_id) + def apply(self,db,handle): + person = db.get_person_from_handle(handle) return (not person.get_main_parents_family_handle() and not len(person.get_family_handle_list())) @@ -184,33 +161,27 @@ class RelationshipPathBetween(Rule): """Rule that checks for a person that is a descendant of a specified person not more than N generations away""" - labels = [ _('ID:'), _('ID:') ] - + labels = [ _('ID:'), _('ID:') ] + name = _("Relationship path between ") + category = _('Relationship filters') + description = _("Matches the ancestors of two persons back to a common ancestor, " + "producing the relationship path between two persons.") + def prepare(self,db): self.db = db self.map = {} - root1 = self.list[0] - root2 = self.list[1] - self.init_list(root1,root2) + root1_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + root2_handle = db.get_person_from_gramps_id(self.list[1]).get_handle() + self.init_list(root1_handle,root2_handle) def reset(self): self.map = {} - def name(self): - return "Relationship path between " - - def category(self): - return _('Relationship filters') - - def description(self): - return _("Matches the ancestors of two persons back to a common ancestor, " - "producing the relationship path between two persons.") - - def desc_list(self, p_id, map, first): + def desc_list(self, handle, map, first): if not first: - map[p_id] = 1 + map[handle] = 1 - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) for fam_id in p.get_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) if fam: @@ -218,8 +189,8 @@ class RelationshipPathBetween(Rule): if child_handle: self.desc_list(child_handle,map,0) - def apply_filter(self,rank,p_id,plist,pmap): - person = self.db.get_person_from_handle(p_id) + def apply_filter(self,rank,handle,plist,pmap): + person = self.db.get_person_from_handle(handle) if person == None: return plist.append(person) @@ -231,10 +202,10 @@ class RelationshipPathBetween(Rule): self.apply_filter(rank+1,family.get_father_handle(),plist,pmap) self.apply_filter(rank+1,family.get_mother_handle(),plist,pmap) - def apply(self,db,p_id): - return self.map.has_key(p_id) + def apply(self,db,handle): + return self.map.has_key(handle) - def init_list(self,p1_id,p2_id): + def init_list(self,p1_handle,p2_handle): firstMap = {} firstList = [] secondMap = {} @@ -242,8 +213,8 @@ class RelationshipPathBetween(Rule): common = [] rank = 9999999 - self.apply_filter(0,p1_id,firstList,firstMap) - self.apply_filter(0,p2_id,secondList,secondMap) + self.apply_filter(0,p1_handle,firstList,firstMap) + self.apply_filter(0,p2_handle,secondList,secondMap) for person_handle in firstList: if person_handle in secondList: @@ -254,8 +225,8 @@ class RelationshipPathBetween(Rule): elif new_rank == rank: common.append(person_handle) - path1 = { p1_id : 1} - path2 = { p2_id : 1} + path1 = { p1_handle : 1} + path2 = { p2_handle : 1} for person_handle in common: new_map = {} @@ -283,19 +254,13 @@ class RelationshipPathBetween(Rule): class HasIdOf(Rule): """Rule that checks for a person with a specific GRAMPS ID""" - labels = [ _('ID:') ] - - def name(self): - return 'People with Id:' + labels = [ _('ID:') ] + name = _('People with Id:') + description = _("Matches people with a specified GRAMPS ID") + category = _('General filters') - def description(self): - return _("Matches people with a specified GRAMPS ID") - - def category(self): - return _('General filters') - - def apply(self,db,p_id): - return p_id == self.list[0] + def apply(self,db,handle): + return db.get_person_from_handle(handle).get_gramps_id() == self.list[0] #------------------------------------------------------------------------- # @@ -305,21 +270,14 @@ class HasIdOf(Rule): class IsDefaultPerson(Rule): """Rule that checks for a default person in the database""" - labels = [] - - def name(self): - return 'Default person' + name = _('Default person') + category = _('General filters') + description = _("Matches the default person") - def description(self): - return _("Matches the default person") - - def category(self): - return _('General filters') - - def apply(self,db,p_id): + def apply(self,db,handle): person = db.get_default_person() if person: - return p_id == person.get_handle() + return handle == person.get_handle() return 0 #------------------------------------------------------------------------- @@ -330,19 +288,12 @@ class IsDefaultPerson(Rule): class IsBookmarked(Rule): """Rule that checks for the bookmark list in the database""" - labels = [] - - def name(self): - return 'Bookmarked people' + name = _('Bookmarked people') + category = _('General filters') + description = _("Matches the people on the bookmark list") - def description(self): - return _("Matches the people on the bookmark list") - - def category(self): - return _('General filters') - - def apply(self,db,p_id): - if p_id in db.get_bookmarks(): + def apply(self,db,handle): + if handle in db.get_bookmarks(): return 1 return 0 @@ -354,19 +305,12 @@ class IsBookmarked(Rule): class HasCompleteRecord(Rule): """Rule that checks for a person whose record is complete""" - labels = [] - - def name(self): - return 'People with complete records' + name = _('People with complete records') + category = _('General filters') + description = _('Matches all people whose records are complete') - def category(self): - return _('General filters') - - def description(self): - return _('Matches all people whose records are complete') - - def apply(self,db,p_id): - return db.get_person_from_handle(p_id).get_complete_flag() == 1 + def apply(self,db,handle): + return db.get_person_from_handle(handle).get_complete_flag() == 1 #------------------------------------------------------------------------- # @@ -376,19 +320,12 @@ class HasCompleteRecord(Rule): class IsFemale(Rule): """Rule that checks for a person that is a female""" - labels = [] - - def name(self): - return 'Females' + name = _('Females') + category = _('General filters') + description = _('Matches all females') - def category(self): - return _('General filters') - - def description(self): - return _('Matches all females') - - def apply(self,db,p_id): - return db.get_person_from_handle(p_id).get_gender() == RelLib.Person.FEMALE + def apply(self,db,handle): + return db.get_person_from_handle(handle).get_gender() == RelLib.Person.FEMALE #------------------------------------------------------------------------- # @@ -398,20 +335,12 @@ class IsFemale(Rule): class HasUnknownGender(Rule): """Rule that checks for a person that has unknown gender""" - labels = [] - - def name(self): - return 'People with unknown gender' - - def category(self): - return _('General filters') - - def description(self): - return _('Matches all people with unknown gender') - - def apply(self,db,p_id): - return db.get_person_from_handle(p_id).get_gender() == RelLib.Person.UNKNOWN + name = _('People with unknown gender') + category = _('General filters') + description = _('Matches all people with unknown gender') + def apply(self,db,handle): + return db.get_person_from_handle(handle).get_gender() == RelLib.Person.UNKNOWN #------------------------------------------------------------------------- # @@ -422,12 +351,14 @@ class IsDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person""" - labels = [ _('ID:'), _('Inclusive:') ] - + labels = [ _('ID:'), _('Inclusive:') ] + name = _('Descendants of ') + category = _('Descendant filters') + description = _('Matches all descendants for the specified person') + def prepare(self,db): self.db = db self.map = {} - self.db = db try: if int(self.list[1]): first = 0 @@ -436,31 +367,22 @@ class IsDescendantOf(Rule): except IndexError: first = 1 - root_id = self.list[0] - self.init_list(root_id,first) + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_list(root_handle,first) def reset(self): self.map = {} - def name(self): - return 'Descendants of ' + def apply(self,db,handle): + return self.map.has_key(handle) - def category(self): - return _('Descendant filters') - - def description(self): - return _('Matches all descendants for the specified person') - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_list(self,p_id,first): - if not p_id: + def init_list(self,handle,first): + if not handle: return if not first: - self.map[p_id] = 1 + self.map[handle] = 1 - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) for fam_id in p.get_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) if fam: @@ -476,22 +398,38 @@ class IsDescendantOfFilterMatch(IsDescendantOf): """Rule that checks for a person that is a descendant of someone matched by a filter""" - labels = [ _('Filter name:'), _('Inclusive:') ] + labels = [ _('Filter name:'), _('Inclusive:') ] + name = _('Descendants of match') + category = _('Descendant filters') + description = _("Matches people that are descendants of anybody matched by a filter") + def __init__(self,list): IsDescendantOf.__init__(self,list) - def name(self): - return 'Descendants of match' + def prepare(self,db): + self.db = db + self.map = {} + try: + if int(self.list[1]): + first = 0 + else: + first = 1 + except IndexError: + first = 1 + + filt = MatchesFilter(self.list) + filt.prepare(db) + for person_handle in db.get_person_handles(sort_handles=False): + if filt.apply (db, person_handle): + self.init_list (person_handle,first) + filt.reset() - def category(self): - return _('Descendant filters') + def reset(self): + self.map = {} - def description(self): - return _("Matches people that are descendants of anybody matched by a filter") - - def apply(self,db,p_id): - return self.map.has_key(p_id) + def apply(self,db,handle): + return self.map.has_key(handle) #------------------------------------------------------------------------- # @@ -502,39 +440,33 @@ class IsLessThanNthGenerationDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person not more than N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] - + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Descendants of not more than generations away') + category = _('Descendant filters') + description = _("Matches people that are descendants of a specified person " + "not more than N generations away") + def prepare(self,db): self.db = db self.map = {} - root_id = self.list[0] - self.init_list(root_id,0) + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_list(root_handle,0) def reset(self): self.map = {} - def name(self): - return 'Descendants of not more than generations away' + def apply(self,db,handle): + return self.map.has_key(handle) - def category(self): - return _('Descendant filters') - - def description(self): - return _("Matches people that are descendants of a specified person " - "not more than N generations away") - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_list(self,p_id,gen): - if not p_id: + def init_list(self,handle,gen): + if not handle: return if gen: - self.map[p_id] = 1 + self.map[handle] = 1 if gen >= int(self.list[1]): return - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) for fam_id in p.get_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) for child_handle in fam.get_child_handle_list(): @@ -549,37 +481,32 @@ class IsMoreThanNthGenerationDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person at least N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Descendants of at least generations away') + category = _("Descendant filters") + description = _("Matches people that are descendants of a specified " + "person at least N generations away") + def prepare(self,db): self.db = db self.map = {} - root_id = self.list[0] - self.init_list(root_id,0) + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_list(root_handle,0) def reset(self): self.map = {} - def name(self): - return 'Descendants of at least generations away' + def apply(self,db,handle): + return self.map.has_key(handle) - def description(self): - return _("Matches people that are descendants of a specified " - "person at least N generations away") - - def category(self): - return _("Descendant filters") - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_list(self,p_id,gen): - if not p_id: + def init_list(self,handle,gen): + if not handle: return if gen >= int(self.list[1]): - self.map[p_id] = 1 + self.map[handle] = 1 - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) for fam_id in p.get_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) for child_handle in fam.get_child_handle_list(): @@ -594,7 +521,10 @@ class IsChildOfFilterMatch(Rule): """Rule that checks for a person that is a child of someone matched by a filter""" - labels = [ _('Filter name:') ] + labels = [ _('Filter name:') ] + name = _('Children of match') + category = _('Family filters') + description = _("Matches children of anybody matched by a filter") def prepare(self,db): self.db = db @@ -609,22 +539,13 @@ class IsChildOfFilterMatch(Rule): def reset(self): self.map = {} - def name(self): - return 'Children of match' + def apply(self,db,handle): + return self.map.has_key(handle) - def description(self): - return _("Matches children of anybody matched by a filter") - - def category(self): - return _('Family filters') - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_list(self,p_id): - if not p_id: + def init_list(self,handle): + if not handle: return - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) for fam_id in p.get_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) for child_handle in fam.get_child_handle_list(): @@ -638,7 +559,10 @@ class IsChildOfFilterMatch(Rule): class IsSiblingOfFilterMatch(Rule): """Rule that checks for siblings of someone matched by a filter""" - labels = [ _('Filter name:') ] + labels = [ _('Filter name:') ] + name = _('Siblings of match') + category = _('Family filters') + description = _("Matches siblings of anybody matched by a filter") def prepare(self,db): self.db = db @@ -653,27 +577,18 @@ class IsSiblingOfFilterMatch(Rule): def reset(self): self.map = {} - def name(self): - return 'Siblings of match' + def apply(self,db,handle): + return self.map.has_key(handle) - def description(self): - return _("Matches siblings of anybody matched by a filter") - - def category(self): - return _('Family filters') - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_list(self,p_id): - if not p_id: + def init_list(self,handle): + if not handle: return - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) fam_id = p.get_main_parents_family_handle() fam = self.db.get_family_from_handle(fam_id) if fam: for child_handle in fam.get_child_handle_list(): - if child_handle != p_id: + if child_handle != handle: self.map[child_handle] = 1 #------------------------------------------------------------------------- @@ -685,30 +600,24 @@ class IsDescendantFamilyOf(Rule): """Rule that checks for a person that is a descendant or the spouse of a descendant of a specified person""" - labels = [ _('ID:') ] - - def name(self): - return "Descendant family members of " - - def category(self): - return _('Descendant filters') - - def description(self): - return _("Matches people that are descendants or the spouse " + labels = [ _('ID:') ] + name = _('Descendant family members of ') + category = _('Descendant filters') + description = _("Matches people that are descendants or the spouse " "of a descendant of a specified person") - def apply(self,db,p_id): + def apply(self,db,handle): self.map = {} - self.orig_id = p_id + self.orig_handle = handle self.db = db - return self.search(p_id,1) + return self.search(handle,1) - def search(self,p_id,val): - if p_id == self.list[0]: - self.map[p_id] = 1 + def search(self,handle,val): + if handle == self.db.get_person_from_gramps_id(self.list[0]).get_handle(): + self.map[handle] = 1 return 1 - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) for (f,r1,r2) in p.get_parent_family_handle_list(): family = self.db.get_family_from_handle(f) for person_handle in [family.get_mother_handle(),family.get_father_handle()]: @@ -718,7 +627,7 @@ class IsDescendantFamilyOf(Rule): if val: for family_handle in p.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) - if p_id == family.get_father_handle(): + if handle == family.get_father_handle(): spouse_id = family.get_mother_handle() else: spouse_id = family.get_father_handle() @@ -735,7 +644,10 @@ class IsDescendantFamilyOf(Rule): class IsAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person""" - labels = [ _('ID:'), _('Inclusive:') ] + labels = [ _('ID:'), _('Inclusive:') ] + name = _('Ancestors of ') + category = _("Ancestral filters") + description = _("Matches people that are ancestors of a specified person") def prepare(self,db): """Assume that if 'Inclusive' not defined, assume inclusive""" @@ -748,31 +660,22 @@ class IsAncestorOf(Rule): first = 1 except IndexError: first = 1 - root_id = self.list[0] - self.init_ancestor_list(db,root_id,first) + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_ancestor_list(db,root_handle,first) def reset(self): self.map = {} - - def name(self): - return 'Ancestors of ' - def description(self): - return _("Matches people that are ancestors of a specified person") - - def category(self): - return _("Ancestral filters") + def apply(self,db,handle): + return self.map.has_key(handle) - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_ancestor_list(self,db,p_id,first): - if not p_id: + def init_ancestor_list(self,db,handle,first): + if not handle: return if not first: - self.map[p_id] = 1 + self.map[handle] = 1 - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) fam_id = p.get_main_parents_family_handle() fam = db.get_family_from_handle(fam_id) if fam: @@ -793,7 +696,12 @@ class IsAncestorOfFilterMatch(IsAncestorOf): """Rule that checks for a person that is an ancestor of someone matched by a filter""" - labels = [ _('Filter name:'), _('Inclusive:') ] + labels = [ _('Filter name:'), _('Inclusive:') ] + name = _('Ancestors of match') + category = _("Ancestral filters") + description = _("Matches people that are ancestors " + "of anybody matched by a filter") + def __init__(self,list): IsAncestorOf.__init__(self,list) @@ -819,18 +727,8 @@ class IsAncestorOfFilterMatch(IsAncestorOf): def reset(self): self.map = {} - def name(self): - return 'Ancestors of match' - - def description(self): - return _("Matches people that are ancestors " - "of anybody matched by a filter") - - def category(self): - return _("Ancestral filters") - - def apply(self,db,p_id): - return self.map.has_key(p_id) + def apply(self,db,handle): + return self.map.has_key(handle) #------------------------------------------------------------------------- # @@ -841,41 +739,35 @@ class IsLessThanNthGenerationAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person not more than N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Ancestors of not more than generations away') + category = _("Ancestral filters") + description = _("Matches people that are ancestors " + "of a specified person not more than N generations away") def prepare(self,db): self.db = db self.map = {} - root_id = self.list[0] - self.init_ancestor_list(root_id,0) + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_ancestor_list(root_handle,0) def reset(self): self.map = {} - def name(self): - return 'Ancestors of not more than generations away' + def apply(self,db,handle): + return self.map.has_key(handle) - def description(self): - return _("Matches people that are ancestors " - "of a specified person not more than N generations away") - - def category(self): - return _("Ancestral filters") - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_ancestor_list(self,p_id,gen): + def init_ancestor_list(self,handle,gen): # if self.map.has_key(p.get_handle()) == 1: # loop_error(self.orig,p) - if not p_id: + if not handle: return if gen: - self.map[p_id] = 1 + self.map[handle] = 1 if gen >= int(self.list[1]): return - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) fam_id = p.get_main_parents_family_handle() fam = self.db.get_family_from_handle(fam_id) if fam: @@ -896,39 +788,33 @@ class IsMoreThanNthGenerationAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person at least N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] + labels = [ _('ID:'), _('Number of generations:') ] + name = _('Ancestors of at least generations away') + category = _("Ancestral filters") + description = _("Matches people that are ancestors " + "of a specified person at least N generations away") def prepare(self,db): self.db = db self.map = {} - root_id = self.list[0] - self.init_ancestor_list(root_id,0) + root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + self.init_ancestor_list(root_handle,0) def reset(self): self.map = [] - def name(self): - return 'Ancestors of at least generations away' + def apply(self,db,handle): + return self.map.has_key(handle) - def description(self): - return _("Matches people that are ancestors " - "of a specified person at least N generations away") - - def category(self): - return _("Ancestral filters") - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_ancestor_list(self,p_id,gen): + def init_ancestor_list(self,handle,gen): # if self.map.has_key(p.get_handle()) == 1: # loop_error(self.orig,p) - if not p_id: + if not handle: return if gen >= int(self.list[1]): - self.map[p_id] = 1 + self.map[handle] = 1 - p = self.db.get_person_from_handle(p_id) + p = self.db.get_person_from_handle(handle) fam_id = p.get_main_parents_family_handle() fam = self.db.get_family_from_handle(fam_id) if fam: @@ -949,7 +835,10 @@ class IsParentOfFilterMatch(Rule): """Rule that checks for a person that is a parent of someone matched by a filter""" - labels = [ _('Filter name:') ] + labels = [ _('Filter name:') ] + name = _('Parents of match') + category = _('Family filters') + description = _("Matches parents of anybody matched by a filter") def prepare(self,db): self.db = db @@ -964,20 +853,11 @@ class IsParentOfFilterMatch(Rule): def reset(self): self.map = {} - def name(self): - return 'Parents of match' + def apply(self,db,handle): + return self.map.has_key(handle) - def description(self): - return _("Matches parents of anybody matched by a filter") - - def category(self): - return _('Family filters') - - def apply(self,db,p_id): - return self.map.has_key(p_id) - - def init_list(self,p_id): - p = self.db.get_person_from_handle(p_id) + def init_list(self,handle): + p = self.db.get_person_from_handle(handle) for fam_id,frel,mrel in p.get_parent_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) for parent_id in [fam.get_father_handle (), fam.get_mother_handle ()]: @@ -992,17 +872,11 @@ class IsParentOfFilterMatch(Rule): class HasCommonAncestorWith(Rule): """Rule that checks for a person that has a common ancestor with a specified person""" - labels = [ _('ID:') ] - - def name(self): - return 'People with a common ancestor with ' - - def description(self): - return _("Matches people that have a common ancestor " - "with a specified person") - - def category(self): - return _("Ancestral filters") + labels = [ _('ID:') ] + name = _('People with a common ancestor with ') + category = _("Ancestral filters") + description = _("Matches people that have a common ancestor " + "with a specified person") def prepare(self,db): self.db = db @@ -1017,19 +891,19 @@ class HasCommonAncestorWith(Rule): def init_ancestor_cache(self,db): # list[0] is an Id, but we need to pass a Person to for_each_ancestor. - p_id = self.list[0] - if p_id: - def init(self,pid): self.ancestor_cache[pid] = 1 - for_each_ancestor(db,[p_id],init,self) + handle = db.get_person_from_gramps_id(self.list[0]).get_handle() + if handle: + def init(self,handle): self.ancestor_cache[handle] = 1 + for_each_ancestor(db,[handle],init,self) - def apply(self,db,p_id): + def apply(self,db,handle): # On the first call, we build the ancestor cache for the # reference person. Then, for each person to test, # we browse his ancestors until we found one in the cache. if len(self.ancestor_cache) == 0: self.init_ancestor_cache(db) - return for_each_ancestor(db,[p_id], - lambda self,p_id: self.ancestor_cache.has_key(p_id), + return for_each_ancestor(db,[handle], + lambda self,handle: self.ancestor_cache.has_key(handle), self); #------------------------------------------------------------------------- @@ -1041,17 +915,11 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): """Rule that checks for a person that has a common ancestor with someone matching a filter""" - labels = [ _('Filter name:') ] - - def name(self): - return 'People with a common ancestor with match' - - def description(self): - return _("Matches people that have a common ancestor " - "with anybody matched by a filter") - - def category(self): - return _("Ancestral filters") + labels = [ _('Filter name:') ] + name = _('People with a common ancestor with match') + description = _("Matches people that have a common ancestor " + "with anybody matched by a filter") + category = _("Ancestral filters") def __init__(self,list): HasCommonAncestorWith.__init__(self,list) @@ -1059,11 +927,11 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): def init_ancestor_cache(self,db): filt = MatchesFilter(self.list) filt.prepare(db) - def init(self,pid): self.ancestor_cache[pid] = 1 - for p_id in db.get_person_handles(sort_handles=False): - if (not self.ancestor_cache.has_key (p_id) - and filt.apply (db, p_id)): - for_each_ancestor(db,[p_id],init,self) + def init(self,h): self.ancestor_cache[h] = 1 + for handle in db.get_person_handles(sort_handles=False): + if (not self.ancestor_cache.has_key (handle) + and filt.apply (db, handle)): + for_each_ancestor(db,[handle],init,self) filt.reset() #------------------------------------------------------------------------- @@ -1074,19 +942,12 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): class IsMale(Rule): """Rule that checks for a person that is a male""" - labels = [] - - def name(self): - return 'Males' + name = _('Males') + category = _('General filters') + description = _('Matches all males') - def category(self): - return _('General filters') - - def description(self): - return _('Matches all males') - - def apply(self,db,p_id): - return db.get_person_from_handle(p_id).get_gender() == RelLib.Person.MALE + def apply(self,db,handle): + return db.get_person_from_handle(handle).get_gender() == RelLib.Person.MALE #------------------------------------------------------------------------- # @@ -1096,7 +957,13 @@ class IsMale(Rule): class HasEvent(Rule): """Rule that checks for a person with a particular value""" - labels = [ _('Personal event:'), _('Date:'), _('Place:'), _('Description:') ] + labels = [ _('Personal event:'), + _('Date:'), + _('Place:'), + _('Description:') ] + name = _('People with the personal event:') + description = _("Matches people with a personal event of a particular value") + category = _('Event filters') def prepare(self,list): self.date = None @@ -1105,17 +972,8 @@ class HasEvent(Rule): self.date = DateHandler.parser.parse(self.list[1]) except: pass - def name(self): - return 'People with the personal event:' - - def description(self): - return _("Matches people with a personal event of a particular value") - - def category(self): - return _('Event filters') - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for event_handle in p.get_event_list(): if not event_handle: continue @@ -1149,7 +1007,13 @@ class HasFamilyEvent(Rule): """Rule that checks for a person who has a relationship event with a particular value""" - labels = [ _('Family event:'), _('Date:'), _('Place:'), _('Description:') ] + labels = [ _('Family event:'), + _('Date:'), + _('Place:'), + _('Description:') ] + name = _('People with the family event:') + description = _("Matches people with a family event of a particular value") + category = _('Event filters') def prepare(self,list): self.date = None @@ -1158,17 +1022,8 @@ class HasFamilyEvent(Rule): self.date = DateHandler.parser.parse(self.list[1]) except: pass - def name(self): - return 'People with the family event:' - - def description(self): - return _("Matches people with a family event of a particular value") - - def category(self): - return _('Event filters') - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for f_id in p.get_family_handle_list(): f = db.get_family_from_handle(f_id) for event_handle in f.get_event_list(): @@ -1202,23 +1057,17 @@ class HasFamilyEvent(Rule): class HasRelationship(Rule): """Rule that checks for a person who has a particular relationship""" - labels = [ _('Number of relationships:'), - _('Relationship type:'), - _('Number of children:') ] + labels = [ _('Number of relationships:'), + _('Relationship type:'), + _('Number of children:') ] + name = _('People with the relationships:') + description = _("Matches people with a particular relationship") + category = _('Family filters') - def name(self): - return 'People with the relationships:' - - def description(self): - return _("Matches people with a particular relationship") - - def category(self): - return _('Family filters') - - def apply(self,db,p_id): + def apply(self,db,handle): rel_type = 0 cnt = 0 - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) num_rel = len(p.get_family_handle_list()) # count children and look for a relationship type match @@ -1260,7 +1109,10 @@ class HasRelationship(Rule): class HasBirth(Rule): """Rule that checks for a person with a birth of a particular value""" - labels = [ _('Date:'), _('Place:'), _('Description:') ] + labels = [ _('Date:'), _('Place:'), _('Description:') ] + name = _('People with the birth data:') + description = _("Matches people with birth data of a particular value") + category = _('Event filters') def __init__(self,list): Rule.__init__(self,list) @@ -1269,17 +1121,8 @@ class HasBirth(Rule): else: self.date = None - def name(self): - return 'People with the birth data:' - - def description(self): - return _("Matches people with birth data of a particular value") - - def category(self): - return _('Event filters') - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) event_handle = p.get_birth_handle() if not event_handle: return False @@ -1306,7 +1149,10 @@ class HasBirth(Rule): class HasDeath(Rule): """Rule that checks for a person with a death of a particular value""" - labels = [ _('Date:'), _('Place:'), _('Description:') ] + labels = [ _('Date:'), _('Place:'), _('Description:') ] + name = _('People with the death data:') + description = _("Matches people with death data of a particular value") + category = _('Event filters') def __init__(self,list): Rule.__init__(self,list) @@ -1315,17 +1161,8 @@ class HasDeath(Rule): else: self.date = None - def name(self): - return 'People with the death data:' - - def description(self): - return _("Matches the person with death data of a particular value") - - def category(self): - return _('Event filters') - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) event_handle = p.get_death_handle() if not event_handle: return 0 @@ -1352,15 +1189,15 @@ class HasDeath(Rule): class HasAttribute(Rule): """Rule that checks for a person with a particular personal attribute""" - labels = [ _('Personal attribute:'), _('Value:') ] - - def name(self): - return 'People with the personal attribute:' + labels = [ _('Personal attribute:'), _('Value:') ] + name = _('People with the personal attribute:') + description = _("Matches people with the personal attribute of a particular value") + category = _('General filters') - def apply(self,db,p_id): + def apply(self,db,handle): if not self.list[0]: return 0 - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) for attr in p.get_attribute_list(): name_match = self.list[0] == attr.get_type() value_match = \ @@ -1377,15 +1214,15 @@ class HasAttribute(Rule): class HasFamilyAttribute(Rule): """Rule that checks for a person with a particular family attribute""" - labels = [ _('Family attribute:'), _('Value:') ] + labels = [ _('Family attribute:'), _('Value:') ] + name = _('People with the family attribute:') + description = _("Matches people with the family attribute of a particular value") + category = _('General filters') - def name(self): - return 'People with the family attribute:' - - def apply(self,db,p_id): + def apply(self,db,handle): if not self.list[0]: return 0 - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) for f_id in p.get_family_handle_list(): f = db.get_family_from_handle(f_id) for attr in f.get_attribute_list(): @@ -1404,23 +1241,20 @@ class HasFamilyAttribute(Rule): class HasNameOf(Rule): """Rule that checks for full or partial name matches""" - labels = [_('Given name:'),_('Family name:'),_('Suffix:'),_('Title:')] - - def name(self): - return 'People with the name:' - - def description(self): - return _("Matches people with a specified (partial) name") + labels = [ _('Given name:'), + _('Family name:'), + _('Suffix:'), + _('Title:')] + name = _('People with the name:') + description = _("Matches people with a specified (partial) name") + category = _('General filters') - def category(self): - return _('General filters') - - def apply(self,db,p_id): + def apply(self,db,handle): self.f = self.list[0] self.l = self.list[1] self.s = self.list[2] self.t = self.list[3] - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) for name in [p.get_primary_name()] + p.get_alternate_names(): val = 1 if self.f and name.get_first_name().upper().find(self.f.upper()) == -1: @@ -1443,20 +1277,14 @@ class HasNameOf(Rule): class SearchName(Rule): """Rule that checks for full or partial name matches""" - labels = [_('Substring:')] - - def name(self): - return 'People matching the ' - - def description(self): - return _("Matches people with a specified (partial) name") + labels = [_('Substring:')] + name = _('People matching the ') + description = _("Matches people with a specified (partial) name") + category = _('General filters') - def category(self): - return _('General filters') - - def apply(self,db,p_id): + def apply(self,db,handle): self.f = self.list[0] - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) n = NameDisplay.displayer.display(p) return self.f and n.upper().find(self.f.upper()) != -1 @@ -1468,19 +1296,12 @@ class SearchName(Rule): class IncompleteNames(Rule): """People with incomplete names""" - labels = [] - - def name(self): - return 'People with incomplete names' - - def description(self): - return _("Matches people with firstname or lastname missing") + name = _('People with incomplete names') + description = _("Matches people with firstname or lastname missing") + category = _('General filters') - def category(self): - return _('General filters') - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for name in [p.get_primary_name()] + p.get_alternate_names(): if name.get_first_name() == "": return 1 @@ -1496,7 +1317,10 @@ class IncompleteNames(Rule): class MatchesFilter(Rule): """Rule that checks against another filter""" - labels = [_('Filter name:')] + labels = [_('Filter name:')] + name = _('People matching the ') + description = _("Matches people macthed by the specified filter name") + category = _('General filters') def prepare(self,db): for filt in SystemFilters.get_filters(): @@ -1518,16 +1342,13 @@ class MatchesFilter(Rule): for rule in filt.flist: rule.reset() - def name(self): - return 'People matching the ' - - def apply(self,db,p_id): + def apply(self,db,handle): for filt in SystemFilters.get_filters(): if filt.get_name() == self.list[0]: - return filt.check(p_id) + return filt.check(handle) for filt in CustomFilters.get_filters(): if filt.get_name() == self.list[0]: - return filt.check(db,p_id) + return filt.check(db,handle) return 0 #------------------------------------------------------------------------- @@ -1539,26 +1360,20 @@ class IsSpouseOfFilterMatch(Rule): """Rule that checks for a person married to someone matching a filter""" - labels = [_('Filter name:')] + labels = [_('Filter name:')] + name = _('Spouses of match') + description = _("Matches people married to anybody matching a filter") + category = _('Family filters') - def name(self): - return 'Spouses of match' - - def description(self): - return _("Matches people married to anybody matching a filter") - - def category(self): - return _('Family filters') - - def apply(self,db,p_id): + def apply(self,db,handle): filt = MatchesFilter (self.list) - p = db.get_person_from_handle(p_id) + p = db.get_person_from_handle(handle) for family_handle in p.get_family_handle_list (): family = db.get_family_from_handle(family_handle) for spouse_id in [family.get_father_handle (), family.get_mother_handle ()]: if not spouse_id: continue - if spouse_id == p_id: + if spouse_id == handle: continue if filt.apply (db, spouse_id): return 1 @@ -1567,25 +1382,15 @@ class IsSpouseOfFilterMatch(Rule): #------------------------------------------------------------------------- # "People who were adopted" #------------------------------------------------------------------------- - - class HaveAltFamilies(Rule): """People who were adopted""" - labels = [] + name = _('Adopted people') + description = _("Matches people who were adopted") + category = _('Family filters') - def name(self): - return 'Adopted people' - - def description(self): - return _("Matches people who were adopted") - - def category(self): - return _('Family filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for (fam,rel1,rel2) in p.get_parent_family_handle_list(): if rel1 == RelLib.Person.CHILD_REL_ADOPT or rel2 == RelLib.Person.CHILD_REL_ADOPT: return 1 @@ -1595,49 +1400,29 @@ class HaveAltFamilies(Rule): #------------------------------------------------------------------------- # "People who have images" #------------------------------------------------------------------------- - - class HavePhotos(Rule): """People who have images""" - labels = [] + name = _('People with images') + description = _("Matches people with images in the gallery") + category = _('General filters') - def name(self): - return 'People with images' - - def description(self): - return _("Matches people with images in the gallery") - - def category(self): - return _('General filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) return len( p.get_media_list()) > 0 #------------------------------------------------------------------------- # "People with children" #------------------------------------------------------------------------- - - class HaveChildren(Rule): """People with children""" - labels = [] + name = _('People with children') + description = _("Matches people who have children") + category = _('Family filters') - def name(self): - return 'People with children' - - def description(self): - return _("Matches people who have children") - - def category(self): - return _('Family filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for family_handle in p.get_family_handle_list(): family = db.get_family_from_handle(family_handle) return len(family.get_child_handle_list()) > 0 @@ -1645,73 +1430,43 @@ class HaveChildren(Rule): #------------------------------------------------------------------------- # "People with no marriage records" #------------------------------------------------------------------------- - - class NeverMarried(Rule): """People with no marriage records""" - labels = [] + name = _('People with no marriage records') + description = _("Matches people who have no spouse") + category = _('Family filters') - def name(self): - return 'People with no marriage records' - - def description(self): - return _("Matches people who have no spouse") - - def category(self): - return _('Family filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) return len(p.get_family_handle_list()) == 0 #------------------------------------------------------------------------- # "People with multiple marriage records" #------------------------------------------------------------------------- - - class MultipleMarriages(Rule): """People with multiple marriage records""" - labels = [] + name = _('People with multiple marriage records') + description = _("Matches people who have more than one spouse") + category = _('Family filters') - def name(self): - return 'People with multiple marriage records' - - def description(self): - return _("Matches people who have more than one spouse") - - def category(self): - return _('Family filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) return len(p.get_family_handle_list()) > 1 #------------------------------------------------------------------------- # "People without a birth date" #------------------------------------------------------------------------- - - class NoBirthdate(Rule): """People without a birth date""" - labels = [] + name = _('People without a known birth date') + description = _("Matches people without a known birthdate") + category = _('General filters') - def name(self): - return 'People without a known birth date' - - def description(self): - return _("Matches people without a known birthdate") - - def category(self): - return _('General filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) birth_handle = p.get_birth_handle() if not birth_handle: return 1 @@ -1723,25 +1478,15 @@ class NoBirthdate(Rule): #------------------------------------------------------------------------- # "People with incomplete events" #------------------------------------------------------------------------- - - class PersonWithIncompleteEvent(Rule): """People with incomplete events""" - labels = [] + name = _('People with incomplete events') + description = _("Matches people with missing date or place in an event") + category = _('Event filters') - def name(self): - return 'People with incomplete events' - - def description(self): - return _("Matches people with missing date or place in an event") - - def category(self): - return _('Event filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for event_handle in p.get_event_list() + [p.get_birth_handle(), p.get_death_handle()]: event = db.get_event_from_handle(event_handle) if event: @@ -1754,25 +1499,15 @@ class PersonWithIncompleteEvent(Rule): #------------------------------------------------------------------------- # "Families with incomplete events" #------------------------------------------------------------------------- - - class FamilyWithIncompleteEvent(Rule): """Families with incomplete events""" - labels = [] + name = _('Families with incomplete events') + description = _("Matches people with missing date or place in an event of the family") + category = _('Event filters') - def name(self): - return 'Families with incomplete events' - - def description(self): - return _("Matches people with missing date or place in an event of the family") - - def category(self): - return _('Event filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) for family_handle in p.get_family_handle_list(): family = db.get_family_from_handle(family_handle) for event_handle in family.get_event_list(): @@ -1784,16 +1519,16 @@ class FamilyWithIncompleteEvent(Rule): return 1 return 0 - #------------------------------------------------------------------------- # "People probably alive" #------------------------------------------------------------------------- - - class ProbablyAlive(Rule): """People probably alive""" - labels = [_("On year:")] + labels = [_("On year:")] + name = _('People probably alive') + description = _("Matches people without indications of death that are not too old") + category = _('General filters') def prepare(self,db): try: @@ -1801,53 +1536,34 @@ class ProbablyAlive(Rule): except: self.current_year = None - def name(self): - return 'People probably alive' - - def description(self): - return _("Matches people without indications of death that are not too old") - - def category(self): - return _('General filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) return probably_alive(p,db,self.current_year) #------------------------------------------------------------------------- # "People marked private" #------------------------------------------------------------------------- - - class PeoplePrivate(Rule): """People marked private""" - labels = [] + name = _('People marked private') + description = _("Matches people that are indicated as private") + category = _('General filters') - def name(self): - return 'People marked private' - - def description(self): - return _("Matches people that are indicated as private") - - def category(self): - return _('General filters') - - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) return p.get_privacy() #------------------------------------------------------------------------- # "Witnesses" #------------------------------------------------------------------------- - - class IsWitness(Rule): """Witnesses""" - labels = [_('Personal event:'), _('Family event:')] + labels = [_('Personal event:'), _('Family event:')] + name = _('Witnesses') + description = _("Matches people who are witnesses in any event") + category = _('Event filters') def prepare(self,db): self.db = db @@ -1857,17 +1573,8 @@ class IsWitness(Rule): def reset(self): self.map = [] - def name(self): - return 'Witnesses' - - def description(self): - return _("Matches people who are witnesses in any event") - - def category(self): - return _('Event filters') - - def apply(self,db,p_id): - return p_id in self.map + def apply(self,db,handle): + return handle in self.map def build_witness_list(self): event_type = None @@ -1904,11 +1611,15 @@ class IsWitness(Rule): #------------------------------------------------------------------------- # "HasTextMatchingSubstringOf" #------------------------------------------------------------------------- - class HasTextMatchingSubstringOf(Rule): """Rule that checks for string matches in any textual information""" - labels = [_('Substring:'), _('Case sensitive:'), _('Regular-Expression matching:')] + labels = [ _('Substring:'), + _('Case sensitive:'), + _('Regular-Expression matching:')] + name = _('People with records containing the substring:') + description = _("Matches people whose records contain text matching a substring") + category = _('General filters') def prepare(self,db): self.db = db @@ -1942,23 +1653,14 @@ class HasTextMatchingSubstringOf(Rule): self.place_map = {} self.media_map = {} - def name(self): - return 'People with records containing the substring:' - - def description(self): - return _("Matches people whose records contain text matching a substring") - - def category(self): - 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 self.match_object(p): # first match the person itself + def apply(self,db,handle): + if handle in self.person_map: # Cached by matching Source? + return self.person_map[handle] + p = db.get_person_from_handle(handle) + 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 + 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): @@ -2072,7 +1774,6 @@ class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): self.regexp_match = True self.cache_sources() - #------------------------------------------------------------------------- # # HasSourceOf @@ -2081,26 +1782,19 @@ class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): class HasSourceOf(Rule): """Rule that checks people that have a particular source.""" - labels = [ _('Source ID:') ] + labels = [ _('Source ID:') ] + name = _('People with the source:') + category = _('General filters') + description = _('Matches people who have a particular source') def prepare(self,db): self.source_handle = db.get_source_from_gramps_id(self.list[0]).get_handle() - def name(self): - return 'People with the source:' - - def category(self): - return _('Event filters') - - def description(self): - return _('Matches people who have a particular source') - - def apply(self,db,p_id): - p = db.get_person_from_handle(p_id) + def apply(self,db,handle): + p = db.get_person_from_handle(handle) return p.has_source_reference( self.source_handle) - #------------------------------------------------------------------------- # # GenericFilter @@ -2166,10 +1860,10 @@ class GenericFilter: def get_rules(self): return self.flist - def check_or(self,db,p_id): + def check_or(self,db,handle): test = 0 for rule in self.flist: - test = test or rule.apply(db,p_id) + test = test or rule.apply(db,handle) if test: break if self.invert: @@ -2177,20 +1871,20 @@ class GenericFilter: else: return test - def check_xor(self,db,p_id): + def check_xor(self,db,handle): test = 0 for rule in self.flist: - temp = rule.apply(db,p_id) + temp = rule.apply(db,handle) test = ((not test) and temp) or (test and (not temp)) if self.invert: return not test else: return test - def check_one(self,db,p_id): + def check_one(self,db,handle): count = 0 for rule in self.flist: - if rule.apply(db,p_id): + if rule.apply(db,handle): count = count + 1 if count > 1: break @@ -2199,10 +1893,10 @@ class GenericFilter: else: return count == 1 - def check_and(self,db,p_id): + def check_and(self,db,handle): test = 1 for rule in self.flist: - test = test and rule.apply(db,p_id) + test = test and rule.apply(db,handle) if not test: break if self.invert: @@ -2217,17 +1911,17 @@ class GenericFilter: m = self.check_and return m - def check(self,db,p_id): - return self.get_check_func()(db,p_id) + def check(self,db,handle): + return self.get_check_func()(db,handle) def apply(self,db,id_list): m = self.get_check_func() res = [] for rule in self.flist: rule.prepare(db) - for p_id in id_list: - if m(db,p_id): - res.append(p_id) + for handle in id_list: + if m(db,handle): + res.append(handle) for rule in self.flist: rule.reset() return res @@ -2240,108 +1934,108 @@ class GenericFilter: #------------------------------------------------------------------------- # This dict is mapping from old names to new names, so that the existing # custom_filters.xml will continue working -old2new = { - "Is default person" : "Default person", - "Has the Id" : "People with Id:", - "Is bookmarked person" : "Bookmarked people", - "Has a name" : "People with the name:", - "Has the relationships" : "People with the relationships:", - "Has the death" : "People with the death data:", - "Has the birth" : "People with the birth data:", - "Is a descendant of" : "Descendants of ", - "Is a descendant family member of" : "Descendant family members of ", - "Is a descendant of filter match": "Descendants of match", +old_names_2_class = { + "Everyone" : Everyone, + "Is default person" : IsDefaultPerson, + "Is bookmarked person" : IsBookmarked, + "Has the Id" : HasIdOf, + "Has a name" : HasNameOf, + "Has the relationships" : HasRelationship, + "Has the death" : HasDeath, + "Has the birth" : HasBirth, + "Is a descendant of" : IsDescendantOf, + "Is a descendant family member of" : IsDescendantFamilyOf, + "Is a descendant of filter match": IsDescendantOfFilterMatch, "Is a descendant of person not more than N generations away": - "Descendants of not more than generations away", - "Is an ancestor of person at least N generations away" : - "Ancestors of at least generations away", - "Is a child of filter match" : "Children of match", - "Is an ancestor of" : "Ancestors of ", - "Is an ancestor of filter match":"Ancestors of match", + IsLessThanNthGenerationDescendantOf, + "Is an descendant of person at least N generations away" : + IsMoreThanNthGenerationDescendantOf, + "Is a child of filter match" : IsChildOfFilterMatch, + "Is an ancestor of" : IsAncestorOf, + "Is an ancestor of filter match": IsAncestorOfFilterMatch, "Is an ancestor of person not more than N generations away" : - "Ancestors of not more than generations away", + IsLessThanNthGenerationAncestorOf, "Is an ancestor of person at least N generations away": - "Ancestors of at least generations away", - "Is a parent of filter match" : "Parents of match", - "Has a common ancestor with" : - "People with a common ancestor with ", - "Has a common ancestor with filter match" : - "People with a common ancestor with match", - "Is a female" : "Females", - "Is a male" : "Males", - "Has complete record" : "People with complete records", - "Has the personal event" : "People with the personal event:", - "Has the family event" : "People with the family event:", - "Has the personal attribute" : "People with the personal attribute:", - "Has the family attribute" : "People with the family attribute:", - "Has source of" : "People with the source:", - "Matches the filter named" : "People matching the ", - "Is spouse of filter match" : "Spouses of match", - "Is a sibling of filter match" : "Siblings of match", - "Relationship path between two people" : "Relationship path between ", - "Adopted people" : "People who were adopted", - "People who have images" : "People with images", - "People without a birth date" : "People without a known birth date", - "Families with incomplete events" :"People with incomplete events", - "Has text matching substring of" :"People with records containing the substring:", + IsMoreThanNthGenerationAncestorOf, + "Is a parent of filter match" : IsParentOfFilterMatch, + "Has a common ancestor with" : HasCommonAncestorWith, + "Has a common ancestor with filter match" :HasCommonAncestorWithFilterMatch, + "Is a female" : IsFemale, + "Is a male" : IsMale, + "Has complete record" : HasCompleteRecord, + "Has the personal event" : HasEvent, + "Has the family event" : HasFamilyEvent, + "Has the personal attribute" : HasAttribute, + "Has the family attribute" : HasFamilyAttribute, + "Has source of" : HasSourceOf, + "Matches the filter named" : HasSourceOf, + "Is spouse of filter match" : IsSpouseOfFilterMatch, + "Is a sibling of filter match" : IsSiblingOfFilterMatch, + "Relationship path between two people" : RelationshipPathBetween, + "People who were adopted" : HaveAltFamilies, + "People who have images" : HavePhotos, + "People with children" : HaveChildren, + "People with incomplete names" : IncompleteNames, + "People with no marriage records" : NeverMarried, + "People with multiple marriage records": MultipleMarriages, + "People without a birth date" : NoBirthdate, + "People with incomplete events" : PersonWithIncompleteEvent, + "Families with incomplete events" :FamilyWithIncompleteEvent, + "People probably alive" : ProbablyAlive, + "People marked private" : PeoplePrivate, + "Witnesses" : IsWitness, + "Has text matching substring of":HasTextMatchingSubstringOf, } -tasks = { - unicode(_("Everyone")) : Everyone, - unicode(_("Default person")) : IsDefaultPerson, - unicode(_("Bookmarked people")) : IsBookmarked, - unicode(_("People with Id:")) : HasIdOf, - unicode(_("People with the name:")) : HasNameOf, - unicode(_("People with the relationships:")) : HasRelationship, - unicode(_("People with the death data:")) : HasDeath, - unicode(_("People with the birth data:")) : HasBirth, - unicode(_("Descendants of ")) : IsDescendantOf, - unicode(_("Descendant family members of ")) : IsDescendantFamilyOf, - unicode(_("Descendants of match")) : IsDescendantOfFilterMatch, - unicode(_("Descendants of not more than generations away")) - : IsLessThanNthGenerationDescendantOf, - unicode(_("Ancestors of at least generations away")) - : IsMoreThanNthGenerationDescendantOf, - unicode(_("Children of match")) : IsChildOfFilterMatch, - unicode(_("Ancestors of ")) : IsAncestorOf, - unicode(_("Ancestors of match")) : IsAncestorOfFilterMatch, - unicode(_("Ancestors of not more than generations away")) - : IsLessThanNthGenerationAncestorOf, - unicode(_("Ancestors of at least generations away")) - : IsMoreThanNthGenerationAncestorOf, - unicode(_("Parents of match")) : IsParentOfFilterMatch, - unicode(_("People with a common ancestor with ")) : HasCommonAncestorWith, - unicode(_("People with a common ancestor with match")) - : HasCommonAncestorWithFilterMatch, - unicode(_("Females")) : IsFemale, - unicode(_("People with unknown gender")) : HasUnknownGender, - unicode(_("Males")) : IsMale, - unicode(_("People with complete records")) : HasCompleteRecord, - unicode(_("People with the personal event:")) : HasEvent, - unicode(_("People with the family event:")) : HasFamilyEvent, - unicode(_("People with the personal attribute:")) : HasAttribute, - unicode(_("People with the family attribute:")) : HasFamilyAttribute, - unicode(_("People with the source:")) : HasSourceOf, - unicode(_("People matching the ")) : MatchesFilter, - unicode(_("Spouses of match")) : IsSpouseOfFilterMatch, - unicode(_("Siblings of match")) : IsSiblingOfFilterMatch, - unicode(_("Relationship path between ")) : RelationshipPathBetween, - - unicode(_("Adopted people")) : HaveAltFamilies, - unicode(_("People with images")) : HavePhotos, - unicode(_("People with children")) : HaveChildren, - unicode(_("People with incomplete names")) : IncompleteNames, - unicode(_("People with no marriage records")) : NeverMarried, - unicode(_("People with multiple marriage records")): MultipleMarriages, - unicode(_("People without a known birth date")) : NoBirthdate, - unicode(_("People with incomplete events")) : PersonWithIncompleteEvent, - unicode(_("Families with incomplete events")) : FamilyWithIncompleteEvent, - unicode(_("People probably alive")) : ProbablyAlive, - unicode(_("People marked private")) : PeoplePrivate, - unicode(_("Witnesses")) : IsWitness, - - unicode(_("People with records containing the substring:")) : HasTextMatchingSubstringOf, -} +editor_rule_list = [ + Everyone, + IsFemale, + HasUnknownGender, + IsMale, + IsDefaultPerson, + IsBookmarked, + HasIdOf, + HasNameOf, + HasRelationship, + HasDeath, + HasBirth, + HasCompleteRecord, + HasEvent, + HasFamilyEvent, + HasAttribute, + HasFamilyAttribute, + HasSourceOf, + HaveAltFamilies, + HavePhotos, + HaveChildren, + IncompleteNames, + NeverMarried, + MultipleMarriages, + NoBirthdate, + PersonWithIncompleteEvent, + FamilyWithIncompleteEvent, + ProbablyAlive, + PeoplePrivate, + IsWitness, + IsDescendantOf, + IsDescendantFamilyOf, + IsDescendantOfFilterMatch, + IsLessThanNthGenerationDescendantOf, + IsMoreThanNthGenerationDescendantOf, + IsAncestorOf, + IsAncestorOfFilterMatch, + IsLessThanNthGenerationAncestorOf, + IsMoreThanNthGenerationAncestorOf, + HasCommonAncestorWith, + HasCommonAncestorWithFilterMatch, + MatchesFilter, + IsChildOfFilterMatch, + IsParentOfFilterMatch, + IsSpouseOfFilterMatch, + IsSiblingOfFilterMatch, + RelationshipPathBetween, + HasTextMatchingSubstringOf, +] #------------------------------------------------------------------------- # @@ -2397,7 +2091,10 @@ class GenericFilterList: f.write(' comment="%s"' % self.fix(comment)) f.write('>\n') for rule in i.get_rules(): - f.write(' \n' % self.fix(rule.name())) + rule_module_name = rule.__module__ + rule_class_name = rule.__class__.__name__ + rule_save_name = "%s.%s" % (rule_module_name,rule_class_name) + f.write(' \n' % rule_save_name) for v in rule.values(): f.write(' \n' % self.fix(v)) f.write(' \n') @@ -2446,21 +2143,26 @@ class FilterParser(handler.ContentHandler): pass self.gfilter_list.add(self.f) elif tag == "rule": - cname = attrs['class'] - if cname in old2new: - cname = old2new[cname] - name = unicode(_(cname)) - self.a = [] - if name in tasks: - self.cname = tasks[name] + save_name = attrs['class'] + if save_name in old_names_2_class.keys(): + self.r = old_names_2_class[save_name] else: - print "ERROR: Filter rule '%s' in filter '%s' not found!" % (name,self.f.get_name()) + module_name,class_name = save_name.split('.') + if class_name not in [item.__name__ for item in editor_rule_list]: + print "ERROR: Filter rule '%s' in filter '%s' not found!" % ( + class_name,self.f.get_name()) + if module_name == self.__module__: + exec 'self.r = %s' % class_name + else: + exec 'import %s' % module_name + exec 'self.r = %s.%s' % (module_name,class_name) + self.a = [] elif tag == "arg": self.a.append(attrs['value']) def endElement(self,tag): if tag == "rule": - rule = self.cname(self.a) + rule = self.r(self.a) self.f.add_rule(rule) def characters(self, data): diff --git a/gramps2/src/plugins/FilterEditor.py b/gramps2/src/plugins/FilterEditor.py index cf138d967..cd637ebe9 100644 --- a/gramps2/src/plugins/FilterEditor.py +++ b/gramps2/src/plugins/FilterEditor.py @@ -65,6 +65,14 @@ _menulist = { _('Relationship type:') : const.family_relations, } +#------------------------------------------------------------------------- +# +# Sorting function for the filter rules +# +#------------------------------------------------------------------------- +def by_rule_name(f,s): + return cmp(f.name,s.name) + #------------------------------------------------------------------------- # # MyBoolean - check button with standard interface @@ -213,7 +221,7 @@ class MyID(gtk.HBox): if val == None: self.set_text('') else: - self.set_text(val.get_handle()) + self.set_text(val.get_gramps_id()) def get_text(self): return unicode(self.entry.get_text()) @@ -550,7 +558,7 @@ class EditFilter: def draw_rules(self): self.rlist.clear() for r in self.filter.get_rules(): - self.rlist.add([r.trans_name(),r.display_values()],r) + self.rlist.add([r.name,r.display_values()],r) def on_ok_clicked(self,obj): n = unicode(self.fname.get_text()).strip() @@ -636,26 +644,21 @@ class EditRule: self.valuebox.add(self.notebook) self.page_num = 0 self.page = [] - self.name2page = {} + self.class2page = {} the_map = {} - the_list = [] - keylist = GenericFilter.tasks.keys() - keylist.sort() - for name in keylist: - cname = GenericFilter.tasks[name] - arglist = cname.labels + for class_obj in GenericFilter.editor_rule_list: + arglist = class_obj.labels vallist = [] tlist = [] - self.page.append((name,cname,vallist,tlist)) + self.page.append((class_obj,vallist,tlist)) pos = 0 - l2 = gtk.Label(name) + l2 = gtk.Label(class_obj.name) l2.set_alignment(0,0.5) l2.show() c = gtk.TreeView() c.set_data('d',pos) c.show() - the_list.append(c) - the_map[name] = c + the_map[class_obj] = c # Only add a table with parameters if there are any parameters if arglist: table = gtk.Table(3,len(arglist)) @@ -698,11 +701,11 @@ class EditRule: table.attach(l,1,2,pos,pos+1,gtk.FILL,0,5,5) table.attach(t,2,3,pos,pos+1,gtk.EXPAND|gtk.FILL,0,5,5) pos = pos + 1 - self.notebook.append_page(table,gtk.Label(name)) - self.name2page[name] = self.page_num + self.notebook.append_page(table,gtk.Label(class_obj.name)) + self.class2page[class_obj] = self.page_num self.page_num = self.page_num + 1 self.page_num = 0 - self.store = gtk.TreeStore(gobject.TYPE_STRING) + self.store = gtk.TreeStore(gobject.TYPE_STRING,gobject.TYPE_PYOBJECT) self.selection = self.rname.get_selection() col = gtk.TreeViewColumn(_('Rule Name'),gtk.CellRendererText(),text=0) self.rname.append_column(col) @@ -719,17 +722,16 @@ class EditRule: # sel_node = None if self.active_rule: - self.sel_name = unicode(_(self.active_rule.name())) + self.sel_class = self.active_rule.__class__ else: - self.sel_name = "" + self.sel_class = None keys = the_map.keys() - keys.sort() + keys.sort(by_rule_name) keys.reverse() catlist = [] - for v in keys: - the_filter = GenericFilter.tasks[v]([None]) - category = the_filter.category() + for class_obj in keys: + category = class_obj.category if category not in catlist: catlist.append(category) catlist.sort() @@ -738,29 +740,28 @@ class EditRule: top_node[category] = self.store.insert_after(None,last_top) top_level[category] = [] last_top = top_node[category] - self.store.set(last_top,0,category) + self.store.set(last_top,0,category,1,None) - for v in keys: - the_filter = GenericFilter.tasks[v]([None]) - category = the_filter.category() - top_level[category].append(v) + for class_obj in keys: + category = class_obj.category + top_level[category].append(class_obj.name) node = self.store.insert_after(top_node[category],prev) - self.store.set(node,0,v) + self.store.set(node,0,class_obj.name,1,class_obj) # # if this is an edit rule, save the node - if v == self.sel_name: + if class_obj == self.sel_class: sel_node = node if sel_node: self.selection.select_iter(sel_node) - page = self.name2page[self.sel_name] + page = self.class2page[self.active_rule.__class__] self.notebook.set_current_page(page) - self.display_values(self.sel_name) - (n,c,v,t) = self.page[page] + self.display_values(self.active_rule.__class__) + (class_obj,vallist,tlist) = self.page[page] r = self.active_rule.values() - for i in range(0,len(t)): - t[i].set_text(r[i]) + for i in range(0,len(tlist)): + tlist[i].set_text(r[i]) self.selection.connect('changed', self.on_node_selected) self.rule.signal_autoconnect({ @@ -787,7 +788,10 @@ class EditRule: def add_itself_to_menu(self): self.parent.child_windows[self.win_key] = self - label = self.sel_name + if self.sel_class: + label = self.sel_class.name + else: + label = '' if not label.strip(): label = _("New Rule") label = "%s: %s" % (_('Rule'),label) @@ -810,32 +814,32 @@ class EditRule: store,iter = self.selection.get_selected() if iter: try: - key = unicode(store.get_value(iter,0)) - self.display_values(key) + class_obj = store.get_value(iter,1) + self.display_values(class_obj) except: self.valuebox.set_sensitive(0) self.rule_name.set_text(_('No rule selected')) + self.rule.get_widget('description').set_text('') - def display_values(self,key): - page = self.name2page[key] + def display_values(self,class_obj): + page = self.class2page[class_obj] self.notebook.set_current_page(page) self.valuebox.set_sensitive(1) - self.rule_name.set_text(key) - the_filter = GenericFilter.tasks[key]([None]) - self.rule.get_widget('description').set_text(the_filter.description()) + self.rule_name.set_text(class_obj.name) + self.rule.get_widget('description').set_text(class_obj.description) def rule_ok(self,obj): - name = unicode(self.rule_name.get_text()) - class_def = GenericFilter.tasks[name] - obj = class_def(None) + if self.rule_name.get_text() == _('No rule selected'): + return + try: - page = self.name2page[name] - (n,c,v,t) = self.page[page] + page = self.notebook.get_current_page() + (class_obj,vallist,tlist) = self.page[page] value_list = [] - for x in t: + for x in tlist: value_list.append(unicode(x.get_text())) store,iter = self.parent.rlist.get_selected() - new_rule = c(value_list) + new_rule = class_obj(value_list) if self.active_rule: rule = self.parent.rlist.get_object(iter) self.parent.filter.delete_rule(rule) @@ -849,7 +853,6 @@ class EditRule: self.window.destroy() DisplayTrace.DisplayTrace() - #------------------------------------------------------------------------- # #