New plugin system for document generators

svn: r733
This commit is contained in:
Don Allingham 2002-01-29 00:44:15 +00:00
parent 93a337b034
commit 3c40fcbd9e
18 changed files with 4019 additions and 44 deletions

View File

@ -27,7 +27,10 @@ import string
import gtk
class AutoComp:
"""
Allows allow completion of the GtkEntry widget with the entries
in the passed string list.
"""
def __init__(self,widget,plist):
self.entry = widget
self.nlist = [("","")]

View File

@ -18,20 +18,26 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
The core of the GRAMPS plugin system. This module provides tasks to load
plugins from specfied directories, build menus for the different categories,
and provide dialog to select and execute plugins.
Plugins are divided into several categories. This are: reports, tools,
filters, importer, exporters, and document generators.
"""
#-------------------------------------------------------------------------
#
#
# GTK libraries
#
#-------------------------------------------------------------------------
import gtk
import libglade
from intl import gettext
_ = gettext
#-------------------------------------------------------------------------
#
#
# Standard Python modules
#
#-------------------------------------------------------------------------
import os
@ -40,15 +46,18 @@ from re import compile
#-------------------------------------------------------------------------
#
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import const
import utils
import Config
from intl import gettext
_ = gettext
#-------------------------------------------------------------------------
#
#
# Global lists
#
#-------------------------------------------------------------------------
_reports = []
@ -59,10 +68,12 @@ _success = []
_failed = []
_attempt = []
_loaddir = []
_textdoc = []
_drawdoc = []
#-------------------------------------------------------------------------
#
#
# Constants
#
#-------------------------------------------------------------------------
DOCSTRING = "d"
@ -71,36 +82,45 @@ TASK = "f"
TITLE = "t"
STATUS = "s"
pymod = compile(r"^(.*)\.py$")
#-------------------------------------------------------------------------
#
#
# ReportPlugins interface class
#
#-------------------------------------------------------------------------
class ReportPlugins:
"""Displays the dialog box that allows the user to select the
report that is desired."""
def __init__(self,db,active):
"""Display the dialog box, and build up the list of available
reports. This is used to build the selection tree on the left
hand side of the dailog box."""
self.db = db
self.active = active
self.dialog = libglade.GladeXML(const.pluginsFile,"report")
self.dialog.signal_autoconnect({
"on_report_apply_clicked" : self.on_report_apply_clicked,
"on_report_ok_clicked" : self.on_report_apply_clicked,
"on_report_apply_clicked" : self.on_apply_clicked,
"on_report_ok_clicked" : self.on_apply_clicked,
"destroy_passed_object" : utils.destroy_passed_object
})
tree = self.dialog.get_widget("tree1")
self.run_tool = None
build_tree(tree,_reports,self.on_report_node_selected)
build_tree(tree,_reports,self.on_node_selected)
def on_apply_clicked(self,obj):
"""Execute the selected report"""
def on_report_apply_clicked(self,obj):
utils.destroy_passed_object(obj)
if self.run_tool:
self.run_tool(self.db,self.active)
def on_report_node_selected(self,obj):
def on_node_selected(self,obj):
"""Updates the informational display on the right hand side of
the dialog box with the description of the selected report"""
doc = obj.get_data(DOCSTRING)
xpm = obj.get_data(IMAGE)
status = ": %s" % obj.get_data(STATUS)
@ -119,11 +139,18 @@ class ReportPlugins:
#-------------------------------------------------------------------------
#
#
# ToolPlugins interface class
#
#-------------------------------------------------------------------------
class ToolPlugins:
"""Displays the dialog box that allows the user to select the tool
that is desired."""
def __init__(self,db,active,update):
"""Display the dialog box, and build up the list of available
reports. This is used to build the selection tree on the left
hand side of the dailog box."""
self.db = db
self.active = active
self.update = update
@ -140,11 +167,16 @@ class ToolPlugins:
build_tree(tree,_tools,self.on_node_selected)
def on_apply_clicked(self,obj):
"""Execute the selected tool."""
utils.destroy_passed_object(obj)
if self.run_tool:
self.run_tool(self.db,self.active,self.update)
def on_node_selected(self,obj):
"""Updates the informational display on the right hand side of
the dialog box with the description of the selected tool."""
doc = obj.get_data(DOCSTRING)
title = obj.get_data(TITLE)
@ -154,10 +186,20 @@ class ToolPlugins:
#-------------------------------------------------------------------------
#
#
# build_tree
#
#-------------------------------------------------------------------------
def build_tree(tree,list,task):
"""Populates a GtkTree with each menu item assocated with a entry
in the lists. The list must consist of a tuples with the following
format:
(task_to_call, category of report, report name, description, image, status)
Items in the same category are grouped under the same submen. The
task_to_call is bound to the 'select' callback of the menu entry."""
# build the tree items and group together based on the category name
item_hash = {}
for report in list:
item = gtk.GtkTreeItem(report[2])
@ -173,6 +215,8 @@ def build_tree(tree,list,task):
else:
item_hash[report[1]] = [item]
# add a submenu for each category, and populate it with the GtkTreeItems
# that are associated with it.
key_list = item_hash.keys()
key_list.sort()
for key in key_list:
@ -189,19 +233,38 @@ def build_tree(tree,list,task):
#-------------------------------------------------------------------------
#
#
# load_plugins
#
#-------------------------------------------------------------------------
def load_plugins(dir):
"""Searches the specified directory, and attempts to load any python
modules that it finds, adding name to the _attempts list. If the module
successfully loads, it is added to the _success list. Each plugin is
responsible for registering itself in the correct manner. No attempt
is done in this routine to register the tasks."""
global _success,_failed,_attempt,_loaddir
# if the directory does not exist, do nothing
if not os.path.isdir(dir):
return
# if the path has not already been loaded, save it in the _loaddir
# list for use on reloading
if dir not in _loaddir:
_loaddir.append(dir)
# add the directory to the python search path
sys.path.append(dir)
pymod = compile(r"^(.*)\.py$")
# loop through each file in the directory, looking for files that
# have a .py extention, and attempt to load the file. If it succeeds,
# add it to the _success list. If it fails, add it to the _failure
# list
for file in os.listdir(dir):
name = os.path.split(file)
match = pymod.match(name[1])
@ -218,7 +281,19 @@ def load_plugins(dir):
traceback.print_exc()
_failed.append(plugin)
#-------------------------------------------------------------------------
#
# reload_plugins
#
#-------------------------------------------------------------------------
def reload_plugins(obj):
"""Treated as a callback, causes all plugins to get reloaded. This is
useful when writing and debugging a plugin"""
pymod = compile(r"^(.*)\.py$")
# attempt to reload all plugins that have succeeded
# in the past
for plugin in _success:
try:
reload(plugin)
@ -227,6 +302,9 @@ def reload_plugins(obj):
import traceback
traceback.print_exc()
_failed.append(plugin)
# attempt to load the plugins that have failed in the past
for plugin in _failed:
try:
__import__(plugin)
@ -236,12 +314,15 @@ def reload_plugins(obj):
traceback.print_exc()
_failed.append(plugin)
# attempt to load any new files found
for dir in _loaddir:
for file in os.listdir(dir):
name = os.path.split(file)
match = pymod.match(name[1])
if not match:
continue
if file in _attempt:
return
_attempt.append(file)
plugin = match.groups()[0]
try:
@ -259,9 +340,11 @@ def reload_plugins(obj):
#
#-------------------------------------------------------------------------
def register_export(task, name):
"""Register an export filter, taking the task and name"""
_exports.append((task, name))
def register_import(task, name):
"""Register an import filter, taking the task and name"""
_imports.append((task, name))
def register_report(task, name,
@ -269,28 +352,36 @@ def register_report(task, name,
description=_("No description was provided"),
xpm=None,
status=_("Unknown")):
"""Register a report with the plugin system"""
if xpm == None:
xpm_data = no_image()
elif type(xpm) == type([]):
xpm_data = xpm
else:
xpm_data = xpm
_reports.append((task, category, name, description, xpm_data, status))
xpm = no_image()
_reports.append((task, category, name, description, xpm, status))
def register_tool(task, name,
category=_("Uncategorized"),
description=_("No description was provided"),
xpm=None,
status=_("Unknown")):
"""Register a tool with the plugin system"""
if xpm == None:
xpm_data = no_image()
elif type(xpm) == type([]):
xpm_data = xpm
else:
xpm_data = xpm
xpm = no_image()
_tools.append((task, category, name, description, xpm, status))
_tools.append((task, category, name, description, xpm_data, status))
def register_text_doc(name,classref, table, paper, style):
"""Register a text document generator"""
for n in _textdoc:
if n[0] == name:
return
_textdoc.append((name,classref,table,paper,style))
def register_draw_doc(name,classref):
"""Register a drawing document generator"""
for n in _drawdoc:
if n[0] == name:
return
_drawdoc.append((name,classref))
#-------------------------------------------------------------------------
#
@ -326,12 +417,27 @@ def build_menu(top_menu,list,callback):
submenu.append(subentry)
top_menu.set_submenu(report_menu)
#-------------------------------------------------------------------------
#
# build_report_menu
#
#-------------------------------------------------------------------------
def build_report_menu(top_menu,callback):
build_menu(top_menu,_reports,callback)
#-------------------------------------------------------------------------
#
# build_tools_menu
#
#-------------------------------------------------------------------------
def build_tools_menu(top_menu,callback):
build_menu(top_menu,_tools,callback)
#-------------------------------------------------------------------------
#
# build_export_menu
#
#-------------------------------------------------------------------------
def build_export_menu(top_menu,callback):
myMenu = gtk.GtkMenu()
@ -342,6 +448,11 @@ def build_export_menu(top_menu,callback):
myMenu.append(item)
top_menu.set_submenu(myMenu)
#-------------------------------------------------------------------------
#
# build_import_menu
#
#-------------------------------------------------------------------------
def build_import_menu(top_menu,callback):
myMenu = gtk.GtkMenu()
@ -352,13 +463,66 @@ def build_import_menu(top_menu,callback):
myMenu.append(item)
top_menu.set_submenu(myMenu)
#-------------------------------------------------------------------------
#
# get_text_doc_menu
#
#-------------------------------------------------------------------------
def get_text_doc_menu(main_menu,tables,callback,obj=None):
index = 0
myMenu = gtk.GtkMenu()
_textdoc.sort()
for item in _textdoc:
if tables and item[2] == 0:
continue
name = item[0]
menuitem = gtk.GtkMenuItem(name)
menuitem.set_data("name",item[1])
menuitem.set_data("styles",item[4])
menuitem.set_data("paper",item[3])
menuitem.set_data("obj",obj)
if callback:
menuitem.connect("activate",callback)
menuitem.show()
myMenu.append(menuitem)
if name == Config.output_preference:
myMenu.set_active(index)
callback(menuitem)
index = index + 1
main_menu.set_menu(myMenu)
#-------------------------------------------------------------------------
#
#
# get_draw_doc_menu
#
#-------------------------------------------------------------------------
def get_draw_doc_menu(main_menu,callback=None,obj=None):
index = 0
myMenu = gtk.GtkMenu()
for (name,classref) in _drawdoc:
menuitem = gtk.GtkMenuItem(name)
menuitem.set_data("name",classref)
menuitem.set_data("obj",obj)
if callback:
menuitem.connect("activate",callback)
menuitem.show()
myMenu.append(menuitem)
if name == Config.output_preference:
myMenu.set_active(index)
if callback:
callback(menuitem)
index = index + 1
main_menu.set_menu(myMenu)
#-------------------------------------------------------------------------
#
# no_image
#
#-------------------------------------------------------------------------
def no_image():
"""Returns XPM data for basic 48x48 icon"""
return [
"48 48 5 1",
" c None",

View File

@ -28,6 +28,7 @@ import sort
import string
import utils
import intl
import Plugins
_ = intl.gettext
@ -35,7 +36,6 @@ from TextDoc import *
from StyleEditor import *
import Config
import FindDoc
import PaperMenu
from gtk import *
@ -898,14 +898,13 @@ class TextReportDialog(ReportDialog):
"""Build a menu of document types that are appropriate for
this text report. This menu will be generated based upon
whether the document requires table support, etc."""
FindDoc.get_text_doc_menu(self.format_menu, self.doc_uses_tables(),
Plugins.get_text_doc_menu(self.format_menu, self.doc_uses_tables(),
self.doc_type_changed)
def make_document(self):
"""Create a document of the type requested by the user."""
self.doc = FindDoc.make_text_doc(self.selected_style,self.format,
self.paper,self.orien,
self.template_name)
self.doc = self.format(self.selected_style,self.paper,
self.template_name,self.orien)
#------------------------------------------------------------------------
#
@ -942,9 +941,8 @@ class DrawReportDialog(ReportDialog):
def make_doc_menu(self):
"""Build a menu of document types that are appropriate for
this drawing report."""
FindDoc.get_draw_doc_menu(self.format_menu)
Plugins.get_draw_doc_menu(self.format_menu)
def make_document(self):
"""Create a document of the type requested by the user."""
self.doc = FindDoc.make_draw_doc(self.selected_style,self.format,
self.paper,self.orien)
self.doc = self.format(self.selected_style,self.paper,self.orien)

View File

@ -572,8 +572,9 @@ class SheetParser(handler.ContentHandler):
#
#------------------------------------------------------------------------
class TextDoc:
def __init__(self,styles,type,orientation=PAPER_PORTRAIT):
def __init__(self,styles,type,template,orientation=PAPER_PORTRAIT):
self.orientation = orientation
self.template = template
if orientation == PAPER_PORTRAIT:
self.width = type.get_width()
self.height = type.get_height()

View File

@ -74,6 +74,7 @@ findFile = "%s/find.glade" % rootDir
mergeFile = "%s/mergedata.glade" % rootDir
traceFile = "%s/trace.glade" % rootDir
pluginsDir = "%s/plugins" % rootDir
docgenDir = "%s/docgen" % rootDir
filtersDir = "%s/filters" % rootDir
dataDir = "%s/data" % rootDir
gtkrcFile = "%s/gtkrc" % rootDir

242
src/docgen/AbiWordDoc.py Normal file
View File

@ -0,0 +1,242 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
"""
Provides a TextDoc based interface to the AbiWord document format.
"""
#-------------------------------------------------------------------------
#
# Imported Modules
#
#-------------------------------------------------------------------------
import os
import base64
from TextDoc import *
from latin_utf8 import latin_to_utf8
import const
import string
import Plugins
import intl
_ = intl.gettext
#-------------------------------------------------------------------------
#
# Attemp to import the Python Imaging Library
#
#-------------------------------------------------------------------------
try:
import PIL.Image
no_pil = 0
except:
no_pil = 1
#-------------------------------------------------------------------------
#
# Class Definitions
#
#-------------------------------------------------------------------------
class AbiWordDoc(TextDoc):
"""AbiWord document generator. Inherits from the TextDoc generic
document interface class."""
def __init__(self,styles,type,orientation):
"""Initializes the AbiWordDoc class, calling the __init__ routine
of the parent TextDoc class"""
TextDoc.__init__(self,styles,type,orientation)
self.f = None
self.level = 0
self.new_page = 0
def open(self,filename):
"""Opens the document, writing the necessary header information.
AbiWord uses an XML format, so the document format is pretty easy
to understand"""
if filename[-4:] != ".abw":
self.filename = "%s.abw" % filename
else:
self.filename = filename
self.f = open(self.filename,"w")
self.f.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
self.f.write('<abiword version="0.7.14" fileformat="1.0">\n')
self.f.write('<pagesize ')
self.f.write('pagetype="%s" ' % self.paper.get_name())
if self.orientation == PAPER_PORTRAIT:
self.f.write('orientation="portrait" ')
else:
self.f.write('orientation="landscape" ')
self.f.write('width="%.4f" ' % self.width/2.54)
self.f.write('height="%.4f" ' % self.height/2.54)
self.f.write('units="inch" page-scale="1.000000"/>\n')
self.f.write('<section ')
rmargin = float(self.rmargin)/2.54
lmargin = float(self.lmargin)/2.54
self.f.write('props="page-margin-right:%.4fin; ' % rmargin)
self.f.write('page-margin-left:%.4fin"' % lmargin)
self.f.write('>\n')
def close(self):
"""Write the trailing information and closes the file"""
self.f.write('</section>\n')
if len(self.photo_list) > 0:
self.f.write('<data>\n')
for file_tuple in self.photo_list:
file = file_tuple[0]
width = file_tuple[1]
height = file_tuple[2]
base = "/tmp/%s.png" % os.path.basename(file)
tag = string.replace(base,'.','_')
if no_pil:
cmd = "%s -geometry %dx%d '%s' '%s'" % (const.convert,width,height,file,base)
os.system(cmd)
else:
im = PIL.Image.open(file)
im.thumbnail((width,height))
im.save(base,"PNG")
self.f.write('<d name="')
self.f.write(tag)
self.f.write('" mime-type="image/png" base64="yes">\n')
f = open(base,"rb")
base64.encode(f,self.f)
f.close()
os.unlink(base)
self.f.write('</d>\n')
self.f.write('</data>\n')
self.f.write('</abiword>\n')
self.f.close()
def add_photo(self,pos,name,x_cm,y_cm):
import gtk
import GdkImlib
image = GdkImlib.Image(name)
scale = float(image.rgb_width)/float(image.rgb_height)
act_width = int(((x_cm * scale)*2.54)*72)
act_height = int(((y_cm * scale)*2.54)*72)
self.photo_list.append((name,act_width,act_height))
base = "/tmp/%s.png" % os.path.basename(name)
tag = string.replace(base,'.','_')
self.f.write('<image dataid="')
self.f.write(tag)
self.f.write('" props="width:%.3fin; ' % act_width)
self.f.write('height:%.3fin"/>' % act_height)
def start_paragraph(self,style_name,leader=None):
style = self.style_list[style_name]
self.current_style = style
self.f.write('<p props="')
if style.get_alignment() == PARA_ALIGN_RIGHT:
self.f.write('text-align:right;')
elif style.get_alignment() == PARA_ALIGN_LEFT:
self.f.write('text-align:left;')
elif style.get_alignment() == PARA_ALIGN_CENTER:
self.f.write('text-align:center;')
else:
self.f.write('text-align:justify;')
rmargin = float(style.get_right_margin())/2.54
lmargin = float(style.get_left_margin())/2.54
indent = float(style.get_first_indent())/2.54
self.f.write(' margin-right:%.4fin;' % rmargin)
self.f.write(' margin-left:%.4fin;' % lmargin)
self.f.write(' tabstops:%.4fin/L;' % lmargin)
self.f.write(' text-indent:%.4fin' % indent)
self.f.write('">')
font = style.get_font()
self.f.write('<c props="font-family:')
if font.get_type_face() == FONT_SANS_SERIF:
self.f.write('Arial;')
else:
self.f.write('Times New Roman;')
self.f.write('font-size:%dpt' % font.get_size())
if font.get_bold():
self.f.write('; font-weight:bold')
if font.get_italic():
self.f.write('; font-style:italic')
color = font.get_color()
if color != (0,0,0):
self.f.write('; color:%2x%2x%2x' % color)
if font.get_underline():
self.f.write('; text-decoration:underline')
self.f.write('">')
if self.new_page == 1:
self.new_page = 0
self.f.write('<pbr/>')
if leader != None:
self.f.write(leader)
self.f.write('\t')
def page_break(self):
self.new_page = 1
def end_paragraph(self):
self.f.write('</c></p>\n')
def write_text(self,text):
text = string.replace(text,'&','&amp;'); # Must be first
text = string.replace(text,'<','&lt;');
text = string.replace(text,'>','&gt;');
self.f.write(text)
def start_bold(self):
font = self.current_style.get_font()
self.f.write('</c><c props="font-family:')
if font.get_type_face() == FONT_SANS_SERIF:
self.f.write('Arial;')
else:
self.f.write('Times New Roman;')
self.f.write('font-size:%dpt' % font.get_size())
self.f.write('; font-weight:bold')
if font.get_italic():
self.f.write('; font-style:italic')
color = font.get_color()
if color != (0,0,0):
self.f.write('; color:%02x%02x%02x' % color)
if font.get_underline():
self.f.write('; text-decoration:underline')
self.f.write('">')
def end_bold(self):
font = self.current_style.get_font()
self.f.write('</c><c props="font-family:')
if font.get_type_face() == FONT_SANS_SERIF:
self.f.write('Arial;')
else:
self.f.write('Times New Roman;')
self.f.write('font-size:%dpt' % font.get_size())
if font.get_bold():
self.f.write('; font-weight:bold')
if font.get_italic():
self.f.write('; font-style:italic')
color = font.get_color()
if color != (0,0,0):
self.f.write('; color:%02x%02x%02x' % color)
if font.get_underline():
self.f.write('; text-decoration:underline')
self.f.write('">')
Plugins.register_text_doc(_("AbiWord"),AbiWordDoc,0,1,1)

340
src/docgen/HtmlDoc.py Normal file
View File

@ -0,0 +1,340 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
import os
import string
import re
import utils
import gnome.ui
import Plugins
from intl import gettext
_ = gettext
from TextDoc import *
#------------------------------------------------------------------------
#
# Attempt to load the Python Imaging Library for the handling of photos.
#
#------------------------------------------------------------------------
try:
import PIL.Image
no_pil = 0
except:
no_pil = 1
t_header_line_re = re.compile(r"(.*)<TITLE>(.*)</TITLE>(.*)", re.DOTALL|re.IGNORECASE|re.MULTILINE)
#------------------------------------------------------------------------
#
# Default template
#
#------------------------------------------------------------------------
_top = [
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\n',
'<HTML>\n',
'<HEAD>\n',
' <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">\n',
' <TITLE>\n',
' </TITLE>\n',
' <STYLE type="text/css">\n',
' <!--\n',
' BODY { background-color: #ffffff }\n',
' .parent_name { font-family: Arial; font-style: bold }\n',
' .child_name { font-family: Arial; font-style: bold }\n',
' -->\n',
' </STYLE>\n',
'</HEAD>\n',
'<BODY>\n',
' <!-- START -->\n'
]
_bottom = [
' <!-- STOP -->\n',
'</BODY>\n',
'</HTML>\n'
]
class HtmlDoc(TextDoc):
def __init__(self,styles,type,template,orientation,source=None):
TextDoc.__init__(self,styles,PaperStyle("",0,0),template,None)
if source == None:
self.f = None
self.filename = None
self.top = []
self.bottom = []
self.base = ""
self.load_template()
self.build_header()
self.build_style_declaration()
else:
self.f = None
self.filename = source.filename
self.template = None
self.top = source.top
self.bottom = source.bottom
self.base = source.base
self.file_header = source.file_header
self.style_declaration = source.style_declaration
self.table_styles = source.table_styles;
self.cell_styles = source.cell_styles;
def load_template(self):
start = re.compile(r"<!--\s*START\s*-->")
stop = re.compile(r"<!--\s*STOP\s*-->")
top_add = 1
bottom_add = 0
if self.template and self.template != "":
try:
templateFile = open(self.template,"r")
for line in templateFile.readlines():
if top_add == 1:
self.top.append(line)
match = start.search(line)
if match:
top_add = 0
elif bottom_add == 0:
match = stop.search(line)
if match != None:
bottom_add = 1
self.bottom.append(line)
else:
self.bottom.append(line)
templateFile.close()
if top_add == 1:
mymsg = _("The marker '<!-- START -->' was not in the template")
gnome.ui.GnomeErrorDialog(mymsg)
except IOError,msg:
mymsg = _("Could not open %s\nUsing the default template") % \
self.template
mymsg = "%s\n%s" % (mymsg,msg)
gnome.ui.GnomeWarningDialog(mymsg)
self.bottom = _bottom
self.top = _top
except:
mymsg = _("Could not open %s\nUsing the default template") % \
self.template
gnome.ui.GnomeWarningDialog(mymsg)
self.bottom = _bottom
self.top = _top
else:
self.bottom = _bottom
self.top = _top
def open(self,filename):
if filename[-5:] == ".html" or filename[-4:0] == ".htm":
self.filename = filename
else:
self.filename = filename + ".html"
self.base = os.path.dirname(self.filename)
self.f = open(self.filename,"w")
self.f.write(self.file_header)
self.f.write(self.style_declaration)
def build_header(self):
top = string.join(self.top, "")
match = t_header_line_re.match(top)
if match:
m = match.groups()
self.file_header = '%s<TITLE>%s</TITLE>%s\n' % (m[0],m[1],m[2])
else:
self.file_header = top
def build_style_declaration(self):
text = ['<style type="text/css">\n<!--']
for key in self.cell_styles.keys():
style = self.cell_styles[key]
pad = "%.3fcm" % style.get_padding()
top = bottom = left = right = 'none'
if style.get_top_border():
top = 'thin solid #000000'
if style.get_bottom_border():
bottom = 'thin solid #000000'
if style.get_left_border():
left = 'thin solid #000000'
if style.get_right_border():
right = 'thin solid #000000'
text.append('.%s {\n' \
'\tpadding: %s %s %s %s;\n' \
'\tborder-top:%s; border-bottom:%s;\n' \
'\tborder-left:%s; border-right:%s;\n}' \
% (key, pad, pad, pad, pad, top, bottom, left, right))
for key in self.style_list.keys():
style = self.style_list[key]
font = style.get_font()
font_size = font.get_size()
font_color = '#%02x%02x%02x' % font.get_color()
align = style.get_alignment_text()
text_indent = "%.2f" % style.get_first_indent()
right_margin = "%.2f" % style.get_right_margin()
left_margin = "%.2f" % style.get_left_margin()
top = bottom = left = right = 'none'
if style.get_top_border():
top = 'thin solid #000000'
if style.get_bottom_border():
bottom = 'thin solid #000000'
if style.get_left_border():
left = 'thin solid #000000'
if style.get_right_border():
right = 'thin solid #000000'
italic = bold = ''
if font.get_italic():
italic = 'font-style:italic; '
if font.get_bold():
bold = 'font-weight:bold; '
if font.get_type_face() == FONT_SANS_SERIF:
family = '"Helvetica","Arial","sans-serif"'
else:
family = '"Times New Roman","Times","serif"'
text.append('.%s {\n' \
'\tfont-size: %dpt; color: %s;\n' \
'\ttext-align: %s; text-indent: %scm;\n' \
'\tmargin-right: %scm; margin-left: %scm;\n' \
'\tborder-top:%s; border-bottom:%s;\n' \
'\tborder-left:%s; border-right:%s;\n' \
'\t%s%sfont-family:%s;\n}' \
% (key, font_size, font_color,
align, text_indent,
right_margin, left_margin,
top, bottom, left, right,
italic, bold, family))
text.append('-->\n</style>')
self.style_declaration = string.join(text,'\n')
def close(self):
for line in self.bottom:
self.f.write(line)
self.f.close()
def add_photo(self,name,pos,x,y):
if no_pil:
return
self.empty = 0
try:
im = PIL.Image.open(name)
except:
return
nx,ny = im.size
scale = float(nx)/float(ny)
if scale > 1.0:
scale = 1.0/scale
act_width = float(x)
act_height = float(y * scale)
else:
act_width = float(x * scale)
act_height = float(y)
cmtopt = float(150.0/2.54)
pixx = int(act_width*cmtopt)
pixy = int(act_height*cmtopt)
im.thumbnail((pixx,pixy))
imdir = self.base + os.sep + "images"
if not os.path.isdir(imdir):
try:
os.mkdir(imdir)
except:
return
refname = "is%s" % os.path.basename(name)
try:
im.save(imdir + os.sep + refname)
except:
return
if pos == "right":
xtra = ' align="right"'
elif pos == "left" :
xtra = ' align="left"'
else:
xtra = ''
self.f.write('<img src="images/%s" border="0" width="%d" height="%d"%s>\n' % \
(refname,pixx,pixy,xtra))
def start_table(self,name,style):
self.tbl = self.table_styles[style]
self.f.write('<table width="%d%%" ' % self.tbl.get_width())
self.f.write('cellspacing="0">\n')
def end_table(self):
self.f.write('</table>\n')
def start_row(self):
self.col = 0
self.f.write('<tr>\n')
def end_row(self):
self.f.write('</tr>\n')
def start_cell(self,style_name,span=1):
self.empty = 1
self.f.write('<td valign="top"')
if span > 1:
self.f.write(' colspan="' + str(span) + '"')
self.col = self.col + 1
else:
self.f.write(' width="')
self.f.write(str(self.tbl.get_column_width(self.col)))
self.f.write('%"')
self.f.write(' class="')
self.f.write(style_name)
self.f.write('">')
self.col = self.col + 1
def end_cell(self):
self.f.write('</td>\n')
def start_paragraph(self,style_name,leader=None):
self.f.write('<p class="' + style_name + '">')
if leader != None:
self.f.write(leader)
self.f.write(' ')
def end_paragraph(self):
if self.empty == 1:
self.f.write('&nbsp;')
self.empty = 0
self.f.write('</p>\n')
def write_text(self,text):
if text != "":
self.empty = 0
text = string.replace(text,'\n','<br>')
self.f.write(text)
Plugins.register_text_doc(_("HTML"),HtmlDoc,1,0,1)

441
src/docgen/KwordDoc.py Normal file
View File

@ -0,0 +1,441 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
from TextDoc import *
from latin_utf8 import latin_to_utf8
import utils
import time
import StringIO
import os
import gzip
from TarFile import TarFile
import Plugins
import intl
_ = intl.gettext
try:
import PIL.Image
no_pil = 0
except:
no_pil = 1
def points(val):
inch = float(val)/2.54
return (int(inch*72))
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class KwordDoc(TextDoc):
def open(self,filename):
self.photo_list = []
if filename[-4:] != ".kwd":
self.filename = filename + ".kwd"
else:
self.filename = filename
self.f = StringIO.StringIO()
self.m = StringIO.StringIO()
self.m.write('<?xml version="1.0" encoding="UTF-8"?>')
self.m.write('<!DOCTYPE document-info ><document-info>\n')
self.m.write('<log>\n')
self.m.write('<text></text>\n')
self.m.write('</log>\n')
self.m.write('<author>\n')
self.m.write('<full-name></full-name>\n')
self.m.write('<title></title>\n')
self.m.write('<company></company>\n')
self.m.write('<email></email>\n')
self.m.write('<telephone></telephone>\n')
self.m.write('<fax></fax>\n')
self.m.write('<country></country>\n')
self.m.write('<postal-code></postal-code>\n')
self.m.write('<city></city>\n')
self.m.write('<street></street>\n')
self.m.write('</author>\n')
self.m.write('<about>\n')
self.m.write('<abstract><![CDATA[]]></abstract>\n')
self.m.write('<title></title>\n')
self.m.write('</about>\n')
self.m.write('</document-info>\n')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>')
self.f.write('<!DOCTYPE DOC >')
self.f.write('<DOC mime="application/x-kword" syntaxVersion="2" ')
self.f.write('editor="KWord" >\n')
self.mtime = time.time()
if self.paper.name == "A3":
self.f.write('<PAPER format="0" ')
elif self.paper.name == "A4":
self.f.write('<PAPER format="1" ')
elif self.paper.name == "A5":
self.f.write('<PAPER format="2" ')
elif self.paper.name == "Letter":
self.f.write('<PAPER format="3" ')
elif self.paper.name == "Legal":
self.f.write('<PAPER format="4" ')
elif self.paper.name == "B5":
self.f.write('<PAPER format="7" ')
else:
self.f.write('<PAPER format="6" ')
self.f.write('width="%d" ' % points(self.width))
self.f.write('height="%d" ' % points(self.height))
if self.orientation == PAPER_PORTRAIT:
self.f.write('orientation="0" ')
else:
self.f.write('orientation="1" ')
self.f.write('columns="1" ')
self.f.write('columnspacing="2.83" ')
self.f.write('hType="0" ')
self.f.write('fType="0" ')
self.f.write('spHeadBody="9" ')
self.f.write('spFootBody="9">\n')
self.f.write('<PAPERBORDERS ')
self.f.write('top="%d" ' % points(self.tmargin))
self.f.write('right="%d" ' % points(self.rmargin))
self.f.write('bottom="%d" ' % points(self.bmargin))
self.f.write('left="%d"/>' % points(self.lmargin))
self.f.write('</PAPER>\n')
self.f.write('<ATTRIBUTES processing="0" ')
self.f.write('standardpage="1" ')
self.f.write('hasTOC="0" ')
self.f.write('hasHeader="0" ')
self.f.write('hasFooter="0" ')
self.f.write('unit="mm"/>\n')
self.f.write('<FRAMESETS>\n')
self.f.write('<FRAMESET frameType="1" ')
self.f.write('frameInfo="0" ')
self.f.write('name="Frameset 1">\n')
self.f.write('<FRAME left="%d" ' % points(self.lmargin))
self.f.write('top="%d" ' % points(self.tmargin))
self.f.write('right="%d" ' % points(self.width-self.rmargin))
self.f.write('bottom="%d" ' % points(self.height-self.bmargin))
self.f.write('runaround="1" />\n')
def close(self):
self.f.write('</FRAMESET>\n')
for p in self.photo_list:
self.f.write('<FRAMESET frameType="2" frameInfo="0" ')
self.f.write('name="%s" visible="1">\n' % p[1])
self.f.write('<FRAME runaround="1" copy="0" newFrameBehaviour="1" ')
self.f.write('right="%d" ' % p[2])
self.f.write('left="0" ')
self.f.write('bottom="%d" ' % p[3])
self.f.write('top="0" ')
self.f.write('runaroundGap="2.8"/>\n')
self.f.write('<IMAGE keepAspectRatio="true">\n')
self.f.write('<KEY filename="%s" ' % p[1])
a = time.localtime(self.mtime)
self.f.write('msec="%d" ' % a[6])
self.f.write('second="%d" ' % a[5])
self.f.write('minute="%d" ' % a[4])
self.f.write('hour="%d" ' % a[3])
self.f.write('day="%d" ' % a[2])
self.f.write('month="%d" ' % a[1])
self.f.write('year="%d"/>\n' % a[0])
self.f.write('</IMAGE>\n')
self.f.write('</FRAMESET>\n')
self.f.write('</FRAMESETS>\n')
self.f.write('<STYLES>\n')
for name in self.style_list.keys():
self.f.write('<STYLE>\n')
self.f.write('<NAME value="%s"/>\n' % name)
p = self.style_list[name]
pad = points(p.get_padding())/2
self.f.write('<OFFSETS before="%d" after="%d"/>\n' % (pad,pad))
if p.get_alignment() == PARA_ALIGN_CENTER:
self.f.write('<FLOW value="center"/>\n')
elif p.get_alignment() == PARA_ALIGN_JUSTIFY:
self.f.write('<FLOW value="justify"/>\n')
elif p.get_alignment() == PARA_ALIGN_RIGHT:
self.f.write('<FLOW value="right"/>\n')
else:
self.f.write('<FLOW value="left"/>\n')
first = p.get_first_indent()
left = p.get_left_margin()
right = p.get_right_margin()
self.f.write('<INDENTS first="%d" ' % points(first))
self.f.write('left="%d" right="%d"/>\n' % (points(left),points(right)))
font = p.get_font()
self.f.write('<FORMAT>\n')
if font.get_type_face==FONT_SANS_SERIF:
self.f.write('<FONT name="helvetica"/>\n')
else:
self.f.write('<FONT name="times"/>\n')
self.f.write('<SIZE value="%d"/>\n' % font.get_size())
self.f.write('<COLOR red="%d" green="%d" blue="%d"/>\n' % font.get_color())
if font.get_bold():
self.f.write('<WEIGHT value="75"/>\n')
if font.get_italic():
self.f.write('<ITALIC value="1"/>\n')
if font.get_underline():
self.f.write('<UNDERLINE value="1"/>\n')
self.f.write('</FORMAT>\n')
if p.get_top_border():
self.f.write('<TOPBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if p.get_bottom_border():
self.f.write('<BOTTOMBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if p.get_right_border():
self.f.write('<RIGHTBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if p.get_left_border():
self.f.write('<LEFTBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if left != 0:
self.f.write('<TABULATOR ptpos="%d" type="0"/>\n' % points(left))
self.f.write('</STYLE>\n')
self.f.write('</STYLES>\n')
self.f.write('<PIXMAPS>\n')
for file in self.photo_list:
self.f.write('<KEY name="%s" filename="%s" ' % (file[1],file[1]))
a = time.localtime(self.mtime)
self.f.write('msec="%d" ' % a[6])
self.f.write('second="%d" ' % a[5])
self.f.write('minute="%d" ' % a[4])
self.f.write('hour="%d" ' % a[3])
self.f.write('day="%d" ' % a[2])
self.f.write('month="%d" ' % a[1])
self.f.write('year="%d"/>\n' % a[0])
self.f.write('</PIXMAPS>\n')
self.f.write('</DOC>\n')
tar = TarFile(self.filename)
tar.add_file("documentinfo.xml",self.mtime,self.m)
tar.add_file("maindoc.xml",self.mtime,self.f)
for file in self.photo_list:
f = open(file[0],"r")
tar.add_file(file[1],self.mtime,f)
f.close()
tar.close()
self.f.close()
self.m.close()
def start_page(self,orientation=None):
pass
def end_page(self):
pass
def start_paragraph(self,style_name,leader=None):
self.format_list = []
self.bold_start = 0
self.text = ""
self.style_name = style_name
self.p = self.style_list[self.style_name]
self.font = self.p.get_font()
if self.font.get_type_face() == FONT_SERIF:
self.font_face = "times"
else:
self.font_face = "helvetica"
if leader != None:
self.text = leader + '\t'
txt = '<FORMAT id="1" pos="0" len="%d">\n' % (len(leader)+1)
txt = txt + '<FONT name="%s"/>\n</FORMAT>\n' % self.font_face
self.format_list.append(txt)
self.bold_stop = len(self.text)
def end_paragraph(self):
if self.bold_start != 0 and self.bold_stop != len(self.text):
txt = '<FORMAT>\n<FONT name="%s"/>\n</FORMAT>\n' % self.font_face
self.format_list.append(txt)
self.f.write('<PARAGRAPH>\n')
self.f.write('<TEXT>')
self.f.write(latin_to_utf8(self.text))
self.f.write('</TEXT>\n')
self.f.write('<FORMATS>\n')
for format in self.format_list:
self.f.write(format)
self.f.write('</FORMATS>\n')
self.f.write('<LAYOUT>\n')
self.f.write('<NAME value="%s"/>\n' % self.style_name)
pad = points(self.p.get_padding())/2
self.f.write('<OFFSETS before="%d" after="%d"/>\n' % (pad,pad))
if self.p.get_alignment() == PARA_ALIGN_CENTER:
self.f.write('<FLOW value="center"/>\n')
elif self.p.get_alignment() == PARA_ALIGN_JUSTIFY:
self.f.write('<FLOW value="justify"/>\n')
elif self.p.get_alignment() == PARA_ALIGN_RIGHT:
self.f.write('<FLOW value="right"/>\n')
else:
self.f.write('<FLOW value="left"/>\n')
first = self.p.get_first_indent()
left = self.p.get_left_margin()
right = self.p.get_right_margin()
self.f.write('<INDENTS first="%d" ' % points(first))
self.f.write('left="%d" right="%d"/>\n' % (points(left),points(right)))
self.f.write('<FORMAT>\n')
self.f.write('<FONT name="%s"/>\n' % self.font_face)
self.f.write('<SIZE value="%d"/>\n' % self.font.get_size())
self.f.write('<COLOR red="%d" green="%d" blue="%d"/>\n' % self.font.get_color())
if self.font.get_bold():
self.f.write('<WEIGHT value="75"/>\n')
if self.font.get_italic():
self.f.write('<ITALIC value="1"/>\n')
if self.font.get_underline():
self.f.write('<UNDERLINE value="1"/>\n')
if self.p.get_top_border():
self.f.write('<TOPBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if self.p.get_bottom_border():
self.f.write('<BOTTOMBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if self.p.get_right_border():
self.f.write('<RIGHTBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
if self.p.get_left_border():
self.f.write('<LEFTBORDER red="0" green="0" blue="0" style="0" width="1"/>\n')
self.f.write('</FORMAT>\n')
if left != 0:
self.f.write('<TABULATOR ptpos="%d" type="0"/>\n' % points(left))
self.f.write('</LAYOUT>\n')
self.f.write('</PARAGRAPH>\n')
def start_bold(self):
self.bold_start = len(self.text)
if self.bold_stop != self.bold_start:
length = self.bold_stop - self.bold_start
txt = '<FORMAT id="1" pos="%d" len="%d">\n' % (self.bold_stop,length)
txt = txt + '<FONT name="%s"/>\n</FORMAT>\n' % self.font_face
self.format_list.append(txt)
def end_bold(self):
self.bold_stop = len(self.text)
length = self.bold_stop - self.bold_start
txt = '<FORMAT id="1" pos="%d" len="%d">\n' % (self.bold_start,length)
txt = txt + '<FONT name="%s"/>\n<WEIGHT value="75"/>\n</FORMAT>\n' % self.font_face
self.format_list.append(txt)
def start_table(self,name,style_name):
pass
def end_table(self):
pass
def start_row(self):
pass
def end_row(self):
pass
def start_cell(self,style_name,span=1):
pass
def end_cell(self):
pass
def add_photo(self,name,pos,x,y):
if no_pil:
return
im = PIL.Image.open(name)
nx,ny = im.size
scale = float(nx)/float(ny)
x = points(x)
y = points(y)
if scale > 1.0:
scale = 1.0/scale
act_width = x
act_height = y * scale
else:
act_width = x * scale
act_height = y
index = len(self.photo_list)+1
tag = 'pictures/picture%d.jpeg' % index
self.photo_list.append((name,tag,act_width,act_height))
txt = '<FORMAT id="6" pos="%d" len="1">\n' % len(self.text)
txt = txt + '<ANCHOR type="frameset" instance="%s"/>\n' % tag
txt = txt + '</FORMAT>\n'
self.bold_stop = len(self.text)
self.format_list.append(txt)
self.text = self.text + '#'
def horizontal_line(self):
pass
def write_text(self,text):
self.text = self.text + text
if __name__ == "__main__":
paper = PaperStyle("Letter",27.94,21.59)
styles = StyleSheet()
foo = FontStyle()
foo.set_type_face(FONT_SANS_SERIF)
foo.set_color((255,0,0))
foo.set_size(24)
foo.set_underline(1)
foo.set_bold(1)
foo.set_italic(1)
para = ParagraphStyle()
para.set_alignment(PARA_ALIGN_RIGHT)
para.set_font(foo)
styles.add_style("Title",para)
foo = FontStyle()
foo.set_type_face(FONT_SERIF)
foo.set_size(12)
para = ParagraphStyle()
para.set_font(foo)
styles.add_style("Normal",para)
doc = KwordDoc(styles,paper,PAPER_PORTRAIT)
doc.open("/home/dona/test")
doc.start_paragraph("Title")
doc.write_text("My Title")
doc.end_paragraph()
doc.start_paragraph("Normal")
doc.write_text("Hello there. This is fun")
doc.end_paragraph()
doc.start_paragraph("Normal")
doc.write_text("This is fun. ")
doc.add_photo("/home/dona/dad.jpg",2.0,2.0)
doc.write_text("So is this. ")
doc.end_paragraph()
doc.close()
Plugins.register_text_doc(_("KWord"),KwordDoc,0,1,1)

136
src/docgen/LaTeXDoc.py Normal file
View File

@ -0,0 +1,136 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
from TextDoc import *
from latin_utf8 import latin_to_utf8
import Plugins
import intl
_ = intl.gettext
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class LaTeXDoc(TextDoc):
def open(self,filename):
if filename[-4:] != ".tex":
self.filename = filename + ".tex"
else:
self.filename = filename
self.f = open(self.filename,"w")
options = "12pt"
if self.orientation == PAPER_LANDSCAPE:
options = options + ",landscape"
if self.paper.name == "A4":
options = options + ",a4paper"
elif self.paper.name == "A5":
options = options + ",a5paper"
elif self.paper.name == "B5":
options = options + ",b4paper"
self.f.write('\\documentclass[%s]{article}\n' % options)
self.f.write('\\usepackage[T1]{fontenc}\n')
self.f.write('\\usepackage[latin1]{inputenc}\n')
self.f.write('\\begin{document}\n')
self.f.write("\\title{}\n")
self.f.write("\\author{}\n")
self.in_list = 0
def close(self):
if self.in_list:
self.f.write('\\end{description}\n')
self.f.write('\\end{document}\n')
self.f.close()
def start_page(self,orientation=None):
pass
def end_page(self):
self.f.write('\\newpage')
def start_paragraph(self,style_name,leader=None):
style = self.style_list[style_name]
self.level = style.get_header_level()
if leader == None and self.in_list:
self.f.write('\\end{description}\n')
self.in_list = 0
if self.level == 1 :
self.f.write('\\section*{')
elif self.level == 2:
self.f.write('\\subsection*{')
elif self.level == 3:
self.f.write('\\subsubsection*{')
if leader != None and not self.in_list:
self.f.write('\\begin{description}\n')
self.in_list = 1
if leader != None:
self.f.write('\\item{%s} ' % leader)
def end_paragraph(self):
if self.level > 0:
self.f.write('}\n')
elif not self.in_list:
self.f.write('\n\\par\\noindent\n')
else:
self.f.write('\n')
def start_bold(self):
self.f.write('\\bfseries ')
pass
def end_bold(self):
self.f.write('\\mdseries ')
pass
def start_table(self,name,style_name):
pass
def end_table(self):
pass
def start_row(self):
pass
def end_row(self):
pass
def start_cell(self,style_name,span=1):
pass
def end_cell(self):
pass
def add_photo(self,name,pos,x,y):
pass
def horizontal_line(self):
pass
def write_text(self,text):
self.f.write(text)
Plugins.register_text_doc(_("LaTeX"),LaTeXDoc,0,1,0)

449
src/docgen/OpenDrawDoc.py Normal file
View File

@ -0,0 +1,449 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
import os
import tempfile
import string
import Plugins
import intl
_ = intl.gettext
from TextDoc import *
from DrawDoc import *
from latin_utf8 import latin_to_utf8
import const
try:
from codecs import *
except:
def EncodedFile(a,b,c):
return a
class OpenDrawDoc(DrawDoc):
def __init__(self,styles,type,orientation):
DrawDoc.__init__(self,styles,type,orientation)
self.f = None
self.filename = None
self.level = 0
self.time = "0000-00-00T00:00:00"
self.page = 0
def open(self,filename):
import time
t = time.localtime(time.time())
self.time = "%04d-%02d-%02dT%02d:%02d:%02d" % \
(t[0],t[1],t[2],t[3],t[4],t[5])
if filename[-4:] != ".sxd":
self.filename = filename + ".sxd"
else:
self.filename = filename
tempfile.tempdir = "/tmp"
self.tempdir = tempfile.mktemp()
os.mkdir(self.tempdir,0700)
os.mkdir(self.tempdir + os.sep + "Pictures")
os.mkdir(self.tempdir + os.sep + "META-INF")
fname = self.tempdir + os.sep + "content.xml"
self.f = EncodedFile(open(fname,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-content ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:style="http://openoffice.org/2000/style" ')
self.f.write('xmlns:text="http://openoffice.org/2000/text" ')
self.f.write('xmlns:table="http://openoffice.org/2000/table" ')
self.f.write('xmlns:draw="http://openoffice.org/2000/drawing" ')
self.f.write('xmlns:fo="http://www.w3.org/1999/XSL/Format" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:number="http://openoffice.org/2000/datastyle" ')
self.f.write('xmlns:svg="http://www.w3.org/2000/svg" ')
self.f.write('xmlns:chart="http://openoffice.org/2000/chart" ')
self.f.write('xmlns:dr3d="http://openoffice.org/2000/dr3d" ')
self.f.write('xmlns:math="http://www.w3.org/1998/Math/MathML" ')
self.f.write('xmlns:form="http://openoffice.org/2000/form" ')
self.f.write('xmlns:script="http://openoffice.org/2000/script" ')
self.f.write('office:class="text" office:version="0.9">\n')
self.f.write('<office:script/>\n')
self.f.write('<office:font-decls>\n')
self.f.write('<style:font-decl style:name="Times New Roman" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('<style:font-decl style:name="Arial" ')
self.f.write('fo:font-family="Arial" ')
self.f.write('style:font-family-generic="swiss" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('</office:font-decls>\n')
self.f.write('<office:automatic-styles>\n')
self.f.write('<style:style style:name="P1" style:family="paragraph">\n')
self.f.write('<style:properties fo:margin-left="0cm" ')
self.f.write('fo:margin-right="0cm" fo:text-indent="0cm"/>\n')
self.f.write('</style:style>\n')
for key in self.style_list.keys():
style = self.style_list[key]
self.f.write('<style:style style:name="T' + key + '" ')
self.f.write('style:family="text">\n')
self.f.write('<style:properties ')
font = style.get_font()
if font.get_type_face() == FONT_SANS_SERIF:
self.f.write('fo:font-family="Arial" ')
else:
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('fo:font-size="' + str(font.get_size()) + 'pt" ')
color = font.get_color()
self.f.write('fo:color="#%02x%02x%02x" ' % color)
if font.get_bold():
self.f.write('fo:font-weight="bold" ')
if font.get_italic():
self.f.write('fo:font-style="italic" ')
if font.get_underline():
self.f.write('style:text-underline="single" ')
self.f.write('style:text-underline-color="font-color" ')
self.f.write('/>\n')
self.f.write('</style:style>\n')
self.f.write('</office:automatic-styles>\n')
self.f.write('<office:body>\n')
def close(self):
self.f.write('</office:body>\n')
self.f.write('</office:document-content>\n')
self.f.close()
self._write_styles_file()
self._write_manifest()
self._write_meta_file()
self._write_zip()
def _write_zip(self):
if os.path.isfile(self.filename):
os.unlink(self.filename)
os.system("cd " + self.tempdir + "; " + const.zipcmd + " " \
+ self.filename + " .")
os.unlink(self.tempdir + os.sep + "META-INF" + os.sep + "manifest.xml")
os.unlink(self.tempdir + os.sep + "content.xml")
os.unlink(self.tempdir + os.sep + "meta.xml")
os.unlink(self.tempdir + os.sep + "styles.xml")
# for image in self.image_list:
# os.unlink(self.tempdir + os.sep + "Pictures" + os.sep + image)
os.rmdir(self.tempdir + os.sep + "Pictures")
os.rmdir(self.tempdir + os.sep + "META-INF")
os.rmdir(self.tempdir)
def _write_styles_file(self):
file = self.tempdir + os.sep + "styles.xml"
self.f = EncodedFile(open(file,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-styles ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:style="http://openoffice.org/2000/style" ')
self.f.write('xmlns:text="http://openoffice.org/2000/text" ')
self.f.write('xmlns:table="http://openoffice.org/2000/table" ')
self.f.write('xmlns:draw="http://openoffice.org/2000/drawing" ')
self.f.write('xmlns:fo="http://www.w3.org/1999/XSL/Format" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:number="http://openoffice.org/2000/datastyle" ')
self.f.write('xmlns:svg="http://www.w3.org/2000/svg" ')
self.f.write('xmlns:chart="http://openoffice.org/2000/chart" ')
self.f.write('xmlns:dr3d="http://openoffice.org/2000/dr3d" ')
self.f.write('xmlns:math="http://www.w3.org/1998/Math/MathML" ')
self.f.write('xmlns:form="http://openoffice.org/2000/form" ')
self.f.write('xmlns:script="http://openoffice.org/2000/script" ')
self.f.write('office:class="text" office:version="0.9">\n')
self.f.write('<office:font-decls>\n')
self.f.write('<style:font-decl style:name="Times New Roman" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('<style:font-decl style:name="Arial" ')
self.f.write('fo:font-family="Arial" ')
self.f.write('style:font-family-generic="swiss" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('</office:font-decls>\n')
self.f.write('<office:styles>\n')
self.f.write('<draw:marker draw:name="Arrow" svg:viewBox="0 0 200 400"')
self.f.write(' svg:d="m100 0 100 400h-200z"/>\n')
self.f.write('<style:default-style style:family="graphics">\n')
self.f.write('<style:properties fo:color="#000000" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-style-name="" style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable" fo:font-size="24pt" ')
self.f.write('fo:language="en" fo:country="US" ')
self.f.write('style:line-break="strict"/>\n')
self.f.write('</style:default-style>\n')
self.f.write('<style:style style:name="standard" style:family="graphics">\n')
self.f.write('<style:properties draw:stroke="solid" ')
self.f.write('svg:stroke-width="0cm" ')
self.f.write('svg:stroke-color="#000000" ')
self.f.write('draw:marker-start-width="0.3cm" ')
self.f.write('draw:marker-start-center="false" ')
self.f.write('draw:marker-end-width="0.3cm" ')
self.f.write('draw:marker-end-center="false" ')
self.f.write('draw:fill="solid" ')
self.f.write('draw:fill-color="#00b8ff" ')
self.f.write('draw:shadow="hidden" ')
self.f.write('draw:shadow-offset-x="0.3cm" ')
self.f.write('draw:shadow-offset-y="0.3cm" ')
self.f.write('draw:shadow-color="#808080" ')
self.f.write('fo:color="#000000" ')
self.f.write('style:text-outline="false" ')
self.f.write('style:text-crossing-out="none" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-style-name="" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable" ')
self.f.write('fo:font-size="24pt" ')
self.f.write('fo:font-style="normal" ')
self.f.write('fo:text-shadow="none" ')
self.f.write('style:text-underline="none" ')
self.f.write('fo:font-weight="normal" ')
self.f.write('fo:line-height="100%" ')
self.f.write('fo:text-align="start" ')
self.f.write('text:enable-numbering="false" ')
self.f.write('fo:margin-left="0cm" ')
self.f.write('fo:margin-right="0cm" ')
self.f.write('fo:text-indent="0cm" ')
self.f.write('fo:margin-top="0cm" ')
self.f.write('fo:margin-bottom="0cm"/>\n')
self.f.write('</style:style>\n')
for style_name in self.draw_styles.keys():
style = self.draw_styles[style_name]
self.f.write('<style:style style:name="')
self.f.write(style_name)
self.f.write('" style:family="graphics" ')
self.f.write('style:parent-style-name="standard">\n')
self.f.write('<style:properties ')
self.f.write('draw:fill-color="#%02x%02x%02x" ' % style.get_color())
if style.get_shadow():
self.f.write('draw:shadow="visible" ')
else:
self.f.write('draw:shadow="hidden" ')
self.f.write('/>\n')
self.f.write('</style:style>\n')
self.f.write('<style:style style:name="Standard" ')
self.f.write('style:family="paragraph" style:class="text"/>\n')
for key in self.style_list.keys():
style = self.style_list[key]
self.f.write('<style:style style:name="' + key + '" ')
self.f.write('style:family="paragraph" ')
self.f.write('style:parent-style-name="Standard" ')
self.f.write('style:class="text">\n')
self.f.write('<style:properties ')
if style.get_padding() != 0.0:
self.f.write('fo:padding="%.3fcm" ' % style.get_padding())
align = style.get_alignment()
if align == PARA_ALIGN_LEFT:
self.f.write('fo:text-align="left" ')
elif align == PARA_ALIGN_RIGHT:
self.f.write('fo:text-align="right" ')
elif align == PARA_ALIGN_CENTER:
self.f.write('fo:text-align="center" ')
self.f.write('style:justify-single-word="false" ')
else:
self.f.write('fo:text-align="justify" ')
self.f.write('style:justify-single-word="false" ')
font = style.get_font()
if font.get_type_face() == FONT_SANS_SERIF:
self.f.write('style:font-name="Arial" ')
else:
self.f.write('style:font-name="Times New Roman" ')
self.f.write('fo:font-size="' + str(font.get_size()) + 'pt" ')
color = font.get_color()
self.f.write('fo:color="#%02x%02x%02x" ' % color)
if font.get_bold():
self.f.write('fo:font-weight="bold" ')
if font.get_italic():
self.f.write('fo:font-style="italic" ')
if font.get_underline():
self.f.write('style:text-underline="single" ')
self.f.write('style:text-underline-color="font-color" ')
self.f.write('fo:text-indent="%.2fcm" ' % style.get_first_indent())
self.f.write('fo:margin-right="%.2fcm" ' % style.get_right_margin())
self.f.write('fo:margin-left="%.2fcm" ' % style.get_left_margin())
self.f.write('fo:margin-top="0cm" ')
self.f.write('fo:margin-bottom="0.212cm"')
self.f.write('/>\n')
self.f.write('</style:style>\n')
# Current no leading number format for headers
self.f.write('</office:styles>\n')
self.f.write('<office:automatic-styles>\n')
self.f.write('<style:page-master style:name="PM0">\n')
self.f.write('<style:properties fo:page-width="%.2fcm" ' % self.width)
self.f.write('fo:page-height="%.2fcm" ' % self.height)
self.f.write('style:num-format="1" ')
if self.orientation == PAPER_PORTRAIT:
self.f.write('style:print-orientation="portrait" ')
else:
self.f.write('style:print-orientation="landscape" ')
self.f.write('fo:margin-top="%.2fcm" ' % self.tmargin)
self.f.write('fo:margin-bottom="%.2fcm" ' % self.bmargin)
self.f.write('fo:margin-left="%.2fcm" ' % self.lmargin)
self.f.write('fo:margin-right="%.2fcm"/>\n' % self.rmargin)
self.f.write('</style:page-master>\n')
self.f.write('<style:style style:name="dp1" style:family="drawing-page">\n')
self.f.write('<style:properties draw:background-size="border" draw:fill="none"/>\n')
self.f.write('</style:style>\n')
self.f.write('</office:automatic-styles>\n')
self.f.write('<office:master-styles>\n')
self.f.write('<draw:layer-set>\n')
self.f.write('<draw:layer draw:name="layout" draw:locked="false" ')
self.f.write('draw:printable="true" draw:visible="true"/>\n')
self.f.write('<draw:layer draw:name="background" draw:locked="false" ')
self.f.write('draw:printable="true" draw:visible="true"/>\n')
self.f.write('<draw:layer draw:name="backgroundobjects" ')
self.f.write('draw:locked="false" draw:printable="true" draw:visible="true"/>\n')
self.f.write('<draw:layer draw:name="controls" draw:locked="false" ')
self.f.write('draw:printable="true" draw:visible="true"/>\n')
self.f.write('<draw:layer draw:name="measurelines" draw:locked="false" ')
self.f.write('draw:printable="true" draw:visible="true"/>\n')
self.f.write('</draw:layer-set>\n')
self.f.write('<style:master-page style:name="Home" ')
self.f.write('style:page-master-name="PM0" draw:style-name="dp1"/>\n')
self.f.write('</office:master-styles>\n')
self.f.close()
def start_paragraph(self,style_name):
self.f.write('<text:p text:style-name="%s">' % style_name)
def end_paragraph(self):
self.f.write('</text:p>\n')
def write_text(self,text):
text = string.replace(text,'\t','<text:tab-stop/>')
text = string.replace(text,'\n','<text:line-break/>')
self.f.write(latin_to_utf8(text))
def _write_manifest(self):
file = self.tempdir + os.sep + "META-INF" + os.sep + "manifest.xml"
self.f = EncodedFile(open(file,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<manifest:manifest ')
self.f.write('xmlns:manifest="http://openoffice.org/2001/manifest">')
self.f.write('<manifest:file-entry ')
self.f.write('manifest:media-type="application/vnd.sun.xml.draw" ')
self.f.write('manifest:full-path="/"/>')
self.f.write('<manifest:file-entry manifest:media-type="" ')
self.f.write('manifest:full-path="Pictures/"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="content.xml"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="styles.xml"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="meta.xml"/>')
#self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
#self.f.write('manifest:full-path="settings.xml"/>')
self.f.write('</manifest:manifest>\n')
self.f.close()
def _write_meta_file(self):
file = self.tempdir + os.sep + "meta.xml"
name = latin_to_utf8(self.name)
self.f = EncodedFile(open(file,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-meta ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:dc="http://purl.org/dc/elements/1.1/" ')
self.f.write('xmlns:meta="http://openoffice.org/2000/meta" ')
self.f.write('office:class="text" office:version="0.9">\n');
self.f.write('<office:meta>\n')
self.f.write('<meta:generator>')
self.f.write(const.progName + ' ' + const.version)
self.f.write('</meta:generator>\n')
self.f.write('<meta:initial-creator>')
self.f.write(name)
self.f.write('</meta:initial-creator>\n')
self.f.write('<meta:creation-date>')
self.f.write(self.time)
self.f.write('</meta:creation-date>\n')
self.f.write('<dc:creator>')
self.f.write(name)
self.f.write('</dc:creator>\n')
self.f.write('<dc:date>')
self.f.write(self.time)
self.f.write('</dc:date>\n')
self.f.write('<meta:print-date>0-00-00T00:00:00</meta:print-date>\n')
self.f.write('<dc:language>en-US</dc:language>\n')
self.f.write('<meta:editing-cycles>1</meta:editing-cycles>\n')
self.f.write('<meta:editing-duration>PT0S</meta:editing-duration>\n')
self.f.write('<meta:user-defined meta:name="Info 0"/>\n')
self.f.write('<meta:user-defined meta:name="Info 1"/>\n')
self.f.write('<meta:user-defined meta:name="Info 2"/>\n')
self.f.write('<meta:user-defined meta:name="Info 3"/>\n')
self.f.write('</office:meta>\n')
self.f.write('</office:document-meta>\n')
self.f.close()
def start_page(self,orientation=None):
self.page = self.page + 1
self.f.write('<draw:page draw:name="page' + str(self.page) + '" ')
self.f.write('draw:master-page-name="Home">\n')
def end_page(self):
self.f.write('</draw:page>\n')
def draw_line(self,style,x1,y1,x2,y2):
self.f.write('<draw:line draw:style="')
self.f.write(style)
self.f.write('" svg:x1="%.3fcm" ' % x1)
self.f.write('svg:y1="%.3fcm" ' % y1)
self.f.write('svg:x2="%.3fcm" ' % x2)
self.f.write('svg:y2="%.3fcm"/>\n' % y2)
def draw_box(self,style,text,x,y):
box_style = self.draw_styles[style]
para_name = box_style.get_paragraph_style()
self.f.write('<draw:rect draw:style-name="')
self.f.write(style)
self.f.write('" draw:layer="layout" ')
self.f.write('svg:width="%.3fcm" ' % box_style.get_width())
self.f.write('svg:height="%.3fcm" ' % box_style.get_height())
self.f.write('svg:x="%.3fcm" ' % float(x))
self.f.write('svg:y="%.3fcm"' % float(y))
if text != "":
text = string.replace(text,'\t','<text:tab-stop/>')
text = latin_to_utf8(string.replace(text,'\n','<text:line-break/>'))
self.f.write('>\n')
self.f.write('<text:p text:style-name="P1">')
self.f.write('<text:span text:style-name="T%s">' % para_name)
self.f.write(text)
self.f.write('</text:span></text:p>\n')
self.f.write('</draw:rect>\n')
else:
self.f.write('/>\n')
Plugins.register_draw_doc(_("OpenOffice/StarOffice 6"),OpenDrawDoc);

579
src/docgen/OpenOfficeDoc.py Normal file
View File

@ -0,0 +1,579 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
import os
import tempfile
import string
from TextDoc import *
from latin_utf8 import latin_to_utf8
import const
import utils
import Plugins
import intl
_ = intl.gettext
try:
import PIL.Image
no_pil = 0
except:
no_pil = 1
try:
from codecs import *
except:
def EncodedFile(a,b,c):
return a
class OpenOfficeDoc(TextDoc):
def __init__(self,styles,type,template,orientation):
TextDoc.__init__(self,styles,type,template,orientation)
self.f = None
self.filename = None
self.level = 0
self.time = "0000-00-00T00:00:00"
self.new_page = 0
def open(self,filename):
import time
t = time.localtime(time.time())
self.time = "%04d-%02d-%02dT%02d:%02d:%02d" % \
(t[0],t[1],t[2],t[3],t[4],t[5])
if filename[-4:] != ".sxw":
self.filename = filename + ".sxw"
else:
self.filename = filename
tempfile.tempdir = "/tmp"
self.tempdir = tempfile.mktemp()
os.mkdir(self.tempdir,0700)
os.mkdir(self.tempdir + os.sep + "Pictures")
os.mkdir(self.tempdir + os.sep + "META-INF")
fname = self.tempdir + os.sep + "content.xml"
self.f = EncodedFile(open(fname,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-content ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:style="http://openoffice.org/2000/style" ')
self.f.write('xmlns:text="http://openoffice.org/2000/text" ')
self.f.write('xmlns:table="http://openoffice.org/2000/table" ')
self.f.write('xmlns:draw="http://openoffice.org/2000/drawing" ')
self.f.write('xmlns:fo="http://www.w3.org/1999/XSL/Format" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:number="http://openoffice.org/2000/datastyle" ')
self.f.write('xmlns:svg="http://www.w3.org/2000/svg" ')
self.f.write('xmlns:chart="http://openoffice.org/2000/chart" ')
self.f.write('xmlns:dr3d="http://openoffice.org/2000/dr3d" ')
self.f.write('xmlns:math="http://www.w3.org/1998/Math/MathML" ')
self.f.write('xmlns:form="http://openoffice.org/2000/form" ')
self.f.write('xmlns:script="http://openoffice.org/2000/script" ')
self.f.write('office:class="text" office:version="0.9">\n')
self.f.write('<office:script/>\n')
self.f.write('<office:font-decls>\n')
self.f.write('<style:font-decl style:name="Times New Roman" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('<style:font-decl style:name="Arial" ')
self.f.write('fo:font-family="Arial" ')
self.f.write('style:font-family-generic="swiss" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('</office:font-decls>\n')
self.f.write('<office:automatic-styles>\n')
for style_name in self.style_list.keys():
style = self.style_list[style_name]
self.f.write('<style:style style:name="NL')
self.f.write(style_name)
self.f.write('" style:family="paragraph" ')
self.f.write('style:parent-style-name="')
self.f.write(style_name)
self.f.write('">\n<style:properties fo:break-before="page"/>\n')
self.f.write('</style:style>\n')
for style_name in self.table_styles.keys():
style = self.table_styles[style_name]
self.f.write('<style:style style:name="' + style_name + '" ')
self.f.write('style:family="table">\n')
table_width = float(self.get_usable_width())
table_width_str = "%.4f" % table_width
self.f.write('<style:properties style:width="%scm" '%table_width_str)
self.f.write('/>\n')
self.f.write('</style:style>\n')
for col in range(0,style.get_columns()):
self.f.write('<style:style style:name="')
self.f.write(style_name + '.' + str(chr(ord('A')+col)) +'" ')
self.f.write('style:family="table-column">')
width = table_width * float(style.get_column_width(col)/100.0)
width_str = "%.4f" % width
self.f.write('<style:properties ')
self.f.write('style:column-width="%scm"/>' % width_str)
self.f.write('</style:style>\n')
for cell in self.cell_styles.keys():
cell_style = self.cell_styles[cell]
self.f.write('<style:style style:name="')
self.f.write(cell)
self.f.write('" style:family="table-cell">\n')
self.f.write('<style:properties')
self.f.write(' fo:padding="%.3fcm"' % cell_style.get_padding())
if cell_style.get_top_border():
self.f.write(' fo:border-top="0.002cm solid #000000"')
else:
self.f.write(' fo:border-top="none"')
if cell_style.get_bottom_border():
self.f.write(' fo:border-bottom="0.002cm solid #000000"')
else:
self.f.write(' fo:border-bottom="none"')
if cell_style.get_left_border():
self.f.write(' fo:border-left="0.002cm solid #000000"')
else:
self.f.write(' fo:border-left="none"')
if cell_style.get_right_border():
self.f.write(' fo:border-right="0.002cm solid #000000"')
else:
self.f.write(' fo:border-right="none"')
self.f.write('/>\n')
self.f.write('</style:style>\n')
self.f.write('<style:style style:name="Tbold" style:family="text">\n')
self.f.write('<style:properties fo:font-weight="bold"/>\n')
self.f.write('</style:style>\n')
#Begin photo style
self.f.write('<style:style style:name="Left" style:family="graphics"')
self.f.write(' style:parent-name="photo">')
self.f.write('<style:properties style:run-through="foreground"')
self.f.write(' style:wrap="parallel"')
self.f.write(' style:numer-wrapped-paragraphs="no-limit"')
self.f.write(' style:wrap-contour="false" style:vertical-pos="from-top"')
self.f.write(' style:vertical-rel="paragraph-content"')
self.f.write(' style:horizontal-pos="left"')
self.f.write(' style:horizontal-rel="paragraph-contnet"')
self.f.write(' style:mirror="none" fo:clip="rect(0cm 0cm 0cm 0cm)"')
self.f.write(' draw:luminance="0%" draw:contrast="0" draw:red="0%"')
self.f.write(' draw:green="0%" draw:blue="0%" draw:gamma="1"')
self.f.write(' draw:color-inversion="false" draw:transparency="-100%"')
self.f.write(' draw:color-mode="standard"/>')
self.f.write('</style:style>\n')
self.f.write('<style:style style:name="Right" style:family="graphics"')
self.f.write(' style:parent-name="photo">')
self.f.write('<style:properties style:run-through="foreground"')
self.f.write(' style:wrap="parallel"')
self.f.write(' style:numer-wrapped-paragraphs="no-limit"')
self.f.write(' style:wrap-contour="false" style:vertical-pos="from-top"')
self.f.write(' style:vertical-rel="paragraph-content"')
self.f.write(' style:horizontal-pos="right"')
self.f.write(' style:horizontal-rel="paragraph-contnet"')
self.f.write(' style:mirror="none" fo:clip="rect(0cm 0cm 0cm 0cm)"')
self.f.write(' draw:luminance="0%" draw:contrast="0" draw:red="0%"')
self.f.write(' draw:green="0%" draw:blue="0%" draw:gamma="1"')
self.f.write(' draw:color-inversion="false" draw:transparency="-100%"')
self.f.write(' draw:color-mode="standard"/>')
self.f.write('</style:style>\n')
self.f.write('<style:style style:name="Single" style:family="graphics"')
self.f.write(' style:parent-name="Graphics">')
self.f.write('<style:properties style:vertical-pos="from-top"')
self.f.write(' style:mirror="none" fo:clip="rect(0cm 0cm 0cm 0cm)"')
self.f.write(' draw:luminance="0%" draw:contrast="0" draw:red="0%"')
self.f.write(' draw:green="0%" draw:blue="0%" draw:gamma="1"')
self.f.write(' draw:color-inversion="false" draw:transparency="-100%"')
self.f.write(' draw:color-mode="standard"/>')
self.f.write('</style:style>\n')
self.f.write('<style:style style:name="Row" style:family="graphics"')
self.f.write(' style:parent-name="Graphics">')
self.f.write('<style:properties style:vertical-pos="from-top"')
self.f.write(' style:vertical-rel="paragraph"')
self.f.write(' style:horizontal-pos="from-left" syle:horizontal-rel="paragraph"')
self.f.write(' style:mirror="none" fo:clip="rect(0cm 0cm 0cm 0cm)"')
self.f.write(' draw:luminance="0%" draw:contrast="0" draw:red="0%"')
self.f.write(' draw:green="0%" draw:blue="0%" draw:gamma="1"')
self.f.write(' draw:color-inversion="false" draw:transparency="-100%"')
self.f.write(' draw:color-mode="standard"/>')
self.f.write('</style:style>\n')
#end of Photo style edits
self.f.write('</office:automatic-styles>\n')
self.f.write('<office:body>\n')
def close(self):
self.f.write('</office:body>\n')
self.f.write('</office:document-content>\n')
self.f.close()
self._write_styles_file()
self._write_manifest()
self._write_meta_file()
self._write_photos()
self._write_zip()
def add_photo(self,name,pos,x_cm,y_cm):
import gtk
import GdkImlib
image = GdkImlib.Image(name)
scale = float(image.rgb_width)/float(image.rgb_height)
act_width = int(((x_cm * scale)*2.54)*72)
act_height = int(((y_cm * scale)*2.54)*72)
self.photo_list.append((name,act_width,act_height))
base = os.path.basename(name)
tag = string.replace(base,'.','_')
if pos == "left":
self.f.write('<draw:image draw:style-name="Left" ')
elif pos == "right":
self.f.write('<draw:image draw:style-name="Right" ')
elif pos == "single":
self.f.write('<draw:image draw:style-name="Single" ')
else:
self.f.write('<draw:image draw:style-name="Row" ')
self.f.write('draw:name="')
self.f.write(tag)
self.f.write('" text:anchor-type="paragraph" ')
self.f.write('svg:width="%.3fcm" ' % x_cm*scale)
self.f.write('svg:height="%.3fcm" ' % y_cm*scale)
self.f.write('draw:z-index="0" ')
self.f.write('xlink:href="#Pictures/')
self.f.write(base)
self.f.write('" xlink:type="simple" xlink:show="embed" ')
self.f.write('xlink:actuate="onLoad"/>\n')
def start_table(self,name,style_name):
self.f.write('<table:table table:name="')
self.f.write(name)
self.f.write('" table:style-name="' + style_name + '">\n')
table = self.table_styles[style_name]
for col in range(0,table.get_columns()):
self.f.write('<table:table-column table:style-name="')
self.f.write(style_name + '.' + str(chr(ord('A')+col)) +'"/>\n')
def end_table(self):
self.f.write('</table:table>\n')
def start_row(self):
self.f.write('<table:table-row>\n')
def end_row(self):
self.f.write('</table:table-row>\n')
def start_cell(self,style_name,span=1):
self.span = span
self.f.write('<table:table-cell table:style-name="')
self.f.write(style_name)
self.f.write('" table:value-type="string"')
if span > 1:
self.f.write(' table:number-columns-spanned="' + str(span) + '">\n')
else:
self.f.write('>\n')
def end_cell(self):
self.f.write('</table:table-cell>\n')
for col in range(1,self.span):
self.f.write('<table:covered-table-cell/>\n')
def start_bold(self):
self.f.write('<text:span text:style-name="Tbold">')
def end_bold(self):
self.f.write('</text:span>')
def _write_zip(self):
if os.path.isfile(self.filename):
os.unlink(self.filename)
os.system("cd " + self.tempdir + "; " + const.zipcmd + " " \
+ self.filename + " .")
os.unlink(self.tempdir + os.sep + "META-INF" + os.sep + "manifest.xml")
os.unlink(self.tempdir + os.sep + "content.xml")
os.unlink(self.tempdir + os.sep + "meta.xml")
os.unlink(self.tempdir + os.sep + "styles.xml")
for image in self.photo_list:
base = os.path.basename(image[0])
os.unlink(self.tempdir + os.sep + "Pictures" + os.sep + base)
os.rmdir(self.tempdir + os.sep + "Pictures")
os.rmdir(self.tempdir + os.sep + "META-INF")
os.rmdir(self.tempdir)
def _write_styles_file(self):
file = self.tempdir + os.sep + "styles.xml"
self.f = EncodedFile(open(file,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-styles ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:style="http://openoffice.org/2000/style" ')
self.f.write('xmlns:text="http://openoffice.org/2000/text" ')
self.f.write('xmlns:table="http://openoffice.org/2000/table" ')
self.f.write('xmlns:draw="http://openoffice.org/2000/drawing" ')
self.f.write('xmlns:fo="http://www.w3.org/1999/XSL/Format" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:number="http://openoffice.org/2000/datastyle" ')
self.f.write('xmlns:svg="http://www.w3.org/2000/svg" ')
self.f.write('xmlns:chart="http://openoffice.org/2000/chart" ')
self.f.write('xmlns:dr3d="http://openoffice.org/2000/dr3d" ')
self.f.write('xmlns:math="http://www.w3.org/1998/Math/MathML" ')
self.f.write('xmlns:form="http://openoffice.org/2000/form" ')
self.f.write('xmlns:script="http://openoffice.org/2000/script" ')
self.f.write('office:class="text" office:version="0.9">\n')
self.f.write('<office:font-decls>\n')
self.f.write('<style:font-decl style:name="Times New Roman" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('<style:font-decl style:name="Arial" ')
self.f.write('fo:font-family="Arial" ')
self.f.write('style:font-family-generic="swiss" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('</office:font-decls>\n')
self.f.write('<office:styles>\n')
self.f.write('<style:default-style style:family="paragraph">\n')
self.f.write('<style:properties style:font-name="Times New Roman" ')
self.f.write('style:font-pitch-asian="fixed" ')
self.f.write('style:font-pitch-complex="fixed" ')
self.f.write('style:tab-stop-distance="2.205cm"/>\n')
self.f.write('</style:default-style>\n')
self.f.write('<style:style style:name="Standard" ')
self.f.write('style:family="paragraph" style:class="text"/>\n')
self.f.write('<style:style style:name="photo" style:family="graphics">\n')
self.f.write('<style:properties text:anchor-type="paragraph" ')
self.f.write('svg:x="0cm" svg:y="0cm" style:wrap="none" ')
self.f.write('style:vertical-pos="top" ')
self.f.write('style:vertical-rel="paragraph-content" ')
self.f.write('style:horizontal-pos="center" ')
self.f.write('style:horizontal-rel="paragraph-content"/>\n')
self.f.write('</style:style>\n')
for key in self.style_list.keys():
style = self.style_list[key]
self.f.write('<style:style style:name="' + key + '" ')
self.f.write('style:family="paragraph" ')
self.f.write('style:parent-style-name="Standard" ')
self.f.write('style:class="text">\n')
self.f.write('<style:properties ')
if style.get_padding() != 0.0:
self.f.write('fo:padding="%.3fcm" ' % style.get_padding())
align = style.get_alignment()
if align == PARA_ALIGN_LEFT:
self.f.write('fo:text-align="left" ')
elif align == PARA_ALIGN_RIGHT:
self.f.write('fo:text-align="right" ')
elif align == PARA_ALIGN_CENTER:
self.f.write('fo:text-align="center" ')
self.f.write('style:justify-single-word="false" ')
else:
self.f.write('fo:text-align="justify" ')
self.f.write('style:justify-single-word="false" ')
font = style.get_font()
if font.get_type_face() == FONT_SANS_SERIF:
self.f.write('style:font-name="Arial" ')
else:
self.f.write('style:font-name="Times New Roman" ')
self.f.write('fo:font-size="' + str(font.get_size()) + 'pt" ')
color = font.get_color()
self.f.write('fo:color="#%02x%02x%02x" ' % color)
if font.get_bold():
self.f.write('fo:font-weight="bold" ')
if font.get_italic():
self.f.write('fo:font-style="italic" ')
if font.get_underline():
self.f.write('style:text-underline="single" ')
self.f.write('style:text-underline-color="font-color" ')
self.f.write('fo:text-indent="%.2fcm" ' % style.get_first_indent())
self.f.write('fo:margin-right="%.2fcm" ' % style.get_right_margin())
self.f.write('fo:margin-left="%.2fcm" ' % style.get_left_margin())
self.f.write('fo:margin-top="0cm" ')
self.f.write('fo:margin-bottom="0.212cm"')
self.f.write('/>\n')
self.f.write('</style:style>\n')
# Current no leading number format for headers
self.f.write('<text:outline-style>\n')
self.f.write('<text:outline-level-style text:level="1" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="2" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="3" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="4" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="5" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="6" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="7" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="8" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="9" style:num-format=""/>\n')
self.f.write('<text:outline-level-style text:level="10" style:num-format=""/>\n')
self.f.write('</text:outline-style>\n')
self.f.write('</office:styles>\n')
self.f.write('<office:automatic-styles>\n')
self.f.write('<style:page-master style:name="pm1">\n')
self.f.write('<style:properties fo:page-width="%.3fcm" ' % self.width)
self.f.write('fo:page-height="%.3fcm" ' % self.height)
self.f.write('style:num-format="1" ')
if self.orientation == PAPER_PORTRAIT:
self.f.write('style:print-orientation="portrait" ')
else:
self.f.write('style:print-orientation="landscape" ')
self.f.write('fo:margin-top="%.2fcm" ' % self.tmargin)
self.f.write('fo:margin-bottom="%.2fcm" ' % self.bmargin)
self.f.write('fo:margin-left="%.2fcm" ' % self.lmargin)
self.f.write('fo:margin-right="%.2fcm" ' % self.rmargin)
self.f.write('style:footnote-max-height="0cm">\n')
self.f.write('<style:footnote-sep style:width="0.018cm" ')
self.f.write('style:distance-before-sep="0.101cm" ')
self.f.write('style:distance-after-sep="0.101cm" ')
self.f.write('style:adjustment="left" style:rel-width="25%" ')
self.f.write('style:color="#000000"/>\n')
self.f.write('</style:properties>\n')
self.f.write('<style:header-style/>\n')
self.f.write('<style:footer-style/>\n')
self.f.write('</style:page-master>\n')
self.f.write('</office:automatic-styles>\n')
self.f.write('<office:master-styles>\n')
self.f.write('<style:master-page style:name="Standard" ')
self.f.write('style:page-master-name="pm1"/>\n')
self.f.write('</office:master-styles>\n')
self.f.write('</office:document-styles>\n')
self.f.close()
def page_break(self):
self.new_page = 1
def start_paragraph(self,style_name,leader=None):
style = self.style_list[style_name]
self.level = style.get_header_level()
if self.new_page == 1:
self.new_page = 0
name = "NL%s" % style_name
else:
name = style_name
if self.level == 0:
self.f.write('<text:p text:style-name="%s">' % name)
else:
self.f.write('<text:h text:style-name="')
self.f.write(name)
self.f.write('" text:level="' + str(self.level) + '">')
if leader != None:
self.f.write(latin_to_utf8(leader))
self.f.write('<text:tab-stop/>')
def end_paragraph(self):
if self.level == 0:
self.f.write('</text:p>\n')
else:
self.f.write('</text:h>\n')
def write_text(self,text):
text = string.replace(text,'\n','<text:line-break/>')
self.f.write(latin_to_utf8(text))
def _write_photos(self):
for file_tuple in self.photo_list:
file = file_tuple[0]
width = file_tuple[1]
height = file_tuple[2]
base = os.path.basename(file)
image_name = self.tempdir + os.sep + "Pictures" + os.sep + base
if no_pil:
cmd = "%s -geometry %dx%d '%s' '%s'" % (const.convert,width,height,file,image_name)
os.system(cmd)
else:
im = PIL.Image.open(file)
im.thumbnail((width,height))
im.save(image_name,"JPEG")
def _write_manifest(self):
file = self.tempdir + os.sep + "META-INF" + os.sep + "manifest.xml"
self.f = EncodedFile(open(file,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<manifest:manifest ')
self.f.write('xmlns:manifest="http://openoffice.org/2001/manifest">')
self.f.write('<manifest:file-entry ')
self.f.write('manifest:media-type="application/vnd.sun.xml.writer" ')
self.f.write('manifest:full-path="/"/>')
for image in self.photo_list:
i = image[0]
base = os.path.basename(i)
self.f.write('<manifest:file-entry manifest:media-type="" ')
self.f.write('manifest:full-path="Pictures/')
self.f.write(base)
self.f.write('"/>')
self.f.write('<manifest:file-entry manifest:media-type="" ')
self.f.write('manifest:full-path="Pictures/"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="content.xml"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="styles.xml"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="meta.xml"/>')
self.f.write('</manifest:manifest>\n')
self.f.close()
def _write_meta_file(self):
file = self.tempdir + os.sep + "meta.xml"
name = latin_to_utf8(self.name)
self.f = EncodedFile(open(file,"wb"),'latin-1','utf-8')
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-meta ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:dc="http://purl.org/dc/elements/1.1/" ')
self.f.write('xmlns:meta="http://openoffice.org/2000/meta" ')
self.f.write('office:class="text" office:version="0.9">\n');
self.f.write('<office:meta>\n')
self.f.write('<meta:generator>')
self.f.write(const.progName + ' ' + const.version)
self.f.write('</meta:generator>\n')
self.f.write('<meta:initial-creator>')
self.f.write(name)
self.f.write('</meta:initial-creator>\n')
self.f.write('<meta:creation-date>')
self.f.write(self.time)
self.f.write('</meta:creation-date>\n')
self.f.write('<dc:creator>')
self.f.write(name)
self.f.write('</dc:creator>\n')
self.f.write('<dc:date>')
self.f.write(self.time)
self.f.write('</dc:date>\n')
self.f.write('<meta:print-date>0-00-00T00:00:00</meta:print-date>\n')
self.f.write('<dc:language>en-US</dc:language>\n')
self.f.write('<meta:editing-cycles>1</meta:editing-cycles>\n')
self.f.write('<meta:editing-duration>PT0S</meta:editing-duration>\n')
self.f.write('<meta:user-defined meta:name="Info 0"/>\n')
self.f.write('<meta:user-defined meta:name="Info 1"/>\n')
self.f.write('<meta:user-defined meta:name="Info 2"/>\n')
self.f.write('<meta:user-defined meta:name="Info 3"/>\n')
self.f.write('</office:meta>\n')
self.f.write('</office:document-meta>\n')
self.f.close()
Plugins.register_text_doc(_("OpenOffice/StarOffice 6"),OpenOfficeDoc,1,1,1)

View File

@ -0,0 +1,457 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
import os
import tempfile
import string
from TextDoc import *
from SpreadSheetDoc import *
from latin_utf8 import latin_to_utf8
import const
class OpenSpreadSheet(SpreadSheetDoc):
def __init__(self,type,orientation):
SpreadSheetDoc.__init__(self,type,orientation)
self.f = None
self.filename = None
self.level = 0
self.time = "0000-00-00T00:00:00"
def open(self,filename):
import time
t = time.localtime(time.time())
self.time = "%04d-%02d-%02dT%02d:%02d:%02d" % \
(t[0],t[1],t[2],t[3],t[4],t[5])
if filename[-4:] != ".sxc":
self.filename = filename + ".sxc"
else:
self.filename = filename
tempfile.tempdir = "/tmp"
self.tempdir = tempfile.mktemp()
os.mkdir(self.tempdir,0700)
os.mkdir(self.tempdir + os.sep + "Pictures")
os.mkdir(self.tempdir + os.sep + "META-INF")
self.f = open(self.tempdir + os.sep + "content.xml","w")
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-content ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:style="http://openoffice.org/2000/style" ')
self.f.write('xmlns:text="http://openoffice.org/2000/text" ')
self.f.write('xmlns:table="http://openoffice.org/2000/table" ')
self.f.write('xmlns:draw="http://openoffice.org/2000/drawing" ')
self.f.write('xmlns:fo="http://www.w3.org/1999/XSL/Format" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:number="http://openoffice.org/2000/datastyle" ')
self.f.write('xmlns:svg="http://www.w3.org/2000/svg" ')
self.f.write('xmlns:chart="http://openoffice.org/2000/chart" ')
self.f.write('xmlns:dr3d="http://openoffice.org/2000/dr3d" ')
self.f.write('xmlns:math="http://www.w3.org/1998/Math/MathML" ')
self.f.write('xmlns:form="http://openoffice.org/2000/form" ')
self.f.write('xmlns:script="http://openoffice.org/2000/script" ')
self.f.write('office:class="spreadsheet" office:version="0.9">\n')
self.f.write('<office:script/>\n')
self.f.write('<office:font-decls>\n')
self.f.write('<style:font-decl style:name="Times New Roman" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('<style:font-decl style:name="Arial" ')
self.f.write('fo:font-family="Arial" ')
self.f.write('style:font-family-generic="swiss" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('</office:font-decls>\n')
self.f.write('<office:automatic-styles>\n')
for key in self.table_styles.keys():
table = self.table_styles[key]
self.f.write('<style:style style:name="')
self.f.write(key)
self.f.write('" style:family="table">\n')
self.f.write('<style:properties table:display="true" ')
self.f.write('table:page-style-name="Default"/>\n')
self.f.write('</style:style>\n')
for index in range(0,table.get_columns()):
self.f.write('<style:style style:name="')
self.f.write(key + '_' + str(index))
self.f.write('" style:family="table-column">\n')
self.f.write('<style:properties fo:break-before="auto" ')
self.f.write('style:column-width="%.3fcm"/>\n' % table.get_column_width(index))
self.f.write('</style:style>\n')
self.f.write('<style:style style:name="ro1" style:family="table-row">\n')
self.f.write('<style:properties fo:break-before="auto"/>\n')
self.f.write('</style:style>\n')
for key in self.style_list.keys():
style = self.style_list[key]
font = style.get_font()
self.f.write('<style:style style:name="')
self.f.write(key)
self.f.write('" style:family="table-cell" ')
self.f.write('style:parent-style-name="Default">\n')
self.f.write('<style:properties ')
self.f.write('fo:color="#%02x%02x%02x" ' % font.get_color())
bgcolor = style.get_background_color()
self.f.write('fo:background-color="#%02x%02x%02x" ' % bgcolor)
self.f.write('fo:padding-bottom="%.3fcm" ' % style.get_padding())
self.f.write('fo:padding-top="%.3fcm" ' % style.get_padding())
self.f.write('fo:padding-right="%.3fcm" ' % style.get_padding())
self.f.write('fo:padding-left="%.3fcm" ' % style.get_padding())
self.f.write('style:text-outline="false" ')
self.f.write('style:text-crossing-out="none" ')
if font.get_type_face() == FONT_SERIF:
self.f.write('style:font-name="Times New Roman" ')
else:
self.f.write('style:font-name="Arial" ')
self.f.write('fo:font-size="%dpt" ' % font.get_size())
if font.get_italic():
self.f.write('fo:font-style="italic" ')
else:
self.f.write('fo:font-style="normal" ')
self.f.write('fo:text-shadow="none" ')
self.f.write('style:text-underline="none" ')
if font.get_bold():
self.f.write('fo:font-weight="bold"/>\n')
else:
self.f.write('fo:font-weight="normal"/>\n')
self.f.write('</style:style>\n')
self.f.write('</office:automatic-styles>\n')
self.f.write('<office:body>\n')
self.f.write('<table:calculation-settings>\n')
self.f.write('<table:iteration table:maximum-difference="0.001"/>\n')
self.f.write('</table:calculation-settings>\n')
def close(self):
self.f.write('</office:body>\n')
self.f.write('</office:document-content>\n')
self.f.close()
self._write_styles_file()
self._write_manifest()
self._write_meta_file()
self._write_zip()
def start_row(self):
self.f.write('<table:table-row table:style-name="')
self.f.write('ro1')
self.f.write('">\n')
def end_row(self):
self.f.write('</table:table-row>\n')
def start_cell(self,style_name,span=1):
self.content = 0
self.span = span
self.f.write('<table:table-cell table:style-name="')
self.f.write(style_name)
self.f.write('" table:value-type="string"')
if span > 1:
self.f.write(' table:number-columns-spanned="' + str(span) + '">\n')
else:
self.f.write('>\n')
def end_cell(self):
if self.content == 0:
self.f.write('<text:p/>\n')
else:
self.f.write('</text:p>\n')
self.f.write('</table:table-cell>\n')
for col in range(1,self.span):
self.f.write('<table:covered-table-cell/>\n')
def _write_zip(self):
if os.path.isfile(self.filename):
os.unlink(self.filename)
os.system("cd " + self.tempdir + "; " + const.zipcmd + " " \
+ self.filename + " .")
os.unlink(self.tempdir + os.sep + "META-INF" + os.sep + "manifest.xml")
os.unlink(self.tempdir + os.sep + "content.xml")
os.unlink(self.tempdir + os.sep + "meta.xml")
os.unlink(self.tempdir + os.sep + "styles.xml")
# for image in self.image_list:
# os.unlink(self.tempdir + os.sep + "Pictures" + os.sep + image)
os.rmdir(self.tempdir + os.sep + "Pictures")
os.rmdir(self.tempdir + os.sep + "META-INF")
os.rmdir(self.tempdir)
def _write_styles_file(self):
file = self.tempdir + os.sep + "styles.xml"
self.f = open(file,"w")
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-styles ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:style="http://openoffice.org/2000/style" ')
self.f.write('xmlns:text="http://openoffice.org/2000/text" ')
self.f.write('xmlns:table="http://openoffice.org/2000/table" ')
self.f.write('xmlns:draw="http://openoffice.org/2000/drawing" ')
self.f.write('xmlns:fo="http://www.w3.org/1999/XSL/Format" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:number="http://openoffice.org/2000/datastyle" ')
self.f.write('xmlns:svg="http://www.w3.org/2000/svg" ')
self.f.write('xmlns:chart="http://openoffice.org/2000/chart" ')
self.f.write('xmlns:dr3d="http://openoffice.org/2000/dr3d" ')
self.f.write('xmlns:math="http://www.w3.org/1998/Math/MathML" ')
self.f.write('xmlns:form="http://openoffice.org/2000/form" ')
self.f.write('xmlns:script="http://openoffice.org/2000/script" ')
self.f.write('office:class="spreadsheet" office:version="0.9">\n')
self.f.write('<office:font-decls>\n')
self.f.write('<style:font-decl style:name="Times New Roman" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('<style:font-decl style:name="Arial" ')
self.f.write('fo:font-family="Arial" ')
self.f.write('style:font-family-generic="swiss" ')
self.f.write('style:font-pitch="variable"/>\n')
self.f.write('</office:font-decls>\n')
self.f.write('<office:styles>\n')
self.f.write('<style:default-style style:family="table-cell">\n')
self.f.write('<style:properties style:decimal-places="2" ')
self.f.write('style:font-name="Arial" ')
self.f.write('style:tab-stop-distance="0.2835inch"/>\n')
self.f.write('</style:default-style>\n')
self.f.write('<style:style style:name="Default" ')
self.f.write('style:family="table-cell" ')
self.f.write('style:data-style-name="N0"/>\n')
self.f.write('<style:default-style style:family="graphics">\n')
self.f.write('<style:properties fo:color="#000000" ')
self.f.write('fo:font-family="&apos;Times New Roman&apos;" ')
self.f.write('style:font-style-name="" ')
self.f.write('style:font-family-generic="roman" ')
self.f.write('style:font-pitch="variable" ')
self.f.write('fo:font-size="12pt" ')
self.f.write('fo:language="none" ')
self.f.write('fo:country="none" ')
self.f.write('style:text-autospace="ideograph-alpha" ')
self.f.write('style:punctuation-wrap="simple" ')
self.f.write('style:line-break="strict"/>\n')
self.f.write('</style:default-style>\n')
self.f.write('<style:style style:name="Standard" ')
self.f.write('style:family="paragraph" style:class="text"/>\n')
self.f.write('<office:automatic-styles>\n')
self.f.write('<style:page-master style:name="pm1">\n')
self.f.write('<style:header-style>\n')
self.f.write('<style:properties fo:min-height="0.2957inch" ')
self.f.write('fo:margin-left="0inch" ')
self.f.write('fo:margin-right="0inch" ')
self.f.write('fo:margin-bottom="0.0984inch"/>\n')
self.f.write('</style:header-style>\n')
self.f.write('<style:footer-style>\n')
self.f.write('<style:properties fo:min-height="0.2957inch" ')
self.f.write('fo:margin-left="0inch" ')
self.f.write('fo:margin-right="0inch" ')
self.f.write('fo:margin-top="0.0984inch"/>\n')
self.f.write('</style:footer-style>\n')
self.f.write('</style:page-master>\n')
self.f.write('<style:page-master style:name="pm2">\n')
self.f.write('<style:header-style>\n')
self.f.write('<style:properties fo:min-height="0.2957inch" ')
self.f.write('fo:margin-left="0inch" ')
self.f.write('fo:margin-right="0inch" ')
self.f.write('fo:margin-bottom="0.0984inch" ')
self.f.write('fo:border="0.0346inch solid #000000" ')
self.f.write('fo:border-top="0.0346inch solid #000000" ')
self.f.write('fo:border-bottom="0.0346inch solid #000000" ')
self.f.write('fo:border-left="0.0346inch solid #000000" ')
self.f.write('fo:border-right="0.0346inch solid #000000" ')
self.f.write('fo:padding="0.0071inch" ')
self.f.write('fo:padding-top="0.0071inch" ')
self.f.write('fo:padding-bottom="0.0071inch" ')
self.f.write('fo:padding-left="0.0071inch" ')
self.f.write('fo:padding-right="0.0071inch" ')
self.f.write('fo:background-color="#c0c0c0"/>\n')
self.f.write('</style:header-style>\n')
self.f.write('<style:footer-style>\n')
self.f.write('<style:properties fo:min-height="0.2957inch" ')
self.f.write('fo:margin-left="0inch" ')
self.f.write('fo:margin-right="0inch" ')
self.f.write('fo:margin-top="0.0984inch" ')
self.f.write('fo:border="0.0346inch solid #000000" ')
self.f.write('fo:border-top="0.0346inch solid #000000" ')
self.f.write('fo:border-bottom="0.0346inch solid #000000" ')
self.f.write('fo:border-left="0.0346inch solid #000000" ')
self.f.write('fo:border-right="0.0346inch solid #000000" ')
self.f.write('fo:padding="0.0071inch" ')
self.f.write('fo:padding-top="0.0071inch" ')
self.f.write('fo:padding-bottom="0.0071inch" ')
self.f.write('fo:padding-left="0.0071inch" ')
self.f.write('fo:padding-right="0.0071inch" ')
self.f.write('fo:background-color="#c0c0c0"/>\n')
self.f.write('</style:footer-style>\n')
self.f.write('</style:page-master>\n')
self.f.write('</office:automatic-styles>\n')
self.f.write('<office:master-styles>\n')
self.f.write('<style:master-page style:name="Default" ')
self.f.write('style:page-master-name="pm1" ')
self.f.write('style:next-style-name="">\n')
self.f.write('<style:header>\n')
self.f.write('<text:p><text:sheet-name>???</text:sheet-name></text:p>\n')
self.f.write('</style:header>\n')
self.f.write('<style:footer>\n')
self.f.write('<text:p>Page <text:page-number>1</text:page-number></text:p>\n')
self.f.write('</style:footer>\n')
self.f.write('</style:master-page>\n')
self.f.write('<style:master-page style:name="Report" ')
self.f.write('style:page-master-name="pm2" ')
self.f.write('style:next-style-name="">\n')
self.f.write('<style:header>\n')
self.f.write('<style:region-left>\n')
self.f.write('<text:p><text:sheet-name>???</text:sheet-name> ')
self.f.write('(<text:file-name>???</text:file-name>)</text:p>\n')
self.f.write('</style:region-left>\n')
self.f.write('<style:region-right>\n')
self.f.write('<text:p><text:date style:data-style-name="N2" ')
self.f.write('text:date-value="2001-05-16">05/16/2001</text:date>, ')
self.f.write('<text:time>10:53:17</text:time></text:p>\n')
self.f.write('</style:region-right>\n')
self.f.write('</style:header>\n')
self.f.write('<style:footer>\n')
self.f.write('<text:p>Page <text:page-number>1</text:page-number> / ')
self.f.write('<text:page-count>99</text:page-count></text:p>\n')
self.f.write('</style:footer>\n')
self.f.write('</style:master-page>\n')
self.f.write('</office:master-styles>\n')
self.f.write('</office:styles>\n')
self.f.write('</office:document-styles>\n')
self.f.close()
def start_page(self,name,style_name):
table = self.table_styles[style_name]
self.f.write('<table:table table:name="')
self.f.write(name)
self.f.write('" table:style-name="')
self.f.write(style_name)
self.f.write('">\n')
for col in range(0,table.get_columns()):
self.f.write('<table:table-column table:style-name="')
self.f.write(style_name + '_' + str(col) +'"/>\n')
def end_page(self):
self.f.write('</table:table>\n')
def write_text(self,text):
if text == "":
return
if self.content == 0:
self.f.write('<text:p>')
self.content = 1
text = string.replace(text,'\t','<text:tab-stop/>')
text = string.replace(text,'\n','<text:line-break/>')
self.f.write(latin_to_utf8(text))
def _write_manifest(self):
file = self.tempdir + os.sep + "META-INF" + os.sep + "manifest.xml"
self.f = open(file,"w")
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<manifest:manifest ')
self.f.write('xmlns:manifest="http://openoffice.org/2001/manifest">')
self.f.write('<manifest:file-entry ')
self.f.write('manifest:media-type="application/vnd.sun.xml.writer" ')
self.f.write('manifest:full-path="/"/>')
self.f.write('<manifest:file-entry manifest:media-type="" ')
self.f.write('manifest:full-path="Pictures/"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="content.xml"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="styles.xml"/>')
self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
self.f.write('manifest:full-path="meta.xml"/>')
#self.f.write('<manifest:file-entry manifest:media-type="text/xml" ')
#self.f.write('manifest:full-path="settings.xml"/>')
self.f.write('</manifest:manifest>\n')
self.f.close()
def _write_meta_file(self):
file = self.tempdir + os.sep + "meta.xml"
name = latin_to_utf8(self.name)
self.f = open(file,"w")
self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<office:document-meta ')
self.f.write('xmlns:office="http://openoffice.org/2000/office" ')
self.f.write('xmlns:xlink="http://www.w3.org/1999/xlink" ')
self.f.write('xmlns:dc="http://purl.org/dc/elements/1.1/" ')
self.f.write('xmlns:meta="http://openoffice.org/2000/meta" ')
self.f.write('office:class="text" office:version="0.9">\n');
self.f.write('<office:meta>\n')
self.f.write('<meta:generator>')
self.f.write(const.progName + ' ' + const.version)
self.f.write('</meta:generator>\n')
self.f.write('<meta:initial-creator>')
self.f.write(name)
self.f.write('</meta:initial-creator>\n')
self.f.write('<meta:creation-date>')
self.f.write(self.time)
self.f.write('</meta:creation-date>\n')
self.f.write('<dc:creator>')
self.f.write(name)
self.f.write('</dc:creator>\n')
self.f.write('<dc:date>')
self.f.write(self.time)
self.f.write('</dc:date>\n')
self.f.write('<meta:print-date>0-00-00T00:00:00</meta:print-date>\n')
self.f.write('<dc:language>en-US</dc:language>\n')
self.f.write('<meta:editing-cycles>1</meta:editing-cycles>\n')
self.f.write('<meta:editing-duration>PT0S</meta:editing-duration>\n')
self.f.write('<meta:user-defined meta:name="Info 0"/>\n')
self.f.write('<meta:user-defined meta:name="Info 1"/>\n')
self.f.write('<meta:user-defined meta:name="Info 2"/>\n')
self.f.write('<meta:user-defined meta:name="Info 3"/>\n')
self.f.write('</office:meta>\n')
self.f.write('</office:document-meta>\n')
self.f.close()
if __name__ == "__main__":
doc = OpenSpreadSheet(PaperStyle("junk",21.59,27),PAPER_PORTRAIT)
t = TableStyle()
t.set_columns(3)
t.set_column_width(0,4)
t.set_column_width(1,2)
t.set_column_width(2,1)
doc.add_table_style("mytblstyle",t)
f = FontStyle()
f.set_type_face(FONT_SANS_SERIF)
f.set_size(16)
f.set_bold(1)
p = ParagraphStyle()
p.set_font(f)
p.set_background_color((0xcc,0xff,0xff))
p.set_padding(0.5)
doc.add_style("p1",p)
doc.open("/home/dona/test")
doc.start_page("Page 1","mytblstyle")
doc.start_row()
doc.start_cell("p1")
doc.write_text("Hello")
doc.end_cell()
doc.end_row()
doc.end_page()
doc.close()

168
src/docgen/PSDrawDoc.py Normal file
View File

@ -0,0 +1,168 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
import os
import tempfile
import string
import Plugins
import intl
_ = intl.gettext
from TextDoc import *
from DrawDoc import *
class PSDrawDoc(DrawDoc):
def __init__(self,styles,type,orientation):
DrawDoc.__init__(self,styles,type,orientation)
self.f = None
self.filename = None
self.level = 0
self.time = "0000-00-00T00:00:00"
self.page = 0
def translate(self,x,y):
return (x,self.height-y)
def fontdef(self,para):
font = para.get_font()
if font.get_type_face() == FONT_SERIF:
if font.get_bold():
if font.get_italic():
font_name = "/Times-BoldItalic"
else:
font_name = "/Times-Bold"
else:
if font.get_italic():
font_name = "/Times-Italic"
else:
font_name = "/Times-Roman"
else:
if font.get_bold():
if font.get_italic():
font_name = "/Helvetica-BoldOblique"
else:
font_name = "/Helvetica-Bold"
else:
if font.get_italic():
font_name = "/Helvetica-Oblique"
else:
font_name = "/Helvetica"
return "%s findfont %d scalefont setfont\n" % (font_name,font.get_size())
def open(self,filename):
if filename[-4:] != ".ps":
self.filename = filename + ".ps"
else:
self.filename = filename
self.f = open(filename,"w")
self.f.write('%!PS-Adobe-3.0\n')
self.f.write('%%LanguageLevel: 2\n')
self.f.write('%%Pages: (atend)\n')
self.f.write('%%PageOrder: Ascend\n')
self.f.write('%%EndComments\n')
self.f.write('/cm { 28.34 mul } def\n')
def close(self):
self.f.write('%%Trailer\n')
self.f.write('%%Pages: ')
self.f.write('%d\n' % self.page)
self.f.write('%%EOF\n')
self.f.close()
def start_paragraph(self,style_name):
pass
def end_paragraph(self):
pass
def write_text(self,text):
pass
def start_page(self,orientation=None):
self.page = self.page + 1
self.f.write("%%Page:")
self.f.write("%d %d\n" % (self.page,self.page))
def end_page(self):
self.f.write('showpage\n')
self.f.write('%%PageTrailer\n')
def draw_line(self,style,x1,y1,x2,y2):
self.f.write('gsave\n')
self.f.write('newpath\n')
self.f.write('%f cm %f cm moveto\n' % self.translate(x1,y1))
self.f.write('%f cm %f cm lineto\n' % self.translate(x2,y2))
self.f.write('1 setlinewidth\n')
self.f.write('2 setlinecap\n')
self.f.write('stroke\n')
self.f.write('grestore\n')
def draw_box(self,style,text,x,y):
box_style = self.draw_styles[style]
para_name = box_style.get_paragraph_style()
p = self.style_list[para_name]
bh = box_style.get_height()
bw = box_style.get_width()
self.f.write('gsave\n')
self.f.write('newpath\n')
self.f.write('%f cm %f cm moveto\n' % self.translate(x+0.15,y+0.15))
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('.5 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('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('0 setgray\n')
self.f.write('1 setlinewidth\n')
self.f.write('stroke\n')
if text != "":
self.f.write(self.fontdef(p))
lines = string.split(text,'\n')
nlines = len(lines)
mar = 10/28.35
f_in_cm = p.get_font().get_size()/28.35
fs = f_in_cm * 1.2
center = y + (bh + fs)/2.0 + (fs*0.2)
ystart = center - (fs/2.0) * nlines
for i in range(nlines):
ypos = ystart + (i * fs)
self.f.write('%f cm %f cm moveto\n' % self.translate(x+mar,ypos))
self.f.write("(%s) show\n" % lines[i])
self.f.write('grestore\n')
Plugins.register_draw_doc(_("PostScript"),PSDrawDoc);

284
src/docgen/PdfDoc.py Normal file
View File

@ -0,0 +1,284 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
from TextDoc import *
import Plugins
import intl
_ = intl.gettext
import reportlab.platypus.tables
from reportlab.platypus import *
from reportlab.lib.units import cm
from reportlab.lib.colors import Color
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
import reportlab.lib.styles
from latin_utf8 import latin_to_utf8
try:
import PIL.Image
no_pil = 0
except:
no_pil = 1
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class GrampsDocTemplate(BaseDocTemplate):
def build(self,flowables):
self._calc() #in case we changed margins sizes etc
BaseDocTemplate.build(self,flowables)
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
def make_color(color):
return Color(float(color[0])/255.0, float(color[1])/255.0,
float(color[2])/255.0)
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class PdfDoc(TextDoc):
def open(self,filename):
if filename[-4:] != ".pdf":
self.filename = filename + ".pdf"
else:
self.filename = filename
self.pagesize = (self.width*cm,self.height*cm)
self.doc = GrampsDocTemplate(self.filename,
pagesize=self.pagesize,
allowSplitting=1,
_pageBreakQuick=0,
leftMargin=self.lmargin*cm,
rightMargin=self.rmargin*cm,
topMargin=self.tmargin*cm,
bottomMargin=self.bmargin*cm)
frameT = Frame(0,0,self.width*cm,self.height*cm,
self.lmargin*cm, self.bmargin*cm, \
self.rmargin*cm,self.tmargin*cm,\
id='normal')
ptemp = PageTemplate(frames=frameT,pagesize=self.pagesize)
self.doc.addPageTemplates([ptemp])
self.pdfstyles = {}
for style_name in self.style_list.keys():
style = self.style_list[style_name]
font = style.get_font()
pdf_style = reportlab.lib.styles.ParagraphStyle(name=style_name)
pdf_style.fontSize = font.get_size()
pdf_style.bulletFontSize = font.get_size()
if font.get_type_face() == FONT_SERIF:
if font.get_bold():
if font.get_italic():
pdf_style.fontName = "Times-BoldItalic"
else:
pdf_style.fontName = "Times-Bold"
else:
if font.get_italic():
pdf_style.fontName = "Times-Italic"
else:
pdf_style.fontName = "Times-Roman"
else:
if font.get_bold():
if font.get_italic():
pdf_style.fontName = "Helvetica-BoldOblique"
else:
pdf_style.fontName = "Helvetica-Bold"
else:
if font.get_italic():
pdf_style.fontName = "Helvetica-Oblique"
else:
pdf_style.fontName = "Helvetica"
pdf_style.bulletFontName = pdf_style.fontName
right = style.get_right_margin()*cm
left = style.get_left_margin()*cm
first = left + style.get_first_indent()*cm
pdf_style.rightIndent = right
pdf_style.leftIndent = left
pdf_style.firstLineIndent = first
pdf_style.bulletIndent = first
align = style.get_alignment()
if align == PARA_ALIGN_RIGHT:
pdf_style.alignment = TA_RIGHT
elif align == PARA_ALIGN_LEFT:
pdf_style.alignment = TA_LEFT
elif align == PARA_ALIGN_CENTER:
pdf_style.alignment = TA_CENTER
else:
pdf_style.alignment = TA_JUSTIFY
pdf_style.spaceBefore = style.get_padding()
pdf_style.spaceAfter = style.get_padding()
pdf_style.textColor = make_color(font.get_color())
self.pdfstyles[style_name] = pdf_style
self.story = []
self.in_table = 0
def close(self):
self.doc.build(self.story)
def end_page(self):
self.story.append(PageBreak())
def start_paragraph(self,style_name,leader=None):
self.current_para = self.pdfstyles[style_name]
self.my_para = self.style_list[style_name]
if leader==None:
self.text = ''
else:
self.text = '<bullet>%s</bullet>' % leader
self.image = 0
def end_paragraph(self):
if self.in_table == 0 and self.image == 0:
self.story.append(Paragraph(self.text,self.current_para))
self.story.append(Spacer(1,0.5*cm))
else:
self.image = 0
def start_bold(self):
self.text = self.text + '<b>'
def end_bold(self):
self.text = self.text + '</b>'
def start_table(self,name,style_name):
self.in_table = 1
self.cur_table = self.table_styles[style_name]
self.row = -1
self.col = 0
self.cur_row = []
self.table_data = []
self.tblstyle = []
self.cur_table_cols = []
width = float(self.cur_table.get_width()/100.0) * self.get_usable_width()
for val in range(self.cur_table.get_columns()):
percent = float(self.cur_table.get_column_width(val))/100.0
self.cur_table_cols.append(int(width * percent * cm))
def end_table(self):
ts = reportlab.platypus.tables.TableStyle(self.tblstyle)
tbl = reportlab.platypus.tables.Table(data=self.table_data,
colWidths=self.cur_table_cols,
style=ts)
self.story.append(tbl)
self.in_table = 0
def start_row(self):
self.row = self.row + 1
self.col = 0
self.cur_row = []
def end_row(self):
self.table_data.append(self.cur_row)
def start_cell(self,style_name,span=1):
self.span = span
self.my_table_style = self.cell_styles[style_name]
pass
def end_cell(self):
if self.span == 1:
# self.cur_row.append(self.text)
self.cur_row.append(Paragraph(self.text,self.current_para))
else:
self.cur_row.append(self.text)
for val in range(1,self.span):
self.cur_row.append("")
p = self.my_para
f = p.get_font()
if f.get_type_face() == FONT_SANS_SERIF:
if f.get_bold():
fn = 'Helvetica-Bold'
else:
fn = 'Helvetica'
else:
if f.get_bold():
fn = 'Times-Bold'
else:
fn = 'Times-Roman'
black = Color(0,0,0)
for inc in range(self.col,self.col+self.span):
loc = (inc,self.row)
self.tblstyle.append(('FONT', loc, loc, fn, f.get_size()))
if self.span == 1 or inc == self.col + self.span - 1:
if self.my_table_style.get_right_border():
self.tblstyle.append('LINEAFTER', loc, loc, 1, black)
if self.span == 1 or inc == self.col:
if self.my_table_style.get_left_border():
self.tblstyle.append('LINEBEFORE', loc, loc, 1, black)
if self.my_table_style.get_top_border():
self.tblstyle.append('LINEABOVE', loc, loc, 1, black)
if self.my_table_style.get_bottom_border():
self.tblstyle.append('LINEBELOW', loc, loc, 1, black)
if p.get_alignment() == PARA_ALIGN_LEFT:
self.tblstyle.append('ALIGN', loc, loc, 'LEFT')
elif p.get_alignment() == PARA_ALIGN_RIGHT:
self.tblstyle.append('ALIGN', loc, loc, 'RIGHT')
else:
self.tblstyle.append('ALIGN', loc, loc, 'CENTER')
self.tblstyle.append('VALIGN', loc, loc, 'TOP')
self.col = self.col + self.span
def add_photo(self,name,pos,x,y):
if no_pil == 0:
im = PIL.Image.open(name)
nx,ny = im.size
scale = float(nx)/float(ny)
if scale > 1.0:
scale = 1.0/scale
act_width = x
act_height = y * scale
else:
act_width = x * scale
act_height = y
self.story.append(Image(name,act_width*cm,act_height*cm))
self.story.append(Spacer(1,0.5*cm))
self.image = 1
def write_text(self,text):
self.text = self.text + text
Plugins.register_text_doc(_("PDF"),PdfDoc,1,1,1)

185
src/docgen/PdfDrawDoc.py Normal file
View File

@ -0,0 +1,185 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
import os
import string
from TextDoc import *
from DrawDoc import *
import Plugins
import intl
_ = intl.gettext
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.lib.colors import Color
def make_color(color):
return Color(float(color[0])/255.0, float(color[1])/255.0,
float(color[2])/255.0)
class PdfDrawDoc(DrawDoc):
def __init__(self,styles,type,orientation):
DrawDoc.__init__(self,styles,type,orientation)
self.f = None
self.filename = None
self.level = 0
self.time = "0000-00-00T00:00:00"
self.page = 0
def open(self,filename):
if filename[-4:] != ".pdf":
self.filename = filename + ".pdf"
else:
self.filename = filename
self.f = canvas.Canvas(self.filename,(self.width*cm,self.height*cm),0)
if self.name:
self.f.setAuthor(self.name)
def close(self):
self.f.save()
def start_paragraph(self,style_name):
pass
def end_paragraph(self):
pass
def write_text(self,text):
pass
def start_page(self,orientation=None):
pass
def end_page(self):
self.f.showPage()
def draw_line(self,style,x1,y1,x2,y2):
self.f.line(x1*cm,y1*cm,x2*cm,y2*cm)
def draw_box(self,style,text,x,y):
box_style = self.draw_styles[style]
para_name = box_style.get_paragraph_style()
p = self.style_list[para_name]
w = box_style.get_width()*cm
h = box_style.get_height()*cm
if box_style.get_shadow():
self.f.setFillColorRGB(0.5,0.5,0.5)
self.f.rect((x+0.3)*cm,(y+0.3)*cm,w,h,fill=1,stroke=0)
font = p.get_font()
self.f.setStrokeColor(make_color(font.get_color()))
self.f.setFillColor(make_color(box_style.get_color()))
self.f.rect(x*cm,y*cm,w,h,fill=1)
if text != "":
lines = string.split(text,'\n')
self.center_print(lines,font,x*cm,y*cm,w,h)
def write_at(self,style,text,x,y):
p = self.style_list[style]
font = p.get_font()
self.f.setStrokeColor(make_color(font.get_color()))
self.left_print(text,font,x*cm,y*cm)
def center_print(self,lines,font,x,y,w,h):
l = len(lines)
size = font.get_size()
start_y = (y + h/2.0 + l/2.0 + l) - ((l*size) + ((l-1)*0.2))/2.0
start_x = (x + w/2.0)
self.f.saveState()
self.f.setFillColor(make_color(font.get_color()))
if font.get_type_face() == FONT_SANS_SERIF:
if font.get_bold():
self.f.setFont("Helvetica-Bold",font.get_size())
else:
self.f.setFont("Helvetica",font.get_size())
else:
if font.get_bold():
self.f.setFont("Times-Bold",font.get_size())
else:
self.f.setFont("Times-Roman",font.get_size())
for text in lines:
self.f.drawCentredString(start_x,start_y,text)
start_y = start_y + size*1.2
start_y = start_y + size*1.2
self.f.restoreState()
def left_print(self,text,font,x,y):
size = font.get_size()
start_y = y
start_x = x
self.f.saveState()
self.f.setFillColor(make_color(font.get_color()))
if font.get_type_face() == FONT_SANS_SERIF:
if font.get_bold():
self.f.setFont("Helvetica-Bold",font.get_size())
else:
self.f.setFont("Helvetica",font.get_size())
else:
if font.get_bold():
self.f.setFont("Times-Bold",font.get_size())
else:
self.f.setFont("Times-Roman",font.get_size())
self.f.drawString(start_x,start_y,text)
self.f.restoreState()
if __name__ == "__main__":
s = PaperStyle("Junk",27.94,21.59)
x = PdfDrawDoc(s,PAPER_PORTRAIT)
f = FontStyle()
f.set_type_face(FONT_SANS_SERIF)
f.set_size(14)
p = ParagraphStyle()
p.set_font(f)
x.add_paragraph_style("mytest",p)
g = GraphicsStyle()
g.set_width(4)
g.set_height(2)
g.set_color((0xff,0xcc,0xff))
g.set_paragraph_style("mytest")
g.set_shadow(1)
x.add_draw_style("mybox",g)
x.open("test")
x.start_page()
x.draw_box("mybox","Hello\nThis is Fun",4,4)
x.end_page()
x.close()
Plugins.register_draw_doc(_("PDF"),PdfDrawDoc);

525
src/docgen/RTFDoc.py Normal file
View File

@ -0,0 +1,525 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
#------------------------------------------------------------------------
#
# Load the base TextDoc class
#
#------------------------------------------------------------------------
from TextDoc import *
import Plugins
import intl
_ = intl.gettext
#------------------------------------------------------------------------
#
# Attempt to load the Python Imaging Library for the handling of photos.
#
#------------------------------------------------------------------------
try:
import PIL.Image
no_pil = 0
except:
no_pil = 1
#------------------------------------------------------------------------
#
# RTF uses a unit called "twips" for its measurements. According to the
# RTF specification, 1 point is 20 twips. This routines converts
# centimeters to twips
#
# 2.54 cm/inch 72pts/inch, 20twips/pt
#
#------------------------------------------------------------------------
def twips(cm):
return int(((cm/2.54)*72)+0.5)*20
#------------------------------------------------------------------------
#
# Rich Text Format Document interface. The current inteface does not
# use style sheets. Instead it writes raw formatting.
#
#------------------------------------------------------------------------
class RTFDoc(TextDoc):
#--------------------------------------------------------------------
#
# Opens the file, and writes the header. Builds the color and font
# tables. Fonts are chosen using the MS TrueType fonts, since it
# is assumed that if you are generating RTF, you are probably
# targeting Word. This generator assumes a Western Europe character
# set.
#
#--------------------------------------------------------------------
def open(self,filename):
if filename[-4:] != ".rtf":
self.filename = filename + ".rtf"
else:
self.filename = filename
self.f = open(self.filename,"w")
self.f.write('{\\rtf1\\ansi\\ansicpg1252\\deff0\n')
self.f.write('{\\fonttbl\n')
self.f.write('{\\f0\\froman\\fcharset0\\fprq0 Times New Roman;}\n')
self.f.write('{\\f1\\fswiss\\fcharset0\\fprq0 Arial;}}\n')
self.f.write('{\colortbl\n')
self.color_map = {}
index = 1
self.color_map[(0,0,0)] = 0
self.f.write('\\red0\\green0\\blue0;')
for style_name in self.style_list.keys():
style = self.style_list[style_name]
fgcolor = style.get_font().get_color()
bgcolor = style.get_background_color()
if not self.color_map.has_key(fgcolor):
self.color_map[fgcolor] = index
self.f.write('\\red%d\\green%d\\blue%d;' % fgcolor)
index = index + 1
if not self.color_map.has_key(bgcolor):
self.f.write('\\red%d\\green%d\\blue%d;' % bgcolor)
self.color_map[bgcolor] = index
index = index + 1
self.f.write('}\n')
self.f.write('\\kerning0\\cf0\\viewkind1')
self.f.write('\\paperw%d' % twips(self.width))
self.f.write('\\paperh%d' % twips(self.height))
self.f.write('\\margl%d' % twips(self.lmargin))
self.f.write('\\margr%d' % twips(self.rmargin))
self.f.write('\\margt%d' % twips(self.tmargin))
self.f.write('\\margb%d' % twips(self.bmargin))
self.f.write('\\widowctl\n')
self.in_table = 0
self.text = ""
#--------------------------------------------------------------------
#
# Write the closing brace, and close the file.
#
#--------------------------------------------------------------------
def close(self):
self.f.write('}\n')
self.f.close()
#--------------------------------------------------------------------
#
# Force a section page break
#
#--------------------------------------------------------------------
def end_page(self):
self.f.write('\\sbkpage\n')
#--------------------------------------------------------------------
#
# Starts a paragraph. Instead of using a style sheet, generate the
# the style for each paragraph on the fly. Not the ideal, but it
# does work.
#
#--------------------------------------------------------------------
def start_paragraph(self,style_name,leader=None):
self.opened = 0
p = self.style_list[style_name]
# build font information
f = p.get_font()
size = f.get_size()*2
bgindex = self.color_map[p.get_background_color()]
fgindex = self.color_map[f.get_color()]
if f.get_type_face() == FONT_SERIF:
self.font_type = '\\f0\\fs%d\\cf%d\\cb%d' % (size,fgindex,bgindex)
else:
self.font_type = '\\f1\\fs%d\\cf%d\\cb%d' % (size,fgindex,bgindex)
if f.get_bold():
self.font_type = self.font_type + "\\b"
if f.get_underline():
self.font_type = self.font_type + "\\ul"
if f.get_italic():
self.font_type = self.font_type + "\\i"
# build paragraph information
if not self.in_table:
self.f.write('\\pard')
if p.get_alignment() == PARA_ALIGN_RIGHT:
self.f.write('\\qr')
elif p.get_alignment() == PARA_ALIGN_CENTER:
self.f.write('\\qc')
self.f.write('\\ri%d' % twips(p.get_right_margin()))
self.f.write('\\li%d' % twips(p.get_left_margin()))
self.f.write('\\fi%d' % twips(p.get_first_indent()))
if p.get_alignment() == PARA_ALIGN_JUSTIFY:
self.f.write('\\qj')
if p.get_padding():
self.f.write('\\sa%d' % twips(p.get_padding()/2.0))
if p.get_top_border():
self.f.write('\\brdrt\\brdrs')
if p.get_bottom_border():
self.f.write('\\brdrb\\brdrs')
if p.get_left_border():
self.f.write('\\brdrl\\brdrs')
if p.get_right_border():
self.f.write('\\brdrr\\brdrs')
if p.get_first_indent():
self.f.write('\\fi%d' % twips(p.get_first_indent()))
if p.get_left_margin():
self.f.write('\\li%d' % twips(p.get_left_margin()))
if p.get_right_margin():
self.f.write('\\ri%d' % twips(p.get_right_margin()))
if leader:
self.opened = 1
self.f.write('\\tx%d' % twips(p.get_left_margin()))
self.f.write('{%s ' % self.font_type)
self.write_text(leader)
self.f.write('\\tab}')
self.opened = 0
#--------------------------------------------------------------------
#
# Ends a paragraph. Care has to be taken to make sure that the
# braces are closed properly. The self.opened flag is used to indicate
# if braces are currently open. If the last write was the end of
# a bold-faced phrase, braces may already be closed.
#
#--------------------------------------------------------------------
def end_paragraph(self):
if not self.in_table:
self.f.write(self.text)
if self.opened:
self.f.write('}')
self.text = ""
self.opened = 0
self.f.write('\n\\par')
else:
if self.text == "":
self.write_text(" ")
self.text = self.text + '}'
#--------------------------------------------------------------------
#
# Starts boldfaced text, enclosed the braces
#
#--------------------------------------------------------------------
def start_bold(self):
if self.opened:
self.f.write('}')
self.f.write('{%s\\b ' % self.font_type)
self.opened = 1
#--------------------------------------------------------------------
#
# Ends boldfaced text, closing the braces
#
#--------------------------------------------------------------------
def end_bold(self):
self.opened = 0
self.f.write('}')
#--------------------------------------------------------------------
#
# Start a table. Grab the table style, and store it. Keep a flag to
# indicate that we are in a table. This helps us deal with paragraphs
# internal to a table. RTF does not require anything to start a
# table, since a table is treated as a bunch of rows.
#
#--------------------------------------------------------------------
def start_table(self,name,style_name):
self.in_table = 1
self.tbl_style = self.table_styles[style_name]
#--------------------------------------------------------------------
#
# End a table. Turn off the table flag
#
#--------------------------------------------------------------------
def end_table(self):
self.in_table = 0
#--------------------------------------------------------------------
#
# Start a row. RTF uses the \trowd to start a row. RTF also specifies
# all the cell data after it has specified the cell definitions for
# the row. Therefore it is necessary to keep a list of cell contents
# that is to be written after all the cells are defined.
#
#--------------------------------------------------------------------
def start_row(self):
self.contents = []
self.cell = 0
self.prev = 0
self.cell_percent = 0.0
self.f.write('\\trowd\n')
#--------------------------------------------------------------------
#
# End a row. Write the cell contents, separated by the \cell marker,
# then terminate the row
#
#--------------------------------------------------------------------
def end_row(self):
self.f.write('{')
for line in self.contents:
self.f.write(line)
self.f.write('\\cell ')
self.f.write('}\\pard\\intbl\\row\n')
#--------------------------------------------------------------------
#
# Start a cell. Dump out the cell specifics, such as borders. Cell
# widths are kind of interesting. RTF doesn't specify how wide a cell
# is, but rather where it's right edge is in relationship to the
# left margin. This means that each cell is the cumlative of the
# previous cells plus its own width.
#
#--------------------------------------------------------------------
def start_cell(self,style_name,span=1):
s = self.cell_styles[style_name]
self.remain = span -1
if s.get_top_border():
self.f.write('\\clbrdrt\\brdrs\\brdrw10\n')
if s.get_bottom_border():
self.f.write('\\clbrdrb\\brdrs\\brdrw10\n')
if s.get_left_border():
self.f.write('\\clbrdrl\\brdrs\\brdrw10\n')
if s.get_right_border():
self.f.write('\\clbrdrr\\brdrs\\brdrw10\n')
table_width = float(self.get_usable_width())
for cell in range(self.cell,self.cell+span):
self.cell_percent = self.cell_percent + float(self.tbl_style.get_column_width(cell))
cell_width = twips((table_width * self.cell_percent)/100.0)
self.f.write('\\cellx%d\\pard\intbl\n' % cell_width)
self.cell = self.cell+1
#--------------------------------------------------------------------
#
# End a cell. Save the current text in the content lists, since data
# must be saved until all cells are defined.
#
#--------------------------------------------------------------------
def end_cell(self):
self.contents.append(self.text)
self.text = ""
#--------------------------------------------------------------------
#
# Add a photo. Embed the photo in the document. Use the Python
# imaging library to load and scale the photo. The image is converted
# to JPEG, since it is smaller, and supported by RTF. The data is
# dumped as a string of HEX numbers.
#
# If the PIL library is not loaded, ignore the request to load the
# photo.
#
#--------------------------------------------------------------------
def add_photo(self,name,pos,x_cm,y_cm):
if no_pil:
return
im = PIL.Image.open(name)
nx,ny = im.size
buf = im.tostring("jpeg","RGB")
scale = float(ny)/float(nx)
if scale > 1:
scale = 1.0/scale
act_width = twips(x_cm * scale)
act_height = twips(y_cm * scale)
im.thumbnail((int(act_width*40),int(act_height*40)))
self.f.write('{\*\shppict{\\pict\\jpegblip')
self.f.write('\\picwgoal%d\\pichgoal%d\n' % (act_width,act_height))
index = 1
for i in buf:
self.f.write('%02x' % ord(i))
if index%32==0:
self.f.write('\n')
index = index+1
self.f.write('}}\\par\n')
#--------------------------------------------------------------------
#
# Writes text. If braces are not currently open, open them. Loop
# character by character (terribly inefficient, but it works). If a
# character is 8 bit (>127), convert it to a hex representation in
# the form of \`XX. Make sure to escape braces.
#
#--------------------------------------------------------------------
def write_text(self,text):
if self.opened == 0:
self.opened = 1
self.text = self.text + '{%s ' % self.font_type
for i in text:
if ord(i) > 127:
self.text = self.text + '\\\'%2x' % ord(i)
elif i == '{' or i == '}' :
self.text = self.text + '\\%s' % i
else:
self.text = self.text + i
if __name__ == "__main__":
paper = PaperStyle("Letter",27.94,21.59)
styles = StyleSheet()
foo = FontStyle()
foo.set_type_face(FONT_SANS_SERIF)
foo.set_color((255,0,0))
foo.set_size(24)
foo.set_underline(1)
foo.set_bold(1)
foo.set_italic(1)
para = ParagraphStyle()
para.set_alignment(PARA_ALIGN_RIGHT)
para.set_font(foo)
styles.add_style("Title",para)
foo = FontStyle()
foo.set_type_face(FONT_SERIF)
foo.set_size(12)
para = ParagraphStyle()
para.set_font(foo)
styles.add_style("Normal",para)
foo = FontStyle()
foo.set_type_face(FONT_SERIF)
foo.set_size(12)
para = ParagraphStyle()
para.set_font(foo)
para.set_top_border(1)
para.set_left_border(1)
para.set_right_border(1)
para.set_bottom_border(1)
styles.add_style("Box",para)
doc = RTFDoc(styles,paper,PAPER_PORTRAIT)
cell = TableCellStyle()
cell.set_padding(0.2)
cell.set_top_border(1)
cell.set_bottom_border(1)
cell.set_right_border(1)
cell.set_left_border(1)
doc.add_cell_style('ParentHead',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(1)
cell.set_left_border(1)
doc.add_cell_style('TextContents',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(0)
cell.set_left_border(1)
cell.set_padding(0.1)
doc.add_cell_style('TextChild1',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(1)
cell.set_left_border(1)
cell.set_padding(0.1)
doc.add_cell_style('TextChild2',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(1)
cell.set_right_border(1)
cell.set_left_border(1)
doc.add_cell_style('TextContentsEnd',cell)
cell = TableCellStyle()
cell.set_padding(0.2)
cell.set_bottom_border(1)
cell.set_right_border(1)
cell.set_left_border(1)
doc.add_cell_style('ChildName',cell)
table = TableStyle()
table.set_width(100)
table.set_columns(3)
table.set_column_width(0,20)
table.set_column_width(1,40)
table.set_column_width(2,40)
doc.add_table_style('ParentTable',table)
table = TableStyle()
table.set_width(100)
table.set_columns(4)
table.set_column_width(0,5)
table.set_column_width(1,15)
table.set_column_width(2,40)
table.set_column_width(3,40)
doc.add_table_style('ChildTable',table)
doc.open("test")
doc.start_paragraph("Title")
doc.write_text("My Title")
doc.end_paragraph()
doc.start_paragraph("Normal")
doc.write_text("Hello there. This is fun")
doc.end_paragraph()
doc.start_paragraph("Box")
doc.write_text("This is my box")
doc.end_paragraph()
doc.start_paragraph("Normal")
doc.add_photo("foo.png",200,200)
doc.end_paragraph()
doc.start_table(id,'ParentTable')
doc.start_row()
doc.start_cell('ParentHead',3)
doc.start_paragraph('Normal')
doc.write_text('Banana : Smith ')
doc.end_paragraph()
doc.end_cell()
doc.end_row()
doc.start_row()
doc.start_cell("TextContents")
doc.start_paragraph('Normal')
doc.write_text("some event")
doc.end_paragraph()
doc.end_cell()
doc.start_cell("TextContents")
doc.start_paragraph('Normal')
doc.write_text("someday")
doc.end_paragraph()
doc.end_cell()
doc.start_cell("TextContentsEnd")
doc.start_paragraph('Normal')
doc.write_text("somewhere")
doc.end_paragraph()
doc.end_cell()
doc.end_row()
doc.end_table()
doc.close()
Plugins.register_text_doc(_("Rich Text Format (RTF)"),RTFDoc,1,1,1)

View File

@ -2009,6 +2009,8 @@ def main(arg):
database = RelDataBase()
Plugins.load_plugins(const.docgenDir)
Plugins.load_plugins(os.path.expanduser("~/.gramps/docgen"))
Plugins.load_plugins(const.pluginsDir)
Plugins.load_plugins(os.path.expanduser("~/.gramps/plugins"))
Filter.load_filters(const.filtersDir)

View File

@ -146,7 +146,7 @@ class AncestorChart:
page = page + 1
generation = generation + 3
try:
self.doc.close()
self.doc.close()
except:
print _("Document write failure")