* src/ReportUtils.py: added estimate_age and sanitize_person

* src/BaseDoc.py: Add checks attempting to add styles after initializing
the document
* src/docgen/OpenOfficeDoc.py: add init assertions
* src/docgen/PSDrawDoc.py: fix line style in boxes
* src/docgen/SvgDrawDoc.py: fix line style in boxes

* src/ReportUtils.py: added documentation


svn: r3942
This commit is contained in:
Don Allingham 2005-01-20 04:11:13 +00:00
parent b818a15850
commit c39b6ba091
6 changed files with 220 additions and 25 deletions

View File

@ -1,3 +1,14 @@
2005-01-19 Don Allingham <dallingham@users.sourceforge.net>
* src/ReportUtils.py: added estimate_age and sanitize_person
* src/BaseDoc.py: Add checks attempting to add styles after initializing
the document
* src/docgen/OpenOfficeDoc.py: add init assertions
* src/docgen/PSDrawDoc.py: fix line style in boxes
* src/docgen/SvgDrawDoc.py: fix line style in boxes
2005-01-18 Don Allingham <dallingham@users.sourceforge.net>
* src/ReportUtils.py: added documentation
2005-01-18 Martin Hawlisch <Martin.Hawlisch@gmx.de>
* src/NameEdit.py: Fix patronymic show/save.

View File

@ -1114,9 +1114,10 @@ class BaseDoc:
self.media_list = []
self.print_req = 0
self.mode = TEXT_MODE
self.init_called = False
def init(self):
pass
self.init_called = True
def set_mode(self, mode):
self.mode = mode
@ -1189,6 +1190,7 @@ class BaseDoc:
self.title = name
def add_draw_style(self,name,style):
assert(self.init_called==False)
self.draw_styles[name] = GraphicsStyle(style)
def get_draw_style(self,name):
@ -1204,6 +1206,7 @@ class BaseDoc:
@param name: name of the table style
@param style: TableStyle instance to be added
"""
assert(self.init_called==False)
self.table_styles[name] = TableStyle(style)
def add_cell_style(self,name,style):
@ -1213,6 +1216,7 @@ class BaseDoc:
@param name: name of the table cell style
@param style: TableCellStyle instance to be added
"""
assert(self.init_called==False)
self.cell_styles[name] = TableCellStyle(style)
def open(self,filename):
@ -1374,6 +1378,7 @@ class BaseDoc:
def draw_wedge(self, style, centerx, centery, radius, start_angle,
end_angle, short_radius=0):
assert(self.init_called)
while end_angle < start_angle:
end_angle += 360

View File

@ -21,6 +21,9 @@
# $Id$
import Date
import RelLib
#-------------------------------------------------------------------------
#
# Convert points to cm and back
@ -116,7 +119,31 @@ def draw_legend(doc, start_x, start_y, data):
start_y += size * 1.3
def draw_vertical_bar_graph(doc, format, start_x, start_y, height, width, data):
doc.draw_line(format,start_x,start_y,start_x,start_y+height)
"""
Draws a vertical bar chart in the specified document. The data passed
should consist of the actual data. The bars are scaled appropriately by
the routine.
@param doc: Document to which the bar chart should be added
@type doc: BaseDoc derived class
@param start_x: x coordinate in centimeters where the left hand side of the
chart should be. 0 is the left hand edge of the document.
@type start_x: float
@param start_y: y coordinate in centimeters where the top of the chart
should be. 0 is the top edge of the document
@param start_y: float
@param height: height of the graph in centimeters
@type height: float
@param width: width of the graph in centimeters
@type width: float
@param data: List of tuples containing the data to be plotted. The values
are (graphics_format, value), where graphics_format is a BaseDoc
GraphicsStyle, and value is a floating point number. Any other items in
the tuple are ignored. This allows you to share the same data list with
the L{draw_legend} function.
@type data: list
"""
doc.draw_line(format,start_x,start_y+height,start_x,start_y)
doc.draw_line(format,start_x,start_y+height,start_x+width,start_y+height)
largest = 0.0
@ -131,13 +158,158 @@ def draw_vertical_bar_graph(doc, format, start_x, start_y, height, width, data):
start = 0.5*box_width + start_x
for index in range(units):
print height, float(data[index][1]) * scale
size = float(data[index][1]) * scale
doc.draw_bar(data[index][0],start,bottom-size,start+box_width,bottom)
start += box_width * 1.5
def age_of(person):
pass
def estimate_age(db, person):
"""
Estimates the age of a person based off the birth and death
dates of the person. A tuple containing the estimated upper
and lower bounds of the person's age is returned. If either
the birth or death date is missing, a (-1,-1) is returned.
@param db: GRAMPS database to which the Person object belongs
@type db: GrampsDbBase
@param person: Person object to calculate the age of
@type db: Person
@returns: tuple containing the lower and upper bounds of the
person's age, or (-1,-1) if it could not be determined.
@rtype: tuple
"""
bhandle = person.get_birth_handle()
dhandle = person.get_death_handle()
# if either of the events is not defined, return an error message
if not bhandle or not dhandle:
return (-1,-1)
bdata = db.get_event_from_handle(bhandle).get_date_object()
ddata = db.get_event_from_handle(dhandle).get_date_object()
# if the date is not valid, return an error message
if not bdata.get_valid() or not ddata.get_valid():
return (-1,-1)
# if a year is not valid, return an error message
if not bdata.get_year_valid() or not ddata.get_year_valid():
return (-1,-1)
bstart = bdata.get_start_date()
bstop = bdata.get_stop_date()
dstart = ddata.get_start_date()
dstop = ddata.get_stop_date()
def _calc_diff(low,high):
if (low[1],low[0]) > (high[1],high[0]):
return high[2] - low[2] - 1
else:
return high[2] - low[2]
if bstop == Date.EMPTY and dstop == Date.EMPTY:
lower = _calc_diff(bstart,dstart)
age = (lower, lower)
elif bstop == Date.EMPTY:
lower = _calc_diff(bstart,dstart)
upper = _calc_diff(bstart,dstop)
age = (lower,upper)
elif dstop == Date.EMPTY:
lower = _calc_diff(bstop,dstart)
upper = _calc_diff(bstart,dstart)
age = (lower,upper)
else:
lower = _calc_diff(bstop,dstart)
upper = _calc_diff(bstart,dstop)
age = (lower,upper)
return age
def sanitize_person(db,person):
"""
Creates a new Person instance based off the passed Person
instance. The returned instance has all private records
removed from it.
@param db: GRAMPS database to which the Person object belongs
@type db: GrampsDbBase
@param person: source Person object that will be copied with
privacy records removed
@type db: Person
@returns: 'cleansed' Person object
@rtype: Person
"""
new_person = RelLib.Person()
name = person.get_primary_name()
# copy gender
new_person.set_gender(person.get_gender())
# copy names if not private
if not name.get_privacy():
new_person.set_primary_name(name)
new_person.set_nick_name(person.get_nick_name())
for name in person.get_alternate_names():
if not name.get_privacy():
new_person.add_alternate_name(name)
# set complete flag
new_person.set_complete_flag(person.get_complete_flag())
# copy birth event
event_handle = person.get_birth_handle()
event = db.get_event_from_handle(event_handle)
if event and not event.get_privacy():
new_person.set_birth_handle(event_handle)
# copy death event
event_handle = person.get_death_handle()
event = db.get_event_from_handle(event_handle)
if event and not event.get_privacy():
new_person.set_death_handle(event_handle)
# copy event list
for event_handle in person.get_event_list():
event = db.get_event_from_handle(event_handle)
if event and not event.get_privacy():
new_person.add_event_handle(event_handle)
# copy address list
for address in person.get_address_list():
if not address.get_privacy():
new_person.add_address(RelLib.Address(address))
# copy attribute list
for attribute in person.get_attribute_list():
if not attribute.get_privacy():
new_person.add_attribute(RelLib.Attribute(attribute))
# copy URL list
for url in person.get_url_list():
if not url.get_privacy():
new_person.add_url(url)
# copy Media reference list
for obj in person.get_media_list():
new_person.add_media_reference(RelLib.MediaRef(obj))
# copy Family reference list
for handle in person.get_family_handle_list():
new_person.add_family_handle(handle)
# LDS ordinances
ord = person.get_lds_baptism()
if ord:
new_person.set_lds_baptism(ord)
ord = person.get_lds_endowment()
if ord:
new_person.set_lds_endowment(ord)
ord = person.get_lds_sealing()
if ord:
new_person.set_lds_sealing(ord)
return new_person
#-------------------------------------------------------------------------
#
@ -146,7 +318,7 @@ def age_of(person):
#-------------------------------------------------------------------------
def roman(num):
""" Integer to Roman numeral converter for 0 < num < 4000 """
if type(num) != type(0):
if type(num) != int:
return "?"
if not 0 < num < 4000:
return "?"
@ -198,7 +370,7 @@ if __name__ == "__main__":
doc.add_draw_style("blue",g)
g = BaseDoc.GraphicsStyle()
g.set_fill_color((0,255,255))
g.set_fill_color((255,255,0))
g.set_paragraph_style('Normal')
g.set_line_width(1)
doc.add_draw_style("yellow",g)

View File

@ -92,6 +92,9 @@ class OpenOfficeDoc(BaseDoc.BaseDoc):
def init(self):
assert(self.init_called==False)
self.init_called = True
current_locale = locale.getlocale()
self.lang = current_locale[0]
if self.lang:

View File

@ -362,13 +362,14 @@ class PSDrawDoc(BaseDoc.BaseDoc):
self.f.write('1 setgray\n')
self.f.write('fill\n')
self.f.write('newpath\n')
self.f.write('%f cm %f cm moveto\n' % self.translate(x,y))
self.f.write('0 -%f cm rlineto\n' % bh)
self.f.write('%f cm 0 rlineto\n' % bw)
self.f.write('0 %f cm rlineto\n' % bh)
self.f.write('closepath\n')
self.f.write('%.4f setlinewidth\n' % box_style.get_line_width())
self.f.write('%.4f %.4f %.4f setrgbcolor stroke\n' % rgb_color(box_style.get_color()))
if box_style.get_line_width():
self.f.write('%f cm %f cm moveto\n' % self.translate(x,y))
self.f.write('0 -%f cm rlineto\n' % bh)
self.f.write('%f cm 0 rlineto\n' % bw)
self.f.write('0 %f cm rlineto\n' % bh)
self.f.write('closepath\n')
self.f.write('%.4f setlinewidth\n' % box_style.get_line_width())
self.f.write('%.4f %.4f %.4f setrgbcolor stroke\n' % rgb_color(box_style.get_color()))
if text != "":
(text,fdef) = self.encode_text(p,text)
self.f.write(fdef)

View File

@ -141,9 +141,8 @@ class SvgDrawDoc(BaseDoc.BaseDoc):
self.f.write('<line x1="%4.2fcm" y1="%4.2fcm" ' % (x1,y1))
self.f.write('x2="%4.2fcm" y2="%4.2fcm" ' % (x2,y2))
color = s.get_color()
self.f.write(' style="stroke:#%02x%02x%02x; stroke-width:%.2fpt;"/>\n' %
(color[0],color[1],color[2],s.get_line_width()))
self.f.write('style="stroke:#%02x%02x%02x; ' % s.get_color())
self.f.write('stroke-width:%.2fpt;"/>\n' % s.get_line_width())
def draw_path(self,style,path):
stype = self.draw_styles[style]
@ -169,7 +168,8 @@ class SvgDrawDoc(BaseDoc.BaseDoc):
self.f.write('y="%4.2fcm" ' % y1)
self.f.write('width="%4.2fcm" ' % (x2-x1))
self.f.write('height="%4.2fcm" ' % (y2-y1))
self.f.write('style="fill:#ffffff; stroke:#000000; ')
self.f.write('style="fill:##%02x%02x%02x; ' % s.get_fill_color())
self.f.write('stroke:#%02x%02x%02x; ' % s.get_color())
self.f.write('stroke-width:%.2f;"/>\n' % s.get_line_width())
def draw_box(self,style,text,x,y):
@ -182,18 +182,21 @@ class SvgDrawDoc(BaseDoc.BaseDoc):
bh = box_style.get_height()
bw = box_style.get_width()
self.f.write('<rect ')
self.f.write('x="%4.2fcm" ' % (x+0.15))
self.f.write('y="%4.2fcm" ' % (y+0.15))
self.f.write('width="%4.2fcm" ' % bw)
self.f.write('height="%4.2fcm" ' % bh)
self.f.write('style="fill:#808080; stroke:#808080; stroke-width:1;"/>\n')
if box_style.get_shadow():
self.f.write('<rect ')
self.f.write('x="%4.2fcm" ' % (x+0.15))
self.f.write('y="%4.2fcm" ' % (y+0.15))
self.f.write('width="%4.2fcm" ' % bw)
self.f.write('height="%4.2fcm" ' % bh)
self.f.write('style="fill:#808080; stroke:#808080; stroke-width:1;"/>\n')
self.f.write('<rect ')
self.f.write('x="%4.2fcm" ' % x)
self.f.write('y="%4.2fcm" ' % y)
self.f.write('width="%4.2fcm" ' % bw)
self.f.write('height="%4.2fcm" ' % bh)
self.f.write('style="fill:#%02x%02x%02x; stroke:#000000; stroke-width:1;"/>\n' % box_style.get_fill_color())
self.f.write('style="fill:#%02x%02x%02x; ' % box_style.get_fill_color())
self.f.write('stroke:#%02x%02x%02x; ' % box_style.get_color())
self.f.write('stroke-width:%f;"/>\n' % box_style.get_line_width())
if text != "":
font = p.get_font()
font_size = font.get_size()