Start of style support

svn: r130
This commit is contained in:
Don Allingham 2001-06-14 17:13:33 +00:00
parent 089f833c48
commit dbd9b59c4c
5 changed files with 264 additions and 109 deletions

View File

@ -20,7 +20,32 @@
from TextDoc import * from TextDoc import *
import string
import os
import sys
import xml.sax
import xml.sax.saxutils
import utils
#-------------------------------------------------------------------------
#
# Try to abstract SAX1 from SAX2
#
#-------------------------------------------------------------------------
if sys.version[0] != '1':
sax = 2
else:
try:
import xml.sax.saxexts
sax = 1
except:
sax = 2
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class GraphicsStyle: class GraphicsStyle:
def __init__(self,obj=None): def __init__(self,obj=None):
if obj: if obj:
@ -72,7 +97,7 @@ class GraphicsStyle:
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class DrawDoc: class DrawDoc:
def __init__(self,type,orientation=PAPER_PORTRAIT): def __init__(self,styles,type,orientation=PAPER_PORTRAIT):
self.orientation = orientation self.orientation = orientation
if orientation == PAPER_PORTRAIT: if orientation == PAPER_PORTRAIT:
self.width = type.get_width() self.width = type.get_width()
@ -85,9 +110,7 @@ class DrawDoc:
self.lmargin = 2.54 self.lmargin = 2.54
self.rmargin = 2.54 self.rmargin = 2.54
self.font = FontStyle() self.style_list = styles.get_styles()
self.actfont = self.font
self.paragraph_styles = {}
self.draw_styles = {} self.draw_styles = {}
self.name = "" self.name = ""

View File

@ -37,8 +37,8 @@ except:
class OpenDrawDoc(DrawDoc): class OpenDrawDoc(DrawDoc):
def __init__(self,type,orientation): def __init__(self,styles,type,orientation):
DrawDoc.__init__(self,type,orientation) DrawDoc.__init__(self,styles,type,orientation)
self.f = None self.f = None
self.filename = None self.filename = None
self.level = 0 self.level = 0
@ -99,8 +99,8 @@ class OpenDrawDoc(DrawDoc):
self.f.write('<style:properties fo:margin-left="0cm" ') self.f.write('<style:properties fo:margin-left="0cm" ')
self.f.write('fo:margin-right="0cm" fo:text-indent="0cm"/>\n') self.f.write('fo:margin-right="0cm" fo:text-indent="0cm"/>\n')
self.f.write('</style:style>\n') self.f.write('</style:style>\n')
for key in self.paragraph_styles.keys(): for key in self.style_list.keys():
style = self.paragraph_styles[key] style = self.style_list[key]
self.f.write('<style:style style:name="T' + key + '" ') self.f.write('<style:style style:name="T' + key + '" ')
self.f.write('style:family="text">\n') self.f.write('style:family="text">\n')
self.f.write('<style:properties ') self.f.write('<style:properties ')
@ -249,8 +249,8 @@ class OpenDrawDoc(DrawDoc):
self.f.write('<style:style style:name="Standard" ') self.f.write('<style:style style:name="Standard" ')
self.f.write('style:family="paragraph" style:class="text"/>\n') self.f.write('style:family="paragraph" style:class="text"/>\n')
for key in self.paragraph_styles.keys(): for key in self.style_list.keys():
style = self.paragraph_styles[key] style = self.style_list[key]
self.f.write('<style:style style:name="' + key + '" ') self.f.write('<style:style style:name="' + key + '" ')
self.f.write('style:family="paragraph" ') self.f.write('style:family="paragraph" ')
self.f.write('style:parent-style-name="Standard" ') self.f.write('style:parent-style-name="Standard" ')

View File

@ -36,8 +36,8 @@ def make_color(color):
class PdfDrawDoc(DrawDoc): class PdfDrawDoc(DrawDoc):
def __init__(self,type,orientation): def __init__(self,styles,type,orientation):
DrawDoc.__init__(self,type,orientation) DrawDoc.__init__(self,styles,type,orientation)
self.f = None self.f = None
self.filename = None self.filename = None
self.level = 0 self.level = 0
@ -78,7 +78,7 @@ class PdfDrawDoc(DrawDoc):
def draw_box(self,style,text,x,y): def draw_box(self,style,text,x,y):
box_style = self.draw_styles[style] box_style = self.draw_styles[style]
para_name = box_style.get_paragraph_style() para_name = box_style.get_paragraph_style()
p = self.paragraph_styles[para_name] p = self.style_list[para_name]
w = box_style.get_width()*cm w = box_style.get_width()*cm
h = box_style.get_height()*cm h = box_style.get_height()*cm

View File

@ -21,25 +21,21 @@
"Generate files/Ancestor Chart" "Generate files/Ancestor Chart"
import RelLib import RelLib
import Config
import const import const
import os import os
import re
import sort
import string import string
import utils import utils
from FontScale import string_width
from TextDoc import * from TextDoc import *
from DrawDoc import * from DrawDoc import *
from OpenDrawDoc import * from StyleEditor import *
try: import FindDoc
from PdfDrawDoc import *
no_pdf = 0
except:
no_pdf = 1
from gtk import *
from gnome.ui import *
from libglade import * from libglade import *
from gtk import *
import intl import intl
_ = intl.gettext _ = intl.gettext
@ -51,6 +47,16 @@ _ = intl.gettext
#------------------------------------------------------------------------ #------------------------------------------------------------------------
active_person = None active_person = None
db = None db = None
styles = StyleSheet()
style_sheet_list = None
#------------------------------------------------------------------------
#
# pt2cm - convert points to centimeters
#
#------------------------------------------------------------------------
def pt2cm(pt):
return (float(pt)/72.0)*2.54
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -59,71 +65,75 @@ db = None
#------------------------------------------------------------------------ #------------------------------------------------------------------------
class AncestorReport: class AncestorReport:
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def __init__(self,database,person,output,doc, max): def __init__(self,database,person,output,doc, max):
self.doc = doc self.doc = doc
self.doc.creator(database.getResearcher().getName()) self.doc.creator(database.getResearcher().getName())
self.map = {} self.map = {}
self.text = {}
self.database = database self.database = database
self.start = person self.start = person
self.max_generations = max self.max_generations = max
self.output = output self.output = output
self.width = 4.5 self.box_width = 0
self.height = 1.25 self.height = 0
self.lines = 0
start = self.doc.get_right_margin()
delta = self.doc.get_usable_width() - (self.width + 0.5)
delta = delta/3.0
uh = self.doc.get_usable_height()
ystart = self.doc.get_top_margin() - ((self.height+0.3)/2.0)
self.x = [start, start + delta, start + (2*delta), start + (3*delta)]
self.y = [ ystart + (uh/2.0), ystart + (uh/4.0),
ystart + 3*(uh/4.0), ystart + (uh/8.0),
ystart + 3*(uh/8.0), ystart + 5*(uh/8.0),
ystart + 7*(uh/8.0),
ystart + (uh/16.0), ystart + 3*(uh/16.0),
ystart + 5*(uh/16.0), ystart + 7*(uh/16.0),
ystart + 9*(uh/16.0), ystart + 11*(uh/16.0),
ystart + 13*(uh/16.0), ystart + 15*(uh/16.0)]
def setup(self):
f = FontStyle()
f.set_size(9)
f.set_type_face(FONT_SANS_SERIF)
p = ParagraphStyle()
p.set_font(f)
self.doc.add_paragraph_style("Normal",p)
g = GraphicsStyle()
g.set_height(self.height)
g.set_width(self.width)
g.set_paragraph_style("Normal")
g.set_shadow(1)
self.doc.add_draw_style("box",g)
g = GraphicsStyle()
self.doc.add_draw_style("line",g)
self.doc.open(self.output)
def end(self):
self.doc.close()
#--------------------------------------------------------------------
#
# filter - traverse the ancestors recursively until either the end
# of a line is found, or until we reach the maximum number of
# generations that we want to deal with
#
#--------------------------------------------------------------------
def filter(self,person,index): def filter(self,person,index):
if person == None or index >= 2**self.max_generations: if person == None or index >= 2**self.max_generations:
return return
self.map[index] = person self.map[index] = person
self.text[index] = [ person.getPrimaryName().getName() ]
birth = person.getBirth()
if birth.getDate() != "":
self.text[index].append("b. %s" % birth.getDate())
death = person.getDeath()
if death.getDate() != "":
self.text[index].append("d. %s" % death.getDate())
if Config.status_bar == 1:
self.text[index].append("id: %s" % person.getId())
elif Config.status_bar == 2:
for attr in active_person.getAttributeList():
if attr.getType() == Config.attr_name:
txt = "%s: %s" % (Config.attr_name,attr.getValue())
self.text[index].append(txt)
break
self.font = self.doc.style_list["Normal"].get_font()
for line in self.text[index]:
self.box_width = max(self.box_width,string_width(self.font,line))
self.lines = max(self.lines,len(self.text[index]))
family = person.getMainFamily() family = person.getMainFamily()
if family != None: if family != None:
self.filter(family.getFather(),index*2) self.filter(family.getFather(),index*2)
self.filter(family.getMother(),(index*2)+1) self.filter(family.getMother(),(index*2)+1)
#--------------------------------------------------------------------
#
# filter - Generate the actual report
#
#--------------------------------------------------------------------
def write_report(self): def write_report(self):
self.filter(self.start,1) self.calc()
try:
generation = 0 self.doc.open(self.output)
need_header = 1 except:
print "Document write failure"
generation = 1 generation = 1
done = 0 done = 0
@ -139,7 +149,56 @@ class AncestorReport:
self.print_page(index, generation, page) self.print_page(index, generation, page)
page = page + 1 page = page + 1
generation = generation + 3 generation = generation + 3
try:
self.doc.close()
except:
print "Document write failure"
#--------------------------------------------------------------------
#
# calc - calculate the maximum width that a box needs to be. From
# that and the page dimensions, calculate the proper place to put
# the elements on a page.
#
#--------------------------------------------------------------------
def calc(self):
width = 0
self.filter(self.start,1)
print self.lines
self.height = self.lines*pt2cm(1.2*self.font.get_size())
self.box_width = pt2cm(self.box_width+20)
start = self.doc.get_right_margin()
delta = (self.doc.get_usable_width() - (self.box_width + 0.5))/3.0
uh = self.doc.get_usable_height()
ystart = self.doc.get_top_margin() - ((self.height+0.3)/2.0)
self.x = [start, start + delta, start + (2*delta), start + (3*delta)]
self.y = [ ystart + (uh/2.0), ystart + (uh/4.0),
ystart + 3*(uh/4.0), ystart + (uh/8.0),
ystart + 3*(uh/8.0), ystart + 5*(uh/8.0),
ystart + 7*(uh/8.0),
ystart + (uh/16.0), ystart + 3*(uh/16.0),
ystart + 5*(uh/16.0), ystart + 7*(uh/16.0),
ystart + 9*(uh/16.0), ystart + 11*(uh/16.0),
ystart + 13*(uh/16.0), ystart + 15*(uh/16.0)]
g = GraphicsStyle()
g.set_height(self.height)
g.set_width(self.box_width)
g.set_paragraph_style("Normal")
g.set_shadow(1)
self.doc.add_draw_style("box",g)
g = GraphicsStyle()
self.doc.add_draw_style("line",g)
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def get_numbers(self,start,index,vals): def get_numbers(self,start,index,vals):
if index > 4: if index > 4:
return return
@ -148,30 +207,33 @@ class AncestorReport:
self.get_numbers(start*2,index+1,vals) self.get_numbers(start*2,index+1,vals)
self.get_numbers((start*2)+1,index+1,vals) self.get_numbers((start*2)+1,index+1,vals)
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def print_page(self,start,generation, page): def print_page(self,start,generation, page):
self.doc.start_page() self.doc.start_page()
self.draw_graph(1,start,0) self.draw_graph(1,start,0)
self.doc.end_page() self.doc.end_page()
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def draw_graph(self,index,start,level): def draw_graph(self,index,start,level):
if self.map.has_key(start) and index <= 15: if self.map.has_key(start) and index <= 15:
person = self.map[start] person = self.map[start]
name = person.getPrimaryName().getRegularName() text = self.text[start]
birth = person.getBirth()
if birth and birth.getDate() != "":
name = name + "\nb. " + birth.getDate()
death = person.getDeath()
if death and death.getDate() != "":
name = name + "\nd. " + death.getDate()
name = string.join(text,"\n")
self.doc.draw_box("box",name,self.x[level],self.y[index-1]) self.doc.draw_box("box",name,self.x[level],self.y[index-1])
if index > 1: if index > 1:
old_index = int(index/2)-1 old_index = int(index/2)-1
x1 = self.x[level-1]+(self.width/2.0)
x2 = self.x[level] x2 = self.x[level]
x1 = self.x[level-1]+(self.x[level]-self.x[level-1])/2.0
if index % 2 == 1: if index % 2 == 1:
y1 = self.y[old_index]+self.height y1 = self.y[old_index]+self.height
else: else:
@ -191,6 +253,7 @@ class AncestorReport:
def report(database,person): def report(database,person):
import PaperMenu import PaperMenu
global style_sheet_list
global active_person global active_person
global topDialog global topDialog
global glade_file global glade_file
@ -207,17 +270,59 @@ def report(database,person):
PaperMenu.make_paper_menu(topDialog.get_widget("papersize")) PaperMenu.make_paper_menu(topDialog.get_widget("papersize"))
PaperMenu.make_orientation_menu(topDialog.get_widget("orientation")) PaperMenu.make_orientation_menu(topDialog.get_widget("orientation"))
FindDoc.get_draw_doc_menu(topDialog.get_widget("format"),0,option_switch)
if no_pdf == 1: styles.clear()
topDialog.get_widget("pdf").set_sensitive(0) f = FontStyle()
f.set_size(9)
f.set_type_face(FONT_SANS_SERIF)
p = ParagraphStyle()
p.set_font(f)
styles.add_style("Normal",p)
style_sheet_list = StyleSheetList("ancestor_chart.xml",styles)
build_menu(None)
title = _("Ancestor Chart for %s") % name title = _("Ancestor Chart for %s") % name
topDialog.get_widget("labelTitle").set_text(title) topDialog.get_widget("labelTitle").set_text(title)
topDialog.signal_autoconnect({ topDialog.signal_autoconnect({
"destroy_passed_object" : utils.destroy_passed_object, "destroy_passed_object" : utils.destroy_passed_object,
"on_style_edit_clicked" : on_style_edit_clicked,
"on_save_clicked" : on_save_clicked "on_save_clicked" : on_save_clicked
}) })
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
def build_menu(object):
menu = topDialog.get_widget("style_menu")
myMenu = GtkMenu()
for style in style_sheet_list.get_style_names():
menuitem = GtkMenuItem(style)
menuitem.set_data("d",style_sheet_list.get_style_sheet(style))
menuitem.show()
myMenu.append(menuitem)
menu.set_menu(myMenu)
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
def option_switch(obj):
pass
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
def on_style_edit_clicked(obj):
StyleListDisplay(style_sheet_list,build_menu,None)
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# #
@ -238,16 +343,13 @@ def on_save_clicked(obj):
max_gen = topDialog.get_widget("generations").get_value_as_int() max_gen = topDialog.get_widget("generations").get_value_as_int()
if topDialog.get_widget("openoffice").get_active(): item = topDialog.get_widget("format").get_menu().get_active()
document = OpenDrawDoc(paper,orien) format = item.get_data("name")
else: doc = FindDoc.make_draw_doc(styles,format,paper,orien)
document = PdfDrawDoc(paper,orien)
MyReport = AncestorReport(db,active_person,outputName,document,max_gen) MyReport = AncestorReport(db,active_person,outputName,doc,max_gen)
MyReport.setup()
MyReport.write_report() MyReport.write_report()
MyReport.end()
utils.destroy_passed_object(obj) utils.destroy_passed_object(obj)
@ -257,8 +359,7 @@ def on_save_clicked(obj):
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
def get_description(): def get_description():
return _("Produces a graphical ancestral tree") return _("Produces a graphical ancestral tree graph")
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #

View File

@ -180,6 +180,7 @@
<widget> <widget>
<class>GtkFrame</class> <class>GtkFrame</class>
<name>frame1</name> <name>frame1</name>
<border_width>5</border_width>
<label>Format</label> <label>Format</label>
<label_xalign>0</label_xalign> <label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
@ -190,36 +191,65 @@
</child> </child>
<widget> <widget>
<class>GtkVBox</class> <class>GtkOptionMenu</class>
<name>vbox4</name> <name>format</name>
<border_width>5</border_width>
<can_focus>True</can_focus>
<items>OpenOffice
</items>
<initial_choice>0</initial_choice>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>style_frame</name>
<border_width>5</border_width>
<label>Styles</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHBox</class>
<name>hbox3</name>
<homogeneous>False</homogeneous> <homogeneous>False</homogeneous>
<spacing>0</spacing> <spacing>0</spacing>
<widget> <widget>
<class>GtkRadioButton</class> <class>GtkOptionMenu</class>
<name>openoffice</name> <name>style_menu</name>
<border_width>10</border_width>
<can_focus>True</can_focus> <can_focus>True</can_focus>
<label>OpenOffice</label> <items>default
<active>True</active> </items>
<draw_indicator>True</draw_indicator> <initial_choice>0</initial_choice>
<group>format</group>
<child> <child>
<padding>0</padding> <padding>0</padding>
<expand>False</expand> <expand>True</expand>
<fill>False</fill> <fill>True</fill>
</child> </child>
</widget> </widget>
<widget> <widget>
<class>GtkRadioButton</class> <class>GtkButton</class>
<name>pdf</name> <name>button17</name>
<border_width>10</border_width>
<can_focus>True</can_focus> <can_focus>True</can_focus>
<label>PDF</label> <signal>
<active>False</active> <name>clicked</name>
<draw_indicator>True</draw_indicator> <handler>on_style_edit_clicked</handler>
<group>format</group> <object>dialog1</object>
<last_modification_time>Tue, 05 Jun 2001 14:39:29 GMT</last_modification_time>
</signal>
<label>Style Editor</label>
<relief>GTK_RELIEF_NORMAL</relief>
<child> <child>
<padding>0</padding> <padding>5</padding>
<expand>False</expand> <expand>False</expand>
<fill>False</fill> <fill>False</fill>
</child> </child>
@ -230,6 +260,7 @@
<widget> <widget>
<class>GtkFrame</class> <class>GtkFrame</class>
<name>frame2</name> <name>frame2</name>
<border_width>5</border_width>
<label>Options</label> <label>Options</label>
<label_xalign>0</label_xalign> <label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
@ -330,7 +361,7 @@
<class>GtkOptionMenu</class> <class>GtkOptionMenu</class>
<name>papersize</name> <name>papersize</name>
<can_focus>True</can_focus> <can_focus>True</can_focus>
<items> <items>Letter
</items> </items>
<initial_choice>0</initial_choice> <initial_choice>0</initial_choice>
<child> <child>
@ -353,7 +384,7 @@
<class>GtkOptionMenu</class> <class>GtkOptionMenu</class>
<name>orientation</name> <name>orientation</name>
<can_focus>True</can_focus> <can_focus>True</can_focus>
<items> <items>Portrait
</items> </items>
<initial_choice>0</initial_choice> <initial_choice>0</initial_choice>
<child> <child>