New 'Include Siblings' feature added.

and got things ready for the report to go in multiple directions
This commit is contained in:
Craig J. Anderson 2015-04-13 14:11:37 -04:00 committed by Ross Gammon
parent ad42e741e2
commit bf7e9d6b0b
2 changed files with 328 additions and 423 deletions

View File

@ -3,7 +3,7 @@
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2007-2008 Brian G. Matherly # Copyright (C) 2007-2008 Brian G. Matherly
# Copyright (C) 2010 Jakim Friant # Copyright (C) 2010 Jakim Friant
# Copyright (C) 2010 Craig J. Anderson # Copyright (C) 2010-2015 Craig J. Anderson
# Copyright (C) 2014 Paul Franklin # Copyright (C) 2014 Paul Franklin
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -28,14 +28,7 @@
# Python modules # Python modules
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
import math from __future__ import division
def log2(val):
"""
Calculate the log base 2 of a value.
"""
return int(math.log(val, 2))
X_INDEX = log2
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -53,6 +46,7 @@ from gramps.gen.plug.report import utils as ReportUtils
from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle, from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle,
FONT_SANS_SERIF, PARA_ALIGN_CENTER) FONT_SANS_SERIF, PARA_ALIGN_CENTER)
from gramps.plugins.lib.libtreebase import * from gramps.plugins.lib.libtreebase import *
from gramps.plugins.lib.librecurse import AscendPerson
PT2CM = ReportUtils.pt2cm PT2CM = ReportUtils.pt2cm
#cm2pt = ReportUtils.cm2pt #cm2pt = ReportUtils.cm2pt
@ -66,51 +60,38 @@ _BORN = _("birth abbreviation|b."),
_DIED = _("death abbreviation|d."), _DIED = _("death abbreviation|d."),
_MARR = _("marriage abbreviation|m."), _MARR = _("marriage abbreviation|m."),
LVL_GEN, LVL_INDX, LVL_Y = range(3)
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# Box classes # Box classes
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class AncestorBoxBase(BoxBase): class PersonBox(BoxBase):
""" The base class for the two boxes used in this report """ """
Calculates information about the box that will print on a page
def __init__(self, boxstr): """
def __init__(self, level):
BoxBase.__init__(self) BoxBase.__init__(self)
self.boxstr = boxstr self.boxstr = "AC2-box"
#self.level = (level[0]-1, level[1])
self.level = level
def y_index(self, max_gen): def __lt__(self, other):
""" Calculate the column or generation that this person is in. """ return self.level[LVL_Y] < other.level[LVL_Y]
x_level = self.level[0]
#Calculate which row in the column of people.
tmp_y = self.level[2] - (2**x_level)
#Calculate which row in the table (yes table) of people.
delta = (2**max_gen) // (2**(x_level))
return int((delta/2) + (tmp_y*delta))
class PersonBox(AncestorBoxBase): class FamilyBox(BoxBase):
""" """
Calculates information about the box that will print on a page Calculates information about the box that will print on a page
""" """
def __init__(self, level): def __init__(self, level):
AncestorBoxBase.__init__(self, "AC2-box") BoxBase.__init__(self)
self.level = (X_INDEX(level), 0, level) self.boxstr = "AC2-fam-box"
#self.level = (level[0]-1, level[1])
self.level = level
class FamilyBox(AncestorBoxBase): def __lt__(self, other):
""" return self.level[LVL_Y] < other.level[LVL_Y]
Calculates information about the box that will print on a page
"""
def __init__(self, level):
AncestorBoxBase.__init__(self, "AC2-fam-box")
self.level = (X_INDEX(level)+1, 1, level)
def y_index(self, max_gen):
""" Calculate the column or generation that this person is in. """
x_level = self.level[0] - 1
#Calculate which row in the column of people.
tmp_y = self.level[2] - (2**x_level)
#Calculate which row in the table (yes table) of people.
delta = (2**max_gen) // (2**(x_level))
return int((delta/2) + (tmp_y*delta))
#------------------------------------------------------------------------ #------------------------------------------------------------------------
@ -156,6 +137,9 @@ class TitleA(TitleBox):
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class CalcItems(object): class CalcItems(object):
""" A helper class to calculate the default box text
and text for each person / marriage
"""
def __init__(self, dbase): def __init__(self, dbase):
__gui = GUIConnect() __gui = GUIConnect()
@ -184,7 +168,7 @@ class CalcItems(object):
def calc_person(self, index, indi_handle, fams_handle): def calc_person(self, index, indi_handle, fams_handle):
working_lines = "" working_lines = ""
if index % 2 == 0 or (index == 1 and self.center_use == 0): if index[1] % 2 == 0 or (index[1] == 1 and self.center_use == 0):
if indi_handle == fams_handle == None: if indi_handle == fams_handle == None:
working_lines = self.__blank_father working_lines = self.__blank_father
else: else:
@ -208,26 +192,39 @@ class CalcItems(object):
return self.__calc_l.calc_lines(indi_handle, fams_handle, return self.__calc_l.calc_lines(indi_handle, fams_handle,
self.disp_marr) self.disp_marr)
class MakeAncestorTree(AscendPerson):
class MakeAncestorTree(object):
""" """
The main procedure to use recursion to make the tree based off of a person. The main procedure to use recursion to make the tree based off of a person.
order of people inserted into Persons is important. order of people inserted into Persons is important.
makes sure that order is done correctly. makes sure that order is done correctly.
""" """
def __init__(self, dbase, canvas, max_gen, inc_marr, fill_out): def __init__(self, dbase, canvas):
_gui = GUIConnect()
AscendPerson.__init__(self, dbase, _gui.maxgen(), _gui.fill_out())
self.database = dbase self.database = dbase
self.canvas = canvas self.canvas = canvas
self.inlc_marr = inc_marr self.inlc_marr = _gui.inc_marr()
self.max_generations = max_gen self.inc_sib = _gui.inc_sib()
self.fill_out = fill_out self.compress_tree = _gui.compress_tree()
self.center_family = None
self.lines = [None] * (_gui.maxgen() + 1)
self.max_generation = 0
self.calc_items = CalcItems(self.database) self.calc_items = CalcItems(self.database)
def add_person_box(self, index, indi_handle, fams_handle): def add_person(self, index, indi_handle, fams_handle):
""" Makes a person box and add that person into the Canvas. """ """ Makes a person box and add that person into the Canvas. """
myself = PersonBox(index) #print str(index) + " add_person " + str(indi_handle)
myself = PersonBox((index[0]-1,) + index[1:])
if index[LVL_GEN] == 1: #Center Person
self.center_family = fams_handle
if index[LVL_GEN] > self.max_generation:
self.max_generation = index[LVL_GEN]
myself.text = self.calc_items.calc_person( myself.text = self.calc_items.calc_person(
index, indi_handle, fams_handle) index, indi_handle, fams_handle)
@ -237,245 +234,131 @@ class MakeAncestorTree(object):
self.canvas.add_box(myself) self.canvas.add_box(myself)
#make the lines
indx = index[LVL_GEN]
self.lines[indx] = myself
if indx > 1:
if self.lines[indx-1].line_to is None:
line = LineBase(self.lines[indx-1])
self.lines[indx-1].line_to = line
self.canvas.add_line(line)
else:
line = self.lines[indx-1].line_to
line.add_to(myself)
return myself return myself
def add_marriage_box(self, index, indi_handle, fams_handle): def add_person_again(self, index, indi_handle, fams_handle):
self.add_person(index, indi_handle, fams_handle)
def add_marriage(self, index, indi_handle, fams_handle):
""" Makes a marriage box and add that person into the Canvas. """ """ Makes a marriage box and add that person into the Canvas. """
myself = FamilyBox(index) if not self.inlc_marr:
return
myself = FamilyBox((index[0]-1,) + index[1:])
#calculate the text. #calculate the text.
myself.text = self.calc_items.calc_marriage(indi_handle, fams_handle) myself.text = self.calc_items.calc_marriage(indi_handle, fams_handle)
self.canvas.add_box(myself) self.canvas.add_box(myself)
def iterate(self, person_handle, index): def y_index(self, x_level, index):
""" Fills out the Ancestor tree as desired/needed. """ Calculate the column or generation that this person is in.
this is an iterative approach. x_level -> 0 to max_gen-1
index -> 1 to (self.max_generation**2)-1
""" """
if self.max_generations < 1: #Calculate which row in the column of people.
tmp_y = index - (2**x_level)
#Calculate which row in the table (yes table) of people.
delta = (2**self.max_generation) // (2**(x_level))
return int((delta/2) + (tmp_y*delta)) -1
def do_y_indx(self):
''' Make the y_index for all boxes
first off of a forumula, then remove blank areas around the edges,
then compress the tree if desired
'''
min_y = self.y_index(self.canvas.boxes[0].level[LVL_GEN],
self.canvas.boxes[0].level[LVL_INDX])
for box in self.canvas.boxes:
if "fam" in box.boxstr:
box.level = box.level + \
(self.y_index(box.level[LVL_GEN]-1, int(box.level[LVL_INDX]/2)),)
else:
box.level = box.level + \
(self.y_index(box.level[LVL_GEN], box.level[LVL_INDX]),)
min_y = min(min_y, box.level[LVL_Y])
#print (str(box.level))
#if a last father (of fathers) does not have a father/parents
#Then there could be a gap. Remove this gap
if min_y > 0:
for box in self.canvas.boxes:
box.level = box.level[:LVL_Y] + (box.level[LVL_Y]-min_y,)
#Now that we have y_index, lets see if we need to squish the tree
self.canvas.boxes.sort() #Sort them on the y_index
if not self.compress_tree:
return
#boxes are already in top down [LVL_Y] form so lets
#set the box in the correct y level depending on compress_tree
y_level = 0
current_y = self.canvas.boxes[0].level[LVL_Y]
for box in self.canvas.boxes:
y_index = box.level[LVL_Y]
if y_index > current_y:
current_y = y_index
y_level += 1
box.level = box.level[:LVL_Y] + (y_level,)
def do_sibs(self):
if not self.inc_sib or self.center_family is None:
return return
person = self.database.get_person_from_handle(person_handle) family = self.database.get_family_from_handle(self.center_family)
if not person: mykids = [kid.ref for kid in family.get_child_ref_list()]
return self.__fill(index,
min(self.fill_out, self.max_generations)
)
if self.max_generations == 1: if len(mykids) == 1: # No other siblings. Don't do anything.
return self.add_person_box(index, person_handle, None)
###########################
#list of boxes
#for each generation (self.max_generations)
__boxes = [None] * self.max_generations
__index = [index]
__fams = [None] * self.max_generations
__pers = [None] * self.max_generations
###########################
#Helper functions:
def _get_family(generation):
person = self.database.get_person_from_handle(__pers[generation-1])
__fams[generation] = person.get_main_parents_family_handle()
def _get_person(generation):
if not __fams[generation]:
__pers[generation] = None
return
family = self.database.get_family_from_handle(__fams[generation])
__pers[generation] = \
family.get_father_handle() \
if __index[generation] % 2 == 0 else \
family.get_mother_handle()
###########################
#Prime the pump
cur_gen = 1 #zero based!
__pers[0] = person_handle
#__fams[0] = person.get_main_parents_family_handle()
#Cur_gen is the current Generation that we are working with
#use a bottom up iterative approach
while cur_gen > 0:
###########################
#Step 1. this level is blank. add our father
if len(__index) == cur_gen:
__index.append(__index[cur_gen-1]*2)
#we will be adding a father here
#Set __fams[cur_gen] and __pers[cur_gen]
_get_family(cur_gen)
_get_person(cur_gen)
if not __pers[cur_gen]:
#Fill in our father
if self.fill_out:
__boxes[cur_gen] = self.__fill(__index[cur_gen],
min(self.fill_out, self.max_generations -
cur_gen))
else:
__boxes[cur_gen] = None
elif cur_gen < self.max_generations-1:
#But first, go to this father first if we can
cur_gen += 1
else:
#found our father. add him
__boxes[cur_gen] = self.add_person_box(__index[cur_gen],
__pers[cur_gen], __fams[cur_gen])
###########################
#Step 1.5. Dad has already been made.
elif __index[cur_gen] % 2 == 0:
###########################
#Step 2. add our kid
__boxes[cur_gen-1] = self.add_person_box(
__index[cur_gen-1],
__pers[cur_gen-1], __fams[cur_gen-1])
###########################
#Step 2.6. line part 1
if __boxes[cur_gen]:
__boxes[cur_gen-1].line_to = LineBase(__boxes[cur_gen-1])
__boxes[cur_gen-1].line_to.add_to(__boxes[cur_gen])
###########################
#Step 2.3. add our marriage
if self.inlc_marr:
if __fams[cur_gen]:
self.add_marriage_box(__index[cur_gen-1],
__pers[cur_gen], __fams[cur_gen])
elif self.fill_out:
self.add_marriage_box(__index[cur_gen-1], None, None)
#Set __fams[cur_gen] and __pers[cur_gen]
#make sure there is a NEW int.
__index.pop()
#not a reference that will clobber dads (other peoples) info
__index.append((__index[cur_gen-1] *2) +1)
_get_person(cur_gen)
if not __pers[cur_gen]:
#Fill in our father
__boxes[cur_gen] = self.__fill(__index[cur_gen],
min(self.fill_out, self.max_generations - cur_gen))
elif cur_gen < self.max_generations-1:
cur_gen += 1
else:
###########################
#Step 3. Now we can make Mom
__boxes[cur_gen] = self.add_person_box( __index[cur_gen],
__pers[cur_gen], __fams[cur_gen])
###########################
#Step 4. Father and Mother are done but only 1/2 line
else:
if cur_gen > 0:
###########################
#Step 2.6. line part 2
if __boxes[cur_gen]:
if not __boxes[cur_gen-1].line_to:
__boxes[cur_gen-1].line_to = \
LineBase(__boxes[cur_gen-1])
__boxes[cur_gen-1].line_to.add_to(__boxes[cur_gen])
__index.pop()
cur_gen -= 1
return __boxes[0]
def __fill(self, index, max_fill):
""" Fills out the Ancestor tree as desired/needed.
this is an iterative approach.
"""
if max_fill < 1:
return return
if max_fill == 1: # The first person is the center person had he/she has our information
return self.add_person_box(index, None, None) center = self.canvas.boxes.pop(self.canvas.boxes.index(self.lines[1]))
line = center.line_to
level = center.level[LVL_Y]
########################### move = level - (len(mykids)//2) + ((len(mykids)+1)%2)
#list of boxes
#for each generation (max_fill)
__boxes = [None] * max_fill
__index = [index]
########################### if move < 0: # more kids than parents. ran off the page. Move them all down
#Prime the pump for box in self.canvas.boxes:
cur_gen = 1 #zero based! box.level = (box.level[0], box.level[1], box.level[2]-move)
#Cur_gen is the current Generation that we are working with move = 0
#use a bottom up iterative approach
while cur_gen > 0:
###########################
#Step 1. this level is blank. add our father
#if __INFO[cur_gen][__index] == 0:
if len(__index) == cur_gen:
__index.append(__index[cur_gen-1]*2)
#we will be adding a father here
if cur_gen < max_fill-1:
#But first, go to this father first if we can
cur_gen += 1
else:
#found our father. add him
__boxes[cur_gen] = self.add_person_box(
__index[cur_gen], None, None)
########################### line.start = []
#Step 1.5. Dad has already been made. r = -1 # if len(mykids)%2 == 1 else 0
elif __index[cur_gen] % 2 == 0: for kid in mykids:
r += 1
me = self.add_person((1, 1, move+r), kid, self.center_family)
line.add_from(me)
#me.level = (0, 1, level - (len(mykids)//2)+r )
###########################
#Step 2. add our kid
__boxes[cur_gen-1] = self.add_person_box(
__index[cur_gen-1], None, None)
###########################
#Step 2.3. add our marriage
if self.inlc_marr and cur_gen <= max_fill+1:
self.add_marriage_box(__index[cur_gen-1], None, None)
###########################
#Step 2.6. line part 1
__boxes[cur_gen-1].line_to = LineBase(__boxes[cur_gen-1])
__boxes[cur_gen-1].line_to.add_to(__boxes[cur_gen])
#make sure there is a NEW int.
__index.pop()
#not a reference that will clobber dads info
__index.append((__index[cur_gen-1] *2) +1)
#__index[cur_gen] +=1
if cur_gen < max_fill-1:
cur_gen += 1
else:
###########################
#Step 3. Now we can make Mom
__boxes[cur_gen] = self.add_person_box(
__index[cur_gen], None, None)
###########################
#Step 4. Father and Mother are done but only 1/2 line
else:
if cur_gen > 0:
###########################
#Step 2.6. line part 2
__boxes[cur_gen-1].line_to.add_to(__boxes[cur_gen])
__index.pop()
cur_gen -= 1
return __boxes[0]
def start(self, person_id): def start(self, person_id):
""" go ahead and make it happen """ """ go ahead and make it happen """
center = self.database.get_person_from_gramps_id(person_id) center = self.database.get_person_from_gramps_id(person_id)
center_h = center.get_handle() center_h = center.get_handle()
self.iterate(center_h, 1) #Step 1. Get the people
self.recurse(center_h)
#Step 2. Calculate the y_index for everyone
self.do_y_indx()
#Step 3. Siblings of the center person
self.do_sibs()
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -483,75 +366,56 @@ class MakeAncestorTree(object):
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# Class rl_Transform # Class lr_Transform
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class RLTransform(): class LRTransform(object):
""" """
setup all of the boxes on the canvas in for a left/right report setup all of the boxes on the canvas in for a left/right report
""" """
def __init__(self, canvas, max_generations, compress_tree): def __init__(self, canvas, max_generations):
self.canvas = canvas self.canvas = canvas
self.rept_opts = canvas.report_opts self.rept_opts = canvas.report_opts
self.max_generations = max_generations
self.compress_tree = compress_tree
self.y_offset = self.rept_opts.littleoffset*2 + self.canvas.title.height self.y_offset = self.rept_opts.littleoffset*2 + self.canvas.title.height
self.__last_y_level = 0
self.__y_level = 0
def __next_y(self, box):
""" boxes are already in top down (.y_cm) form so if we
set the box in the correct y level depending on compress_tree
"""
y_index = box.y_index(self.max_generations+1) -1
if self.compress_tree:
current_y = self.__y_level
if y_index > self.__last_y_level:
self.__last_y_level = y_index
self.__y_level += 1
current_y = self.__y_level
return current_y
else:
return y_index
def _place(self, box): def _place(self, box):
""" put the box in it's correct spot """ """ put the box in it's correct spot """
#1. cm_x #1. cm_x
box.x_cm = self.rept_opts.littleoffset box.x_cm = self.rept_opts.littleoffset
box.x_cm += (box.level[0] * box.x_cm += (box.level[LVL_GEN] *
(self.rept_opts.col_width + self.rept_opts.max_box_width)) (self.rept_opts.col_width + self.rept_opts.max_box_width))
#2. cm_y #2. cm_y
box.y_cm = self.__next_y(box) * self.rept_opts.max_box_height box.y_cm = self.rept_opts.max_box_height + self.rept_opts.box_pgap
box.y_cm *= box.level[LVL_Y]
box.y_cm += self.y_offset box.y_cm += self.y_offset
#if box.height < self.rept_opts.max_box_height: #if box.height < self.rept_opts.max_box_height:
# box.y_cm += ((self.rept_opts.max_box_height - box.height) /2) # box.y_cm += ((self.rept_opts.max_box_height - box.height) /2)
def place(self): def place(self):
""" step through boxes so they can be put in the right spot """ """ Step through boxes so they can be put in the right spot """
#prime the pump #prime the pump
self.__last_y_level = \ self.__last_y_level = self.canvas.boxes[0].level[LVL_Y]
self.canvas.boxes[0].y_index(self.max_generations+1) -1
#go #go
for box in self.canvas.boxes: for box in self.canvas.boxes:
self._place(box) self._place(box)
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# class make_report # class make_report
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class MakeReport(): class MakeReport(object):
def __init__(self, dbase, doc, canvas, def __init__(self, dbase, doc, canvas, font_normal):
font_normal, inlc_marr, compress_tree):
self.database = dbase self.database = dbase
self.doc = doc self.doc = doc
self.canvas = canvas self.canvas = canvas
self.font_normal = font_normal self.font_normal = font_normal
self.inlc_marr = inlc_marr
self.compress_tree = compress_tree _gui = GUIConnect()
self.inlc_marr = _gui.inc_marr()
self.compress_tree = _gui.compress_tree()
self.mother_ht = self.father_ht = 0 self.mother_ht = self.father_ht = 0
self.max_generations = 0 self.max_generations = 0
@ -567,20 +431,20 @@ class MakeReport():
if box.width > self.canvas.report_opts.max_box_width: if box.width > self.canvas.report_opts.max_box_width:
self.canvas.report_opts.max_box_width = box.width #+ box.shadow self.canvas.report_opts.max_box_width = box.width #+ box.shadow
if box.level[2] > 0: if box.level[LVL_Y] > 0:
if box.level[2] % 2 == 0 and box.height > self.father_ht: if box.level[LVL_INDX] % 2 == 0 and box.height > self.father_ht:
self.father_ht = box.height self.father_ht = box.height
elif box.level[2] % 2 == 1 and box.height > self.mother_ht: elif box.level[LVL_INDX] % 2 == 1 and box.height > self.mother_ht:
self.mother_ht = box.height self.mother_ht = box.height
tmp = log2(box.level[2]) if box.level[LVL_GEN] > self.max_generations:
if tmp > self.max_generations: self.max_generations = box.level[LVL_GEN]
self.max_generations = tmp
def get_generations(self): def get_generations(self):
return self.max_generations return self.max_generations
def start(self): def start(self):
__gui = GUIConnect()
# 1. # 1.
#set the sizes for each box and get the max_generations. #set the sizes for each box and get the max_generations.
self.father_ht = 0.0 self.father_ht = 0.0
@ -605,12 +469,11 @@ class MakeReport():
# 2. # 2.
#setup the transform class to move around the boxes on the canvas #setup the transform class to move around the boxes on the canvas
transform = RLTransform(self.canvas, transform = LRTransform(self.canvas, self.max_generations)
self.max_generations, self.compress_tree)
transform.place() transform.place()
class GUIConnect(): class GUIConnect(object):
""" This is a BORG object. There is ONLY one. """ This is a BORG object. There is ONLY one.
This give some common routines that EVERYONE can use like This give some common routines that EVERYONE can use like
get the value from a GUI variable get the value from a GUI variable
@ -643,6 +506,21 @@ class GUIConnect():
else: else:
return TitleN(doc, self._locale) return TitleN(doc, self._locale)
def inc_marr(self):
return self.get_val("inc_marr")
def inc_sib(self):
return self.get_val("inc_siblings")
def maxgen(self):
return self.get_val("maxgen")
def fill_out(self):
return self.get_val("fill_out")
def compress_tree(self):
return self.get_val("compress_tree")
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# AncestorTree # AncestorTree
@ -717,9 +595,7 @@ class AncestorTree(Report):
#make the tree onto the canvas #make the tree onto the canvas
inlc_marr = self.connect.get_val("inc_marr") inlc_marr = self.connect.get_val("inc_marr")
self.max_generations = self.connect.get_val('maxgen') self.max_generations = self.connect.get_val('maxgen')
fillout = self.connect.get_val('fill_out') tree = MakeAncestorTree(database, self.canvas)
tree = MakeAncestorTree(database, self.canvas, self.max_generations,
inlc_marr, fillout)
tree.start(self.connect.get_val('pid')) tree.start(self.connect.get_val('pid'))
tree = None tree = None
@ -734,9 +610,7 @@ class AncestorTree(Report):
self.canvas.add_title(title) self.canvas.add_title(title)
#make the report as big as it wants to be. #make the report as big as it wants to be.
compress = self.connect.get_val('compress_tree') report = MakeReport(database, self.doc, self.canvas, font_normal)
report = MakeReport(database, self.doc, self.canvas, font_normal,
inlc_marr, compress)
report.start() report.start()
self.max_generations = report.get_generations() #already know self.max_generations = report.get_generations() #already know
report = None report = None
@ -790,6 +664,8 @@ class AncestorTree(Report):
if prnnum: if prnnum:
page_num_box = PageNumberBox(self.doc, 'AC2-box', self._locale) page_num_box = PageNumberBox(self.doc, 'AC2-box', self._locale)
#TODO - Here
##################### #####################
#ok, everyone is now ready to print on the canvas. Paginate? #ok, everyone is now ready to print on the canvas. Paginate?
self.canvas.paginate(colsperpage, one_page) self.canvas.paginate(colsperpage, one_page)
@ -895,9 +771,10 @@ class AncestorTreeOptions(MenuReportOptions):
pid.set_help(_("The center person for the tree")) pid.set_help(_("The center person for the tree"))
menu.add_option(category_name, "pid", pid) menu.add_option(category_name, "pid", pid)
stdoptions.add_name_format_option(menu, category_name) siblings = BooleanOption(_('Include siblings of the center person'), False)
siblings.set_help(_("Whether to only display the center person or all "
stdoptions.add_private_data_option(menu, category_name) "of his/her siblings too"))
menu.add_option(category_name, "inc_siblings", siblings)
self.max_gen = NumberOption(_("Generations"), 10, 1, 50) self.max_gen = NumberOption(_("Generations"), 10, 1, 50)
self.max_gen.set_help(_("The number of generations to include " self.max_gen.set_help(_("The number of generations to include "
@ -928,12 +805,26 @@ class AncestorTreeOptions(MenuReportOptions):
#Spouse_disp.set_help(_("Show spouses of the center person?")) #Spouse_disp.set_help(_("Show spouses of the center person?"))
#menu.add_option(category_name, "Spouse_disp", Spouse_disp) #menu.add_option(category_name, "Spouse_disp", Spouse_disp)
centerDisp = EnumeratedListOption(_("Center person uses\n" ##################
"which format"), 0) category_name = _("Report Options")
centerDisp.add_item( 0, _("Use Fathers Display format"))
centerDisp.add_item( 1, _("Use Mothers display format")) self.title = EnumeratedListOption(_("Report Title"), 0)
centerDisp.set_help(_("Which Display format to use the center person")) self.title.add_item(0, _("Do not include a title"))
menu.add_option(category_name, "center_uses", centerDisp) self.title.add_item(1, _("Include Report Title"))
self.title.set_help(_("Choose a title for the report"))
menu.add_option(category_name, "report_title", self.title)
border = BooleanOption(_('Include a border'), False)
border.set_help(_("Whether to make a border around the report."))
menu.add_option(category_name, "inc_border", border)
prnnum = BooleanOption(_('Include Page Numbers'), False)
prnnum.set_help(_("Whether to print page numbers on each page."))
menu.add_option(category_name, "inc_pagenum", prnnum)
stdoptions.add_private_data_option(menu, category_name)
stdoptions.add_name_format_option(menu, category_name)
stdoptions.add_localization_option(menu, category_name) stdoptions.add_localization_option(menu, category_name)
@ -943,7 +834,7 @@ class AncestorTreeOptions(MenuReportOptions):
disp = TextOption(_("Father\nDisplay Format"), disp = TextOption(_("Father\nDisplay Format"),
["$n", ["$n",
"%s $b" %_BORN, "%s $b" %_BORN,
"-{%s $d}" %_DIED] ) "-{%s $d}" %_DIED])
disp.set_help(_("Display format for the fathers box.")) disp.set_help(_("Display format for the fathers box."))
menu.add_option(category_name, "father_disp", disp) menu.add_option(category_name, "father_disp", disp)
@ -966,6 +857,13 @@ class AncestorTreeOptions(MenuReportOptions):
dispMom.set_help(_("Display format for the mothers box.")) dispMom.set_help(_("Display format for the mothers box."))
menu.add_option(category_name, "mother_disp", dispMom) menu.add_option(category_name, "mother_disp", dispMom)
centerDisp = EnumeratedListOption(_("Center person uses\n"
"which format"), 0)
centerDisp.add_item(0, _("Use Fathers Display format"))
centerDisp.add_item(1, _("Use Mothers display format"))
centerDisp.set_help(_("Which Display format to use the center person"))
menu.add_option(category_name, "center_uses", centerDisp)
incmarr = BooleanOption(_('Include Marriage box'), False) incmarr = BooleanOption(_('Include Marriage box'), False)
incmarr.set_help( incmarr.set_help(
_("Whether to include a separate marital box in the report")) _("Whether to include a separate marital box in the report"))
@ -979,9 +877,9 @@ class AncestorTreeOptions(MenuReportOptions):
category_name = _("Size") category_name = _("Size")
self.scale = EnumeratedListOption(_("Scale tree to fit"), 0) self.scale = EnumeratedListOption(_("Scale tree to fit"), 0)
self.scale.add_item( 0, _("Do not scale tree")) self.scale.add_item(0, _("Do not scale tree"))
self.scale.add_item( 1, _("Scale tree to fit page width only")) self.scale.add_item(1, _("Scale tree to fit page width only"))
self.scale.add_item( 2, _("Scale tree to fit the size of the page")) self.scale.add_item(2, _("Scale tree to fit the size of the page"))
self.scale.set_help( self.scale.set_help(
_("Whether to scale the tree to fit a specific paper size") _("Whether to scale the tree to fit a specific paper size")
) )
@ -1015,9 +913,9 @@ class AncestorTreeOptions(MenuReportOptions):
else: else:
self.__onepage = None self.__onepage = None
self.box_Y_sf = NumberOption(_("inter-box Y scale factor"), self.box_Y_sf = NumberOption(_("inter-box scale factor"),
1.00, 0.10, 2.00, 0.01) 1.00, 0.10, 2.00, 0.01)
self.box_Y_sf.set_help(_("Make the inter-box Y bigger or smaller")) self.box_Y_sf.set_help(_("Make the inter-box spacing bigger or smaller"))
menu.add_option(category_name, "box_Yscale", self.box_Y_sf) menu.add_option(category_name, "box_Yscale", self.box_Y_sf)
self.box_shadow_sf = NumberOption(_("box shadow scale factor"), self.box_shadow_sf = NumberOption(_("box shadow scale factor"),
@ -1026,29 +924,31 @@ class AncestorTreeOptions(MenuReportOptions):
menu.add_option(category_name, "shadowscale", self.box_shadow_sf) menu.add_option(category_name, "shadowscale", self.box_shadow_sf)
##################
category_name = _("Replace")
repldisp = TextOption(
_("Replace Display Format:\n'Replace this'/' with this'"),
[])
repldisp.set_help(_("i.e.\nUnited States of America/U.S.A"))
menu.add_option(category_name, "replace_list", repldisp)
################## ##################
category_name = _("Include") category_name = _("Include")
self.title = EnumeratedListOption(_("Report Title"), 0)
self.title.add_item( 0, _("Do not include a title"))
self.title.add_item( 1, _("Include Report Title"))
self.title.set_help(_("Choose a title for the report"))
menu.add_option(category_name, "report_title", self.title)
border = BooleanOption(_('Include a border'), False)
border.set_help(_("Whether to make a border around the report."))
menu.add_option(category_name, "inc_border", border)
prnnum = BooleanOption(_('Include Page Numbers'), False)
prnnum.set_help(_("Whether to print page numbers on each page."))
menu.add_option(category_name, "inc_pagenum", prnnum)
self.__blank = BooleanOption(_('Include Blank Pages'), True) self.__blank = BooleanOption(_('Include Blank Pages'), True)
self.__blank.set_help(_("Whether to include pages that are blank.")) self.__blank.set_help(_("Whether to include pages that are blank."))
menu.add_option(category_name, "inc_blank", self.__blank) menu.add_option(category_name, "inc_blank", self.__blank)
self.__check_blank() self.__check_blank()
self.__include_images = BooleanOption(
_('Include thumbnail images of people'), False)
self.__include_images.set_help(
_("Whether to include thumbnails of people."))
menu.add_option(category_name, "includeImages", self.__include_images)
#category_name = _("Notes") #category_name = _("Notes")
self.usenote = BooleanOption(_('Include a note'), False) self.usenote = BooleanOption(_('Include a note'), False)
@ -1064,7 +964,7 @@ class AncestorTreeOptions(MenuReportOptions):
locales = NoteType(0, 1) locales = NoteType(0, 1)
self.notelocal = EnumeratedListOption(_("Note Location"), 0) self.notelocal = EnumeratedListOption(_("Note Location"), 0)
for num, text in locales.note_locals(): for num, text in locales.note_locals():
self.notelocal.add_item( num, text ) self.notelocal.add_item(num, text)
self.notelocal.set_help(_("Where to place the note.")) self.notelocal.set_help(_("Where to place the note."))
menu.add_option(category_name, "note_place", self.notelocal) menu.add_option(category_name, "note_place", self.notelocal)
@ -1074,17 +974,17 @@ class AncestorTreeOptions(MenuReportOptions):
else: else:
value = True value = True
off = value and (self.scale.get_value() != 2) off = value and (self.scale.get_value() != 2)
self.__blank.set_available( off ) self.__blank.set_available(off)
def __fillout_vals(self): def __fillout_vals(self):
max_gen = self.max_gen.get_value() max_gen = self.max_gen.get_value()
old_val = self.fillout.get_value() old_val = self.fillout.get_value()
item_list = [] item_list = []
item_list.append([0, _("No generations of empty boxes " item_list.append([0, _("No generations of empty boxes "
"for unknown ancestors") ]) "for unknown ancestors")])
if max_gen > 1: if max_gen > 1:
item_list.append([1, _("One Generation of empty boxes " item_list.append([1, _("One Generation of empty boxes "
"for unknown ancestors") ]) "for unknown ancestors")])
item_list.extend([itr, str(itr) + item_list.extend([itr, str(itr) +
_(" Generations of empty boxes for unknown ancestors")] _(" Generations of empty boxes for unknown ancestors")]
@ -1095,7 +995,6 @@ class AncestorTreeOptions(MenuReportOptions):
if old_val+2 > len(item_list): if old_val+2 > len(item_list):
self.fillout.set_value(len(item_list) -2) self.fillout.set_value(len(item_list) -2)
def make_default_style(self, default_style): def make_default_style(self, default_style):
"""Make the default output style for the Ancestor Tree.""" """Make the default output style for the Ancestor Tree."""
@ -1147,12 +1046,13 @@ class AncestorTreeOptions(MenuReportOptions):
graph_style.set_fill_color((255, 255, 255)) graph_style.set_fill_color((255, 255, 255))
default_style.add_draw_style("AC2-note-box", graph_style) default_style.add_draw_style("AC2-note-box", graph_style)
graph_style = GraphicsStyle() # TODO - Why is this here twice?
graph_style.set_paragraph_style("AC2-Title") #graph_style = GraphicsStyle()
graph_style.set_color((0, 0, 0)) #graph_style.set_paragraph_style("AC2-Title")
graph_style.set_fill_color((255, 255, 255)) #graph_style.set_color((0, 0, 0))
graph_style.set_line_width(0) #graph_style.set_fill_color((255, 255, 255))
default_style.add_draw_style("AC2-Title", graph_style) #graph_style.set_line_width(0)
#default_style.add_draw_style("AC2-Title", graph_style)
graph_style = GraphicsStyle() graph_style = GraphicsStyle()
default_style.add_draw_style("AC2-line", graph_style) default_style.add_draw_style("AC2-line", graph_style)

View File

@ -510,21 +510,26 @@ class AscendPerson(_StopRecurse, _PersonSeen):
if father_handle and mother_handle: if father_handle and mother_handle:
break break
# we have a valid person, add him/her # we have a valid person, add him/her
self._add_person((generation, index), person_handle, fam_handle) self._add_person((generation, index), person_handle, fam_handle)
# has the user canceled recursion? # has the user canceled recursion?
if not self.can_recurse(): if not self.can_recurse():
self.continue_recursion() self.continue_recursion()
return return
# Recursively call the function. It is okay if the handle is None, # Recursively call the function. It is okay if the handle is None,
self.__iterate(father_handle, generation+1, index*2) #recurse on dad self.__iterate(father_handle, generation+1, index*2) #recurse on dad
if generation < self.max_generations or self.fill_out > 0: if generation < self.max_generations:
if father_handle is not None: # Stil winin max_generations if father_handle is not None: # Stil winin max_generations
self.add_marriage((generation+1, index*2), father_handle, fam_handle) self.add_marriage((generation+1, index*2), father_handle, fam_handle)
else: elif mother_handle is not None:
self.add_marriage((generation+1, index*2), mother_handle, fam_handle) self.add_marriage((generation+1, index*2), mother_handle, fam_handle)
elif fam_handle is not None:
self.add_marriage((generation+1, index*2), None, fam_handle)
elif self.fill_out > 0:
self.add_marriage((generation+1, index*2), None, None)
if not self.can_recurse(): if not self.can_recurse():
self.continue_recursion() self.continue_recursion()
return return