gramps/src/plugins/lib/libtreebase.py
Craig J. Anderson 1a3a101420 Fixed issue 4670.
'one_page' option in the Ancestor/Descendant graphical repororts did not 
change the page type to 'custom'.
also landscape orientation did not switch the page.height and page.width
properties which made items print outside the page and give infinate loop
errors.



svn: r16708
2011-02-24 17:11:35 +00:00

905 lines
33 KiB
Python

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008-2010 Craig J. Anderson
#
# 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id: Descendant.py .... ander882 $
"""Reports/Graphical Reports/Tree_Base"""
#------------------------------------------------------------------------
#
# python modules
#
#------------------------------------------------------------------------
from gen.ggettext import sgettext as _
from gen.plug.report import utils as ReportUtils
from gen.display.name import displayer as name_displayer
from libsubstkeyword import SubstKeywords
PT2CM = ReportUtils.pt2cm
#------------------------------------------------------------------------
#
# Class Calc_Lines
#
#------------------------------------------------------------------------
class CalcLines(object):
""" wrapper for libsubstkeyword and added functionality for
replacements.
Receive: Individual and family handle, and display format [string]
return: [Text] ready for a box.
"""
def __init__(self, dbase, repl):
self.database = dbase
self.display_repl = repl
#self.default_string = default_str
def calc_lines(self, _indi_handle, _fams_handle, workinglines):
"""
In this pass we will:
1. make our text and do our replacements
2. remove any extra (unwanted) lines with the compres option
"""
####################
#1.1 Get our line information here
subst = SubstKeywords(self.database, _indi_handle, _fams_handle)
lines = subst.replace_and_clean(workinglines)
####################
#1.2 do our replacements
lns = []
for line in lines:
for pair in self.display_repl:
if pair.count("/") == 1:
repl = pair.split("/", 1)
line = line.replace(repl[0], repl[1])
lns.append(line)
return lns
#------------------------------------------------------------------------
#
# Class Canvas/Pages
#
#------------------------------------------------------------------------
class Page(object):
""" This class is a printable page.
Offsets from the canvas, Page numbers
boxes and lines
"""
def __init__(self, doc, canvas):
#parts from canvas
self.doc = doc
self.canvas = canvas
#parts about the page
self.page_x_offset = 0
self.page_y_offset = 0
self.x_page_num = 0
self.y_page_num = 0
self.boxes = [] #All object must derive from BoxBase
self.lines = [] #All must derive form Linebase
self.note = None
def is_blank(self):
""" Am I a blank page? Notes and Titles are boxes too """
return self.boxes == [] and self.lines == []
def add_box(self, box):
""" The box must derive from class Box_Base(Object): """
self.boxes.append(box)
box.page = self
def add_line(self, line):
""" Add a line onto this page """
self.lines.append(line)
def draw_border(self, line_name):
if self.y_page_num == 0:
self.doc.draw_line(line_name, 0, 0,
self.doc.get_usable_width(), 0)
if self.x_page_num == 0:
self.doc.draw_line(line_name, 0, 0, 0,
self.doc.get_usable_height())
if self.y_page_num == self.canvas.y_pages-1:
self.doc.draw_line(line_name, 0,
self.doc.get_usable_height(),
self.doc.get_usable_width(),
self.doc.get_usable_height())
if self.x_page_num == self.canvas.x_pages-1:
self.doc.draw_line(line_name, self.doc.get_usable_width(),
0, self.doc.get_usable_width(),
self.doc.get_usable_height())
def display(self):
""" Display all boxes and lines that are on this page """
for box in self.boxes:
box.display()
for line in self.lines:
line.display(self)
class Canvas(Page):
""" The Canvas is two things.
The all in one canvas. a canvas is a page of unlimited size
a group of pages. each page is set is size and shows only a
part of what is on the entire canvas
"""
def __init__(self, doc):
Page.__init__(self, doc, self)
self.doc = doc
self.report_opts = None
#How many pages are there in the report. one more than real.
self.x_pages = 1
self.y_pages = 1
self.__pages = {(0, 0): self} #set page 0,0 to me.
self.__fonts = {} #keep a list of fonts so we don't have to lookup.
self.title = None
self.note = None
def __new_page(self, x_page, y_page, x_offset, y_offset):
""" Make a new page. This will only happen if we are
paginating (making new pages to hold parts of the canvas) """
if x_page >= self.x_pages:
self.x_pages = x_page + 1
new_page = Page(self.doc, self)
new_page.x_page_num = x_page
new_page.y_page_num = y_page
new_page.page_x_offset = x_offset
new_page.page_y_offset = y_offset
self.__pages[x_page, y_page] = new_page
return new_page
def sort_boxes_on_y_cm(self):
""" sorts the list of boxes on the canvas by .y_cm (top down) """
self.boxes.sort( key=lambda box: box.y_cm)
def add_title(self, title):
""" The title must derive from class TitleBox(BoxBase): """
self.title = title
def add_note(self, note):
""" The note must derive from class NoteBox(BoxBase, NoteType) """
self.note = note
self.set_box_height_width(self.note)
def __get_font(self, box):
""" returns the font used by a box. makes a list of all seen fonts
to be faster. If a new is found, run through the process to get it """
if not self.__fonts.has_key(box.boxstr):
style_sheet = self.doc.get_style_sheet()
style_name = style_sheet.get_draw_style(box.boxstr)
style_name = style_name.get_paragraph_style()
self.__fonts[box.boxstr] = \
style_sheet.get_paragraph_style(style_name).get_font()
return self.__fonts[box.boxstr]
def get_report_height_width(self):
""" returns the (max width, max height) of the report
This does not take into account any shadows """
max_width = 0
max_height = 0
for box in self.boxes:
tmp = box.x_cm + box.width
if tmp > max_width:
max_width = tmp
tmp = box.y_cm + box.height
if tmp > max_height:
max_height = tmp
max_width += self.doc.report_opts.box_shadow
max_width += self.doc.report_opts.littleoffset
max_height += self.doc.report_opts.box_shadow
max_height += self.doc.report_opts.littleoffset
return (max_width, max_height)
def __scale_canvas(self, scale_amount):
""" scales everything up/down depending upon scale_amount """
self.doc.report_opts.scale_everything(scale_amount)
self.title.scale(scale_amount)
if self.note is not None:
self.note.scale(scale_amount)
#scale down everyone!
for box in self.boxes:
box.scale(scale_amount)
def set_box_height_width(self, box):
""" Sets the .width and .height of a box. """
if box.boxstr == "None":
box.height = box.width = 0
return
font = self.__get_font(box)
#####################
#Get the width
for line in box.text:
width = self.doc.string_width(font, line)
width = PT2CM(width)
if width > box.width:
box.width = width
#####################
#Get the height
height = len(box.text) * font.get_size() * 1.5
height += 1.0/2.0 * font.get_size() #funny number(s) based upon font.
box.height = PT2CM(height)
def page_count(self, incblank):
count = 0
if incblank:
return self.y_pages * self.x_pages
for y_p in range(self.y_pages):
for x_p in range(self.x_pages):
if self.__pages.has_key((x_p, y_p)):
count += 1
return count
def page_iter_gen(self, incblank):
""" generate the pages of the report. do so in a left to right
up down approach. incblank asks to include blank pages """
blank = Page(self.doc, self)
for y_p in range(self.y_pages):
for x_p in range(self.x_pages):
if self.__pages.has_key((x_p, y_p)):
yield self.__pages[(x_p, y_p)]
else:
if incblank:
blank.x_page_num = x_p
blank.y_page_num = y_p
yield blank
def __add_box_to_page(self, x_page, y_page, x_offset, y_offset, box):
""" adds a box to a page. If the page is not there, make it first """
if not self.__pages.has_key((x_page, y_page)):
#Add the new page into the dictionary
self.__new_page(x_page, y_page, x_offset, y_offset)
#Add the box into the page
self.__pages[x_page, self.y_pages-1].add_box(box)
def scale_report(self, one_page, scale_to_width, scale_to_height):
""" We have a report in its full size (on the canvas
and pages to print on. scale one or both as needed/desired.
- one_page, boolean. Whether to make the page(or parts of) the size
of the report
- scale_to_width, boolean. Scale the report width to the page size?
- scale_to_height, boolean. Scale the report height to page size?
"""
if scale_to_width or scale_to_height:
max_width, max_height = self.canvas.get_report_height_width()
#max_width += self.doc.report_opts.littleoffset
#max_height += self.doc.report_opts.littleoffset
"""
calc - Calculate the scale amount (if any).
<1 everything is smaller to fit on the page
1 == no scaling
>1 make everything bigger to fill out the page
"""
scale = 1
scaled_report_to = None
#####################
#scale the report option - width
if scale_to_width:
#Check the width of the title
title_width = self.title.width
title_width += self.doc.report_opts.littleoffset * 2
max_width = max(title_width, max_width)
#This will be our base amount and
#then we will decrease only as needed from here.
scale = self.doc.get_usable_width() / max_width
scaled_report_to = "width"
#####################
#scale the report option - height
if scale_to_height:
tmp = self.doc.get_usable_height() / max_height
if not scale_to_width or tmp < scale:
scale = tmp
scaled_report_to = "height"
#Now I have the scale amount
if scale != 1: #scale everything on the canvas
self.__scale_canvas(scale)
#####################
#Scale the page option
if one_page:
#user wants PAGE to be the size of the report.
size = self.doc.paper.get_size()
size.name = 'custom'
max_width, max_height = \
self.canvas.get_report_height_width()
if scaled_report_to != "width":
#calculate the width of the report
#max_width += self.doc.report_opts.littleoffset
max_width += self.doc.paper.get_left_margin()
max_width += self.doc.paper.get_right_margin()
#calculate the width of the title
title_width = self.canvas.title.width
title_width += self.doc.paper.get_left_margin()
title_width += self.doc.paper.get_right_margin()
title_width += self.doc.report_opts.littleoffset
max_width = max(title_width, max_width)
size.set_width(max_width)
if scaled_report_to != "height":
#calculate the height of the report
max_height += self.doc.paper.get_top_margin()
max_height += self.doc.paper.get_bottom_margin()
#max_height += self.doc.report_opts.littleoffset
size.set_height(max_height)
return scale
def __paginate_x_offsets(self, colsperpage):
""" Go through the boxes and get the x page offsets """
#fix soon. should not use .level
liloffset = self.doc.report_opts.littleoffset
x_page_offsets = {0:0} #change me to [] ???
for box in self.boxes:
x_index = box.level[0]
x_page = x_index / colsperpage
if x_page not in x_page_offsets and x_index % colsperpage == 0:
x_page_offsets[x_page] = box.x_cm - liloffset
if x_page >= self.x_pages:
self.x_pages = x_page+1
return x_page_offsets
def __paginate_y_pages(self, colsperpage, x_page_offsets):
""" Go through the boxes and put each one in a page
note that the self.boxes needs to be sorted by .y_cm """
page_y_top = [0]
page_y_height = [self.doc.get_usable_height()]
liloffset = self.doc.report_opts.littleoffset
for box in self.boxes:
#check to see if this box cross over to the next (y) page
height = box.y_cm + liloffset + box.height #+ box.shadow/2
if height > page_y_height[-1]:
#we went off the end
page_y_height.append(box.y_cm - liloffset + page_y_height[0])
page_y_top.append(box.y_cm - liloffset)
self.y_pages = len(page_y_height)
#Calculate my (x) page
#fix soon. should not use .level
x_page = box.level[0] / colsperpage
self.__add_box_to_page(x_page, self.y_pages-1,
x_page_offsets[x_page],
page_y_top[self.y_pages-1],
box)
#if not self.__pages.has_key((x_page, self.y_pages-1)):
# #Add the new page into the dictionary
# self.__new_page(x_page, self.y_pages-1,
# )
#
##Add the box into the page
#self.__pages[x_page, self.y_pages-1].add_box(box)
return page_y_top
def __paginate_note(self, x_page_offsets, page_y_top):
""" Put the note on first. it can be overwritten by other
boxes but it CAN NOT overwrite a box. """
x_page, y_page = self.note.set_on_page(self)
if not self.__pages.has_key((x_page, y_page)):
#Add the new page into the dictionary
self.__new_page(x_page, y_page,
x_page_offsets[x_page], page_y_top[y_page])
#Add the box into the page
self.__pages[x_page, y_page].boxes.insert(0, self.note)
self.note.doc = self.doc
self.note.page = self
def __paginate_lines(self, x_page_offsets, page_y_top):
""" Step three go through the lines and put each in page(s) """
for box1 in self.boxes:
if not box1.line_to:
continue
line = box1.line_to
pages = [box1.page.y_page_num]
end = line.start + line.end
x_page = box1.page.x_page_num
start_y_page = end[0].page.y_page_num
end_y_page = end[0].page.y_page_num
for box in end:
y_page = box.page.y_page_num
if y_page not in pages:
if not self.__pages.has_key((x_page, y_page)):
#Add the new page into the dictionary
self.__new_page(x_page, y_page,
x_page_offsets[x_page],
page_y_top[y_page])
self.__pages[x_page, y_page].add_line(box1.line_to)
pages.append(y_page)
if y_page < start_y_page:
start_y_page = y_page
if y_page > end_y_page:
end_y_page = y_page
#if len(end) = 2 & end[0].y_page = 0 & end[1].y_page = 4
#the line will not print on y_pages 1,2,3. Fix that here.
#x_page = start_x_page
for y_page in range(start_y_page, end_y_page+1):
if y_page not in pages:
if not self.__pages.has_key((x_page, y_page)):
#Add the new page into the dictionary
self.__new_page(x_page, y_page,
x_page_offsets[x_page],
page_y_top[y_page])
self.__pages[x_page, y_page].add_line(box1.line_to)
def __paginate_title(self, x_page_offsets):
#step four work with the title
if self.title.boxstr == "None":
return
#x_page_offsets[page] tells me the widths I can use
if len(x_page_offsets) > 1:
title_list = self.title.text.split(" ")
title_font = self.__get_font(self.title)
#space_width = PT2CM(self.doc.string_width(title_font," "))
list_title = [title_list.pop(0)]
while len(title_list):
tmp = list_title[-1] + " " + title_list[0]
if PT2CM(self.doc.string_width(title_font, tmp)) > \
x_page_offsets[1]:
list_title.append("")
if list_title[-1] != "":
list_title[-1] += " "
list_title[-1] += title_list.pop(0)
start_page = (len(x_page_offsets) - len(list_title)) / 2
for tmp in range(start_page):
list_title.insert(0, "")
list_title.append("")
#one extra for security. doesn't hurt.
list_title.append("")
x_page = 0
for title in list_title:
if title == "":
x_page += 1
continue
if not self.__pages.has_key((x_page, 0)):
#Add the new page into the dictionary
self.__new_page(x_page, 0, x_page_offsets[1], 0)
title_part = TitleBox(self.doc, self.title.boxstr)
title_part.text = list_title[x_page]
title_part.width = x_page_offsets[1]
#Add the box into the page
self.__pages[x_page, 0].add_box(title_part)
x_page = x_page + 1
else:
self.title.width = self.doc.get_usable_width()
self.__pages[0, 0].add_box(self.title)
def __paginate(self, colsperpage):
""" take the boxes on the canvas and put them into separate pages.
The boxes need to be sorted by y_cm """
liloffset = self.doc.report_opts.littleoffset
self.__pages = {}
x_page_offsets = self.__paginate_x_offsets(colsperpage)
page_y_top = self.__paginate_y_pages(colsperpage, x_page_offsets)
if self.note is not None:
self.__paginate_note(x_page_offsets, page_y_top)
self.__paginate_lines(x_page_offsets, page_y_top)
self.__paginate_title(x_page_offsets)
def paginate(self, colsperpage, one_page_report):
""" self.boxes must be sorted by box.y_cm for this to work. """
if one_page_report:
#self.canvas.add_box(self.canvas.title)
title_part = TitleBox(self.doc, self.title.boxstr)
title_part.text = self.title.text
title_part.width = self.doc.get_usable_width()
self.add_box(title_part)
if self.note is not None:
self.note.set_on_page(self)
self.boxes.insert(0, self.note)
self.note.doc = self.doc
self.note.page = self
else:
self.__paginate(colsperpage)
#------------------------------------------------------------------------
#
# Class Box_Base
#
#------------------------------------------------------------------------
class BoxBase(object):
""" boxes are always in/on a Page
Needed to print are: boxstr, text, x_cm, y_cm, width, height
"""
def __init__(self):
self.page = None
#'None' will cause an error. Sub-classes will init
self.boxstr = "None"
self.text = ""
#level requires ...
# (# - which column am I in (zero based)
# ,# - Am I a (0)direct descendant/ancestor or (>0)other
# , ) - anything else the report needs to run
self.level = (0,0)
self.x_cm = 0.0
self.y_cm = 0.0
self.width = 0.0
self.height = 0.0
self.line_to = None
def scale(self, scale_amount):
""" Scale the amounts """
self.x_cm *= scale_amount
self.y_cm *= scale_amount
self.width *= scale_amount
self.height *= scale_amount
def display(self):
""" display the box accounting for page x, y offsets
Ignore any box with 'None' is boxstr """
if self.boxstr == "None":
return
text = '\n'.join(self.text)
xbegin = self.x_cm - self.page.page_x_offset
ybegin = self.y_cm - self.page.page_y_offset
self.page.doc.draw_box(self.boxstr,
text,
xbegin, ybegin,
self.width, self.height)
#I am responsible for my own lines. Do them here.
if self.line_to:
#draw my line out here.
self.line_to.display(self.page)
if self.page.x_page_num > 0 and self.level[1] == 0 and \
xbegin < self.page.doc.report_opts.littleoffset*2:
#I am a child on the first column
yme = ybegin + self.height/2
self.page.doc.draw_line(self.page.doc.report_opts.line_str, \
0, yme, xbegin, yme)
class TitleBox(BoxBase):
"""
Holds information about the Title that will print on a page
"""
def __init__(self, doc, boxstr):
""" initalize the title box """
BoxBase.__init__(self)
self.doc = doc
self.boxstr = boxstr
if boxstr == "None":
return
self.cm_y = self.doc.report_opts.littleoffset
style_sheet = self.doc.get_style_sheet()
style_name = style_sheet.get_draw_style(self.boxstr)
style_name = style_name.get_paragraph_style()
self.font = style_sheet.get_paragraph_style(style_name).get_font()
def set_box_height_width(self):
if self.boxstr == "None":
return
#fix me. width should be the printable area
self.width = PT2CM(self.doc.string_width(self.font, self.text))
self.height = PT2CM(self.font.get_size() * 1.2)
def _get_names(self, persons):
""" A helper function that receives a list of persons and
returns their names in a list """
return [name_displayer.display(person) for person in persons]
def display(self):
""" display the title box. """
if self.page.y_page_num or self.boxstr == "None":
return
if self.text:
self.doc.center_text(self.boxstr, self.text,
self.width/2, self.y_cm)
class PageNumberBox(BoxBase):
"""
Calculates information about the page numbers that will print on a page
do not put in a value for PageNumberBox.text. this will be calculated for
each page """
def __init__(self, doc, boxstr):
""" initalize the page number box """
BoxBase.__init__(self)
self.doc = doc
self.boxstr = boxstr
def __calc_position(self, page):
""" calculate where I am to print on the page(s) """
self.text = "(%d,%d)"
style_sheet = self.doc.get_style_sheet()
style_name = style_sheet.get_draw_style(self.boxstr)
style_name = style_name.get_paragraph_style()
font = style_sheet.get_paragraph_style(style_name).get_font()
#calcualate how much space is needed
if page.canvas.x_pages > 10:
tmp = "00"
else:
tmp = "0"
if page.canvas.y_pages > 10:
tmp += "00"
else:
tmp += "0"
width = self.doc.string_width(font, '(,)'+tmp)
width = PT2CM(width)
self.width = width
height = font.get_size() * 1.4
height += 0.5/2.0 * font.get_size() #funny number(s) based upon font.
self.height = PT2CM(height)
self.x_cm = self.doc.get_usable_width() - self.width
self.y_cm = self.doc.get_usable_height() - self.height
def display(self, page):
""" If this is the first time I am ran, get my position
then display the page number """
if self.text == "":
self.__calc_position(page)
self.doc.draw_text(self.boxstr,
self.text % (page.x_page_num+1,page.y_page_num+1),
self.x_cm, self.y_cm)
class NoteType(object):
""" Provide the different options (corners) to place the note """
TOPLEFT = 0
TOPRIGHT = 1
BOTTOMLEFT = 2
BOTTOMRIGHT = 3
_DEFAULT = BOTTOMRIGHT
_DATAMAP = [
(TOPLEFT, _("Top Left"), "Top Left"),
(TOPRIGHT, _("Top Right"), "Top Right"),
(BOTTOMLEFT, _("Bottom Left"), "Bottom Left"),
(BOTTOMRIGHT, _("Bottom Right"), "Bottom Right"),
]
def __init__(self, value, exclude=None):
""" initalize GrampsType """
self.value = value
self.exclude = exclude
#GrampsType.__init__(self, value)
def note_locals(self, start=0):
""" generates an int of all the options """
for tuple in self._DATAMAP:
if tuple[0] != self.exclude:
yield tuple[0], tuple[1]
class NoteBox(BoxBase, NoteType):
""" Box that will hold the note to display on the page """
def __init__(self, doc, boxstr, locale, exclude=None):
""" initalize the NoteBox """
BoxBase.__init__(self)
NoteType.__init__(self, locale, exclude)
self.doc = doc
self.boxstr = boxstr
def set_on_page(self, canvas):
""" set the x_cm and y_cm given
self.doc, leloffset, and title_height """
liloffset = self.doc.report_opts.littleoffset
#left or right side
if self.value == NoteType.BOTTOMLEFT or \
self.value == NoteType.TOPLEFT:
self.x_cm = liloffset
else:
self.x_cm = self.doc.get_usable_width() - self.width - liloffset
#top or bottom
if self.value == NoteType.TOPRIGHT or \
self.value == NoteType.TOPLEFT:
self.y_cm = canvas.title.height + liloffset*2
else:
self.y_cm = self.doc.get_usable_height() - self.height - liloffset
""" helper function for canvas.paginate().
return the (x, y) page I want to print on """
if self.value == NoteType.TOPLEFT:
return (0, 0)
elif self.value == NoteType.TOPRIGHT:
return (canvas.x_pages-1, 0)
elif self.value == NoteType.BOTTOMLEFT:
return (0, canvas.y_pages-1)
elif self.value == NoteType.BOTTOMRIGHT:
return (canvas.x_pages-1, canvas.y_pages-1)
def display(self):
""" position the box and display """
title = self.page.canvas.title
title_height = 0
if title is not None:
title_height = title.height
text = '\n'.join(self.text)
self.doc.draw_box(self.boxstr, text,
self.x_cm, self.y_cm,
self.width, self.height)
#------------------------------------------------------------------------
#
# Class Line_base
#
#------------------------------------------------------------------------
class LineBase(object):
""" A simple line class.
self.start is the box that we are drawing a line from
self.end are the boxes that we are drawing lines to.
"""
def __init__(self, start):
#self.linestr = "None"
self.start = [start]
self.end = []
def add_to(self, person):
""" add destination boxes to draw this line to """
self.end.append(person)
def display(self, page):
""" display the line. left to right line. one start, multiple end.
page will tell us what parts of the line we can print """
if self.end == [] and len(self.start) == 1:
return
# y_cm and x_cm start points - take into account page offsets
#yme = self.start.y_cm + self.start.height/2 - page.page_y_offset
#if type(self.start) != type([]):
# self.start = [self.start]
start = self.start[0]
doc = start.page.doc
linestr = doc.report_opts.line_str
xbegin = start.x_cm + start.width - page.page_x_offset
# out 3/4 of the way and x_cm end point(s)
x34 = xbegin + (doc.report_opts.col_width * 3/4)
xend = xbegin + doc.report_opts.col_width
if x34 > 0: # > 0 tell us we are printing on this page.
usable_height = doc.get_usable_height()
#1 - Line from start box out
for box in self.start:
yme = box.y_cm + box.height/2 - page.page_y_offset
if box.page.y_page_num == page.y_page_num:
# and 0 < yme < usable_height and \
doc.draw_line(linestr, xbegin, yme, x34, yme)
#2 - veritcal line
mid = []
for box in self.start + self.end:
tmp = box.y_cm + box.height/2
mid.append(tmp)
mid.sort()
mid = [mid[0]-page.page_y_offset, mid[-1]-page.page_y_offset]
if mid[0] < 0:
mid[0] = 0
if mid[1] > usable_height:
mid[1] = usable_height
#draw the connecting vertical line.
doc.draw_line(linestr, x34, mid[0], x34, mid[1])
else:
x34 = 0
#3 - horizontal line(s)
for box in self.end:
if box.page.y_page_num == page.y_page_num:
yme = box.y_cm + box.height/2 - box.page.page_y_offset
doc.draw_line(linestr, x34, yme, xend, yme)
#------------------------------------------------------------------------
#
# Class report_options
#
#------------------------------------------------------------------------
class ReportOptions(object):
"""
A simple class to hold various report information
Calculates
the gap between persons,
the column width, for lines,
the left hand spacing for spouses (Descendant report only)
"""
def __init__(self, doc, normal_font, normal_line):
""" initalize various report variables that are used """
self.box_pgap = PT2CM(1.25*normal_font.get_size()) #gap between persons
self.box_mgap = self.box_pgap /2 #gap between marriage information
self.box_shadow = PT2CM(normal_font.get_size()) * .6 #normal text
self.spouse_offset = PT2CM(doc.string_width(normal_font, "0"))
self.col_width = PT2CM(doc.string_width(normal_font, "(000,0)"))
self.littleoffset = PT2CM(1)
self.x_cm_cols = [self.littleoffset]
self.line_str = normal_line
#Things that will get added later
self.max_box_width = 0
self.max_box_height = 0
self.scale = 1
def scale_everything(self, amount):
""" Scale the amounts that are needed to generate a report """
self.scale = amount
self.col_width *= amount
self.littleoffset *= amount
self.max_box_width *= amount #box_width
self.spouse_offset *= amount
self.box_shadow *= amount
#=====================================
#"And Jesus said unto them ... , "If ye have faith as a grain of mustard
#seed, ye shall say unto this mountain, Remove hence to younder place; and
#it shall remove; and nothing shall be impossible to you."
#Romans 1:17