* src/AddSpouse.py: accept Person instead of handle

* src/ChooseParents.py: accept Person instead of handle
* src/GenericFilter.py: use single pass through database, filters
accept Person objects instead of handles
* src/PeopleModel.py: don't precalculate handle list
* src/RelLib.py: allow person object to be initialized with
serialized data
* src/SelectChild.py: accept Person instead of handle

* src/SelectChild.py (LikelyFilter.prepare,LikelyFilter.apply):


svn: r4854
This commit is contained in:
Don Allingham 2005-06-21 04:04:44 +00:00
parent b33fcb04a9
commit 6730d35232
7 changed files with 290 additions and 257 deletions

View File

@ -1,5 +1,15 @@
2005-06-20 Don Allingham <don@gramps-project.org>
* src/AddSpouse.py: accept Person instead of handle
* src/ChooseParents.py: accept Person instead of handle
* src/GenericFilter.py: use single pass through database, filters
accept Person objects instead of handles
* src/PeopleModel.py: don't precalculate handle list
* src/RelLib.py: allow person object to be initialized with
serialized data
* src/SelectChild.py: accept Person instead of handle
2005-06-20 Alexander Roitman <shura@gramps-project.org> 2005-06-20 Alexander Roitman <shura@gramps-project.org>
* src/SelectChildpy (LikelyFilter.prepare,LikelyFilter.apply): * src/SelectChild.py (LikelyFilter.prepare,LikelyFilter.apply):
Handle absent birth of a parent. Handle absent birth of a parent.
* src/AddSpouse.py (LikelyFilter.prepare,LikelyFilter.apply): * src/AddSpouse.py (LikelyFilter.prepare,LikelyFilter.apply):
Handle absent birth of a parent; correctly use gender. Handle absent birth of a parent; correctly use gender.

View File

@ -410,8 +410,7 @@ class LikelyFilter(GenericFilter.Rule):
else: else:
self.gender = RelLib.Person.MALE self.gender = RelLib.Person.MALE
def apply(self,db,handle): def apply(self,db,person):
person = db.get_person_from_handle(handle)
if person.gender != self.gender: if person.gender != self.gender:
return False return False
if not person.birth_handle or (self.upper == None and if not person.birth_handle or (self.upper == None and

View File

@ -820,8 +820,7 @@ class LikelyFilter(GenericFilter.Rule):
dateobj.set_year(year-70) dateobj.set_year(year-70)
self.upper = dateobj.sortval self.upper = dateobj.sortval
def apply(self,db,handle): def apply(self,db,person):
person = db.get_person_from_handle(handle)
if person.gender != self.gender: if person.gender != self.gender:
return False return False
if not person.birth_handle: if not person.birth_handle:

View File

@ -109,8 +109,8 @@ class Rule:
def check(self): def check(self):
return len(self.list) == len(self.labels) return len(self.list) == len(self.labels)
def apply(self,db,handle): def apply(self,db,person):
return 1 return True
def display_values(self): def display_values(self):
v = [] v = []
@ -131,8 +131,8 @@ class Everyone(Rule):
category = _('General filters') category = _('General filters')
description = _('Matches everyone in the database') description = _('Matches everyone in the database')
def apply(self,db,handle): def apply(self,db,person):
return 1 return True
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -147,8 +147,7 @@ class Disconnected(Rule):
description = _('Matches people that have no family relationships ' description = _('Matches people that have no family relationships '
'to any other person in the database') 'to any other person in the database')
def apply(self,db,handle): def apply(self,db,person):
person = db.get_person_from_handle(handle)
return (not person.get_main_parents_family_handle() and return (not person.get_main_parents_family_handle() and
not len(person.get_family_handle_list())) not len(person.get_family_handle_list()))
@ -205,8 +204,8 @@ class RelationshipPathBetween(Rule):
self.apply_filter(rank+1,family.get_father_handle(),plist,pmap) self.apply_filter(rank+1,family.get_father_handle(),plist,pmap)
self.apply_filter(rank+1,family.get_mother_handle(),plist,pmap) self.apply_filter(rank+1,family.get_mother_handle(),plist,pmap)
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,p1_handle,p2_handle): def init_list(self,p1_handle,p2_handle):
firstMap = {} firstMap = {}
@ -262,8 +261,8 @@ class HasIdOf(Rule):
description = _("Matches people with a specified GRAMPS ID") description = _("Matches people with a specified GRAMPS ID")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
return db.get_person_from_handle(handle).get_gramps_id() == self.list[0] return person.gramps_id == self.list[0]
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -277,11 +276,11 @@ class IsDefaultPerson(Rule):
category = _('General filters') category = _('General filters')
description = _("Matches the default person") description = _("Matches the default person")
def apply(self,db,handle): def apply(self,db,person):
person = db.get_default_person() def_person = db.get_default_person()
if person: if def_person:
return handle == person.get_handle() return person.handle == def_person.handle
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -295,10 +294,10 @@ class IsBookmarked(Rule):
category = _('General filters') category = _('General filters')
description = _("Matches the people on the bookmark list") description = _("Matches the people on the bookmark list")
def apply(self,db,handle): def apply(self,db,person):
if handle in db.get_bookmarks(): if person.handle in db.get_bookmarks():
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -312,8 +311,8 @@ class HasCompleteRecord(Rule):
category = _('General filters') category = _('General filters')
description = _('Matches all people whose records are complete') description = _('Matches all people whose records are complete')
def apply(self,db,handle): def apply(self,db,person):
return db.get_person_from_handle(handle).get_complete_flag() == 1 return person.get_complete_flag() == 1
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -327,8 +326,8 @@ class IsFemale(Rule):
category = _('General filters') category = _('General filters')
description = _('Matches all females') description = _('Matches all females')
def apply(self,db,handle): def apply(self,db,person):
return db.get_person_from_handle(handle).get_gender() == RelLib.Person.FEMALE return person.gender == RelLib.Person.FEMALE
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -342,8 +341,8 @@ class HasUnknownGender(Rule):
category = _('General filters') category = _('General filters')
description = _('Matches all people with unknown gender') description = _('Matches all people with unknown gender')
def apply(self,db,handle): def apply(self,db,person):
return db.get_person_from_handle(handle).get_gender() == RelLib.Person.UNKNOWN return person.get_gender() == RelLib.Person.UNKNOWN
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -364,11 +363,11 @@ class IsDescendantOf(Rule):
self.map = {} self.map = {}
try: try:
if int(self.list[1]): if int(self.list[1]):
first = 0 first = False
else: else:
first = 1 first = True
except IndexError: except IndexError:
first = 1 first = True
try: try:
root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle()
self.init_list(root_handle,first) self.init_list(root_handle,first)
@ -378,8 +377,8 @@ class IsDescendantOf(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,handle,first): def init_list(self,handle,first):
if not handle: if not handle:
@ -433,8 +432,8 @@ class IsDescendantOfFilterMatch(IsDescendantOf):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -463,8 +462,8 @@ class IsLessThanNthGenerationDescendantOf(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,handle,gen): def init_list(self,handle,gen):
if not handle: if not handle:
@ -508,8 +507,8 @@ class IsMoreThanNthGenerationDescendantOf(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,handle,gen): def init_list(self,handle,gen):
if not handle: if not handle:
@ -550,8 +549,8 @@ class IsChildOfFilterMatch(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,handle): def init_list(self,handle):
if not handle: if not handle:
@ -588,8 +587,8 @@ class IsSiblingOfFilterMatch(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,handle): def init_list(self,handle):
if not handle: if not handle:
@ -617,9 +616,9 @@ class IsDescendantFamilyOf(Rule):
description = _("Matches people that are descendants or the spouse " description = _("Matches people that are descendants or the spouse "
"of a descendant of a specified person") "of a descendant of a specified person")
def apply(self,db,handle): def apply(self,db,person):
self.map = {} self.map = {}
self.orig_handle = handle self.orig_handle = person.handle
self.db = db self.db = db
return self.search(handle,1) return self.search(handle,1)
@ -627,9 +626,9 @@ class IsDescendantFamilyOf(Rule):
try: try:
if handle == self.db.get_person_from_gramps_id(self.list[0]).get_handle(): if handle == self.db.get_person_from_gramps_id(self.list[0]).get_handle():
self.map[handle] = 1 self.map[handle] = 1
return 1 return True
except: except:
return 0 return False
p = self.db.get_person_from_handle(handle) p = self.db.get_person_from_handle(handle)
for (f,r1,r2) in p.get_parent_family_handle_list(): for (f,r1,r2) in p.get_parent_family_handle_list():
@ -637,7 +636,7 @@ class IsDescendantFamilyOf(Rule):
for person_handle in [family.get_mother_handle(),family.get_father_handle()]: for person_handle in [family.get_mother_handle(),family.get_father_handle()]:
if person_handle: if person_handle:
if self.search(person_handle,0): if self.search(person_handle,0):
return 1 return True
if val: if val:
for family_handle in p.get_family_handle_list(): for family_handle in p.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle) family = self.db.get_family_from_handle(family_handle)
@ -647,8 +646,8 @@ class IsDescendantFamilyOf(Rule):
spouse_id = family.get_father_handle() spouse_id = family.get_father_handle()
if spouse_id: if spouse_id:
if self.search(spouse_id,0): if self.search(spouse_id,0):
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -683,8 +682,8 @@ class IsAncestorOf(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_ancestor_list(self,db,handle,first): def init_ancestor_list(self,db,handle,first):
if not handle: if not handle:
@ -744,8 +743,8 @@ class IsAncestorOfFilterMatch(IsAncestorOf):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -774,8 +773,8 @@ class IsLessThanNthGenerationAncestorOf(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_ancestor_list(self,handle,gen): def init_ancestor_list(self,handle,gen):
# if self.map.has_key(p.get_handle()) == 1: # if self.map.has_key(p.get_handle()) == 1:
@ -826,8 +825,8 @@ class IsMoreThanNthGenerationAncestorOf(Rule):
def reset(self): def reset(self):
self.map = [] self.map = []
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_ancestor_list(self,handle,gen): def init_ancestor_list(self,handle,gen):
# if self.map.has_key(p.get_handle()) == 1: # if self.map.has_key(p.get_handle()) == 1:
@ -876,8 +875,8 @@ class IsParentOfFilterMatch(Rule):
def reset(self): def reset(self):
self.map = {} self.map = {}
def apply(self,db,handle): def apply(self,db,person):
return self.map.has_key(handle) return self.map.has_key(person.handle)
def init_list(self,handle): def init_list(self,handle):
p = self.db.get_person_from_handle(handle) p = self.db.get_person_from_handle(handle)
@ -919,12 +918,13 @@ class HasCommonAncestorWith(Rule):
def init(self,handle): self.ancestor_cache[handle] = 1 def init(self,handle): self.ancestor_cache[handle] = 1
for_each_ancestor(db,[handle],init,self) for_each_ancestor(db,[handle],init,self)
def apply(self,db,handle): def apply(self,db,person):
# On the first call, we build the ancestor cache for the # On the first call, we build the ancestor cache for the
# reference person. Then, for each person to test, # reference person. Then, for each person to test,
# we browse his ancestors until we found one in the cache. # we browse his ancestors until we found one in the cache.
if len(self.ancestor_cache) == 0: if len(self.ancestor_cache) == 0:
self.init_ancestor_cache(db) self.init_ancestor_cache(db)
handle = person.handle
return for_each_ancestor(db,[handle], return for_each_ancestor(db,[handle],
lambda self,handle: self.ancestor_cache.has_key(handle), lambda self,handle: self.ancestor_cache.has_key(handle),
self); self);
@ -969,8 +969,8 @@ class IsMale(Rule):
category = _('General filters') category = _('General filters')
description = _('Matches all males') description = _('Matches all males')
def apply(self,db,handle): def apply(self,db,person):
return db.get_person_from_handle(handle).get_gender() == RelLib.Person.MALE return person.gender == RelLib.Person.MALE
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -995,9 +995,8 @@ class HasEvent(Rule):
self.date = DateHandler.parser.parse(self.list[1]) self.date = DateHandler.parser.parse(self.list[1])
except: pass except: pass
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for event_handle in person.get_event_list():
for event_handle in p.get_event_list():
if not event_handle: if not event_handle:
continue continue
event = db.get_event_from_handle(event_handle) event = db.get_event_from_handle(event_handle)
@ -1018,8 +1017,8 @@ class HasEvent(Rule):
if pn.upper().find(self.list[2].upper()) == -1: if pn.upper().find(self.list[2].upper()) == -1:
val = 0 val = 0
if val == 1: if val == 1:
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1045,9 +1044,8 @@ class HasFamilyEvent(Rule):
self.date = DateHandler.parser.parse(self.list[1]) self.date = DateHandler.parser.parse(self.list[1])
except: pass except: pass
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for f_id in person.get_family_handle_list():
for f_id in p.get_family_handle_list():
f = db.get_family_from_handle(f_id) f = db.get_family_from_handle(f_id)
for event_handle in f.get_event_list(): for event_handle in f.get_event_list():
if not event_handle: if not event_handle:
@ -1069,8 +1067,8 @@ class HasFamilyEvent(Rule):
if self.list[2] and pn.find(self.list[2].upper()) == -1: if self.list[2] and pn.find(self.list[2].upper()) == -1:
val = 0 val = 0
if val == 1: if val == 1:
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1087,14 +1085,13 @@ class HasRelationship(Rule):
description = _("Matches people with a particular relationship") description = _("Matches people with a particular relationship")
category = _('Family filters') category = _('Family filters')
def apply(self,db,handle): def apply(self,db,person):
rel_type = 0 rel_type = 0
cnt = 0 cnt = 0
p = db.get_person_from_handle(handle) num_rel = len(person.get_family_handle_list())
num_rel = len(p.get_family_handle_list())
# count children and look for a relationship type match # count children and look for a relationship type match
for f_id in p.get_family_handle_list(): for f_id in person.get_family_handle_list():
f = db.get_family_from_handle(f_id) f = db.get_family_from_handle(f_id)
cnt = cnt + len(f.get_child_handle_list()) cnt = cnt + len(f.get_child_handle_list())
if self.list[1] and int(self.list[1]) == f.get_relationship(): if self.list[1] and int(self.list[1]) == f.get_relationship():
@ -1105,24 +1102,24 @@ class HasRelationship(Rule):
try: try:
v = int(self.list[0]) v = int(self.list[0])
except: except:
return 0 return False
if v != num_rel: if v != num_rel:
return 0 return False
# number of childred # number of childred
if self.list[2]: if self.list[2]:
try: try:
v = int(self.list[2]) v = int(self.list[2])
except: except:
return 0 return False
if v != cnt: if v != cnt:
return 0 return False
# relation # relation
if self.list[1]: if self.list[1]:
return rel_type == 1 return rel_type == 1
else: else:
return 1 return True
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1144,9 +1141,8 @@ class HasBirth(Rule):
else: else:
self.date = None self.date = None
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) event_handle = person.get_birth_handle()
event_handle = p.get_birth_handle()
if not event_handle: if not event_handle:
return False return False
event = db.get_event_from_handle(event_handle) event = db.get_event_from_handle(event_handle)
@ -1184,25 +1180,24 @@ class HasDeath(Rule):
else: else:
self.date = None self.date = None
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) event_handle = person.get_death_handle()
event_handle = p.get_death_handle()
if not event_handle: if not event_handle:
return 0 return False
event = db.get_event_from_handle(event_handle) event = db.get_event_from_handle(event_handle)
ed = event.get_description().upper() ed = event.get_description().upper()
if self.list[2] and ed.find(self.list[2].upper())==-1: if self.list[2] and ed.find(self.list[2].upper())==-1:
return 0 return False
if self.date: if self.date:
if date_cmp(self.date,event.get_date_object()) == 0: if date_cmp(self.date,event.get_date_object()) == 0:
return 0 return False
pl_id = event.get_place_handle() pl_id = event.get_place_handle()
if pl_id: if pl_id:
pl = db.get_place_from_handle(pl_id) pl = db.get_place_from_handle(pl_id)
pn = pl.get_title() pn = pl.get_title()
if self.list[1] and pn.find(self.list[1].upper()) == -1: if self.list[1] and pn.find(self.list[1].upper()) == -1:
return 0 return False
return 1 return True
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1217,17 +1212,16 @@ class HasAttribute(Rule):
description = _("Matches people with the personal attribute of a particular value") description = _("Matches people with the personal attribute of a particular value")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
if not self.list[0]: if not self.list[0]:
return 0 return False
p = db.get_person_from_handle(handle) for attr in person.get_attribute_list():
for attr in p.get_attribute_list():
name_match = self.list[0] == attr.get_type() name_match = self.list[0] == attr.get_type()
value_match = \ value_match = \
attr.get_value().upper().find(self.list[1].upper()) != -1 attr.get_value().upper().find(self.list[1].upper()) != -1
if name_match and value_match: if name_match and value_match:
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1242,19 +1236,18 @@ class HasFamilyAttribute(Rule):
description = _("Matches people with the family attribute of a particular value") description = _("Matches people with the family attribute of a particular value")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
if not self.list[0]: if not self.list[0]:
return 0 return False
p = db.get_person_from_handle(handle) for f_id in person.get_family_handle_list():
for f_id in p.get_family_handle_list():
f = db.get_family_from_handle(f_id) f = db.get_family_from_handle(f_id)
for attr in f.get_attribute_list(): for attr in f.get_attribute_list():
name_match = self.list[0] == attr.get_type() name_match = self.list[0] == attr.get_type()
value_match = \ value_match = \
attr.get_value().upper().find(self.list[1].upper()) != -1 attr.get_value().upper().find(self.list[1].upper()) != -1
if name_match and value_match: if name_match and value_match:
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1272,13 +1265,12 @@ class HasNameOf(Rule):
description = _("Matches people with a specified (partial) name") description = _("Matches people with a specified (partial) name")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
self.f = self.list[0] self.f = self.list[0]
self.l = self.list[1] self.l = self.list[1]
self.s = self.list[2] self.s = self.list[2]
self.t = self.list[3] self.t = self.list[3]
p = db.get_person_from_handle(handle) for name in [person.get_primary_name()] + person.get_alternate_names():
for name in [p.get_primary_name()] + p.get_alternate_names():
val = 1 val = 1
if self.f and name.get_first_name().upper().find(self.f.upper()) == -1: if self.f and name.get_first_name().upper().find(self.f.upper()) == -1:
val = 0 val = 0
@ -1289,8 +1281,8 @@ class HasNameOf(Rule):
if self.t and name.get_title().upper().find(self.t.upper()) == -1: if self.t and name.get_title().upper().find(self.t.upper()) == -1:
val = 0 val = 0
if val == 1: if val == 1:
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1323,14 +1315,13 @@ class IncompleteNames(Rule):
description = _("Matches people with firstname or lastname missing") description = _("Matches people with firstname or lastname missing")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for name in [person.get_primary_name()] + person.get_alternate_names():
for name in [p.get_primary_name()] + p.get_alternate_names():
if name.get_first_name() == "": if name.get_first_name() == "":
return 1 return True
if name.get_surname() == "": if name.get_surname() == "":
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1372,7 +1363,7 @@ class MatchesFilter(Rule):
for filt in CustomFilters.get_filters(): for filt in CustomFilters.get_filters():
if filt.get_name() == self.list[0]: if filt.get_name() == self.list[0]:
return filt.check(db,handle) return filt.check(db,handle)
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1388,10 +1379,9 @@ class IsSpouseOfFilterMatch(Rule):
description = _("Matches people married to anybody matching a filter") description = _("Matches people married to anybody matching a filter")
category = _('Family filters') category = _('Family filters')
def apply(self,db,handle): def apply(self,db,person):
filt = MatchesFilter (self.list) filt = MatchesFilter (self.list)
p = db.get_person_from_handle(handle) for family_handle in person.get_family_handle_list ():
for family_handle in p.get_family_handle_list ():
family = db.get_family_from_handle(family_handle) family = db.get_family_from_handle(family_handle)
for spouse_id in [family.get_father_handle (), family.get_mother_handle ()]: for spouse_id in [family.get_father_handle (), family.get_mother_handle ()]:
if not spouse_id: if not spouse_id:
@ -1399,8 +1389,8 @@ class IsSpouseOfFilterMatch(Rule):
if spouse_id == handle: if spouse_id == handle:
continue continue
if filt.apply (db, spouse_id): if filt.apply (db, spouse_id):
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People who were adopted" # "People who were adopted"
@ -1412,12 +1402,11 @@ class HaveAltFamilies(Rule):
description = _("Matches people who were adopted") description = _("Matches people who were adopted")
category = _('Family filters') category = _('Family filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for (fam,rel1,rel2) in person.get_parent_family_handle_list():
for (fam,rel1,rel2) in p.get_parent_family_handle_list(): if rel1 == RelLib.Person.CHILD_ADOPTED or rel2 == RelLib.Person.CHILD_ADOPTED:
if rel1 == RelLib.Person.CHILD_REL_ADOPT or rel2 == RelLib.Person.CHILD_REL_ADOPT: return True
return 1 return False
return 0
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -1430,9 +1419,8 @@ class HavePhotos(Rule):
description = _("Matches people with images in the gallery") description = _("Matches people with images in the gallery")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) return len( person.get_media_list()) > 0
return len( p.get_media_list()) > 0
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People with children" # "People with children"
@ -1444,9 +1432,8 @@ class HaveChildren(Rule):
description = _("Matches people who have children") description = _("Matches people who have children")
category = _('Family filters') category = _('Family filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for family_handle in person.get_family_handle_list():
for family_handle in p.get_family_handle_list():
family = db.get_family_from_handle(family_handle) family = db.get_family_from_handle(family_handle)
return len(family.get_child_handle_list()) > 0 return len(family.get_child_handle_list()) > 0
@ -1460,9 +1447,8 @@ class NeverMarried(Rule):
description = _("Matches people who have no spouse") description = _("Matches people who have no spouse")
category = _('Family filters') category = _('Family filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) return len(person.get_family_handle_list()) == 0
return len(p.get_family_handle_list()) == 0
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People with multiple marriage records" # "People with multiple marriage records"
@ -1474,9 +1460,8 @@ class MultipleMarriages(Rule):
description = _("Matches people who have more than one spouse") description = _("Matches people who have more than one spouse")
category = _('Family filters') category = _('Family filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) return len(person.get_family_handle_list()) > 1
return len(p.get_family_handle_list()) > 1
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People without a birth date" # "People without a birth date"
@ -1488,15 +1473,14 @@ class NoBirthdate(Rule):
description = _("Matches people without a known birthdate") description = _("Matches people without a known birthdate")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) birth_handle = person.get_birth_handle()
birth_handle = p.get_birth_handle()
if not birth_handle: if not birth_handle:
return 1 return True
birth = db.get_event_from_handle(birth_handle) birth = db.get_event_from_handle(birth_handle)
if not birth.get_date_object(): if not birth.get_date_object():
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People with incomplete events" # "People with incomplete events"
@ -1508,16 +1492,15 @@ class PersonWithIncompleteEvent(Rule):
description = _("Matches people with missing date or place in an event") description = _("Matches people with missing date or place in an event")
category = _('Event filters') category = _('Event filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for event_handle in person.get_event_list() + [person.get_birth_handle(), person.get_death_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) event = db.get_event_from_handle(event_handle)
if event: if event:
if not event.get_place_handle(): if not event.get_place_handle():
return 1 return True
if not event.get_date_object(): if not event.get_date_object():
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "Families with incomplete events" # "Families with incomplete events"
@ -1529,18 +1512,17 @@ class FamilyWithIncompleteEvent(Rule):
description = _("Matches people with missing date or place in an event of the family") description = _("Matches people with missing date or place in an event of the family")
category = _('Event filters') category = _('Event filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) for family_handle in person.get_family_handle_list():
for family_handle in p.get_family_handle_list():
family = db.get_family_from_handle(family_handle) family = db.get_family_from_handle(family_handle)
for event_handle in family.get_event_list(): for event_handle in family.get_event_list():
event = db.get_event_from_handle(event_handle) event = db.get_event_from_handle(event_handle)
if event: if event:
if not event.get_place_handle(): if not event.get_place_handle():
return 1 return True
if not event.get_date_object(): if not event.get_date_object():
return 1 return True
return 0 return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People probably alive" # "People probably alive"
@ -1559,9 +1541,8 @@ class ProbablyAlive(Rule):
except: except:
self.current_year = None self.current_year = None
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) return probably_alive(person,db,self.current_year)
return probably_alive(p,db,self.current_year)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "People marked private" # "People marked private"
@ -1573,9 +1554,8 @@ class PeoplePrivate(Rule):
description = _("Matches people that are indicated as private") description = _("Matches people that are indicated as private")
category = _('General filters') category = _('General filters')
def apply(self,db,handle): def apply(self,db,person):
p = db.get_person_from_handle(handle) return person.get_privacy()
return p.get_privacy()
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# "Witnesses" # "Witnesses"
@ -1596,8 +1576,8 @@ class IsWitness(Rule):
def reset(self): def reset(self):
self.map = [] self.map = []
def apply(self,db,handle): def apply(self,db,person):
return handle in self.map return person.handle in self.map
def build_witness_list(self): def build_witness_list(self):
event_type = None event_type = None
@ -1649,6 +1629,7 @@ class HasTextMatchingSubstringOf(Rule):
self.person_map = {} self.person_map = {}
self.event_map = {} self.event_map = {}
self.source_map = {} self.source_map = {}
self.repo_map = {}
self.family_map = {} self.family_map = {}
self.place_map = {} self.place_map = {}
self.media_map = {} self.media_map = {}
@ -1666,36 +1647,37 @@ class HasTextMatchingSubstringOf(Rule):
self.regexp_match = False self.regexp_match = False
except IndexError: except IndexError:
self.regexp_match = False self.regexp_match = False
self.cache_repos()
self.cache_sources() self.cache_sources()
def reset(self): def reset(self):
self.person_map = {} self.person_map = {}
self.event_map = {} self.event_map = {}
self.source_map = {} self.source_map = {}
self.repo_map = {}
self.family_map = {} self.family_map = {}
self.place_map = {} self.place_map = {}
self.media_map = {} self.media_map = {}
def apply(self,db,handle): def apply(self,db,person):
if handle in self.person_map: # Cached by matching Source? if person.handle in self.person_map: # Cached by matching Source?
return self.person_map[handle] return self.person_map[handle]
p = db.get_person_from_handle(handle) if self.match_object(person): # first match the person itself
if self.match_object(p): # first match the person itself return True
return 1 for event_handle in person.get_event_list()+[person.get_birth_handle(), person.get_death_handle()]:
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 return True
for family_handle in p.get_family_handle_list(): # match families for family_handle in person.get_family_handle_list(): # match families
if self.search_family(family_handle): if self.search_family(family_handle):
return 1 return True
for media_ref in p.get_media_list(): # match Media object for media_ref in person.get_media_list(): # match Media object
if self.search_media(media_ref.get_reference_handle()): if self.search_media(media_ref.get_reference_handle()):
return 1 return True
return 0 return False
def search_family(self,family_handle): def search_family(self,family_handle):
if not family_handle: if not family_handle:
return 0 return False
# search inside the family and cache the result to not search a family twice # search inside the family and cache the result to not search a family twice
if not family_handle in self.family_map: if not family_handle in self.family_map:
match = 0 match = 0
@ -1709,13 +1691,13 @@ class HasTextMatchingSubstringOf(Rule):
break break
for media_ref in family.get_media_list(): # match Media object for media_ref in family.get_media_list(): # match Media object
if self.search_media(media_ref.get_reference_handle()): if self.search_media(media_ref.get_reference_handle()):
return 1 return True
self.family_map[family_handle] = match self.family_map[family_handle] = match
return self.family_map[family_handle] return self.family_map[family_handle]
def search_event(self,event_handle): def search_event(self,event_handle):
if not event_handle: if not event_handle:
return 0 return False
# search inside the event and cache the result (event sharing) # search inside the event and cache the result (event sharing)
if not event_handle in self.event_map: if not event_handle in self.event_map:
match = 0 match = 0
@ -1729,13 +1711,13 @@ class HasTextMatchingSubstringOf(Rule):
match = 1 match = 1
for media_ref in event.get_media_list(): # match Media object for media_ref in event.get_media_list(): # match Media object
if self.search_media(media_ref.get_reference_handle()): if self.search_media(media_ref.get_reference_handle()):
return 1 return True
self.event_map[event_handle] = match self.event_map[event_handle] = match
return self.event_map[event_handle] return self.event_map[event_handle]
def search_place(self,place_handle): def search_place(self,place_handle):
if not place_handle: if not place_handle:
return 0 return False
# search inside the place and cache the result # search inside the place and cache the result
if not place_handle in self.place_map: if not place_handle in self.place_map:
place = self.db.get_place_from_handle(place_handle) place = self.db.get_place_from_handle(place_handle)
@ -1744,18 +1726,30 @@ class HasTextMatchingSubstringOf(Rule):
def search_media(self,media_handle): def search_media(self,media_handle):
if not media_handle: if not media_handle:
return 0 return False
# search inside the place and cache the result # search inside the place and cache the result
if not media_handle in self.media_map: if not media_handle in self.media_map:
media = self.db.get_object_from_handle(media_handle) media = self.db.get_object_from_handle(media_handle)
self.media_map[media_handle] = self.match_object(media) self.media_map[media_handle] = self.match_object(media)
return self.media_map[media_handle] return self.media_map[media_handle]
def cache_repos(self):
# search all matching repositories
for repo_handle in self.db.get_repository_handles():
repo = self.db.get_repository_from_handle(repo_handle)
if( self.match_object(repo)):
self.repo_map[repo_handle] = 1
def cache_sources(self): def cache_sources(self):
# search all sources and match all referents of a matching source # search all sources and match all referents of a matching source
for source_handle in self.db.get_source_handles(): for source_handle in self.db.get_source_handles():
source = self.db.get_source_from_handle(source_handle) source = self.db.get_source_from_handle(source_handle)
if self.match_object(source): match = self.match_object(source)
if not match:
for reporef in source.get_reporef_list():
if reporef.get_reference_handle() in self.repo_map:
match = 1
if match:
(person_list,family_list,event_list, (person_list,family_list,event_list,
place_list,source_list,media_list place_list,source_list,media_list
) = get_source_referents(source_handle,self.db) ) = get_source_referents(source_handle,self.db)
@ -1772,7 +1766,7 @@ class HasTextMatchingSubstringOf(Rule):
def match_object(self,obj): def match_object(self,obj):
if not obj: if not obj:
return 0 return False
if self.regexp_match: if self.regexp_match:
return obj.matches_regexp(self.list[0],self.case_sensitive) return obj.matches_regexp(self.list[0],self.case_sensitive)
return obj.matches_string(self.list[0],self.case_sensitive) return obj.matches_string(self.list[0],self.case_sensitive)
@ -1790,6 +1784,7 @@ class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf):
self.person_map = {} self.person_map = {}
self.event_map = {} self.event_map = {}
self.source_map = {} self.source_map = {}
self.repo_map = {}
self.family_map = {} self.family_map = {}
self.place_map = {} self.place_map = {}
self.media_map = {} self.media_map = {}
@ -1816,11 +1811,10 @@ class HasSourceOf(Rule):
except: except:
self.source_handle = None self.source_handle = None
def apply(self,db,handle): def apply(self,db,person):
if not self.source_handle: if not self.source_handle:
return False return False
p = db.get_person_from_handle(handle) return person.has_source_reference( self.source_handle)
return p.has_source_reference( self.source_handle)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1846,7 +1840,7 @@ class GenericFilter:
self.name = '' self.name = ''
self.comment = '' self.comment = ''
self.logical_op = 'and' self.logical_op = 'and'
self.invert = 0 self.invert = False
def set_logical_op(self,val): def set_logical_op(self,val):
if val in GenericFilter.logical_functions: if val in GenericFilter.logical_functions:
@ -1887,49 +1881,83 @@ class GenericFilter:
def get_rules(self): def get_rules(self):
return self.flist return self.flist
def check_or(self,db,handle): def check_func(self,db,id_list,task):
test = 0 final_list = []
for rule in self.flist:
test = test or rule.apply(db,handle) if id_list == None:
if test: cursor = db.get_person_cursor()
data = cursor.next()
while data:
person = RelLib.Person()
person.unserialize(data[1])
if self.invert ^ task(db,person):
final_list.append(data[0])
data = cursor.next()
else:
for handle in id_list:
person = db.get_person_from_handle(handle)
if self.invert ^ task(db,person):
final_list.append(handle)
return final_list
def check_or(self,db,id_list):
return self.check_func(db,id_list,self.or_test)
def check_and(self,db,id_list):
final_list = []
flist = self.flist
invert = self.invert
if id_list == None:
cursor = db.get_person_cursor()
data = cursor.next()
p = RelLib.Person
while data:
person = p(data[1])
val = True
for rule in flist:
if not rule.apply(db,person):
val = False
break break
if self.invert: if invert ^ val:
return not test final_list.append(data[0])
data = cursor.next()
else: else:
return test for handle in id_list:
person = db.get_person_from_handle(handle)
val = True
for rule in flist:
if not rule.apply(db,person):
val = False
if invert ^ val:
final_list.append(handle)
return final_list
def check_xor(self,db,handle): def check_one(self,db,id_list):
test = 0 return self.check_func(db,id_list,self.one_test)
def check_xor(self,db,id_list):
return self.check_func(db,id_list,self.xor_test)
def xor_test(self,db,person):
test = False
for rule in self.flist: for rule in self.flist:
temp = rule.apply(db,handle) test = test ^ rule.apply(db,handle)
test = ((not test) and temp) or (test and (not temp))
if self.invert:
return not test
else:
return test return test
def check_one(self,db,handle): def one_test(self,db,person):
count = 0 count = 0
for rule in self.flist: for rule in self.flist:
if rule.apply(db,handle): if rule.apply(db,person):
count = count + 1 if count:
if count > 1: return False
break count += 1
if self.invert:
return count != 1 return count != 1
else:
return count == 1
def check_and(self,db,handle): def and_or(self,db,person):
test = 1
for rule in self.flist: for rule in self.flist:
test = test and rule.apply(db,handle) if rule.apply(db,person):
if not test: return True
break return False
if self.invert:
return not test
else:
return test
def get_check_func(self): def get_check_func(self):
try: try:
@ -1941,14 +1969,11 @@ class GenericFilter:
def check(self,db,handle): def check(self,db,handle):
return self.get_check_func()(db,handle) return self.get_check_func()(db,handle)
def apply(self,db,id_list): def apply(self,db,id_list=None):
m = self.get_check_func() m = self.get_check_func()
res = []
for rule in self.flist: for rule in self.flist:
rule.prepare(db) rule.prepare(db)
for handle in id_list: res = m(db,id_list)
if m(db,handle):
res.append(handle)
for rule in self.flist: for rule in self.flist:
rule.reset() rule.reset()
return res return res

View File

@ -105,11 +105,9 @@ class PeopleModel(gtk.GenericTreeModel):
return return
if data_filter: if data_filter:
handle_list = self.db.get_person_handles(sort_handles=False) keys = data_filter.apply(self.db)
keys = data_filter.apply(self.db,handle_list)
if self.invert_result: if self.invert_result:
keys = [k for k in handle_list if k not in keys] keys = [k for k in handle_list if k not in keys]
del handle_list
else: else:
keys = self.db.get_person_handles(sort_handles=False) keys = self.db.get_person_handles(sort_handles=False)

View File

@ -907,12 +907,15 @@ class Person(PrimaryObject,PrivateSourceNote,MediaBase,AttributeBase):
CHILD_REL_UNKWN = 6 CHILD_REL_UNKWN = 6
CHILD_REL_OTHER = 7 CHILD_REL_OTHER = 7
def __init__(self): def __init__(self,data=None):
""" """
Creates a new Person instance. After initialization, most Creates a new Person instance. After initialization, most
data items have empty or null values, including the database data items have empty or null values, including the database
handle. handle.
""" """
if data:
self.unserialize(data)
else:
PrimaryObject.__init__(self) PrimaryObject.__init__(self)
PrivateSourceNote.__init__(self) PrivateSourceNote.__init__(self)
MediaBase.__init__(self) MediaBase.__init__(self)

View File

@ -318,8 +318,7 @@ class LikelyFilter(GenericFilter.Rule):
self.lower = None self.lower = None
self.upper = None self.upper = None
def apply(self,db,handle): def apply(self,db,person):
person = db.get_person_from_handle(handle)
if not person.birth_handle or (self.upper == None and if not person.birth_handle or (self.upper == None and
self.lower == None): self.lower == None):
return True return True