2007-09-13 Benny Malengier <benny.malengier@gramps-project.org>

* src/plugins/lineage.py: Final touches, loop detection



svn: r8971
This commit is contained in:
Benny Malengier 2007-09-13 09:51:10 +00:00
parent dd42d5b11f
commit 997252630b
2 changed files with 93 additions and 40 deletions

View File

@ -1,3 +1,6 @@
2007-09-13 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/lineage.py: Final touches, loop detection
2007-09-12 Don Allingham <don@gramps-project.org> 2007-09-12 Don Allingham <don@gramps-project.org>
* src/DataViews/_MediaView.py: cleanup and documentation * src/DataViews/_MediaView.py: cleanup and documentation
* src/DataViews/_RepositoryView.py: cleanup and documentation * src/DataViews/_RepositoryView.py: cleanup and documentation

View File

@ -38,10 +38,12 @@ from PluginUtils import register_quick_report
from ReportBase import CATEGORY_QR_PERSON from ReportBase import CATEGORY_QR_PERSON
__FMT = "%-30s\t%-12s\t%-12s" __FMT = "%-30s\t%-12s\t%-12s"
__FMT_rem = " %s: %s" __FMT_REM = " %s: %s"
__MAX_GEN = 100
def run_father(database, document, person): def run_father(database, document, person):
""" Function writing the father lineage quick report
"""
sa = SimpleAccess(database) sa = SimpleAccess(database)
sd = SimpleDoc(document) sd = SimpleDoc(document)
@ -56,7 +58,7 @@ def run_father(database, document, person):
)) ))
sd.paragraph("") sd.paragraph("")
sd.header2(__FMT %(_("Name Father"),_("Birth Date"),_("Death Date"))) sd.header2(__FMT %(_("Name Father"), _("Birth Date"), _("Death Date")))
sd.paragraph("") sd.paragraph("")
make_details(RelLib.Person.MALE, person, sa, sd, database) make_details(RelLib.Person.MALE, person, sa, sd, database)
@ -64,13 +66,17 @@ def run_father(database, document, person):
sd.paragraph("") sd.paragraph("")
sd.paragraph("") sd.paragraph("")
sd.header2((_("Sons"))) if person.gender == RelLib.Person.FEMALE :
return
sd.header2((_("Direct line male descendants")))
sd.paragraph("") sd.paragraph("")
make_details_child(RelLib.Person.FEMALE, person, sa, sd, database) make_details_child(RelLib.Person.MALE, person, sa, sd, database)
def run_mother(database, document, person): def run_mother(database, document, person):
""" Function writing the mother lineage quick report
"""
sa = SimpleAccess(database) sa = SimpleAccess(database)
sd = SimpleDoc(document) sd = SimpleDoc(document)
@ -85,7 +91,7 @@ def run_mother(database, document, person):
)) ))
sd.paragraph("") sd.paragraph("")
sd.header2(__FMT %(_("Name Mother"),_("Birth"),_("Death Date"))) sd.header2(__FMT %(_("Name Mother"), _("Birth"), _("Death Date")))
sd.paragraph("") sd.paragraph("")
make_details(RelLib.Person.FEMALE, person, sa, sd, database) make_details(RelLib.Person.FEMALE, person, sa, sd, database)
@ -93,12 +99,21 @@ def run_mother(database, document, person):
sd.paragraph("") sd.paragraph("")
sd.paragraph("") sd.paragraph("")
sd.header2((_("Daughters"))) if person.gender == RelLib.Person.MALE :
return
sd.header2((_("Direct line female descendants")))
sd.paragraph("") sd.paragraph("")
make_details_child(RelLib.Person.FEMALE, person, sa, sd, database) make_details_child(RelLib.Person.FEMALE, person, sa, sd, database)
def make_details(gender, person, sa, sd, database) : def make_details(gender, person, sa, sd, database) :
""" Function writing one line of ancestry on the document in
direct lineage
"""
# avoid infinite loop:
personsprinted = 0
# loop as long as there are fathers/mothers # loop as long as there are fathers/mothers
rem_str = "" rem_str = ""
while person: while person:
@ -106,7 +121,14 @@ def make_details(gender, person, sa, sd, database) :
sd.paragraph(__FMT % (sa.name(person), sa.birth_date(person), sd.paragraph(__FMT % (sa.name(person), sa.birth_date(person),
sa.death_date(person))) sa.death_date(person)))
if rem_str: if rem_str:
sd.paragraph(__FMT_rem % (_("Remark"), rem_str)) sd.paragraph(__FMT_REM % (_("Remark"), rem_str))
personsprinted += 1
if personsprinted > __MAX_GEN :
sd.paragraph("")
sd.paragraph(_("ERROR : Too many levels in the tree "
"(perhaps a loop?)."))
return
# obtain the first father/mother we find in the list # obtain the first father/mother we find in the list
parent_handle_list = person.get_parent_family_handle_list() parent_handle_list = person.get_parent_family_handle_list()
@ -115,17 +137,24 @@ def make_details(gender, person, sa, sd, database) :
rem_str = "" rem_str = ""
family_id = parent_handle_list[0] family_id = parent_handle_list[0]
family = database.get_family_from_handle(family_id) family = database.get_family_from_handle(family_id)
if gender == RelLib.Person.MALE :
person = database.get_person_from_handle(
family.get_father_handle())
else :
person = database.get_person_from_handle(
family.get_mother_handle())
childrel = [(ref.get_mother_relation(), childrel = [(ref.get_mother_relation(),
ref.get_father_relation()) for ref in ref.get_father_relation()) for ref in
family.get_child_ref_list() family.get_child_ref_list()
if ref.ref == person_handle] if ref.ref == person_handle]
if not childrel[0][1] == RelLib.ChildRefType.BIRTH : if gender == RelLib.Person.MALE :
person = database.get_person_from_handle(
family.get_father_handle())
refnr = 1
else :
person = database.get_person_from_handle(
family.get_mother_handle())
refnr = 0
#We do not allow for same sex marriages when going up
# that would complicate the code
#Also, we assume the birth relation is in the FIRST
# family of the person, so we go up on non-birth
if not childrel[0][refnr] == RelLib.ChildRefType.BIRTH :
rem_str = add_rem(rem_str, _("No birth relation with child")) rem_str = add_rem(rem_str, _("No birth relation with child"))
if person and person.gender == gender : if person and person.gender == gender :
break break
@ -136,10 +165,20 @@ def make_details(gender, person, sa, sd, database) :
person = None person = None
def make_details_child(gender, person, sa, sd, database) : def make_details_child(gender, person, sa, sd, database) :
#recursively called function """ Function that prints the details of the children in the
def make_child_line(person, prepend) : male/female lineage
"""
def make_child_line(child, prepend, gen) :
""" Recursively called funcion to write one child line
Person is the child, prepend is the string that preceeds it
on print. As the recursion grows, prepend is increased
Gen is the generation level
"""
if gen > __MAX_GEN :
raise RuntimeError
#we use some global var from make_details_child !
rem_str = "" rem_str = ""
if person.gender == RelLib.Person.UNKNOWN : if child.gender == RelLib.Person.UNKNOWN :
rem_str = add_rem(rem_str, _("Unknown gender")) rem_str = add_rem(rem_str, _("Unknown gender"))
if rem_str : if rem_str :
@ -147,35 +186,46 @@ def make_details_child(gender, person, sa, sd, database) :
front = "" front = ""
if prepend : if prepend :
front = prepend + "-" front = prepend + "-"
sd.paragraph(front + "%s (%s - %s) %s" % (sa.name(person), sd.paragraph(front + "%s (%s - %s) %s" % (sa.name(child),
sa.birth_date(person), sa.birth_date(child),
sa.death_date(person), rem_str)) sa.death_date(child), rem_str))
#obtain families in which child is a parent
family_handles = person.get_family_handle_list() family_handles = child.get_family_handle_list()
for fam_handle in family_handles : for fam_handle in family_handles :
fam = database.get_family_from_handle(fam_handle) fam = database.get_family_from_handle(fam_handle)
#what parent is the previous child? We are fancy and allow
# for same sex marriage
if fam.get_father_handle() == child.handle :
childrelnr = 2
elif fam.get_mother_handle() == child.handle :
childrelnr = 1
else :
#something wrong with this family, continue with next
continue
childrel = [(ref.ref, ref.get_mother_relation(), childrel = [(ref.ref, ref.get_mother_relation(),
ref.get_father_relation()) for ref in ref.get_father_relation()) for ref in
fam.get_child_ref_list()] fam.get_child_ref_list()]
for child in childrel: for childdet in childrel:
if gender == RelLib.Person.FEMALE and \ #relation with parent must be by birth
not child[1] == RelLib.ChildRefType.BIRTH : if not childdet[childrelnr] == RelLib.ChildRefType.BIRTH :
continue continue
if gender == RelLib.Person.MALE and \
not child[2] == RelLib.ChildRefType.BIRTH : newchild = database.get_person_from_handle(childdet[0])
continue # person must have the required gender
if newchild and newchild.gender == gender :
person = database.get_person_from_handle(child[0]) make_child_line(newchild, prepend + ' |', gen+1)
if person and person.gender == gender :
make_child_line(person, prepend + ' |')
# loop over all children of gender and output # loop over all children of gender and output, start with no prepend
prev_str = "" try :
rem_str = "" make_child_line(person, "", 0)
make_child_line(person,prev_str) except RuntimeError:
sd.paragraph("")
sd.paragraph(_("ERROR : Too many levels in the tree "
"(perhaps a loop?)."))
def add_rem(remark, text): def add_rem(remark, text):
""" Allow for extension of remark, return new remark string
"""
if remark: if remark:
return remark + ', ' + text return remark + ', ' + text
else: else: