Add Ahnentafel option on hourglass
This commit is contained in:
parent
0fb1742362
commit
08a4aeff7b
@ -11,6 +11,7 @@
|
||||
# Copyright (C) 2017 Jonathan Biegert <azrdev@qrdn.de>
|
||||
# Copyright (C) 2017 Mindaugas Baranauskas
|
||||
# Copyright (C) 2017 Paul Culley
|
||||
# Copyright (C) 2018 Christophe aka khrys63
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -364,6 +365,34 @@ class GVDoc(metaclass=ABCMeta):
|
||||
:return: nothing
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def add_samerank(self, id1, id2):
|
||||
"""
|
||||
Force the same line for two linked nodes.
|
||||
|
||||
:param id1: The unique identifier of the starting node.
|
||||
Example: "p55"
|
||||
:type id1: string
|
||||
:param id2: The unique identifier of the ending node.
|
||||
Example: "p55"
|
||||
:type id2: string
|
||||
:return: nothing
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def rewrite_label(self, id, label):
|
||||
"""
|
||||
Rewrite the node label.
|
||||
|
||||
:param id: The unique identifier of the node.
|
||||
Example: "p55"
|
||||
:type id: string
|
||||
:param label: The text to be displayed in the node.
|
||||
Example: "John Smith"
|
||||
:type label: string
|
||||
:return: nothing
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def start_subgraph(self, graph_id):
|
||||
"""
|
||||
@ -600,6 +629,22 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
else:
|
||||
self.write('# %s\n' % text)
|
||||
|
||||
def add_samerank(self, id1, id2):
|
||||
"""
|
||||
Force the same line for two linked nodes.
|
||||
|
||||
Implements GVDocBase.add_samerank().
|
||||
"""
|
||||
self.write(' {rank=same "%s" "%s"}\n' % (id1, id2))
|
||||
|
||||
def rewrite_label(self, id, label):
|
||||
"""
|
||||
Rewrite the node label.
|
||||
|
||||
Implements GVDocBase.rewrite_label().
|
||||
"""
|
||||
self.write(' "%s" [label = "%s"]\n' % (id, label))
|
||||
|
||||
def start_subgraph(self, graph_id):
|
||||
""" Implement GVDocBase.start_subgraph() """
|
||||
graph_id = graph_id.replace(' ', '_') # for user-defined ID with space
|
||||
|
@ -7,6 +7,7 @@
|
||||
# Copyright (C) 2010 Jakim Friant
|
||||
# Copyright (C) 2013-2014 Paul Franklin
|
||||
# Copyright (C) 2015 Detlef Wolz <detlef.wolz@t-online.de>
|
||||
# Copyright (C) 2018 Christophe aka khrys63
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -98,6 +99,8 @@ class HourGlassReport(Report):
|
||||
self.__family_father = [] # links allocated from family to father
|
||||
self.__family_mother = [] # links allocated from family to mother
|
||||
|
||||
self.__node_label = {} # labels of node for merge sosa number
|
||||
|
||||
self.max_descend = menu.get_option_by_name('maxdescend').get_value()
|
||||
self.max_ascend = menu.get_option_by_name('maxascend').get_value()
|
||||
pid = menu.get_option_by_name('pid').get_value()
|
||||
@ -113,6 +116,10 @@ class HourGlassReport(Report):
|
||||
}
|
||||
self.roundcorners = menu.get_option_by_name('roundcorners').get_value()
|
||||
|
||||
self.ahnentafel = menu.get_option_by_name('ahnentafel').get_value()
|
||||
|
||||
self.ahnentafelnum = menu.get_option_by_name('ahnentafelnum').get_value()
|
||||
|
||||
self.includeid = menu.get_option_by_name('inc_id').get_value()
|
||||
|
||||
arrow_str = menu.get_option_by_name('arrow').get_value()
|
||||
@ -131,8 +138,8 @@ class HourGlassReport(Report):
|
||||
"""
|
||||
Generate the report.
|
||||
"""
|
||||
self.add_person(self.center_person)
|
||||
self.traverse_up(self.center_person, 1)
|
||||
self.add_person(self.center_person, 1)
|
||||
self.traverse_up(self.center_person, 1, 1)
|
||||
self.traverse_down(self.center_person, 1)
|
||||
|
||||
def traverse_down(self, person, gen):
|
||||
@ -153,27 +160,32 @@ class HourGlassReport(Report):
|
||||
# Avoid going down paths twice when descendant cousins marry
|
||||
self.__used_people.append(child_handle)
|
||||
child = self.__db.get_person_from_handle(child_handle)
|
||||
self.add_person(child)
|
||||
self.add_person(child, 0)
|
||||
self.doc.add_link(family.get_gramps_id(),
|
||||
child.get_gramps_id(),
|
||||
head=self.arrowheadstyle,
|
||||
tail=self.arrowtailstyle)
|
||||
self.traverse_down(child, gen+1)
|
||||
|
||||
def traverse_up(self, person, gen):
|
||||
def traverse_up(self, person, gen, sosanumber):
|
||||
"""
|
||||
Recursively find the ancestors of the given person.
|
||||
"""
|
||||
fathersosanumber = sosanumber * 2
|
||||
mothersosanumber = fathersosanumber + 1
|
||||
if gen > self.max_ascend:
|
||||
return
|
||||
family_handle = person.get_main_parents_family_handle()
|
||||
person_id=person.get_gramps_id()
|
||||
if family_handle:
|
||||
family = self.__db.get_family_from_handle(family_handle)
|
||||
family_id = family.get_gramps_id()
|
||||
self.add_family(family)
|
||||
self.doc.add_link(family_id, person.get_gramps_id(),
|
||||
self.doc.add_link(family_id, person_id,
|
||||
head=self.arrowtailstyle,
|
||||
tail=self.arrowheadstyle )
|
||||
father_id = ''
|
||||
mother_id = ''
|
||||
|
||||
# create link from family to father
|
||||
father_handle = family.get_father_handle()
|
||||
@ -181,14 +193,19 @@ class HourGlassReport(Report):
|
||||
# allocate only one father per family
|
||||
self.__family_father.append(family_handle)
|
||||
father = self.__db.get_person_from_handle(father_handle)
|
||||
self.add_person(father)
|
||||
self.add_person(father, fathersosanumber)
|
||||
father_id = father.get_gramps_id()
|
||||
self.doc.add_link(father.get_gramps_id(), family_id,
|
||||
head=self.arrowtailstyle,
|
||||
tail=self.arrowheadstyle )
|
||||
# update node with its father node id
|
||||
self.__node_label[person_id] = [self.__node_label[person_id][0], father_id, self.__node_label[person_id][2]]
|
||||
# no need to go up if he is a father in another family
|
||||
if father_handle not in self.__used_people:
|
||||
self.__used_people.append(father_handle)
|
||||
self.traverse_up(father, gen+1)
|
||||
self.traverse_up(father, gen+1, fathersosanumber)
|
||||
elif family_handle in self.__family_father and self.ahnentafelnum:
|
||||
self.rewrite_sosa_number(self.__db.get_person_from_handle(father_handle).get_gramps_id(), fathersosanumber)
|
||||
|
||||
# create link from family to mother
|
||||
mother_handle = family.get_mother_handle()
|
||||
@ -196,16 +213,39 @@ class HourGlassReport(Report):
|
||||
# allocate only one mother per family
|
||||
self.__family_mother.append(family_handle)
|
||||
mother = self.__db.get_person_from_handle(mother_handle)
|
||||
self.add_person(mother)
|
||||
self.add_person(mother, mothersosanumber)
|
||||
mother_id = mother.get_gramps_id()
|
||||
self.doc.add_link(mother.get_gramps_id(), family_id,
|
||||
head=self.arrowtailstyle,
|
||||
tail=self.arrowheadstyle)
|
||||
# update node with its mother node id
|
||||
self.__node_label[person_id] = [self.__node_label[person_id][0], self.__node_label[person_id][1], mother_id]
|
||||
# no need to go up if she is a mother in another family
|
||||
if mother_handle not in self.__used_people:
|
||||
self.__used_people.append(mother_handle)
|
||||
self.traverse_up(mother, gen+1)
|
||||
self.traverse_up(mother, gen+1, mothersosanumber)
|
||||
elif family_handle in self.__family_mother and self.ahnentafelnum:
|
||||
self.rewrite_sosa_number(self.__db.get_person_from_handle(mother_handle).get_gramps_id(), mothersosanumber)
|
||||
|
||||
def add_person(self, person):
|
||||
if self.ahnentafel and mother_handle and father_handle and father_id != '' and mother_id != '':
|
||||
self.doc.add_link(father_id, mother_id,
|
||||
style='invis')
|
||||
self.doc.add_samerank(father_id, mother_id)
|
||||
|
||||
def rewrite_sosa_number(self, pid, sosanumber):
|
||||
"""
|
||||
Rewrite the Sosa number of a node for multiple sosa member in the tree.
|
||||
"""
|
||||
self.__node_label[pid][0]+=" - #%s" % (sosanumber)
|
||||
self.doc.rewrite_label(pid,self.__node_label[pid][0])
|
||||
|
||||
# Recursively rewrite for all ancestors
|
||||
if self.__node_label[pid][1] != '':
|
||||
self.rewrite_sosa_number(self.__node_label[pid][1], sosanumber*2)
|
||||
if self.__node_label[pid][2] != '':
|
||||
self.rewrite_sosa_number(self.__node_label[pid][2], sosanumber*2+1)
|
||||
|
||||
def add_person(self, person, sosanumber):
|
||||
"""
|
||||
Add a person to the Graph. The node id will be the person's gramps id.
|
||||
"""
|
||||
@ -236,11 +276,17 @@ class HourGlassReport(Report):
|
||||
elif self.includeid == 2: # own line
|
||||
label = "%s \\n(%s%s)\\n(%s)" % (name, birth, death, p_id)
|
||||
|
||||
if self.ahnentafelnum and sosanumber != 0:
|
||||
label +="\\n #%s" % (sosanumber)
|
||||
|
||||
label = label.replace('"', '\\\"')
|
||||
|
||||
(shape, style, color, fill) = self.get_gender_style(person)
|
||||
self.doc.add_node(p_id, label, shape, color, style, fill)
|
||||
|
||||
# save node with them label, father node id, mother node id and sosanumber
|
||||
self.__node_label[p_id] = [label, '', '']
|
||||
|
||||
def add_family(self, family):
|
||||
"""
|
||||
Add a family to the Graph. The node id will be the family's gramps id.
|
||||
@ -352,7 +398,9 @@ class HourGlassOptions(MenuReportOptions):
|
||||
|
||||
stdoptions.add_gramps_id_option(menu, category_name, ownline=True)
|
||||
|
||||
################################
|
||||
category_name = _("Report Options (2)")
|
||||
################################
|
||||
|
||||
stdoptions.add_name_format_option(menu, category_name)
|
||||
|
||||
@ -384,3 +432,13 @@ class HourGlassOptions(MenuReportOptions):
|
||||
color_family = ColorOption(_('Families'), '#ffffe0')
|
||||
color_family.set_help(_('The color to use to display families.'))
|
||||
menu.add_option(category_name, 'colorfamilies', color_family)
|
||||
|
||||
ahnentafelorder = BooleanOption(_("Force Ahnentafel order"), False) # 10826
|
||||
ahnentafelorder.set_help(
|
||||
_("Force Sosa / Sosa-Stradonitz / Ahnentafel layout order for all ancestors, so that fathers are always on the left branch and mothers are on the right branch."))
|
||||
menu.add_option(category_name, "ahnentafel", ahnentafelorder)
|
||||
|
||||
ahnentafelnumvisible = BooleanOption(_("Ahnentafel number visible"), False) # 10826
|
||||
ahnentafelnumvisible.set_help(
|
||||
_("Show Sosa / Sosa-Stradonitz / Ahnentafel number under all others informations."))
|
||||
menu.add_option(category_name, "ahnentafelnum", ahnentafelnumvisible)
|
||||
|
Loading…
Reference in New Issue
Block a user