New plugin system for document generators
svn: r733
This commit is contained in:
parent
93a337b034
commit
3c40fcbd9e
@ -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 = [("","")]
|
||||
|
230
src/Plugins.py
230
src/Plugins.py
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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
242
src/docgen/AbiWordDoc.py
Normal 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,'&','&'); # Must be first
|
||||
text = string.replace(text,'<','<');
|
||||
text = string.replace(text,'>','>');
|
||||
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
340
src/docgen/HtmlDoc.py
Normal 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(' ')
|
||||
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
441
src/docgen/KwordDoc.py
Normal 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
136
src/docgen/LaTeXDoc.py
Normal 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
449
src/docgen/OpenDrawDoc.py
Normal 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="'Times New Roman'" ')
|
||||
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="'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('/>\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="'Times New Roman'" ')
|
||||
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="'Times New Roman'" ')
|
||||
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="'Times New Roman'" ')
|
||||
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
579
src/docgen/OpenOfficeDoc.py
Normal 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="'Times New Roman'" ')
|
||||
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="'Times New Roman'" ')
|
||||
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)
|
457
src/docgen/OpenSpreadSheet.py
Normal file
457
src/docgen/OpenSpreadSheet.py
Normal 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="'Times New Roman'" ')
|
||||
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="'Times New Roman'" ')
|
||||
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="'Times New Roman'" ')
|
||||
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
168
src/docgen/PSDrawDoc.py
Normal 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
284
src/docgen/PdfDoc.py
Normal 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
185
src/docgen/PdfDrawDoc.py
Normal 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
525
src/docgen/RTFDoc.py
Normal 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)
|
@ -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)
|
||||
|
@ -146,7 +146,7 @@ class AncestorChart:
|
||||
page = page + 1
|
||||
generation = generation + 3
|
||||
try:
|
||||
self.doc.close()
|
||||
self.doc.close()
|
||||
except:
|
||||
print _("Document write failure")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user